mirror of
https://github.com/Hydr8gon/NooDS.git
synced 2025-04-02 11:11:57 -04:00
Threaded 2D: share work with the main thread instead of waiting
This commit is contained in:
parent
b49fb0ad84
commit
61687755cc
2 changed files with 41 additions and 22 deletions
61
src/gpu.cpp
61
src/gpu.cpp
|
@ -27,7 +27,7 @@ Gpu::Gpu(Core *core): core(core)
|
|||
{
|
||||
// Mark the thread as not drawing to start
|
||||
ready.store(true);
|
||||
drawing.store(false);
|
||||
drawing.store(0);
|
||||
|
||||
// Prepare tasks to be used with the scheduler
|
||||
gbaScanline240Task = std::bind(&Gpu::gbaScanline240, this);
|
||||
|
@ -110,12 +110,13 @@ void Gpu::gbaScanline240()
|
|||
{
|
||||
if (thread)
|
||||
{
|
||||
// Wait for the scanline to finish drawing
|
||||
while (drawing.load()) std::this_thread::yield();
|
||||
// Wait for the thread to finish the scanline
|
||||
while (drawing.load() != 0)
|
||||
std::this_thread::yield();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw visible scanlines
|
||||
// Draw the current scanline
|
||||
core->gpu2D[0].drawGbaScanline(vCount);
|
||||
}
|
||||
|
||||
|
@ -206,9 +207,9 @@ void Gpu::gbaScanline308()
|
|||
}
|
||||
}
|
||||
|
||||
// Signal that the next scanline has started
|
||||
// Signal that the next scanline should start drawing
|
||||
if (vCount < 160 && thread)
|
||||
drawing.store(true);
|
||||
drawing.store(1);
|
||||
|
||||
// Check if the current scanline matches the V-counter
|
||||
if (vCount == (dispStat[1] >> 8))
|
||||
|
@ -236,12 +237,26 @@ void Gpu::scanline256()
|
|||
{
|
||||
if (thread)
|
||||
{
|
||||
// Wait for the scanlines to finish drawing
|
||||
while (drawing.load()) std::this_thread::yield();
|
||||
// Make sure the thread has started before changing the state
|
||||
while (drawing.load() == 1)
|
||||
std::this_thread::yield();
|
||||
|
||||
switch (drawing.exchange(3))
|
||||
{
|
||||
case 2:
|
||||
// Draw engine B's scanline if it hasn't started yet (and purposely fall through)
|
||||
core->gpu2D[1].drawScanline(vCount);
|
||||
|
||||
case 3:
|
||||
// Wait for the thread to finish the scanlines
|
||||
while (drawing.load() != 0)
|
||||
std::this_thread::yield();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw visible scanlines
|
||||
// Draw the current scanlines
|
||||
core->gpu2D[0].drawScanline(vCount);
|
||||
core->gpu2D[1].drawScanline(vCount);
|
||||
}
|
||||
|
@ -461,9 +476,9 @@ void Gpu::scanline355()
|
|||
}
|
||||
}
|
||||
|
||||
// Signal that the next scanline has started
|
||||
// Signal that the next scanline should start drawing
|
||||
if (vCount < 192 && thread)
|
||||
drawing.store(true);
|
||||
drawing.store(1);
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
|
@ -495,18 +510,18 @@ void Gpu::drawGbaThreaded()
|
|||
{
|
||||
while (running)
|
||||
{
|
||||
// Wait until the next scanline starts
|
||||
while (!drawing.load())
|
||||
// Wait until the next scanline should start
|
||||
while (drawing.load() != 1)
|
||||
{
|
||||
if (!running) return;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// Draw the scanline
|
||||
// Draw the current scanline
|
||||
core->gpu2D[0].drawGbaScanline(vCount);
|
||||
|
||||
// Signal that the scanline is finished
|
||||
drawing.store(false);
|
||||
drawing.store(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,19 +529,23 @@ void Gpu::drawThreaded()
|
|||
{
|
||||
while (running)
|
||||
{
|
||||
// Wait until the next scanline starts
|
||||
while (!drawing.load())
|
||||
// Wait until the next scanline should start
|
||||
while (drawing.load() != 1)
|
||||
{
|
||||
if (!running) return;
|
||||
std::this_thread::yield();
|
||||
}
|
||||
|
||||
// Draw the scanlines
|
||||
// Draw engine A's scanline
|
||||
drawing.store(2);
|
||||
core->gpu2D[0].drawScanline(vCount);
|
||||
core->gpu2D[1].drawScanline(vCount);
|
||||
|
||||
// Signal that the scanline is finished
|
||||
drawing.store(false);
|
||||
// Draw engine B's scanline if it hasn't started yet
|
||||
if (drawing.exchange(3) == 2)
|
||||
core->gpu2D[1].drawScanline(vCount);
|
||||
|
||||
// Signal that the scanlines are finished
|
||||
drawing.store(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ class Gpu
|
|||
std::mutex mutex;
|
||||
|
||||
bool running = false;
|
||||
std::atomic<bool> drawing;
|
||||
std::atomic<int> drawing;
|
||||
std::thread *thread = nullptr;
|
||||
|
||||
bool displayCapture = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue