• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "KeyedVectorUtils.h"
20 #include "glUtils.h"
21 
22 /**** BufferData ****/
23 
BufferData()24 BufferData::BufferData() : m_size(0), m_usage(0), m_mapped(false) {};
25 
BufferData(GLsizeiptr size,const void * data)26 BufferData::BufferData(GLsizeiptr size, const void* data) :
27     m_size(size), m_usage(0), m_mapped(false) {
28 
29     if (size > 0) {
30         m_fixedBuffer.resize(size);
31     }
32 
33     if (data) {
34         memcpy(m_fixedBuffer.data(), data, size);
35     }
36 }
37 
38 /**** ProgramData ****/
ProgramData()39 ProgramData::ProgramData() : m_numIndexes(0),
40                              m_numAttributes(0),
41                              m_initialized(false) {
42     m_Indexes = NULL;
43     m_attribIndexes = NULL;
44     m_refcount = 1;
45     m_linkStatus = 0;
46     m_activeUniformBlockCount = 0;
47     m_transformFeedbackVaryingsCount = 0;
48 }
49 
initProgramData(GLuint numIndexes,GLuint numAttributes)50 void ProgramData::initProgramData(GLuint numIndexes, GLuint numAttributes) {
51     m_initialized = true;
52     m_numIndexes = numIndexes;
53     m_numAttributes = numAttributes;
54 
55     delete [] m_Indexes;
56     delete [] m_attribIndexes;
57 
58     m_Indexes = new IndexInfo[numIndexes];
59     m_attribIndexes = new AttribInfo[m_numAttributes];
60 }
61 
isInitialized()62 bool ProgramData::isInitialized() {
63     return m_initialized;
64 }
65 
~ProgramData()66 ProgramData::~ProgramData() {
67 
68     delete [] m_Indexes;
69     delete [] m_attribIndexes;
70 
71     m_Indexes = NULL;
72 }
73 
setIndexInfo(GLuint index,GLint base,GLint size,GLenum type)74 void ProgramData::setIndexInfo(
75     GLuint index, GLint base, GLint size, GLenum type) {
76 
77     if (index >= m_numIndexes) return;
78 
79     m_Indexes[index].base = base;
80     m_Indexes[index].size = size;
81     m_Indexes[index].type = type;
82     m_Indexes[index].hostLocsPerElement = 1;
83     m_Indexes[index].flags = 0;
84     m_Indexes[index].samplerValue = 0;
85 }
86 
setAttribInfo(GLuint index,GLint attribLoc,GLint size,GLenum type)87 void ProgramData::setAttribInfo(
88     GLuint index, GLint attribLoc, GLint size, GLenum type) {
89 
90     if (index >= m_numAttributes) return;
91 
92     m_attribIndexes[index].attribLoc = attribLoc;
93     m_attribIndexes[index].size = size;
94     m_attribIndexes[index].type = type;
95 }
96 
setIndexFlags(GLuint index,GLuint flags)97 void ProgramData::setIndexFlags(GLuint index, GLuint flags) {
98 
99     if (index >= m_numIndexes) return;
100 
101     m_Indexes[index].flags |= flags;
102 }
103 
getIndexForLocation(GLint location)104 GLuint ProgramData::getIndexForLocation(GLint location) {
105     GLuint index = m_numIndexes;
106 
107     GLint minDist = -1;
108 
109     for (GLuint i = 0; i < m_numIndexes; ++i) {
110         GLint dist = location - m_Indexes[i].base;
111         if (dist >= 0 && (minDist < 0 || dist < minDist)) {
112             index = i;
113             minDist = dist;
114         }
115     }
116 
117     return index;
118 }
119 
getTypeForLocation(GLint location)120 GLenum ProgramData::getTypeForLocation(GLint location) {
121     GLuint index = getIndexForLocation(location);
122     if (index < m_numIndexes) {
123         return m_Indexes[index].type;
124     }
125     return 0;
126 }
127 
isValidUniformLocation(GLint location)128 bool ProgramData::isValidUniformLocation(GLint location) {
129     for (GLuint i = 0; i < m_numIndexes; ++i) {
130         if (location >= m_Indexes[i].base &&
131             location < m_Indexes[i].base + m_Indexes[i].size)
132             return true;
133     }
134 
135     return false;
136 }
137 
getNextSamplerUniform(GLint index,GLint * val,GLenum * target)138 GLint ProgramData::getNextSamplerUniform(
139     GLint index, GLint* val, GLenum* target) {
140 
141     for (GLint i = index + 1; i >= 0 && i < (GLint)m_numIndexes; i++) {
142 
143         if (m_Indexes[i].type == GL_SAMPLER_2D) {
144 
145             if (val) *val = m_Indexes[i].samplerValue;
146 
147             if (target) {
148                 if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
149                     *target = GL_TEXTURE_EXTERNAL_OES;
150                 } else {
151                     *target = GL_TEXTURE_2D;
152                 }
153             }
154 
155             return i;
156         }
157 
158     }
159 
160     return -1;
161 }
162 
setSamplerUniform(GLint appLoc,GLint val,GLenum * target)163 bool ProgramData::setSamplerUniform(GLint appLoc, GLint val, GLenum* target) {
164 
165     for (GLuint i = 0; i < m_numIndexes; i++) {
166 
167         GLint elemIndex = appLoc - m_Indexes[i].base;
168 
169         if (elemIndex >= 0 && elemIndex < m_Indexes[i].size) {
170             if (m_Indexes[i].type == GL_SAMPLER_2D) {
171                 m_Indexes[i].samplerValue = val;
172                 if (target) {
173                     if (m_Indexes[i].flags & INDEX_FLAG_SAMPLER_EXTERNAL) {
174                         *target = GL_TEXTURE_EXTERNAL_OES;
175                     } else {
176                         *target = GL_TEXTURE_2D;
177 
178                     }
179                 }
180                 return true;
181             }
182         }
183     }
184 
185     return false;
186 }
187 
attachShader(GLuint shader,GLenum shaderType)188 bool ProgramData::attachShader(GLuint shader, GLenum shaderType) {
189     size_t n = m_shaders.size();
190 
191     for (size_t i = 0; i < n; i++) {
192         if (m_shaders[i] == shader) {
193             return false;
194         } else if (m_shaderTypes[i] == shaderType) {
195             return false;
196         }
197     }
198     m_shaders.push_back(shader);
199     m_shaderTypes.push_back(shaderType);
200     return true;
201 }
202 
detachShader(GLuint shader)203 bool ProgramData::detachShader(GLuint shader) {
204     size_t n = m_shaders.size();
205 
206     for (size_t i = 0; i < n; i++) {
207         if (m_shaders[i] == shader) {
208             m_shaders.erase(m_shaders.begin() + i);
209             m_shaderTypes.erase(m_shaderTypes.begin() + i);
210             return true;
211         }
212     }
213 
214     return false;
215 }
216 
compileValidationInfo(bool * error) const217 UniformValidationInfo ProgramData::compileValidationInfo(bool* error) const {
218     UniformValidationInfo res;
219     if (!m_Indexes) {
220         *error = true;
221         return res;
222     }
223 
224     for (GLuint i = 0; i < m_numIndexes; ++i) {
225         if (m_Indexes[i].base < 0) continue;
226 
227         UniformLocationInfo info = {
228             .valid = true,
229             .columns = getColumnsOfType(m_Indexes[i].type),
230             .rows = getRowsOfType(m_Indexes[i].type),
231             .isSampler = isSamplerType(m_Indexes[i].type),
232             .isInt = isIntegerType(m_Indexes[i].type),
233             .isArray = m_Indexes[i].size > 1,
234             .isUnsigned = isUnsignedIntType(m_Indexes[i].type),
235             .isBool = isBoolType(m_Indexes[i].type),
236         };
237         for (GLuint j = 0; j < m_Indexes[i].size; ++j) {
238             res.add(m_Indexes[i].base + j, info);
239         }
240     }
241 
242     return res;
243 }
244 
compileAttribValidationInfo(bool * error) const245 AttribValidationInfo ProgramData::compileAttribValidationInfo(bool* error) const {
246     AttribValidationInfo res;
247     if (!m_attribIndexes) {
248         *error = true;
249         return res;
250     }
251 
252     for (GLuint i = 0; i < m_numAttributes; ++i) {
253         if (m_attribIndexes[i].attribLoc < 0) continue;
254 
255         AttribIndexInfo info = {
256             .validInProgram = true,
257         };
258 
259         for (GLuint j = 0; j < getAttributeCountOfType(m_attribIndexes[i].type) * m_attribIndexes[i].size ; ++j) {
260             res.add(m_attribIndexes[i].attribLoc + j, info);
261         }
262     }
263 
264     return res;
265 }
266 /***** GLSharedGroup ****/
267 
GLSharedGroup()268 GLSharedGroup::GLSharedGroup() { }
269 
~GLSharedGroup()270 GLSharedGroup::~GLSharedGroup() {
271     m_buffers.clear();
272     m_programs.clear();
273     clearObjectMap(m_buffers);
274     clearObjectMap(m_programs);
275     clearObjectMap(m_shaders);
276     clearObjectMap(m_shaderPrograms);
277 }
278 
isShaderOrProgramObject(GLuint obj)279 bool GLSharedGroup::isShaderOrProgramObject(GLuint obj) {
280 
281     android::AutoMutex _lock(m_lock);
282 
283     return (findObjectOrDefault(m_shaders, obj) ||
284             findObjectOrDefault(m_programs, obj) ||
285             findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[obj]));
286 }
287 
getBufferData(GLuint bufferId)288 BufferData* GLSharedGroup::getBufferData(GLuint bufferId) {
289 
290     android::AutoMutex _lock(m_lock);
291 
292     return findObjectOrDefault(m_buffers, bufferId);
293 }
294 
getTextureData()295 SharedTextureDataMap* GLSharedGroup::getTextureData() {
296     return &m_textureRecs;
297 }
298 
getRenderbufferInfo()299 RenderbufferInfo* GLSharedGroup::getRenderbufferInfo() {
300     return &m_renderbufferInfo;
301 }
302 
getSamplerInfo()303 SamplerInfo* GLSharedGroup::getSamplerInfo() {
304     return &m_samplerInfo;
305 }
306 
addBufferData(GLuint bufferId,GLsizeiptr size,const void * data)307 void GLSharedGroup::addBufferData(GLuint bufferId, GLsizeiptr size, const void* data) {
308 
309     android::AutoMutex _lock(m_lock);
310 
311     m_buffers[bufferId] = new BufferData(size, data);
312 }
313 
updateBufferData(GLuint bufferId,GLsizeiptr size,const void * data)314 void GLSharedGroup::updateBufferData(GLuint bufferId, GLsizeiptr size, const void* data) {
315 
316     android::AutoMutex _lock(m_lock);
317 
318     BufferData* currentBuffer = findObjectOrDefault(m_buffers, bufferId);
319 
320     if (currentBuffer) delete currentBuffer;
321 
322     m_buffers[bufferId] = new BufferData(size, data);
323 }
324 
setBufferUsage(GLuint bufferId,GLenum usage)325 void GLSharedGroup::setBufferUsage(GLuint bufferId, GLenum usage) {
326 
327     android::AutoMutex _lock(m_lock);
328 
329     BufferData* data = findObjectOrDefault(m_buffers, bufferId);
330 
331     if (data) data->m_usage = usage;
332 }
333 
setBufferMapped(GLuint bufferId,bool mapped)334 void GLSharedGroup::setBufferMapped(GLuint bufferId, bool mapped) {
335     BufferData* buf = findObjectOrDefault(m_buffers, bufferId);
336 
337     if (!buf) return;
338 
339     buf->m_mapped = mapped;
340 }
341 
getBufferUsage(GLuint bufferId)342 GLenum GLSharedGroup::getBufferUsage(GLuint bufferId) {
343     BufferData* buf = findObjectOrDefault(m_buffers, bufferId);
344 
345     if (!buf) return 0;
346 
347     return buf->m_usage;
348 }
349 
isBufferMapped(GLuint bufferId)350 bool GLSharedGroup::isBufferMapped(GLuint bufferId) {
351     BufferData* buf = findObjectOrDefault(m_buffers, bufferId);
352 
353     if (!buf) return false;
354 
355     return buf->m_mapped;
356 }
357 
subUpdateBufferData(GLuint bufferId,GLintptr offset,GLsizeiptr size,const void * data)358 GLenum GLSharedGroup::subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, const void* data) {
359 
360     android::AutoMutex _lock(m_lock);
361 
362     BufferData* buf = findObjectOrDefault(m_buffers, bufferId);
363 
364     if ((!buf) || (buf->m_size < offset+size) || (offset < 0) || (size<0)) {
365         return GL_INVALID_VALUE;
366     }
367 
368     memcpy(&buf->m_fixedBuffer[offset], data, size);
369 
370     buf->m_indexRangeCache.invalidateRange((size_t)offset, (size_t)size);
371     return GL_NO_ERROR;
372 }
373 
deleteBufferData(GLuint bufferId)374 void GLSharedGroup::deleteBufferData(GLuint bufferId) {
375 
376     android::AutoMutex _lock(m_lock);
377 
378     BufferData* buf = findObjectOrDefault(m_buffers, bufferId);
379     if (buf) {
380         delete buf;
381         m_buffers.erase(bufferId);
382     }
383 }
384 
addProgramData(GLuint program)385 void GLSharedGroup::addProgramData(GLuint program) {
386 
387     android::AutoMutex _lock(m_lock);
388 
389     ProgramData* pData = findObjectOrDefault(m_programs, program);
390     if (pData) {
391         delete pData;
392     }
393 
394     m_programs[program] = new ProgramData();
395 }
396 
initProgramData(GLuint program,GLuint numIndexes,GLuint numAttributes)397 void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes, GLuint numAttributes) {
398 
399     android::AutoMutex _lock(m_lock);
400 
401     ProgramData* pData = findObjectOrDefault(m_programs, program);
402     if (pData) {
403         pData->initProgramData(numIndexes, numAttributes);
404     }
405 }
406 
refProgramData(GLuint program)407 void GLSharedGroup::refProgramData(GLuint program) {
408     android::AutoMutex _lock(m_lock);
409     ProgramData* pData = findObjectOrDefault(m_programs, program);
410     if (!pData) return;
411     pData->incRef();
412 }
413 
onUseProgram(GLuint previous,GLuint next)414 void GLSharedGroup::onUseProgram(GLuint previous, GLuint next) {
415     if (previous == next) return;
416 
417     android::AutoMutex _lock(m_lock);
418 
419     if (previous) {
420         deleteProgramDataLocked(previous);
421     }
422 
423     ProgramData* pData = findObjectOrDefault(m_programs, next);
424     if (!pData) return;
425     pData->incRef();
426 }
427 
isProgramInitialized(GLuint program)428 bool GLSharedGroup::isProgramInitialized(GLuint program) {
429 
430     android::AutoMutex _lock(m_lock);
431 
432     ProgramData* pData = findObjectOrDefault(m_programs, program);
433 
434     if (pData) {
435         return pData->isInitialized();
436     }
437 
438     if (m_shaderProgramIdMap.find(program) == m_shaderProgramIdMap.end()) {
439         return false;
440     }
441 
442     ShaderProgramData* shaderProgramData =
443         findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);
444 
445     if (shaderProgramData) {
446         return shaderProgramData->programData.isInitialized();
447     }
448 
449     return false;
450 }
451 
deleteProgramData(GLuint program)452 void GLSharedGroup::deleteProgramData(GLuint program) {
453     android::AutoMutex _lock(m_lock);
454     deleteProgramDataLocked(program);
455 }
456 
deleteProgramDataLocked(GLuint program)457 void GLSharedGroup::deleteProgramDataLocked(GLuint program) {
458 
459     ProgramData* pData = findObjectOrDefault(m_programs, program);
460 
461     if (pData && pData->decRef()) {
462         size_t numShaders = pData->getNumShaders();
463         for (size_t i = 0; i < numShaders; ++i) {
464             // changes the first one
465             detachShaderLocked(program, pData->getShader(0));
466         }
467         delete pData;
468         m_programs.erase(program);
469     }
470 
471     if (m_shaderProgramIdMap.find(program) ==
472         m_shaderProgramIdMap.end()) return;
473 
474     ShaderProgramData* spData =
475         findObjectOrDefault(
476             m_shaderPrograms, m_shaderProgramIdMap[program]);
477 
478     if (spData) delete spData;
479 
480     m_shaderPrograms.erase(m_shaderProgramIdMap[program]);
481     m_shaderProgramIdMap.erase(program);
482 }
483 
484 // No such thing for separable shader programs.
attachShader(GLuint program,GLuint shader)485 bool GLSharedGroup::attachShader(GLuint program, GLuint shader) {
486     android::AutoMutex _lock(m_lock);
487 
488     ProgramData* pData = findObjectOrDefault(m_programs, program);
489     ShaderData* sData = findObjectOrDefault(m_shaders, shader);
490 
491     bool res = false;
492 
493     if (pData && sData) {
494         res = pData->attachShader(shader, sData->shaderType);
495         if (res) {
496             refShaderDataLocked(shader);
497         }
498     }
499 
500     return res;
501 }
502 
detachShader(GLuint program,GLuint shader)503 bool GLSharedGroup::detachShader(GLuint program, GLuint shader) {
504     android::AutoMutex _lock(m_lock);
505     return detachShaderLocked(program, shader);
506 }
507 
detachShaderLocked(GLuint program,GLuint shader)508 bool GLSharedGroup::detachShaderLocked(GLuint program, GLuint shader) {
509     ProgramData* pData = findObjectOrDefault(m_programs, program);
510     ShaderData* sData = findObjectOrDefault(m_shaders, shader);
511 
512     bool res = false;
513 
514     if (pData && sData) {
515         res = pData->detachShader(shader);
516         if (res) {
517             unrefShaderDataLocked(shader);
518         }
519     }
520 
521     return res;
522 }
523 
524 // Not needed/used for separate shader programs.
setProgramIndexInfo(GLuint program,GLuint index,GLint base,GLint size,GLenum type,const char * name)525 void GLSharedGroup::setProgramIndexInfo(
526     GLuint program, GLuint index, GLint base,
527     GLint size, GLenum type, const char* name) {
528 
529     android::AutoMutex _lock(m_lock);
530 
531     ProgramData* pData = findObjectOrDefault(m_programs, program);
532 
533     if (pData) {
534         pData->setIndexInfo(index,base,size,type);
535         if (type == GL_SAMPLER_2D) {
536             size_t n = pData->getNumShaders();
537             for (size_t i = 0; i < n; i++) {
538                 GLuint shaderId = pData->getShader(i);
539                 ShaderData* shader = findObjectOrDefault(m_shaders, shaderId);
540                 if (!shader) continue;
541                 ShaderData::StringList::iterator nameIter =
542                     shader->samplerExternalNames.begin();
543                 ShaderData::StringList::iterator nameEnd =
544                     shader->samplerExternalNames.end();
545                 while (nameIter != nameEnd) {
546                     if (*nameIter == name) {
547                         pData->setIndexFlags(
548                             index,
549                             ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
550                         break;
551                     }
552                     ++nameIter;
553                 }
554             }
555         }
556     }
557 }
558 
setProgramAttribInfo(GLuint program,GLuint index,GLint attribLoc,GLint size,GLenum type,const char * name)559 void GLSharedGroup::setProgramAttribInfo(
560     GLuint program, GLuint index, GLint attribLoc,
561     GLint size, GLenum type, const char* name) {
562 
563     android::AutoMutex _lock(m_lock);
564 
565     ProgramData* pData = getProgramDataLocked(program);
566 
567     if (pData) {
568         pData->setAttribInfo(index,attribLoc,size,type);
569     }
570 }
571 
getProgramUniformType(GLuint program,GLint location)572 GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location) {
573 
574     android::AutoMutex _lock(m_lock);
575 
576     ProgramData* pData = findObjectOrDefault(m_programs, program);
577     GLenum type = 0;
578 
579     if (pData) {
580         type = pData->getTypeForLocation(location);
581     }
582 
583     if (m_shaderProgramIdMap.find(program) ==
584         m_shaderProgramIdMap.end()) return type;
585 
586     ShaderProgramData* spData =
587         findObjectOrDefault(
588             m_shaderPrograms, m_shaderProgramIdMap[program]);
589 
590     if (spData) {
591         type = spData->programData.getTypeForLocation(location);
592     }
593 
594     return type;
595 }
596 
isProgram(GLuint program)597 bool GLSharedGroup::isProgram(GLuint program) {
598 
599     android::AutoMutex _lock(m_lock);
600 
601     ProgramData* pData = findObjectOrDefault(m_programs, program);
602 
603     if (pData) return true;
604 
605     if (m_shaderProgramIdMap.find(program) ==
606         m_shaderProgramIdMap.end()) return false;
607 
608     ShaderProgramData* spData =
609         findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);
610 
611     if (spData) return true;
612 
613     return false;
614 }
615 
getNextSamplerUniform(GLuint program,GLint index,GLint * val,GLenum * target) const616 GLint GLSharedGroup::getNextSamplerUniform(
617     GLuint program, GLint index, GLint* val, GLenum* target) const {
618 
619     android::AutoMutex _lock(m_lock);
620 
621     ProgramData* pData = findObjectOrDefault(m_programs, program);
622 
623     if (pData) return pData->getNextSamplerUniform(index, val, target);
624 
625     if (m_shaderProgramIdMap.find(program) ==
626         m_shaderProgramIdMap.end()) return -1;
627 
628     ShaderProgramData* spData =
629         findObjectOrDefault(
630             m_shaderPrograms,
631             findObjectOrDefault(m_shaderProgramIdMap, program));
632 
633     if (spData) return spData->programData.getNextSamplerUniform(index, val, target);
634 
635     return -1;
636 }
637 
setSamplerUniform(GLuint program,GLint appLoc,GLint val,GLenum * target)638 bool GLSharedGroup::setSamplerUniform(
639     GLuint program, GLint appLoc, GLint val, GLenum* target) {
640 
641     android::AutoMutex _lock(m_lock);
642 
643     ProgramData* pData =
644         findObjectOrDefault(m_programs, program);
645 
646     if (pData) return pData->setSamplerUniform(appLoc, val, target);
647 
648     if (m_shaderProgramIdMap.find(program) ==
649         m_shaderProgramIdMap.end()) return false;
650 
651     ShaderProgramData* spData =
652         findObjectOrDefault(m_shaderPrograms, m_shaderProgramIdMap[program]);
653 
654     if (spData) return spData->programData.setSamplerUniform(appLoc, val, target);
655 
656     return false;
657 }
658 
isProgramUniformLocationValid(GLuint program,GLint location)659 bool GLSharedGroup::isProgramUniformLocationValid(GLuint program, GLint location) {
660     if (location < 0) return false;
661 
662     android::AutoMutex _lock(m_lock);
663 
664     ProgramData* pData =
665         findObjectOrDefault(m_programs, program);
666 
667     if (!pData) return false;
668 
669     return pData->isValidUniformLocation(location);
670 }
671 
isShader(GLuint shader)672 bool GLSharedGroup::isShader(GLuint shader) {
673 
674     android::AutoMutex _lock(m_lock);
675 
676     ShaderData* pData = findObjectOrDefault(m_shaders, shader);
677 
678     return pData != NULL;
679 }
680 
addShaderData(GLuint shader,GLenum shaderType)681 bool GLSharedGroup::addShaderData(GLuint shader, GLenum shaderType) {
682 
683     android::AutoMutex _lock(m_lock);
684 
685     ShaderData* data = new ShaderData;
686 
687     if (data) {
688         m_shaders[shader] = data;
689         data->refcount = 1;
690         data->shaderType = shaderType;
691     }
692 
693     return data != NULL;
694 }
695 
getShaderData(GLuint shader)696 ShaderData* GLSharedGroup::getShaderData(GLuint shader) {
697 
698     android::AutoMutex _lock(m_lock);
699 
700     return findObjectOrDefault(m_shaders, shader);
701 }
702 
unrefShaderData(GLuint shader)703 void GLSharedGroup::unrefShaderData(GLuint shader) {
704 
705     android::AutoMutex _lock(m_lock);
706 
707     unrefShaderDataLocked(shader);
708 }
709 
refShaderDataLocked(GLuint shaderId)710 void GLSharedGroup::refShaderDataLocked(GLuint shaderId) {
711     ShaderData* data = findObjectOrDefault(m_shaders, shaderId);
712     data->refcount++;
713 }
714 
unrefShaderDataLocked(GLuint shaderId)715 void GLSharedGroup::unrefShaderDataLocked(GLuint shaderId) {
716     ShaderData* data = findObjectOrDefault(m_shaders, shaderId);
717 
718     if (data && --data->refcount == 0) {
719 
720         delete data;
721 
722         m_shaders.erase(shaderId);
723     }
724 }
725 
getProgramDataLocked(GLuint program)726 ProgramData* GLSharedGroup::getProgramDataLocked(GLuint program) {
727     // Check the space of normal programs, then separable ones
728     ProgramData* pData = findObjectOrDefault(m_programs, program);
729 
730     if (pData) return pData;
731 
732     std::map<GLuint, uint32_t>::const_iterator it =
733         m_shaderProgramIdMap.find(program);
734     if (it == m_shaderProgramIdMap.end()) return NULL;
735 
736     ShaderProgramData* spData = findObjectOrDefault(m_shaderPrograms, it->second);
737     if (!spData) return NULL;
738     return &spData->programData;
739 }
740 
addNewShaderProgramData()741 uint32_t GLSharedGroup::addNewShaderProgramData() {
742 
743     android::AutoMutex _lock(m_lock);
744 
745     ShaderProgramData* data = new ShaderProgramData;
746     uint32_t currId = m_shaderProgramId;
747 
748     m_shaderPrograms[currId] = data;
749     m_shaderProgramId++;
750     return currId;
751 }
752 
associateGLShaderProgram(GLuint shaderProgramName,uint32_t shaderProgramId)753 void GLSharedGroup::associateGLShaderProgram(
754     GLuint shaderProgramName, uint32_t shaderProgramId) {
755 
756     android::AutoMutex _lock(m_lock);
757 
758     m_shaderProgramIdMap[shaderProgramName] = shaderProgramId;
759 }
760 
getShaderProgramDataById(uint32_t id)761 ShaderProgramData* GLSharedGroup::getShaderProgramDataById(uint32_t id) {
762 
763     android::AutoMutex _lock(m_lock);
764 
765     ShaderProgramData* res = findObjectOrDefault(m_shaderPrograms, id);
766 
767     return res;
768 }
769 
getShaderProgramData(GLuint shaderProgramName)770 ShaderProgramData* GLSharedGroup::getShaderProgramData(
771     GLuint shaderProgramName) {
772 
773     android::AutoMutex _lock(m_lock);
774 
775     return findObjectOrDefault(m_shaderPrograms,
776                                m_shaderProgramIdMap[shaderProgramName]);
777 }
778 
deleteShaderProgramDataById(uint32_t id)779 void GLSharedGroup::deleteShaderProgramDataById(uint32_t id) {
780 
781     android::AutoMutex _lock(m_lock);
782 
783     ShaderProgramData* data =
784         findObjectOrDefault(m_shaderPrograms, id);
785 
786     delete data;
787 
788     m_shaderPrograms.erase(id);
789 }
790 
791 
deleteShaderProgramData(GLuint shaderProgramName)792 void GLSharedGroup::deleteShaderProgramData(GLuint shaderProgramName) {
793 
794     android::AutoMutex _lock(m_lock);
795 
796     uint32_t id = m_shaderProgramIdMap[shaderProgramName];
797     ShaderProgramData* data = findObjectOrDefault(m_shaderPrograms, id);
798 
799     delete data;
800 
801     m_shaderPrograms.erase(id);
802     m_shaderProgramIdMap.erase(shaderProgramName);
803 }
804 
initShaderProgramData(GLuint shaderProgram,GLuint numIndices,GLuint numAttributes)805 void GLSharedGroup::initShaderProgramData(GLuint shaderProgram, GLuint numIndices, GLuint numAttributes) {
806     ShaderProgramData* spData = getShaderProgramData(shaderProgram);
807     spData->programData.initProgramData(numIndices, numAttributes);
808 }
809 
setShaderProgramIndexInfo(GLuint shaderProgram,GLuint index,GLint base,GLint size,GLenum type,const char * name)810 void GLSharedGroup::setShaderProgramIndexInfo(
811     GLuint shaderProgram, GLuint index, GLint base,
812     GLint size, GLenum type, const char* name) {
813 
814     ShaderProgramData* spData = getShaderProgramData(shaderProgram);
815     ProgramData& pData = spData->programData;
816     ShaderData& sData = spData->shaderData;
817 
818     pData.setIndexInfo(index, base, size, type);
819 
820     if (type == GL_SAMPLER_2D) {
821 
822         ShaderData::StringList::iterator nameIter =
823             sData.samplerExternalNames.begin();
824         ShaderData::StringList::iterator nameEnd =
825             sData.samplerExternalNames.end();
826 
827         while (nameIter != nameEnd) {
828             if (*nameIter == name) {
829                 pData.setIndexFlags(
830                     index, ProgramData::INDEX_FLAG_SAMPLER_EXTERNAL);
831                 break;
832             }
833             ++nameIter;
834         }
835     }
836 }
837 
getUniformValidationInfo(GLuint program)838 UniformValidationInfo GLSharedGroup::getUniformValidationInfo(GLuint program) {
839     UniformValidationInfo res;
840 
841     android::AutoMutex _lock(m_lock);
842 
843     ProgramData* pData =
844         getProgramDataLocked(program);
845 
846     if (!pData) return res;
847 
848     bool error; (void)error;
849     return pData->compileValidationInfo(&error);
850 }
851 
getAttribValidationInfo(GLuint program)852 AttribValidationInfo GLSharedGroup::getAttribValidationInfo(GLuint program) {
853     AttribValidationInfo res;
854 
855     android::AutoMutex _lock(m_lock);
856 
857     ProgramData* pData =
858         getProgramDataLocked(program);
859 
860     if (!pData) return res;
861 
862     bool error; (void)error;
863     return pData->compileAttribValidationInfo(&error);
864 }
865 
setProgramLinkStatus(GLuint program,GLint linkStatus)866 void GLSharedGroup::setProgramLinkStatus(GLuint program, GLint linkStatus) {
867     android::AutoMutex _lock(m_lock);
868     ProgramData* pData =
869         getProgramDataLocked(program);
870     if (!pData) return;
871     pData->setLinkStatus(linkStatus);
872 }
873 
getProgramLinkStatus(GLuint program)874 GLint GLSharedGroup::getProgramLinkStatus(GLuint program) {
875     android::AutoMutex _lock(m_lock);
876     ProgramData* pData = getProgramDataLocked(program);
877     if (!pData) return 0;
878     return pData->getLinkStatus();
879 }
880 
setActiveUniformBlockCountForProgram(GLuint program,GLint count)881 void GLSharedGroup::setActiveUniformBlockCountForProgram(GLuint program, GLint count) {
882     android::AutoMutex _lock(m_lock);
883     ProgramData* pData =
884         getProgramDataLocked(program);
885 
886     if (!pData) return;
887 
888     pData->setActiveUniformBlockCount(count);
889 }
890 
getActiveUniformBlockCount(GLuint program)891 GLint GLSharedGroup::getActiveUniformBlockCount(GLuint program) {
892     android::AutoMutex _lock(m_lock);
893     ProgramData* pData =
894         getProgramDataLocked(program);
895 
896     if (!pData) return 0;
897 
898     return pData->getActiveUniformBlockCount();
899 }
900 
setTransformFeedbackVaryingsCountForProgram(GLuint program,GLint count)901 void GLSharedGroup::setTransformFeedbackVaryingsCountForProgram(GLuint program, GLint count) {
902     android::AutoMutex _lock(m_lock);
903     ProgramData* pData = getProgramDataLocked(program);
904     if (!pData) return;
905     pData->setTransformFeedbackVaryingsCount(count);
906 }
907 
getTransformFeedbackVaryingsCountForProgram(GLuint program)908 GLint GLSharedGroup::getTransformFeedbackVaryingsCountForProgram(GLuint program) {
909     android::AutoMutex _lock(m_lock);
910     ProgramData* pData = getProgramDataLocked(program);
911     if (!pData) return 0;
912     return pData->getTransformFeedbackVaryingsCount();
913 }
914 
getActiveUniformsCountForProgram(GLuint program)915 int GLSharedGroup::getActiveUniformsCountForProgram(GLuint program) {
916     android::AutoMutex _lock(m_lock);
917     ProgramData* pData =
918         getProgramDataLocked(program);
919 
920     if (!pData) return 0;
921 
922     return pData->getActiveUniformsCount();
923 }
924 
getActiveAttributesCountForProgram(GLuint program)925 int GLSharedGroup::getActiveAttributesCountForProgram(GLuint program) {
926     android::AutoMutex _lock(m_lock);
927     ProgramData* pData =
928         getProgramDataLocked(program);
929 
930     if (!pData) return 0;
931 
932     return pData->getActiveAttributesCount();
933 }
934 
935