Headless: Add simple GL thread handling.

Because of the way headless works and runs tests, it was a lot simpler to
use a separate thread (unlike elsewhere) for the GL rendering.  Hopefully
this difference doesn't bite us later.
This commit is contained in:
Unknown W. Brackets 2018-03-25 09:47:56 -07:00
parent b0a22fb5c7
commit 2c493f3633
2 changed files with 55 additions and 3 deletions

View File

@ -32,6 +32,7 @@
#include "Windows/GPU/WindowsVulkanContext.h"
#include "base/logging.h"
#include "base/timeutil.h"
#include "gfx/gl_common.h"
#include "gfx_es2/gpu_features.h"
#include "file/vfs.h"
@ -86,11 +87,13 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte
}
WindowsGraphicsContext *graphicsContext = nullptr;
bool needRenderThread = false;
switch (gpuCore_) {
case GPUCORE_NULL:
case GPUCORE_GLES:
case GPUCORE_SOFTWARE:
graphicsContext = new WindowsGLContext();
needRenderThread = true;
break;
case GPUCORE_DIRECTX9:
@ -116,17 +119,53 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte
return false;
}
if (gpuCore_ == GPUCORE_GLES) {
// TODO: Do we need to do this here?
CheckGLExtensions();
if (needRenderThread) {
std::thread th([&]{
while (threadState_ == RenderThreadState::IDLE)
sleep_ms(1);
threadState_ = RenderThreadState::STARTING;
std::string err;
if (!gfx_->InitFromRenderThread(&err)) {
threadState_ = RenderThreadState::START_FAILED;
return;
}
gfx_->ThreadStart();
threadState_ = RenderThreadState::STARTED;
while (threadState_ != RenderThreadState::STOP_REQUESTED) {
if (!gfx_->ThreadFrame()) {
break;
}
gfx_->SwapBuffers();
}
threadState_ = RenderThreadState::STOPPING;
gfx_->ThreadEnd();
gfx_->ShutdownFromRenderThread();
threadState_ = RenderThreadState::STOPPED;
});
th.detach();
}
LoadNativeAssets();
if (needRenderThread) {
threadState_ = RenderThreadState::START_REQUESTED;
while (threadState_ == RenderThreadState::START_REQUESTED || threadState_ == RenderThreadState::STARTING)
sleep_ms(1);
return threadState_ == RenderThreadState::STARTED;
}
return true;
}
void WindowsHeadlessHost::ShutdownGraphics() {
gfx_->StopThread();
while (threadState_ != RenderThreadState::STOPPED)
sleep_ms(1);
gfx_->Shutdown();
delete gfx_;
gfx_ = nullptr;

View File

@ -18,6 +18,7 @@
#pragma once
#include "headless/StubHost.h"
#include <thread>
#undef HEADLESSHOST_CLASS
#define HEADLESSHOST_CLASS WindowsHeadlessHost
@ -38,8 +39,20 @@ public:
protected:
void LoadNativeAssets();
enum class RenderThreadState {
IDLE,
START_REQUESTED,
STARTING,
START_FAILED,
STARTED,
STOP_REQUESTED,
STOPPING,
STOPPED,
};
HWND hWnd;
HDC hDC;
HGLRC hRC;
GraphicsContext *gfx_;
volatile RenderThreadState threadState_ = RenderThreadState::IDLE;
};