all repos — mgba @ b70a601e37237c934cb8b259e0fedd9f40ed6c04

mGBA Game Boy Advance Emulator

GBA Video: Add get/put pixels to threaded proxy
Jeffrey Pfau jeffrey@endrift.com
Sat, 06 Aug 2016 10:28:30 -0700
commit

b70a601e37237c934cb8b259e0fedd9f40ed6c04

parent

9264441e0991eb0baf2d180d2ffd16c5cf815456

1 files changed, 35 insertions(+), 7 deletions(-)

jump to
M src/gba/renderers/thread-proxy.csrc/gba/renderers/thread-proxy.c

@@ -37,7 +37,7 @@ static void GBAVideoThreadProxyRendererWritePalette(struct GBAVideoRenderer* renderer, uint32_t address, uint16_t value);

static void GBAVideoThreadProxyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoThreadProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); static void GBAVideoThreadProxyRendererFinishFrame(struct GBAVideoRenderer* renderer); -static void GBAVideoThreadProxyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels); +static void GBAVideoThreadProxyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, const void** pixels); static void GBAVideoThreadProxyRendererPutPixels(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels); static THREAD_ENTRY _proxyThread(void* renderer);

@@ -230,21 +230,49 @@ 0,

0xDEADBEEF, }; RingFIFOWrite(&proxyRenderer->dirtyQueue, &dirty, sizeof(dirty)); - do { + while (proxyRenderer->threadState == PROXY_THREAD_BUSY) { ConditionWake(&proxyRenderer->toThreadCond); ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); - } while (proxyRenderer->threadState == PROXY_THREAD_BUSY); + } proxyRenderer->backend->finishFrame(proxyRenderer->backend); proxyRenderer->vramDirtyBitmap = 0; MutexUnlock(&proxyRenderer->mutex); } -void GBAVideoThreadProxyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels) { - // TODO +static void GBAVideoThreadProxyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, const void** pixels) { + struct GBAVideoThreadProxyRenderer* proxyRenderer = (struct GBAVideoThreadProxyRenderer*) renderer; MutexLock(&proxyRenderer->mutex); + // Insert an extra item into the queue to make sure it gets flushed + struct GBAVideoDirtyInfo dirty = { + DIRTY_FLUSH, + 0, + 0, + 0xDEADBEEF, + }; + RingFIFOWrite(&proxyRenderer->dirtyQueue, &dirty, sizeof(dirty)); + while (proxyRenderer->threadState == PROXY_THREAD_BUSY) { + ConditionWake(&proxyRenderer->toThreadCond); + ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); + } + proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); + MutexUnlock(&proxyRenderer->mutex); } -void GBAVideoThreadProxyRendererPutPixels(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels) { - // TODO +static void GBAVideoThreadProxyRendererPutPixels(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels) { + struct GBAVideoThreadProxyRenderer* proxyRenderer = (struct GBAVideoThreadProxyRenderer*) renderer; MutexLock(&proxyRenderer->mutex); + // Insert an extra item into the queue to make sure it gets flushed + struct GBAVideoDirtyInfo dirty = { + DIRTY_FLUSH, + 0, + 0, + 0xDEADBEEF, + }; + RingFIFOWrite(&proxyRenderer->dirtyQueue, &dirty, sizeof(dirty)); + while (proxyRenderer->threadState == PROXY_THREAD_BUSY) { + ConditionWake(&proxyRenderer->toThreadCond); + ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); + } + proxyRenderer->backend->putPixels(proxyRenderer->backend, stride, pixels); + MutexUnlock(&proxyRenderer->mutex); } static THREAD_ENTRY _proxyThread(void* renderer) {