1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include "GLSharedGroup.h"
18 
19 /**** KeyedVector utilities ****/
20 
21 template <typename T>
clearObjectMap(android::DefaultKeyedVector<GLuint,T> & v)22 static void clearObjectMap(android::DefaultKeyedVector<GLuint, T>& v) {
23     for (size_t i = 0; i < v.size(); i++)
24         delete v.valueAt(i);
25     v.clear();
26 }
27 
28 /**** BufferData ****/
29 
BufferData()30 BufferData::BufferData() : m_size(0), m_usage(0), m_mapped(false) {};
BufferData(GLsizeiptr size,void * data)31 BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size), m_usage(0), m_mapped(false)
32 {
33     void * buffer = NULL;
34     if (size>0) buffer = m_fixedBuffer.alloc(size);
35     if (data) memcpy(buffer, data, size);
36 }
37 
38 /**** ProgramData ****/
ProgramData()39 ProgramData::ProgramData() : m_numIndexes(0),
40                              m_initialized(false),
41                              m_locShiftWAR(false)
42 {
43     m_Indexes = NULL;
44 }
45 
initProgramData(GLuint numIndexes)46 void ProgramData::initProgramData(GLuint numIndexes)
47 {
48     m_initialized = true;
49     m_numIndexes = numIndexes;
50     delete[] m_Indexes;
51     m_Indexes = new IndexInfo[numIndexes];
52     m_locShiftWAR = false;
53 }
54 
isInitialized()55 bool ProgramData::isInitialized()
56 {
57     return m_initialized;
58 }
59 
~ProgramData()60 ProgramData::~ProgramData()
61 {
62     delete[] m_Indexes;
63     m_Indexes = NULL;
64 }
65 
setIndexInfo(GLuint index,GLint base,GLint size,GLenum type)66 void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type)
67 {
68     if (index>=m_numIndexes)
69         return;
70     m_Indexes[index].base = base;
71     m_Indexes[index].size = size;
72     m_Indexes[index].type = type;
73     if (index > 0) {
74         m_Indexes[index].appBase = m_Indexes[index-1].appBase +
75                                    m_Indexes[index-1].size;
76     }
77     else {
78         m_Indexes[index].appBase = 0;
79     }
80     m_Indexes[index].hostLocsPerElement = 1;
81     m_Indexes[index].flags = 0;
82     m_Indexes[index].samplerValue = 0;
83 }
84 
setIndexFlags(GLuint index,GLuint flags)85 void ProgramData::setIndexFlags(GLuint index, GLuint flags)
86 {
87     if (index >= m_numIndexes)
88         return;
89     m_Indexes[index].flags |= flags;
90 }
91 
getIndexForLocation(GLint location)92 GLuint ProgramData::getIndexForLocation(GLint location)
93 {
94     GLuint index = m_numIndexes;
95     GLint minDist = -1;
96     for (GLuint i=0;i<m_numIndexes;++i)
97     {
98         GLint dist = location - m_Indexes[i].base;
99         if (dist >= 0 &&
100             (minDist < 0 || dist < minDist)) {
101             index = i;
102             minDist = dist;
103         }
104     }
105     return index;
106 }
107 
getTypeForLocation(GLint location)108 GLenum ProgramData::getTypeForLocation(GLint location)
109 {
110     GLuint index = getIndexForLocation(location);
111     if (index<m_numIndexes) {
112         return m_Indexes[index].type;
113     }
114     return 0;
115 }
116 
setupLocationShiftWAR()117 void ProgramData::setupLocationShiftWAR()
118 {
119     m_locShiftWAR = false;
120     for (GLuint i=0; i<m_numIndexes; i++) {
121         if (0 != (m_Indexes[i].base & 0xffff)) {
122             return;
123         }
124     }
125     // if we have one uniform at location 0, we do not need the WAR.
126     if (m_numIndexes > 1) {
127         m_locShiftWAR = true;
128     }
129 }
130 
locationWARHostToApp(GLint hostLoc,GLint arrIndex)131 GLint ProgramData::locationWARHostToApp(GLint hostLoc, GLint arrIndex)
132 {
133     if (!m_locShiftWAR) return hostLoc;
134 
135     GLuint index = getIndexForLocation(hostLoc);
136     if (index<m_numIndexes) {
137         if (arrIndex > 0) {
138             m_Indexes[index].hostLocsPerElement =
139                               (hostLoc - m_Indexes[index].base) / arrIndex;
140         }
141         return m_Indexes[index].appBase + arrIndex;
142     }
143     return -1;
144 }
145 
locationWARAppToHost(GLint appLoc)146 GLint ProgramData::locationWARAppToHost(GLint appLoc)
147 {
148     if (!m_locShiftWAR) return appLoc;
149 
150     for(GLuint i=0; i<m_numIndexes; i++) {
151         GLint elemIndex = appLoc - m_Indexes[i].appBase;
152         if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
153             return m_Indexes[i].base +
154                    elemIndex * m_Indexes[i].hostLocsPerElement;
155         }
156     }
157     return -1;
158 }
159 
getNextSamplerUniform(GLint index,GLint * val,GLenum * target)160 GLint ProgramData::getNextSamplerUniform(GLint index, GLint* val, GLenum* target)
161 {
162     for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) {
163         if (m_Indexes[i].type == GL_SAMPLER_2D) {
164             if (val) *val = m_Indexes[i].samplerValue;
165             if (target) {
166                 if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
167                     *target = GL_TEXTURE_EXTERNAL_OES;
168                 } else {
169                     *target = GL_TEXTURE_2D;
170                 }
171             }
172             return i;
173         }
174     }
175     return -1;
176 }
177 
setSamplerUniform(GLint appLoc,GLint val,GLenum * target)178 bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target)
179 {
180     for (GLuint i = 0; i < m_numIndexes; i++) {
181         GLint elemIndex = appLoc - m_Indexes[i].appBase;
182         if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
183             if (m_Indexes[i].type == GL_TEXTURE_2D) {
184                 m_Indexes[i].samplerValue = val;
185                 if (target) {
186                     if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
187                         *target = GL_TEXTURE_EXTERNAL_OES;
188                     } else {
189                         *target = GL_TEXTURE_2D;
190                     }
191                 }
192                 return true;
193             }
194         }
195     }
196     return false;
197 }
198 
attachShader(GLuint shader)199 bool ProgramData::attachShader(GLuint shader)
200 {
201     size_t n = m_shaders.size();
202     for (size_t i = 0; i < n; i++) {
203         if (m_shaders[i] == shader) {
204             return false;
205         }
206     }
207     // AKA m_shaders.push_back(), but that has an ambiguous call to insertAt()
208     // due to the default parameters. This is the desired insertAt() overload.
209     m_shaders.insertAt(shader, m_shaders.size(), 1);
210     return true;
211 }
212 
detachShader(GLuint shader)213 bool ProgramData::detachShader(GLuint shader)
214 {
215     size_t n = m_shaders.size();
216     for (size_t i = 0; i < n; i++) {
217         if (m_shaders[i] == shader) {
218             m_shaders.removeAt(i);
219             return true;
220         }
221     }
222     return false;
223 }
224 
225 /***** GLSharedGroup ****/
226 
GLSharedGroup()227 GLSharedGroup::GLSharedGroup() :
228     m_buffers(android::DefaultKeyedVector<GLuint, BufferData*>(NULL)),
229     m_programs(android::DefaultKeyedVector<GLuint, ProgramData*>(NULL)),
230     m_shaders(android::DefaultKeyedVector<GLuint, ShaderData*>(NULL)),
231     m_shaderPrograms(android::DefaultKeyedVector<GLuint, ShaderProgramData*>(NULL))
232 {
233 }
234 
~GLSharedGroup()235 GLSharedGroup::~GLSharedGroup()
236 {
237     m_buffers.clear();
238     m_programs.clear();
239     clearObjectMap(m_buffers);
240     clearObjectMap(m_programs);
241     clearObjectMap(m_shaders);
242     clearObjectMap(m_shaderPrograms);
243 }
244 
isShaderOrProgramObject(GLuint obj)245 bool GLSharedGroup::isShaderOrProgramObject(GLuint obj)
246 {
247     android::AutoMutex _lock(m_lock);
248     return ((m_shaders.valueFor(obj)!=NULL) ||
249             (m_programs.valueFor(obj)!=NULL) ||
250             (m_shaderPrograms.valueFor(m_shaderProgramIdMap[obj]) !=NULL));
251 }
252 
getBufferData(GLuint bufferId)253 BufferData * GLSharedGroup::getBufferData(GLuint bufferId)
254 {
255     android::AutoMutex _lock(m_lock);
256     return m_buffers.valueFor(bufferId);
257 }
258 
getTextureData()259 SharedTextureDataMap* GLSharedGroup::getTextureData() {
260     return &m_textureRecs;
261 }
262 
addBufferData(GLuint bufferId,GLsizeiptr size,void * data)263 void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, void * data)
264 {
265     android::AutoMutex _lock(m_lock);
266     m_buffers.add(bufferId, new BufferData(size, data));
267 }
268 
updateBufferData(GLuint bufferId,GLsizeiptr size,void * data)269 void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, void * data)
270 {
271     android::AutoMutex _lock(m_lock);
272     ssize_t idx = m_buffers.indexOfKey(bufferId);
273     if (idx >= 0) {
274         delete m_buffers.valueAt(idx);
275         m_buffers.editValueAt(idx) = new BufferData(size, data);
276     } else {
277         m_buffers.add(bufferId, new BufferData(size, data));
278     }
279 }
280 
setBufferUsage(GLuint bufferId,GLenum usage)281 void GLSharedGroup::setBufferUsage(GLuint bufferId, GLenum usage) {
282     android::AutoMutex _lock(m_lock);
283     ssize_t idx = m_buffers.indexOfKey(bufferId);
284     if (idx >= 0) {
285         m_buffers.editValueAt(idx)->m_usage = usage;
286     }
287 }
288 
setBufferMapped(GLuint bufferId,bool mapped)289 void GLSharedGroup::setBufferMapped(GLuint bufferId, bool mapped) {
290     BufferData * buf = m_buffers.valueFor(bufferId);
291     if (!buf) return;
292     buf->m_mapped = mapped;
293 }
294 
getBufferUsage(GLuint bufferId)295 GLenum GLSharedGroup::getBufferUsage(GLuint bufferId) {
296     BufferData * buf = m_buffers.valueFor(bufferId);
297     if (!buf) return 0;
298     return buf->m_usage;
299 }
300 
isBufferMapped(GLuint bufferId)301 bool GLSharedGroup::isBufferMapped(GLuint bufferId) {
302     BufferData * buf = m_buffers.valueFor(bufferId);
303     if (!buf) return false;
304     return buf->m_mapped;
305 }
306 
subUpdateBufferData(GLuint bufferId,GLintptr offset,GLsizeiptr size,void * data)307 GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data)
308 {
309     android::AutoMutex _lock(m_lock);
310     BufferData * buf = m_buffers.valueFor(bufferId);
311     if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) return GL_INVALID_VALUE;
312 
313     //it's safe to update now
314     memcpy((char*)buf->m_fixedBuffer.ptr() + offset, data, size);
315 
316     buf->m_indexRangeCache.invalidateRange((size_t)offset, (size_t)size);
317     return GL_NO_ERROR;
318 }
319 
deleteBufferData(GLuint bufferId)320 void GLSharedGroup::deleteBufferData(GLuint bufferId)
321 {
322     android::AutoMutex _lock(m_lock);
323     ssize_t idx = m_buffers.indexOfKey(bufferId);
324     if (idx >= 0) {
325         delete m_buffers.valueAt(idx);
326         m_buffers.removeItemsAt(idx);
327     }
328 }
329 
addProgramData(GLuint program)330 void GLSharedGroup::addProgramData(GLuint program)
331 {
332     android::AutoMutex _lock(m_lock);
333     ProgramData *pData = m_programs.valueFor(program);
334     if (pData)
335     {
336         m_programs.removeItem(program);
337         delete pData;
338     }
339 
340     m_programs.add(program,new ProgramData());
341 }
342 
initProgramData(GLuint program,GLuint numIndexes)343 void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes)
344 {
345     android::AutoMutex _lock(m_lock);
346     ProgramData *pData = m_programs.valueFor(program);
347     if (pData)
348     {
349         pData->initProgramData(numIndexes);
350     }
351 }
352 
isProgramInitialized(GLuint program)353 bool GLSharedGroup::isProgramInitialized(GLuint program)
354 {
355     android::AutoMutex _lock(m_lock);
356     ProgramData* pData = m_programs.valueFor(program);
357     if (pData)
358     {
359         return pData->isInitialized();
360     }
361     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
362     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
363     if (spData) {
364         return spData->programData->isInitialized();
365     }
366     return false;
367 }
368 
deleteProgramData(GLuint program)369 void GLSharedGroup::deleteProgramData(GLuint program)
370 {
371     android::AutoMutex _lock(m_lock);
372     ProgramData *pData = m_programs.valueFor(program);
373     if (pData) {
374         delete pData;
375     }
376     m_programs.removeItem(program);
377 
378     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return;
379     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
380     if (spData) {
381         delete spData;
382     }
383     m_shaderPrograms.removeItem(m_shaderProgramIdMap[program]);
384     m_shaderProgramIdMap.erase(program);
385 }
386 
387 // No such thing for separable shader programs.
attachShader(GLuint program,GLuint shader)388 void GLSharedGroup::attachShader(GLuint program, GLuint shader)
389 {
390     android::AutoMutex _lock(m_lock);
391     ProgramData* programData = m_programs.valueFor(program);
392     ssize_t idx = m_shaders.indexOfKey(shader);
393     if (programData && idx >= 0) {
394         if (programData->attachShader(shader)) {
395             refShaderDataLocked(idx);
396         }
397     }
398 }
399 
detachShader(GLuint program,GLuint shader)400 void GLSharedGroup::detachShader(GLuint program, GLuint shader)
401 {
402     android::AutoMutex _lock(m_lock);
403     ProgramData* programData = m_programs.valueFor(program);
404     ssize_t idx = m_shaders.indexOfKey(shader);
405     if (programData && idx >= 0) {
406         if (programData->detachShader(shader)) {
407             unrefShaderDataLocked(idx);
408         }
409     }
410 }
411 
412 // Not needed/used for separate shader programs.
setProgramIndexInfo(GLuint program,GLuint index,GLint base,GLint size,GLenum type,const char * name)413 void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type, const char* name)
414 {
415     android::AutoMutex _lock(m_lock);
416     ProgramData* pData = m_programs.valueFor(program);
417     if (pData)
418     {
419         pData->setIndexInfo(index,base,size,type);
420 
421         if (type == GL_SAMPLER_2D) {
422             size_t n = pData->getNumShaders();
423             for (size_t i = 0; i < n; i++) {
424                 GLuint shaderId = pData->getShader(i);
425                 ShaderData* shader = m_shaders.valueFor(shaderId);
426                 if (!shader) continue;
427                 ShaderData::StringList::iterator nameIter = shader->samplerExternalNames.begin();
428                 ShaderData::StringList::iterator nameEnd  = shader->samplerExternalNames.end();
429                 while (nameIter != nameEnd) {
430                     if (*nameIter == name) {
431                         pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
432                         break;
433                     }
434                     ++nameIter;
435                 }
436             }
437         }
438     }
439 }
440 
getProgramUniformType(GLuint program,GLint location)441 GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location)
442 {
443     android::AutoMutex _lock(m_lock);
444     ProgramData* pData = m_programs.valueFor(program);
445     GLenum type=0;
446     if (pData) {
447         type = pData->getTypeForLocation(location);
448     }
449     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return type;
450     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
451     if (spData) {
452         type = spData->programData->getTypeForLocation(location);
453     }
454     return type;
455 }
456 
isProgram(GLuint program)457 bool  GLSharedGroup::isProgram(GLuint program)
458 {
459     android::AutoMutex _lock(m_lock);
460     ProgramData* pData = m_programs.valueFor(program);
461     if (pData) return true;
462     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
463     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
464     if (spData) return true;
465     return false;
466 }
467 
setupLocationShiftWAR(GLuint program)468 void GLSharedGroup::setupLocationShiftWAR(GLuint program)
469 {
470     android::AutoMutex _lock(m_lock);
471     ProgramData* pData = m_programs.valueFor(program);
472     if (pData) pData->setupLocationShiftWAR();
473 }
474 
locationWARHostToApp(GLuint program,GLint hostLoc,GLint arrIndex)475 GLint GLSharedGroup::locationWARHostToApp(GLuint program, GLint hostLoc, GLint arrIndex)
476 {
477     android::AutoMutex _lock(m_lock);
478     ProgramData* pData = m_programs.valueFor(program);
479     if (pData) return pData->locationWARHostToApp(hostLoc, arrIndex);
480     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return hostLoc;
481     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
482     if (spData) return spData->programData->locationWARHostToApp(hostLoc, arrIndex);
483     return hostLoc;
484 }
485 
locationWARAppToHost(GLuint program,GLint appLoc)486 GLint GLSharedGroup::locationWARAppToHost(GLuint program, GLint appLoc)
487 {
488     android::AutoMutex _lock(m_lock);
489     ProgramData* pData = m_programs.valueFor(program);
490     if (pData) return pData->locationWARAppToHost(appLoc);
491     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return appLoc;
492     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
493     if (spData) return spData->programData->locationWARAppToHost(appLoc);
494     return appLoc;
495 }
496 
needUniformLocationWAR(GLuint program)497 bool GLSharedGroup::needUniformLocationWAR(GLuint program)
498 {
499     android::AutoMutex _lock(m_lock);
500     ProgramData* pData = m_programs.valueFor(program);
501     if (pData) return pData->needUniformLocationWAR();
502     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
503     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
504     if (spData) return spData->programData->needUniformLocationWAR();
505     return false;
506 }
507 
getNextSamplerUniform(GLuint program,GLint index,GLint * val,GLenum * target) const508 GLint GLSharedGroup::getNextSamplerUniform(GLuint program, GLint index, GLint* val, GLenum* target) const
509 {
510     android::AutoMutex _lock(m_lock);
511     ProgramData* pData = m_programs.valueFor(program);
512     if (pData) return pData->getNextSamplerUniform(index, val, target);
513     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return -1;
514     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap.find(program)->second);
515     if (spData) return spData->programData->getNextSamplerUniform(index, val, target);
516     return -1;
517 }
518 
setSamplerUniform(GLuint program,GLint appLoc,GLint val,GLenum * target)519 bool GLSharedGroup::setSamplerUniform(GLuint program, GLint appLoc, GLint val, GLenum* target)
520 {
521     android::AutoMutex _lock(m_lock);
522     ProgramData* pData = m_programs.valueFor(program);
523     if (pData) return pData->setSamplerUniform(appLoc, val, target);
524     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) return false;
525     ShaderProgramData* spData = m_shaderPrograms.valueFor(m_shaderProgramIdMap[program]);
526     if (spData) return spData->programData->setSamplerUniform(appLoc, val, target);
527     return false;
528 }
529 
isShader(GLuint shader)530 bool  GLSharedGroup::isShader(GLuint shader)
531 {
532     android::AutoMutex _lock(m_lock);
533     ShaderData* pData = m_shaders.valueFor(shader);
534     return (pData!=NULL);
535 }
536 
addShaderData(GLuint shader)537 bool GLSharedGroup::addShaderData(GLuint shader)
538 {
539     android::AutoMutex _lock(m_lock);
540     ShaderData* data = new ShaderData;
541     if (data) {
542         if (m_shaders.add(shader, data) < 0) {
543             delete data;
544             data = NULL;
545         }
546         data->refcount = 1;
547     }
548     return data != NULL;
549 }
550 
getShaderData(GLuint shader)551 ShaderData* GLSharedGroup::getShaderData(GLuint shader)
552 {
553     android::AutoMutex _lock(m_lock);
554     return m_shaders.valueFor(shader);
555 }
556 
unrefShaderData(GLuint shader)557 void GLSharedGroup::unrefShaderData(GLuint shader)
558 {
559     android::AutoMutex _lock(m_lock);
560     ssize_t idx = m_shaders.indexOfKey(shader);
561     if (idx >= 0) {
562         unrefShaderDataLocked(idx);
563     }
564 }
565 
refShaderDataLocked(ssize_t shaderIdx)566 void GLSharedGroup::refShaderDataLocked(ssize_t shaderIdx)
567 {
568     assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
569     ShaderData* data = m_shaders.valueAt(shaderIdx);
570     data->refcount++;
571 }
572 
unrefShaderDataLocked(ssize_t shaderIdx)573 void GLSharedGroup::unrefShaderDataLocked(ssize_t shaderIdx)
574 {
575     assert(shaderIdx >= 0 && shaderIdx <= m_shaders.size());
576     ShaderData* data = m_shaders.valueAt(shaderIdx);
577     if (--data->refcount == 0) {
578         delete data;
579         m_shaders.removeItemsAt(shaderIdx);
580     }
581 }
582 
addNewShaderProgramData()583 uint32_t GLSharedGroup::addNewShaderProgramData() {
584     android::AutoMutex _lock(m_lock);
585     ShaderProgramData* data = new ShaderProgramData;
586     uint32_t currId = m_shaderProgramId;
587     ALOGD("%s: new data %p id %u", __FUNCTION__, data, currId);
588     m_shaderPrograms.add(currId, data);
589     m_shaderProgramId++;
590     return currId;
591 }
592 
associateGLShaderProgram(GLuint shaderProgramName,uint32_t shaderProgramId)593 void GLSharedGroup::associateGLShaderProgram(GLuint shaderProgramName, uint32_t shaderProgramId) {
594     android::AutoMutex _lock(m_lock);
595     m_shaderProgramIdMap[shaderProgramName] = shaderProgramId;
596 }
597 
getShaderProgramDataById(uint32_t id)598 ShaderProgramData* GLSharedGroup::getShaderProgramDataById(uint32_t id) {
599     android::AutoMutex _lock(m_lock);
600     ShaderProgramData* res = m_shaderPrograms.valueFor(id);
601     ALOGD("%s: id=%u res=%p", __FUNCTION__, id, res);
602     return res;
603 }
604 
getShaderProgramData(GLuint shaderProgramName)605 ShaderProgramData* GLSharedGroup::getShaderProgramData(GLuint shaderProgramName) {
606     android::AutoMutex _lock(m_lock);
607     return m_shaderPrograms.valueFor(m_shaderProgramIdMap[shaderProgramName]);
608 }
609 
deleteShaderProgramDataById(uint32_t id)610 void GLSharedGroup::deleteShaderProgramDataById(uint32_t id) {
611     android::AutoMutex _lock(m_lock);
612     ShaderProgramData* data = m_shaderPrograms.valueFor(id);
613     delete data;
614     m_shaderPrograms.removeItemsAt(id);
615 }
616 
617 
deleteShaderProgramData(GLuint shaderProgramName)618 void GLSharedGroup::deleteShaderProgramData(GLuint shaderProgramName) {
619     android::AutoMutex _lock(m_lock);
620     uint32_t id = m_shaderProgramIdMap[shaderProgramName];
621     ShaderProgramData* data = m_shaderPrograms.valueFor(id);
622     delete data;
623     m_shaderPrograms.removeItemsAt(id);
624     m_shaderProgramIdMap.erase(shaderProgramName);
625 }
626 
initShaderProgramData(GLuint shaderProgram,GLuint numIndices)627 void GLSharedGroup::initShaderProgramData(GLuint shaderProgram, GLuint numIndices) {
628     ShaderProgramData* spData = getShaderProgramData(shaderProgram);
629     spData->programData->initProgramData(numIndices);
630 }
631 
setShaderProgramIndexInfo(GLuint shaderProgram,GLuint index,GLint base,GLint size,GLenum type,const char * name)632 void GLSharedGroup::setShaderProgramIndexInfo(GLuint shaderProgram, GLuint index, GLint base, GLint size, GLenum type, const char* name) {
633     ShaderProgramData* spData = getShaderProgramData(shaderProgram);
634     ProgramData* pData = spData->programData;
635     ShaderData* sData = spData->shaderData;
636 
637     if (pData)
638     {
639         pData->setIndexInfo(index, base, size, type);
640 
641         if (type == GL_SAMPLER_2D) {
642             ShaderData::StringList::iterator nameIter = sData->samplerExternalNames.begin();
643             ShaderData::StringList::iterator nameEnd  = sData->samplerExternalNames.end();
644             while (nameIter != nameEnd) {
645                 if (*nameIter == name) {
646                     pData->setIndexFlags(index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
647                     break;
648                 }
649                 ++nameIter;
650             }
651         }
652     }
653 }
654 
setupShaderProgramLocationShiftWAR(GLuint shaderProgram)655 void GLSharedGroup::setupShaderProgramLocationShiftWAR(GLuint shaderProgram) {
656     ShaderProgramData* spData = getShaderProgramData(shaderProgram);
657     spData->programData->setupLocationShiftWAR();
658 }
659