diff options
author | bohu <bohu@google.com> | 2014-10-28 17:08:44 -0700 |
---|---|---|
committer | bohu <bohu@google.com> | 2014-10-28 17:08:44 -0700 |
commit | bc42a0598f6e5ffb0ebd646e0bad8d94c50ec193 (patch) | |
tree | 12e8fa1a09c30aff5536d40e372e2c0c9b0df1f7 /emulator | |
parent | cf7e8c7948b3b811a6693ac871d2578a2bdf0a46 (diff) | |
download | sdk-bc42a0598f6e5ffb0ebd646e0bad8d94c50ec193.zip sdk-bc42a0598f6e5ffb0ebd646e0bad8d94c50ec193.tar.gz sdk-bc42a0598f6e5ffb0ebd646e0bad8d94c50ec193.tar.bz2 |
Properly handle shader deletion
When deleting a shader that is still attached to program,
it should not be deleted immediately. Instead, it should
be marked for deletion.
When a program is deleted, its shaders should be detached.
When a shader is detached, it should be deleted if it is
marked for deletion.
Change-Id: I481dbfe37e3ad4af454574b75d157bdfeb1c9cdd
Diffstat (limited to 'emulator')
3 files changed, 61 insertions, 3 deletions
diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp index fe64f6f..706de36 100644 --- a/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp +++ b/emulator/opengl/host/libs/Translator/GLES_V2/GLESv2Imp.cpp @@ -116,6 +116,27 @@ GL_APICALL GLESiface* __translator_getIfaces(EGLiface* eglIface){ } +static void s_attachShader(GLEScontext* ctx, GLuint program, GLuint shader) { + if (ctx && program && shader && ctx->shareGroup().Ptr()) { + ObjectDataPtr shaderData = ctx->shareGroup()->getObjectData(SHADER,shader); + if (!shaderData.Ptr()) return; + ShaderParser* shaderParser = (ShaderParser*)shaderData.Ptr(); + shaderParser->setAttachedProgram(program); + } +} + +static void s_detachShader(GLEScontext* ctx, GLuint shader) { + if (ctx && shader && ctx->shareGroup().Ptr()) { + ObjectDataPtr shaderData = ctx->shareGroup()->getObjectData(SHADER,shader); + if (!shaderData.Ptr()) return; + ShaderParser* shaderParser = (ShaderParser*)shaderData.Ptr(); + shaderParser->setAttachedProgram(0); + if (shaderParser->getDeleteStatus()) { + ctx->shareGroup()->deleteName(SHADER, shader); + } + } +} + static ObjectLocalName TextureLocalName(GLenum target,unsigned int tex) { GET_CTX_RET(0); return (tex!=0? tex : ctx->getDefaultTextureName(target)); @@ -165,6 +186,7 @@ GL_APICALL void GL_APIENTRY glAttachShader(GLuint program, GLuint shader){ ProgramData* pData = (ProgramData*)programData.Ptr(); SET_ERROR_IF((pData->getAttachedShader(shaderType)!=0), GL_INVALID_OPERATION); pData->attachShader(shader,shaderType); + s_attachShader(ctx, program, shader); ctx->dispatcher().glAttachShader(globalProgramName,globalShaderName); } } @@ -493,6 +515,12 @@ GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program){ if(program && ctx->shareGroup().Ptr()) { const GLuint globalProgramName = ctx->shareGroup()->getGlobalName(SHADER,program); SET_ERROR_IF(!globalProgramName, GL_INVALID_VALUE); + + ObjectDataPtr programData = ctx->shareGroup()->getObjectData(SHADER,program); + ProgramData* pData = (ProgramData*)programData.Ptr(); + s_detachShader(ctx, pData->getAttachedVertexShader()); + s_detachShader(ctx, pData->getAttachedFragmentShader()); + ctx->shareGroup()->deleteName(SHADER,program); ctx->dispatcher().glDeleteProgram(globalProgramName); } @@ -503,7 +531,15 @@ GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader){ if(shader && ctx->shareGroup().Ptr()) { const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader); SET_ERROR_IF(!globalShaderName, GL_INVALID_VALUE); - ctx->shareGroup()->deleteName(SHADER,shader); + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader); + SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_OPERATION); + SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION); + ShaderParser* sp = (ShaderParser*)objData.Ptr(); + if (sp->getAttachedProgram()) { + sp->setDeleteStatus(true); + } else { + ctx->shareGroup()->deleteName(SHADER,shader); + } ctx->dispatcher().glDeleteShader(globalShaderName); } @@ -538,6 +574,8 @@ GL_APICALL void GL_APIENTRY glDetachShader(GLuint program, GLuint shader){ SET_ERROR_IF(!programData->isAttached(shader),GL_INVALID_OPERATION); programData->detachShader(shader); + s_detachShader(ctx, shader); + ctx->dispatcher().glDetachShader(globalProgramName,globalShaderName); } } @@ -1221,6 +1259,15 @@ GL_APICALL void GL_APIENTRY glGetShaderiv(GLuint shader, GLenum pname, GLint* p GET_CTX(); if(ctx->shareGroup().Ptr()) { const GLuint globalShaderName = ctx->shareGroup()->getGlobalName(SHADER,shader); + if (pname == GL_DELETE_STATUS) { + SET_ERROR_IF(globalShaderName == 0, GL_INVALID_VALUE); + ObjectDataPtr objData = ctx->shareGroup()->getObjectData(SHADER,shader); + SET_ERROR_IF(!objData.Ptr() ,GL_INVALID_VALUE); + SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_VALUE); + ShaderParser* sp = (ShaderParser*)objData.Ptr(); + params[0] = (sp->getDeleteStatus()) ? GL_TRUE : GL_FALSE; + return; + } SET_ERROR_IF(globalShaderName==0, GL_INVALID_VALUE); switch(pname) { case GL_INFO_LOG_LENGTH: diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp b/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp index 9bbedbf..ca17514 100644 --- a/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp +++ b/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp @@ -21,7 +21,9 @@ ShaderParser::ShaderParser():ObjectData(SHADER_DATA), m_type(0), m_originalSrc(NULL), - m_parsedLines(NULL) { + m_parsedLines(NULL), + m_deleteStatus(false), + m_program(0) { m_infoLog = new GLchar[1]; m_infoLog[0] = '\0'; }; @@ -29,7 +31,9 @@ ShaderParser::ShaderParser():ObjectData(SHADER_DATA), ShaderParser::ShaderParser(GLenum type):ObjectData(SHADER_DATA), m_type(type), m_originalSrc(NULL), - m_parsedLines(NULL) { + m_parsedLines(NULL), + m_deleteStatus(false), + m_program(0) { m_infoLog = new GLchar[1]; m_infoLog[0] = '\0'; diff --git a/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h b/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h index 7b538c3..6da5476 100644 --- a/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h +++ b/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h @@ -35,6 +35,11 @@ public: void setInfoLog(GLchar * infoLog); GLchar* getInfoLog(); + void setDeleteStatus(bool val) { m_deleteStatus = val; } + bool getDeleteStatus() const { return m_deleteStatus; } + + void setAttachedProgram(GLuint program) { m_program = program; } + GLuint getAttachedProgram() const { return m_program; } private: void parseOriginalSrc(); void parseGLSLversion(); @@ -50,5 +55,7 @@ private: std::string m_parsedSrc; GLchar* m_parsedLines; GLchar* m_infoLog; + bool m_deleteStatus; + GLuint m_program; }; #endif |