Feature: More video logging plumbing

This commit is contained in:
Vicki Pfau 2019-05-10 11:13:21 -07:00
parent 42813bb197
commit 82ef919ee2
7 changed files with 78 additions and 9 deletions

View File

@ -29,6 +29,7 @@ struct mVideoThreadProxy {
Condition toThreadCond;
Mutex mutex;
enum mVideoThreadProxyState threadState;
enum mVideoLoggerEvent event;
struct RingFIFO dirtyQueue;
};

View File

@ -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;

View File

@ -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;

View File

@ -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) {

View File

@ -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() {

View File

@ -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();
}

View File

@ -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();