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