658 lines
20 KiB
C++
Executable file
658 lines
20 KiB
C++
Executable file
/*
|
|
* 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"
|
|
|
|
/**** KeyedVector utilities ****/
|
|
|
|
template <typename T>
|
|
static void clearObjectMap(android::DefaultKeyedVector<GLuint, T>& v) {
|
|
for (size_t i = 0; i < v.size(); i++)
|
|
delete v.valueAt(i);
|
|
v.clear();
|
|
}
|
|
|
|
/**** BufferData ****/
|
|
|
|
BufferData::BufferData() : m_size(0), m_usage(0), m_mapped(false) {};
|
|
BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size), m_usage(0), m_mapped(false)
|
|
{
|
|
void * buffer = NULL;
|
|
if (size>0) buffer = m_fixedBuffer.alloc(size);
|
|
if (data) memcpy(buffer, data, size);
|
|
}
|
|
|
|
/**** ProgramData ****/
|
|
ProgramData::ProgramData() : m_numIndexes(0),
|
|
m_initialized(false),
|
|
m_locShiftWAR(false)
|
|
{
|
|
m_Indexes = NULL;
|
|
}
|
|
|
|
void ProgramData::initProgramData(GLuint numIndexes)
|
|
{
|
|
m_initialized = true;
|
|
m_numIndexes = numIndexes;
|
|
delete[] m_Indexes;
|
|
m_Indexes = new IndexInfo[numIndexes];
|
|
m_locShiftWAR = false;
|
|
}
|
|
|
|
bool ProgramData::isInitialized()
|
|
{
|
|
return m_initialized;
|
|
}
|
|
|
|
ProgramData::~ProgramData()
|
|
{
|
|
delete[] m_Indexes;
|
|
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;
|
|
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;
|
|
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)
|
|
{
|
|
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;
|
|
}
|
|
|
|
void ProgramData::setupLocationShiftWAR()
|
|
{
|
|
m_locShiftWAR = false;
|
|
for (GLuint i=0; i<m_numIndexes; i++) {
|
|
if (0 != (m_Indexes[i].base & 0xffff)) {
|
|
return;
|
|
}
|
|
}
|
|
// if we have one uniform at location 0, we do not need the WAR.
|
|
if (m_numIndexes > 1) {
|
|
m_locShiftWAR = true;
|
|
}
|
|
}
|
|
|
|
GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
|
|
{
|
|
if (!m_locShiftWAR) return hostLoc;
|
|
|
|
GLuint index = getIndexForLocation(hostLoc);
|
|
if (index<m_numIndexes) {
|
|
if (arrIndex > 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) return appLoc;
|
|
|
|
for(GLuint i=0; i<m_numIndexes; i++) {
|
|
GLint elemIndex = appLoc - m_Indexes[i].appBase;
|
|
if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
|
|
return m_Indexes[i].base +
|
|
elemIndex * m_Indexes[i].hostLocsPerElement;
|
|
}
|
|
}
|
|
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::DefaultKeyedVector<GLuint, ShaderData*>(NULL)),
|
|
m_shaderPrograms(android::DefaultKeyedVector<GLuint, ShaderProgramData*>(NULL))
|
|
{
|
|
}
|
|
|
|
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)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
return ((m_shaders.valueFor(obj)!=NULL) ||
|
|
(m_programs.valueFor(obj)!=NULL) ||
|
|
(m_shaderPrograms.valueFor(m_shaderProgramIdMap[obj]) !=NULL));
|
|
}
|
|
|
|
BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
return m_buffers.valueFor(bufferId);
|
|
}
|
|
|
|
SharedTextureDataMap* GLSharedGroup::getTextureData() {
|
|
return &m_textureRecs;
|
|
}
|
|
|
|
void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
m_buffers.add(bufferId, new BufferData(size, data));
|
|
}
|
|
|
|
void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ssize_t idx = m_buffers.indexOfKey(bufferId);
|
|
if (idx >= 0) {
|
|
delete m_buffers.valueAt(idx);
|
|
m_buffers.editValueAt(idx) = new BufferData(size, data);
|
|
} else {
|
|
m_buffers.add(bufferId, new BufferData(size, data));
|
|
}
|
|
}
|
|
|
|
void GLSharedGroup::setBufferUsage(GLuint bufferId, GLenum usage) {
|
|
android::AutoMutex _lock(m_lock);
|
|
ssize_t idx = m_buffers.indexOfKey(bufferId);
|
|
if (idx >= 0) {
|
|
m_buffers.editValueAt(idx)->m_usage = usage;
|
|
}
|
|
}
|
|
|
|
void GLSharedGroup::setBufferMapped(GLuint bufferId, bool mapped) {
|
|
BufferData * buf = m_buffers.valueFor(bufferId);
|
|
if (!buf) return;
|
|
buf->m_mapped = mapped;
|
|
}
|
|
|
|
GLenum GLSharedGroup::getBufferUsage(GLuint bufferId) {
|
|
BufferData * buf = m_buffers.valueFor(bufferId);
|
|
if (!buf) return 0;
|
|
return buf->m_usage;
|
|
}
|
|
|
|
bool GLSharedGroup::isBufferMapped(GLuint bufferId) {
|
|
BufferData * buf = m_buffers.valueFor(bufferId);
|
|
if (!buf) return false;
|
|
return buf->m_mapped;
|
|
}
|
|
|
|
GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
BufferData * buf = m_buffers.valueFor(bufferId);
|
|
if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE;
|
|
|
|
//it's safe to update now
|
|
memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
|
|
|
|
buf->m_indexRangeCache.invalidateRange((size_t)offset, (size_t)size);
|
|
return GL_NO_ERROR;
|
|
}
|
|
|
|
void GLSharedGroup::deleteBufferData(GLuint bufferId)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ssize_t idx = m_buffers.indexOfKey(bufferId);
|
|
if (idx >= 0) {
|
|
delete m_buffers.valueAt(idx);
|
|
m_buffers.removeItemsAt(idx);
|
|
}
|
|
}
|
|
|
|
void GLSharedGroup::addProgramData(GLuint program)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData *pData = m_programs.valueFor(program);
|
|
if (pData)
|
|
{
|
|
m_programs.removeItem(program);
|
|
delete pData;
|
|
}
|
|
|
|
m_programs.add(program,new ProgramData());
|
|
}
|
|
|
|
void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData *pData = m_programs.valueFor(program);
|
|
if (pData)
|
|
{
|
|
pData->initProgramData(numIndexes);
|
|
}
|
|
}
|
|
|
|
bool GLSharedGroup::isProgramInitialized(GLuint program)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
if (pData)
|
|
{
|
|
return pData->isInitialized();
|
|
}
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) {
|
|
return spData->programData->isInitialized();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void GLSharedGroup::deleteProgramData(GLuint program)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData *pData = m_programs.valueFor(program);
|
|
if (pData) {
|
|
delete pData;
|
|
}
|
|
m_programs.removeItem(program);
|
|
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) {
|
|
delete spData;
|
|
}
|
|
m_shaderPrograms.removeItem(m_shaderProgramIdMap[program]);
|
|
m_shaderProgramIdMap.erase(program);
|
|
}
|
|
|
|
// No such thing for separable shader programs.
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Not needed/used for separate shader programs.
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
GLenum type=0;
|
|
if (pData) {
|
|
type = pData->getTypeForLocation(location);
|
|
}
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return type;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) {
|
|
type = spData->programData->getTypeForLocation(location);
|
|
}
|
|
return type;
|
|
}
|
|
|
|
bool GLSharedGroup::isProgram(GLuint program)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
if (pData) return true;
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) return true;
|
|
return false;
|
|
}
|
|
|
|
void GLSharedGroup::setupLocationShiftWAR(GLuint program)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
if (pData) pData->setupLocationShiftWAR();
|
|
}
|
|
|
|
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, arrIndex);
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return hostLoc;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) return spData->programData->locationWARHostToApp(hostLoc, arrIndex);
|
|
return hostLoc;
|
|
}
|
|
|
|
GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
if (pData) return pData->locationWARAppToHost(appLoc);
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return appLoc;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) return spData->programData->locationWARAppToHost(appLoc);
|
|
return appLoc;
|
|
}
|
|
|
|
bool GLSharedGroup::needUniformLocationWAR(GLuint program)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
if (pData) return pData->needUniformLocationWAR();
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) return spData->programData->needUniformLocationWAR();
|
|
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);
|
|
if (pData) return pData->getNextSamplerUniform(index, val, target);
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return -1;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap.find(program)->second);
|
|
if (spData) return spData->programData->getNextSamplerUniform(index, val, target);
|
|
return -1;
|
|
}
|
|
|
|
bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ProgramData* pData = m_programs.valueFor(program);
|
|
if (pData) return pData->setSamplerUniform(appLoc, val, target);
|
|
if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
|
|
ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
|
|
if (spData) return spData->programData->setSamplerUniform(appLoc, val, target);
|
|
return false;
|
|
}
|
|
|
|
bool GLSharedGroup::isShader(GLuint shader)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ShaderData* pData = m_shaders.valueFor(shader);
|
|
return (pData!=NULL);
|
|
}
|
|
|
|
bool GLSharedGroup::addShaderData(GLuint shader)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
ShaderData* data = new ShaderData;
|
|
if (data) {
|
|
if (m_shaders.add(shader, data) < 0) {
|
|
delete data;
|
|
data = NULL;
|
|
}
|
|
data->refcount = 1;
|
|
}
|
|
return data != NULL;
|
|
}
|
|
|
|
ShaderData* GLSharedGroup::getShaderData(GLuint shader)
|
|
{
|
|
android::AutoMutex _lock(m_lock);
|
|
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);
|
|
}
|
|
}
|
|
|
|
uint32_t GLSharedGroup::addNewShaderProgramData() {
|
|
android::AutoMutex _lock(m_lock);
|
|
ShaderProgramData* data = new ShaderProgramData;
|
|
uint32_t currId = m_shaderProgramId;
|
|
ALOGD("%s: new data %p id %u", __FUNCTION__, data, currId);
|
|
m_shaderPrograms.add(currId, data);
|
|
m_shaderProgramId++;
|
|
return currId;
|
|
}
|
|
|
|
void GLSharedGroup::associateGLShaderProgram(GLuint shaderProgramName, uint32_t shaderProgramId) {
|
|
android::AutoMutex _lock(m_lock);
|
|
m_shaderProgramIdMap[shaderProgramName] = shaderProgramId;
|
|
}
|
|
|
|
ShaderProgramData* GLSharedGroup::getShaderProgramDataById(uint32_t id) {
|
|
android::AutoMutex _lock(m_lock);
|
|
ShaderProgramData* res = m_shaderPrograms.valueFor(id);
|
|
ALOGD("%s: id=%u res=%p", __FUNCTION__, id, res);
|
|
return res;
|
|
}
|
|
|
|
ShaderProgramData* GLSharedGroup::getShaderProgramData(GLuint shaderProgramName) {
|
|
android::AutoMutex _lock(m_lock);
|
|
return m_shaderPrograms.valueFor(m_shaderProgramIdMap[shaderProgramName]);
|
|
}
|
|
|
|
void GLSharedGroup::deleteShaderProgramDataById(uint32_t id) {
|
|
android::AutoMutex _lock(m_lock);
|
|
ShaderProgramData* data = m_shaderPrograms.valueFor(id);
|
|
delete data;
|
|
m_shaderPrograms.removeItemsAt(id);
|
|
}
|
|
|
|
|
|
void GLSharedGroup::deleteShaderProgramData(GLuint shaderProgramName) {
|
|
android::AutoMutex _lock(m_lock);
|
|
uint32_t id = m_shaderProgramIdMap[shaderProgramName];
|
|
ShaderProgramData* data = m_shaderPrograms.valueFor(id);
|
|
delete data;
|
|
m_shaderPrograms.removeItemsAt(id);
|
|
m_shaderProgramIdMap.erase(shaderProgramName);
|
|
}
|
|
|
|
void GLSharedGroup::initShaderProgramData(GLuint shaderProgram, GLuint numIndices) {
|
|
ShaderProgramData* spData = getShaderProgramData(shaderProgram);
|
|
spData->programData->initProgramData(numIndices);
|
|
}
|
|
|
|
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;
|
|
|
|
if (pData)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void GLSharedGroup::setupShaderProgramLocationShiftWAR(GLuint shaderProgram) {
|
|
ShaderProgramData* spData = getShaderProgramData(shaderProgram);
|
|
spData->programData->setupLocationShiftWAR();
|
|
}
|