Skip to content

Commit

Permalink
Rough fix for threaded GL for Qt.
Browse files Browse the repository at this point in the history
  • Loading branch information
hrydgard committed Jan 31, 2018
1 parent 3a98840 commit 98cfaef
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 23 deletions.
97 changes: 76 additions & 21 deletions Qt/QtMain.cpp
Expand Up @@ -29,6 +29,7 @@
#include "QtMain.h"
#include "gfx_es2/gpu_features.h"
#include "math/math_util.h"
#include "thread/threadutil.h"

#include <string.h>

Expand Down Expand Up @@ -188,31 +189,64 @@ static int mainInternal(QApplication &a)
return a.exec();
}

void MainUI::EmuThreadFunc() {
ILOG("In emu thread");
setCurrentThreadName("Emu");

// There's no real requirement that NativeInit happen on this thread.
// We just call the update/render loop here.
emuThreadState = (int)EmuThreadState::RUNNING;
while (emuThreadState != (int)EmuThreadState::QUIT_REQUESTED) {
#ifdef SDL
SDL_PumpEvents();
#endif
updateAccelerometer();
time_update();
UpdateRunLoop();
}
emuThreadState = (int)EmuThreadState::STOPPED;
}

void MainUI::EmuThreadStart() {
emuThreadState = (int)EmuThreadState::START_REQUESTED;
emuThread = std::thread([&]() { this->EmuThreadFunc(); } );
}

void MainUI::EmuThreadStop() {
emuThreadState = (int)EmuThreadState::QUIT_REQUESTED;
emuThread.join();
emuThread = std::thread();
}

MainUI::MainUI(QWidget *parent):
QGLWidget(parent)
QGLWidget(parent)
{
setAttribute(Qt::WA_AcceptTouchEvents);
emuThreadState = (int)EmuThreadState::DISABLED;
setAttribute(Qt::WA_AcceptTouchEvents);
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
setAttribute(Qt::WA_LockLandscapeOrientation);
setAttribute(Qt::WA_LockLandscapeOrientation);
#endif
#if defined(MOBILE_DEVICE)
acc = new QAccelerometer(this);
acc->start();
acc = new QAccelerometer(this);
acc->start();
#endif
setFocus();
setFocusPolicy(Qt::StrongFocus);
startTimer(16);
setFocus();
setFocusPolicy(Qt::StrongFocus);
startTimer(16);
}

MainUI::~MainUI()
{
if (useThread_) {
EmuThreadStop();
}
#if defined(MOBILE_DEVICE)
delete acc;
delete acc;
#endif
NativeShutdownGraphics();
graphicsContext->Shutdown();
delete graphicsContext;
graphicsContext = nullptr;
NativeShutdownGraphics();
graphicsContext->Shutdown();
delete graphicsContext;
graphicsContext = nullptr;
}

QString MainUI::InputBoxGetQString(QString title, QString defaultValue)
Expand Down Expand Up @@ -330,18 +364,36 @@ void MainUI::initializeGL()
if (gl_extensions.IsCoreContext)
glGetError();
#endif
ILOG("Initializing graphics context");
graphicsContext = new QtDummyGraphicsContext();
NativeInitGraphics(graphicsContext);

// OpenGL uses a background thread to do the main processing and only renders on the gl thread.
useThread_ = g_Config.iGPUBackend == (int)GPUBackend::OPENGL;

if (useThread_) {
ILOG("Using thread, starting emu thread");
EmuThreadStart();

graphicsContext->ThreadStart();
} else {
ILOG("Not using thread, backend=%d", (int)g_Config.iGPUBackend);
}
}

void MainUI::paintGL()
{
#ifdef SDL
SDL_PumpEvents();
#endif
updateAccelerometer();
time_update();
UpdateRunLoop();
if (useThread_) {
graphicsContext->ThreadFrame();
// Do the rest in EmuThreadFunc
} else {
#ifdef SDL
SDL_PumpEvents();
#endif
updateAccelerometer();
time_update();
UpdateRunLoop();
}
}

void MainUI::updateAccelerometer()
Expand Down Expand Up @@ -454,14 +506,17 @@ int main(int argc, char *argv[])
#endif
savegame_dir += "/";
external_dir += "/";

bool fullscreenCLI=false;
for (int i = 1; i < argc; i++) {
if (!strcmp(argv[i],"--fullscreen"))
fullscreenCLI=true;
}
NativeInit(argc, (const char **)argv, savegame_dir.c_str(), external_dir.c_str(), nullptr, fullscreenCLI);


// TODO: Support other backends than GL, like Vulkan, in the Qt backend.
g_Config.iGPUBackend = (int)GPUBackend::OPENGL;

This comment has been minimized.

Copy link
@unknownbrackets

unknownbrackets Feb 10, 2018

Collaborator

I think it's better to use GetGPUBackend() instead of changing g_Config. This makes it simpler to handle GPU switching and restarts.

In this specific case, it would improve the scenario when someone uses the same config (likely, since it's in ~/.config) for Qt and SDL.

-[Unknown]

This comment has been minimized.

Copy link
@hrydgard

hrydgard Feb 10, 2018

Author Owner

Yeah. I'll try to get around to it soon..


int ret = mainInternal(a);

NativeShutdownGraphics();
Expand Down
43 changes: 41 additions & 2 deletions Qt/QtMain.h
Expand Up @@ -19,6 +19,8 @@ QTM_USE_NAMESPACE
#endif

#include <cassert>
#include <atomic>
#include <thread>

#include "base/display.h"
#include "base/logging.h"
Expand All @@ -37,6 +39,7 @@ QTM_USE_NAMESPACE
#include "Core/Core.h"
#include "Core/Config.h"
#include "Core/System.h"
#include "thin3d/GLRenderManager.h"

// Input
void SimulateGamepad();
Expand All @@ -47,21 +50,48 @@ class QtDummyGraphicsContext : public DummyGraphicsContext {
CheckGLExtensions();
draw_ = Draw::T3DCreateGLContext();
SetGPUBackend(GPUBackend::OPENGL);
renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);
bool success = draw_->CreatePresets();
assert(success);
}

~QtDummyGraphicsContext() {
delete draw_;
draw_ = nullptr;
renderManager_ = nullptr;
}

Draw::DrawContext *GetDrawContext() override {
return draw_;
}

void ThreadStart() override {
renderManager_->ThreadStart();
}

bool ThreadFrame() override {
return renderManager_->ThreadFrame();
}

void ThreadEnd() override {
renderManager_->ThreadEnd();
}

private:
Draw::DrawContext *draw_;
Draw::DrawContext *draw_ = nullptr;
GLRenderManager *renderManager_ = nullptr;
};

enum class EmuThreadState {
DISABLED,
START_REQUESTED,
RUNNING,
QUIT_REQUESTED,
STOPPED,
};

//GUI

// GUI, thread manager
class MainUI : public QGLWidget
{
Q_OBJECT
Expand All @@ -87,13 +117,22 @@ public slots:

void updateAccelerometer();

void EmuThreadFunc();
void EmuThreadStart();
void EmuThreadStop();

private:
QtDummyGraphicsContext *graphicsContext;

float xscale, yscale;
#if defined(MOBILE_DEVICE)
QAccelerometer* acc;
#endif

std::thread emuThread;
std::atomic<int> emuThreadState;

bool useThread_ = false;
};

extern MainUI* emugl;
Expand Down

0 comments on commit 98cfaef

Please sign in to comment.