mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-19 04:13:24 +00:00
Rough fix for threaded GL for Qt.
This commit is contained in:
parent
3a988400a7
commit
98cfaef6ec
@ -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>
|
||||
|
||||
@ -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)
|
||||
@ -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()
|
||||
@ -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;
|
||||
|
||||
int ret = mainInternal(a);
|
||||
|
||||
NativeShutdownGraphics();
|
||||
|
43
Qt/QtMain.h
43
Qt/QtMain.h
@ -19,6 +19,8 @@ QTM_USE_NAMESPACE
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
#include <atomic>
|
||||
#include <thread>
|
||||
|
||||
#include "base/display.h"
|
||||
#include "base/logging.h"
|
||||
@ -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();
|
||||
@ -47,21 +50,48 @@ public:
|
||||
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;
|
||||
};
|
||||
|
||||
//GUI
|
||||
enum class EmuThreadState {
|
||||
DISABLED,
|
||||
START_REQUESTED,
|
||||
RUNNING,
|
||||
QUIT_REQUESTED,
|
||||
STOPPED,
|
||||
};
|
||||
|
||||
|
||||
// GUI, thread manager
|
||||
class MainUI : public QGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -87,6 +117,10 @@ protected:
|
||||
|
||||
void updateAccelerometer();
|
||||
|
||||
void EmuThreadFunc();
|
||||
void EmuThreadStart();
|
||||
void EmuThreadStop();
|
||||
|
||||
private:
|
||||
QtDummyGraphicsContext *graphicsContext;
|
||||
|
||||
@ -94,6 +128,11 @@ private:
|
||||
#if defined(MOBILE_DEVICE)
|
||||
QAccelerometer* acc;
|
||||
#endif
|
||||
|
||||
std::thread emuThread;
|
||||
std::atomic<int> emuThreadState;
|
||||
|
||||
bool useThread_ = false;
|
||||
};
|
||||
|
||||
extern MainUI* emugl;
|
||||
|
Loading…
x
Reference in New Issue
Block a user