mirror of https://github.com/stella-emu/stella.git
Threaded Blargg + phosphor improvements:
- Handle case of only 1 or zero (!) reported cores - Fix memory leak by using smart pointers
This commit is contained in:
parent
6d1a306b52
commit
a29d1da57b
|
@ -36,8 +36,21 @@ void AtariNTSC::initialize(const Setup& setup, const uInt8* palette)
|
||||||
init(myImpl, setup);
|
init(myImpl, setup);
|
||||||
initializePalette(palette);
|
initializePalette(palette);
|
||||||
|
|
||||||
myNumThreads = std::min(4u, std::thread::hardware_concurrency());
|
uInt32 systemThreads = std::thread::hardware_concurrency();
|
||||||
myThreads = new std::thread[myNumThreads];
|
if(systemThreads <= 1)
|
||||||
|
{
|
||||||
|
myWorkerThreads = 0;
|
||||||
|
myTotalThreads = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
systemThreads = std::min(4u, systemThreads);
|
||||||
|
|
||||||
|
myWorkerThreads = systemThreads - 1;
|
||||||
|
myTotalThreads = systemThreads;
|
||||||
|
|
||||||
|
myThreads = make_unique<std::thread[]>(myWorkerThreads);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -69,35 +82,29 @@ void AtariNTSC::initializePalette(const uInt8* palette)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
void AtariNTSC::render(const uInt8* atari_in, const uInt32 in_width,
|
|
||||||
const uInt32 in_height, void* rgb_out, const uInt32 out_pitch)
|
|
||||||
{
|
|
||||||
// Spawn the threads...
|
|
||||||
for(uInt8 i = 0; i < myNumThreads; i++)
|
|
||||||
myThreads[i] = std::thread([=] {
|
|
||||||
renderThread(atari_in, in_width, in_height, myNumThreads, i, rgb_out, out_pitch);
|
|
||||||
});
|
|
||||||
// ...and make them join again
|
|
||||||
for(uInt8 i = 0; i < myNumThreads; i++)
|
|
||||||
myThreads[i].join();
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void AtariNTSC::render(const uInt8* atari_in, const uInt32 in_width, const uInt32 in_height,
|
void AtariNTSC::render(const uInt8* atari_in, const uInt32 in_width, const uInt32 in_height,
|
||||||
void* rgb_out, const uInt32 out_pitch, uInt32* rgb_in)
|
void* rgb_out, const uInt32 out_pitch, uInt32* rgb_in)
|
||||||
{
|
{
|
||||||
// Spawn the threads...
|
// Spawn the threads...
|
||||||
for(uInt8 i = 0; i < myNumThreads; i++)
|
for(uInt32 i = 0; i < myWorkerThreads; ++i)
|
||||||
|
{
|
||||||
myThreads[i] = std::thread([=] {
|
myThreads[i] = std::thread([=] {
|
||||||
renderWithPhosphorThread(atari_in, in_width, in_height, myNumThreads, i,
|
rgb_in == nullptr ?
|
||||||
rgb_in, rgb_out, out_pitch);
|
renderThread(atari_in, in_width, in_height, myTotalThreads, i+1, rgb_out, out_pitch) :
|
||||||
|
renderWithPhosphorThread(atari_in, in_width, in_height, myTotalThreads, i+1, rgb_in, rgb_out, out_pitch);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
// Make the main thread busy too
|
||||||
|
rgb_in == nullptr ?
|
||||||
|
renderThread(atari_in, in_width, in_height, myTotalThreads, 0, rgb_out, out_pitch) :
|
||||||
|
renderWithPhosphorThread(atari_in, in_width, in_height, myTotalThreads, 0, rgb_in, rgb_out, out_pitch);
|
||||||
// ...and make them join again
|
// ...and make them join again
|
||||||
for(uInt8 i = 0; i < myNumThreads; i++)
|
for(uInt32 i = 0; i < myWorkerThreads; ++i)
|
||||||
myThreads[i].join();
|
myThreads[i].join();
|
||||||
|
|
||||||
// Copy phosphor values into out buffer
|
// Copy phosphor values into out buffer
|
||||||
|
if(rgb_in != nullptr)
|
||||||
memcpy(rgb_out, rgb_in, in_height * out_pitch);
|
memcpy(rgb_out, rgb_in, in_height * out_pitch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -90,9 +90,7 @@ class AtariNTSC
|
||||||
// In_row_width is the number of pixels to get to the next input row.
|
// In_row_width is the number of pixels to get to the next input row.
|
||||||
// Out_pitch is the number of *bytes* to get to the next output row.
|
// Out_pitch is the number of *bytes* to get to the next output row.
|
||||||
void render(const uInt8* atari_in, const uInt32 in_width, const uInt32 in_height,
|
void render(const uInt8* atari_in, const uInt32 in_width, const uInt32 in_height,
|
||||||
void* rgb_out, const uInt32 out_pitch);
|
void* rgb_out, const uInt32 out_pitch, uInt32* rgb_in = nullptr);
|
||||||
void render(const uInt8* atari_in, const uInt32 in_width, const uInt32 in_height,
|
|
||||||
void* rgb_out, const uInt32 out_pitch, uInt32* rgb_in);
|
|
||||||
|
|
||||||
// Number of input pixels that will fit within given output width.
|
// Number of input pixels that will fit within given output width.
|
||||||
// Might be rounded down slightly; use outWidth() on result to find
|
// Might be rounded down slightly; use outWidth() on result to find
|
||||||
|
@ -165,9 +163,9 @@ class AtariNTSC
|
||||||
uInt8 myPhosphorPalette[256][256];
|
uInt8 myPhosphorPalette[256][256];
|
||||||
|
|
||||||
// Rendering threads
|
// Rendering threads
|
||||||
std::thread* myThreads;
|
unique_ptr<std::thread[]> myThreads;
|
||||||
// Number of rendering threads
|
// Number of rendering and total threads
|
||||||
uInt8 myNumThreads;
|
uInt32 myWorkerThreads, myTotalThreads;
|
||||||
|
|
||||||
struct init_t
|
struct init_t
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue