blob: 50d4d6547047dbeea985102b8cc7262b723c54d8 [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"
Luca Stefani1cb647a2019-03-07 21:58:17 +010023
24#if PLATFORM_SDK_VERSION < 26
Logan Chiend7bf00d2018-09-21 06:30:09 +000025#include <cutils/log.h>
Luca Stefani1cb647a2019-03-07 21:58:17 +010026#else
27#include <log/log.h>
28#endif
keunyoungb85b2752013-03-08 12:28:03 -080029
30#ifndef MAX
31#define MAX(a, b) ((a) < (b) ? (b) : (a))
32#endif
33
Lingfeng Yang74e29292017-01-10 14:54:38 -080034// Don't include these in the .h file, or we get weird compile errors.
35#include <GLES3/gl3.h>
36#include <GLES3/gl31.h>
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080037
38void GLClientState::init() {
39 m_initialized = false;
40 m_nLocations = CODEC_MAX_VERTEX_ATTRIBUTES;
41
42 m_arrayBuffer = 0;
Lingfeng Yang554a5152019-02-21 20:20:48 -080043 m_arrayBuffer_lastEncode = 0;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080044 m_max_vertex_attrib_bindings = m_nLocations;
45 addVertexArrayObject(0);
46 setVertexArrayObject(0);
keunyoungb85b2752013-03-08 12:28:03 -080047 // init gl constans;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080048 m_currVaoState[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
49 m_currVaoState[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
50 m_currVaoState[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
51 m_currVaoState[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
52 m_currVaoState[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
53 m_currVaoState[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
54 m_currVaoState[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
55 m_currVaoState[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
56 m_currVaoState[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
57 m_currVaoState[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
58 m_currVaoState[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
59 m_currVaoState[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
60 m_currVaoState[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
61 m_currVaoState[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
62
63 m_copyReadBuffer = 0;
64 m_copyWriteBuffer = 0;
65 m_pixelPackBuffer = 0;
66 m_pixelUnpackBuffer = 0;
67 m_transformFeedbackBuffer = 0;
68 m_uniformBuffer = 0;
69 m_atomicCounterBuffer = 0;
70 m_dispatchIndirectBuffer = 0;
71 m_drawIndirectBuffer = 0;
72 m_shaderStorageBuffer = 0;
73
74 m_transformFeedbackActiveUnpaused = false;
75
76 // to be modified later when these are queried from host.
77 m_max_transform_feedback_separate_attribs = 0;
78 m_max_uniform_buffer_bindings = 0;
79 m_max_atomic_counter_buffer_bindings = 0;
80 m_max_shader_storage_buffer_bindings = 0;
81
keunyoungb85b2752013-03-08 12:28:03 -080082 m_activeTexture = 0;
83 m_currentProgram = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -080084 m_currentShaderProgram = 0;
keunyoungb85b2752013-03-08 12:28:03 -080085
86 m_pixelStore.unpack_alignment = 4;
87 m_pixelStore.pack_alignment = 4;
88
Lingfeng Yang74e29292017-01-10 14:54:38 -080089 m_pixelStore.unpack_row_length = 0;
90 m_pixelStore.unpack_image_height = 0;
91 m_pixelStore.unpack_skip_pixels = 0;
92 m_pixelStore.unpack_skip_rows = 0;
93 m_pixelStore.unpack_skip_images = 0;
94
95 m_pixelStore.pack_row_length = 0;
96 m_pixelStore.pack_skip_pixels = 0;
97 m_pixelStore.pack_skip_rows = 0;
98
keunyoungb85b2752013-03-08 12:28:03 -080099 memset(m_tex.unit, 0, sizeof(m_tex.unit));
100 m_tex.activeUnit = &m_tex.unit[0];
Lingfeng Yang74e29292017-01-10 14:54:38 -0800101 m_tex.textureRecs = NULL;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800102
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700103 mRboState.boundRenderbuffer = 0;
104 mRboState.boundRenderbufferIndex = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700105
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800106 mFboState.boundDrawFramebuffer = 0;
107 mFboState.boundReadFramebuffer = 0;
108 mFboState.drawFboCheckStatus = GL_NONE;
109 mFboState.readFboCheckStatus = GL_NONE;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700110
Lingfeng Yangb0176982016-03-01 21:27:49 -0800111 m_maxVertexAttribsDirty = true;
keunyoungb85b2752013-03-08 12:28:03 -0800112}
113
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800114GLClientState::GLClientState()
115{
116 init();
117}
118
119GLClientState::GLClientState(int majorVersion, int minorVersion) :
120 m_glesMajorVersion(majorVersion),
121 m_glesMinorVersion(minorVersion) {
122 init();
123}
124
keunyoungb85b2752013-03-08 12:28:03 -0800125GLClientState::~GLClientState()
126{
keunyoungb85b2752013-03-08 12:28:03 -0800127}
128
129void GLClientState::enable(int location, int state)
130{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800131 m_currVaoState[location].enableDirty |= (state != m_currVaoState[location].enabled);
132 m_currVaoState[location].enabled = state;
133}
134
135void GLClientState::setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt)
136{
137 m_currVaoState[location].size = size;
138 m_currVaoState[location].type = type;
139 m_currVaoState[location].stride = stride;
140 m_currVaoState[location].data = (void*)data;
141 m_currVaoState[location].bufferObject = m_arrayBuffer;
142 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
143 switch (type) {
144 case GL_INT_2_10_10_10_REV:
145 case GL_UNSIGNED_INT_2_10_10_10_REV:
146 m_currVaoState[location].elementSize =
147 m_currVaoState[location].elementSize / 4;
148 break;
149 default:
150 break;
151 }
152 m_currVaoState[location].normalized = normalized;
153 m_currVaoState[location].isInt = isInt;
154}
155
156void GLClientState::setVertexBindingDivisor(int bindingindex, GLuint divisor) {
157 m_currVaoState.bufferBinding(bindingindex).divisor = divisor;
158}
159
160const GLClientState::BufferBinding& GLClientState::getCurrAttributeBindingInfo(int attribindex) {
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -0800161 return m_currVaoState.bufferBindings_const()[m_currVaoState[attribindex].bindingindex];
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800162}
163
164void GLClientState::setVertexAttribBinding(int attribindex, int bindingindex) {
165 m_currVaoState[attribindex].bindingindex = bindingindex;
166}
167
168void GLClientState::setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) {
169 m_currVaoState[location].size = size;
170 m_currVaoState[location].type = type;
171 m_currVaoState[location].normalized = normalized;
172 m_currVaoState[location].reloffset = reloffset;
173 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
174 switch (type) {
175 case GL_INT_2_10_10_10_REV:
176 case GL_UNSIGNED_INT_2_10_10_10_REV:
177 m_currVaoState[location].elementSize =
178 m_currVaoState[location].elementSize / 4;
179 break;
180 default:
181 break;
182 }
183 m_currVaoState[location].isInt = isInt;
184}
185
186void GLClientState::addVertexArrayObjects(GLsizei n, GLuint* arrays) {
187 for (GLsizei i = 0; i < n; i++) {
188 addVertexArrayObject(arrays[i]);
189 }
190}
191
192void GLClientState::removeVertexArrayObjects(GLsizei n, const GLuint* arrays) {
193 for (GLsizei i = 0; i < n; i++) {
194 if (arrays[i] && m_currVaoState.vaoId() == arrays[i]) {
195 setVertexArrayObject(0);
196 }
197 removeVertexArrayObject(arrays[i]);
198 }
199}
200
201void GLClientState::addVertexArrayObject(GLuint name) {
202 if (m_vaoMap.find(name) !=
203 m_vaoMap.end()) {
204 ALOGE("%s: ERROR: %u already part of current VAO state!",
205 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800206 return;
207 }
208
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800209 m_vaoMap.insert(
210 VAOStateMap::value_type(
211 name,
212 VAOState(0, m_nLocations, std::max(m_nLocations, m_max_vertex_attrib_bindings))));
213 VertexAttribStateVector& attribState =
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -0800214 m_vaoMap.find(name)->second.attribState;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800215 for (int i = 0; i < m_nLocations; i++) {
216 attribState[i].enabled = 0;
217 attribState[i].enableDirty = false;
218 attribState[i].data = 0;
219 attribState[i].reloffset = 0;
220 attribState[i].bindingindex = i;
221 attribState[i].divisor = 0;
222 attribState[i].size = 4; // 4 is the default size
223 attribState[i].type = GL_FLOAT; // GL_FLOAT is the default type
224 }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800225
226 VertexAttribBindingVector& bindingState =
227 m_vaoMap.find(name)->second.bindingState;
228 for (int i = 0; i < bindingState.size(); i++) {
229 bindingState[i].effectiveStride = 16;
230 }
keunyoungb85b2752013-03-08 12:28:03 -0800231}
232
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800233void GLClientState::removeVertexArrayObject(GLuint name) {
234 if (name == 0) {
235 ALOGE("%s: ERROR: cannot delete VAO 0!",
236 __FUNCTION__);
keunyoungb85b2752013-03-08 12:28:03 -0800237 return;
238 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800239 if (m_vaoMap.find(name) ==
240 m_vaoMap.end()) {
241 ALOGE("%s: ERROR: %u not found in VAO state!",
242 __FUNCTION__, name);
243 return;
244 }
245 m_vaoMap.erase(name);
keunyoungb85b2752013-03-08 12:28:03 -0800246}
247
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800248void GLClientState::setVertexArrayObject(GLuint name) {
249 if (m_vaoMap.find(name) ==
250 m_vaoMap.end()) {
251 ALOGE("%s: ERROR: %u not found in VAO state!",
252 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800253 return;
254 }
255
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800256 if (name && m_currVaoState.vaoId() == name) {
257 ALOGV("%s: set vao to self, no-op (%u)",
258 __FUNCTION__, name);
259 return;
keunyoungb85b2752013-03-08 12:28:03 -0800260 }
261
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800262 m_currVaoState =
263 VAOStateRef(m_vaoMap.find(name));
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -0800264 ALOGD("%s: set vao to %u (%u) %u %u", __FUNCTION__,
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800265 name,
266 m_currVaoState.vaoId(),
267 m_arrayBuffer,
268 m_currVaoState.iboId());
269}
270
271bool GLClientState::isVertexArrayObject(GLuint vao) const {
272 return m_vaoMap.find(vao) != m_vaoMap.end();
273}
274
275const GLClientState::VertexAttribState& GLClientState::getState(int location)
276{
277 return m_currVaoState[location];
278}
279
280const GLClientState::VertexAttribState& GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
281{
keunyoungb85b2752013-03-08 12:28:03 -0800282 if (enableChanged) {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800283 *enableChanged = m_currVaoState[location].enableDirty;
keunyoungb85b2752013-03-08 12:28:03 -0800284 }
285
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800286 m_currVaoState[location].enableDirty = false;
287 return m_currVaoState[location];
keunyoungb85b2752013-03-08 12:28:03 -0800288}
289
Lingfeng Yang554a5152019-02-21 20:20:48 -0800290void GLClientState::updateEnableDirtyArrayForDraw() {
291 bool enableChanged;
Lingfeng Yang6f0878f2019-02-27 17:27:32 -0800292 VAOState& vaoState = m_currVaoState.vaoState();
Lingfeng Yang554a5152019-02-21 20:20:48 -0800293
294 int k = 0;
295 for (int i = 0; i < CODEC_MAX_VERTEX_ATTRIBUTES; ++i) {
296 const VertexAttribState &state = getStateAndEnableDirty(i, &enableChanged);
297 if (enableChanged || state.enabled) {
298 vaoState.attributesNeedingUpdateForDraw[k] = i;
299 ++k;
300 }
301 }
302 vaoState.numAttributesNeedingUpdateForDraw = k;
303}
304
305GLClientState::VAOState& GLClientState::currentVaoState() {
306 return m_currVaoState.vaoState();
307}
308
keunyoungb85b2752013-03-08 12:28:03 -0800309int GLClientState::getLocation(GLenum loc)
310{
311 int retval;
312
313 switch(loc) {
314 case GL_VERTEX_ARRAY:
315 retval = int(VERTEX_LOCATION);
316 break;
317 case GL_NORMAL_ARRAY:
318 retval = int(NORMAL_LOCATION);
319 break;
320 case GL_COLOR_ARRAY:
321 retval = int(COLOR_LOCATION);
322 break;
323 case GL_POINT_SIZE_ARRAY_OES:
324 retval = int(POINTSIZE_LOCATION);
325 break;
326 case GL_TEXTURE_COORD_ARRAY:
327 retval = int (TEXCOORD0_LOCATION + m_activeTexture);
328 break;
329 case GL_MATRIX_INDEX_ARRAY_OES:
330 retval = int (MATRIXINDEX_LOCATION);
331 break;
332 case GL_WEIGHT_ARRAY_OES:
333 retval = int (WEIGHT_LOCATION);
334 break;
335 default:
336 retval = loc;
337 }
338 return retval;
339}
340
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800341static void sClearIndexedBufferBinding(GLuint id, std::vector<GLClientState::BufferBinding>& bindings) {
342 for (size_t i = 0; i < bindings.size(); i++) {
343 if (bindings[i].buffer == id) {
344 bindings[i].offset = 0;
345 bindings[i].stride = 0;
346 bindings[i].effectiveStride = 16;
347 bindings[i].size = 0;
348 bindings[i].buffer = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800349 }
350 }
351}
352
353void GLClientState::addBuffer(GLuint id) {
354 mBufferIds.insert(id);
355}
356
357void GLClientState::removeBuffer(GLuint id) {
358 mBufferIds.erase(id);
359}
360
361bool GLClientState::bufferIdExists(GLuint id) const {
362 return mBufferIds.find(id) != mBufferIds.end();
363}
364
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800365void GLClientState::unBindBuffer(GLuint id) {
Lingfeng Yang554a5152019-02-21 20:20:48 -0800366 if (m_arrayBuffer == id) {
367 m_arrayBuffer = 0;
368 m_arrayBuffer_lastEncode = 0;
369 }
370
371 if (m_currVaoState.iboId() == id) {
372 m_currVaoState.iboId() = 0;
373 m_currVaoState.iboIdLastEncode() = 0;
374 }
375
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800376 if (m_copyReadBuffer == id)
377 m_copyReadBuffer = 0;
378 if (m_copyWriteBuffer == id)
379 m_copyWriteBuffer = 0;
380 if (m_pixelPackBuffer == id)
381 m_pixelPackBuffer = 0;
382 if (m_pixelUnpackBuffer == id)
383 m_pixelUnpackBuffer = 0;
384 if (m_transformFeedbackBuffer == id)
385 m_transformFeedbackBuffer = 0;
386 if (m_uniformBuffer == id)
387 m_uniformBuffer = 0;
388 if (m_atomicCounterBuffer == id)
389 m_atomicCounterBuffer = 0;
390 if (m_dispatchIndirectBuffer == id)
391 m_dispatchIndirectBuffer = 0;
392 if (m_drawIndirectBuffer == id)
393 m_drawIndirectBuffer = 0;
394 if (m_shaderStorageBuffer == id)
395 m_shaderStorageBuffer = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800396
397 sClearIndexedBufferBinding(id, m_indexedTransformFeedbackBuffers);
398 sClearIndexedBufferBinding(id, m_indexedUniformBuffers);
399 sClearIndexedBufferBinding(id, m_indexedAtomicCounterBuffers);
400 sClearIndexedBufferBinding(id, m_indexedShaderStorageBuffers);
401 sClearIndexedBufferBinding(id, m_currVaoState.bufferBindings());
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800402}
403
404int GLClientState::bindBuffer(GLenum target, GLuint id)
405{
406 int err = 0;
407 switch(target) {
408 case GL_ARRAY_BUFFER:
409 m_arrayBuffer = id;
410 break;
411 case GL_ELEMENT_ARRAY_BUFFER:
412 m_currVaoState.iboId() = id;
413 break;
414 case GL_COPY_READ_BUFFER:
415 m_copyReadBuffer = id;
416 break;
417 case GL_COPY_WRITE_BUFFER:
418 m_copyWriteBuffer = id;
419 break;
420 case GL_PIXEL_PACK_BUFFER:
421 m_pixelPackBuffer = id;
422 break;
423 case GL_PIXEL_UNPACK_BUFFER:
424 m_pixelUnpackBuffer = id;
425 break;
426 case GL_TRANSFORM_FEEDBACK_BUFFER:
427 m_transformFeedbackBuffer = id;
428 break;
429 case GL_UNIFORM_BUFFER:
430 m_uniformBuffer = id;
431 break;
432 case GL_ATOMIC_COUNTER_BUFFER:
433 m_atomicCounterBuffer = id;
434 break;
435 case GL_DISPATCH_INDIRECT_BUFFER:
436 m_dispatchIndirectBuffer = id;
437 break;
438 case GL_DRAW_INDIRECT_BUFFER:
439 m_drawIndirectBuffer = id;
440 break;
441 case GL_SHADER_STORAGE_BUFFER:
442 m_shaderStorageBuffer = id;
443 break;
444 default:
445 err = -1;
446 }
447 return err;
448}
449
450void GLClientState::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) {
451 switch (target) {
452 case GL_TRANSFORM_FEEDBACK_BUFFER:
453 m_indexedTransformFeedbackBuffers[index].buffer = buffer;
454 m_indexedTransformFeedbackBuffers[index].offset = offset;
455 m_indexedTransformFeedbackBuffers[index].size = size;
456 m_indexedTransformFeedbackBuffers[index].stride = stride;
457 break;
458 case GL_UNIFORM_BUFFER:
459 m_indexedUniformBuffers[index].buffer = buffer;
460 m_indexedUniformBuffers[index].offset = offset;
461 m_indexedUniformBuffers[index].size = size;
462 m_indexedUniformBuffers[index].stride = stride;
463 break;
464 case GL_ATOMIC_COUNTER_BUFFER:
465 m_indexedAtomicCounterBuffers[index].buffer = buffer;
466 m_indexedAtomicCounterBuffers[index].offset = offset;
467 m_indexedAtomicCounterBuffers[index].size = size;
468 m_indexedAtomicCounterBuffers[index].stride = stride;
469 break;
470 case GL_SHADER_STORAGE_BUFFER:
471 m_indexedShaderStorageBuffers[index].buffer = buffer;
472 m_indexedShaderStorageBuffers[index].offset = offset;
473 m_indexedShaderStorageBuffers[index].size = size;
474 m_indexedShaderStorageBuffers[index].stride = stride;
475 break;
476 default:
477 m_currVaoState.bufferBinding(index).buffer = buffer;
478 m_currVaoState.bufferBinding(index).offset = offset;
479 m_currVaoState.bufferBinding(index).size = size;
480 m_currVaoState.bufferBinding(index).stride = stride;
481 m_currVaoState.bufferBinding(index).effectiveStride = effectiveStride;
482 return;
483 }
484}
485
486int GLClientState::getMaxIndexedBufferBindings(GLenum target) const {
487 switch (target) {
488 case GL_TRANSFORM_FEEDBACK_BUFFER:
489 return m_indexedTransformFeedbackBuffers.size();
490 case GL_UNIFORM_BUFFER:
491 return m_indexedUniformBuffers.size();
492 case GL_ATOMIC_COUNTER_BUFFER:
493 return m_indexedAtomicCounterBuffers.size();
494 case GL_SHADER_STORAGE_BUFFER:
495 return m_indexedShaderStorageBuffers.size();
496 default:
497 return m_currVaoState.bufferBindings_const().size();
498 }
499}
500
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -0800501bool GLClientState::isNonIndexedBindNoOp(GLenum target, GLuint buffer) {
502 if (buffer != !getLastEncodedBufferBind(target)) return false;
503
504 int idOrError = getBuffer(target);
505 if (idOrError < 0) {
506 return false;
507 } else {
508 return buffer == (GLuint)idOrError;
509 }
510}
511
Lingfeng Yang554a5152019-02-21 20:20:48 -0800512bool GLClientState::isIndexedBindNoOp(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) {
513
514 if (target == GL_TRANSFORM_FEEDBACK_BUFFER) return false;
515
516 if (buffer != getLastEncodedBufferBind(target)) return false;
517
518 switch (target) {
519 case GL_TRANSFORM_FEEDBACK_BUFFER:
520 return m_indexedTransformFeedbackBuffers[index].buffer == buffer &&
521 m_indexedTransformFeedbackBuffers[index].offset == offset &&
522 m_indexedTransformFeedbackBuffers[index].size == size &&
523 m_indexedTransformFeedbackBuffers[index].stride == stride;
524 case GL_UNIFORM_BUFFER:
525 return m_indexedUniformBuffers[index].buffer == buffer &&
526 m_indexedUniformBuffers[index].offset == offset &&
527 m_indexedUniformBuffers[index].size == size &&
528 m_indexedUniformBuffers[index].stride == stride;
529 case GL_ATOMIC_COUNTER_BUFFER:
530 return m_indexedAtomicCounterBuffers[index].buffer == buffer &&
531 m_indexedAtomicCounterBuffers[index].offset == offset &&
532 m_indexedAtomicCounterBuffers[index].size == size &&
533 m_indexedAtomicCounterBuffers[index].stride == stride;
534 case GL_SHADER_STORAGE_BUFFER:
535 return m_indexedShaderStorageBuffers[index].buffer == buffer &&
536 m_indexedShaderStorageBuffers[index].offset == offset &&
537 m_indexedShaderStorageBuffers[index].size == size &&
538 m_indexedShaderStorageBuffers[index].stride == stride;
539 default:
540 return m_currVaoState.bufferBinding(index).buffer == buffer &&
541 m_currVaoState.bufferBinding(index).offset == offset &&
542 m_currVaoState.bufferBinding(index).size == size &&
543 m_currVaoState.bufferBinding(index).stride == stride &&
544 m_currVaoState.bufferBinding(index).effectiveStride == effectiveStride;
545 }
546}
547
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800548int GLClientState::getBuffer(GLenum target) {
549 int ret=0;
550 switch (target) {
551 case GL_ARRAY_BUFFER:
552 ret = m_arrayBuffer;
553 break;
554 case GL_ELEMENT_ARRAY_BUFFER:
555 ret = m_currVaoState.iboId();
556 break;
557 case GL_COPY_READ_BUFFER:
558 ret = m_copyReadBuffer;
559 break;
560 case GL_COPY_WRITE_BUFFER:
561 ret = m_copyWriteBuffer;
562 break;
563 case GL_PIXEL_PACK_BUFFER:
564 ret = m_pixelPackBuffer;
565 break;
566 case GL_PIXEL_UNPACK_BUFFER:
567 ret = m_pixelUnpackBuffer;
568 break;
569 case GL_TRANSFORM_FEEDBACK_BUFFER:
570 ret = m_transformFeedbackBuffer;
571 break;
572 case GL_UNIFORM_BUFFER:
573 ret = m_uniformBuffer;
574 break;
575 case GL_ATOMIC_COUNTER_BUFFER:
576 ret = m_atomicCounterBuffer;
577 break;
578 case GL_DISPATCH_INDIRECT_BUFFER:
579 ret = m_dispatchIndirectBuffer;
580 break;
581 case GL_DRAW_INDIRECT_BUFFER:
582 ret = m_drawIndirectBuffer;
583 break;
584 case GL_SHADER_STORAGE_BUFFER:
585 ret = m_shaderStorageBuffer;
586 break;
587 default:
588 ret = -1;
589 }
590 return ret;
591}
592
Lingfeng Yang554a5152019-02-21 20:20:48 -0800593GLuint GLClientState::getLastEncodedBufferBind(GLenum target) {
594 GLuint ret;
595 switch (target)
596 {
597 case GL_ARRAY_BUFFER:
598 ret = m_arrayBuffer_lastEncode;
599 break;
600 case GL_ELEMENT_ARRAY_BUFFER:
601 ret = m_currVaoState.iboIdLastEncode();
602 break;
603 default:
604 {
605 int idOrError = getBuffer(target);
606 ret = (idOrError < 0) ? 0 : (GLuint)idOrError;
607 }
608 }
609
610 return ret;
611}
612
613void GLClientState::setLastEncodedBufferBind(GLenum target, GLuint id)
614{
615 switch (target)
616 {
617 case GL_ARRAY_BUFFER:
618 m_arrayBuffer_lastEncode = id;
619 break;
620 case GL_ELEMENT_ARRAY_BUFFER:
621 m_currVaoState.iboIdLastEncode() = id;
622 break;
623 default:
624 break;
625 }
626}
627
keunyoungb85b2752013-03-08 12:28:03 -0800628void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
629{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800630 GLenum which_state = -1;
keunyoungb85b2752013-03-08 12:28:03 -0800631 switch (pname) {
632 case GL_VERTEX_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800633 which_state = GLClientState::VERTEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800634 break;
635 }
636 case GL_NORMAL_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800637 which_state = GLClientState::NORMAL_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800638 break;
639 }
640 case GL_COLOR_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800641 which_state = GLClientState::COLOR_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800642 break;
643 }
644 case GL_TEXTURE_COORD_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800645 which_state = getActiveTexture() + GLClientState::TEXCOORD0_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800646 break;
647 }
648 case GL_POINT_SIZE_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800649 which_state = GLClientState::POINTSIZE_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800650 break;
651 }
652 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800653 which_state = GLClientState::MATRIXINDEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800654 break;
655 }
656 case GL_WEIGHT_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800657 which_state = GLClientState::WEIGHT_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800658 break;
659 }
660 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800661 if (which_state != -1)
662 *params = getState(which_state).data;
keunyoungb85b2752013-03-08 12:28:03 -0800663}
664
665int GLClientState::setPixelStore(GLenum param, GLint value)
666{
667 int retval = 0;
668 switch(param) {
669 case GL_UNPACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800670 m_pixelStore.unpack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800671 break;
672 case GL_PACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800673 m_pixelStore.pack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800674 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800675 case GL_UNPACK_ROW_LENGTH:
676 m_pixelStore.unpack_row_length = value;
677 break;
678 case GL_UNPACK_IMAGE_HEIGHT:
679 m_pixelStore.unpack_image_height = value;
680 break;
681 case GL_UNPACK_SKIP_PIXELS:
682 m_pixelStore.unpack_skip_pixels = value;
683 break;
684 case GL_UNPACK_SKIP_ROWS:
685 m_pixelStore.unpack_skip_rows = value;
686 break;
687 case GL_UNPACK_SKIP_IMAGES:
688 m_pixelStore.unpack_skip_images = value;
689 break;
690 case GL_PACK_ROW_LENGTH:
691 m_pixelStore.pack_row_length = value;
692 break;
693 case GL_PACK_SKIP_PIXELS:
694 m_pixelStore.pack_skip_pixels = value;
695 break;
696 case GL_PACK_SKIP_ROWS:
697 m_pixelStore.pack_skip_rows = value;
698 break;
699 default:
700 retval = GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800701 }
702 return retval;
703}
704
705
Lingfeng Yang74e29292017-01-10 14:54:38 -0800706size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
keunyoungb85b2752013-03-08 12:28:03 -0800707{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800708 if (width <= 0 || height <= 0 || depth <= 0) return 0;
bohubd119bf2014-10-17 13:48:06 -0700709
Lingfeng Yang74e29292017-01-10 14:54:38 -0800710 ALOGV("%s: pack? %d", __FUNCTION__, pack);
711 if (pack) {
712 ALOGV("%s: pack stats", __FUNCTION__);
713 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
714 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
715 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
716 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
717 } else {
718 ALOGV("%s: unpack stats", __FUNCTION__);
719 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
720 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
721 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
722 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
723 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
724 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800725 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800726 return GLESTextureUtils::computeTotalImageSize(
727 width, height, depth,
728 format, type,
729 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
730 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
731 pack ? 0 : m_pixelStore.unpack_image_height,
732 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
733 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
734 pack ? 0 : m_pixelStore.unpack_skip_images);
735}
736
737size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
738{
739 if (width <= 0 || height <= 0 || depth <= 0) return 0;
740
741 ALOGV("%s: pack? %d", __FUNCTION__, pack);
742 if (pack) {
743 ALOGV("%s: pack stats", __FUNCTION__);
744 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
745 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
746 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
747 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
748 } else {
749 ALOGV("%s: unpack stats", __FUNCTION__);
750 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
751 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
752 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
753 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
754 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
755 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800756 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800757 return GLESTextureUtils::computeNeededBufferSize(
758 width, height, depth,
759 format, type,
760 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
761 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
762 pack ? 0 : m_pixelStore.unpack_image_height,
763 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
764 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
765 pack ? 0 : m_pixelStore.unpack_skip_images);
766}
767
768
769size_t GLClientState::clearBufferNumElts(GLenum buffer) const
770{
771 switch (buffer) {
772 case GL_COLOR:
773 return 4;
774 case GL_DEPTH:
775 case GL_STENCIL:
776 return 1;
777 }
778 return 1;
779}
780
Lingfeng Yang22dc42d2018-05-29 10:11:38 -0700781void GLClientState::getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const
782{
783 if (width <= 0 || height <= 0) {
784 *startOffset = 0;
785 *pixelRowSize = 0;
786 *totalRowSize = 0;
787 return;
788 }
789
790 GLESTextureUtils::computePackingOffsets2D(
791 width, height,
792 format, type,
793 m_pixelStore.pack_alignment,
794 m_pixelStore.pack_row_length,
795 m_pixelStore.pack_skip_pixels,
796 m_pixelStore.pack_skip_rows,
797 startOffset,
798 pixelRowSize,
799 totalRowSize);
800
801 *skipRows = m_pixelStore.pack_skip_rows;
802}
803
Lingfeng Yang74e29292017-01-10 14:54:38 -0800804void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) {
805 UniformBlockInfoKey key;
806 key.program = program;
807 key.uniformBlockIndex = uniformBlockIndex;
808
809 UniformBlockUniformInfo info;
810 info.numActiveUniforms = (size_t)numActiveUniforms;
811
812 m_uniformBlockInfoMap[key] = info;
813}
814
815size_t GLClientState::numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const {
816 UniformBlockInfoKey key;
817 key.program = program;
818 key.uniformBlockIndex = uniformBlockIndex;
819 UniformBlockInfoMap::const_iterator it =
820 m_uniformBlockInfoMap.find(key);
821 if (it == m_uniformBlockInfoMap.end()) return 0;
822 return it->second.numActiveUniforms;
823}
824
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800825void GLClientState::associateProgramWithPipeline(GLuint program, GLuint pipeline) {
826 m_programPipelines[program] = pipeline;
827}
828
829GLClientState::ProgramPipelineIterator GLClientState::programPipelineBegin() {
830 return m_programPipelines.begin();
831}
832
833GLClientState::ProgramPipelineIterator GLClientState::programPipelineEnd() {
834 return m_programPipelines.end();
keunyoungb85b2752013-03-08 12:28:03 -0800835}
836
837GLenum GLClientState::setActiveTextureUnit(GLenum texture)
838{
839 GLuint unit = texture - GL_TEXTURE0;
840 if (unit >= MAX_TEXTURE_UNITS) {
Yahan Zhoudb856572016-03-01 12:03:48 -0800841 return GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800842 }
843 m_tex.activeUnit = &m_tex.unit[unit];
844 return GL_NO_ERROR;
845}
846
847GLenum GLClientState::getActiveTextureUnit() const
848{
849 return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
850}
851
852void GLClientState::enableTextureTarget(GLenum target)
853{
854 switch (target) {
855 case GL_TEXTURE_2D:
856 m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
857 break;
858 case GL_TEXTURE_EXTERNAL_OES:
859 m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
860 break;
861 }
862}
863
864void GLClientState::disableTextureTarget(GLenum target)
865{
866 switch (target) {
867 case GL_TEXTURE_2D:
868 m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
869 break;
870 case GL_TEXTURE_EXTERNAL_OES:
871 m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
872 break;
873 }
874}
875
Lingfeng Yang554a5152019-02-21 20:20:48 -0800876void GLClientState::bindSampler(GLuint unit, GLuint sampler) {
877 m_tex.unit[unit].boundSampler = sampler;
878}
879
880bool GLClientState::isSamplerBindNoOp(GLuint unit, GLuint sampler) {
881 return m_tex.unit[unit].boundSampler == sampler;
882}
883
884void GLClientState::onDeleteSamplers(GLsizei n, const GLuint* samplers) {
885 for (uint32_t i = 0; i < n; ++i) {
886 for (uint32_t j = 0; j < MAX_TEXTURE_UNITS; ++j) {
887 uint32_t currentSampler = m_tex.unit[j].boundSampler;
888 if (currentSampler == samplers[i]) {
889 m_tex.unit[j].boundSampler = 0;
890 }
891 }
892 }
893}
894
keunyoungb85b2752013-03-08 12:28:03 -0800895GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
896{
897 unsigned int enables = m_tex.activeUnit->enables;
898 if (enables & (1u << TEXTURE_EXTERNAL)) {
899 return GL_TEXTURE_EXTERNAL_OES;
900 } else if (enables & (1u << TEXTURE_2D)) {
901 return GL_TEXTURE_2D;
902 } else {
903 return allDisabled;
904 }
905}
906
907int GLClientState::compareTexId(const void* pid, const void* prec)
908{
909 const GLuint* id = (const GLuint*)pid;
910 const TextureRec* rec = (const TextureRec*)prec;
911 return (GLint)(*id) - (GLint)rec->id;
912}
913
914GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
915 GLboolean* firstUse)
916{
917 GLboolean first = GL_FALSE;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800918
919 TextureRec* texrec = getTextureRec(texture);
920 if (!texrec) {
921 texrec = addTextureRec(texture, target);
922 }
923
924 if (texture && target != texrec->target &&
925 (target != GL_TEXTURE_EXTERNAL_OES &&
926 texrec->target != GL_TEXTURE_EXTERNAL_OES)) {
927 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 -0800928 }
929
930 switch (target) {
931 case GL_TEXTURE_2D:
932 m_tex.activeUnit->texture[TEXTURE_2D] = texture;
933 break;
934 case GL_TEXTURE_EXTERNAL_OES:
935 m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
936 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800937 case GL_TEXTURE_CUBE_MAP:
938 m_tex.activeUnit->texture[TEXTURE_CUBE_MAP] = texture;
939 break;
940 case GL_TEXTURE_2D_ARRAY:
941 m_tex.activeUnit->texture[TEXTURE_2D_ARRAY] = texture;
942 break;
943 case GL_TEXTURE_3D:
944 m_tex.activeUnit->texture[TEXTURE_3D] = texture;
945 break;
946 case GL_TEXTURE_2D_MULTISAMPLE:
947 m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE] = texture;
948 break;
keunyoungb85b2752013-03-08 12:28:03 -0800949 }
950
951 if (firstUse) {
952 *firstUse = first;
953 }
954
955 return GL_NO_ERROR;
956}
957
Lingfeng Yang74e29292017-01-10 14:54:38 -0800958void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) {
959 GLuint texture = getBoundTexture(target);
960 TextureRec* texrec = getTextureRec(texture);
961 if (!texrec) return;
962 texrec->boundEGLImage = true;
963}
964
965TextureRec* GLClientState::addTextureRec(GLuint id, GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -0800966{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800967 TextureRec* tex = new TextureRec;
keunyoungb85b2752013-03-08 12:28:03 -0800968 tex->id = id;
969 tex->target = target;
Lingfeng Yang69066602016-04-12 09:29:11 -0700970 tex->format = -1;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800971 tex->multisamples = 0;
972 tex->immutable = false;
973 tex->boundEGLImage = false;
974 tex->dims = new TextureDims;
keunyoungb85b2752013-03-08 12:28:03 -0800975
Lingfeng Yang74e29292017-01-10 14:54:38 -0800976 (*(m_tex.textureRecs))[id] = tex;
keunyoungb85b2752013-03-08 12:28:03 -0800977 return tex;
978}
979
Lingfeng Yang74e29292017-01-10 14:54:38 -0800980TextureRec* GLClientState::getTextureRec(GLuint id) const {
981 SharedTextureDataMap::const_iterator it =
982 m_tex.textureRecs->find(id);
983 if (it == m_tex.textureRecs->end()) {
984 return NULL;
985 }
986 return it->second;
987}
988
Lingfeng Yang69066602016-04-12 09:29:11 -0700989void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
990 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800991 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700992 if (!texrec) return;
993 texrec->internalformat = internalformat;
994}
995
996void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) {
997 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -0800998 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -0700999 if (!texrec) return;
1000 texrec->format = format;
1001}
1002
1003void GLClientState::setBoundTextureType(GLenum target, GLenum type) {
1004 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -08001005 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001006 if (!texrec) return;
1007 texrec->type = type;
1008}
1009
Lingfeng Yang74e29292017-01-10 14:54:38 -08001010void GLClientState::setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) {
1011 GLuint texture = getBoundTexture(target);
1012 TextureRec* texrec = getTextureRec(texture);
1013 if (!texrec) {
1014 return;
1015 }
1016
1017 if (level == -1) {
1018 GLsizei curr_width = width;
1019 GLsizei curr_height = height;
1020 GLsizei curr_depth = depth;
1021 GLsizei curr_level = 0;
1022
1023 while (true) {
1024 texrec->dims->widths[curr_level] = curr_width;
1025 texrec->dims->heights[curr_level] = curr_height;
1026 texrec->dims->depths[curr_level] = curr_depth;
1027 if (curr_width >> 1 == 0 &&
1028 curr_height >> 1 == 0 &&
1029 ((target == GL_TEXTURE_3D && curr_depth == 0) ||
1030 true)) {
1031 break;
1032 }
1033 curr_width = (curr_width >> 1) ? (curr_width >> 1) : 1;
1034 curr_height = (curr_height >> 1) ? (curr_height >> 1) : 1;
1035 if (target == GL_TEXTURE_3D) {
1036 curr_depth = (curr_depth >> 1) ? (curr_depth >> 1) : 1;
1037 }
1038 curr_level++;
1039 }
1040
1041 } else {
1042 texrec->dims->widths[level] = width;
1043 texrec->dims->heights[level] = height;
1044 texrec->dims->depths[level] = depth;
1045 }
1046}
1047
1048void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) {
1049 GLuint texture = getBoundTexture(target);
1050 TextureRec* texrec = getTextureRec(texture);
1051 if (!texrec) return;
1052 texrec->multisamples = samples;
1053}
1054
1055void GLClientState::setBoundTextureImmutableFormat(GLenum target) {
1056 GLuint texture = getBoundTexture(target);
1057 TextureRec* texrec = getTextureRec(texture);
1058 if (!texrec) return;
1059 texrec->immutable = true;
1060}
1061
1062bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const {
1063 GLuint texture = getBoundTexture(target);
1064 TextureRec* texrec = getTextureRec(texture);
1065 if (!texrec) return false;
1066 return texrec->immutable;
1067}
1068
keunyoungb85b2752013-03-08 12:28:03 -08001069GLuint GLClientState::getBoundTexture(GLenum target) const
1070{
1071 switch (target) {
1072 case GL_TEXTURE_2D:
1073 return m_tex.activeUnit->texture[TEXTURE_2D];
1074 case GL_TEXTURE_EXTERNAL_OES:
1075 return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
Lingfeng Yang74e29292017-01-10 14:54:38 -08001076 case GL_TEXTURE_CUBE_MAP:
1077 return m_tex.activeUnit->texture[TEXTURE_CUBE_MAP];
1078 case GL_TEXTURE_2D_ARRAY:
1079 return m_tex.activeUnit->texture[TEXTURE_2D_ARRAY];
1080 case GL_TEXTURE_3D:
1081 return m_tex.activeUnit->texture[TEXTURE_3D];
1082 case GL_TEXTURE_2D_MULTISAMPLE:
1083 return m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE];
keunyoungb85b2752013-03-08 12:28:03 -08001084 default:
1085 return 0;
1086 }
1087}
1088
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07001089// BEGIN driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1090// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
1091
1092static bool unreliableInternalFormat(GLenum internalformat) {
1093 switch (internalformat) {
1094 case GL_LUMINANCE:
1095 return true;
1096 default:
1097 return false;
1098 }
1099}
1100
1101void GLClientState::writeCopyTexImageState
1102 (GLenum target, GLint level, GLenum internalformat) {
1103 if (unreliableInternalFormat(internalformat)) {
1104 CubeMapDef entry;
1105 entry.id = getBoundTexture(GL_TEXTURE_2D);
1106 entry.target = target;
1107 entry.level = level;
1108 entry.internalformat = internalformat;
1109 m_cubeMapDefs.insert(entry);
1110 }
1111}
1112
1113static GLenum identifyPositiveCubeMapComponent(GLenum target) {
1114 switch (target) {
1115 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1116 return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1117 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1118 return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
1119 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1120 return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
1121 default:
1122 return 0;
1123 }
1124}
1125
1126GLenum GLClientState::copyTexImageNeededTarget
1127 (GLenum target, GLint level, GLenum internalformat) {
1128 if (unreliableInternalFormat(internalformat)) {
1129 GLenum positiveComponent =
1130 identifyPositiveCubeMapComponent(target);
1131 if (positiveComponent) {
1132 CubeMapDef query;
1133 query.id = getBoundTexture(GL_TEXTURE_2D);
1134 query.target = positiveComponent;
1135 query.level = level;
1136 query.internalformat = internalformat;
1137 if (m_cubeMapDefs.find(query) ==
1138 m_cubeMapDefs.end()) {
1139 return positiveComponent;
1140 }
1141 }
1142 }
1143 return 0;
1144}
1145
1146GLenum GLClientState::copyTexImageLuminanceCubeMapAMDWorkaround
1147 (GLenum target, GLint level, GLenum internalformat) {
1148 writeCopyTexImageState(target, level, internalformat);
1149 return copyTexImageNeededTarget(target, level, internalformat);
1150}
1151
1152// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
1153// END driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1154
keunyoungb85b2752013-03-08 12:28:03 -08001155void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
1156{
1157 // Updating the textures array could be made more efficient when deleting
1158 // several textures:
1159 // - compacting the array could be done in a single pass once the deleted
1160 // textures are marked, or
1161 // - could swap deleted textures to the end and re-sort.
1162 TextureRec* texrec;
1163 for (const GLuint* texture = textures; texture != textures + n; texture++) {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001164 texrec = getTextureRec(*texture);
1165 if (texrec && texrec->dims) {
1166 delete texrec->dims;
1167 }
keunyoungb85b2752013-03-08 12:28:03 -08001168 if (texrec) {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001169 m_tex.textureRecs->erase(*texture);
1170 delete texrec;
keunyoungb85b2752013-03-08 12:28:03 -08001171 for (TextureUnit* unit = m_tex.unit;
1172 unit != m_tex.unit + MAX_TEXTURE_UNITS;
1173 unit++)
1174 {
1175 if (unit->texture[TEXTURE_2D] == *texture) {
1176 unit->texture[TEXTURE_2D] = 0;
1177 } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
1178 unit->texture[TEXTURE_EXTERNAL] = 0;
1179 }
1180 }
1181 }
1182 }
1183}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001184
1185// RBO//////////////////////////////////////////////////////////////////////////
1186
1187void GLClientState::addFreshRenderbuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001188 // if underlying opengl says these are fresh names,
1189 // but we are keeping a stale one, reset it.
1190 RboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001191 props.target = GL_RENDERBUFFER;
1192 props.name = name;
Lingfeng Yang69066602016-04-12 09:29:11 -07001193 props.format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001194 props.multisamples = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001195 props.previouslyBound = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001196
1197 if (usedRenderbufferName(name)) {
1198 mRboState.rboData[getRboIndex(name)] = props;
1199 } else {
1200 mRboState.rboData.push_back(props);
1201 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001202}
1203
1204void GLClientState::addRenderbuffers(GLsizei n, GLuint* renderbuffers) {
1205 for (size_t i = 0; i < n; i++) {
1206 addFreshRenderbuffer(renderbuffers[i]);
1207 }
1208}
1209
1210size_t GLClientState::getRboIndex(GLuint name) const {
1211 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1212 if (mRboState.rboData[i].name == name) {
1213 return i;
1214 }
1215 }
1216 return -1;
1217}
1218
1219void GLClientState::removeRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
1220 size_t bound_rbo_idx = getRboIndex(boundRboProps_const().name);
1221
1222 std::vector<GLuint> to_remove;
1223 for (size_t i = 0; i < n; i++) {
1224 if (renderbuffers[i] != 0) { // Never remove the zero rb.
1225 to_remove.push_back(getRboIndex(renderbuffers[i]));
1226 }
1227 }
1228
1229 for (size_t i = 0; i < to_remove.size(); i++) {
1230 mRboState.rboData[to_remove[i]] = mRboState.rboData.back();
1231 mRboState.rboData.pop_back();
1232 }
1233
1234 // If we just deleted the currently bound rb,
1235 // bind the zero rb
1236 if (getRboIndex(boundRboProps_const().name) != bound_rbo_idx) {
1237 bindRenderbuffer(GL_RENDERBUFFER, 0);
1238 }
1239}
1240
1241bool GLClientState::usedRenderbufferName(GLuint name) const {
1242 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1243 if (mRboState.rboData[i].name == name) {
1244 return true;
1245 }
1246 }
1247 return false;
1248}
1249
1250void GLClientState::setBoundRenderbufferIndex() {
1251 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1252 if (mRboState.rboData[i].name == mRboState.boundRenderbuffer) {
1253 mRboState.boundRenderbufferIndex = i;
1254 break;
1255 }
1256 }
1257}
1258
1259RboProps& GLClientState::boundRboProps() {
1260 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1261}
1262
1263const RboProps& GLClientState::boundRboProps_const() const {
1264 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1265}
1266
1267void GLClientState::bindRenderbuffer(GLenum target, GLuint name) {
1268 // If unused, add it.
1269 if (!usedRenderbufferName(name)) {
1270 addFreshRenderbuffer(name);
1271 }
1272 mRboState.boundRenderbuffer = name;
1273 setBoundRenderbufferIndex();
1274 boundRboProps().target = target;
1275 boundRboProps().previouslyBound = true;
1276}
1277
1278GLuint GLClientState::boundRenderbuffer() const {
1279 return boundRboProps_const().name;
1280}
1281
Lingfeng Yang69066602016-04-12 09:29:11 -07001282void GLClientState::setBoundRenderbufferFormat(GLenum format) {
1283 boundRboProps().format = format;
1284}
1285
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001286void GLClientState::setBoundRenderbufferSamples(GLsizei samples) {
1287 boundRboProps().multisamples = samples;
1288}
1289
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001290// FBO//////////////////////////////////////////////////////////////////////////
1291
Lingfeng Yang69066602016-04-12 09:29:11 -07001292// Format querying
1293
1294GLenum GLClientState::queryRboFormat(GLuint rbo_name) const {
1295 return mRboState.rboData[getRboIndex(rbo_name)].format;
1296}
1297
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001298GLsizei GLClientState::queryRboSamples(GLuint rbo_name) const {
1299 return mRboState.rboData[getRboIndex(rbo_name)].multisamples;
1300}
1301
Lingfeng Yang69066602016-04-12 09:29:11 -07001302GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001303 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001304 if (!texrec) return -1;
1305 return texrec->internalformat;
1306}
1307
Lingfeng Yang74e29292017-01-10 14:54:38 -08001308GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const {
1309 TextureRec* texrec = getTextureRec(tex_name);
1310 if (!texrec) {
1311 return 0;
1312 }
1313 return texrec->dims->widths[level];
1314}
1315
1316GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const {
1317 TextureRec* texrec = getTextureRec(tex_name);
1318 if (!texrec) return 0;
1319 return texrec->dims->heights[level];
1320}
1321
1322GLsizei GLClientState::queryTexDepth(GLsizei level, GLuint tex_name) const {
1323 TextureRec* texrec = getTextureRec(tex_name);
1324 if (!texrec) return 0;
1325 return texrec->dims->depths[level];
1326}
1327
1328bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const {
1329 TextureRec* texrec = getTextureRec(tex_name);
1330 if (!texrec) return false;
1331 return texrec->boundEGLImage;
1332}
1333
Lingfeng Yang69066602016-04-12 09:29:11 -07001334GLenum GLClientState::queryTexFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001335 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001336 if (!texrec) return -1;
1337 return texrec->format;
1338}
1339
1340GLenum GLClientState::queryTexType(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001341 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001342 if (!texrec) return -1;
1343 return texrec->type;
1344}
1345
Lingfeng Yang74e29292017-01-10 14:54:38 -08001346GLsizei GLClientState::queryTexSamples(GLuint tex_name) const {
1347 TextureRec* texrec = getTextureRec(tex_name);
1348 if (!texrec) return 0;
1349 return texrec->multisamples;
1350}
1351
1352GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const {
1353 TextureRec* texrec = getTextureRec(tex_name);
1354 if (!texrec) return GL_NONE;
1355 return texrec->target;
1356}
1357
Lingfeng Yang69066602016-04-12 09:29:11 -07001358void GLClientState::getBoundFramebufferFormat(
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001359 GLenum target,
Lingfeng Yang69066602016-04-12 09:29:11 -07001360 GLenum attachment, FboFormatInfo* res_info) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001361 const FboProps& props = boundFboProps_const(target);
Lingfeng Yang69066602016-04-12 09:29:11 -07001362
1363 res_info->type = FBO_ATTACHMENT_NONE;
1364 res_info->rb_format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001365 res_info->rb_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001366 res_info->tex_internalformat = -1;
1367 res_info->tex_format = GL_NONE;
1368 res_info->tex_type = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001369 res_info->tex_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001370
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001371 int colorAttachmentIndex =
1372 glUtilsColorAttachmentIndex(attachment);
1373
1374 if (colorAttachmentIndex != -1) {
1375 if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001376 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001377 res_info->rb_format =
1378 queryRboFormat(
1379 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1380 res_info->rb_multisamples =
1381 queryRboSamples(
1382 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1383 } else if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001384 res_info->type = FBO_ATTACHMENT_TEXTURE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001385 res_info->tex_internalformat =
1386 queryTexInternalFormat(
1387 props.colorAttachmenti_textures[colorAttachmentIndex]);
1388 res_info->tex_format =
1389 queryTexFormat(
1390 props.colorAttachmenti_textures[colorAttachmentIndex]);
1391 res_info->tex_type =
1392 queryTexType(props.colorAttachmenti_textures[colorAttachmentIndex]);
1393 res_info->tex_multisamples =
1394 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001395 } else {
1396 res_info->type = FBO_ATTACHMENT_NONE;
1397 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001398 }
1399
1400 switch (attachment) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001401 case GL_DEPTH_ATTACHMENT:
1402 if (props.depthAttachment_hasRbo) {
1403 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1404 res_info->rb_format = queryRboFormat(props.depthAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001405 res_info->rb_multisamples =
1406 queryRboSamples(
Lingfeng Yang400bc512018-10-12 12:39:17 -07001407 props.depthAttachment_rbo);
Lingfeng Yang69066602016-04-12 09:29:11 -07001408 } else if (props.depthAttachment_hasTexObj) {
1409 res_info->type = FBO_ATTACHMENT_TEXTURE;
1410 res_info->tex_internalformat = queryTexInternalFormat(props.depthAttachment_texture);
1411 res_info->tex_format = queryTexFormat(props.depthAttachment_texture);
1412 res_info->tex_type = queryTexType(props.depthAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001413 res_info->tex_multisamples =
Lingfeng Yang400bc512018-10-12 12:39:17 -07001414 queryTexSamples(props.depthAttachment_texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001415 } else {
1416 res_info->type = FBO_ATTACHMENT_NONE;
1417 }
1418 break;
1419 case GL_STENCIL_ATTACHMENT:
1420 if (props.stencilAttachment_hasRbo) {
1421 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1422 res_info->rb_format = queryRboFormat(props.stencilAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001423 res_info->rb_multisamples =
1424 queryRboSamples(
Lingfeng Yang400bc512018-10-12 12:39:17 -07001425 props.stencilAttachment_rbo);
Lingfeng Yang69066602016-04-12 09:29:11 -07001426 } else if (props.stencilAttachment_hasTexObj) {
1427 res_info->type = FBO_ATTACHMENT_TEXTURE;
1428 res_info->tex_internalformat = queryTexInternalFormat(props.stencilAttachment_texture);
1429 res_info->tex_format = queryTexFormat(props.stencilAttachment_texture);
1430 res_info->tex_type = queryTexType(props.stencilAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001431 res_info->tex_multisamples =
Lingfeng Yang400bc512018-10-12 12:39:17 -07001432 queryTexSamples(props.stencilAttachment_texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001433 } else {
1434 res_info->type = FBO_ATTACHMENT_NONE;
1435 }
1436 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001437 case GL_DEPTH_STENCIL_ATTACHMENT:
1438 if (props.depthstencilAttachment_hasRbo) {
1439 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1440 res_info->rb_format = queryRboFormat(props.depthstencilAttachment_rbo);
1441 res_info->rb_multisamples =
1442 queryRboSamples(
Lingfeng Yang400bc512018-10-12 12:39:17 -07001443 props.depthstencilAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001444 } else if (props.depthstencilAttachment_hasTexObj) {
1445 res_info->type = FBO_ATTACHMENT_TEXTURE;
1446 res_info->tex_internalformat = queryTexInternalFormat(props.depthstencilAttachment_texture);
1447 res_info->tex_format = queryTexFormat(props.depthstencilAttachment_texture);
1448 res_info->tex_type = queryTexType(props.depthstencilAttachment_texture);
1449 res_info->tex_multisamples =
Lingfeng Yang400bc512018-10-12 12:39:17 -07001450 queryTexSamples(props.depthstencilAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001451 } else {
1452 res_info->type = FBO_ATTACHMENT_NONE;
1453 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001454 break;
1455 }
1456}
1457
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001458FboAttachmentType GLClientState::getBoundFramebufferAttachmentType(GLenum target, GLenum attachment) const {
1459 FboFormatInfo info;
1460 getBoundFramebufferFormat(target, attachment, &info);
1461 return info.type;
1462}
1463
1464
1465int GLClientState::getMaxColorAttachments() const {
1466 return m_max_color_attachments;
1467}
1468
1469int GLClientState::getMaxDrawBuffers() const {
1470 return m_max_draw_buffers;
1471}
1472
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001473void GLClientState::addFreshFramebuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001474 FboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001475 props.name = name;
1476 props.previouslyBound = false;
1477
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001478 props.colorAttachmenti_textures.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001479 props.depthAttachment_texture = 0;
1480 props.stencilAttachment_texture = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001481 props.depthstencilAttachment_texture = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001482
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001483 props.colorAttachmenti_hasTex.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001484 props.depthAttachment_hasTexObj = false;
1485 props.stencilAttachment_hasTexObj = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001486 props.depthstencilAttachment_hasTexObj = false;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001487
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001488 props.colorAttachmenti_rbos.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001489 props.depthAttachment_rbo = 0;
1490 props.stencilAttachment_rbo = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001491 props.depthstencilAttachment_rbo = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001492
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001493 props.colorAttachmenti_hasRbo.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001494 props.depthAttachment_hasRbo = false;
1495 props.stencilAttachment_hasRbo = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001496 props.depthstencilAttachment_hasRbo = false;
1497 mFboState.fboData[name] = props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001498}
1499
1500void GLClientState::addFramebuffers(GLsizei n, GLuint* framebuffers) {
1501 for (size_t i = 0; i < n; i++) {
1502 addFreshFramebuffer(framebuffers[i]);
1503 }
1504}
1505
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001506void GLClientState::removeFramebuffers(GLsizei n, const GLuint* framebuffers) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001507 for (size_t i = 0; i < n; i++) {
1508 if (framebuffers[i] != 0) { // Never remove the zero fb.
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001509 if (framebuffers[i] == mFboState.boundDrawFramebuffer) {
1510 bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1511 }
1512 if (framebuffers[i] == mFboState.boundReadFramebuffer) {
1513 bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1514 }
1515 mFboState.fboData.erase(framebuffers[i]);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001516 }
1517 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001518}
1519
1520bool GLClientState::usedFramebufferName(GLuint name) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001521 return mFboState.fboData.find(name) != mFboState.fboData.end();
1522}
1523
1524FboProps& GLClientState::boundFboProps(GLenum target) {
1525 switch (target) {
1526 case GL_DRAW_FRAMEBUFFER:
1527 return mFboState.fboData[mFboState.boundDrawFramebuffer];
1528 case GL_READ_FRAMEBUFFER:
1529 return mFboState.fboData[mFboState.boundReadFramebuffer];
1530 case GL_FRAMEBUFFER:
1531 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001532 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001533 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001534}
1535
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001536const FboProps& GLClientState::boundFboProps_const(GLenum target) const {
1537 switch (target) {
1538 case GL_DRAW_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001539 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001540 case GL_READ_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001541 return mFboState.fboData.find(mFboState.boundReadFramebuffer)->second;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001542 case GL_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001543 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001544 }
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001545 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001546}
1547
1548void GLClientState::bindFramebuffer(GLenum target, GLuint name) {
1549 // If unused, add it.
1550 if (!usedFramebufferName(name)) {
1551 addFreshFramebuffer(name);
1552 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001553 switch (target) {
1554 case GL_DRAW_FRAMEBUFFER:
1555 mFboState.boundDrawFramebuffer = name;
1556 break;
1557 case GL_READ_FRAMEBUFFER:
1558 mFboState.boundReadFramebuffer = name;
1559 break;
1560 default: // case GL_FRAMEBUFFER:
1561 mFboState.boundDrawFramebuffer = name;
1562 mFboState.boundReadFramebuffer = name;
1563 break;
1564 }
1565 boundFboProps(target).previouslyBound = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001566}
1567
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001568void GLClientState::setCheckFramebufferStatus(GLenum target, GLenum status) {
1569 switch (target) {
1570 case GL_DRAW_FRAMEBUFFER:
1571 mFboState.drawFboCheckStatus = status;
1572 break;
1573 case GL_READ_FRAMEBUFFER:
1574 mFboState.readFboCheckStatus = status;
1575 break;
1576 case GL_FRAMEBUFFER:
1577 mFboState.drawFboCheckStatus = status;
1578 break;
1579 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001580}
1581
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001582GLenum GLClientState::getCheckFramebufferStatus(GLenum target) const {
1583 switch (target) {
1584 case GL_DRAW_FRAMEBUFFER:
1585 return mFboState.drawFboCheckStatus;
1586 case GL_READ_FRAMEBUFFER:
1587 return mFboState.readFboCheckStatus;
1588 case GL_FRAMEBUFFER:
1589 return mFboState.drawFboCheckStatus;
1590 }
1591 return mFboState.drawFboCheckStatus;
Lingfeng Yang69066602016-04-12 09:29:11 -07001592}
1593
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001594GLuint GLClientState::boundFramebuffer(GLenum target) const {
1595 return boundFboProps_const(target).name;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001596}
1597
1598// Texture objects for FBOs/////////////////////////////////////////////////////
1599
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001600void GLClientState::attachTextureObject(
1601 GLenum target,
1602 GLenum attachment, GLuint texture) {
1603
1604 int colorAttachmentIndex =
1605 glUtilsColorAttachmentIndex(attachment);
1606
1607 if (colorAttachmentIndex != -1) {
1608 boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texture;
1609 boundFboProps(target).colorAttachmenti_hasTex[colorAttachmentIndex] = true;
1610 }
1611
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001612 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001613 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001614 boundFboProps(target).depthAttachment_texture = texture;
1615 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001616 break;
1617 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001618 boundFboProps(target).stencilAttachment_texture = texture;
1619 boundFboProps(target).stencilAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001620 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001621 case GL_DEPTH_STENCIL_ATTACHMENT:
1622 boundFboProps(target).depthstencilAttachment_texture = texture;
1623 boundFboProps(target).depthstencilAttachment_hasTexObj = true;
1624 boundFboProps(target).stencilAttachment_texture = texture;
1625 boundFboProps(target).stencilAttachment_hasTexObj = true;
1626 boundFboProps(target).depthAttachment_texture = texture;
1627 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001628 break;
1629 }
1630}
1631
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001632GLuint GLClientState::getFboAttachmentTextureId(GLenum target, GLenum attachment) const {
1633 GLuint res = 0; // conservative
1634
1635 int colorAttachmentIndex =
1636 glUtilsColorAttachmentIndex(attachment);
1637
1638 if (colorAttachmentIndex != -1) {
1639 res = boundFboProps_const(target).colorAttachmenti_textures[colorAttachmentIndex];
1640 }
1641
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001642 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001643 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001644 res = boundFboProps_const(target).depthAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001645 break;
1646 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001647 res = boundFboProps_const(target).stencilAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001648 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001649 case GL_DEPTH_STENCIL_ATTACHMENT:
1650 res = boundFboProps_const(target).depthstencilAttachment_texture;
1651 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001652 }
1653 return res;
1654}
1655
1656// RBOs for FBOs////////////////////////////////////////////////////////////////
1657
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001658void GLClientState::detachRbo(GLuint renderbuffer) {
1659 for (int i = 0; i < m_max_color_attachments; i++) {
1660 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1661 detachRboFromFbo(GL_READ_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1662 }
1663
1664 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1665 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1666
1667 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1668 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1669
1670 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1671 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1672}
1673
1674void GLClientState::detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1675 int colorAttachmentIndex =
1676 glUtilsColorAttachmentIndex(attachment);
1677
1678 if (colorAttachmentIndex != -1) {
1679 if (boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] &&
1680 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] == renderbuffer) {
1681 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = 0;
1682 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = false;
1683 }
1684 }
1685
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001686 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001687 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001688 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1689 boundFboProps(target).depthAttachment_hasRbo) {
1690 boundFboProps(target).depthAttachment_rbo = 0;
1691 boundFboProps(target).depthAttachment_hasRbo = false;
1692 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001693 break;
1694 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001695 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1696 boundFboProps(target).stencilAttachment_hasRbo) {
1697 boundFboProps(target).stencilAttachment_rbo = 0;
1698 boundFboProps(target).stencilAttachment_hasRbo = false;
1699 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001700 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001701 case GL_DEPTH_STENCIL_ATTACHMENT:
1702 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1703 boundFboProps(target).depthAttachment_hasRbo) {
1704 boundFboProps(target).depthAttachment_rbo = 0;
1705 boundFboProps(target).depthAttachment_hasRbo = false;
1706 }
1707 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1708 boundFboProps(target).stencilAttachment_hasRbo) {
1709 boundFboProps(target).stencilAttachment_rbo = 0;
1710 boundFboProps(target).stencilAttachment_hasRbo = false;
1711 }
1712 if (boundFboProps(target).depthstencilAttachment_rbo == renderbuffer &&
1713 boundFboProps(target).depthstencilAttachment_hasRbo) {
1714 boundFboProps(target).depthstencilAttachment_rbo = 0;
1715 boundFboProps(target).depthstencilAttachment_hasRbo = false;
1716 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001717 break;
1718 }
1719}
1720
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001721void GLClientState::attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1722
1723 int colorAttachmentIndex =
1724 glUtilsColorAttachmentIndex(attachment);
1725
1726 if (colorAttachmentIndex != -1) {
1727 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = renderbuffer;
1728 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = true;
1729 }
1730
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001731 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001732 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001733 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1734 boundFboProps(target).depthAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001735 break;
1736 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001737 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1738 boundFboProps(target).stencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001739 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001740 case GL_DEPTH_STENCIL_ATTACHMENT:
1741 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1742 boundFboProps(target).depthAttachment_hasRbo = true;
1743 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1744 boundFboProps(target).stencilAttachment_hasRbo = true;
1745 boundFboProps(target).depthstencilAttachment_rbo = renderbuffer;
1746 boundFboProps(target).depthstencilAttachment_hasRbo = true;
1747 break;
1748 }
1749}
1750
1751GLuint GLClientState::getFboAttachmentRboId(GLenum target, GLenum attachment) const {
1752 GLuint res = 0; // conservative
1753
1754 int colorAttachmentIndex =
1755 glUtilsColorAttachmentIndex(attachment);
1756
1757 if (colorAttachmentIndex != -1) {
1758 res = boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex];
1759 }
1760
1761 switch (attachment) {
1762 case GL_DEPTH_ATTACHMENT:
1763 res = boundFboProps_const(target).depthAttachment_rbo;
1764 break;
1765 case GL_STENCIL_ATTACHMENT:
1766 res = boundFboProps_const(target).stencilAttachment_rbo;
1767 break;
1768 case GL_DEPTH_STENCIL_ATTACHMENT:
1769 res = boundFboProps_const(target).depthstencilAttachment_rbo;
1770 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001771 }
1772 return res;
1773}
1774
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001775bool GLClientState::attachmentHasObject(GLenum target, GLenum attachment) const {
1776 bool res = true; // liberal
1777
1778 int colorAttachmentIndex =
1779 glUtilsColorAttachmentIndex(attachment);
1780
1781 if (colorAttachmentIndex != -1) {
1782 res = boundFboProps_const(target).colorAttachmenti_hasTex[colorAttachmentIndex] ||
1783 boundFboProps_const(target).colorAttachmenti_hasRbo[colorAttachmentIndex];
1784 }
1785
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001786 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001787 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001788 res = (boundFboProps_const(target).depthAttachment_hasTexObj) ||
1789 (boundFboProps_const(target).depthAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001790 break;
1791 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001792 res = (boundFboProps_const(target).stencilAttachment_hasTexObj) ||
1793 (boundFboProps_const(target).stencilAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001794 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001795 case GL_DEPTH_STENCIL_ATTACHMENT:
1796 res = (boundFboProps_const(target).depthstencilAttachment_hasTexObj) ||
1797 (boundFboProps_const(target).depthstencilAttachment_hasRbo);
1798 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001799 }
1800 return res;
1801}
1802
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001803GLuint GLClientState::objectOfAttachment(GLenum target, GLenum attachment) const {
1804 const FboProps& props = boundFboProps_const(target);
1805
1806 int colorAttachmentIndex =
1807 glUtilsColorAttachmentIndex(attachment);
1808
1809 if (colorAttachmentIndex != -1) {
1810 if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
1811 return props.colorAttachmenti_textures[colorAttachmentIndex];
1812 } else if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
1813 return props.colorAttachmenti_rbos[colorAttachmentIndex];
1814 } else {
1815 return 0;
1816 }
1817 }
1818
1819 switch (attachment) {
1820 case GL_DEPTH_ATTACHMENT:
1821 if (props.depthAttachment_hasTexObj) {
1822 return props.depthAttachment_texture;
1823 } else if (props.depthAttachment_hasRbo) {
1824 return props.depthAttachment_rbo;
1825 } else {
1826 return 0;
1827 }
1828 break;
1829 case GL_STENCIL_ATTACHMENT:
1830 if (props.stencilAttachment_hasTexObj) {
1831 return props.stencilAttachment_texture;
1832 } else if (props.stencilAttachment_hasRbo) {
1833 return props.stencilAttachment_rbo;
1834 } else {
1835 return 0;
1836 }
1837 case GL_DEPTH_STENCIL_ATTACHMENT:
1838 if (props.depthstencilAttachment_hasTexObj) {
1839 return props.depthstencilAttachment_texture;
1840 } else if (props.depthstencilAttachment_hasRbo) {
1841 return props.depthstencilAttachment_rbo;
1842 } else {
1843 return 0;
1844 }
1845 break;
1846 }
1847 return 0;
1848}
Lingfeng Yang4a66b312017-01-09 13:27:49 -08001849
1850void GLClientState::setTransformFeedbackActiveUnpaused(bool activeUnpaused) {
1851 m_transformFeedbackActiveUnpaused = activeUnpaused;
1852}
1853
1854bool GLClientState::getTransformFeedbackActiveUnpaused() const {
1855 return m_transformFeedbackActiveUnpaused;
1856}
1857
1858void GLClientState::setTextureData(SharedTextureDataMap* sharedTexData) {
1859 m_tex.textureRecs = sharedTexData;
1860}
1861
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001862void GLClientState::fromMakeCurrent() {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001863 if (mFboState.fboData.find(0) == mFboState.fboData.end()) {
1864 addFreshFramebuffer(0);
1865 }
1866 FboProps& default_fb_props = mFboState.fboData[0];
1867 default_fb_props.colorAttachmenti_hasRbo[0] = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001868 default_fb_props.depthAttachment_hasRbo = true;
1869 default_fb_props.stencilAttachment_hasRbo = true;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001870 default_fb_props.depthstencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001871}
Lingfeng Yangf654f3f2017-01-09 13:12:33 -08001872
1873void GLClientState::initFromCaps(
1874 int max_transform_feedback_separate_attribs,
1875 int max_uniform_buffer_bindings,
1876 int max_atomic_counter_buffer_bindings,
1877 int max_shader_storage_buffer_bindings,
1878 int max_vertex_attrib_bindings,
1879 int max_color_attachments,
1880 int max_draw_buffers) {
1881
1882 m_max_vertex_attrib_bindings = max_vertex_attrib_bindings;
1883
1884 if (m_glesMajorVersion >= 3) {
1885 m_max_transform_feedback_separate_attribs = max_transform_feedback_separate_attribs;
1886 m_max_uniform_buffer_bindings = max_uniform_buffer_bindings;
1887 m_max_atomic_counter_buffer_bindings = max_atomic_counter_buffer_bindings;
1888 m_max_shader_storage_buffer_bindings = max_shader_storage_buffer_bindings;
1889
1890 if (m_max_transform_feedback_separate_attribs)
1891 m_indexedTransformFeedbackBuffers.resize(m_max_transform_feedback_separate_attribs);
1892 if (m_max_uniform_buffer_bindings)
1893 m_indexedUniformBuffers.resize(m_max_uniform_buffer_bindings);
1894 if (m_max_atomic_counter_buffer_bindings)
1895 m_indexedAtomicCounterBuffers.resize(m_max_atomic_counter_buffer_bindings);
1896 if (m_max_shader_storage_buffer_bindings)
1897 m_indexedShaderStorageBuffers.resize(m_max_shader_storage_buffer_bindings);
1898
1899 BufferBinding buf0Binding;
1900 buf0Binding.buffer = 0;
1901 buf0Binding.offset = 0;
1902 buf0Binding.size = 0;
1903 buf0Binding.stride = 0;
1904 buf0Binding.effectiveStride = 0;
1905
1906 for (size_t i = 0; i < m_indexedTransformFeedbackBuffers.size(); ++i)
1907 m_indexedTransformFeedbackBuffers[i] = buf0Binding;
1908 for (size_t i = 0; i < m_indexedUniformBuffers.size(); ++i)
1909 m_indexedUniformBuffers[i] = buf0Binding;
1910 for (size_t i = 0; i < m_indexedAtomicCounterBuffers.size(); ++i)
1911 m_indexedAtomicCounterBuffers[i] = buf0Binding;
1912 for (size_t i = 0; i < m_indexedShaderStorageBuffers.size(); ++i)
1913 m_indexedShaderStorageBuffers[i] = buf0Binding;
1914 }
1915
1916 m_max_color_attachments = max_color_attachments;
1917 m_max_draw_buffers = max_draw_buffers;
1918
1919 addFreshRenderbuffer(0);
1920 addFreshFramebuffer(0);
1921
1922 m_initialized = true;
1923}
1924
1925bool GLClientState::needsInitFromCaps() const {
1926 return !m_initialized;
1927}