mirror of
https://github.com/libretro/mgba.git
synced 2024-11-27 02:00:42 +00:00
Core: Fix up thread proxy waiting
This commit is contained in:
parent
de9bff4a29
commit
fdfab146a0
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user