- Do various stability improvements.

task.cpp:
- Fix race condition on Windows.
- Do some minor code cleanup.
This commit is contained in:
rogerman 2013-01-16 23:38:47 +00:00
parent 39997cfebf
commit c15911a1b1
4 changed files with 51 additions and 30 deletions

View File

@ -1036,6 +1036,7 @@ static void OGLClose()
{ {
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
glDeleteBuffersARB(1, &vboVertexID); glDeleteBuffersARB(1, &vboVertexID);
isVBOSupported = false;
} }
if (isPBOSupported) if (isPBOSupported)
@ -1044,6 +1045,7 @@ static void OGLClose()
glDeleteBuffersARB(2, pboRenderDataID); glDeleteBuffersARB(2, pboRenderDataID);
pboRenderBuffer[0] = NULL; pboRenderBuffer[0] = NULL;
pboRenderBuffer[1] = NULL; pboRenderBuffer[1] = NULL;
isPBOSupported = false;
} }
// FBO // FBO
@ -1056,6 +1058,8 @@ static void OGLClose()
glDeleteFramebuffersEXT(1, &fboClearImageID); glDeleteFramebuffersEXT(1, &fboClearImageID);
glDeleteTextures(1, &texClearImageColorID); glDeleteTextures(1, &texClearImageColorID);
glDeleteTextures(1, &texClearImageDepthStencilID); glDeleteTextures(1, &texClearImageDepthStencilID);
isFBOSupported = false;
} }
//kill the tex cache to free all the texture ids //kill the tex cache to free all the texture ids
@ -1071,6 +1075,9 @@ static void OGLClose()
glDeleteTextures(1,&temp); glDeleteTextures(1,&temp);
} }
hasTexture = false;
currTexture = NULL;
glFinish(); glFinish();
ENDGL(); ENDGL();

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2006 yopyop Copyright (C) 2006 yopyop
Copyright (C) 2008-2012 DeSmuME team Copyright (C) 2008-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -2418,6 +2418,8 @@ SFORMAT SF_GFX3D[]={
//-------------savestate //-------------savestate
void gfx3d_savestate(EMUFILE* os) void gfx3d_savestate(EMUFILE* os)
{ {
gpu3D->NDS_3D_RenderFinish();
//version //version
write32le(4,os); write32le(4,os);

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2012 DeSmuME team Copyright (C) 2009-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -1073,7 +1073,7 @@ static SoftRasterizerEngine mainSoftRasterizer;
static Task rasterizerUnitTask[_MAX_CORES]; static Task rasterizerUnitTask[_MAX_CORES];
static RasterizerUnit<true> rasterizerUnit[_MAX_CORES]; static RasterizerUnit<true> rasterizerUnit[_MAX_CORES];
static RasterizerUnit<false> _HACK_viewer_rasterizerUnit; static RasterizerUnit<false> _HACK_viewer_rasterizerUnit;
static unsigned int rasterizerCores; static unsigned int rasterizerCores = 0;
static bool rasterizerUnitTasksInited = false; static bool rasterizerUnitTasksInited = false;
static void* execRasterizerUnit(void* arg) static void* execRasterizerUnit(void* arg)
@ -1629,6 +1629,15 @@ void _HACK_Viewer_ExecUnit(SoftRasterizerEngine* engine)
static void SoftRastRender() static void SoftRastRender()
{ {
// Force threads to finish before rendering with new data
if (rasterizerCores > 1)
{
for(unsigned int i = 0; i < rasterizerCores; i++)
{
rasterizerUnitTask[i].finish();
}
}
mainSoftRasterizer.polylist = gfx3d.polylist; mainSoftRasterizer.polylist = gfx3d.polylist;
mainSoftRasterizer.vertlist = gfx3d.vertlist; mainSoftRasterizer.vertlist = gfx3d.vertlist;
mainSoftRasterizer.indexlist = &gfx3d.indexlist; mainSoftRasterizer.indexlist = &gfx3d.indexlist;

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2011 DeSmuME team Copyright (C) 2009-2013 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -47,8 +47,8 @@ public:
void init(); void init();
//the work function that shall be executed //the work function that shall be executed
TWork work; TWork workFunc;
void* param; void* workFuncParam;
HANDLE incomingWork, workDone, hThread; HANDLE incomingWork, workDone, hThread;
volatile bool bIncomingWork, bWorkDone, bKill; volatile bool bIncomingWork, bWorkDone, bKill;
@ -67,7 +67,7 @@ Task::Impl::~Impl()
} }
Task::Impl::Impl() Task::Impl::Impl()
: work(NULL) : workFunc(NULL)
, bIncomingWork(false) , bIncomingWork(false)
, bWorkDone(true) , bWorkDone(true)
, bKill(false) , bKill(false)
@ -96,10 +96,10 @@ void Task::Impl::taskProc()
bIncomingWork = false; bIncomingWork = false;
//execute the work //execute the work
param = work(param); workFuncParam = workFunc(workFuncParam);
//signal completion //signal completion
if(!spinlock) SetEvent(workDone);
bWorkDone = true; bWorkDone = true;
if(!spinlock) SetEvent(workDone);
} }
} }
@ -134,8 +134,8 @@ void Task::Impl::shutdown()
void Task::Impl::execute(const TWork &work, void* param) void Task::Impl::execute(const TWork &work, void* param)
{ {
//setup the work //setup the work
this->work = work; this->workFunc = work;
this->param = param; this->workFuncParam = param;
bWorkDone = false; bWorkDone = false;
//signal it to start //signal it to start
if(!spinlock) SetEvent(incomingWork); if(!spinlock) SetEvent(incomingWork);
@ -145,15 +145,18 @@ void Task::Impl::execute(const TWork &work, void* param)
void* Task::Impl::finish() void* Task::Impl::finish()
{ {
//just wait for the work to be done //just wait for the work to be done
if(spinlock) if(spinlock)
while(!bWorkDone) {
while(!bWorkDone)
Sleep(0); Sleep(0);
}
else else
{ {
if(!bWorkDone) while(!bWorkDone)
WaitForSingleObject(workDone,INFINITE); WaitForSingleObject(workDone, INFINITE);
} }
return param;
return workFuncParam;
} }
#else #else
@ -174,8 +177,8 @@ public:
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t condWork; pthread_cond_t condWork;
TWork work; TWork workFunc;
void *param; void *workFuncParam;
void *ret; void *ret;
bool exitThread; bool exitThread;
}; };
@ -187,17 +190,17 @@ static void* taskProc(void *arg)
do { do {
pthread_mutex_lock(&ctx->mutex); pthread_mutex_lock(&ctx->mutex);
while (ctx->work == NULL && !ctx->exitThread) { while (ctx->workFunc == NULL && !ctx->exitThread) {
pthread_cond_wait(&ctx->condWork, &ctx->mutex); pthread_cond_wait(&ctx->condWork, &ctx->mutex);
} }
if (ctx->work != NULL) { if (ctx->workFunc != NULL) {
ctx->ret = ctx->work(ctx->param); ctx->ret = ctx->workFunc(ctx->workFuncParam);
} else { } else {
ctx->ret = NULL; ctx->ret = NULL;
} }
ctx->work = NULL; ctx->workFunc = NULL;
pthread_cond_signal(&ctx->condWork); pthread_cond_signal(&ctx->condWork);
pthread_mutex_unlock(&ctx->mutex); pthread_mutex_unlock(&ctx->mutex);
@ -210,8 +213,8 @@ static void* taskProc(void *arg)
Task::Impl::Impl() Task::Impl::Impl()
{ {
_isThreadRunning = false; _isThreadRunning = false;
work = NULL; workFunc = NULL;
param = NULL; workFuncParam = NULL;
ret = NULL; ret = NULL;
exitThread = false; exitThread = false;
@ -235,8 +238,8 @@ void Task::Impl::start(bool spinlock)
return; return;
} }
this->work = NULL; this->workFunc = NULL;
this->param = NULL; this->workFuncParam = NULL;
this->ret = NULL; this->ret = NULL;
this->exitThread = false; this->exitThread = false;
pthread_create(&this->_thread, NULL, &taskProc, this); pthread_create(&this->_thread, NULL, &taskProc, this);
@ -254,8 +257,8 @@ void Task::Impl::execute(const TWork &work, void *param)
return; return;
} }
this->work = work; this->workFunc = work;
this->param = param; this->workFuncParam = param;
pthread_cond_signal(&this->condWork); pthread_cond_signal(&this->condWork);
pthread_mutex_unlock(&this->mutex); pthread_mutex_unlock(&this->mutex);
@ -272,7 +275,7 @@ void* Task::Impl::finish()
return returnValue; return returnValue;
} }
while (this->work != NULL) { while (this->workFunc != NULL) {
pthread_cond_wait(&this->condWork, &this->mutex); pthread_cond_wait(&this->condWork, &this->mutex);
} }
@ -292,7 +295,7 @@ void Task::Impl::shutdown()
return; return;
} }
this->work = NULL; this->workFunc = NULL;
this->exitThread = true; this->exitThread = true;
pthread_cond_signal(&this->condWork); pthread_cond_signal(&this->condWork);