diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp index f46889b3d..ff48c9d6a 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp @@ -45,19 +45,30 @@ void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type m_Indexes[index].base = base; m_Indexes[index].size = size; m_Indexes[index].type = type; + if (index > 0) { + m_Indexes[index].appBase = m_Indexes[index-1].appBase + + m_Indexes[index-1].size; + } + else { + m_Indexes[index].appBase = 0; + } + m_Indexes[index].hostLocsPerElement = 1; } GLuint ProgramData::getIndexForLocation(GLint location) { - GLuint i=0; - for (i=0;i= low && location < high) - break; + GLint dist = location - m_Indexes[i].base; + if (dist >= 0 && + (minDist < 0 || dist < minDist)) { + index = i; + minDist = dist; + } } - return i; + return index; } GLenum ProgramData::getTypeForLocation(GLint location) @@ -72,24 +83,44 @@ GLenum ProgramData::getTypeForLocation(GLint location) void ProgramData::setupLocationShiftWAR() { m_locShiftWAR = false; - for (int i=0; i 1) { + m_locShiftWAR = true; + } } -GLint ProgramData::locationWARHostToApp(GLint hostLoc) +GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex) { - if (m_locShiftWAR && hostLoc>0) return hostLoc>>16; - else return hostLoc; + if (!m_locShiftWAR) return hostLoc; + + GLuint index = getIndexForLocation(hostLoc); + if (index 0) { + m_Indexes[index].hostLocsPerElement = + (hostLoc - m_Indexes[index].base) / arrIndex; + } + return m_Indexes[index].appBase + arrIndex; + } + return -1; } GLint ProgramData::locationWARAppToHost(GLint appLoc) { - if (m_locShiftWAR && appLoc>0) return appLoc<<16; - else return appLoc; + if (!m_locShiftWAR) return appLoc; + + for(GLuint i=0; i= 0 && elemIndex < m_Indexes[i].size) { + return m_Indexes[i].base + + elemIndex * m_Indexes[i].hostLocsPerElement; + } + } + return -1; } @@ -222,11 +253,11 @@ void GLSharedGroup::setupLocationShiftWAR(GLuint program) if (pData) pData->setupLocationShiftWAR(); } -GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc) +GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex) { android::AutoMutex _lock(m_lock); ProgramData* pData = m_programs.valueFor(program); - if (pData) return pData->locationWARHostToApp(hostLoc); + if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex); else return hostLoc; } @@ -238,6 +269,14 @@ GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc) else return appLoc; } +bool GLSharedGroup::needUniformLocationWAR(GLuint program) +{ + android::AutoMutex _lock(m_lock); + ProgramData* pData = m_programs.valueFor(program); + if (pData) return pData->needUniformLocationWAR(); + return false; +} + void GLSharedGroup::addShaderData(GLuint shader) { diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h index 2443562bc..7104550d1 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h @@ -49,7 +49,9 @@ private: GLint base; GLint size; GLenum type; - }IndexInfo; + GLint appBase; + GLint hostLocsPerElement; + } IndexInfo; GLuint m_numIndexes; IndexInfo* m_Indexes; @@ -64,8 +66,9 @@ public: GLuint getIndexForLocation(GLint location); GLenum getTypeForLocation(GLint location); + bool needUniformLocationWAR() const { return m_locShiftWAR; } void setupLocationShiftWAR(); - GLint locationWARHostToApp(GLint hostLoc); + GLint locationWARHostToApp(GLint hostLoc, GLint arrIndex); GLint locationWARAppToHost(GLint appLoc); }; @@ -93,8 +96,9 @@ public: void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type); GLenum getProgramUniformType(GLuint program, GLint location); void setupLocationShiftWAR(GLuint program); - GLint locationWARHostToApp(GLuint program, GLint hostLoc); + GLint locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex); GLint locationWARAppToHost(GLuint program, GLint appLoc); + bool needUniformLocationWAR(GLuint program); void addShaderData(GLuint shader); bool isShader(GLuint shader); diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp index 5781dd4fe..61b19c1f6 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -534,9 +534,30 @@ void GL2Encoder::s_glDeleteShader(void *self, GLenum shader) int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name) { + if (!name) return -1; + GL2Encoder *ctx = (GL2Encoder*)self; + + // if we need the uniform location WAR + // parse array index from the end of the name string + int arrIndex = 0; + bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program); + if (needLocationWAR) { + int namelen = strlen(name); + if (name[namelen-1] == ']') { + char *brace = strrchr(name,'['); + if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) { + return -1; + } + + } + } + int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name); - return ctx->m_shared->locationWARHostToApp(program, hostLoc); + if (hostLoc >= 0 && needLocationWAR) { + return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex); + } + return hostLoc; } void GL2Encoder::s_glUseProgram(void *self, GLuint program)