diff --git a/include/mgba-util/ring-fifo.h b/include/mgba-util/ring-fifo.h index c5b1fdcc5..1cfaa3d00 100644 --- a/include/mgba-util/ring-fifo.h +++ b/include/mgba-util/ring-fifo.h @@ -20,6 +20,7 @@ struct RingFIFO { void RingFIFOInit(struct RingFIFO* buffer, size_t capacity); void RingFIFODeinit(struct RingFIFO* buffer); size_t RingFIFOCapacity(const struct RingFIFO* buffer); +size_t RingFIFOSize(const struct RingFIFO* buffer); void RingFIFOClear(struct RingFIFO* buffer); size_t RingFIFOWrite(struct RingFIFO* buffer, const void* value, size_t length); size_t RingFIFORead(struct RingFIFO* buffer, void* output, size_t length); diff --git a/src/feature/thread-proxy.c b/src/feature/thread-proxy.c index 8fe944846..196877002 100644 --- a/src/feature/thread-proxy.c +++ b/src/feature/thread-proxy.c @@ -121,7 +121,7 @@ static bool _readData(struct mVideoLogger* logger, void* data, size_t length, bo if (!block || read) { break; } - mLOG(GBA_VIDEO, DEBUG, "Proxy thread can't read VRAM. CPU thread asleep?"); + mLOG(GBA_VIDEO, DEBUG, "Can't read %"PRIz"u bytes. CPU thread asleep?", length); MutexLock(&proxyRenderer->mutex); ConditionWake(&proxyRenderer->fromThreadCond); ConditionWait(&proxyRenderer->toThreadCond, &proxyRenderer->mutex); @@ -142,7 +142,7 @@ static void _wait(struct mVideoLogger* logger) { _proxyThreadRecover(proxyRenderer); return; } - while (proxyRenderer->threadState == PROXY_THREAD_BUSY) { + while (RingFIFOSize(&proxyRenderer->dirtyQueue)) { ConditionWake(&proxyRenderer->toThreadCond); ConditionWait(&proxyRenderer->fromThreadCond, &proxyRenderer->mutex); } diff --git a/src/feature/video-logger.c b/src/feature/video-logger.c index 6f49e482d..be1c7b3f7 100644 --- a/src/feature/video-logger.c +++ b/src/feature/video-logger.c @@ -258,6 +258,9 @@ void mVideoLoggerRendererFlush(struct mVideoLogger* logger) { 0xDEADBEEF, }; logger->writeData(logger, &dirty, sizeof(dirty)); + if (logger->wait) { + logger->wait(logger); + } } void mVideoLoggerRendererFinishFrame(struct mVideoLogger* logger) { diff --git a/src/gb/extra/proxy.c b/src/gb/extra/proxy.c index 5de65ae84..c5230c88c 100644 --- a/src/gb/extra/proxy.c +++ b/src/gb/extra/proxy.c @@ -252,7 +252,6 @@ void GBVideoProxyRendererFinishFrame(struct GBVideoRenderer* renderer) { struct GBVideoProxyRenderer* proxyRenderer = (struct GBVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->lock(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } if (!proxyRenderer->logger->block) { proxyRenderer->backend->finishFrame(proxyRenderer->backend); diff --git a/src/gba/extra/proxy.c b/src/gba/extra/proxy.c index 8189c6f74..d7092f30c 100644 --- a/src/gba/extra/proxy.c +++ b/src/gba/extra/proxy.c @@ -146,6 +146,8 @@ static bool _parsePacket(struct mVideoLogger* logger, const struct mVideoLoggerD if (item->address <= SIZE_VRAM - 0x1000) { logger->readData(logger, &logger->vram[item->address >> 1], 0x1000, true); proxyRenderer->backend->writeVRAM(proxyRenderer->backend, item->address); + } else { + logger->readData(logger, NULL, 0x1000, true); } break; case DIRTY_SCANLINE: @@ -250,7 +252,6 @@ void GBAVideoProxyRendererFinishFrame(struct GBAVideoRenderer* renderer) { struct GBAVideoProxyRenderer* proxyRenderer = (struct GBAVideoProxyRenderer*) renderer; if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { proxyRenderer->logger->lock(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } if (!proxyRenderer->logger->block) { proxyRenderer->backend->finishFrame(proxyRenderer->backend); @@ -268,7 +269,6 @@ static void GBAVideoProxyRendererGetPixels(struct GBAVideoRenderer* renderer, si proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } proxyRenderer->backend->getPixels(proxyRenderer->backend, stride, pixels); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { @@ -282,7 +282,6 @@ static void GBAVideoProxyRendererPutPixels(struct GBAVideoRenderer* renderer, si proxyRenderer->logger->lock(proxyRenderer->logger); // Insert an extra item into the queue to make sure it gets flushed mVideoLoggerRendererFlush(proxyRenderer->logger); - proxyRenderer->logger->wait(proxyRenderer->logger); } proxyRenderer->backend->putPixels(proxyRenderer->backend, stride, pixels); if (proxyRenderer->logger->block && proxyRenderer->logger->wait) { diff --git a/src/util/ring-fifo.c b/src/util/ring-fifo.c index 39c10934a..0d5b40266 100644 --- a/src/util/ring-fifo.c +++ b/src/util/ring-fifo.c @@ -22,6 +22,18 @@ size_t RingFIFOCapacity(const struct RingFIFO* buffer) { return buffer->capacity; } +size_t RingFIFOSize(const struct RingFIFO* buffer) { + const void* read; + const void* write; + ATOMIC_LOAD(read, buffer->readPtr); + ATOMIC_LOAD(write, buffer->readPtr); + if (read <= write) { + return (uintptr_t) write - (uintptr_t) read; + } else { + return buffer->capacity - (uintptr_t) read + (uintptr_t) write; + } +} + void RingFIFOClear(struct RingFIFO* buffer) { ATOMIC_STORE(buffer->readPtr, buffer->data); ATOMIC_STORE(buffer->writePtr, buffer->data);