GBA Video: Add get/put pixels to threaded proxy

This commit is contained in:
Jeffrey Pfau 2016-08-06 10:28:30 -07:00
parent 9264441e09
commit b70a601e37
1 changed files with 35 additions and 7 deletions

View File

@ -37,7 +37,7 @@ static void GBAVideoThreadProxyRendererWritePalette(struct GBAVideoRenderer* ren
static void GBAVideoThreadProxyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam); static void GBAVideoThreadProxyRendererWriteOAM(struct GBAVideoRenderer* renderer, uint32_t oam);
static void GBAVideoThreadProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y); static void GBAVideoThreadProxyRendererDrawScanline(struct GBAVideoRenderer* renderer, int y);
static void GBAVideoThreadProxyRendererFinishFrame(struct GBAVideoRenderer* renderer); 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 void GBAVideoThreadProxyRendererPutPixels(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels);
static THREAD_ENTRY _proxyThread(void* renderer); static THREAD_ENTRY _proxyThread(void* renderer);
@ -230,21 +230,49 @@ void GBAVideoThreadProxyRendererFinishFrame(struct GBAVideoRenderer* renderer) {
0xDEADBEEF, 0xDEADBEEF,
}; };
RingFIFOWrite(&proxyRenderer->dirtyQueue, &dirty, sizeof(dirty)); RingFIFOWrite(&proxyRenderer->dirtyQueue, &dirty, sizeof(dirty));
do { while (proxyRenderer->threadState == PROXY_THREAD_BUSY) {
ConditionWake(&proxyRenderer->toThreadCond); ConditionWake(&proxyRenderer->toThreadCond);
ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex);
} while (proxyRenderer->threadState == PROXY_THREAD_BUSY); }
proxyRenderer->backend->finishFrame(proxyRenderer->backend); proxyRenderer->backend->finishFrame(proxyRenderer->backend);
proxyRenderer->vramDirtyBitmap = 0; proxyRenderer->vramDirtyBitmap = 0;
MutexUnlock(&proxyRenderer->mutex); MutexUnlock(&proxyRenderer->mutex);
} }
void GBAVideoThreadProxyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, void** pixels) { static void GBAVideoThreadProxyRendererGetPixels(struct GBAVideoRenderer* renderer, unsigned* stride, const void** pixels) {
// TODO 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) { static void GBAVideoThreadProxyRendererPutPixels(struct GBAVideoRenderer* renderer, unsigned stride, void* pixels) {
// TODO 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) { static THREAD_ENTRY _proxyThread(void* renderer) {