Core: Fix up thread proxy waiting

This commit is contained in:
Vicki Pfau 2018-09-23 13:26:52 -07:00
parent de9bff4a29
commit fdfab146a0
6 changed files with 20 additions and 6 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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