mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Headless: Quick update to use render thread.
This commit is contained in:
parent
0d10bb8515
commit
0366e05c44
2 changed files with 97 additions and 15 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue