diff options
Diffstat (limited to 'tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp')
| -rw-r--r-- | tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp | 205 |
1 files changed, 180 insertions, 25 deletions
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp index ff48c9d6a..8504f7f78 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp @@ -1,3 +1,19 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + #include "GLSharedGroup.h" /**** BufferData ****/ @@ -53,6 +69,15 @@ void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type m_Indexes[index].appBase = 0; } m_Indexes[index].hostLocsPerElement = 1; + m_Indexes[index].flags = 0; + m_Indexes[index].samplerValue = 0; +} + +void ProgramData::setIndexFlags(GLuint index, GLuint flags) +{ + if (index >= m_numIndexes) + return; + m_Indexes[index].flags |= flags; } GLuint ProgramData::getIndexForLocation(GLint location) @@ -123,13 +148,77 @@ GLint ProgramData::locationWARAppToHost(GLint appLoc) return -1; } +GLint ProgramData::getNextSamplerUniform(GLint index, GLint* val, GLenum* target) +{ + for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) { + if (m_Indexes[i].type == GL_SAMPLER_2D) { + if (val) *val = m_Indexes[i].samplerValue; + if (target) { + if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) { + *target = GL_TEXTURE_EXTERNAL_OES; + } else { + *target = GL_TEXTURE_2D; + } + } + return i; + } + } + return -1; +} + +bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target) +{ + for (GLuint i = 0; i < m_numIndexes; i++) { + GLint elemIndex = appLoc - m_Indexes[i].appBase; + if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) { + if (m_Indexes[i].type == GL_TEXTURE_2D) { + m_Indexes[i].samplerValue = val; + if (target) { + if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) { + *target = GL_TEXTURE_EXTERNAL_OES; + } else { + *target = GL_TEXTURE_2D; + } + } + return true; + } + } + } + return false; +} + +bool ProgramData::attachShader(GLuint shader) +{ + size_t n = m_shaders.size(); + for (size_t i = 0; i < n; i++) { + if (m_shaders[i] == shader) { + return false; + } + } + // AKA m_shaders.push_back(), but that has an ambiguous call to insertAt() + // due to the default parameters. This is the desired insertAt() overload. + m_shaders.insertAt(shader, m_shaders.size(), 1); + return true; +} + +bool ProgramData::detachShader(GLuint shader) +{ + size_t n = m_shaders.size(); + for (size_t i = 0; i < n; i++) { + if (m_shaders[i] == shader) { + m_shaders.removeAt(i); + return true; + } + } + return false; +} /***** GLSharedGroup ****/ GLSharedGroup::GLSharedGroup() : m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)), m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)), - m_shaders(android::List<GLuint>()) + m_shaders(android::DefaultKeyedVector<GLuint, ShaderData*>(NULL)) { } @@ -217,13 +306,55 @@ void GLSharedGroup::deleteProgramData(GLuint program) m_programs.removeItem(program); } -void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type) +void GLSharedGroup::attachShader(GLuint program, GLuint shader) +{ + android::AutoMutex _lock(m_lock); + ProgramData* programData = m_programs.valueFor(program); + ssize_t idx = m_shaders.indexOfKey(shader); + if (programData && idx >= 0) { + if (programData->attachShader(shader)) { + refShaderDataLocked(idx); + } + } +} + +void GLSharedGroup::detachShader(GLuint program, GLuint shader) +{ + android::AutoMutex _lock(m_lock); + ProgramData* programData = m_programs.valueFor(program); + ssize_t idx = m_shaders.indexOfKey(shader); + if (programData && idx >= 0) { + if (programData->detachShader(shader)) { + unrefShaderDataLocked(idx); + } + } +} + +void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name) { android::AutoMutex _lock(m_lock); ProgramData* pData = m_programs.valueFor(program); if (pData) { pData->setIndexInfo(index,base,size,type); + + if (type == GL_SAMPLER_2D) { + size_t n = pData->getNumShaders(); + for (size_t i = 0; i < n; i++) { + GLuint shaderId = pData->getShader(i); + ShaderData* shader = m_shaders.valueFor(shaderId); + if (!shader) continue; + ShaderData::StringList::iterator nameIter = shader->samplerExternalNames.begin(); + ShaderData::StringList::iterator nameEnd = shader->samplerExternalNames.end(); + while (nameIter != nameEnd) { + if (*nameIter == name) { + pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL); + break; + } + ++nameIter; + } + } + } } } @@ -277,38 +408,62 @@ bool GLSharedGroup::needUniformLocationWAR(GLuint program) return false; } +GLint GLSharedGroup::getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const +{ + android::AutoMutex _lock(m_lock); + ProgramData* pData = m_programs.valueFor(program); + return pData ? pData->getNextSamplerUniform(index, val, target) : -1; +} -void GLSharedGroup::addShaderData(GLuint shader) +bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target) { android::AutoMutex _lock(m_lock); - m_shaders.push_front(shader); - + ProgramData* pData = m_programs.valueFor(program); + return pData ? pData->setSamplerUniform(appLoc, val, target) : false; } -bool GLSharedGroup::isShader(GLuint shader) + +bool GLSharedGroup::addShaderData(GLuint shader) { android::AutoMutex _lock(m_lock); - android::List<GLuint>::iterator iter; - iter = m_shaders.begin(); - while (iter!=m_shaders.end()) - { - if (*iter==shader) - return true; - iter++; + ShaderData* data = new ShaderData; + if (data) { + if (m_shaders.add(shader, data) < 0) { + delete data; + data = NULL; + } + data->refcount = 1; } - return false; + return data != NULL; } -void GLSharedGroup::deleteShaderData(GLuint shader) + +ShaderData* GLSharedGroup::getShaderData(GLuint shader) { android::AutoMutex _lock(m_lock); - android::List<GLuint>::iterator iter; - iter = m_shaders.begin(); - while (iter!=m_shaders.end()) - { - if (*iter==shader) - { - m_shaders.erase(iter); - return; - } - iter++; + return m_shaders.valueFor(shader); +} + +void GLSharedGroup::unrefShaderData(GLuint shader) +{ + android::AutoMutex _lock(m_lock); + ssize_t idx = m_shaders.indexOfKey(shader); + if (idx >= 0) { + unrefShaderDataLocked(idx); + } +} + +void GLSharedGroup::refShaderDataLocked(ssize_t shaderIdx) +{ + assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size()); + ShaderData* data = m_shaders.valueAt(shaderIdx); + data->refcount++; +} + +void GLSharedGroup::unrefShaderDataLocked(ssize_t shaderIdx) +{ + assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size()); + ShaderData* data = m_shaders.valueAt(shaderIdx); + if (--data->refcount == 0) { + delete data; + m_shaders.removeItemsAt(shaderIdx); } } |
