Qt: Hook up proxy backend to DisplayGL

This commit is contained in:
Vicki Pfau 2023-04-20 20:08:27 -07:00
parent dc6639b30b
commit 399ace760c
4 changed files with 57 additions and 11 deletions

View File

@ -944,6 +944,9 @@ void PainterGL::dequeueAll(bool keep) {
void PainterGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) { void PainterGL::setVideoProxy(std::shared_ptr<VideoProxy> proxy) {
m_videoProxy = proxy; m_videoProxy = proxy;
if (proxy) {
proxy->setProxiedBackend(m_backend);
}
} }
void PainterGL::interrupt() { void PainterGL::interrupt() {

View File

@ -29,7 +29,19 @@ VideoProxy::VideoProxy() {
m_logger.readData = &callback<bool, void*, size_t, bool>::func<&VideoProxy::readData>; m_logger.readData = &callback<bool, void*, size_t, bool>::func<&VideoProxy::readData>;
m_logger.postEvent = &callback<void, enum mVideoLoggerEvent>::func<&VideoProxy::postEvent>; m_logger.postEvent = &callback<void, enum mVideoLoggerEvent>::func<&VideoProxy::postEvent>;
mVideoProxyBackendInit(&m_backend, nullptr);
m_backend.context = this;
m_backend.wakeupCb = [](struct mVideoProxyBackend*, void* context) {
VideoProxy* self = static_cast<VideoProxy*>(context);
QMetaObject::invokeMethod(self, "commandAvailable");
};
connect(this, &VideoProxy::dataAvailable, this, &VideoProxy::processData); connect(this, &VideoProxy::dataAvailable, this, &VideoProxy::processData);
connect(this, &VideoProxy::commandAvailable, this, &VideoProxy::processCommands);
}
VideoProxy::~VideoProxy() {
mVideoProxyBackendDeinit(&m_backend);
} }
void VideoProxy::attach(CoreController* controller) { void VideoProxy::attach(CoreController* controller) {
@ -44,11 +56,20 @@ void VideoProxy::detach(CoreController* controller) {
} }
} }
void VideoProxy::setProxiedBackend(VideoBackend* backend) {
// TODO: This needs some safety around it
m_backend.backend = backend;
}
void VideoProxy::processData() { void VideoProxy::processData() {
mVideoLoggerRendererRun(&m_logger, false); mVideoLoggerRendererRun(&m_logger, false);
m_fromThreadCond.wakeAll(); m_fromThreadCond.wakeAll();
} }
void VideoProxy::processCommands() {
mVideoProxyBackendRun(&m_backend, false);
}
void VideoProxy::init() { void VideoProxy::init() {
RingFIFOInit(&m_dirtyQueue, 0x80000); RingFIFOInit(&m_dirtyQueue, 0x80000);
} }

View File

@ -7,9 +7,12 @@
#include <QMutex> #include <QMutex>
#include <QObject> #include <QObject>
#include <QQueue>
#include <QReadWriteLock>
#include <QWaitCondition> #include <QWaitCondition>
#include <mgba/feature/video-logger.h> #include <mgba/feature/video-logger.h>
#include <mgba/feature/proxy-backend.h>
#include <mgba-util/ring-fifo.h> #include <mgba-util/ring-fifo.h>
namespace QGBA { namespace QGBA {
@ -21,16 +24,22 @@ Q_OBJECT
public: public:
VideoProxy(); VideoProxy();
~VideoProxy();
void attach(CoreController*); void attach(CoreController*);
void detach(CoreController*); void detach(CoreController*);
void setBlocking(bool block) { m_logger.waitOnFlush = block; } void setBlocking(bool block) { m_logger.waitOnFlush = block; }
VideoBackend* backend() { return &m_backend.d; }
void setProxiedBackend(VideoBackend*);
signals: signals:
void dataAvailable(); void dataAvailable();
void commandAvailable();
public slots: public slots:
void processData(); void processData();
void processCommands();
void reset(); void reset();
void handleEvent(int); void handleEvent(int);
@ -62,10 +71,19 @@ private:
VideoProxy* p; VideoProxy* p;
} m_logger; } m_logger;
struct mVideoProxyBackend m_backend;
RingFIFO m_dirtyQueue; RingFIFO m_dirtyQueue;
QMutex m_mutex; QMutex m_mutex;
QWaitCondition m_toThreadCond; QWaitCondition m_toThreadCond;
QWaitCondition m_fromThreadCond; QWaitCondition m_fromThreadCond;
QReadWriteLock m_backendInLock;
QReadWriteLock m_backendOutLock;
QQueue<QByteArray> m_backendIn;
QQueue<QByteArray> m_backendOut;
QWaitCondition m_toBackendThreadCond;
QWaitCondition m_fromBackendThreadCond;
}; };
} }

View File

@ -633,6 +633,11 @@ void Window::scriptingOpen() {
m_scripting->setController(m_controller); m_scripting->setController(m_controller);
m_display->installEventFilter(m_scripting.get()); m_display->installEventFilter(m_scripting.get());
} }
std::shared_ptr<VideoProxy> proxy = m_display->videoProxy();
if (proxy) {
m_scripting->setVideoBackend(proxy->backend());
}
} }
ScriptingView* view = new ScriptingView(m_scripting.get(), m_config); ScriptingView* view = new ScriptingView(m_scripting.get(), m_config);
openView(view); openView(view);
@ -1055,6 +1060,9 @@ void Window::reloadDisplayDriver() {
#endif #endif
m_display->setBackgroundImage(QImage{m_config->getOption("backgroundImage")}); m_display->setBackgroundImage(QImage{m_config->getOption("backgroundImage")});
std::shared_ptr<VideoProxy> proxy = std::make_shared<VideoProxy>();
m_display->setVideoProxy(proxy);
} }
void Window::reloadAudioDriver() { void Window::reloadAudioDriver() {
@ -1079,12 +1087,7 @@ void Window::changeRenderer() {
CoreController::Interrupter interrupter(m_controller); CoreController::Interrupter interrupter(m_controller);
if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && m_controller->supportsFeature(CoreController::Feature::OPENGL)) { if (m_config->getOption("hwaccelVideo").toInt() && m_display->supportsShaders() && m_controller->supportsFeature(CoreController::Feature::OPENGL)) {
std::shared_ptr<VideoProxy> proxy = m_display->videoProxy(); m_display->videoProxy()->attach(m_controller.get());
if (!proxy) {
proxy = std::make_shared<VideoProxy>();
}
m_display->setVideoProxy(proxy);
proxy->attach(m_controller.get());
int fb = m_display->framebufferHandle(); int fb = m_display->framebufferHandle();
if (fb >= 0) { if (fb >= 0) {
@ -1092,11 +1095,7 @@ void Window::changeRenderer() {
m_config->updateOption("videoScale"); m_config->updateOption("videoScale");
} }
} else { } else {
std::shared_ptr<VideoProxy> proxy = m_display->videoProxy(); m_display->videoProxy()->detach(m_controller.get());
if (proxy) {
proxy->detach(m_controller.get());
m_display->setVideoProxy({});
}
m_controller->setFramebufferHandle(-1); m_controller->setFramebufferHandle(-1);
} }
} }
@ -2113,6 +2112,11 @@ void Window::setController(CoreController* controller, const QString& fname) {
#ifdef ENABLE_SCRIPTING #ifdef ENABLE_SCRIPTING
if (m_scripting) { if (m_scripting) {
m_scripting->setController(m_controller); m_scripting->setController(m_controller);
std::shared_ptr<VideoProxy> proxy = m_display->videoProxy();
if (proxy) {
m_scripting->setVideoBackend(proxy->backend());
}
} }
#endif #endif