From c15911a1b13962a895e9c47bf77c7a3f9b41abdb Mon Sep 17 00:00:00 2001 From: rogerman Date: Wed, 16 Jan 2013 23:38:47 +0000 Subject: [PATCH] GFX3D: - Do various stability improvements. task.cpp: - Fix race condition on Windows. - Do some minor code cleanup. --- desmume/src/OGLRender.cpp | 7 +++++ desmume/src/gfx3d.cpp | 4 ++- desmume/src/rasterize.cpp | 13 +++++++-- desmume/src/utils/task.cpp | 57 ++++++++++++++++++++------------------ 4 files changed, 51 insertions(+), 30 deletions(-) diff --git a/desmume/src/OGLRender.cpp b/desmume/src/OGLRender.cpp index 10529eb8a..02a30567f 100644 --- a/desmume/src/OGLRender.cpp +++ b/desmume/src/OGLRender.cpp @@ -1036,6 +1036,7 @@ static void OGLClose() { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); glDeleteBuffersARB(1, &vboVertexID); + isVBOSupported = false; } if (isPBOSupported) @@ -1044,6 +1045,7 @@ static void OGLClose() glDeleteBuffersARB(2, pboRenderDataID); pboRenderBuffer[0] = NULL; pboRenderBuffer[1] = NULL; + isPBOSupported = false; } // FBO @@ -1056,6 +1058,8 @@ static void OGLClose() glDeleteFramebuffersEXT(1, &fboClearImageID); glDeleteTextures(1, &texClearImageColorID); glDeleteTextures(1, &texClearImageDepthStencilID); + + isFBOSupported = false; } //kill the tex cache to free all the texture ids @@ -1071,6 +1075,9 @@ static void OGLClose() glDeleteTextures(1,&temp); } + hasTexture = false; + currTexture = NULL; + glFinish(); ENDGL(); diff --git a/desmume/src/gfx3d.cpp b/desmume/src/gfx3d.cpp index 30c089fc9..4a58055ab 100644 --- a/desmume/src/gfx3d.cpp +++ b/desmume/src/gfx3d.cpp @@ -1,6 +1,6 @@ /* 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 it under the terms of the GNU General Public License as published by @@ -2418,6 +2418,8 @@ SFORMAT SF_GFX3D[]={ //-------------savestate void gfx3d_savestate(EMUFILE* os) { + gpu3D->NDS_3D_RenderFinish(); + //version write32le(4,os); diff --git a/desmume/src/rasterize.cpp b/desmume/src/rasterize.cpp index ac892152e..c7cde76d5 100644 --- a/desmume/src/rasterize.cpp +++ b/desmume/src/rasterize.cpp @@ -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 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 RasterizerUnit rasterizerUnit[_MAX_CORES]; static RasterizerUnit _HACK_viewer_rasterizerUnit; -static unsigned int rasterizerCores; +static unsigned int rasterizerCores = 0; static bool rasterizerUnitTasksInited = false; static void* execRasterizerUnit(void* arg) @@ -1629,6 +1629,15 @@ void _HACK_Viewer_ExecUnit(SoftRasterizerEngine* engine) 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.vertlist = gfx3d.vertlist; mainSoftRasterizer.indexlist = &gfx3d.indexlist; diff --git a/desmume/src/utils/task.cpp b/desmume/src/utils/task.cpp index 31bc7509a..e8ff73c8a 100644 --- a/desmume/src/utils/task.cpp +++ b/desmume/src/utils/task.cpp @@ -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 it under the terms of the GNU General Public License as published by @@ -47,8 +47,8 @@ public: void init(); //the work function that shall be executed - TWork work; - void* param; + TWork workFunc; + void* workFuncParam; HANDLE incomingWork, workDone, hThread; volatile bool bIncomingWork, bWorkDone, bKill; @@ -67,7 +67,7 @@ Task::Impl::~Impl() } Task::Impl::Impl() - : work(NULL) + : workFunc(NULL) , bIncomingWork(false) , bWorkDone(true) , bKill(false) @@ -96,10 +96,10 @@ void Task::Impl::taskProc() bIncomingWork = false; //execute the work - param = work(param); + workFuncParam = workFunc(workFuncParam); //signal completion - if(!spinlock) SetEvent(workDone); bWorkDone = true; + if(!spinlock) SetEvent(workDone); } } @@ -134,8 +134,8 @@ void Task::Impl::shutdown() void Task::Impl::execute(const TWork &work, void* param) { //setup the work - this->work = work; - this->param = param; + this->workFunc = work; + this->workFuncParam = param; bWorkDone = false; //signal it to start if(!spinlock) SetEvent(incomingWork); @@ -145,15 +145,18 @@ void Task::Impl::execute(const TWork &work, void* param) void* Task::Impl::finish() { //just wait for the work to be done - if(spinlock) - while(!bWorkDone) + if(spinlock) + { + while(!bWorkDone) Sleep(0); + } else { - if(!bWorkDone) - WaitForSingleObject(workDone,INFINITE); + while(!bWorkDone) + WaitForSingleObject(workDone, INFINITE); } - return param; + + return workFuncParam; } #else @@ -174,8 +177,8 @@ public: pthread_mutex_t mutex; pthread_cond_t condWork; - TWork work; - void *param; + TWork workFunc; + void *workFuncParam; void *ret; bool exitThread; }; @@ -187,17 +190,17 @@ static void* taskProc(void *arg) do { pthread_mutex_lock(&ctx->mutex); - while (ctx->work == NULL && !ctx->exitThread) { + while (ctx->workFunc == NULL && !ctx->exitThread) { pthread_cond_wait(&ctx->condWork, &ctx->mutex); } - if (ctx->work != NULL) { - ctx->ret = ctx->work(ctx->param); + if (ctx->workFunc != NULL) { + ctx->ret = ctx->workFunc(ctx->workFuncParam); } else { ctx->ret = NULL; } - ctx->work = NULL; + ctx->workFunc = NULL; pthread_cond_signal(&ctx->condWork); pthread_mutex_unlock(&ctx->mutex); @@ -210,8 +213,8 @@ static void* taskProc(void *arg) Task::Impl::Impl() { _isThreadRunning = false; - work = NULL; - param = NULL; + workFunc = NULL; + workFuncParam = NULL; ret = NULL; exitThread = false; @@ -235,8 +238,8 @@ void Task::Impl::start(bool spinlock) return; } - this->work = NULL; - this->param = NULL; + this->workFunc = NULL; + this->workFuncParam = NULL; this->ret = NULL; this->exitThread = false; pthread_create(&this->_thread, NULL, &taskProc, this); @@ -254,8 +257,8 @@ void Task::Impl::execute(const TWork &work, void *param) return; } - this->work = work; - this->param = param; + this->workFunc = work; + this->workFuncParam = param; pthread_cond_signal(&this->condWork); pthread_mutex_unlock(&this->mutex); @@ -272,7 +275,7 @@ void* Task::Impl::finish() return returnValue; } - while (this->work != NULL) { + while (this->workFunc != NULL) { pthread_cond_wait(&this->condWork, &this->mutex); } @@ -292,7 +295,7 @@ void Task::Impl::shutdown() return; } - this->work = NULL; + this->workFunc = NULL; this->exitThread = true; pthread_cond_signal(&this->condWork);