| /* |
| * 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" |
| |
| #include "KeyedVectorUtils.h" |
| #include "glUtils.h" |
| |
| /**** BufferData ****/ |
| |
| BufferData::BufferData() : m_size(0), m_usage(0), m_mapped(false) {}; |
| |
| BufferData::BufferData(GLsizeiptr size, const void* data) : |
| m_size(size), m_usage(0), m_mapped(false) { |
| |
| if (size > 0) { |
| m_fixedBuffer.resize(size); |
| } |
| |
| if (data) { |
| memcpy(m_fixedBuffer.data(), data, size); |
| } |
| } |
| |
| /**** ProgramData ****/ |
| ProgramData::ProgramData() : m_numIndexes(0), |
| m_numAttributes(0), |
| m_initialized(false) { |
| m_Indexes = NULL; |
| m_attribIndexes = NULL; |
| m_refcount = 1; |
| m_linkStatus = 0; |
| m_activeUniformBlockCount = 0; |
| m_transformFeedbackVaryingsCount = 0; |
| } |
| |
| void ProgramData::initProgramData(GLuint numIndexes, GLuint numAttributes) { |
| m_initialized = true; |
| m_numIndexes = numIndexes; |
| m_numAttributes = numAttributes; |
| |
| delete [] m_Indexes; |
| delete [] m_attribIndexes; |
| |
| m_Indexes = new IndexInfo[numIndexes]; |
| m_attribIndexes = new AttribInfo[m_numAttributes]; |
| } |
| |
| bool ProgramData::isInitialized() { |
| return m_initialized; |
| } |
| |
| ProgramData::~ProgramData() { |
| |
| delete [] m_Indexes; |
| delete [] m_attribIndexes; |
| |
| m_Indexes = NULL; |
| } |
| |
| void ProgramData::setIndexInfo( |
| GLuint index, GLint base, GLint size, GLenum type) { |
| |
| if (index >= m_numIndexes) return; |
| |
| m_Indexes[index].base = base; |
| m_Indexes[index].size = size; |
| m_Indexes[index].type = type; |
| m_Indexes[index].hostLocsPerElement = 1; |
| m_Indexes[index].flags = 0; |
| m_Indexes[index].samplerValue = 0; |
| } |
| |
| void ProgramData::setAttribInfo( |
| GLuint index, GLint attribLoc, GLint size, GLenum type) { |
| |
| if (index >= m_numAttributes) return; |
| |
| m_attribIndexes[index].attribLoc = attribLoc; |
| m_attribIndexes[index].size = size; |
| m_attribIndexes[index].type = type; |
| } |
| |
| void ProgramData::setIndexFlags(GLuint index, GLuint flags) { |
| |
| if (index >= m_numIndexes) return; |
| |
| m_Indexes[index].flags |= flags; |
| } |
| |
| GLuint ProgramData::getIndexForLocation(GLint location) { |
| GLuint index = m_numIndexes; |
| |
| GLint minDist = -1; |
| |
| for (GLuint i = 0; i < m_numIndexes; ++i) { |
| GLint dist = location - m_Indexes[i].base; |
| if (dist >= 0 && (minDist < 0 || dist < minDist)) { |
| index = i; |
| minDist = dist; |
| } |
| } |
| |
| return index; |
| } |
| |
| GLenum ProgramData::getTypeForLocation(GLint location) { |
| GLuint index = getIndexForLocation(location); |
| if (index < m_numIndexes) { |
| return m_Indexes[index].type; |
| } |
| return 0; |
| } |
| |
| bool ProgramData::isValidUniformLocation(GLint location) { |
| for (GLuint i = 0; i < m_numIndexes; ++i) { |
| if (location >= m_Indexes[i].base && |
| location < m_Indexes[i].base + m_Indexes[i].size) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| 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].base; |
| |
| if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) { |
| if (m_Indexes[i].type == GL_SAMPLER_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, GLenum shaderType) { |
| size_t n = m_shaders.size(); |
| |
| for (size_t i = 0; i < n; i++) { |
| if (m_shaders[i] == shader) { |
| return false; |
| } else if (m_shaderTypes[i] == shaderType) { |
| return false; |
| } |
| } |
| m_shaders.push_back(shader); |
| m_shaderTypes.push_back(shaderType); |
| 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.erase(m_shaders.begin() + i); |
| m_shaderTypes.erase(m_shaderTypes.begin() + i); |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| UniformValidationInfo ProgramData::compileValidationInfo(bool* error) const { |
| UniformValidationInfo res; |
| if (!m_Indexes) { |
| *error = true; |
| return res; |
| } |
| |
| for (GLuint i = 0; i < m_numIndexes; ++i) { |
| if (m_Indexes[i].base < 0) continue; |
| |
| UniformLocationInfo info = { |
| .valid = true, |
| .columns = getColumnsOfType(m_Indexes[i].type), |
| .rows = getRowsOfType(m_Indexes[i].type), |
| .isSampler = isSamplerType(m_Indexes[i].type), |
| .isInt = isIntegerType(m_Indexes[i].type), |
| .isArray = m_Indexes[i].size > 1, |
| .isUnsigned = isUnsignedIntType(m_Indexes[i].type), |
| .isBool = isBoolType(m_Indexes[i].type), |
| }; |
| for (GLuint j = 0; j < m_Indexes[i].size; ++j) { |
| res.add(m_Indexes[i].base + j, info); |
| } |
| } |
| |
| return res; |
| } |
| |
| AttribValidationInfo ProgramData::compileAttribValidationInfo(bool* error) const { |
| AttribValidationInfo res; |
| if (!m_attribIndexes) { |
| *error = true; |
| return res; |
| } |
| |
| for (GLuint i = 0; i < m_numAttributes; ++i) { |
| if (m_attribIndexes[i].attribLoc < 0) continue; |
| |
| AttribIndexInfo info = { |
| .validInProgram = true, |
| }; |
| |
| for (GLuint j = 0; j < getAttributeCountOfType(m_attribIndexes[i].type) * m_attribIndexes[i].size ; ++j) { |
| res.add(m_attribIndexes[i].attribLoc + j, info); |
| } |
| } |
| |
| return res; |
| } |
| /***** GLSharedGroup ****/ |
| |
| GLSharedGroup::GLSharedGroup() { } |
| |
| GLSharedGroup::~GLSharedGroup() { |
| m_buffers.clear(); |
| m_programs.clear(); |
| clearObjectMap(m_buffers); |
| clearObjectMap(m_programs); |
| clearObjectMap(m_shaders); |
| clearObjectMap(m_shaderPrograms); |
| } |
| |
| bool GLSharedGroup::isShaderOrProgramObject(GLuint obj) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| return (findObjectOrDefault(m_shaders, obj) || |
| findObjectOrDefault(m_programs, obj) || |
| findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[obj])); |
| } |
| |
| BufferData* GLSharedGroup::getBufferData(GLuint bufferId) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| return findObjectOrDefault(m_buffers, bufferId); |
| } |
| |
| SharedTextureDataMap* GLSharedGroup::getTextureData() { |
| return &m_textureRecs; |
| } |
| |
| RenderbufferInfo* GLSharedGroup::getRenderbufferInfo() { |
| return &m_renderbufferInfo; |
| } |
| |
| SamplerInfo* GLSharedGroup::getSamplerInfo() { |
| return &m_samplerInfo; |
| } |
| |
| void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, const void* data) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| m_buffers[bufferId] = new BufferData(size, data); |
| } |
| |
| void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, const void* data) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| BufferData* currentBuffer = findObjectOrDefault(m_buffers, bufferId); |
| |
| if (currentBuffer) delete currentBuffer; |
| |
| m_buffers[bufferId] = new BufferData(size, data); |
| } |
| |
| void GLSharedGroup::setBufferUsage(GLuint bufferId, GLenum usage) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| BufferData* data = findObjectOrDefault(m_buffers, bufferId); |
| |
| if (data) data->m_usage = usage; |
| } |
| |
| void GLSharedGroup::setBufferMapped(GLuint bufferId, bool mapped) { |
| BufferData* buf = findObjectOrDefault(m_buffers, bufferId); |
| |
| if (!buf) return; |
| |
| buf->m_mapped = mapped; |
| } |
| |
| GLenum GLSharedGroup::getBufferUsage(GLuint bufferId) { |
| BufferData* buf = findObjectOrDefault(m_buffers, bufferId); |
| |
| if (!buf) return 0; |
| |
| return buf->m_usage; |
| } |
| |
| bool GLSharedGroup::isBufferMapped(GLuint bufferId) { |
| BufferData* buf = findObjectOrDefault(m_buffers, bufferId); |
| |
| if (!buf) return false; |
| |
| return buf->m_mapped; |
| } |
| |
| GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, const void* data) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| BufferData* buf = findObjectOrDefault(m_buffers, bufferId); |
| |
| if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) { |
| return GL_INVALID_VALUE; |
| } |
| |
| memcpy(&buf->m_fixedBuffer[offset], data, size); |
| |
| buf->m_indexRangeCache.invalidateRange((size_t)offset, (size_t)size); |
| return GL_NO_ERROR; |
| } |
| |
| void GLSharedGroup::deleteBufferData(GLuint bufferId) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| BufferData* buf = findObjectOrDefault(m_buffers, bufferId); |
| if (buf) { |
| delete buf; |
| m_buffers.erase(bufferId); |
| } |
| } |
| |
| void GLSharedGroup::addProgramData(GLuint program) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| if (pData) { |
| delete pData; |
| } |
| |
| m_programs[program] = new ProgramData(); |
| } |
| |
| void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes, GLuint numAttributes) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| if (pData) { |
| pData->initProgramData(numIndexes, numAttributes); |
| } |
| } |
| |
| void GLSharedGroup::refProgramData(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| if (!pData) return; |
| pData->incRef(); |
| } |
| |
| void GLSharedGroup::onUseProgram(GLuint previous, GLuint next) { |
| if (previous == next) return; |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| if (previous) { |
| deleteProgramDataLocked(previous); |
| } |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, next); |
| if (!pData) return; |
| pData->incRef(); |
| } |
| |
| bool GLSharedGroup::isProgramInitialized(GLuint program) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| |
| if (pData) { |
| return pData->isInitialized(); |
| } |
| |
| if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) { |
| return false; |
| } |
| |
| ShaderProgramData* shaderProgramData = |
| findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]); |
| |
| if (shaderProgramData) { |
| return shaderProgramData->programData.isInitialized(); |
| } |
| |
| return false; |
| } |
| |
| void GLSharedGroup::deleteProgramData(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| deleteProgramDataLocked(program); |
| } |
| |
| void GLSharedGroup::deleteProgramDataLocked(GLuint program) { |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| |
| if (pData && pData->decRef()) { |
| size_t numShaders = pData->getNumShaders(); |
| for (size_t i = 0; i < numShaders; ++i) { |
| // changes the first one |
| detachShaderLocked(program, pData->getShader(0)); |
| } |
| delete pData; |
| m_programs.erase(program); |
| } |
| |
| if (m_shaderProgramIdMap.find(program) == |
| m_shaderProgramIdMap.end()) return; |
| |
| ShaderProgramData* spData = |
| findObjectOrDefault( |
| m_shaderPrograms, m_shaderProgramIdMap[program]); |
| |
| if (spData) delete spData; |
| |
| m_shaderPrograms.erase(m_shaderProgramIdMap[program]); |
| m_shaderProgramIdMap.erase(program); |
| } |
| |
| // No such thing for separable shader programs. |
| bool GLSharedGroup::attachShader(GLuint program, GLuint shader) { |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| ShaderData* sData = findObjectOrDefault(m_shaders, shader); |
| |
| bool res = false; |
| |
| if (pData && sData) { |
| res = pData->attachShader(shader, sData->shaderType); |
| if (res) { |
| refShaderDataLocked(shader); |
| } |
| } |
| |
| return res; |
| } |
| |
| bool GLSharedGroup::detachShader(GLuint program, GLuint shader) { |
| AutoLock<Lock> _lock(m_lock); |
| return detachShaderLocked(program, shader); |
| } |
| |
| bool GLSharedGroup::detachShaderLocked(GLuint program, GLuint shader) { |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| ShaderData* sData = findObjectOrDefault(m_shaders, shader); |
| |
| bool res = false; |
| |
| if (pData && sData) { |
| res = pData->detachShader(shader); |
| if (res) { |
| unrefShaderDataLocked(shader); |
| } |
| } |
| |
| return res; |
| } |
| |
| // Not needed/used for separate shader programs. |
| void GLSharedGroup::setProgramIndexInfo( |
| GLuint program, GLuint index, GLint base, |
| GLint size, GLenum type, const char* name) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, 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 = findObjectOrDefault(m_shaders, shaderId); |
| if (!shader) continue; |
| ShaderData::StringList::iterator nameIter = |
| shader->samplerExternalNames.begin(); |
| ShaderData::StringList::iterator nameEnd = |
| shader->samplerExternalNames.end(); |
| while (nameIter != nameEnd) { |
| if (*nameIter == name || *nameIter + "[0]" == name) { |
| pData->setIndexFlags( |
| index, |
| ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL); |
| break; |
| } |
| ++nameIter; |
| } |
| } |
| } |
| } |
| } |
| |
| void GLSharedGroup::setProgramAttribInfo( |
| GLuint program, GLuint index, GLint attribLoc, |
| GLint size, GLenum type, const char* name) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = getProgramDataLocked(program); |
| |
| if (pData) { |
| pData->setAttribInfo(index,attribLoc,size,type); |
| } |
| } |
| |
| GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| GLenum type = 0; |
| |
| if (pData) { |
| type = pData->getTypeForLocation(location); |
| } |
| |
| if (m_shaderProgramIdMap.find(program) == |
| m_shaderProgramIdMap.end()) return type; |
| |
| ShaderProgramData* spData = |
| findObjectOrDefault( |
| m_shaderPrograms, m_shaderProgramIdMap[program]); |
| |
| if (spData) { |
| type = spData->programData.getTypeForLocation(location); |
| } |
| |
| return type; |
| } |
| |
| bool GLSharedGroup::isProgram(GLuint program) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| |
| if (pData) return true; |
| |
| if (m_shaderProgramIdMap.find(program) == |
| m_shaderProgramIdMap.end()) return false; |
| |
| ShaderProgramData* spData = |
| findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]); |
| |
| if (spData) return true; |
| |
| return false; |
| } |
| |
| GLint GLSharedGroup::getNextSamplerUniform( |
| GLuint program, GLint index, GLint* val, GLenum* target) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| |
| if (pData) return pData->getNextSamplerUniform(index, val, target); |
| |
| if (m_shaderProgramIdMap.find(program) == |
| m_shaderProgramIdMap.end()) return -1; |
| |
| ShaderProgramData* spData = |
| findObjectOrDefault( |
| m_shaderPrograms, |
| findObjectOrDefault(m_shaderProgramIdMap, program)); |
| |
| if (spData) return spData->programData.getNextSamplerUniform(index, val, target); |
| |
| return -1; |
| } |
| |
| bool GLSharedGroup::setSamplerUniform( |
| GLuint program, GLint appLoc, GLint val, GLenum* target) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = |
| findObjectOrDefault(m_programs, program); |
| |
| if (pData) return pData->setSamplerUniform(appLoc, val, target); |
| |
| if (m_shaderProgramIdMap.find(program) == |
| m_shaderProgramIdMap.end()) return false; |
| |
| ShaderProgramData* spData = |
| findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]); |
| |
| if (spData) return spData->programData.setSamplerUniform(appLoc, val, target); |
| |
| return false; |
| } |
| |
| bool GLSharedGroup::isProgramUniformLocationValid(GLuint program, GLint location) { |
| if (location < 0) return false; |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = |
| findObjectOrDefault(m_programs, program); |
| |
| if (!pData) return false; |
| |
| return pData->isValidUniformLocation(location); |
| } |
| |
| bool GLSharedGroup::isShader(GLuint shader) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ShaderData* pData = findObjectOrDefault(m_shaders, shader); |
| |
| return pData != NULL; |
| } |
| |
| bool GLSharedGroup::addShaderData(GLuint shader, GLenum shaderType) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ShaderData* data = new ShaderData; |
| |
| if (data) { |
| m_shaders[shader] = data; |
| data->refcount = 1; |
| data->shaderType = shaderType; |
| } |
| |
| return data != NULL; |
| } |
| |
| ShaderData* GLSharedGroup::getShaderData(GLuint shader) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| return findObjectOrDefault(m_shaders, shader); |
| } |
| |
| void GLSharedGroup::unrefShaderData(GLuint shader) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| unrefShaderDataLocked(shader); |
| } |
| |
| void GLSharedGroup::refShaderDataLocked(GLuint shaderId) { |
| ShaderData* data = findObjectOrDefault(m_shaders, shaderId); |
| data->refcount++; |
| } |
| |
| void GLSharedGroup::unrefShaderDataLocked(GLuint shaderId) { |
| ShaderData* data = findObjectOrDefault(m_shaders, shaderId); |
| |
| if (data && --data->refcount == 0) { |
| |
| delete data; |
| |
| m_shaders.erase(shaderId); |
| } |
| } |
| |
| ProgramData* GLSharedGroup::getProgramDataLocked(GLuint program) { |
| // Check the space of normal programs, then separable ones |
| ProgramData* pData = findObjectOrDefault(m_programs, program); |
| |
| if (pData) return pData; |
| |
| std::map<GLuint, uint32_t>::const_iterator it = |
| m_shaderProgramIdMap.find(program); |
| if (it == m_shaderProgramIdMap.end()) return NULL; |
| |
| ShaderProgramData* spData = findObjectOrDefault(m_shaderPrograms, it->second); |
| if (!spData) return NULL; |
| return &spData->programData; |
| } |
| |
| uint32_t GLSharedGroup::addNewShaderProgramData() { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ShaderProgramData* data = new ShaderProgramData; |
| uint32_t currId = m_shaderProgramId; |
| |
| m_shaderPrograms[currId] = data; |
| m_shaderProgramId++; |
| return currId; |
| } |
| |
| void GLSharedGroup::associateGLShaderProgram( |
| GLuint shaderProgramName, uint32_t shaderProgramId) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| m_shaderProgramIdMap[shaderProgramName] = shaderProgramId; |
| } |
| |
| ShaderProgramData* GLSharedGroup::getShaderProgramDataById(uint32_t id) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ShaderProgramData* res = findObjectOrDefault(m_shaderPrograms, id); |
| |
| return res; |
| } |
| |
| ShaderProgramData* GLSharedGroup::getShaderProgramData( |
| GLuint shaderProgramName) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| return findObjectOrDefault(m_shaderPrograms, |
| m_shaderProgramIdMap[shaderProgramName]); |
| } |
| |
| void GLSharedGroup::deleteShaderProgramDataById(uint32_t id) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ShaderProgramData* data = |
| findObjectOrDefault(m_shaderPrograms, id); |
| |
| delete data; |
| |
| m_shaderPrograms.erase(id); |
| } |
| |
| |
| void GLSharedGroup::deleteShaderProgramData(GLuint shaderProgramName) { |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| uint32_t id = m_shaderProgramIdMap[shaderProgramName]; |
| ShaderProgramData* data = findObjectOrDefault(m_shaderPrograms, id); |
| |
| delete data; |
| |
| m_shaderPrograms.erase(id); |
| m_shaderProgramIdMap.erase(shaderProgramName); |
| } |
| |
| void GLSharedGroup::initShaderProgramData(GLuint shaderProgram, GLuint numIndices, GLuint numAttributes) { |
| ShaderProgramData* spData = getShaderProgramData(shaderProgram); |
| spData->programData.initProgramData(numIndices, numAttributes); |
| } |
| |
| void GLSharedGroup::setShaderProgramIndexInfo( |
| GLuint shaderProgram, GLuint index, GLint base, |
| GLint size, GLenum type, const char* name) { |
| |
| ShaderProgramData* spData = getShaderProgramData(shaderProgram); |
| ProgramData& pData = spData->programData; |
| ShaderData& sData = spData->shaderData; |
| |
| pData.setIndexInfo(index, base, size, type); |
| |
| if (type == GL_SAMPLER_2D) { |
| |
| ShaderData::StringList::iterator nameIter = |
| sData.samplerExternalNames.begin(); |
| ShaderData::StringList::iterator nameEnd = |
| sData.samplerExternalNames.end(); |
| |
| while (nameIter != nameEnd) { |
| if (*nameIter == name) { |
| pData.setIndexFlags( |
| index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL); |
| break; |
| } |
| ++nameIter; |
| } |
| } |
| } |
| |
| UniformValidationInfo GLSharedGroup::getUniformValidationInfo(GLuint program) { |
| UniformValidationInfo res; |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| |
| if (!pData) return res; |
| |
| bool error; (void)error; |
| return pData->compileValidationInfo(&error); |
| } |
| |
| AttribValidationInfo GLSharedGroup::getAttribValidationInfo(GLuint program) { |
| AttribValidationInfo res; |
| |
| AutoLock<Lock> _lock(m_lock); |
| |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| |
| if (!pData) return res; |
| |
| bool error; (void)error; |
| return pData->compileAttribValidationInfo(&error); |
| } |
| |
| void GLSharedGroup::setProgramLinkStatus(GLuint program, GLint linkStatus) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| if (!pData) return; |
| pData->setLinkStatus(linkStatus); |
| } |
| |
| GLint GLSharedGroup::getProgramLinkStatus(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = getProgramDataLocked(program); |
| if (!pData) return 0; |
| return pData->getLinkStatus(); |
| } |
| |
| void GLSharedGroup::setActiveUniformBlockCountForProgram(GLuint program, GLint count) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| |
| if (!pData) return; |
| |
| pData->setActiveUniformBlockCount(count); |
| } |
| |
| GLint GLSharedGroup::getActiveUniformBlockCount(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| |
| if (!pData) return 0; |
| |
| return pData->getActiveUniformBlockCount(); |
| } |
| |
| void GLSharedGroup::setTransformFeedbackVaryingsCountForProgram(GLuint program, GLint count) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = getProgramDataLocked(program); |
| if (!pData) return; |
| pData->setTransformFeedbackVaryingsCount(count); |
| } |
| |
| GLint GLSharedGroup::getTransformFeedbackVaryingsCountForProgram(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = getProgramDataLocked(program); |
| if (!pData) return 0; |
| return pData->getTransformFeedbackVaryingsCount(); |
| } |
| |
| int GLSharedGroup::getActiveUniformsCountForProgram(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| |
| if (!pData) return 0; |
| |
| return pData->getActiveUniformsCount(); |
| } |
| |
| int GLSharedGroup::getActiveAttributesCountForProgram(GLuint program) { |
| AutoLock<Lock> _lock(m_lock); |
| ProgramData* pData = |
| getProgramDataLocked(program); |
| |
| if (!pData) return 0; |
| |
| return pData->getActiveAttributesCount(); |
| } |
| |