mirror of https://github.com/mgba-emu/mgba.git
Qt: Allow switching between GL and GL2 backends
This commit is contained in:
parent
6cdfb3ae9a
commit
f689bfcb2b
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue