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()
|
endif()
|
||||||
|
|
||||||
if(BUILD_GL)
|
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()
|
endif()
|
||||||
|
|
||||||
if(BUILD_GLES2)
|
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()
|
endif()
|
||||||
|
|
||||||
get_target_property(QT_TYPE Qt5::Core TYPE)
|
get_target_property(QT_TYPE Qt5::Core TYPE)
|
||||||
|
|
|
@ -10,6 +10,13 @@
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "gba/supervisor/thread.h"
|
#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;
|
using namespace QGBA;
|
||||||
|
@ -18,10 +25,15 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent)
|
||||||
: Display(parent)
|
: Display(parent)
|
||||||
, m_isDrawing(false)
|
, m_isDrawing(false)
|
||||||
, m_gl(new EmptyGLWidget(format, this))
|
, m_gl(new EmptyGLWidget(format, this))
|
||||||
, m_painter(new PainterGL(m_gl))
|
|
||||||
, m_drawThread(nullptr)
|
, m_drawThread(nullptr)
|
||||||
, m_context(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->setMouseTracking(true);
|
||||||
m_gl->setAttribute(Qt::WA_TransparentForMouseEvents); // This doesn't seem to work?
|
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_gl(parent)
|
||||||
, m_active(false)
|
, m_active(false)
|
||||||
, m_context(nullptr)
|
, m_context(nullptr)
|
||||||
, m_messagePainter(nullptr)
|
, m_messagePainter(nullptr)
|
||||||
{
|
{
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
GBAGLContextCreate(&m_backend);
|
GBAGLContext* glBackend;
|
||||||
#elif defined(BUILD_GLES2)
|
|
||||||
GBAGLES2ContextCreate(&m_backend);
|
|
||||||
#endif
|
#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);
|
PainterGL* painter = static_cast<PainterGL*>(v->user);
|
||||||
painter->m_gl->swapBuffers();
|
painter->m_gl->swapBuffers();
|
||||||
};
|
};
|
||||||
m_backend.d.user = this;
|
m_backend->user = this;
|
||||||
m_backend.d.filter = false;
|
m_backend->filter = false;
|
||||||
m_backend.d.lockAspectRatio = false;
|
m_backend->lockAspectRatio = false;
|
||||||
|
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
m_free.append(new uint32_t[256 * 256]);
|
m_free.append(new uint32_t[256 * 256]);
|
||||||
|
@ -166,6 +198,7 @@ PainterGL::~PainterGL() {
|
||||||
for (auto item : m_free) {
|
for (auto item : m_free) {
|
||||||
delete[] item;
|
delete[] item;
|
||||||
}
|
}
|
||||||
|
delete m_backend;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::setContext(GBAThread* context) {
|
void PainterGL::setContext(GBAThread* context) {
|
||||||
|
@ -184,14 +217,14 @@ void PainterGL::resize(const QSize& size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::lockAspectRatio(bool lock) {
|
void PainterGL::lockAspectRatio(bool lock) {
|
||||||
m_backend.d.lockAspectRatio = lock;
|
m_backend->lockAspectRatio = lock;
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
forceDraw();
|
forceDraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::filter(bool filter) {
|
void PainterGL::filter(bool filter) {
|
||||||
m_backend.d.filter = filter;
|
m_backend->filter = filter;
|
||||||
if (m_active) {
|
if (m_active) {
|
||||||
forceDraw();
|
forceDraw();
|
||||||
}
|
}
|
||||||
|
@ -199,7 +232,7 @@ void PainterGL::filter(bool filter) {
|
||||||
|
|
||||||
void PainterGL::start() {
|
void PainterGL::start() {
|
||||||
m_gl->makeCurrent();
|
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_gl->doneCurrent();
|
||||||
m_active = true;
|
m_active = true;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +247,7 @@ void PainterGL::draw() {
|
||||||
performDraw();
|
performDraw();
|
||||||
m_painter.end();
|
m_painter.end();
|
||||||
GBASyncWaitFrameEnd(&m_context->sync);
|
GBASyncWaitFrameEnd(&m_context->sync);
|
||||||
m_backend.d.swap(&m_backend.d);
|
m_backend->swap(m_backend);
|
||||||
} else {
|
} else {
|
||||||
GBASyncWaitFrameEnd(&m_context->sync);
|
GBASyncWaitFrameEnd(&m_context->sync);
|
||||||
}
|
}
|
||||||
|
@ -227,16 +260,16 @@ void PainterGL::forceDraw() {
|
||||||
m_painter.begin(m_gl->context()->device());
|
m_painter.begin(m_gl->context()->device());
|
||||||
performDraw();
|
performDraw();
|
||||||
m_painter.end();
|
m_painter.end();
|
||||||
m_backend.d.swap(&m_backend.d);
|
m_backend->swap(m_backend);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PainterGL::stop() {
|
void PainterGL::stop() {
|
||||||
m_active = false;
|
m_active = false;
|
||||||
m_gl->makeCurrent();
|
m_gl->makeCurrent();
|
||||||
dequeueAll();
|
dequeueAll();
|
||||||
m_backend.d.clear(&m_backend.d);
|
m_backend->clear(m_backend);
|
||||||
m_backend.d.swap(&m_backend.d);
|
m_backend->swap(m_backend);
|
||||||
m_backend.d.deinit(&m_backend.d);
|
m_backend->deinit(m_backend);
|
||||||
m_gl->doneCurrent();
|
m_gl->doneCurrent();
|
||||||
m_gl->context()->moveToThread(m_gl->thread());
|
m_gl->context()->moveToThread(m_gl->thread());
|
||||||
moveToThread(m_gl->thread());
|
moveToThread(m_gl->thread());
|
||||||
|
@ -253,8 +286,8 @@ void PainterGL::unpause() {
|
||||||
void PainterGL::performDraw() {
|
void PainterGL::performDraw() {
|
||||||
m_painter.beginNativePainting();
|
m_painter.beginNativePainting();
|
||||||
float r = m_gl->devicePixelRatio();
|
float r = m_gl->devicePixelRatio();
|
||||||
m_backend.d.resized(&m_backend.d, m_size.width() * r, m_size.height() * r);
|
m_backend->resized(m_backend, m_size.width() * r, m_size.height() * r);
|
||||||
m_backend.d.drawFrame(&m_backend.d);
|
m_backend->drawFrame(m_backend);
|
||||||
m_painter.endNativePainting();
|
m_painter.endNativePainting();
|
||||||
if (m_messagePainter) {
|
if (m_messagePainter) {
|
||||||
m_messagePainter->paint(&m_painter);
|
m_messagePainter->paint(&m_painter);
|
||||||
|
@ -281,7 +314,7 @@ void PainterGL::dequeue() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t* buffer = m_queue.dequeue();
|
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_free.append(buffer);
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
@ -294,7 +327,7 @@ void PainterGL::dequeueAll() {
|
||||||
m_free.append(buffer);
|
m_free.append(buffer);
|
||||||
}
|
}
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
m_backend.d.postFrame(&m_backend.d, buffer);
|
m_backend->postFrame(m_backend, buffer);
|
||||||
}
|
}
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,15 +15,8 @@
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QTimer>
|
#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 GBAThread;
|
||||||
|
struct VideoBackend;
|
||||||
|
|
||||||
namespace QGBA {
|
namespace QGBA {
|
||||||
|
|
||||||
|
@ -75,7 +68,7 @@ class PainterGL : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PainterGL(QGLWidget* parent);
|
PainterGL(QGLWidget* parent, QGLFormat::OpenGLVersionFlag = QGLFormat::OpenGL_Version_1_1);
|
||||||
~PainterGL();
|
~PainterGL();
|
||||||
|
|
||||||
void setContext(GBAThread*);
|
void setContext(GBAThread*);
|
||||||
|
@ -105,11 +98,7 @@ private:
|
||||||
QGLWidget* m_gl;
|
QGLWidget* m_gl;
|
||||||
bool m_active;
|
bool m_active;
|
||||||
GBAThread* m_context;
|
GBAThread* m_context;
|
||||||
#ifdef BUILD_GL
|
VideoBackend* m_backend;
|
||||||
GBAGLContext m_backend;
|
|
||||||
#elif defined(BUILD_GLES2)
|
|
||||||
GBAGLES2Context m_backend;
|
|
||||||
#endif
|
|
||||||
QSize m_size;
|
QSize m_size;
|
||||||
MessagePainter* m_messagePainter;
|
MessagePainter* m_messagePainter;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue