// derived values (DPSOFTRAST_VALIDATE_BLENDFUNC)
int fb_blendmode;
- ATOMIC(int commandoffset);
+ ATOMIC(volatile int commandoffset);
- bool waiting;
+ volatile bool waiting;
+ volatile bool starving;
#ifdef USE_THREADS
SDL_cond *waitcond;
+ SDL_cond *drawcond;
+ SDL_mutex *drawmutex;
#endif
int numspans;
int numthreads;
DPSOFTRAST_State_Thread *threads;
-#ifdef USE_THREADS
- SDL_mutex *drawmutex;
- SDL_cond *drawcond;
-#endif
- ATOMIC(int drawcommand);
+ ATOMIC(volatile int drawcommand);
DPSOFTRAST_State_Command_Pool commandpool;
}
DPSOFTRAST_State dpsoftrast;
-extern int dpsoftrast_test;
-
#define DPSOFTRAST_DEPTHSCALE (1024.0f*1048576.0f)
#define DPSOFTRAST_DEPTHOFFSET (128.0f)
#define DPSOFTRAST_BGRA8_FROM_RGBA32F(r,g,b,a) (((int)(r * 255.0f + 0.5f) << 16) | ((int)(g * 255.0f + 0.5f) << 8) | (int)(b * 255.0f + 0.5f) | ((int)(a * 255.0f + 0.5f) << 24))
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space)
return;
DPSOFTRAST_Draw_SyncCommands();
- SDL_LockMutex(dpsoftrast.drawmutex);
for(;;)
{
int waitindex = -1;
if (usedcommands <= DPSOFTRAST_DRAW_MAXCOMMANDPOOL-space || waitindex < 0)
break;
thread = &dpsoftrast.threads[waitindex];
- thread->waiting = true;
- SDL_CondBroadcast(dpsoftrast.drawcond);
- SDL_CondWait(thread->waitcond, dpsoftrast.drawmutex);
- thread->waiting = false;
+ SDL_LockMutex(thread->drawmutex);
+ if (thread->commandoffset != dpsoftrast.drawcommand)
+ {
+ thread->waiting = true;
+ if (thread->starving) SDL_CondSignal(thread->drawcond);
+ SDL_CondWait(thread->waitcond, thread->drawmutex);
+ thread->waiting = false;
+ }
+ SDL_UnlockMutex(thread->drawmutex);
}
- SDL_UnlockMutex(dpsoftrast.drawmutex);
dpsoftrast.commandpool.usedcommands = usedcommands;
#else
DPSOFTRAST_Draw_FlushThreads();
#ifdef USE_THREADS
DPSOFTRAST_Draw_SyncCommands();
- //SDL_LockMutex(dpsoftrast.drawmutex);
- SDL_CondBroadcast(dpsoftrast.drawcond);
- //SDL_UnlockMutex(dpsoftrast.drawmutex);
+ {
+ int i;
+ int nexty = 0;
+ for (i = 0; i < dpsoftrast.numthreads; i++)
+ {
+ DPSOFTRAST_State_Thread *thread = &dpsoftrast.threads[i];
+ int y = nexty;
+ nexty = ((i+1)*dpsoftrast.fb_height)/dpsoftrast.numthreads;
+ if (command->starty < nexty && command->endy > y && thread->starving)
+ SDL_CondSignal(thread->drawcond);
+ }
+ }
#else
DPSOFTRAST_Draw_FlushThreads();
#endif
}
else
{
- SDL_LockMutex(dpsoftrast.drawmutex);
- if (thread->commandoffset != dpsoftrast.drawcommand)
+ SDL_LockMutex(thread->drawmutex);
+ if (thread->commandoffset == dpsoftrast.drawcommand && thread->index >= 0)
{
- SDL_UnlockMutex(dpsoftrast.drawmutex);
- continue;
+ if (thread->waiting) SDL_CondSignal(thread->waitcond);
+ thread->starving = true;
+ SDL_CondWait(thread->drawcond, thread->drawmutex);
+ thread->starving = false;
}
- if (thread->waiting) SDL_CondSignal(thread->waitcond);
- SDL_CondWait(dpsoftrast.drawcond, dpsoftrast.drawmutex);
- SDL_UnlockMutex(dpsoftrast.drawmutex);
+ SDL_UnlockMutex(thread->drawmutex);
}
}
return 0;
int i;
DPSOFTRAST_Draw_SyncCommands();
#ifdef USE_THREADS
- SDL_LockMutex(dpsoftrast.drawmutex);
-#endif
+ for (i = 0; i < dpsoftrast.numthreads; i++)
+ {
+ thread = &dpsoftrast.threads[i];
+ if (thread->commandoffset != dpsoftrast.drawcommand)
+ {
+ SDL_LockMutex(thread->drawmutex);
+ if (thread->commandoffset != dpsoftrast.drawcommand && thread->starving)
+ SDL_CondSignal(thread->drawcond);
+ SDL_UnlockMutex(thread->drawmutex);
+ }
+ }
+#endif
for (i = 0; i < dpsoftrast.numthreads; i++)
{
thread = &dpsoftrast.threads[i];
#ifdef USE_THREADS
- while (thread->commandoffset != dpsoftrast.drawcommand)
+ if (thread->commandoffset != dpsoftrast.drawcommand)
{
- thread->waiting = true;
- SDL_CondBroadcast(dpsoftrast.drawcond);
- SDL_CondWait(thread->waitcond, dpsoftrast.drawmutex);
- thread->waiting = false;
+ SDL_LockMutex(thread->drawmutex);
+ if (thread->commandoffset != dpsoftrast.drawcommand)
+ {
+ thread->waiting = true;
+ SDL_CondWait(thread->waitcond, thread->drawmutex);
+ thread->waiting = false;
+ }
+ SDL_UnlockMutex(thread->drawmutex);
}
#else
if (thread->commandoffset != dpsoftrast.drawcommand)
DPSOFTRAST_Draw_InterpretCommands(thread, dpsoftrast.drawcommand);
#endif
}
-#ifdef USE_THREADS
- SDL_UnlockMutex(dpsoftrast.drawmutex);
-#endif
dpsoftrast.commandpool.usedcommands = 0;
}
dpsoftrast.color[3] = 1;
#ifdef USE_THREADS
dpsoftrast.numthreads = bound(1, numthreads, 64);
- dpsoftrast.drawmutex = SDL_CreateMutex();
- dpsoftrast.drawcond = SDL_CreateCond();
#else
dpsoftrast.numthreads = 1;
#endif
thread->numtriangles = 0;
thread->commandoffset = 0;
thread->waiting = false;
+ thread->starving = false;
#ifdef USE_THREADS
thread->waitcond = SDL_CreateCond();
+ thread->drawcond = SDL_CreateCond();
+ thread->drawmutex = SDL_CreateMutex();
#endif
thread->validate = -1;
if(dpsoftrast.numthreads > 0)
{
DPSOFTRAST_State_Thread *thread;
- SDL_LockMutex(dpsoftrast.drawmutex);
for (i = 0; i < dpsoftrast.numthreads; i++)
{
thread = &dpsoftrast.threads[i];
+ SDL_LockMutex(thread->drawmutex);
thread->index = -1;
- }
- SDL_CondBroadcast(dpsoftrast.drawcond);
- SDL_UnlockMutex(dpsoftrast.drawmutex);
- for (i = 0; i < dpsoftrast.numthreads; i++)
- {
- thread = &dpsoftrast.threads[i];
+ SDL_CondSignal(thread->drawcond);
+ SDL_UnlockMutex(thread->drawmutex);
SDL_WaitThread(thread->thread, NULL);
SDL_DestroyCond(thread->waitcond);
+ SDL_DestroyCond(thread->drawcond);
+ SDL_DestroyMutex(thread->drawmutex);
}
- SDL_DestroyMutex(dpsoftrast.drawmutex);
- SDL_DestroyCond(dpsoftrast.drawcond);
}
#endif
for (i = 0;i < dpsoftrast.texture_end;i++)