Headless: Quick update to use render thread.

This commit is contained in:
Unknown W. Brackets 2018-03-25 14:45:43 -07:00
parent 0d10bb8515
commit 0366e05c44
2 changed files with 97 additions and 15 deletions

View file

@ -32,11 +32,13 @@
#include "GPU/GPUState.h"
#include "base/logging.h"
#include "base/timeutil.h"
#include "gfx/gl_common.h"
#include "gfx_es2/gpu_features.h"
#include "file/vfs.h"
#include "file/zip_read.h"
#include "thin3d/thin3d_create.h"
#include "thin3d/GLRenderManager.h"
const bool WINDOW_VISIBLE = false;
const int WINDOW_WIDTH = 480;
@ -53,20 +55,47 @@ SDL_Window *CreateHiddenWindow() {
class GLDummyGraphicsContext : public DummyGraphicsContext {
public:
GLDummyGraphicsContext() {
CheckGLExtensions();
draw_ = Draw::T3DCreateGLContext();
SetGPUBackend(GPUBackend::OPENGL);
bool success = draw_->CreatePresets();
assert(success);
}
~GLDummyGraphicsContext() { delete draw_; }
bool InitFromRenderThread(std::string *errorMessage) override;
void ShutdownFromRenderThread() override {
delete draw_;
draw_ = nullptr;
SDL_GL_DeleteContext(glContext_);
glContext_ = nullptr;
SDL_DestroyWindow(screen_);
screen_ = nullptr;
}
Draw::DrawContext *GetDrawContext() override {
return draw_;
}
void ThreadStart() override {
renderManager_->ThreadStart();
}
bool ThreadFrame() override {
return renderManager_->ThreadFrame();
}
void ThreadEnd() override {
renderManager_->ThreadEnd();
}
void StopThread() override {
renderManager_->WaitUntilQueueIdle();
renderManager_->StopThread();
}
private:
Draw::DrawContext *draw_;
GLRenderManager *renderManager_ = nullptr;
SDL_Window *screen_;
SDL_GLContext glContext_;
};
void SDLHeadlessHost::LoadNativeAssets() {
@ -75,7 +104,7 @@ void SDLHeadlessHost::LoadNativeAssets() {
VFSRegister("", new DirectoryAssetReader("../"));
}
bool SDLHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext **ctx) {
bool GLDummyGraphicsContext::InitFromRenderThread(std::string *errorMessage) {
SDL_Init(SDL_INIT_VIDEO);
// TODO
@ -115,29 +144,72 @@ bool SDLHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext *
}
#endif
CheckGLExtensions();
draw_ = Draw::T3DCreateGLContext();
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
SetGPUBackend(GPUBackend::OPENGL);
bool success = draw_->CreatePresets();
assert(success);
renderManager_->SetSwapFunction([&]() {
SDL_GL_SwapWindow(screen_);
});
return success;
}
bool SDLHeadlessHost::InitGraphics(std::string *error_message, GraphicsContext **ctx) {
GraphicsContext *graphicsContext = new GLDummyGraphicsContext();
*ctx = graphicsContext;
gfx_ = graphicsContext;
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();
return true;
threadState_ = RenderThreadState::START_REQUESTED;
while (threadState_ == RenderThreadState::START_REQUESTED || threadState_ == RenderThreadState::STARTING)
sleep_ms(1);
return threadState_ == RenderThreadState::STARTED;
}
void SDLHeadlessHost::ShutdownGraphics() {
gfx_->StopThread();
while (threadState_ != RenderThreadState::STOPPED)
sleep_ms(1);
gfx_->Shutdown();
delete gfx_;
gfx_ = nullptr;
SDL_GL_DeleteContext(glContext_);
glContext_ = nullptr;
SDL_DestroyWindow(screen_);
screen_ = nullptr;
}
void SDLHeadlessHost::SwapBuffers() {
gfx_->SwapBuffers();
SDL_GL_SwapWindow(screen_);
}
#endif

View file

@ -38,9 +38,19 @@ public:
protected:
void LoadNativeAssets();
SDL_Window *screen_;
SDL_GLContext glContext_;
enum class RenderThreadState {
IDLE,
START_REQUESTED,
STARTING,
START_FAILED,
STARTED,
STOP_REQUESTED,
STOPPING,
STOPPED,
};
GraphicsContext *gfx_;
volatile RenderThreadState threadState_ = RenderThreadState::IDLE;
};
#endif