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