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