Qt: Allow switching between GL and GL2 backends

This commit is contained in:
Jeffrey Pfau 2015-10-28 23:22:10 -07:00
parent 6cdfb3ae9a
commit f689bfcb2b
3 changed files with 62 additions and 37 deletions

View File

@ -47,11 +47,14 @@ if(NOT Qt5OpenGL_FOUND OR NOT Qt5Widgets_FOUND)
endif()
if(BUILD_GL)
list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c)
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gl.c)
if(NOT WIN32)
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c)
endif()
endif()
if(BUILD_GLES2)
list(APPEND PLATFORM_SRC ${PLATFORM_SRC} ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c)
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c)
endif()
get_target_property(QT_TYPE Qt5::Core TYPE)

View File

@ -10,6 +10,13 @@
extern "C" {
#include "gba/supervisor/thread.h"
#ifdef BUILD_GL
#include "platform/opengl/gl.h"
#endif
#if !defined(_WIN32)
#include "platform/opengl/gles2.h"
#endif
}
using namespace QGBA;
@ -18,10 +25,15 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent)
: Display(parent)
, m_isDrawing(false)
, m_gl(new EmptyGLWidget(format, this))
, m_painter(new PainterGL(m_gl))
, m_drawThread(nullptr)
, m_context(nullptr)
{
QGLFormat::OpenGLVersionFlag glVersion = QGLFormat::OpenGL_Version_1_4;
QGLFormat::OpenGLVersionFlags supported = QGLFormat::openGLVersionFlags();
if (supported & QGLFormat::OpenGL_Version_2_1) {
glVersion = QGLFormat::OpenGL_Version_2_1;
}
m_painter = new PainterGL(m_gl, glVersion);
m_gl->setMouseTracking(true);
m_gl->setAttribute(Qt::WA_TransparentForMouseEvents); // This doesn't seem to work?
}
@ -135,24 +147,44 @@ void DisplayGL::resizePainter() {
}
}
PainterGL::PainterGL(QGLWidget* parent)
PainterGL::PainterGL(QGLWidget* parent, QGLFormat::OpenGLVersionFlag glVersion)
: m_gl(parent)
, m_active(false)
, m_context(nullptr)
, m_messagePainter(nullptr)
{
#ifdef BUILD_GL
GBAGLContextCreate(&m_backend);
#elif defined(BUILD_GLES2)
GBAGLES2ContextCreate(&m_backend);
GBAGLContext* glBackend;
#endif
m_backend.d.swap = [](VideoBackend* v) {
#if !defined(_WIN32)
GBAGLES2Context* gl2Backend;
#endif
switch (glVersion) {
default:
#if !defined(_WIN32)
gl2Backend = new GBAGLES2Context;
GBAGLES2ContextCreate(gl2Backend);
m_backend = &gl2Backend->d;
break;
#endif
case QGLFormat::OpenGL_Version_1_1:
case QGLFormat::OpenGL_Version_1_2:
case QGLFormat::OpenGL_Version_1_3:
case QGLFormat::OpenGL_Version_1_4:
case QGLFormat::OpenGL_Version_1_5:
glBackend = new GBAGLContext;
GBAGLContextCreate(glBackend);
m_backend = &glBackend->d;
break;
}
m_backend->swap = [](VideoBackend* v) {
PainterGL* painter = static_cast<PainterGL*>(v->user);
painter->m_gl->swapBuffers();
};
m_backend.d.user = this;
m_backend.d.filter = false;
m_backend.d.lockAspectRatio = false;
m_backend->user = this;
m_backend->filter = false;
m_backend->lockAspectRatio = false;
for (int i = 0; i < 2; ++i) {
m_free.append(new uint32_t[256 * 256]);
@ -166,6 +198,7 @@ PainterGL::~PainterGL() {
for (auto item : m_free) {
delete[] item;
}
delete m_backend;
}
void PainterGL::setContext(GBAThread* context) {
@ -184,14 +217,14 @@ void PainterGL::resize(const QSize& size) {
}
void PainterGL::lockAspectRatio(bool lock) {
m_backend.d.lockAspectRatio = lock;
m_backend->lockAspectRatio = lock;
if (m_active) {
forceDraw();
}
}
void PainterGL::filter(bool filter) {
m_backend.d.filter = filter;
m_backend->filter = filter;
if (m_active) {
forceDraw();
}
@ -199,7 +232,7 @@ void PainterGL::filter(bool filter) {
void PainterGL::start() {
m_gl->makeCurrent();
m_backend.d.init(&m_backend.d, reinterpret_cast<WHandle>(m_gl->winId()));
m_backend->init(m_backend, reinterpret_cast<WHandle>(m_gl->winId()));
m_gl->doneCurrent();
m_active = true;
}
@ -214,7 +247,7 @@ void PainterGL::draw() {
performDraw();
m_painter.end();
GBASyncWaitFrameEnd(&m_context->sync);
m_backend.d.swap(&m_backend.d);
m_backend->swap(m_backend);
} else {
GBASyncWaitFrameEnd(&m_context->sync);
}
@ -227,16 +260,16 @@ void PainterGL::forceDraw() {
m_painter.begin(m_gl->context()->device());
performDraw();
m_painter.end();
m_backend.d.swap(&m_backend.d);
m_backend->swap(m_backend);
}
void PainterGL::stop() {
m_active = false;
m_gl->makeCurrent();
dequeueAll();
m_backend.d.clear(&m_backend.d);
m_backend.d.swap(&m_backend.d);
m_backend.d.deinit(&m_backend.d);
m_backend->clear(m_backend);
m_backend->swap(m_backend);
m_backend->deinit(m_backend);
m_gl->doneCurrent();
m_gl->context()->moveToThread(m_gl->thread());
moveToThread(m_gl->thread());
@ -253,8 +286,8 @@ void PainterGL::unpause() {
void PainterGL::performDraw() {
m_painter.beginNativePainting();
float r = m_gl->devicePixelRatio();
m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r);
m_backend.d.drawFrame(&m_backend.d);
m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r);
m_backend->drawFrame(m_backend);
m_painter.endNativePainting();
if (m_messagePainter) {
m_messagePainter->paint(&m_painter);
@ -281,7 +314,7 @@ void PainterGL::dequeue() {
return;
}
uint32_t* buffer = m_queue.dequeue();
m_backend.d.postFrame(&m_backend.d, buffer);
m_backend->postFrame(m_backend, buffer);
m_free.append(buffer);
m_mutex.unlock();
}
@ -294,7 +327,7 @@ void PainterGL::dequeueAll() {
m_free.append(buffer);
}
if (buffer) {
m_backend.d.postFrame(&m_backend.d, buffer);
m_backend->postFrame(m_backend, buffer);
}
m_mutex.unlock();
}

View File

@ -15,15 +15,8 @@
#include <QThread>
#include <QTimer>
extern "C" {
#ifdef BUILD_GL
#include "platform/opengl/gl.h"
#elif defined(BUILD_GLES2)
#include "platform/opengl/gles2.h"
#endif
}
struct GBAThread;
struct VideoBackend;
namespace QGBA {
@ -75,7 +68,7 @@ class PainterGL : public QObject {
Q_OBJECT
public:
PainterGL(QGLWidget* parent);
PainterGL(QGLWidget* parent, QGLFormat::OpenGLVersionFlag = QGLFormat::OpenGL_Version_1_1);
~PainterGL();
void setContext(GBAThread*);
@ -105,11 +98,7 @@ private:
QGLWidget* m_gl;
bool m_active;
GBAThread* m_context;
#ifdef BUILD_GL
GBAGLContext m_backend;
#elif defined(BUILD_GLES2)
GBAGLES2Context m_backend;
#endif
VideoBackend* m_backend;
QSize m_size;
MessagePainter* m_messagePainter;
};