blob: 6e9c8f67bdc050c6e035a93cd4796e470da689a3 [file] [log] [blame]
keunyoungb85b2752013-03-08 12:28:03 -08001/*
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#include "GLClientState.h"
Lingfeng Yang74e29292017-01-10 14:54:38 -080017#include "GLESTextureUtils.h"
keunyoungb85b2752013-03-08 12:28:03 -080018#include "ErrorLog.h"
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include "glUtils.h"
23#include <cutils/log.h>
24
25#ifndef MAX
26#define MAX(a, b) ((a) < (b) ? (b) : (a))
27#endif
28
Lingfeng Yang74e29292017-01-10 14:54:38 -080029// Don't include these in the .h file, or we get weird compile errors.
30#include <GLES3/gl3.h>
31#include <GLES3/gl31.h>
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080032
33void GLClientState::init() {
34 m_initialized = false;
35 m_nLocations = CODEC_MAX_VERTEX_ATTRIBUTES;
36
37 m_arrayBuffer = 0;
38 m_max_vertex_attrib_bindings = m_nLocations;
39 addVertexArrayObject(0);
40 setVertexArrayObject(0);
keunyoungb85b2752013-03-08 12:28:03 -080041 // init gl constans;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080042 m_currVaoState[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
43 m_currVaoState[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
44 m_currVaoState[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
45 m_currVaoState[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
46 m_currVaoState[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
47 m_currVaoState[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
48 m_currVaoState[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
49 m_currVaoState[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
50 m_currVaoState[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
51 m_currVaoState[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
52 m_currVaoState[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
53 m_currVaoState[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
54 m_currVaoState[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
55 m_currVaoState[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
56
57 m_copyReadBuffer = 0;
58 m_copyWriteBuffer = 0;
59 m_pixelPackBuffer = 0;
60 m_pixelUnpackBuffer = 0;
61 m_transformFeedbackBuffer = 0;
62 m_uniformBuffer = 0;
63 m_atomicCounterBuffer = 0;
64 m_dispatchIndirectBuffer = 0;
65 m_drawIndirectBuffer = 0;
66 m_shaderStorageBuffer = 0;
67
68 m_transformFeedbackActiveUnpaused = false;
69
70 // to be modified later when these are queried from host.
71 m_max_transform_feedback_separate_attribs = 0;
72 m_max_uniform_buffer_bindings = 0;
73 m_max_atomic_counter_buffer_bindings = 0;
74 m_max_shader_storage_buffer_bindings = 0;
75
keunyoungb85b2752013-03-08 12:28:03 -080076 m_activeTexture = 0;
77 m_currentProgram = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -080078 m_currentShaderProgram = 0;
keunyoungb85b2752013-03-08 12:28:03 -080079
80 m_pixelStore.unpack_alignment = 4;
81 m_pixelStore.pack_alignment = 4;
82
Lingfeng Yang74e29292017-01-10 14:54:38 -080083 m_pixelStore.unpack_row_length = 0;
84 m_pixelStore.unpack_image_height = 0;
85 m_pixelStore.unpack_skip_pixels = 0;
86 m_pixelStore.unpack_skip_rows = 0;
87 m_pixelStore.unpack_skip_images = 0;
88
89 m_pixelStore.pack_row_length = 0;
90 m_pixelStore.pack_skip_pixels = 0;
91 m_pixelStore.pack_skip_rows = 0;
92
keunyoungb85b2752013-03-08 12:28:03 -080093 memset(m_tex.unit, 0, sizeof(m_tex.unit));
94 m_tex.activeUnit = &m_tex.unit[0];
Lingfeng Yang74e29292017-01-10 14:54:38 -080095 m_tex.textureRecs = NULL;
Lingfeng Yangb0176982016-03-01 21:27:49 -080096
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070097 mRboState.boundRenderbuffer = 0;
98 mRboState.boundRenderbufferIndex = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070099
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800100 mFboState.boundDrawFramebuffer = 0;
101 mFboState.boundReadFramebuffer = 0;
102 mFboState.drawFboCheckStatus = GL_NONE;
103 mFboState.readFboCheckStatus = GL_NONE;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700104
Lingfeng Yangb0176982016-03-01 21:27:49 -0800105 m_maxVertexAttribsDirty = true;
keunyoungb85b2752013-03-08 12:28:03 -0800106}
107
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800108GLClientState::GLClientState()
109{
110 init();
111}
112
113GLClientState::GLClientState(int majorVersion, int minorVersion) :
114 m_glesMajorVersion(majorVersion),
115 m_glesMinorVersion(minorVersion) {
116 init();
117}
118
keunyoungb85b2752013-03-08 12:28:03 -0800119GLClientState::~GLClientState()
120{
keunyoungb85b2752013-03-08 12:28:03 -0800121}
122
123void GLClientState::enable(int location, int state)
124{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800125 m_currVaoState[location].enableDirty |= (state != m_currVaoState[location].enabled);
126 m_currVaoState[location].enabled = state;
127}
128
129void GLClientState::setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt)
130{
131 m_currVaoState[location].size = size;
132 m_currVaoState[location].type = type;
133 m_currVaoState[location].stride = stride;
134 m_currVaoState[location].data = (void*)data;
135 m_currVaoState[location].bufferObject = m_arrayBuffer;
136 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
137 switch (type) {
138 case GL_INT_2_10_10_10_REV:
139 case GL_UNSIGNED_INT_2_10_10_10_REV:
140 m_currVaoState[location].elementSize =
141 m_currVaoState[location].elementSize / 4;
142 break;
143 default:
144 break;
145 }
146 m_currVaoState[location].normalized = normalized;
147 m_currVaoState[location].isInt = isInt;
148}
149
150void GLClientState::setVertexBindingDivisor(int bindingindex, GLuint divisor) {
151 m_currVaoState.bufferBinding(bindingindex).divisor = divisor;
152}
153
154const GLClientState::BufferBinding& GLClientState::getCurrAttributeBindingInfo(int attribindex) {
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -0800155 return m_currVaoState.bufferBindings_const()[m_currVaoState[attribindex].bindingindex];
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800156}
157
158void GLClientState::setVertexAttribBinding(int attribindex, int bindingindex) {
159 m_currVaoState[attribindex].bindingindex = bindingindex;
160}
161
162void GLClientState::setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) {
163 m_currVaoState[location].size = size;
164 m_currVaoState[location].type = type;
165 m_currVaoState[location].normalized = normalized;
166 m_currVaoState[location].reloffset = reloffset;
167 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
168 switch (type) {
169 case GL_INT_2_10_10_10_REV:
170 case GL_UNSIGNED_INT_2_10_10_10_REV:
171 m_currVaoState[location].elementSize =
172 m_currVaoState[location].elementSize / 4;
173 break;
174 default:
175 break;
176 }
177 m_currVaoState[location].isInt = isInt;
178}
179
180void GLClientState::addVertexArrayObjects(GLsizei n, GLuint* arrays) {
181 for (GLsizei i = 0; i < n; i++) {
182 addVertexArrayObject(arrays[i]);
183 }
184}
185
186void GLClientState::removeVertexArrayObjects(GLsizei n, const GLuint* arrays) {
187 for (GLsizei i = 0; i < n; i++) {
188 if (arrays[i] && m_currVaoState.vaoId() == arrays[i]) {
189 setVertexArrayObject(0);
190 }
191 removeVertexArrayObject(arrays[i]);
192 }
193}
194
195void GLClientState::addVertexArrayObject(GLuint name) {
196 if (m_vaoMap.find(name) !=
197 m_vaoMap.end()) {
198 ALOGE("%s: ERROR: %u already part of current VAO state!",
199 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800200 return;
201 }
202
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800203 m_vaoMap.insert(
204 VAOStateMap::value_type(
205 name,
206 VAOState(0, m_nLocations, std::max(m_nLocations, m_max_vertex_attrib_bindings))));
207 VertexAttribStateVector& attribState =
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -0800208 m_vaoMap.find(name)->second.attribState;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800209 for (int i = 0; i < m_nLocations; i++) {
210 attribState[i].enabled = 0;
211 attribState[i].enableDirty = false;
212 attribState[i].data = 0;
213 attribState[i].reloffset = 0;
214 attribState[i].bindingindex = i;
215 attribState[i].divisor = 0;
216 attribState[i].size = 4; // 4 is the default size
217 attribState[i].type = GL_FLOAT; // GL_FLOAT is the default type
218 }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800219
220 VertexAttribBindingVector& bindingState =
221 m_vaoMap.find(name)->second.bindingState;
222 for (int i = 0; i < bindingState.size(); i++) {
223 bindingState[i].effectiveStride = 16;
224 }
keunyoungb85b2752013-03-08 12:28:03 -0800225}
226
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800227void GLClientState::removeVertexArrayObject(GLuint name) {
228 if (name == 0) {
229 ALOGE("%s: ERROR: cannot delete VAO 0!",
230 __FUNCTION__);
keunyoungb85b2752013-03-08 12:28:03 -0800231 return;
232 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800233 if (m_vaoMap.find(name) ==
234 m_vaoMap.end()) {
235 ALOGE("%s: ERROR: %u not found in VAO state!",
236 __FUNCTION__, name);
237 return;
238 }
239 m_vaoMap.erase(name);
keunyoungb85b2752013-03-08 12:28:03 -0800240}
241
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800242void GLClientState::setVertexArrayObject(GLuint name) {
243 if (m_vaoMap.find(name) ==
244 m_vaoMap.end()) {
245 ALOGE("%s: ERROR: %u not found in VAO state!",
246 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800247 return;
248 }
249
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800250 if (name && m_currVaoState.vaoId() == name) {
251 ALOGV("%s: set vao to self, no-op (%u)",
252 __FUNCTION__, name);
253 return;
keunyoungb85b2752013-03-08 12:28:03 -0800254 }
255
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800256 m_currVaoState =
257 VAOStateRef(m_vaoMap.find(name));
258 ALOGV("%s: set vao to %u (%u) %u %u", __FUNCTION__,
259 name,
260 m_currVaoState.vaoId(),
261 m_arrayBuffer,
262 m_currVaoState.iboId());
263}
264
265bool GLClientState::isVertexArrayObject(GLuint vao) const {
266 return m_vaoMap.find(vao) != m_vaoMap.end();
267}
268
269const GLClientState::VertexAttribState& GLClientState::getState(int location)
270{
271 return m_currVaoState[location];
272}
273
274const GLClientState::VertexAttribState& GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
275{
keunyoungb85b2752013-03-08 12:28:03 -0800276 if (enableChanged) {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800277 *enableChanged = m_currVaoState[location].enableDirty;
keunyoungb85b2752013-03-08 12:28:03 -0800278 }
279
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800280 m_currVaoState[location].enableDirty = false;
281 return m_currVaoState[location];
keunyoungb85b2752013-03-08 12:28:03 -0800282}
283
284int GLClientState::getLocation(GLenum loc)
285{
286 int retval;
287
288 switch(loc) {
289 case GL_VERTEX_ARRAY:
290 retval = int(VERTEX_LOCATION);
291 break;
292 case GL_NORMAL_ARRAY:
293 retval = int(NORMAL_LOCATION);
294 break;
295 case GL_COLOR_ARRAY:
296 retval = int(COLOR_LOCATION);
297 break;
298 case GL_POINT_SIZE_ARRAY_OES:
299 retval = int(POINTSIZE_LOCATION);
300 break;
301 case GL_TEXTURE_COORD_ARRAY:
302 retval = int (TEXCOORD0_LOCATION + m_activeTexture);
303 break;
304 case GL_MATRIX_INDEX_ARRAY_OES:
305 retval = int (MATRIXINDEX_LOCATION);
306 break;
307 case GL_WEIGHT_ARRAY_OES:
308 retval = int (WEIGHT_LOCATION);
309 break;
310 default:
311 retval = loc;
312 }
313 return retval;
314}
315
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800316static void sClearIndexedBufferBinding(GLuint id, std::vector<GLClientState::BufferBinding>& bindings) {
317 for (size_t i = 0; i < bindings.size(); i++) {
318 if (bindings[i].buffer == id) {
319 bindings[i].offset = 0;
320 bindings[i].stride = 0;
321 bindings[i].effectiveStride = 16;
322 bindings[i].size = 0;
323 bindings[i].buffer = 0;
324 bindings[i].divisor = 0;
325 }
326 }
327}
328
329void GLClientState::addBuffer(GLuint id) {
330 mBufferIds.insert(id);
331}
332
333void GLClientState::removeBuffer(GLuint id) {
334 mBufferIds.erase(id);
335}
336
337bool GLClientState::bufferIdExists(GLuint id) const {
338 return mBufferIds.find(id) != mBufferIds.end();
339}
340
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800341void GLClientState::unBindBuffer(GLuint id) {
342 if (m_arrayBuffer == id) m_arrayBuffer = 0;
343 if (m_currVaoState.iboId() == id) m_currVaoState.iboId() = 0;
344 if (m_copyReadBuffer == id)
345 m_copyReadBuffer = 0;
346 if (m_copyWriteBuffer == id)
347 m_copyWriteBuffer = 0;
348 if (m_pixelPackBuffer == id)
349 m_pixelPackBuffer = 0;
350 if (m_pixelUnpackBuffer == id)
351 m_pixelUnpackBuffer = 0;
352 if (m_transformFeedbackBuffer == id)
353 m_transformFeedbackBuffer = 0;
354 if (m_uniformBuffer == id)
355 m_uniformBuffer = 0;
356 if (m_atomicCounterBuffer == id)
357 m_atomicCounterBuffer = 0;
358 if (m_dispatchIndirectBuffer == id)
359 m_dispatchIndirectBuffer = 0;
360 if (m_drawIndirectBuffer == id)
361 m_drawIndirectBuffer = 0;
362 if (m_shaderStorageBuffer == id)
363 m_shaderStorageBuffer = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800364
365 sClearIndexedBufferBinding(id, m_indexedTransformFeedbackBuffers);
366 sClearIndexedBufferBinding(id, m_indexedUniformBuffers);
367 sClearIndexedBufferBinding(id, m_indexedAtomicCounterBuffers);
368 sClearIndexedBufferBinding(id, m_indexedShaderStorageBuffers);
369 sClearIndexedBufferBinding(id, m_currVaoState.bufferBindings());
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800370}
371
372int GLClientState::bindBuffer(GLenum target, GLuint id)
373{
374 int err = 0;
375 switch(target) {
376 case GL_ARRAY_BUFFER:
377 m_arrayBuffer = id;
378 break;
379 case GL_ELEMENT_ARRAY_BUFFER:
380 m_currVaoState.iboId() = id;
381 break;
382 case GL_COPY_READ_BUFFER:
383 m_copyReadBuffer = id;
384 break;
385 case GL_COPY_WRITE_BUFFER:
386 m_copyWriteBuffer = id;
387 break;
388 case GL_PIXEL_PACK_BUFFER:
389 m_pixelPackBuffer = id;
390 break;
391 case GL_PIXEL_UNPACK_BUFFER:
392 m_pixelUnpackBuffer = id;
393 break;
394 case GL_TRANSFORM_FEEDBACK_BUFFER:
395 m_transformFeedbackBuffer = id;
396 break;
397 case GL_UNIFORM_BUFFER:
398 m_uniformBuffer = id;
399 break;
400 case GL_ATOMIC_COUNTER_BUFFER:
401 m_atomicCounterBuffer = id;
402 break;
403 case GL_DISPATCH_INDIRECT_BUFFER:
404 m_dispatchIndirectBuffer = id;
405 break;
406 case GL_DRAW_INDIRECT_BUFFER:
407 m_drawIndirectBuffer = id;
408 break;
409 case GL_SHADER_STORAGE_BUFFER:
410 m_shaderStorageBuffer = id;
411 break;
412 default:
413 err = -1;
414 }
415 return err;
416}
417
418void GLClientState::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) {
419 switch (target) {
420 case GL_TRANSFORM_FEEDBACK_BUFFER:
421 m_indexedTransformFeedbackBuffers[index].buffer = buffer;
422 m_indexedTransformFeedbackBuffers[index].offset = offset;
423 m_indexedTransformFeedbackBuffers[index].size = size;
424 m_indexedTransformFeedbackBuffers[index].stride = stride;
425 break;
426 case GL_UNIFORM_BUFFER:
427 m_indexedUniformBuffers[index].buffer = buffer;
428 m_indexedUniformBuffers[index].offset = offset;
429 m_indexedUniformBuffers[index].size = size;
430 m_indexedUniformBuffers[index].stride = stride;
431 break;
432 case GL_ATOMIC_COUNTER_BUFFER:
433 m_indexedAtomicCounterBuffers[index].buffer = buffer;
434 m_indexedAtomicCounterBuffers[index].offset = offset;
435 m_indexedAtomicCounterBuffers[index].size = size;
436 m_indexedAtomicCounterBuffers[index].stride = stride;
437 break;
438 case GL_SHADER_STORAGE_BUFFER:
439 m_indexedShaderStorageBuffers[index].buffer = buffer;
440 m_indexedShaderStorageBuffers[index].offset = offset;
441 m_indexedShaderStorageBuffers[index].size = size;
442 m_indexedShaderStorageBuffers[index].stride = stride;
443 break;
444 default:
445 m_currVaoState.bufferBinding(index).buffer = buffer;
446 m_currVaoState.bufferBinding(index).offset = offset;
447 m_currVaoState.bufferBinding(index).size = size;
448 m_currVaoState.bufferBinding(index).stride = stride;
449 m_currVaoState.bufferBinding(index).effectiveStride = effectiveStride;
450 return;
451 }
452}
453
454int GLClientState::getMaxIndexedBufferBindings(GLenum target) const {
455 switch (target) {
456 case GL_TRANSFORM_FEEDBACK_BUFFER:
457 return m_indexedTransformFeedbackBuffers.size();
458 case GL_UNIFORM_BUFFER:
459 return m_indexedUniformBuffers.size();
460 case GL_ATOMIC_COUNTER_BUFFER:
461 return m_indexedAtomicCounterBuffers.size();
462 case GL_SHADER_STORAGE_BUFFER:
463 return m_indexedShaderStorageBuffers.size();
464 default:
465 return m_currVaoState.bufferBindings_const().size();
466 }
467}
468
469int GLClientState::getBuffer(GLenum target) {
470 int ret=0;
471 switch (target) {
472 case GL_ARRAY_BUFFER:
473 ret = m_arrayBuffer;
474 break;
475 case GL_ELEMENT_ARRAY_BUFFER:
476 ret = m_currVaoState.iboId();
477 break;
478 case GL_COPY_READ_BUFFER:
479 ret = m_copyReadBuffer;
480 break;
481 case GL_COPY_WRITE_BUFFER:
482 ret = m_copyWriteBuffer;
483 break;
484 case GL_PIXEL_PACK_BUFFER:
485 ret = m_pixelPackBuffer;
486 break;
487 case GL_PIXEL_UNPACK_BUFFER:
488 ret = m_pixelUnpackBuffer;
489 break;
490 case GL_TRANSFORM_FEEDBACK_BUFFER:
491 ret = m_transformFeedbackBuffer;
492 break;
493 case GL_UNIFORM_BUFFER:
494 ret = m_uniformBuffer;
495 break;
496 case GL_ATOMIC_COUNTER_BUFFER:
497 ret = m_atomicCounterBuffer;
498 break;
499 case GL_DISPATCH_INDIRECT_BUFFER:
500 ret = m_dispatchIndirectBuffer;
501 break;
502 case GL_DRAW_INDIRECT_BUFFER:
503 ret = m_drawIndirectBuffer;
504 break;
505 case GL_SHADER_STORAGE_BUFFER:
506 ret = m_shaderStorageBuffer;
507 break;
508 default:
509 ret = -1;
510 }
511 return ret;
512}
513
keunyoungb85b2752013-03-08 12:28:03 -0800514void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
515{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800516 GLenum which_state = -1;
keunyoungb85b2752013-03-08 12:28:03 -0800517 switch (pname) {
518 case GL_VERTEX_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800519 which_state = GLClientState::VERTEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800520 break;
521 }
522 case GL_NORMAL_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800523 which_state = GLClientState::NORMAL_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800524 break;
525 }
526 case GL_COLOR_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800527 which_state = GLClientState::COLOR_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800528 break;
529 }
530 case GL_TEXTURE_COORD_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800531 which_state = getActiveTexture() + GLClientState::TEXCOORD0_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800532 break;
533 }
534 case GL_POINT_SIZE_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800535 which_state = GLClientState::POINTSIZE_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800536 break;
537 }
538 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800539 which_state = GLClientState::MATRIXINDEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800540 break;
541 }
542 case GL_WEIGHT_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800543 which_state = GLClientState::WEIGHT_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800544 break;
545 }
546 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800547 if (which_state != -1)
548 *params = getState(which_state).data;
keunyoungb85b2752013-03-08 12:28:03 -0800549}
550
551int GLClientState::setPixelStore(GLenum param, GLint value)
552{
553 int retval = 0;
554 switch(param) {
555 case GL_UNPACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800556 m_pixelStore.unpack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800557 break;
558 case GL_PACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800559 m_pixelStore.pack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800560 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800561 case GL_UNPACK_ROW_LENGTH:
562 m_pixelStore.unpack_row_length = value;
563 break;
564 case GL_UNPACK_IMAGE_HEIGHT:
565 m_pixelStore.unpack_image_height = value;
566 break;
567 case GL_UNPACK_SKIP_PIXELS:
568 m_pixelStore.unpack_skip_pixels = value;
569 break;
570 case GL_UNPACK_SKIP_ROWS:
571 m_pixelStore.unpack_skip_rows = value;
572 break;
573 case GL_UNPACK_SKIP_IMAGES:
574 m_pixelStore.unpack_skip_images = value;
575 break;
576 case GL_PACK_ROW_LENGTH:
577 m_pixelStore.pack_row_length = value;
578 break;
579 case GL_PACK_SKIP_PIXELS:
580 m_pixelStore.pack_skip_pixels = value;
581 break;
582 case GL_PACK_SKIP_ROWS:
583 m_pixelStore.pack_skip_rows = value;
584 break;
585 default:
586 retval = GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800587 }
588 return retval;
589}
590
591
Lingfeng Yang74e29292017-01-10 14:54:38 -0800592size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
keunyoungb85b2752013-03-08 12:28:03 -0800593{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800594 if (width <= 0 || height <= 0 || depth <= 0) return 0;
bohubd119bf2014-10-17 13:48:06 -0700595
Lingfeng Yang74e29292017-01-10 14:54:38 -0800596 ALOGV("%s: pack? %d", __FUNCTION__, pack);
597 if (pack) {
598 ALOGV("%s: pack stats", __FUNCTION__);
599 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
600 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
601 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
602 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
603 } else {
604 ALOGV("%s: unpack stats", __FUNCTION__);
605 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
606 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
607 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
608 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
609 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
610 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800611 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800612 return GLESTextureUtils::computeTotalImageSize(
613 width, height, depth,
614 format, type,
615 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
616 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
617 pack ? 0 : m_pixelStore.unpack_image_height,
618 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
619 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
620 pack ? 0 : m_pixelStore.unpack_skip_images);
621}
622
623size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
624{
625 if (width <= 0 || height <= 0 || depth <= 0) return 0;
626
627 ALOGV("%s: pack? %d", __FUNCTION__, pack);
628 if (pack) {
629 ALOGV("%s: pack stats", __FUNCTION__);
630 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
631 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
632 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
633 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
634 } else {
635 ALOGV("%s: unpack stats", __FUNCTION__);
636 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
637 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
638 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
639 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
640 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
641 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800642 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800643 return GLESTextureUtils::computeNeededBufferSize(
644 width, height, depth,
645 format, type,
646 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
647 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
648 pack ? 0 : m_pixelStore.unpack_image_height,
649 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
650 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
651 pack ? 0 : m_pixelStore.unpack_skip_images);
652}
653
654
655size_t GLClientState::clearBufferNumElts(GLenum buffer) const
656{
657 switch (buffer) {
658 case GL_COLOR:
659 return 4;
660 case GL_DEPTH:
661 case GL_STENCIL:
662 return 1;
663 }
664 return 1;
665}
666
667void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) {
668 UniformBlockInfoKey key;
669 key.program = program;
670 key.uniformBlockIndex = uniformBlockIndex;
671
672 UniformBlockUniformInfo info;
673 info.numActiveUniforms = (size_t)numActiveUniforms;
674
675 m_uniformBlockInfoMap[key] = info;
676}
677
678size_t GLClientState::numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const {
679 UniformBlockInfoKey key;
680 key.program = program;
681 key.uniformBlockIndex = uniformBlockIndex;
682 UniformBlockInfoMap::const_iterator it =
683 m_uniformBlockInfoMap.find(key);
684 if (it == m_uniformBlockInfoMap.end()) return 0;
685 return it->second.numActiveUniforms;
686}
687
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800688void GLClientState::associateProgramWithPipeline(GLuint program, GLuint pipeline) {
689 m_programPipelines[program] = pipeline;
690}
691
692GLClientState::ProgramPipelineIterator GLClientState::programPipelineBegin() {
693 return m_programPipelines.begin();
694}
695
696GLClientState::ProgramPipelineIterator GLClientState::programPipelineEnd() {
697 return m_programPipelines.end();
keunyoungb85b2752013-03-08 12:28:03 -0800698}
699
700GLenum GLClientState::setActiveTextureUnit(GLenum texture)
701{
702 GLuint unit = texture - GL_TEXTURE0;
703 if (unit >= MAX_TEXTURE_UNITS) {
Yahan Zhoudb856572016-03-01 12:03:48 -0800704 return GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800705 }
706 m_tex.activeUnit = &m_tex.unit[unit];
707 return GL_NO_ERROR;
708}
709
710GLenum GLClientState::getActiveTextureUnit() const
711{
712 return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
713}
714
715void GLClientState::enableTextureTarget(GLenum target)
716{
717 switch (target) {
718 case GL_TEXTURE_2D:
719 m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
720 break;
721 case GL_TEXTURE_EXTERNAL_OES:
722 m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
723 break;
724 }
725}
726
727void GLClientState::disableTextureTarget(GLenum target)
728{
729 switch (target) {
730 case GL_TEXTURE_2D:
731 m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
732 break;
733 case GL_TEXTURE_EXTERNAL_OES:
734 m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
735 break;
736 }
737}
738
739GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
740{
741 unsigned int enables = m_tex.activeUnit->enables;
742 if (enables & (1u << TEXTURE_EXTERNAL)) {
743 return GL_TEXTURE_EXTERNAL_OES;
744 } else if (enables & (1u << TEXTURE_2D)) {
745 return GL_TEXTURE_2D;
746 } else {
747 return allDisabled;
748 }
749}
750
751int GLClientState::compareTexId(const void* pid, const void* prec)
752{
753 const GLuint* id = (const GLuint*)pid;
754 const TextureRec* rec = (const TextureRec*)prec;
755 return (GLint)(*id) - (GLint)rec->id;
756}
757
758GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
759 GLboolean* firstUse)
760{
761 GLboolean first = GL_FALSE;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800762
763 TextureRec* texrec = getTextureRec(texture);
764 if (!texrec) {
765 texrec = addTextureRec(texture, target);
766 }
767
768 if (texture && target != texrec->target &&
769 (target != GL_TEXTURE_EXTERNAL_OES &&
770 texrec->target != GL_TEXTURE_EXTERNAL_OES)) {
771 ALOGD("%s: issue GL_INVALID_OPERATION: target 0x%x texrectarget 0x%x texture %u", __FUNCTION__, target, texrec->target, texture);
keunyoungb85b2752013-03-08 12:28:03 -0800772 }
773
774 switch (target) {
775 case GL_TEXTURE_2D:
776 m_tex.activeUnit->texture[TEXTURE_2D] = texture;
777 break;
778 case GL_TEXTURE_EXTERNAL_OES:
779 m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
780 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800781 case GL_TEXTURE_CUBE_MAP:
782 m_tex.activeUnit->texture[TEXTURE_CUBE_MAP] = texture;
783 break;
784 case GL_TEXTURE_2D_ARRAY:
785 m_tex.activeUnit->texture[TEXTURE_2D_ARRAY] = texture;
786 break;
787 case GL_TEXTURE_3D:
788 m_tex.activeUnit->texture[TEXTURE_3D] = texture;
789 break;
790 case GL_TEXTURE_2D_MULTISAMPLE:
791 m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE] = texture;
792 break;
keunyoungb85b2752013-03-08 12:28:03 -0800793 }
794
795 if (firstUse) {
796 *firstUse = first;
797 }
798
799 return GL_NO_ERROR;
800}
801
Lingfeng Yang74e29292017-01-10 14:54:38 -0800802void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) {
803 GLuint texture = getBoundTexture(target);
804 TextureRec* texrec = getTextureRec(texture);
805 if (!texrec) return;
806 texrec->boundEGLImage = true;
807}
808
809TextureRec* GLClientState::addTextureRec(GLuint id, GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -0800810{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800811 TextureRec* tex = new TextureRec;
keunyoungb85b2752013-03-08 12:28:03 -0800812 tex->id = id;
813 tex->target = target;
Lingfeng Yang69066602016-04-12 09:29:11 -0700814 tex->format = -1;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800815 tex->multisamples = 0;
816 tex->immutable = false;
817 tex->boundEGLImage = false;
818 tex->dims = new TextureDims;
keunyoungb85b2752013-03-08 12:28:03 -0800819
Lingfeng Yang74e29292017-01-10 14:54:38 -0800820 (*(m_tex.textureRecs))[id] = tex;
keunyoungb85b2752013-03-08 12:28:03 -0800821 return tex;
822}
823
Lingfeng Yang74e29292017-01-10 14:54:38 -0800824TextureRec* GLClientState::getTextureRec(GLuint id) const {
825 SharedTextureDataMap::const_iterator it =
826 m_tex.textureRecs->find(id);
827 if (it == m_tex.textureRecs->end()) {
828 return NULL;
829 }
830 return it->second;
831}
832
Lingfeng Yang69066602016-04-12 09:29:11 -0700833void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
834 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800835 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700836 if (!texrec) return;
837 texrec->internalformat = internalformat;
838}
839
840void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) {
841 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800842 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700843 if (!texrec) return;
844 texrec->format = format;
845}
846
847void GLClientState::setBoundTextureType(GLenum target, GLenum type) {
848 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800849 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700850 if (!texrec) return;
851 texrec->type = type;
852}
853
Lingfeng Yang74e29292017-01-10 14:54:38 -0800854void GLClientState::setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) {
855 GLuint texture = getBoundTexture(target);
856 TextureRec* texrec = getTextureRec(texture);
857 if (!texrec) {
858 return;
859 }
860
861 if (level == -1) {
862 GLsizei curr_width = width;
863 GLsizei curr_height = height;
864 GLsizei curr_depth = depth;
865 GLsizei curr_level = 0;
866
867 while (true) {
868 texrec->dims->widths[curr_level] = curr_width;
869 texrec->dims->heights[curr_level] = curr_height;
870 texrec->dims->depths[curr_level] = curr_depth;
871 if (curr_width >> 1 == 0 &&
872 curr_height >> 1 == 0 &&
873 ((target == GL_TEXTURE_3D && curr_depth == 0) ||
874 true)) {
875 break;
876 }
877 curr_width = (curr_width >> 1) ? (curr_width >> 1) : 1;
878 curr_height = (curr_height >> 1) ? (curr_height >> 1) : 1;
879 if (target == GL_TEXTURE_3D) {
880 curr_depth = (curr_depth >> 1) ? (curr_depth >> 1) : 1;
881 }
882 curr_level++;
883 }
884
885 } else {
886 texrec->dims->widths[level] = width;
887 texrec->dims->heights[level] = height;
888 texrec->dims->depths[level] = depth;
889 }
890}
891
892void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) {
893 GLuint texture = getBoundTexture(target);
894 TextureRec* texrec = getTextureRec(texture);
895 if (!texrec) return;
896 texrec->multisamples = samples;
897}
898
899void GLClientState::setBoundTextureImmutableFormat(GLenum target) {
900 GLuint texture = getBoundTexture(target);
901 TextureRec* texrec = getTextureRec(texture);
902 if (!texrec) return;
903 texrec->immutable = true;
904}
905
906bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const {
907 GLuint texture = getBoundTexture(target);
908 TextureRec* texrec = getTextureRec(texture);
909 if (!texrec) return false;
910 return texrec->immutable;
911}
912
keunyoungb85b2752013-03-08 12:28:03 -0800913GLuint GLClientState::getBoundTexture(GLenum target) const
914{
915 switch (target) {
916 case GL_TEXTURE_2D:
917 return m_tex.activeUnit->texture[TEXTURE_2D];
918 case GL_TEXTURE_EXTERNAL_OES:
919 return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
Lingfeng Yang74e29292017-01-10 14:54:38 -0800920 case GL_TEXTURE_CUBE_MAP:
921 return m_tex.activeUnit->texture[TEXTURE_CUBE_MAP];
922 case GL_TEXTURE_2D_ARRAY:
923 return m_tex.activeUnit->texture[TEXTURE_2D_ARRAY];
924 case GL_TEXTURE_3D:
925 return m_tex.activeUnit->texture[TEXTURE_3D];
926 case GL_TEXTURE_2D_MULTISAMPLE:
927 return m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE];
keunyoungb85b2752013-03-08 12:28:03 -0800928 default:
929 return 0;
930 }
931}
932
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700933// BEGIN driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
934// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
935
936static bool unreliableInternalFormat(GLenum internalformat) {
937 switch (internalformat) {
938 case GL_LUMINANCE:
939 return true;
940 default:
941 return false;
942 }
943}
944
945void GLClientState::writeCopyTexImageState
946 (GLenum target, GLint level, GLenum internalformat) {
947 if (unreliableInternalFormat(internalformat)) {
948 CubeMapDef entry;
949 entry.id = getBoundTexture(GL_TEXTURE_2D);
950 entry.target = target;
951 entry.level = level;
952 entry.internalformat = internalformat;
953 m_cubeMapDefs.insert(entry);
954 }
955}
956
957static GLenum identifyPositiveCubeMapComponent(GLenum target) {
958 switch (target) {
959 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
960 return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
961 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
962 return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
963 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
964 return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
965 default:
966 return 0;
967 }
968}
969
970GLenum GLClientState::copyTexImageNeededTarget
971 (GLenum target, GLint level, GLenum internalformat) {
972 if (unreliableInternalFormat(internalformat)) {
973 GLenum positiveComponent =
974 identifyPositiveCubeMapComponent(target);
975 if (positiveComponent) {
976 CubeMapDef query;
977 query.id = getBoundTexture(GL_TEXTURE_2D);
978 query.target = positiveComponent;
979 query.level = level;
980 query.internalformat = internalformat;
981 if (m_cubeMapDefs.find(query) ==
982 m_cubeMapDefs.end()) {
983 return positiveComponent;
984 }
985 }
986 }
987 return 0;
988}
989
990GLenum GLClientState::copyTexImageLuminanceCubeMapAMDWorkaround
991 (GLenum target, GLint level, GLenum internalformat) {
992 writeCopyTexImageState(target, level, internalformat);
993 return copyTexImageNeededTarget(target, level, internalformat);
994}
995
996// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
997// END driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
998
keunyoungb85b2752013-03-08 12:28:03 -0800999void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
1000{
1001 // Updating the textures array could be made more efficient when deleting
1002 // several textures:
1003 // - compacting the array could be done in a single pass once the deleted
1004 // textures are marked, or
1005 // - could swap deleted textures to the end and re-sort.
1006 TextureRec* texrec;
1007 for (const GLuint* texture = textures; texture != textures + n; texture++) {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001008 texrec = getTextureRec(*texture);
1009 if (texrec && texrec->dims) {
1010 delete texrec->dims;
1011 }
keunyoungb85b2752013-03-08 12:28:03 -08001012 if (texrec) {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001013 m_tex.textureRecs->erase(*texture);
1014 delete texrec;
keunyoungb85b2752013-03-08 12:28:03 -08001015 for (TextureUnit* unit = m_tex.unit;
1016 unit != m_tex.unit + MAX_TEXTURE_UNITS;
1017 unit++)
1018 {
1019 if (unit->texture[TEXTURE_2D] == *texture) {
1020 unit->texture[TEXTURE_2D] = 0;
1021 } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
1022 unit->texture[TEXTURE_EXTERNAL] = 0;
1023 }
1024 }
1025 }
1026 }
1027}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001028
1029// RBO//////////////////////////////////////////////////////////////////////////
1030
1031void GLClientState::addFreshRenderbuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001032 // if underlying opengl says these are fresh names,
1033 // but we are keeping a stale one, reset it.
1034 RboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001035 props.target = GL_RENDERBUFFER;
1036 props.name = name;
Lingfeng Yang69066602016-04-12 09:29:11 -07001037 props.format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001038 props.multisamples = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001039 props.previouslyBound = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001040
1041 if (usedRenderbufferName(name)) {
1042 mRboState.rboData[getRboIndex(name)] = props;
1043 } else {
1044 mRboState.rboData.push_back(props);
1045 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001046}
1047
1048void GLClientState::addRenderbuffers(GLsizei n, GLuint* renderbuffers) {
1049 for (size_t i = 0; i < n; i++) {
1050 addFreshRenderbuffer(renderbuffers[i]);
1051 }
1052}
1053
1054size_t GLClientState::getRboIndex(GLuint name) const {
1055 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1056 if (mRboState.rboData[i].name == name) {
1057 return i;
1058 }
1059 }
1060 return -1;
1061}
1062
1063void GLClientState::removeRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
1064 size_t bound_rbo_idx = getRboIndex(boundRboProps_const().name);
1065
1066 std::vector<GLuint> to_remove;
1067 for (size_t i = 0; i < n; i++) {
1068 if (renderbuffers[i] != 0) { // Never remove the zero rb.
1069 to_remove.push_back(getRboIndex(renderbuffers[i]));
1070 }
1071 }
1072
1073 for (size_t i = 0; i < to_remove.size(); i++) {
1074 mRboState.rboData[to_remove[i]] = mRboState.rboData.back();
1075 mRboState.rboData.pop_back();
1076 }
1077
1078 // If we just deleted the currently bound rb,
1079 // bind the zero rb
1080 if (getRboIndex(boundRboProps_const().name) != bound_rbo_idx) {
1081 bindRenderbuffer(GL_RENDERBUFFER, 0);
1082 }
1083}
1084
1085bool GLClientState::usedRenderbufferName(GLuint name) const {
1086 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1087 if (mRboState.rboData[i].name == name) {
1088 return true;
1089 }
1090 }
1091 return false;
1092}
1093
1094void GLClientState::setBoundRenderbufferIndex() {
1095 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1096 if (mRboState.rboData[i].name == mRboState.boundRenderbuffer) {
1097 mRboState.boundRenderbufferIndex = i;
1098 break;
1099 }
1100 }
1101}
1102
1103RboProps& GLClientState::boundRboProps() {
1104 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1105}
1106
1107const RboProps& GLClientState::boundRboProps_const() const {
1108 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1109}
1110
1111void GLClientState::bindRenderbuffer(GLenum target, GLuint name) {
1112 // If unused, add it.
1113 if (!usedRenderbufferName(name)) {
1114 addFreshRenderbuffer(name);
1115 }
1116 mRboState.boundRenderbuffer = name;
1117 setBoundRenderbufferIndex();
1118 boundRboProps().target = target;
1119 boundRboProps().previouslyBound = true;
1120}
1121
1122GLuint GLClientState::boundRenderbuffer() const {
1123 return boundRboProps_const().name;
1124}
1125
Lingfeng Yang69066602016-04-12 09:29:11 -07001126void GLClientState::setBoundRenderbufferFormat(GLenum format) {
1127 boundRboProps().format = format;
1128}
1129
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001130void GLClientState::setBoundRenderbufferSamples(GLsizei samples) {
1131 boundRboProps().multisamples = samples;
1132}
1133
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001134// FBO//////////////////////////////////////////////////////////////////////////
1135
Lingfeng Yang69066602016-04-12 09:29:11 -07001136// Format querying
1137
1138GLenum GLClientState::queryRboFormat(GLuint rbo_name) const {
1139 return mRboState.rboData[getRboIndex(rbo_name)].format;
1140}
1141
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001142GLsizei GLClientState::queryRboSamples(GLuint rbo_name) const {
1143 return mRboState.rboData[getRboIndex(rbo_name)].multisamples;
1144}
1145
Lingfeng Yang69066602016-04-12 09:29:11 -07001146GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001147 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001148 if (!texrec) return -1;
1149 return texrec->internalformat;
1150}
1151
Lingfeng Yang74e29292017-01-10 14:54:38 -08001152GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const {
1153 TextureRec* texrec = getTextureRec(tex_name);
1154 if (!texrec) {
1155 return 0;
1156 }
1157 return texrec->dims->widths[level];
1158}
1159
1160GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const {
1161 TextureRec* texrec = getTextureRec(tex_name);
1162 if (!texrec) return 0;
1163 return texrec->dims->heights[level];
1164}
1165
1166GLsizei GLClientState::queryTexDepth(GLsizei level, GLuint tex_name) const {
1167 TextureRec* texrec = getTextureRec(tex_name);
1168 if (!texrec) return 0;
1169 return texrec->dims->depths[level];
1170}
1171
1172bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const {
1173 TextureRec* texrec = getTextureRec(tex_name);
1174 if (!texrec) return false;
1175 return texrec->boundEGLImage;
1176}
1177
Lingfeng Yang69066602016-04-12 09:29:11 -07001178GLenum GLClientState::queryTexFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001179 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001180 if (!texrec) return -1;
1181 return texrec->format;
1182}
1183
1184GLenum GLClientState::queryTexType(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001185 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001186 if (!texrec) return -1;
1187 return texrec->type;
1188}
1189
Lingfeng Yang74e29292017-01-10 14:54:38 -08001190GLsizei GLClientState::queryTexSamples(GLuint tex_name) const {
1191 TextureRec* texrec = getTextureRec(tex_name);
1192 if (!texrec) return 0;
1193 return texrec->multisamples;
1194}
1195
1196GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const {
1197 TextureRec* texrec = getTextureRec(tex_name);
1198 if (!texrec) return GL_NONE;
1199 return texrec->target;
1200}
1201
Lingfeng Yang69066602016-04-12 09:29:11 -07001202void GLClientState::getBoundFramebufferFormat(
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001203 GLenum target,
Lingfeng Yang69066602016-04-12 09:29:11 -07001204 GLenum attachment, FboFormatInfo* res_info) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001205 const FboProps& props = boundFboProps_const(target);
Lingfeng Yang69066602016-04-12 09:29:11 -07001206
1207 res_info->type = FBO_ATTACHMENT_NONE;
1208 res_info->rb_format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001209 res_info->rb_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001210 res_info->tex_internalformat = -1;
1211 res_info->tex_format = GL_NONE;
1212 res_info->tex_type = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001213 res_info->tex_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001214
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001215 int colorAttachmentIndex =
1216 glUtilsColorAttachmentIndex(attachment);
1217
1218 if (colorAttachmentIndex != -1) {
1219 if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001220 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001221 res_info->rb_format =
1222 queryRboFormat(
1223 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1224 res_info->rb_multisamples =
1225 queryRboSamples(
1226 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1227 } else if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001228 res_info->type = FBO_ATTACHMENT_TEXTURE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001229 res_info->tex_internalformat =
1230 queryTexInternalFormat(
1231 props.colorAttachmenti_textures[colorAttachmentIndex]);
1232 res_info->tex_format =
1233 queryTexFormat(
1234 props.colorAttachmenti_textures[colorAttachmentIndex]);
1235 res_info->tex_type =
1236 queryTexType(props.colorAttachmenti_textures[colorAttachmentIndex]);
1237 res_info->tex_multisamples =
1238 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001239 } else {
1240 res_info->type = FBO_ATTACHMENT_NONE;
1241 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001242 }
1243
1244 switch (attachment) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001245 case GL_DEPTH_ATTACHMENT:
1246 if (props.depthAttachment_hasRbo) {
1247 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1248 res_info->rb_format = queryRboFormat(props.depthAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001249 res_info->rb_multisamples =
1250 queryRboSamples(
1251 props.colorAttachmenti_rbos[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001252 } else if (props.depthAttachment_hasTexObj) {
1253 res_info->type = FBO_ATTACHMENT_TEXTURE;
1254 res_info->tex_internalformat = queryTexInternalFormat(props.depthAttachment_texture);
1255 res_info->tex_format = queryTexFormat(props.depthAttachment_texture);
1256 res_info->tex_type = queryTexType(props.depthAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001257 res_info->tex_multisamples =
1258 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001259 } else {
1260 res_info->type = FBO_ATTACHMENT_NONE;
1261 }
1262 break;
1263 case GL_STENCIL_ATTACHMENT:
1264 if (props.stencilAttachment_hasRbo) {
1265 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1266 res_info->rb_format = queryRboFormat(props.stencilAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001267 res_info->rb_multisamples =
1268 queryRboSamples(
1269 props.colorAttachmenti_rbos[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001270 } else if (props.stencilAttachment_hasTexObj) {
1271 res_info->type = FBO_ATTACHMENT_TEXTURE;
1272 res_info->tex_internalformat = queryTexInternalFormat(props.stencilAttachment_texture);
1273 res_info->tex_format = queryTexFormat(props.stencilAttachment_texture);
1274 res_info->tex_type = queryTexType(props.stencilAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001275 res_info->tex_multisamples =
1276 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001277 } else {
1278 res_info->type = FBO_ATTACHMENT_NONE;
1279 }
1280 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001281 case GL_DEPTH_STENCIL_ATTACHMENT:
1282 if (props.depthstencilAttachment_hasRbo) {
1283 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1284 res_info->rb_format = queryRboFormat(props.depthstencilAttachment_rbo);
1285 res_info->rb_multisamples =
1286 queryRboSamples(
1287 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1288 } else if (props.depthstencilAttachment_hasTexObj) {
1289 res_info->type = FBO_ATTACHMENT_TEXTURE;
1290 res_info->tex_internalformat = queryTexInternalFormat(props.depthstencilAttachment_texture);
1291 res_info->tex_format = queryTexFormat(props.depthstencilAttachment_texture);
1292 res_info->tex_type = queryTexType(props.depthstencilAttachment_texture);
1293 res_info->tex_multisamples =
1294 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
1295 } else {
1296 res_info->type = FBO_ATTACHMENT_NONE;
1297 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001298 break;
1299 }
1300}
1301
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001302FboAttachmentType GLClientState::getBoundFramebufferAttachmentType(GLenum target, GLenum attachment) const {
1303 FboFormatInfo info;
1304 getBoundFramebufferFormat(target, attachment, &info);
1305 return info.type;
1306}
1307
1308
1309int GLClientState::getMaxColorAttachments() const {
1310 return m_max_color_attachments;
1311}
1312
1313int GLClientState::getMaxDrawBuffers() const {
1314 return m_max_draw_buffers;
1315}
1316
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001317void GLClientState::addFreshFramebuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001318 FboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001319 props.name = name;
1320 props.previouslyBound = false;
1321
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001322 props.colorAttachmenti_textures.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001323 props.depthAttachment_texture = 0;
1324 props.stencilAttachment_texture = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001325 props.depthstencilAttachment_texture = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001326
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001327 props.colorAttachmenti_hasTex.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001328 props.depthAttachment_hasTexObj = false;
1329 props.stencilAttachment_hasTexObj = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001330 props.depthstencilAttachment_hasTexObj = false;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001331
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001332 props.colorAttachmenti_rbos.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001333 props.depthAttachment_rbo = 0;
1334 props.stencilAttachment_rbo = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001335 props.depthstencilAttachment_rbo = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001336
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001337 props.colorAttachmenti_hasRbo.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001338 props.depthAttachment_hasRbo = false;
1339 props.stencilAttachment_hasRbo = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001340 props.depthstencilAttachment_hasRbo = false;
1341 mFboState.fboData[name] = props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001342}
1343
1344void GLClientState::addFramebuffers(GLsizei n, GLuint* framebuffers) {
1345 for (size_t i = 0; i < n; i++) {
1346 addFreshFramebuffer(framebuffers[i]);
1347 }
1348}
1349
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001350void GLClientState::removeFramebuffers(GLsizei n, const GLuint* framebuffers) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001351 for (size_t i = 0; i < n; i++) {
1352 if (framebuffers[i] != 0) { // Never remove the zero fb.
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001353 if (framebuffers[i] == mFboState.boundDrawFramebuffer) {
1354 bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1355 }
1356 if (framebuffers[i] == mFboState.boundReadFramebuffer) {
1357 bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1358 }
1359 mFboState.fboData.erase(framebuffers[i]);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001360 }
1361 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001362}
1363
1364bool GLClientState::usedFramebufferName(GLuint name) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001365 return mFboState.fboData.find(name) != mFboState.fboData.end();
1366}
1367
1368FboProps& GLClientState::boundFboProps(GLenum target) {
1369 switch (target) {
1370 case GL_DRAW_FRAMEBUFFER:
1371 return mFboState.fboData[mFboState.boundDrawFramebuffer];
1372 case GL_READ_FRAMEBUFFER:
1373 return mFboState.fboData[mFboState.boundReadFramebuffer];
1374 case GL_FRAMEBUFFER:
1375 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001376 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001377 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001378}
1379
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001380const FboProps& GLClientState::boundFboProps_const(GLenum target) const {
1381 switch (target) {
1382 case GL_DRAW_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001383 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001384 case GL_READ_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001385 return mFboState.fboData.find(mFboState.boundReadFramebuffer)->second;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001386 case GL_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001387 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001388 }
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001389 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001390}
1391
1392void GLClientState::bindFramebuffer(GLenum target, GLuint name) {
1393 // If unused, add it.
1394 if (!usedFramebufferName(name)) {
1395 addFreshFramebuffer(name);
1396 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001397 switch (target) {
1398 case GL_DRAW_FRAMEBUFFER:
1399 mFboState.boundDrawFramebuffer = name;
1400 break;
1401 case GL_READ_FRAMEBUFFER:
1402 mFboState.boundReadFramebuffer = name;
1403 break;
1404 default: // case GL_FRAMEBUFFER:
1405 mFboState.boundDrawFramebuffer = name;
1406 mFboState.boundReadFramebuffer = name;
1407 break;
1408 }
1409 boundFboProps(target).previouslyBound = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001410}
1411
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001412void GLClientState::setCheckFramebufferStatus(GLenum target, GLenum status) {
1413 switch (target) {
1414 case GL_DRAW_FRAMEBUFFER:
1415 mFboState.drawFboCheckStatus = status;
1416 break;
1417 case GL_READ_FRAMEBUFFER:
1418 mFboState.readFboCheckStatus = status;
1419 break;
1420 case GL_FRAMEBUFFER:
1421 mFboState.drawFboCheckStatus = status;
1422 break;
1423 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001424}
1425
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001426GLenum GLClientState::getCheckFramebufferStatus(GLenum target) const {
1427 switch (target) {
1428 case GL_DRAW_FRAMEBUFFER:
1429 return mFboState.drawFboCheckStatus;
1430 case GL_READ_FRAMEBUFFER:
1431 return mFboState.readFboCheckStatus;
1432 case GL_FRAMEBUFFER:
1433 return mFboState.drawFboCheckStatus;
1434 }
1435 return mFboState.drawFboCheckStatus;
Lingfeng Yang69066602016-04-12 09:29:11 -07001436}
1437
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001438GLuint GLClientState::boundFramebuffer(GLenum target) const {
1439 return boundFboProps_const(target).name;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001440}
1441
1442// Texture objects for FBOs/////////////////////////////////////////////////////
1443
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001444void GLClientState::attachTextureObject(
1445 GLenum target,
1446 GLenum attachment, GLuint texture) {
1447
1448 int colorAttachmentIndex =
1449 glUtilsColorAttachmentIndex(attachment);
1450
1451 if (colorAttachmentIndex != -1) {
1452 boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texture;
1453 boundFboProps(target).colorAttachmenti_hasTex[colorAttachmentIndex] = true;
1454 }
1455
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001456 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001457 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001458 boundFboProps(target).depthAttachment_texture = texture;
1459 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001460 break;
1461 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001462 boundFboProps(target).stencilAttachment_texture = texture;
1463 boundFboProps(target).stencilAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001464 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001465 case GL_DEPTH_STENCIL_ATTACHMENT:
1466 boundFboProps(target).depthstencilAttachment_texture = texture;
1467 boundFboProps(target).depthstencilAttachment_hasTexObj = true;
1468 boundFboProps(target).stencilAttachment_texture = texture;
1469 boundFboProps(target).stencilAttachment_hasTexObj = true;
1470 boundFboProps(target).depthAttachment_texture = texture;
1471 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001472 break;
1473 }
1474}
1475
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001476GLuint GLClientState::getFboAttachmentTextureId(GLenum target, GLenum attachment) const {
1477 GLuint res = 0; // conservative
1478
1479 int colorAttachmentIndex =
1480 glUtilsColorAttachmentIndex(attachment);
1481
1482 if (colorAttachmentIndex != -1) {
1483 res = boundFboProps_const(target).colorAttachmenti_textures[colorAttachmentIndex];
1484 }
1485
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001486 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001487 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001488 res = boundFboProps_const(target).depthAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001489 break;
1490 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001491 res = boundFboProps_const(target).stencilAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001492 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001493 case GL_DEPTH_STENCIL_ATTACHMENT:
1494 res = boundFboProps_const(target).depthstencilAttachment_texture;
1495 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001496 }
1497 return res;
1498}
1499
1500// RBOs for FBOs////////////////////////////////////////////////////////////////
1501
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001502void GLClientState::detachRbo(GLuint renderbuffer) {
1503 for (int i = 0; i < m_max_color_attachments; i++) {
1504 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1505 detachRboFromFbo(GL_READ_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1506 }
1507
1508 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1509 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1510
1511 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1512 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1513
1514 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1515 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1516}
1517
1518void GLClientState::detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1519 int colorAttachmentIndex =
1520 glUtilsColorAttachmentIndex(attachment);
1521
1522 if (colorAttachmentIndex != -1) {
1523 if (boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] &&
1524 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] == renderbuffer) {
1525 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = 0;
1526 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = false;
1527 }
1528 }
1529
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001530 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001531 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001532 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1533 boundFboProps(target).depthAttachment_hasRbo) {
1534 boundFboProps(target).depthAttachment_rbo = 0;
1535 boundFboProps(target).depthAttachment_hasRbo = false;
1536 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001537 break;
1538 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001539 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1540 boundFboProps(target).stencilAttachment_hasRbo) {
1541 boundFboProps(target).stencilAttachment_rbo = 0;
1542 boundFboProps(target).stencilAttachment_hasRbo = false;
1543 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001544 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001545 case GL_DEPTH_STENCIL_ATTACHMENT:
1546 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1547 boundFboProps(target).depthAttachment_hasRbo) {
1548 boundFboProps(target).depthAttachment_rbo = 0;
1549 boundFboProps(target).depthAttachment_hasRbo = false;
1550 }
1551 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1552 boundFboProps(target).stencilAttachment_hasRbo) {
1553 boundFboProps(target).stencilAttachment_rbo = 0;
1554 boundFboProps(target).stencilAttachment_hasRbo = false;
1555 }
1556 if (boundFboProps(target).depthstencilAttachment_rbo == renderbuffer &&
1557 boundFboProps(target).depthstencilAttachment_hasRbo) {
1558 boundFboProps(target).depthstencilAttachment_rbo = 0;
1559 boundFboProps(target).depthstencilAttachment_hasRbo = false;
1560 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001561 break;
1562 }
1563}
1564
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001565void GLClientState::attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1566
1567 int colorAttachmentIndex =
1568 glUtilsColorAttachmentIndex(attachment);
1569
1570 if (colorAttachmentIndex != -1) {
1571 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = renderbuffer;
1572 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = true;
1573 }
1574
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001575 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001576 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001577 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1578 boundFboProps(target).depthAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001579 break;
1580 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001581 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1582 boundFboProps(target).stencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001583 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001584 case GL_DEPTH_STENCIL_ATTACHMENT:
1585 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1586 boundFboProps(target).depthAttachment_hasRbo = true;
1587 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1588 boundFboProps(target).stencilAttachment_hasRbo = true;
1589 boundFboProps(target).depthstencilAttachment_rbo = renderbuffer;
1590 boundFboProps(target).depthstencilAttachment_hasRbo = true;
1591 break;
1592 }
1593}
1594
1595GLuint GLClientState::getFboAttachmentRboId(GLenum target, GLenum attachment) const {
1596 GLuint res = 0; // conservative
1597
1598 int colorAttachmentIndex =
1599 glUtilsColorAttachmentIndex(attachment);
1600
1601 if (colorAttachmentIndex != -1) {
1602 res = boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex];
1603 }
1604
1605 switch (attachment) {
1606 case GL_DEPTH_ATTACHMENT:
1607 res = boundFboProps_const(target).depthAttachment_rbo;
1608 break;
1609 case GL_STENCIL_ATTACHMENT:
1610 res = boundFboProps_const(target).stencilAttachment_rbo;
1611 break;
1612 case GL_DEPTH_STENCIL_ATTACHMENT:
1613 res = boundFboProps_const(target).depthstencilAttachment_rbo;
1614 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001615 }
1616 return res;
1617}
1618
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001619bool GLClientState::attachmentHasObject(GLenum target, GLenum attachment) const {
1620 bool res = true; // liberal
1621
1622 int colorAttachmentIndex =
1623 glUtilsColorAttachmentIndex(attachment);
1624
1625 if (colorAttachmentIndex != -1) {
1626 res = boundFboProps_const(target).colorAttachmenti_hasTex[colorAttachmentIndex] ||
1627 boundFboProps_const(target).colorAttachmenti_hasRbo[colorAttachmentIndex];
1628 }
1629
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001630 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001631 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001632 res = (boundFboProps_const(target).depthAttachment_hasTexObj) ||
1633 (boundFboProps_const(target).depthAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001634 break;
1635 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001636 res = (boundFboProps_const(target).stencilAttachment_hasTexObj) ||
1637 (boundFboProps_const(target).stencilAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001638 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001639 case GL_DEPTH_STENCIL_ATTACHMENT:
1640 res = (boundFboProps_const(target).depthstencilAttachment_hasTexObj) ||
1641 (boundFboProps_const(target).depthstencilAttachment_hasRbo);
1642 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001643 }
1644 return res;
1645}
1646
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001647GLuint GLClientState::objectOfAttachment(GLenum target, GLenum attachment) const {
1648 const FboProps& props = boundFboProps_const(target);
1649
1650 int colorAttachmentIndex =
1651 glUtilsColorAttachmentIndex(attachment);
1652
1653 if (colorAttachmentIndex != -1) {
1654 if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
1655 return props.colorAttachmenti_textures[colorAttachmentIndex];
1656 } else if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
1657 return props.colorAttachmenti_rbos[colorAttachmentIndex];
1658 } else {
1659 return 0;
1660 }
1661 }
1662
1663 switch (attachment) {
1664 case GL_DEPTH_ATTACHMENT:
1665 if (props.depthAttachment_hasTexObj) {
1666 return props.depthAttachment_texture;
1667 } else if (props.depthAttachment_hasRbo) {
1668 return props.depthAttachment_rbo;
1669 } else {
1670 return 0;
1671 }
1672 break;
1673 case GL_STENCIL_ATTACHMENT:
1674 if (props.stencilAttachment_hasTexObj) {
1675 return props.stencilAttachment_texture;
1676 } else if (props.stencilAttachment_hasRbo) {
1677 return props.stencilAttachment_rbo;
1678 } else {
1679 return 0;
1680 }
1681 case GL_DEPTH_STENCIL_ATTACHMENT:
1682 if (props.depthstencilAttachment_hasTexObj) {
1683 return props.depthstencilAttachment_texture;
1684 } else if (props.depthstencilAttachment_hasRbo) {
1685 return props.depthstencilAttachment_rbo;
1686 } else {
1687 return 0;
1688 }
1689 break;
1690 }
1691 return 0;
1692}
Lingfeng Yang4a66b312017-01-09 13:27:49 -08001693
1694void GLClientState::setTransformFeedbackActiveUnpaused(bool activeUnpaused) {
1695 m_transformFeedbackActiveUnpaused = activeUnpaused;
1696}
1697
1698bool GLClientState::getTransformFeedbackActiveUnpaused() const {
1699 return m_transformFeedbackActiveUnpaused;
1700}
1701
1702void GLClientState::setTextureData(SharedTextureDataMap* sharedTexData) {
1703 m_tex.textureRecs = sharedTexData;
1704}
1705
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001706void GLClientState::fromMakeCurrent() {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001707 if (mFboState.fboData.find(0) == mFboState.fboData.end()) {
1708 addFreshFramebuffer(0);
1709 }
1710 FboProps& default_fb_props = mFboState.fboData[0];
1711 default_fb_props.colorAttachmenti_hasRbo[0] = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001712 default_fb_props.depthAttachment_hasRbo = true;
1713 default_fb_props.stencilAttachment_hasRbo = true;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001714 default_fb_props.depthstencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001715}
Lingfeng Yangf654f3f2017-01-09 13:12:33 -08001716
1717void GLClientState::initFromCaps(
1718 int max_transform_feedback_separate_attribs,
1719 int max_uniform_buffer_bindings,
1720 int max_atomic_counter_buffer_bindings,
1721 int max_shader_storage_buffer_bindings,
1722 int max_vertex_attrib_bindings,
1723 int max_color_attachments,
1724 int max_draw_buffers) {
1725
1726 m_max_vertex_attrib_bindings = max_vertex_attrib_bindings;
1727
1728 if (m_glesMajorVersion >= 3) {
1729 m_max_transform_feedback_separate_attribs = max_transform_feedback_separate_attribs;
1730 m_max_uniform_buffer_bindings = max_uniform_buffer_bindings;
1731 m_max_atomic_counter_buffer_bindings = max_atomic_counter_buffer_bindings;
1732 m_max_shader_storage_buffer_bindings = max_shader_storage_buffer_bindings;
1733
1734 if (m_max_transform_feedback_separate_attribs)
1735 m_indexedTransformFeedbackBuffers.resize(m_max_transform_feedback_separate_attribs);
1736 if (m_max_uniform_buffer_bindings)
1737 m_indexedUniformBuffers.resize(m_max_uniform_buffer_bindings);
1738 if (m_max_atomic_counter_buffer_bindings)
1739 m_indexedAtomicCounterBuffers.resize(m_max_atomic_counter_buffer_bindings);
1740 if (m_max_shader_storage_buffer_bindings)
1741 m_indexedShaderStorageBuffers.resize(m_max_shader_storage_buffer_bindings);
1742
1743 BufferBinding buf0Binding;
1744 buf0Binding.buffer = 0;
1745 buf0Binding.offset = 0;
1746 buf0Binding.size = 0;
1747 buf0Binding.stride = 0;
1748 buf0Binding.effectiveStride = 0;
1749
1750 for (size_t i = 0; i < m_indexedTransformFeedbackBuffers.size(); ++i)
1751 m_indexedTransformFeedbackBuffers[i] = buf0Binding;
1752 for (size_t i = 0; i < m_indexedUniformBuffers.size(); ++i)
1753 m_indexedUniformBuffers[i] = buf0Binding;
1754 for (size_t i = 0; i < m_indexedAtomicCounterBuffers.size(); ++i)
1755 m_indexedAtomicCounterBuffers[i] = buf0Binding;
1756 for (size_t i = 0; i < m_indexedShaderStorageBuffers.size(); ++i)
1757 m_indexedShaderStorageBuffers[i] = buf0Binding;
1758 }
1759
1760 m_max_color_attachments = max_color_attachments;
1761 m_max_draw_buffers = max_draw_buffers;
1762
1763 addFreshRenderbuffer(0);
1764 addFreshFramebuffer(0);
1765
1766 m_initialized = true;
1767}
1768
1769bool GLClientState::needsInitFromCaps() const {
1770 return !m_initialized;
1771}