From 9b3c3647baf41e15cf9564df4b974162a7135873 Mon Sep 17 00:00:00 2001 From: bohu Date: Thu, 6 Nov 2014 14:40:19 -0800 Subject: Properly handle shader program deletion When deleting a program that is still in use, its delete status should set to true and the actual deletion should happen later when the program is not in use. Change-Id: I821312997d372ed4773033ba373a8c792f6d7ba9 --- .../host/libs/Translator/GLES_V2/GLESv2Imp.cpp | 32 ++++++++++++++++++++++ .../host/libs/Translator/GLES_V2/ProgramData.cpp | 4 ++- .../host/libs/Translator/GLES_V2/ProgramData.h | 7 +++++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'emulator') diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp index 45b39d5..ade6e34 100644 --- a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp +++ b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp @@ -546,6 +546,10 @@ GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program){ ObjectDataPtr programData = ctx->shareGroup()->getObjectData(SHADER,program); ProgramData* pData = (ProgramData*)programData.Ptr(); + if (pData && pData->isInUse()) { + pData->setDeleteStatus(true); + return; + } s_detachShader(ctx, pData->getAttachedVertexShader()); s_detachShader(ctx, pData->getAttachedFragmentShader()); @@ -1215,6 +1219,15 @@ GL_APICALL void GL_APIENTRY glGetProgramiv(GLuint program, GLenum pname, GLint* const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program); SET_ERROR_IF(globalProgramName==0, GL_INVALID_VALUE); switch(pname) { + case GL_DELETE_STATUS: + { + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program); + SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION); + SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION); + ProgramData* programData = (ProgramData*)objData.Ptr(); + params[0] = programData->getDeleteStatus() ? GL_TRUE : GL_FALSE; + } + break; case GL_LINK_STATUS: { ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program); @@ -1991,6 +2004,19 @@ GL_APICALL void GL_APIENTRY glUniformMatrix4fv(GLint location, GLsizei count, G ctx->dispatcher().glUniformMatrix4fv(location,count,transpose,value); } +static void s_unUseCurrentProgram() { + GET_CTX(); + GLint localCurrentProgram = 0; + glGetIntegerv(GL_CURRENT_PROGRAM, &localCurrentProgram); + if (!localCurrentProgram) return; + + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,localCurrentProgram); + SET_ERROR_IF(objData.Ptr()->getDataType()!=PROGRAM_DATA,GL_INVALID_OPERATION); + ProgramData* programData = (ProgramData*)objData.Ptr(); + programData->setInUse(false); + if (programData->getDeleteStatus()) { glDeleteProgram(localCurrentProgram); } +} + GL_APICALL void GL_APIENTRY glUseProgram(GLuint program){ GET_CTX(); if(ctx->shareGroup().Ptr()) { @@ -1998,6 +2024,12 @@ GL_APICALL void GL_APIENTRY glUseProgram(GLuint program){ SET_ERROR_IF(program!=0 && globalProgramName==0,GL_INVALID_VALUE); ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,program); SET_ERROR_IF(objData.Ptr() && (objData.Ptr()->getDataType()!=PROGRAM_DATA),GL_INVALID_OPERATION); + + s_unUseCurrentProgram(); + + ProgramData* programData = (ProgramData*)objData.Ptr(); + if (programData) programData->setInUse(true); + ctx->dispatcher().glUseProgram(globalProgramName); } } diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp index 656c782..b008e91 100644 --- a/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp +++ b/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.cpp @@ -20,7 +20,9 @@ ProgramData::ProgramData() : ObjectData(PROGRAM_DATA), AttachedVertexShader(0), AttachedFragmentShader(0), - LinkStatus(GL_FALSE) { + LinkStatus(GL_FALSE), + IsInUse(false), + DeleteStatus(false) { infoLog = new GLchar[1]; infoLog[0] = '\0'; } diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h b/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h index a79574a..7ce5801 100644 --- a/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h +++ b/emulator/opengl/host/libs/Translator/GLES_V2/ProgramData.h @@ -35,10 +35,17 @@ public: void setInfoLog(GLchar *log); GLchar* getInfoLog(); + bool isInUse() const { return IsInUse; } + void setInUse(bool inUse) { IsInUse = inUse; } + + bool getDeleteStatus() const { return DeleteStatus; } + void setDeleteStatus(bool status) { DeleteStatus = status; } private: GLuint AttachedVertexShader; GLuint AttachedFragmentShader; GLint LinkStatus; GLchar* infoLog; + bool IsInUse; + bool DeleteStatus; }; #endif -- cgit v1.1