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