blob: 9de12d9857af0a33eaa8b1172a3240043aef482a [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;
78
79 m_pixelStore.unpack_alignment = 4;
80 m_pixelStore.pack_alignment = 4;
81
Lingfeng Yang74e29292017-01-10 14:54:38 -080082 m_pixelStore.unpack_row_length = 0;
83 m_pixelStore.unpack_image_height = 0;
84 m_pixelStore.unpack_skip_pixels = 0;
85 m_pixelStore.unpack_skip_rows = 0;
86 m_pixelStore.unpack_skip_images = 0;
87
88 m_pixelStore.pack_row_length = 0;
89 m_pixelStore.pack_skip_pixels = 0;
90 m_pixelStore.pack_skip_rows = 0;
91
keunyoungb85b2752013-03-08 12:28:03 -080092 memset(m_tex.unit, 0, sizeof(m_tex.unit));
93 m_tex.activeUnit = &m_tex.unit[0];
Lingfeng Yang74e29292017-01-10 14:54:38 -080094 m_tex.textureRecs = NULL;
Lingfeng Yangb0176982016-03-01 21:27:49 -080095
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070096 mRboState.boundRenderbuffer = 0;
97 mRboState.boundRenderbufferIndex = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -070098
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -080099 mFboState.boundDrawFramebuffer = 0;
100 mFboState.boundReadFramebuffer = 0;
101 mFboState.drawFboCheckStatus = GL_NONE;
102 mFboState.readFboCheckStatus = GL_NONE;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700103
Lingfeng Yangb0176982016-03-01 21:27:49 -0800104 m_maxVertexAttribsDirty = true;
keunyoungb85b2752013-03-08 12:28:03 -0800105}
106
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800107GLClientState::GLClientState()
108{
109 init();
110}
111
112GLClientState::GLClientState(int majorVersion, int minorVersion) :
113 m_glesMajorVersion(majorVersion),
114 m_glesMinorVersion(minorVersion) {
115 init();
116}
117
keunyoungb85b2752013-03-08 12:28:03 -0800118GLClientState::~GLClientState()
119{
keunyoungb85b2752013-03-08 12:28:03 -0800120}
121
122void GLClientState::enable(int location, int state)
123{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800124 m_currVaoState[location].enableDirty |= (state != m_currVaoState[location].enabled);
125 m_currVaoState[location].enabled = state;
126}
127
128void GLClientState::setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt)
129{
130 m_currVaoState[location].size = size;
131 m_currVaoState[location].type = type;
132 m_currVaoState[location].stride = stride;
133 m_currVaoState[location].data = (void*)data;
134 m_currVaoState[location].bufferObject = m_arrayBuffer;
135 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
136 switch (type) {
137 case GL_INT_2_10_10_10_REV:
138 case GL_UNSIGNED_INT_2_10_10_10_REV:
139 m_currVaoState[location].elementSize =
140 m_currVaoState[location].elementSize / 4;
141 break;
142 default:
143 break;
144 }
145 m_currVaoState[location].normalized = normalized;
146 m_currVaoState[location].isInt = isInt;
147}
148
149void GLClientState::setVertexBindingDivisor(int bindingindex, GLuint divisor) {
150 m_currVaoState.bufferBinding(bindingindex).divisor = divisor;
151}
152
153const GLClientState::BufferBinding& GLClientState::getCurrAttributeBindingInfo(int attribindex) {
154 return m_currVaoState.bufferBindings_const().at(m_currVaoState[attribindex].bindingindex);
155}
156
157void GLClientState::setVertexAttribBinding(int attribindex, int bindingindex) {
158 m_currVaoState[attribindex].bindingindex = bindingindex;
159}
160
161void GLClientState::setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) {
162 m_currVaoState[location].size = size;
163 m_currVaoState[location].type = type;
164 m_currVaoState[location].normalized = normalized;
165 m_currVaoState[location].reloffset = reloffset;
166 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
167 switch (type) {
168 case GL_INT_2_10_10_10_REV:
169 case GL_UNSIGNED_INT_2_10_10_10_REV:
170 m_currVaoState[location].elementSize =
171 m_currVaoState[location].elementSize / 4;
172 break;
173 default:
174 break;
175 }
176 m_currVaoState[location].isInt = isInt;
177}
178
179void GLClientState::addVertexArrayObjects(GLsizei n, GLuint* arrays) {
180 for (GLsizei i = 0; i < n; i++) {
181 addVertexArrayObject(arrays[i]);
182 }
183}
184
185void GLClientState::removeVertexArrayObjects(GLsizei n, const GLuint* arrays) {
186 for (GLsizei i = 0; i < n; i++) {
187 if (arrays[i] && m_currVaoState.vaoId() == arrays[i]) {
188 setVertexArrayObject(0);
189 }
190 removeVertexArrayObject(arrays[i]);
191 }
192}
193
194void GLClientState::addVertexArrayObject(GLuint name) {
195 if (m_vaoMap.find(name) !=
196 m_vaoMap.end()) {
197 ALOGE("%s: ERROR: %u already part of current VAO state!",
198 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800199 return;
200 }
201
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800202 m_vaoMap.insert(
203 VAOStateMap::value_type(
204 name,
205 VAOState(0, m_nLocations, std::max(m_nLocations, m_max_vertex_attrib_bindings))));
206 VertexAttribStateVector& attribState =
207 m_vaoMap.at(name).attribState;
208 for (int i = 0; i < m_nLocations; i++) {
209 attribState[i].enabled = 0;
210 attribState[i].enableDirty = false;
211 attribState[i].data = 0;
212 attribState[i].reloffset = 0;
213 attribState[i].bindingindex = i;
214 attribState[i].divisor = 0;
215 attribState[i].size = 4; // 4 is the default size
216 attribState[i].type = GL_FLOAT; // GL_FLOAT is the default type
217 }
keunyoungb85b2752013-03-08 12:28:03 -0800218}
219
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800220void GLClientState::removeVertexArrayObject(GLuint name) {
221 if (name == 0) {
222 ALOGE("%s: ERROR: cannot delete VAO 0!",
223 __FUNCTION__);
keunyoungb85b2752013-03-08 12:28:03 -0800224 return;
225 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800226 if (m_vaoMap.find(name) ==
227 m_vaoMap.end()) {
228 ALOGE("%s: ERROR: %u not found in VAO state!",
229 __FUNCTION__, name);
230 return;
231 }
232 m_vaoMap.erase(name);
keunyoungb85b2752013-03-08 12:28:03 -0800233}
234
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800235void GLClientState::setVertexArrayObject(GLuint name) {
236 if (m_vaoMap.find(name) ==
237 m_vaoMap.end()) {
238 ALOGE("%s: ERROR: %u not found in VAO state!",
239 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800240 return;
241 }
242
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800243 if (name && m_currVaoState.vaoId() == name) {
244 ALOGV("%s: set vao to self, no-op (%u)",
245 __FUNCTION__, name);
246 return;
keunyoungb85b2752013-03-08 12:28:03 -0800247 }
248
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800249 m_currVaoState =
250 VAOStateRef(m_vaoMap.find(name));
251 ALOGV("%s: set vao to %u (%u) %u %u", __FUNCTION__,
252 name,
253 m_currVaoState.vaoId(),
254 m_arrayBuffer,
255 m_currVaoState.iboId());
256}
257
258bool GLClientState::isVertexArrayObject(GLuint vao) const {
259 return m_vaoMap.find(vao) != m_vaoMap.end();
260}
261
262const GLClientState::VertexAttribState& GLClientState::getState(int location)
263{
264 return m_currVaoState[location];
265}
266
267const GLClientState::VertexAttribState& GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
268{
keunyoungb85b2752013-03-08 12:28:03 -0800269 if (enableChanged) {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800270 *enableChanged = m_currVaoState[location].enableDirty;
keunyoungb85b2752013-03-08 12:28:03 -0800271 }
272
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800273 m_currVaoState[location].enableDirty = false;
274 return m_currVaoState[location];
keunyoungb85b2752013-03-08 12:28:03 -0800275}
276
277int GLClientState::getLocation(GLenum loc)
278{
279 int retval;
280
281 switch(loc) {
282 case GL_VERTEX_ARRAY:
283 retval = int(VERTEX_LOCATION);
284 break;
285 case GL_NORMAL_ARRAY:
286 retval = int(NORMAL_LOCATION);
287 break;
288 case GL_COLOR_ARRAY:
289 retval = int(COLOR_LOCATION);
290 break;
291 case GL_POINT_SIZE_ARRAY_OES:
292 retval = int(POINTSIZE_LOCATION);
293 break;
294 case GL_TEXTURE_COORD_ARRAY:
295 retval = int (TEXCOORD0_LOCATION + m_activeTexture);
296 break;
297 case GL_MATRIX_INDEX_ARRAY_OES:
298 retval = int (MATRIXINDEX_LOCATION);
299 break;
300 case GL_WEIGHT_ARRAY_OES:
301 retval = int (WEIGHT_LOCATION);
302 break;
303 default:
304 retval = loc;
305 }
306 return retval;
307}
308
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800309void GLClientState::unBindBuffer(GLuint id) {
310 if (m_arrayBuffer == id) m_arrayBuffer = 0;
311 if (m_currVaoState.iboId() == id) m_currVaoState.iboId() = 0;
312 if (m_copyReadBuffer == id)
313 m_copyReadBuffer = 0;
314 if (m_copyWriteBuffer == id)
315 m_copyWriteBuffer = 0;
316 if (m_pixelPackBuffer == id)
317 m_pixelPackBuffer = 0;
318 if (m_pixelUnpackBuffer == id)
319 m_pixelUnpackBuffer = 0;
320 if (m_transformFeedbackBuffer == id)
321 m_transformFeedbackBuffer = 0;
322 if (m_uniformBuffer == id)
323 m_uniformBuffer = 0;
324 if (m_atomicCounterBuffer == id)
325 m_atomicCounterBuffer = 0;
326 if (m_dispatchIndirectBuffer == id)
327 m_dispatchIndirectBuffer = 0;
328 if (m_drawIndirectBuffer == id)
329 m_drawIndirectBuffer = 0;
330 if (m_shaderStorageBuffer == id)
331 m_shaderStorageBuffer = 0;
332}
333
334int GLClientState::bindBuffer(GLenum target, GLuint id)
335{
336 int err = 0;
337 switch(target) {
338 case GL_ARRAY_BUFFER:
339 m_arrayBuffer = id;
340 break;
341 case GL_ELEMENT_ARRAY_BUFFER:
342 m_currVaoState.iboId() = id;
343 break;
344 case GL_COPY_READ_BUFFER:
345 m_copyReadBuffer = id;
346 break;
347 case GL_COPY_WRITE_BUFFER:
348 m_copyWriteBuffer = id;
349 break;
350 case GL_PIXEL_PACK_BUFFER:
351 m_pixelPackBuffer = id;
352 break;
353 case GL_PIXEL_UNPACK_BUFFER:
354 m_pixelUnpackBuffer = id;
355 break;
356 case GL_TRANSFORM_FEEDBACK_BUFFER:
357 m_transformFeedbackBuffer = id;
358 break;
359 case GL_UNIFORM_BUFFER:
360 m_uniformBuffer = id;
361 break;
362 case GL_ATOMIC_COUNTER_BUFFER:
363 m_atomicCounterBuffer = id;
364 break;
365 case GL_DISPATCH_INDIRECT_BUFFER:
366 m_dispatchIndirectBuffer = id;
367 break;
368 case GL_DRAW_INDIRECT_BUFFER:
369 m_drawIndirectBuffer = id;
370 break;
371 case GL_SHADER_STORAGE_BUFFER:
372 m_shaderStorageBuffer = id;
373 break;
374 default:
375 err = -1;
376 }
377 return err;
378}
379
380void GLClientState::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) {
381 switch (target) {
382 case GL_TRANSFORM_FEEDBACK_BUFFER:
383 m_indexedTransformFeedbackBuffers[index].buffer = buffer;
384 m_indexedTransformFeedbackBuffers[index].offset = offset;
385 m_indexedTransformFeedbackBuffers[index].size = size;
386 m_indexedTransformFeedbackBuffers[index].stride = stride;
387 break;
388 case GL_UNIFORM_BUFFER:
389 m_indexedUniformBuffers[index].buffer = buffer;
390 m_indexedUniformBuffers[index].offset = offset;
391 m_indexedUniformBuffers[index].size = size;
392 m_indexedUniformBuffers[index].stride = stride;
393 break;
394 case GL_ATOMIC_COUNTER_BUFFER:
395 m_indexedAtomicCounterBuffers[index].buffer = buffer;
396 m_indexedAtomicCounterBuffers[index].offset = offset;
397 m_indexedAtomicCounterBuffers[index].size = size;
398 m_indexedAtomicCounterBuffers[index].stride = stride;
399 break;
400 case GL_SHADER_STORAGE_BUFFER:
401 m_indexedShaderStorageBuffers[index].buffer = buffer;
402 m_indexedShaderStorageBuffers[index].offset = offset;
403 m_indexedShaderStorageBuffers[index].size = size;
404 m_indexedShaderStorageBuffers[index].stride = stride;
405 break;
406 default:
407 m_currVaoState.bufferBinding(index).buffer = buffer;
408 m_currVaoState.bufferBinding(index).offset = offset;
409 m_currVaoState.bufferBinding(index).size = size;
410 m_currVaoState.bufferBinding(index).stride = stride;
411 m_currVaoState.bufferBinding(index).effectiveStride = effectiveStride;
412 return;
413 }
414}
415
416int GLClientState::getMaxIndexedBufferBindings(GLenum target) const {
417 switch (target) {
418 case GL_TRANSFORM_FEEDBACK_BUFFER:
419 return m_indexedTransformFeedbackBuffers.size();
420 case GL_UNIFORM_BUFFER:
421 return m_indexedUniformBuffers.size();
422 case GL_ATOMIC_COUNTER_BUFFER:
423 return m_indexedAtomicCounterBuffers.size();
424 case GL_SHADER_STORAGE_BUFFER:
425 return m_indexedShaderStorageBuffers.size();
426 default:
427 return m_currVaoState.bufferBindings_const().size();
428 }
429}
430
431int GLClientState::getBuffer(GLenum target) {
432 int ret=0;
433 switch (target) {
434 case GL_ARRAY_BUFFER:
435 ret = m_arrayBuffer;
436 break;
437 case GL_ELEMENT_ARRAY_BUFFER:
438 ret = m_currVaoState.iboId();
439 break;
440 case GL_COPY_READ_BUFFER:
441 ret = m_copyReadBuffer;
442 break;
443 case GL_COPY_WRITE_BUFFER:
444 ret = m_copyWriteBuffer;
445 break;
446 case GL_PIXEL_PACK_BUFFER:
447 ret = m_pixelPackBuffer;
448 break;
449 case GL_PIXEL_UNPACK_BUFFER:
450 ret = m_pixelUnpackBuffer;
451 break;
452 case GL_TRANSFORM_FEEDBACK_BUFFER:
453 ret = m_transformFeedbackBuffer;
454 break;
455 case GL_UNIFORM_BUFFER:
456 ret = m_uniformBuffer;
457 break;
458 case GL_ATOMIC_COUNTER_BUFFER:
459 ret = m_atomicCounterBuffer;
460 break;
461 case GL_DISPATCH_INDIRECT_BUFFER:
462 ret = m_dispatchIndirectBuffer;
463 break;
464 case GL_DRAW_INDIRECT_BUFFER:
465 ret = m_drawIndirectBuffer;
466 break;
467 case GL_SHADER_STORAGE_BUFFER:
468 ret = m_shaderStorageBuffer;
469 break;
470 default:
471 ret = -1;
472 }
473 return ret;
474}
475
keunyoungb85b2752013-03-08 12:28:03 -0800476void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
477{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800478 GLenum which_state = -1;
keunyoungb85b2752013-03-08 12:28:03 -0800479 switch (pname) {
480 case GL_VERTEX_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800481 which_state = GLClientState::VERTEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800482 break;
483 }
484 case GL_NORMAL_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800485 which_state = GLClientState::NORMAL_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800486 break;
487 }
488 case GL_COLOR_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800489 which_state = GLClientState::COLOR_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800490 break;
491 }
492 case GL_TEXTURE_COORD_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800493 which_state = getActiveTexture() + GLClientState::TEXCOORD0_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800494 break;
495 }
496 case GL_POINT_SIZE_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800497 which_state = GLClientState::POINTSIZE_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800498 break;
499 }
500 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800501 which_state = GLClientState::MATRIXINDEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800502 break;
503 }
504 case GL_WEIGHT_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800505 which_state = GLClientState::WEIGHT_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800506 break;
507 }
508 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800509 if (which_state != -1)
510 *params = getState(which_state).data;
keunyoungb85b2752013-03-08 12:28:03 -0800511}
512
513int GLClientState::setPixelStore(GLenum param, GLint value)
514{
515 int retval = 0;
516 switch(param) {
517 case GL_UNPACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800518 m_pixelStore.unpack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800519 break;
520 case GL_PACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800521 m_pixelStore.pack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800522 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800523 case GL_UNPACK_ROW_LENGTH:
524 m_pixelStore.unpack_row_length = value;
525 break;
526 case GL_UNPACK_IMAGE_HEIGHT:
527 m_pixelStore.unpack_image_height = value;
528 break;
529 case GL_UNPACK_SKIP_PIXELS:
530 m_pixelStore.unpack_skip_pixels = value;
531 break;
532 case GL_UNPACK_SKIP_ROWS:
533 m_pixelStore.unpack_skip_rows = value;
534 break;
535 case GL_UNPACK_SKIP_IMAGES:
536 m_pixelStore.unpack_skip_images = value;
537 break;
538 case GL_PACK_ROW_LENGTH:
539 m_pixelStore.pack_row_length = value;
540 break;
541 case GL_PACK_SKIP_PIXELS:
542 m_pixelStore.pack_skip_pixels = value;
543 break;
544 case GL_PACK_SKIP_ROWS:
545 m_pixelStore.pack_skip_rows = value;
546 break;
547 default:
548 retval = GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800549 }
550 return retval;
551}
552
553
Lingfeng Yang74e29292017-01-10 14:54:38 -0800554size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
keunyoungb85b2752013-03-08 12:28:03 -0800555{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800556 if (width <= 0 || height <= 0 || depth <= 0) return 0;
bohubd119bf2014-10-17 13:48:06 -0700557
Lingfeng Yang74e29292017-01-10 14:54:38 -0800558 ALOGV("%s: pack? %d", __FUNCTION__, pack);
559 if (pack) {
560 ALOGV("%s: pack stats", __FUNCTION__);
561 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
562 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
563 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
564 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
565 } else {
566 ALOGV("%s: unpack stats", __FUNCTION__);
567 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
568 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
569 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
570 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
571 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
572 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800573 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800574 return GLESTextureUtils::computeTotalImageSize(
575 width, height, depth,
576 format, type,
577 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
578 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
579 pack ? 0 : m_pixelStore.unpack_image_height,
580 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
581 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
582 pack ? 0 : m_pixelStore.unpack_skip_images);
583}
584
585size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
586{
587 if (width <= 0 || height <= 0 || depth <= 0) return 0;
588
589 ALOGV("%s: pack? %d", __FUNCTION__, pack);
590 if (pack) {
591 ALOGV("%s: pack stats", __FUNCTION__);
592 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
593 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
594 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
595 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
596 } else {
597 ALOGV("%s: unpack stats", __FUNCTION__);
598 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
599 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
600 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
601 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
602 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
603 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800604 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800605 return GLESTextureUtils::computeNeededBufferSize(
606 width, height, depth,
607 format, type,
608 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
609 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
610 pack ? 0 : m_pixelStore.unpack_image_height,
611 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
612 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
613 pack ? 0 : m_pixelStore.unpack_skip_images);
614}
615
616
617size_t GLClientState::clearBufferNumElts(GLenum buffer) const
618{
619 switch (buffer) {
620 case GL_COLOR:
621 return 4;
622 case GL_DEPTH:
623 case GL_STENCIL:
624 return 1;
625 }
626 return 1;
627}
628
629void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) {
630 UniformBlockInfoKey key;
631 key.program = program;
632 key.uniformBlockIndex = uniformBlockIndex;
633
634 UniformBlockUniformInfo info;
635 info.numActiveUniforms = (size_t)numActiveUniforms;
636
637 m_uniformBlockInfoMap[key] = info;
638}
639
640size_t GLClientState::numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const {
641 UniformBlockInfoKey key;
642 key.program = program;
643 key.uniformBlockIndex = uniformBlockIndex;
644 UniformBlockInfoMap::const_iterator it =
645 m_uniformBlockInfoMap.find(key);
646 if (it == m_uniformBlockInfoMap.end()) return 0;
647 return it->second.numActiveUniforms;
648}
649
keunyoungb85b2752013-03-08 12:28:03 -0800650}
651
652GLenum GLClientState::setActiveTextureUnit(GLenum texture)
653{
654 GLuint unit = texture - GL_TEXTURE0;
655 if (unit >= MAX_TEXTURE_UNITS) {
Yahan Zhoudb856572016-03-01 12:03:48 -0800656 return GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800657 }
658 m_tex.activeUnit = &m_tex.unit[unit];
659 return GL_NO_ERROR;
660}
661
662GLenum GLClientState::getActiveTextureUnit() const
663{
664 return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
665}
666
667void GLClientState::enableTextureTarget(GLenum target)
668{
669 switch (target) {
670 case GL_TEXTURE_2D:
671 m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
672 break;
673 case GL_TEXTURE_EXTERNAL_OES:
674 m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
675 break;
676 }
677}
678
679void GLClientState::disableTextureTarget(GLenum target)
680{
681 switch (target) {
682 case GL_TEXTURE_2D:
683 m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
684 break;
685 case GL_TEXTURE_EXTERNAL_OES:
686 m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
687 break;
688 }
689}
690
691GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
692{
693 unsigned int enables = m_tex.activeUnit->enables;
694 if (enables & (1u << TEXTURE_EXTERNAL)) {
695 return GL_TEXTURE_EXTERNAL_OES;
696 } else if (enables & (1u << TEXTURE_2D)) {
697 return GL_TEXTURE_2D;
698 } else {
699 return allDisabled;
700 }
701}
702
703int GLClientState::compareTexId(const void* pid, const void* prec)
704{
705 const GLuint* id = (const GLuint*)pid;
706 const TextureRec* rec = (const TextureRec*)prec;
707 return (GLint)(*id) - (GLint)rec->id;
708}
709
710GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
711 GLboolean* firstUse)
712{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800713 assert(m_tex.textureRecs);
keunyoungb85b2752013-03-08 12:28:03 -0800714 GLboolean first = GL_FALSE;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800715
716 TextureRec* texrec = getTextureRec(texture);
717 if (!texrec) {
718 texrec = addTextureRec(texture, target);
719 }
720
721 if (texture && target != texrec->target &&
722 (target != GL_TEXTURE_EXTERNAL_OES &&
723 texrec->target != GL_TEXTURE_EXTERNAL_OES)) {
724 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 -0800725 }
726
727 switch (target) {
728 case GL_TEXTURE_2D:
729 m_tex.activeUnit->texture[TEXTURE_2D] = texture;
730 break;
731 case GL_TEXTURE_EXTERNAL_OES:
732 m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
733 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800734 case GL_TEXTURE_CUBE_MAP:
735 m_tex.activeUnit->texture[TEXTURE_CUBE_MAP] = texture;
736 break;
737 case GL_TEXTURE_2D_ARRAY:
738 m_tex.activeUnit->texture[TEXTURE_2D_ARRAY] = texture;
739 break;
740 case GL_TEXTURE_3D:
741 m_tex.activeUnit->texture[TEXTURE_3D] = texture;
742 break;
743 case GL_TEXTURE_2D_MULTISAMPLE:
744 m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE] = texture;
745 break;
keunyoungb85b2752013-03-08 12:28:03 -0800746 }
747
748 if (firstUse) {
749 *firstUse = first;
750 }
751
752 return GL_NO_ERROR;
753}
754
Lingfeng Yang74e29292017-01-10 14:54:38 -0800755void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) {
756 GLuint texture = getBoundTexture(target);
757 TextureRec* texrec = getTextureRec(texture);
758 if (!texrec) return;
759 texrec->boundEGLImage = true;
760}
761
762TextureRec* GLClientState::addTextureRec(GLuint id, GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -0800763{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800764 TextureRec* tex = new TextureRec;
keunyoungb85b2752013-03-08 12:28:03 -0800765 tex->id = id;
766 tex->target = target;
Lingfeng Yang69066602016-04-12 09:29:11 -0700767 tex->format = -1;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800768 tex->multisamples = 0;
769 tex->immutable = false;
770 tex->boundEGLImage = false;
771 tex->dims = new TextureDims;
keunyoungb85b2752013-03-08 12:28:03 -0800772
Lingfeng Yang74e29292017-01-10 14:54:38 -0800773 (*(m_tex.textureRecs))[id] = tex;
keunyoungb85b2752013-03-08 12:28:03 -0800774 return tex;
775}
776
Lingfeng Yang74e29292017-01-10 14:54:38 -0800777TextureRec* GLClientState::getTextureRec(GLuint id) const {
778 SharedTextureDataMap::const_iterator it =
779 m_tex.textureRecs->find(id);
780 if (it == m_tex.textureRecs->end()) {
781 return NULL;
782 }
783 return it->second;
784}
785
Lingfeng Yang69066602016-04-12 09:29:11 -0700786void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
787 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800788 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700789 if (!texrec) return;
790 texrec->internalformat = internalformat;
791}
792
793void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) {
794 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800795 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700796 if (!texrec) return;
797 texrec->format = format;
798}
799
800void GLClientState::setBoundTextureType(GLenum target, GLenum type) {
801 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800802 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700803 if (!texrec) return;
804 texrec->type = type;
805}
806
Lingfeng Yang74e29292017-01-10 14:54:38 -0800807void GLClientState::setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) {
808 GLuint texture = getBoundTexture(target);
809 TextureRec* texrec = getTextureRec(texture);
810 if (!texrec) {
811 return;
812 }
813
814 if (level == -1) {
815 GLsizei curr_width = width;
816 GLsizei curr_height = height;
817 GLsizei curr_depth = depth;
818 GLsizei curr_level = 0;
819
820 while (true) {
821 texrec->dims->widths[curr_level] = curr_width;
822 texrec->dims->heights[curr_level] = curr_height;
823 texrec->dims->depths[curr_level] = curr_depth;
824 if (curr_width >> 1 == 0 &&
825 curr_height >> 1 == 0 &&
826 ((target == GL_TEXTURE_3D && curr_depth == 0) ||
827 true)) {
828 break;
829 }
830 curr_width = (curr_width >> 1) ? (curr_width >> 1) : 1;
831 curr_height = (curr_height >> 1) ? (curr_height >> 1) : 1;
832 if (target == GL_TEXTURE_3D) {
833 curr_depth = (curr_depth >> 1) ? (curr_depth >> 1) : 1;
834 }
835 curr_level++;
836 }
837
838 } else {
839 texrec->dims->widths[level] = width;
840 texrec->dims->heights[level] = height;
841 texrec->dims->depths[level] = depth;
842 }
843}
844
845void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) {
846 GLuint texture = getBoundTexture(target);
847 TextureRec* texrec = getTextureRec(texture);
848 if (!texrec) return;
849 texrec->multisamples = samples;
850}
851
852void GLClientState::setBoundTextureImmutableFormat(GLenum target) {
853 GLuint texture = getBoundTexture(target);
854 TextureRec* texrec = getTextureRec(texture);
855 if (!texrec) return;
856 texrec->immutable = true;
857}
858
859bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const {
860 GLuint texture = getBoundTexture(target);
861 TextureRec* texrec = getTextureRec(texture);
862 if (!texrec) return false;
863 return texrec->immutable;
864}
865
keunyoungb85b2752013-03-08 12:28:03 -0800866GLuint GLClientState::getBoundTexture(GLenum target) const
867{
868 switch (target) {
869 case GL_TEXTURE_2D:
870 return m_tex.activeUnit->texture[TEXTURE_2D];
871 case GL_TEXTURE_EXTERNAL_OES:
872 return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
Lingfeng Yang74e29292017-01-10 14:54:38 -0800873 case GL_TEXTURE_CUBE_MAP:
874 return m_tex.activeUnit->texture[TEXTURE_CUBE_MAP];
875 case GL_TEXTURE_2D_ARRAY:
876 return m_tex.activeUnit->texture[TEXTURE_2D_ARRAY];
877 case GL_TEXTURE_3D:
878 return m_tex.activeUnit->texture[TEXTURE_3D];
879 case GL_TEXTURE_2D_MULTISAMPLE:
880 return m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE];
keunyoungb85b2752013-03-08 12:28:03 -0800881 default:
882 return 0;
883 }
884}
885
Lingfeng Yange00ec9d2016-09-16 08:54:03 -0700886// BEGIN driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
887// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
888
889static bool unreliableInternalFormat(GLenum internalformat) {
890 switch (internalformat) {
891 case GL_LUMINANCE:
892 return true;
893 default:
894 return false;
895 }
896}
897
898void GLClientState::writeCopyTexImageState
899 (GLenum target, GLint level, GLenum internalformat) {
900 if (unreliableInternalFormat(internalformat)) {
901 CubeMapDef entry;
902 entry.id = getBoundTexture(GL_TEXTURE_2D);
903 entry.target = target;
904 entry.level = level;
905 entry.internalformat = internalformat;
906 m_cubeMapDefs.insert(entry);
907 }
908}
909
910static GLenum identifyPositiveCubeMapComponent(GLenum target) {
911 switch (target) {
912 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
913 return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
914 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
915 return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
916 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
917 return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
918 default:
919 return 0;
920 }
921}
922
923GLenum GLClientState::copyTexImageNeededTarget
924 (GLenum target, GLint level, GLenum internalformat) {
925 if (unreliableInternalFormat(internalformat)) {
926 GLenum positiveComponent =
927 identifyPositiveCubeMapComponent(target);
928 if (positiveComponent) {
929 CubeMapDef query;
930 query.id = getBoundTexture(GL_TEXTURE_2D);
931 query.target = positiveComponent;
932 query.level = level;
933 query.internalformat = internalformat;
934 if (m_cubeMapDefs.find(query) ==
935 m_cubeMapDefs.end()) {
936 return positiveComponent;
937 }
938 }
939 }
940 return 0;
941}
942
943GLenum GLClientState::copyTexImageLuminanceCubeMapAMDWorkaround
944 (GLenum target, GLint level, GLenum internalformat) {
945 writeCopyTexImageState(target, level, internalformat);
946 return copyTexImageNeededTarget(target, level, internalformat);
947}
948
949// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
950// END driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
951
keunyoungb85b2752013-03-08 12:28:03 -0800952void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
953{
954 // Updating the textures array could be made more efficient when deleting
955 // several textures:
956 // - compacting the array could be done in a single pass once the deleted
957 // textures are marked, or
958 // - could swap deleted textures to the end and re-sort.
959 TextureRec* texrec;
960 for (const GLuint* texture = textures; texture != textures + n; texture++) {
Lingfeng Yang74e29292017-01-10 14:54:38 -0800961 texrec = getTextureRec(*texture);
962 if (texrec && texrec->dims) {
963 delete texrec->dims;
964 }
keunyoungb85b2752013-03-08 12:28:03 -0800965 if (texrec) {
Lingfeng Yang74e29292017-01-10 14:54:38 -0800966 m_tex.textureRecs->erase(*texture);
967 delete texrec;
keunyoungb85b2752013-03-08 12:28:03 -0800968 for (TextureUnit* unit = m_tex.unit;
969 unit != m_tex.unit + MAX_TEXTURE_UNITS;
970 unit++)
971 {
972 if (unit->texture[TEXTURE_2D] == *texture) {
973 unit->texture[TEXTURE_2D] = 0;
974 } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
975 unit->texture[TEXTURE_EXTERNAL] = 0;
976 }
977 }
978 }
979 }
980}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700981
982// RBO//////////////////////////////////////////////////////////////////////////
983
984void GLClientState::addFreshRenderbuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800985 // if underlying opengl says these are fresh names,
986 // but we are keeping a stale one, reset it.
987 RboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700988 props.target = GL_RENDERBUFFER;
989 props.name = name;
Lingfeng Yang69066602016-04-12 09:29:11 -0700990 props.format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800991 props.multisamples = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700992 props.previouslyBound = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800993
994 if (usedRenderbufferName(name)) {
995 mRboState.rboData[getRboIndex(name)] = props;
996 } else {
997 mRboState.rboData.push_back(props);
998 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700999}
1000
1001void GLClientState::addRenderbuffers(GLsizei n, GLuint* renderbuffers) {
1002 for (size_t i = 0; i < n; i++) {
1003 addFreshRenderbuffer(renderbuffers[i]);
1004 }
1005}
1006
1007size_t GLClientState::getRboIndex(GLuint name) const {
1008 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1009 if (mRboState.rboData[i].name == name) {
1010 return i;
1011 }
1012 }
1013 return -1;
1014}
1015
1016void GLClientState::removeRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
1017 size_t bound_rbo_idx = getRboIndex(boundRboProps_const().name);
1018
1019 std::vector<GLuint> to_remove;
1020 for (size_t i = 0; i < n; i++) {
1021 if (renderbuffers[i] != 0) { // Never remove the zero rb.
1022 to_remove.push_back(getRboIndex(renderbuffers[i]));
1023 }
1024 }
1025
1026 for (size_t i = 0; i < to_remove.size(); i++) {
1027 mRboState.rboData[to_remove[i]] = mRboState.rboData.back();
1028 mRboState.rboData.pop_back();
1029 }
1030
1031 // If we just deleted the currently bound rb,
1032 // bind the zero rb
1033 if (getRboIndex(boundRboProps_const().name) != bound_rbo_idx) {
1034 bindRenderbuffer(GL_RENDERBUFFER, 0);
1035 }
1036}
1037
1038bool GLClientState::usedRenderbufferName(GLuint name) const {
1039 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1040 if (mRboState.rboData[i].name == name) {
1041 return true;
1042 }
1043 }
1044 return false;
1045}
1046
1047void GLClientState::setBoundRenderbufferIndex() {
1048 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1049 if (mRboState.rboData[i].name == mRboState.boundRenderbuffer) {
1050 mRboState.boundRenderbufferIndex = i;
1051 break;
1052 }
1053 }
1054}
1055
1056RboProps& GLClientState::boundRboProps() {
1057 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1058}
1059
1060const RboProps& GLClientState::boundRboProps_const() const {
1061 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1062}
1063
1064void GLClientState::bindRenderbuffer(GLenum target, GLuint name) {
1065 // If unused, add it.
1066 if (!usedRenderbufferName(name)) {
1067 addFreshRenderbuffer(name);
1068 }
1069 mRboState.boundRenderbuffer = name;
1070 setBoundRenderbufferIndex();
1071 boundRboProps().target = target;
1072 boundRboProps().previouslyBound = true;
1073}
1074
1075GLuint GLClientState::boundRenderbuffer() const {
1076 return boundRboProps_const().name;
1077}
1078
Lingfeng Yang69066602016-04-12 09:29:11 -07001079void GLClientState::setBoundRenderbufferFormat(GLenum format) {
1080 boundRboProps().format = format;
1081}
1082
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001083void GLClientState::setBoundRenderbufferSamples(GLsizei samples) {
1084 boundRboProps().multisamples = samples;
1085}
1086
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001087// FBO//////////////////////////////////////////////////////////////////////////
1088
Lingfeng Yang69066602016-04-12 09:29:11 -07001089// Format querying
1090
1091GLenum GLClientState::queryRboFormat(GLuint rbo_name) const {
1092 return mRboState.rboData[getRboIndex(rbo_name)].format;
1093}
1094
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001095GLsizei GLClientState::queryRboSamples(GLuint rbo_name) const {
1096 return mRboState.rboData[getRboIndex(rbo_name)].multisamples;
1097}
1098
Lingfeng Yang69066602016-04-12 09:29:11 -07001099GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001100 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001101 if (!texrec) return -1;
1102 return texrec->internalformat;
1103}
1104
Lingfeng Yang74e29292017-01-10 14:54:38 -08001105GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const {
1106 TextureRec* texrec = getTextureRec(tex_name);
1107 if (!texrec) {
1108 return 0;
1109 }
1110 return texrec->dims->widths[level];
1111}
1112
1113GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const {
1114 TextureRec* texrec = getTextureRec(tex_name);
1115 if (!texrec) return 0;
1116 return texrec->dims->heights[level];
1117}
1118
1119GLsizei GLClientState::queryTexDepth(GLsizei level, GLuint tex_name) const {
1120 TextureRec* texrec = getTextureRec(tex_name);
1121 if (!texrec) return 0;
1122 return texrec->dims->depths[level];
1123}
1124
1125bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const {
1126 TextureRec* texrec = getTextureRec(tex_name);
1127 if (!texrec) return false;
1128 return texrec->boundEGLImage;
1129}
1130
Lingfeng Yang69066602016-04-12 09:29:11 -07001131GLenum GLClientState::queryTexFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001132 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001133 if (!texrec) return -1;
1134 return texrec->format;
1135}
1136
1137GLenum GLClientState::queryTexType(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001138 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001139 if (!texrec) return -1;
1140 return texrec->type;
1141}
1142
Lingfeng Yang74e29292017-01-10 14:54:38 -08001143GLsizei GLClientState::queryTexSamples(GLuint tex_name) const {
1144 TextureRec* texrec = getTextureRec(tex_name);
1145 if (!texrec) return 0;
1146 return texrec->multisamples;
1147}
1148
1149GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const {
1150 TextureRec* texrec = getTextureRec(tex_name);
1151 if (!texrec) return GL_NONE;
1152 return texrec->target;
1153}
1154
Lingfeng Yang69066602016-04-12 09:29:11 -07001155void GLClientState::getBoundFramebufferFormat(
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001156 GLenum target,
Lingfeng Yang69066602016-04-12 09:29:11 -07001157 GLenum attachment, FboFormatInfo* res_info) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001158 const FboProps& props = boundFboProps_const(target);
Lingfeng Yang69066602016-04-12 09:29:11 -07001159
1160 res_info->type = FBO_ATTACHMENT_NONE;
1161 res_info->rb_format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001162 res_info->rb_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001163 res_info->tex_internalformat = -1;
1164 res_info->tex_format = GL_NONE;
1165 res_info->tex_type = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001166 res_info->tex_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001167
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001168 int colorAttachmentIndex =
1169 glUtilsColorAttachmentIndex(attachment);
1170
1171 if (colorAttachmentIndex != -1) {
1172 if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001173 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001174 res_info->rb_format =
1175 queryRboFormat(
1176 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1177 res_info->rb_multisamples =
1178 queryRboSamples(
1179 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1180 } else if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001181 res_info->type = FBO_ATTACHMENT_TEXTURE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001182 res_info->tex_internalformat =
1183 queryTexInternalFormat(
1184 props.colorAttachmenti_textures[colorAttachmentIndex]);
1185 res_info->tex_format =
1186 queryTexFormat(
1187 props.colorAttachmenti_textures[colorAttachmentIndex]);
1188 res_info->tex_type =
1189 queryTexType(props.colorAttachmenti_textures[colorAttachmentIndex]);
1190 res_info->tex_multisamples =
1191 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001192 } else {
1193 res_info->type = FBO_ATTACHMENT_NONE;
1194 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001195 }
1196
1197 switch (attachment) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001198 case GL_DEPTH_ATTACHMENT:
1199 if (props.depthAttachment_hasRbo) {
1200 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1201 res_info->rb_format = queryRboFormat(props.depthAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001202 res_info->rb_multisamples =
1203 queryRboSamples(
1204 props.colorAttachmenti_rbos[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001205 } else if (props.depthAttachment_hasTexObj) {
1206 res_info->type = FBO_ATTACHMENT_TEXTURE;
1207 res_info->tex_internalformat = queryTexInternalFormat(props.depthAttachment_texture);
1208 res_info->tex_format = queryTexFormat(props.depthAttachment_texture);
1209 res_info->tex_type = queryTexType(props.depthAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001210 res_info->tex_multisamples =
1211 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001212 } else {
1213 res_info->type = FBO_ATTACHMENT_NONE;
1214 }
1215 break;
1216 case GL_STENCIL_ATTACHMENT:
1217 if (props.stencilAttachment_hasRbo) {
1218 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1219 res_info->rb_format = queryRboFormat(props.stencilAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001220 res_info->rb_multisamples =
1221 queryRboSamples(
1222 props.colorAttachmenti_rbos[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001223 } else if (props.stencilAttachment_hasTexObj) {
1224 res_info->type = FBO_ATTACHMENT_TEXTURE;
1225 res_info->tex_internalformat = queryTexInternalFormat(props.stencilAttachment_texture);
1226 res_info->tex_format = queryTexFormat(props.stencilAttachment_texture);
1227 res_info->tex_type = queryTexType(props.stencilAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001228 res_info->tex_multisamples =
1229 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001230 } else {
1231 res_info->type = FBO_ATTACHMENT_NONE;
1232 }
1233 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001234 case GL_DEPTH_STENCIL_ATTACHMENT:
1235 if (props.depthstencilAttachment_hasRbo) {
1236 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1237 res_info->rb_format = queryRboFormat(props.depthstencilAttachment_rbo);
1238 res_info->rb_multisamples =
1239 queryRboSamples(
1240 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1241 } else if (props.depthstencilAttachment_hasTexObj) {
1242 res_info->type = FBO_ATTACHMENT_TEXTURE;
1243 res_info->tex_internalformat = queryTexInternalFormat(props.depthstencilAttachment_texture);
1244 res_info->tex_format = queryTexFormat(props.depthstencilAttachment_texture);
1245 res_info->tex_type = queryTexType(props.depthstencilAttachment_texture);
1246 res_info->tex_multisamples =
1247 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
1248 } else {
1249 res_info->type = FBO_ATTACHMENT_NONE;
1250 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001251 break;
1252 }
1253}
1254
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001255FboAttachmentType GLClientState::getBoundFramebufferAttachmentType(GLenum target, GLenum attachment) const {
1256 FboFormatInfo info;
1257 getBoundFramebufferFormat(target, attachment, &info);
1258 return info.type;
1259}
1260
1261
1262int GLClientState::getMaxColorAttachments() const {
1263 return m_max_color_attachments;
1264}
1265
1266int GLClientState::getMaxDrawBuffers() const {
1267 return m_max_draw_buffers;
1268}
1269
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001270void GLClientState::addFreshFramebuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001271 FboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001272 props.name = name;
1273 props.previouslyBound = false;
1274
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001275 props.colorAttachmenti_textures.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001276 props.depthAttachment_texture = 0;
1277 props.stencilAttachment_texture = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001278 props.depthstencilAttachment_texture = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001279
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001280 props.colorAttachmenti_hasTex.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001281 props.depthAttachment_hasTexObj = false;
1282 props.stencilAttachment_hasTexObj = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001283 props.depthstencilAttachment_hasTexObj = false;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001284
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001285 props.colorAttachmenti_rbos.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001286 props.depthAttachment_rbo = 0;
1287 props.stencilAttachment_rbo = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001288 props.depthstencilAttachment_rbo = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001289
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001290 props.colorAttachmenti_hasRbo.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001291 props.depthAttachment_hasRbo = false;
1292 props.stencilAttachment_hasRbo = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001293 props.depthstencilAttachment_hasRbo = false;
1294 mFboState.fboData[name] = props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001295}
1296
1297void GLClientState::addFramebuffers(GLsizei n, GLuint* framebuffers) {
1298 for (size_t i = 0; i < n; i++) {
1299 addFreshFramebuffer(framebuffers[i]);
1300 }
1301}
1302
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001303void GLClientState::removeFramebuffers(GLsizei n, const GLuint* framebuffers) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001304 for (size_t i = 0; i < n; i++) {
1305 if (framebuffers[i] != 0) { // Never remove the zero fb.
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001306 if (framebuffers[i] == mFboState.boundDrawFramebuffer) {
1307 bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1308 }
1309 if (framebuffers[i] == mFboState.boundReadFramebuffer) {
1310 bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1311 }
1312 mFboState.fboData.erase(framebuffers[i]);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001313 }
1314 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001315}
1316
1317bool GLClientState::usedFramebufferName(GLuint name) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001318 return mFboState.fboData.find(name) != mFboState.fboData.end();
1319}
1320
1321FboProps& GLClientState::boundFboProps(GLenum target) {
1322 switch (target) {
1323 case GL_DRAW_FRAMEBUFFER:
1324 return mFboState.fboData[mFboState.boundDrawFramebuffer];
1325 case GL_READ_FRAMEBUFFER:
1326 return mFboState.fboData[mFboState.boundReadFramebuffer];
1327 case GL_FRAMEBUFFER:
1328 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001329 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001330 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001331}
1332
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001333const FboProps& GLClientState::boundFboProps_const(GLenum target) const {
1334 switch (target) {
1335 case GL_DRAW_FRAMEBUFFER:
1336 return mFboState.fboData.at(mFboState.boundDrawFramebuffer);
1337 case GL_READ_FRAMEBUFFER:
1338 return mFboState.fboData.at(mFboState.boundReadFramebuffer);
1339 case GL_FRAMEBUFFER:
1340 return mFboState.fboData.at(mFboState.boundDrawFramebuffer);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001341 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001342 return mFboState.fboData.at(mFboState.boundDrawFramebuffer);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001343}
1344
1345void GLClientState::bindFramebuffer(GLenum target, GLuint name) {
1346 // If unused, add it.
1347 if (!usedFramebufferName(name)) {
1348 addFreshFramebuffer(name);
1349 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001350 switch (target) {
1351 case GL_DRAW_FRAMEBUFFER:
1352 mFboState.boundDrawFramebuffer = name;
1353 break;
1354 case GL_READ_FRAMEBUFFER:
1355 mFboState.boundReadFramebuffer = name;
1356 break;
1357 default: // case GL_FRAMEBUFFER:
1358 mFboState.boundDrawFramebuffer = name;
1359 mFboState.boundReadFramebuffer = name;
1360 break;
1361 }
1362 boundFboProps(target).previouslyBound = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001363}
1364
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001365void GLClientState::setCheckFramebufferStatus(GLenum target, GLenum status) {
1366 switch (target) {
1367 case GL_DRAW_FRAMEBUFFER:
1368 mFboState.drawFboCheckStatus = status;
1369 break;
1370 case GL_READ_FRAMEBUFFER:
1371 mFboState.readFboCheckStatus = status;
1372 break;
1373 case GL_FRAMEBUFFER:
1374 mFboState.drawFboCheckStatus = status;
1375 break;
1376 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001377}
1378
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001379GLenum GLClientState::getCheckFramebufferStatus(GLenum target) const {
1380 switch (target) {
1381 case GL_DRAW_FRAMEBUFFER:
1382 return mFboState.drawFboCheckStatus;
1383 case GL_READ_FRAMEBUFFER:
1384 return mFboState.readFboCheckStatus;
1385 case GL_FRAMEBUFFER:
1386 return mFboState.drawFboCheckStatus;
1387 }
1388 return mFboState.drawFboCheckStatus;
Lingfeng Yang69066602016-04-12 09:29:11 -07001389}
1390
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001391GLuint GLClientState::boundFramebuffer(GLenum target) const {
1392 return boundFboProps_const(target).name;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001393}
1394
1395// Texture objects for FBOs/////////////////////////////////////////////////////
1396
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001397void GLClientState::attachTextureObject(
1398 GLenum target,
1399 GLenum attachment, GLuint texture) {
1400
1401 int colorAttachmentIndex =
1402 glUtilsColorAttachmentIndex(attachment);
1403
1404 if (colorAttachmentIndex != -1) {
1405 boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texture;
1406 boundFboProps(target).colorAttachmenti_hasTex[colorAttachmentIndex] = true;
1407 }
1408
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001409 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001410 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001411 boundFboProps(target).depthAttachment_texture = texture;
1412 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001413 break;
1414 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001415 boundFboProps(target).stencilAttachment_texture = texture;
1416 boundFboProps(target).stencilAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001417 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001418 case GL_DEPTH_STENCIL_ATTACHMENT:
1419 boundFboProps(target).depthstencilAttachment_texture = texture;
1420 boundFboProps(target).depthstencilAttachment_hasTexObj = true;
1421 boundFboProps(target).stencilAttachment_texture = texture;
1422 boundFboProps(target).stencilAttachment_hasTexObj = true;
1423 boundFboProps(target).depthAttachment_texture = texture;
1424 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001425 break;
1426 }
1427}
1428
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001429GLuint GLClientState::getFboAttachmentTextureId(GLenum target, GLenum attachment) const {
1430 GLuint res = 0; // conservative
1431
1432 int colorAttachmentIndex =
1433 glUtilsColorAttachmentIndex(attachment);
1434
1435 if (colorAttachmentIndex != -1) {
1436 res = boundFboProps_const(target).colorAttachmenti_textures[colorAttachmentIndex];
1437 }
1438
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001439 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001440 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001441 res = boundFboProps_const(target).depthAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001442 break;
1443 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001444 res = boundFboProps_const(target).stencilAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001445 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001446 case GL_DEPTH_STENCIL_ATTACHMENT:
1447 res = boundFboProps_const(target).depthstencilAttachment_texture;
1448 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001449 }
1450 return res;
1451}
1452
1453// RBOs for FBOs////////////////////////////////////////////////////////////////
1454
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001455void GLClientState::detachRbo(GLuint renderbuffer) {
1456 for (int i = 0; i < m_max_color_attachments; i++) {
1457 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1458 detachRboFromFbo(GL_READ_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1459 }
1460
1461 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1462 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1463
1464 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1465 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1466
1467 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1468 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1469}
1470
1471void GLClientState::detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1472 int colorAttachmentIndex =
1473 glUtilsColorAttachmentIndex(attachment);
1474
1475 if (colorAttachmentIndex != -1) {
1476 if (boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] &&
1477 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] == renderbuffer) {
1478 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = 0;
1479 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = false;
1480 }
1481 }
1482
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001483 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001484 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001485 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1486 boundFboProps(target).depthAttachment_hasRbo) {
1487 boundFboProps(target).depthAttachment_rbo = 0;
1488 boundFboProps(target).depthAttachment_hasRbo = false;
1489 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001490 break;
1491 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001492 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1493 boundFboProps(target).stencilAttachment_hasRbo) {
1494 boundFboProps(target).stencilAttachment_rbo = 0;
1495 boundFboProps(target).stencilAttachment_hasRbo = false;
1496 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001497 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001498 case GL_DEPTH_STENCIL_ATTACHMENT:
1499 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1500 boundFboProps(target).depthAttachment_hasRbo) {
1501 boundFboProps(target).depthAttachment_rbo = 0;
1502 boundFboProps(target).depthAttachment_hasRbo = false;
1503 }
1504 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1505 boundFboProps(target).stencilAttachment_hasRbo) {
1506 boundFboProps(target).stencilAttachment_rbo = 0;
1507 boundFboProps(target).stencilAttachment_hasRbo = false;
1508 }
1509 if (boundFboProps(target).depthstencilAttachment_rbo == renderbuffer &&
1510 boundFboProps(target).depthstencilAttachment_hasRbo) {
1511 boundFboProps(target).depthstencilAttachment_rbo = 0;
1512 boundFboProps(target).depthstencilAttachment_hasRbo = false;
1513 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001514 break;
1515 }
1516}
1517
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001518void GLClientState::attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1519
1520 int colorAttachmentIndex =
1521 glUtilsColorAttachmentIndex(attachment);
1522
1523 if (colorAttachmentIndex != -1) {
1524 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = renderbuffer;
1525 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = true;
1526 }
1527
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001528 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001529 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001530 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1531 boundFboProps(target).depthAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001532 break;
1533 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001534 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1535 boundFboProps(target).stencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001536 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001537 case GL_DEPTH_STENCIL_ATTACHMENT:
1538 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1539 boundFboProps(target).depthAttachment_hasRbo = true;
1540 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1541 boundFboProps(target).stencilAttachment_hasRbo = true;
1542 boundFboProps(target).depthstencilAttachment_rbo = renderbuffer;
1543 boundFboProps(target).depthstencilAttachment_hasRbo = true;
1544 break;
1545 }
1546}
1547
1548GLuint GLClientState::getFboAttachmentRboId(GLenum target, GLenum attachment) const {
1549 GLuint res = 0; // conservative
1550
1551 int colorAttachmentIndex =
1552 glUtilsColorAttachmentIndex(attachment);
1553
1554 if (colorAttachmentIndex != -1) {
1555 res = boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex];
1556 }
1557
1558 switch (attachment) {
1559 case GL_DEPTH_ATTACHMENT:
1560 res = boundFboProps_const(target).depthAttachment_rbo;
1561 break;
1562 case GL_STENCIL_ATTACHMENT:
1563 res = boundFboProps_const(target).stencilAttachment_rbo;
1564 break;
1565 case GL_DEPTH_STENCIL_ATTACHMENT:
1566 res = boundFboProps_const(target).depthstencilAttachment_rbo;
1567 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001568 }
1569 return res;
1570}
1571
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001572bool GLClientState::attachmentHasObject(GLenum target, GLenum attachment) const {
1573 bool res = true; // liberal
1574
1575 int colorAttachmentIndex =
1576 glUtilsColorAttachmentIndex(attachment);
1577
1578 if (colorAttachmentIndex != -1) {
1579 res = boundFboProps_const(target).colorAttachmenti_hasTex[colorAttachmentIndex] ||
1580 boundFboProps_const(target).colorAttachmenti_hasRbo[colorAttachmentIndex];
1581 }
1582
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001583 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001584 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001585 res = (boundFboProps_const(target).depthAttachment_hasTexObj) ||
1586 (boundFboProps_const(target).depthAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001587 break;
1588 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001589 res = (boundFboProps_const(target).stencilAttachment_hasTexObj) ||
1590 (boundFboProps_const(target).stencilAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001591 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001592 case GL_DEPTH_STENCIL_ATTACHMENT:
1593 res = (boundFboProps_const(target).depthstencilAttachment_hasTexObj) ||
1594 (boundFboProps_const(target).depthstencilAttachment_hasRbo);
1595 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001596 }
1597 return res;
1598}
1599
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001600GLuint GLClientState::objectOfAttachment(GLenum target, GLenum attachment) const {
1601 const FboProps& props = boundFboProps_const(target);
1602
1603 int colorAttachmentIndex =
1604 glUtilsColorAttachmentIndex(attachment);
1605
1606 if (colorAttachmentIndex != -1) {
1607 if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
1608 return props.colorAttachmenti_textures[colorAttachmentIndex];
1609 } else if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
1610 return props.colorAttachmenti_rbos[colorAttachmentIndex];
1611 } else {
1612 return 0;
1613 }
1614 }
1615
1616 switch (attachment) {
1617 case GL_DEPTH_ATTACHMENT:
1618 if (props.depthAttachment_hasTexObj) {
1619 return props.depthAttachment_texture;
1620 } else if (props.depthAttachment_hasRbo) {
1621 return props.depthAttachment_rbo;
1622 } else {
1623 return 0;
1624 }
1625 break;
1626 case GL_STENCIL_ATTACHMENT:
1627 if (props.stencilAttachment_hasTexObj) {
1628 return props.stencilAttachment_texture;
1629 } else if (props.stencilAttachment_hasRbo) {
1630 return props.stencilAttachment_rbo;
1631 } else {
1632 return 0;
1633 }
1634 case GL_DEPTH_STENCIL_ATTACHMENT:
1635 if (props.depthstencilAttachment_hasTexObj) {
1636 return props.depthstencilAttachment_texture;
1637 } else if (props.depthstencilAttachment_hasRbo) {
1638 return props.depthstencilAttachment_rbo;
1639 } else {
1640 return 0;
1641 }
1642 break;
1643 }
1644 return 0;
1645}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001646void GLClientState::fromMakeCurrent() {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001647 if (mFboState.fboData.find(0) == mFboState.fboData.end()) {
1648 addFreshFramebuffer(0);
1649 }
1650 FboProps& default_fb_props = mFboState.fboData[0];
1651 default_fb_props.colorAttachmenti_hasRbo[0] = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001652 default_fb_props.depthAttachment_hasRbo = true;
1653 default_fb_props.stencilAttachment_hasRbo = true;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001654 default_fb_props.depthstencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001655}
Lingfeng Yangf654f3f2017-01-09 13:12:33 -08001656
1657void GLClientState::initFromCaps(
1658 int max_transform_feedback_separate_attribs,
1659 int max_uniform_buffer_bindings,
1660 int max_atomic_counter_buffer_bindings,
1661 int max_shader_storage_buffer_bindings,
1662 int max_vertex_attrib_bindings,
1663 int max_color_attachments,
1664 int max_draw_buffers) {
1665
1666 m_max_vertex_attrib_bindings = max_vertex_attrib_bindings;
1667
1668 if (m_glesMajorVersion >= 3) {
1669 m_max_transform_feedback_separate_attribs = max_transform_feedback_separate_attribs;
1670 m_max_uniform_buffer_bindings = max_uniform_buffer_bindings;
1671 m_max_atomic_counter_buffer_bindings = max_atomic_counter_buffer_bindings;
1672 m_max_shader_storage_buffer_bindings = max_shader_storage_buffer_bindings;
1673
1674 if (m_max_transform_feedback_separate_attribs)
1675 m_indexedTransformFeedbackBuffers.resize(m_max_transform_feedback_separate_attribs);
1676 if (m_max_uniform_buffer_bindings)
1677 m_indexedUniformBuffers.resize(m_max_uniform_buffer_bindings);
1678 if (m_max_atomic_counter_buffer_bindings)
1679 m_indexedAtomicCounterBuffers.resize(m_max_atomic_counter_buffer_bindings);
1680 if (m_max_shader_storage_buffer_bindings)
1681 m_indexedShaderStorageBuffers.resize(m_max_shader_storage_buffer_bindings);
1682
1683 BufferBinding buf0Binding;
1684 buf0Binding.buffer = 0;
1685 buf0Binding.offset = 0;
1686 buf0Binding.size = 0;
1687 buf0Binding.stride = 0;
1688 buf0Binding.effectiveStride = 0;
1689
1690 for (size_t i = 0; i < m_indexedTransformFeedbackBuffers.size(); ++i)
1691 m_indexedTransformFeedbackBuffers[i] = buf0Binding;
1692 for (size_t i = 0; i < m_indexedUniformBuffers.size(); ++i)
1693 m_indexedUniformBuffers[i] = buf0Binding;
1694 for (size_t i = 0; i < m_indexedAtomicCounterBuffers.size(); ++i)
1695 m_indexedAtomicCounterBuffers[i] = buf0Binding;
1696 for (size_t i = 0; i < m_indexedShaderStorageBuffers.size(); ++i)
1697 m_indexedShaderStorageBuffers[i] = buf0Binding;
1698 }
1699
1700 m_max_color_attachments = max_color_attachments;
1701 m_max_draw_buffers = max_draw_buffers;
1702
1703 addFreshRenderbuffer(0);
1704 addFreshFramebuffer(0);
1705
1706 m_initialized = true;
1707}
1708
1709bool GLClientState::needsInitFromCaps() const {
1710 return !m_initialized;
1711}