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