GBA Video: Trim down GBAVideoProxyRenderer

This commit is contained in:
Vicki Pfau 2017-04-17 02:21:02 -07:00
parent fbb02475da
commit 3f92b1e67f
6 changed files with 94 additions and 100 deletions

View File

@ -17,17 +17,6 @@ struct GBAVideoProxyRenderer {
struct GBAVideoRenderer d;
struct GBAVideoRenderer* backend;
struct mVideoLogger logger;
bool block;
void (*init)(struct GBAVideoProxyRenderer*);
void (*deinit)(struct GBAVideoProxyRenderer*);
void (*reset)(struct GBAVideoProxyRenderer*);
void (*lock)(struct GBAVideoProxyRenderer*);
void (*unlock)(struct GBAVideoProxyRenderer*);
void (*wait)(struct GBAVideoProxyRenderer*);
void (*wake)(struct GBAVideoProxyRenderer*, int y);
};
void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend, bool readonly);

View File

@ -37,11 +37,21 @@ static inline size_t _roundUp(size_t value, int shift) {
void mVideoLoggerRendererCreate(struct mVideoLogger* logger, bool readonly) {
if (readonly) {
logger->writeData = _writeNull;
logger->block = true;
} else {
logger->writeData = _writeData;
}
logger->readData = _readData;
logger->vf = NULL;
logger->init = NULL;
logger->deinit = NULL;
logger->reset = NULL;
logger->lock = NULL;
logger->unlock = NULL;
logger->wait = NULL;
logger->wake = NULL;
}
void mVideoLoggerRendererInit(struct mVideoLogger* logger) {
@ -51,9 +61,17 @@ void mVideoLoggerRendererInit(struct mVideoLogger* logger) {
logger->vramDirtyBitmap = calloc(_roundUp(logger->vramSize, 17), sizeof(uint32_t));
logger->oamDirtyBitmap = calloc(_roundUp(logger->oamSize, 6), sizeof(uint32_t));
if (logger->init) {
logger->init(logger);
}
}
void mVideoLoggerRendererDeinit(struct mVideoLogger* logger) {
if (logger->deinit) {
logger->deinit(logger);
}
mappedMemoryFree(logger->palette, logger->paletteSize);
mappedMemoryFree(logger->vram, logger->vramSize);
mappedMemoryFree(logger->oam, logger->oamSize);
@ -65,6 +83,10 @@ void mVideoLoggerRendererDeinit(struct mVideoLogger* logger) {
void mVideoLoggerRendererReset(struct mVideoLogger* logger) {
memset(logger->vramDirtyBitmap, 0, sizeof(uint32_t) * _roundUp(logger->vramSize, 17));
memset(logger->oamDirtyBitmap, 0, sizeof(uint32_t) * _roundUp(logger->oamSize, 6));
if (logger->reset) {
logger->reset(logger);
}
}
void mVideoLoggerRendererWriteVideoRegister(struct mVideoLogger* logger, uint32_t address, uint16_t value) {
@ -179,6 +201,7 @@ static bool _writeNull(struct mVideoLogger* logger, const void* data, size_t len
}
static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bool block) {
UNUSED(block);
return logger->vf->read(logger->vf, data, length) == (ssize_t) length;
}

View File

@ -33,6 +33,16 @@ 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);
bool block;
void (*init)(struct mVideoLogger*);
void (*deinit)(struct mVideoLogger*);
void (*reset)(struct mVideoLogger*);
void (*lock)(struct mVideoLogger*);
void (*unlock)(struct mVideoLogger*);
void (*wait)(struct mVideoLogger*);
void (*wake)(struct mVideoLogger*, int y);
void* context;
bool (*parsePacket)(struct mVideoLogger* logger, const struct mVideoLoggerDirtyInfo* packet);

View File

@ -672,7 +672,7 @@ static void _GBACoreStartVideoLog(struct mCore* core, struct mVideoLogContext* c
context->channels[0].channelData = vf;
context->channels[0].type = 0;
gbacore->logProxy.logger.vf = vf;
gbacore->logProxy.block = false;
gbacore->logProxy.logger.block = false;
GBAVideoProxyRendererShim(&gba->video, &gbacore->logProxy);
}

View File

@ -26,9 +26,6 @@ static uint16_t* _vramBlock(struct mVideoLogger* logger, uint32_t address);
void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct GBAVideoRenderer* backend, bool readonly) {
mVideoLoggerRendererCreate(&renderer->logger, readonly);
if (readonly) {
renderer->block = true;
}
renderer->d.init = GBAVideoProxyRendererInit;
renderer->d.reset = GBAVideoProxyRendererReset;
@ -48,10 +45,6 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct
renderer->d.disableBG[3] = false;
renderer->d.disableOBJ = false;
renderer->init = NULL;
renderer->deinit = NULL;
renderer->reset = NULL;
renderer->logger.context = renderer;
renderer->logger.parsePacket = _parsePacket;
renderer->logger.vramBlock = _vramBlock;
@ -59,27 +52,18 @@ void GBAVideoProxyRendererCreate(struct GBAVideoProxyRenderer* renderer, struct
renderer->logger.vramSize = SIZE_VRAM;
renderer->logger.oamSize = SIZE_OAM;
renderer->lock = NULL;
renderer->unlock = NULL;
renderer->wait = NULL;
renderer->wake = NULL;
renderer->backend = backend;
}
static void _init(struct GBAVideoProxyRenderer* proxyRenderer) {
mVideoLoggerRendererInit(&proxyRenderer->logger);
if (proxyRenderer->block) {
if (proxyRenderer->logger.block) {
proxyRenderer->backend->palette = proxyRenderer->logger.palette;
proxyRenderer->backend->vram = proxyRenderer->logger.vram;
proxyRenderer->backend->oam = (union GBAOAM*) proxyRenderer->logger.oam;
proxyRenderer->backend->cache = NULL;
}
if (proxyRenderer->init) {
proxyRenderer->init(proxyRenderer);
}
}
static void _reset(struct GBAVideoProxyRenderer* proxyRenderer) {
@ -88,10 +72,6 @@ static void _reset(struct GBAVideoProxyRenderer* proxyRenderer) {
memcpy(proxyRenderer->logger.vram, proxyRenderer->d.vram, SIZE_VRAM);
mVideoLoggerRendererReset(&proxyRenderer->logger);
if (proxyRenderer->reset) {
proxyRenderer->reset(proxyRenderer);
}
}
void GBAVideoProxyRendererShim(struct GBAVideo* video, struct GBAVideoProxyRenderer* renderer) {
@ -118,10 +98,6 @@ void GBAVideoProxyRendererUnshim(struct GBAVideo* video, struct GBAVideoProxyRen
renderer->backend->vram = video->vram;
renderer->backend->oam = &video->oam;
if (renderer->deinit) {
renderer->deinit(renderer);
}
mVideoLoggerRendererDeinit(&renderer->logger);
}
@ -144,10 +120,6 @@ void GBAVideoProxyRendererReset(struct GBAVideoRenderer* renderer) {
void GBAVideoProxyRendererDeinit(struct GBAVideoRenderer* renderer) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
if (proxyRenderer->deinit) {
proxyRenderer->deinit(proxyRenderer);
}
proxyRenderer->backend->deinit(proxyRenderer->backend);
mVideoLoggerRendererDeinit(&proxyRenderer->logger);
@ -212,7 +184,7 @@ uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* render
}
mVideoLoggerRendererWriteVideoRegister(&proxyRenderer->logger, address, value);
if (!proxyRenderer->block) {
if (!proxyRenderer->logger.block) {
proxyRenderer->backend->writeVideoRegister(proxyRenderer->backend, address, value);
}
return value;
@ -221,7 +193,7 @@ uint16_t GBAVideoProxyRendererWriteVideoRegister(struct GBAVideoRenderer* render
void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t address) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
mVideoLoggerRendererWriteVRAM(&proxyRenderer->logger, address);
if (!proxyRenderer->block) {
if (!proxyRenderer->logger.block) {
proxyRenderer->backend->writeVRAM(proxyRenderer->backend, address);
}
if (renderer->cache) {
@ -232,7 +204,7 @@ void GBAVideoProxyRendererWriteVRAM(struct GBAVideoRenderer* renderer, uint32_t
void GBAVideoProxyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
mVideoLoggerRendererWritePalette(&proxyRenderer->logger, address, value);
if (!proxyRenderer->block) {
if (!proxyRenderer->logger.block) {
proxyRenderer->backend->writePalette(proxyRenderer->backend, address, value);
}
if (renderer->cache) {
@ -242,7 +214,7 @@ void GBAVideoProxyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32
void GBAVideoProxyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
if (!proxyRenderer->block) {
if (!proxyRenderer->logger.block) {
proxyRenderer->backend->writeOAM(proxyRenderer->backend, oam);
}
mVideoLoggerRendererWriteOAM(&proxyRenderer->logger, oam, proxyRenderer->d.oam->raw[oam]);
@ -250,51 +222,51 @@ void GBAVideoProxyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t o
void GBAVideoProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
if (!proxyRenderer->block) {
if (!proxyRenderer->logger.block) {
proxyRenderer->backend->drawScanline(proxyRenderer->backend, y);
}
mVideoLoggerRendererDrawScanline(&proxyRenderer->logger, y);
if (proxyRenderer->block && proxyRenderer->wake) {
proxyRenderer->wake(proxyRenderer, y);
if (proxyRenderer->logger.block && proxyRenderer->logger.wake) {
proxyRenderer->logger.wake(&proxyRenderer->logger, y);
}
}
void GBAVideoProxyRendererFinishFrame(struct GBAVideoRenderer* renderer) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
if (proxyRenderer->block && proxyRenderer->wait) {
proxyRenderer->lock(proxyRenderer);
proxyRenderer->wait(proxyRenderer);
if (proxyRenderer->logger.block && proxyRenderer->logger.wait) {
proxyRenderer->logger.lock(&proxyRenderer->logger);
proxyRenderer->logger.wait(&proxyRenderer->logger);
}
mVideoLoggerRendererFlush(&proxyRenderer->logger);
if (proxyRenderer->block && proxyRenderer->wait) {
proxyRenderer->unlock(proxyRenderer);
if (proxyRenderer->logger.block && proxyRenderer->logger.wait) {
proxyRenderer->logger.unlock(&proxyRenderer->logger);
}
}
static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, size_t* stride, const void** pixels) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
if (proxyRenderer->block && proxyRenderer->wait) {
proxyRenderer->lock(proxyRenderer);
if (proxyRenderer->logger.block && proxyRenderer->logger.wait) {
proxyRenderer->logger.lock(&proxyRenderer->logger);
// Insert an extra item into the queue to make sure it gets flushed
mVideoLoggerRendererFlush(&proxyRenderer->logger);
proxyRenderer->wait(proxyRenderer);
proxyRenderer->logger.wait(&proxyRenderer->logger);
}
proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels);
if (proxyRenderer->block && proxyRenderer->wait) {
proxyRenderer->unlock(proxyRenderer);
if (proxyRenderer->logger.block && proxyRenderer->logger.wait) {
proxyRenderer->logger.unlock(&proxyRenderer->logger);
}
}
static void GBAVideoProxyRendererPutPixels(struct GBAVideoRenderer* renderer, size_t stride, const void* pixels) {
struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer;
if (proxyRenderer->block && proxyRenderer->wait) {
proxyRenderer->lock(proxyRenderer);
if (proxyRenderer->logger.block && proxyRenderer->logger.wait) {
proxyRenderer->logger.lock(&proxyRenderer->logger);
// Insert an extra item into the queue to make sure it gets flushed
mVideoLoggerRendererFlush(&proxyRenderer->logger);
proxyRenderer->wait(proxyRenderer);
proxyRenderer->logger.wait(&proxyRenderer->logger);
}
proxyRenderer->backend->putPixels(proxyRenderer->backend, stride, pixels);
if (proxyRenderer->block && proxyRenderer->wait) {
proxyRenderer->unlock(proxyRenderer);
if (proxyRenderer->logger.block && proxyRenderer->logger.wait) {
proxyRenderer->logger.unlock(&proxyRenderer->logger);
}
}

View File

@ -11,39 +11,39 @@
#ifndef DISABLE_THREADING
static void GBAVideoThreadProxyRendererInit(struct GBAVideoProxyRenderer* renderer);
static void GBAVideoThreadProxyRendererReset(struct GBAVideoProxyRenderer* renderer);
static void GBAVideoThreadProxyRendererDeinit(struct GBAVideoProxyRenderer* renderer);
static void GBAVideoThreadProxyRendererInit(struct mVideoLogger* logger);
static void GBAVideoThreadProxyRendererReset(struct mVideoLogger* logger);
static void GBAVideoThreadProxyRendererDeinit(struct mVideoLogger* logger);
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 _lock(struct GBAVideoProxyRenderer* proxyRenderer);
static void _unlock(struct GBAVideoProxyRenderer* proxyRenderer);
static void _wait(struct GBAVideoProxyRenderer* proxyRenderer);
static void _wake(struct GBAVideoProxyRenderer* proxyRenderer, int y);
static void _lock(struct mVideoLogger* logger);
static void _unlock(struct mVideoLogger* logger);
static void _wait(struct mVideoLogger* logger);
static void _wake(struct mVideoLogger* logger, int y);
void GBAVideoThreadProxyRendererCreate(struct GBAVideoThreadProxyRenderer* renderer, struct GBAVideoRenderer* backend) {
renderer->d.block = true;
renderer->d.logger.block = true;
GBAVideoProxyRendererCreate(&renderer->d, backend, false);
renderer->d.init = GBAVideoThreadProxyRendererInit;
renderer->d.reset = GBAVideoThreadProxyRendererReset;
renderer->d.deinit = GBAVideoThreadProxyRendererDeinit;
renderer->d.lock = _lock;
renderer->d.unlock = _unlock;
renderer->d.wait = _wait;
renderer->d.wake = _wake;
renderer->d.logger.init = GBAVideoThreadProxyRendererInit;
renderer->d.logger.reset = GBAVideoThreadProxyRendererReset;
renderer->d.logger.deinit = GBAVideoThreadProxyRendererDeinit;
renderer->d.logger.lock = _lock;
renderer->d.logger.unlock = _unlock;
renderer->d.logger.wait = _wait;
renderer->d.logger.wake = _wake;
renderer->d.logger.writeData = _writeData;
renderer->d.logger.readData = _readData;
renderer->d.logger.vf = NULL;
}
void GBAVideoThreadProxyRendererInit(struct GBAVideoProxyRenderer* renderer) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = (struct GBAVideoThreadProxyRenderer*) renderer;
void GBAVideoThreadProxyRendererInit(struct mVideoLogger* logger) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
ConditionInit(&proxyRenderer->fromThreadCond);
ConditionInit(&proxyRenderer->toThreadCond);
MutexInit(&proxyRenderer->mutex);
@ -53,8 +53,8 @@ void GBAVideoThreadProxyRendererInit(struct GBAVideoProxyRenderer* renderer) {
ThreadCreate(&proxyRenderer->thread, _proxyThread, proxyRenderer);
}
void GBAVideoThreadProxyRendererReset(struct GBAVideoProxyRenderer* renderer) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = (struct GBAVideoThreadProxyRenderer*) renderer;
void GBAVideoThreadProxyRendererReset(struct mVideoLogger* logger) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
MutexLock(&proxyRenderer->mutex);
while (proxyRenderer->threadState == PROXY_THREAD_BUSY) {
ConditionWake(&proxyRenderer->toThreadCond);
@ -63,8 +63,8 @@ void GBAVideoThreadProxyRendererReset(struct GBAVideoProxyRenderer* renderer) {
MutexUnlock(&proxyRenderer->mutex);
}
void GBAVideoThreadProxyRendererDeinit(struct GBAVideoProxyRenderer* renderer) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = (struct GBAVideoThreadProxyRenderer*) renderer;
void GBAVideoThreadProxyRendererDeinit(struct mVideoLogger* logger) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
bool waiting = false;
MutexLock(&proxyRenderer->mutex);
while (proxyRenderer->threadState == PROXY_THREAD_BUSY) {
@ -132,33 +132,33 @@ static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bo
return read;
}
static void _lock(struct GBAVideoProxyRenderer* proxyRenderer) {
struct GBAVideoThreadProxyRenderer* threadProxy = (struct GBAVideoThreadProxyRenderer*) proxyRenderer;
MutexLock(&threadProxy->mutex);
static void _lock(struct mVideoLogger* logger) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
MutexLock(&proxyRenderer->mutex);
}
static void _wait(struct GBAVideoProxyRenderer* proxyRenderer) {
struct GBAVideoThreadProxyRenderer* threadProxy = (struct GBAVideoThreadProxyRenderer*) proxyRenderer;
if (threadProxy->threadState == PROXY_THREAD_STOPPED) {
static void _wait(struct mVideoLogger* logger) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
if (proxyRenderer->threadState == PROXY_THREAD_STOPPED) {
mLOG(GBA_VIDEO, ERROR, "Proxy thread stopped prematurely!");
_proxyThreadRecover(threadProxy);
_proxyThreadRecover(proxyRenderer);
return;
}
while (threadProxy->threadState == PROXY_THREAD_BUSY) {
ConditionWake(&threadProxy->toThreadCond);
ConditionWait(&threadProxy->fromThreadCond, &threadProxy->mutex);
while (proxyRenderer->threadState == PROXY_THREAD_BUSY) {
ConditionWake(&proxyRenderer->toThreadCond);
ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex);
}
}
static void _unlock(struct GBAVideoProxyRenderer* proxyRenderer) {
struct GBAVideoThreadProxyRenderer* threadProxy = (struct GBAVideoThreadProxyRenderer*) proxyRenderer;
MutexUnlock(&threadProxy->mutex);
static void _unlock(struct mVideoLogger* logger) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
MutexUnlock(&proxyRenderer->mutex);
}
static void _wake(struct GBAVideoProxyRenderer* proxyRenderer, int y) {
struct GBAVideoThreadProxyRenderer* threadProxy = (struct GBAVideoThreadProxyRenderer*) proxyRenderer;
static void _wake(struct mVideoLogger* logger, int y) {
struct GBAVideoThreadProxyRenderer* proxyRenderer = logger->context;
if ((y & 15) == 15) {
ConditionWake(&threadProxy->toThreadCond);
ConditionWake(&proxyRenderer->toThreadCond);
}
}