mirror of https://github.com/mgba-emu/mgba.git
Feature: More video logging plumbing
This commit is contained in:
parent
42813bb197
commit
82ef919ee2
|
@ -29,6 +29,7 @@ struct mVideoThreadProxy {
|
|||
Condition toThreadCond;
|
||||
Mutex mutex;
|
||||
enum mVideoThreadProxyState threadState;
|
||||
enum mVideoLoggerEvent event;
|
||||
|
||||
struct RingFIFO dirtyQueue;
|
||||
};
|
||||
|
|
|
@ -27,6 +27,13 @@ enum mVideoLoggerDirtyType {
|
|||
DIRTY_BUFFER,
|
||||
};
|
||||
|
||||
enum mVideoLoggerEvent {
|
||||
LOGGER_EVENT_NONE = 0,
|
||||
LOGGER_EVENT_INIT,
|
||||
LOGGER_EVENT_DEINIT,
|
||||
LOGGER_EVENT_RESET,
|
||||
};
|
||||
|
||||
struct mVideoLoggerDirtyInfo {
|
||||
enum mVideoLoggerDirtyType type;
|
||||
uint32_t address;
|
||||
|
@ -38,6 +45,7 @@ struct VFile;
|
|||
struct mVideoLogger {
|
||||
bool (*writeData)(struct mVideoLogger* logger, const void* data, size_t length);
|
||||
bool (*readData)(struct mVideoLogger* logger, void* data, size_t length, bool block);
|
||||
void (*postEvent)(struct mVideoLogger* logger, enum mVideoLoggerEvent event);
|
||||
void* dataContext;
|
||||
|
||||
bool block;
|
||||
|
@ -52,6 +60,7 @@ struct mVideoLogger {
|
|||
void* context;
|
||||
|
||||
bool (*parsePacket)(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet);
|
||||
void (*handleEvent)(struct mVideoLogger* logger, enum mVideoLoggerEvent event);
|
||||
uint16_t* (*vramBlock)(struct mVideoLogger* logger, uint32_t address);
|
||||
|
||||
size_t vramSize;
|
||||
|
|
|
@ -18,6 +18,7 @@ static THREAD_ENTRY _proxyThread(void* renderer);
|
|||
|
||||
static bool _writeData(struct mVideoLogger* logger, const void* data, size_t length);
|
||||
static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bool block);
|
||||
static void _postEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent);
|
||||
|
||||
static void _lock(struct mVideoLogger* logger);
|
||||
static void _unlock(struct mVideoLogger* logger);
|
||||
|
@ -38,6 +39,7 @@ void mVideoThreadProxyCreate(struct mVideoThreadProxy* renderer) {
|
|||
|
||||
renderer->d.writeData = _writeData;
|
||||
renderer->d.readData = _readData;
|
||||
renderer->d.postEvent = _postEvent;
|
||||
}
|
||||
|
||||
void mVideoThreadProxyInit(struct mVideoLogger* logger) {
|
||||
|
@ -131,6 +133,14 @@ static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bo
|
|||
return read;
|
||||
}
|
||||
|
||||
static void _postEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event) {
|
||||
struct mVideoThreadProxy* proxyRenderer = (struct mVideoThreadProxy*) logger;
|
||||
MutexLock(&proxyRenderer->mutex);
|
||||
proxyRenderer->event = event;
|
||||
ConditionWake(&proxyRenderer->toThreadCond);
|
||||
MutexUnlock(&proxyRenderer->mutex);
|
||||
}
|
||||
|
||||
static void _lock(struct mVideoLogger* logger) {
|
||||
struct mVideoThreadProxy* proxyRenderer = (struct mVideoThreadProxy*) logger;
|
||||
MutexLock(&proxyRenderer->mutex);
|
||||
|
@ -172,6 +182,10 @@ static THREAD_ENTRY _proxyThread(void* logger) {
|
|||
break;
|
||||
}
|
||||
proxyRenderer->threadState = PROXY_THREAD_BUSY;
|
||||
if (proxyRenderer->event) {
|
||||
proxyRenderer->d.handleEvent(&proxyRenderer->d, proxyRenderer->event);
|
||||
proxyRenderer->event = 0;
|
||||
} else {
|
||||
MutexUnlock(&proxyRenderer->mutex);
|
||||
if (!mVideoLoggerRendererRun(&proxyRenderer->d, false)) {
|
||||
// FIFO was corrupted
|
||||
|
@ -179,6 +193,7 @@ static THREAD_ENTRY _proxyThread(void* logger) {
|
|||
mLOG(GBA_VIDEO, ERROR, "Proxy thread queue got corrupted!");
|
||||
}
|
||||
MutexLock(&proxyRenderer->mutex);
|
||||
}
|
||||
ConditionWake(&proxyRenderer->fromThreadCond);
|
||||
if (proxyRenderer->threadState != PROXY_THREAD_STOPPED) {
|
||||
proxyRenderer->threadState = PROXY_THREAD_IDLE;
|
||||
|
|
|
@ -21,6 +21,7 @@ static void GBAVideoProxyRendererFinishFrame(struct GBAVideoRenderer* renderer);
|
|||
static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels);
|
||||
static void GBAVideoProxyRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels);
|
||||
|
||||
static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event);
|
||||
static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet);
|
||||
static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address);
|
||||
|
||||
|
@ -45,6 +46,7 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct
|
|||
|
||||
renderer->logger->context = renderer;
|
||||
renderer->logger->parsePacket = _parsePacket;
|
||||
renderer->logger->handleEvent = _handleEvent;
|
||||
renderer->logger->vramBlock = _vramBlock;
|
||||
renderer->logger->paletteSize = SIZE_PALETTE_RAM;
|
||||
renderer->logger->vramSize = SIZE_VRAM;
|
||||
|
@ -105,7 +107,11 @@ void GBAVideoProxyRendererInit(struct GBAVideoRenderer* renderer) {
|
|||
_init(proxyRenderer);
|
||||
_reset(proxyRenderer);
|
||||
|
||||
if (!proxyRenderer->logger->block) {
|
||||
proxyRenderer->backend->init(proxyRenderer->backend);
|
||||
} else {
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_INIT);
|
||||
}
|
||||
}
|
||||
|
||||
void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer) {
|
||||
|
@ -113,17 +119,42 @@ void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer) {
|
|||
|
||||
_reset(proxyRenderer);
|
||||
|
||||
if (!proxyRenderer->logger->block) {
|
||||
proxyRenderer->backend->reset(proxyRenderer->backend);
|
||||
} else {
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) {
|
||||
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
|
||||
|
||||
if (!proxyRenderer->logger->block) {
|
||||
proxyRenderer->backend->deinit(proxyRenderer->backend);
|
||||
} else {
|
||||
proxyRenderer->logger->postEvent(proxyRenderer->logger, LOGGER_EVENT_DEINIT);
|
||||
}
|
||||
|
||||
mVideoLoggerRendererDeinit(proxyRenderer->logger);
|
||||
}
|
||||
|
||||
static void _handleEvent(struct mVideoLogger* logger, enum mVideoLoggerEvent event) {
|
||||
struct GBAVideoProxyRenderer* proxyRenderer = logger->context;
|
||||
switch (event) {
|
||||
default:
|
||||
break;
|
||||
case LOGGER_EVENT_INIT:
|
||||
proxyRenderer->backend->init(proxyRenderer->backend);
|
||||
break;
|
||||
case LOGGER_EVENT_DEINIT:
|
||||
proxyRenderer->backend->deinit(proxyRenderer->backend);
|
||||
break;
|
||||
case LOGGER_EVENT_RESET:
|
||||
proxyRenderer->backend->reset(proxyRenderer->backend);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* item) {
|
||||
struct GBAVideoProxyRenderer* proxyRenderer = logger->context;
|
||||
switch (item->type) {
|
||||
|
|
|
@ -40,6 +40,7 @@ DisplayGL::DisplayGL(const QGLFormat& format, QWidget* parent)
|
|||
setUpdatesEnabled(false); // Prevent paint events, which can cause race conditions
|
||||
|
||||
connect(&m_videoProxy, &VideoProxy::dataAvailable, &m_videoProxy, &VideoProxy::processData);
|
||||
connect(&m_videoProxy, &VideoProxy::eventPosted, &m_videoProxy, &VideoProxy::handleEvent);
|
||||
}
|
||||
|
||||
DisplayGL::~DisplayGL() {
|
||||
|
|
|
@ -23,6 +23,7 @@ VideoProxy::VideoProxy() {
|
|||
|
||||
m_logger.d.writeData = &callback<bool, const void*, size_t>::func<&VideoProxy::writeData>;
|
||||
m_logger.d.readData = &callback<bool, void*, size_t, bool>::func<&VideoProxy::readData>;
|
||||
m_logger.d.postEvent = &callback<void, enum mVideoLoggerEvent>::func<&VideoProxy::postEvent>;
|
||||
}
|
||||
|
||||
void VideoProxy::attach(CoreController* controller) {
|
||||
|
@ -74,6 +75,14 @@ bool VideoProxy::readData(void* data, size_t length, bool block) {
|
|||
return read;
|
||||
}
|
||||
|
||||
void VideoProxy::postEvent(enum mVideoLoggerEvent event) {
|
||||
emit eventPosted(event);
|
||||
}
|
||||
|
||||
void VideoProxy::handleEvent(int event) {
|
||||
m_logger.d.handleEvent(&m_logger.d, static_cast<enum mVideoLoggerEvent>(event));
|
||||
}
|
||||
|
||||
void VideoProxy::lock() {
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
|
|
@ -26,9 +26,11 @@ public:
|
|||
|
||||
signals:
|
||||
void dataAvailable();
|
||||
void eventPosted(int);
|
||||
|
||||
public slots:
|
||||
void processData();
|
||||
void handleEvent(int);
|
||||
|
||||
private:
|
||||
void init();
|
||||
|
@ -37,6 +39,7 @@ private:
|
|||
|
||||
bool writeData(const void* data, size_t length);
|
||||
bool readData(void* data, size_t length, bool block);
|
||||
void postEvent(enum mVideoLoggerEvent event);
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
|
Loading…
Reference in New Issue