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