Qt: Move frame upload back onto main thread

This commit is contained in:
Jeffrey Pfau 2015-02-17 22:22:31 -08:00
parent 848cf162af
commit 0cdb26df54
3 changed files with 21 additions and 24 deletions

View File

@ -57,6 +57,7 @@ Misc:
- Debugger: Make I/O register names be addresses instead of values - Debugger: Make I/O register names be addresses instead of values
- Debugger: Rename read/write commands - Debugger: Rename read/write commands
- Qt: Optimize logo drawing - Qt: Optimize logo drawing
- Qt: Move frame upload back onto main thread
0.1.1: (2015-01-24) 0.1.1: (2015-01-24)
Bugfixes: Bugfixes:

View File

@ -31,7 +31,7 @@ static const GLint _glTexCoords[] = {
Display::Display(QGLFormat format, QWidget* parent) Display::Display(QGLFormat format, QWidget* parent)
: QGLWidget(format, parent) : QGLWidget(format, parent)
, m_painter(nullptr) , m_painter(nullptr)
, m_drawThread(nullptr) , m_started(false)
{ {
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS); setMinimumSize(VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS);
@ -40,33 +40,29 @@ Display::Display(QGLFormat format, QWidget* parent)
} }
void Display::startDrawing(const uint32_t* buffer, GBAThread* thread) { void Display::startDrawing(const uint32_t* buffer, GBAThread* thread) {
if (m_drawThread) { if (m_started) {
return; return;
} }
m_drawThread = new QThread(this);
m_painter = new Painter(this); m_painter = new Painter(this);
m_painter->setContext(thread); m_painter->setContext(thread);
m_painter->setBacking(buffer); m_painter->setBacking(buffer);
m_painter->moveToThread(m_drawThread);
m_context = thread; m_context = thread;
doneCurrent(); doneCurrent();
context()->moveToThread(m_drawThread); m_painter->start();
connect(m_drawThread, SIGNAL(started()), m_painter, SLOT(start())); m_started = true;
m_drawThread->start(QThread::TimeCriticalPriority);
lockAspectRatio(m_lockAspectRatio); lockAspectRatio(m_lockAspectRatio);
filter(m_filter); filter(m_filter);
} }
void Display::stopDrawing() { void Display::stopDrawing() {
if (m_drawThread) { if (m_started) {
if (GBAThreadIsActive(m_context)) { if (GBAThreadIsActive(m_context)) {
GBAThreadInterrupt(m_context); GBAThreadInterrupt(m_context);
GBASyncSuspendDrawing(&m_context->sync); GBASyncSuspendDrawing(&m_context->sync);
} }
QMetaObject::invokeMethod(m_painter, "stop", Qt::BlockingQueuedConnection); m_painter->stop();
m_drawThread->exit(); m_started = false;
m_drawThread = nullptr;
if (GBAThreadIsActive(m_context)) { if (GBAThreadIsActive(m_context)) {
GBASyncResumeDrawing(&m_context->sync); GBASyncResumeDrawing(&m_context->sync);
GBAThreadContinue(m_context); GBAThreadContinue(m_context);
@ -75,12 +71,12 @@ void Display::stopDrawing() {
} }
void Display::pauseDrawing() { void Display::pauseDrawing() {
if (m_drawThread) { if (m_started) {
if (GBAThreadIsActive(m_context)) { if (GBAThreadIsActive(m_context)) {
GBAThreadInterrupt(m_context); GBAThreadInterrupt(m_context);
GBASyncSuspendDrawing(&m_context->sync); GBASyncSuspendDrawing(&m_context->sync);
} }
QMetaObject::invokeMethod(m_painter, "pause", Qt::BlockingQueuedConnection); m_painter->pause();
if (GBAThreadIsActive(m_context)) { if (GBAThreadIsActive(m_context)) {
GBASyncResumeDrawing(&m_context->sync); GBASyncResumeDrawing(&m_context->sync);
GBAThreadContinue(m_context); GBAThreadContinue(m_context);
@ -89,12 +85,12 @@ void Display::pauseDrawing() {
} }
void Display::unpauseDrawing() { void Display::unpauseDrawing() {
if (m_drawThread) { if (m_started) {
if (GBAThreadIsActive(m_context)) { if (GBAThreadIsActive(m_context)) {
GBAThreadInterrupt(m_context); GBAThreadInterrupt(m_context);
GBASyncSuspendDrawing(&m_context->sync); GBASyncSuspendDrawing(&m_context->sync);
} }
QMetaObject::invokeMethod(m_painter, "unpause", Qt::BlockingQueuedConnection); m_painter->unpause();
if (GBAThreadIsActive(m_context)) { if (GBAThreadIsActive(m_context)) {
GBASyncResumeDrawing(&m_context->sync); GBASyncResumeDrawing(&m_context->sync);
GBAThreadContinue(m_context); GBAThreadContinue(m_context);
@ -103,22 +99,22 @@ void Display::unpauseDrawing() {
} }
void Display::forceDraw() { void Display::forceDraw() {
if (m_drawThread) { if (m_started) {
QMetaObject::invokeMethod(m_painter, "forceDraw", Qt::QueuedConnection); m_painter->forceDraw();
} }
} }
void Display::lockAspectRatio(bool lock) { void Display::lockAspectRatio(bool lock) {
m_lockAspectRatio = lock; m_lockAspectRatio = lock;
if (m_drawThread) { if (m_started) {
QMetaObject::invokeMethod(m_painter, "lockAspectRatio", Qt::QueuedConnection, Q_ARG(bool, lock)); m_painter->lockAspectRatio(lock);
} }
} }
void Display::filter(bool filter) { void Display::filter(bool filter) {
m_filter = filter; m_filter = filter;
if (m_drawThread) { if (m_started) {
QMetaObject::invokeMethod(m_painter, "filter", Qt::QueuedConnection, Q_ARG(bool, filter)); m_painter->filter(filter);
} }
} }
@ -137,10 +133,10 @@ void Display::initializeGL() {
} }
void Display::resizeEvent(QResizeEvent* event) { void Display::resizeEvent(QResizeEvent* event) {
if (m_drawThread) { if (m_started) {
GBAThreadInterrupt(m_context); GBAThreadInterrupt(m_context);
GBASyncSuspendDrawing(&m_context->sync); GBASyncSuspendDrawing(&m_context->sync);
QMetaObject::invokeMethod(m_painter, "resize", Qt::BlockingQueuedConnection, Q_ARG(QSize, event->size())); m_painter->resize(event->size());
GBASyncResumeDrawing(&m_context->sync); GBASyncResumeDrawing(&m_context->sync);
GBAThreadContinue(m_context); GBAThreadContinue(m_context);
} }

View File

@ -40,7 +40,7 @@ protected:
private: private:
Painter* m_painter; Painter* m_painter;
QThread* m_drawThread; bool m_started;
GBAThread* m_context; GBAThread* m_context;
bool m_lockAspectRatio; bool m_lockAspectRatio;
bool m_filter; bool m_filter;