blob: c6140dbf4588a2a963dec9a3f16e8b02af226c6d [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 Yang28a757c2019-11-08 21:37:59 -080044
45 m_attribEnableCache = 0;
46 m_vaoAttribBindingCacheInvalid = 0xffff;
47 m_vaoAttribBindingHasClientArrayCache = 0;
48 m_vaoAttribBindingHasVboCache = 0;
Lingfeng Yangf8519c12019-11-09 09:35:23 -080049 m_noClientArraysCache = 0;
Lingfeng Yang28a757c2019-11-08 21:37:59 -080050
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080051 m_max_vertex_attrib_bindings = m_nLocations;
52 addVertexArrayObject(0);
53 setVertexArrayObject(0);
keunyoungb85b2752013-03-08 12:28:03 -080054 // init gl constans;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -080055 m_currVaoState[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY;
56 m_currVaoState[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY;
57 m_currVaoState[COLOR_LOCATION].glConst = GL_COLOR_ARRAY;
58 m_currVaoState[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES;
59 m_currVaoState[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
60 m_currVaoState[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
61 m_currVaoState[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
62 m_currVaoState[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
63 m_currVaoState[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
64 m_currVaoState[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
65 m_currVaoState[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
66 m_currVaoState[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY;
67 m_currVaoState[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES;
68 m_currVaoState[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES;
69
70 m_copyReadBuffer = 0;
71 m_copyWriteBuffer = 0;
72 m_pixelPackBuffer = 0;
73 m_pixelUnpackBuffer = 0;
74 m_transformFeedbackBuffer = 0;
75 m_uniformBuffer = 0;
76 m_atomicCounterBuffer = 0;
77 m_dispatchIndirectBuffer = 0;
78 m_drawIndirectBuffer = 0;
79 m_shaderStorageBuffer = 0;
80
81 m_transformFeedbackActiveUnpaused = false;
82
83 // to be modified later when these are queried from host.
84 m_max_transform_feedback_separate_attribs = 0;
85 m_max_uniform_buffer_bindings = 0;
86 m_max_atomic_counter_buffer_bindings = 0;
87 m_max_shader_storage_buffer_bindings = 0;
88
keunyoungb85b2752013-03-08 12:28:03 -080089 m_activeTexture = 0;
90 m_currentProgram = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -080091 m_currentShaderProgram = 0;
keunyoungb85b2752013-03-08 12:28:03 -080092
93 m_pixelStore.unpack_alignment = 4;
94 m_pixelStore.pack_alignment = 4;
95
Lingfeng Yang74e29292017-01-10 14:54:38 -080096 m_pixelStore.unpack_row_length = 0;
97 m_pixelStore.unpack_image_height = 0;
98 m_pixelStore.unpack_skip_pixels = 0;
99 m_pixelStore.unpack_skip_rows = 0;
100 m_pixelStore.unpack_skip_images = 0;
101
102 m_pixelStore.pack_row_length = 0;
103 m_pixelStore.pack_skip_pixels = 0;
104 m_pixelStore.pack_skip_rows = 0;
105
keunyoungb85b2752013-03-08 12:28:03 -0800106 memset(m_tex.unit, 0, sizeof(m_tex.unit));
107 m_tex.activeUnit = &m_tex.unit[0];
Lingfeng Yang74e29292017-01-10 14:54:38 -0800108 m_tex.textureRecs = NULL;
Lingfeng Yangb0176982016-03-01 21:27:49 -0800109
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700110 mRboState.boundRenderbuffer = 0;
111 mRboState.boundRenderbufferIndex = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700112
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -0800113 mFboState.boundDrawFramebuffer = 0;
114 mFboState.boundReadFramebuffer = 0;
115 mFboState.drawFboCheckStatus = GL_NONE;
116 mFboState.readFboCheckStatus = GL_NONE;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -0700117
Lingfeng Yangb0176982016-03-01 21:27:49 -0800118 m_maxVertexAttribsDirty = true;
keunyoungb85b2752013-03-08 12:28:03 -0800119}
120
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800121GLClientState::GLClientState()
122{
123 init();
124}
125
126GLClientState::GLClientState(int majorVersion, int minorVersion) :
127 m_glesMajorVersion(majorVersion),
128 m_glesMinorVersion(minorVersion) {
129 init();
130}
131
keunyoungb85b2752013-03-08 12:28:03 -0800132GLClientState::~GLClientState()
133{
keunyoungb85b2752013-03-08 12:28:03 -0800134}
135
136void GLClientState::enable(int location, int state)
137{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800138 m_currVaoState[location].enableDirty |= (state != m_currVaoState[location].enabled);
139 m_currVaoState[location].enabled = state;
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800140 if (state) {
141 m_attribEnableCache |= (1 << location);
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800142 m_noClientArraysCache = 0;
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800143 } else {
144 m_attribEnableCache &= ~(1 << location);
145 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800146}
147
148void GLClientState::setVertexAttribState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt)
149{
150 m_currVaoState[location].size = size;
151 m_currVaoState[location].type = type;
152 m_currVaoState[location].stride = stride;
153 m_currVaoState[location].data = (void*)data;
154 m_currVaoState[location].bufferObject = m_arrayBuffer;
155 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
156 switch (type) {
157 case GL_INT_2_10_10_10_REV:
158 case GL_UNSIGNED_INT_2_10_10_10_REV:
159 m_currVaoState[location].elementSize =
160 m_currVaoState[location].elementSize / 4;
161 break;
162 default:
163 break;
164 }
165 m_currVaoState[location].normalized = normalized;
166 m_currVaoState[location].isInt = isInt;
167}
168
169void GLClientState::setVertexBindingDivisor(int bindingindex, GLuint divisor) {
170 m_currVaoState.bufferBinding(bindingindex).divisor = divisor;
171}
172
173const GLClientState::BufferBinding& GLClientState::getCurrAttributeBindingInfo(int attribindex) {
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -0800174 return m_currVaoState.bufferBindings_const()[m_currVaoState[attribindex].bindingindex];
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800175}
176
177void GLClientState::setVertexAttribBinding(int attribindex, int bindingindex) {
178 m_currVaoState[attribindex].bindingindex = bindingindex;
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800179 m_currVaoState.bufferBinding(bindingindex).vertexAttribLoc = attribindex;
180 m_vaoAttribBindingCacheInvalid |= (1 << attribindex);
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800181 m_noClientArraysCache = 0;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800182}
183
184void GLClientState::setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt) {
185 m_currVaoState[location].size = size;
186 m_currVaoState[location].type = type;
187 m_currVaoState[location].normalized = normalized;
188 m_currVaoState[location].reloffset = reloffset;
189 m_currVaoState[location].elementSize = size ? (glSizeof(type) * size) : 0;
190 switch (type) {
191 case GL_INT_2_10_10_10_REV:
192 case GL_UNSIGNED_INT_2_10_10_10_REV:
193 m_currVaoState[location].elementSize =
194 m_currVaoState[location].elementSize / 4;
195 break;
196 default:
197 break;
198 }
199 m_currVaoState[location].isInt = isInt;
200}
201
202void GLClientState::addVertexArrayObjects(GLsizei n, GLuint* arrays) {
203 for (GLsizei i = 0; i < n; i++) {
204 addVertexArrayObject(arrays[i]);
205 }
206}
207
208void GLClientState::removeVertexArrayObjects(GLsizei n, const GLuint* arrays) {
209 for (GLsizei i = 0; i < n; i++) {
210 if (arrays[i] && m_currVaoState.vaoId() == arrays[i]) {
211 setVertexArrayObject(0);
212 }
213 removeVertexArrayObject(arrays[i]);
214 }
215}
216
217void GLClientState::addVertexArrayObject(GLuint name) {
218 if (m_vaoMap.find(name) !=
219 m_vaoMap.end()) {
220 ALOGE("%s: ERROR: %u already part of current VAO state!",
221 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800222 return;
223 }
224
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800225 m_vaoMap.insert(
226 VAOStateMap::value_type(
227 name,
228 VAOState(0, m_nLocations, std::max(m_nLocations, m_max_vertex_attrib_bindings))));
229 VertexAttribStateVector& attribState =
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -0800230 m_vaoMap.find(name)->second.attribState;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800231 for (int i = 0; i < m_nLocations; i++) {
232 attribState[i].enabled = 0;
233 attribState[i].enableDirty = false;
234 attribState[i].data = 0;
235 attribState[i].reloffset = 0;
236 attribState[i].bindingindex = i;
237 attribState[i].divisor = 0;
238 attribState[i].size = 4; // 4 is the default size
239 attribState[i].type = GL_FLOAT; // GL_FLOAT is the default type
240 }
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800241
242 VertexAttribBindingVector& bindingState =
243 m_vaoMap.find(name)->second.bindingState;
244 for (int i = 0; i < bindingState.size(); i++) {
245 bindingState[i].effectiveStride = 16;
246 }
keunyoungb85b2752013-03-08 12:28:03 -0800247}
248
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800249void GLClientState::removeVertexArrayObject(GLuint name) {
250 if (name == 0) {
251 ALOGE("%s: ERROR: cannot delete VAO 0!",
252 __FUNCTION__);
keunyoungb85b2752013-03-08 12:28:03 -0800253 return;
254 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800255 if (m_vaoMap.find(name) ==
256 m_vaoMap.end()) {
257 ALOGE("%s: ERROR: %u not found in VAO state!",
258 __FUNCTION__, name);
259 return;
260 }
261 m_vaoMap.erase(name);
keunyoungb85b2752013-03-08 12:28:03 -0800262}
263
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800264void GLClientState::setVertexArrayObject(GLuint name) {
265 if (m_vaoMap.find(name) ==
266 m_vaoMap.end()) {
267 ALOGE("%s: ERROR: %u not found in VAO state!",
268 __FUNCTION__, name);
keunyoungb85b2752013-03-08 12:28:03 -0800269 return;
270 }
271
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800272 if (name && m_currVaoState.vaoId() == name) {
273 ALOGV("%s: set vao to self, no-op (%u)",
274 __FUNCTION__, name);
275 return;
keunyoungb85b2752013-03-08 12:28:03 -0800276 }
277
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800278 m_currVaoState =
279 VAOStateRef(m_vaoMap.find(name));
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800280}
281
282bool GLClientState::isVertexArrayObject(GLuint vao) const {
283 return m_vaoMap.find(vao) != m_vaoMap.end();
284}
285
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800286void GLClientState::getVBOUsage(bool* hasClientArrays, bool* hasVBOs) {
287 uint8_t todo_count = 0;
288 uint8_t todo[CODEC_MAX_VERTEX_ATTRIBUTES];
289
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800290 if (m_noClientArraysCache) {
291 *hasClientArrays = false;
292 *hasVBOs = true;
293 return;
294 }
295
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800296 for (int i = 0; i < CODEC_MAX_VERTEX_ATTRIBUTES; i++) {
297 if ((1 << i) & (m_attribEnableCache)) {
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800298 if (!((1 << i) & m_vaoAttribBindingCacheInvalid)) {
299 if ((1 << i) & m_vaoAttribBindingHasClientArrayCache) {
300 *hasClientArrays = true;
301 }
302 if ((1 << i) & m_vaoAttribBindingHasVboCache) {
303 *hasVBOs = true;
304 }
305 if (*hasClientArrays && *hasVBOs) return;
306 } else {
307 todo[todo_count] = i;
308 ++todo_count;
309 }
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800310 }
311 }
312
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800313 if (todo_count == 0 &&
314 !(*hasClientArrays) &&
315 *hasVBOs) {
316 m_noClientArraysCache = 1;
317 }
318
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800319 for (int k = 0; k < todo_count; ++k) {
320 int i = todo[k];
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800321 const GLClientState::BufferBinding& curr_binding =
322 m_currVaoState.bufferBindings_const()[
323 m_currVaoState[i].bindingindex];
324 GLuint bufferObject = curr_binding.buffer;
325 if (bufferObject == 0 && curr_binding.offset && hasClientArrays) {
326 *hasClientArrays = true;
327 m_vaoAttribBindingHasClientArrayCache |= (1 << i);
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800328 } else {
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800329 m_vaoAttribBindingHasClientArrayCache &= ~(1 << i);
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800330 }
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800331 if (bufferObject != 0 && hasVBOs) {
332 *hasVBOs = true;
333 m_vaoAttribBindingHasVboCache |= (1 << i);
334 } else {
335 m_vaoAttribBindingHasVboCache &= ~(1 << i);
336 }
337 m_vaoAttribBindingCacheInvalid &= ~(1 << i);
338 if (*hasClientArrays && *hasVBOs) return;
339 }
340
341 if (!(*hasClientArrays) &&
342 *hasVBOs) {
343 m_noClientArraysCache = 1;
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800344 }
345}
346
347const GLClientState::VertexAttribState& GLClientState::getState(int location) {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800348 return m_currVaoState[location];
349}
350
351const GLClientState::VertexAttribState& GLClientState::getStateAndEnableDirty(int location, bool *enableChanged)
352{
keunyoungb85b2752013-03-08 12:28:03 -0800353 if (enableChanged) {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800354 *enableChanged = m_currVaoState[location].enableDirty;
keunyoungb85b2752013-03-08 12:28:03 -0800355 }
356
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800357 m_currVaoState[location].enableDirty = false;
358 return m_currVaoState[location];
keunyoungb85b2752013-03-08 12:28:03 -0800359}
360
Lingfeng Yang554a5152019-02-21 20:20:48 -0800361void GLClientState::updateEnableDirtyArrayForDraw() {
362 bool enableChanged;
Lingfeng Yang6f0878f2019-02-27 17:27:32 -0800363 VAOState& vaoState = m_currVaoState.vaoState();
Lingfeng Yang554a5152019-02-21 20:20:48 -0800364
365 int k = 0;
366 for (int i = 0; i < CODEC_MAX_VERTEX_ATTRIBUTES; ++i) {
367 const VertexAttribState &state = getStateAndEnableDirty(i, &enableChanged);
368 if (enableChanged || state.enabled) {
369 vaoState.attributesNeedingUpdateForDraw[k] = i;
370 ++k;
371 }
372 }
373 vaoState.numAttributesNeedingUpdateForDraw = k;
374}
375
376GLClientState::VAOState& GLClientState::currentVaoState() {
377 return m_currVaoState.vaoState();
378}
379
keunyoungb85b2752013-03-08 12:28:03 -0800380int GLClientState::getLocation(GLenum loc)
381{
382 int retval;
383
384 switch(loc) {
385 case GL_VERTEX_ARRAY:
386 retval = int(VERTEX_LOCATION);
387 break;
388 case GL_NORMAL_ARRAY:
389 retval = int(NORMAL_LOCATION);
390 break;
391 case GL_COLOR_ARRAY:
392 retval = int(COLOR_LOCATION);
393 break;
394 case GL_POINT_SIZE_ARRAY_OES:
395 retval = int(POINTSIZE_LOCATION);
396 break;
397 case GL_TEXTURE_COORD_ARRAY:
398 retval = int (TEXCOORD0_LOCATION + m_activeTexture);
399 break;
400 case GL_MATRIX_INDEX_ARRAY_OES:
401 retval = int (MATRIXINDEX_LOCATION);
402 break;
403 case GL_WEIGHT_ARRAY_OES:
404 retval = int (WEIGHT_LOCATION);
405 break;
406 default:
407 retval = loc;
408 }
409 return retval;
410}
411
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800412static void sClearIndexedBufferBinding(GLuint id, std::vector<GLClientState::BufferBinding>& bindings) {
413 for (size_t i = 0; i < bindings.size(); i++) {
414 if (bindings[i].buffer == id) {
415 bindings[i].offset = 0;
416 bindings[i].stride = 0;
417 bindings[i].effectiveStride = 16;
418 bindings[i].size = 0;
419 bindings[i].buffer = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800420 }
421 }
422}
423
424void GLClientState::addBuffer(GLuint id) {
425 mBufferIds.insert(id);
426}
427
428void GLClientState::removeBuffer(GLuint id) {
429 mBufferIds.erase(id);
430}
431
432bool GLClientState::bufferIdExists(GLuint id) const {
433 return mBufferIds.find(id) != mBufferIds.end();
434}
435
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800436void GLClientState::unBindBuffer(GLuint id) {
Lingfeng Yang554a5152019-02-21 20:20:48 -0800437 if (m_arrayBuffer == id) {
438 m_arrayBuffer = 0;
439 m_arrayBuffer_lastEncode = 0;
440 }
441
442 if (m_currVaoState.iboId() == id) {
443 m_currVaoState.iboId() = 0;
444 m_currVaoState.iboIdLastEncode() = 0;
445 }
446
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800447 if (m_copyReadBuffer == id)
448 m_copyReadBuffer = 0;
449 if (m_copyWriteBuffer == id)
450 m_copyWriteBuffer = 0;
451 if (m_pixelPackBuffer == id)
452 m_pixelPackBuffer = 0;
453 if (m_pixelUnpackBuffer == id)
454 m_pixelUnpackBuffer = 0;
455 if (m_transformFeedbackBuffer == id)
456 m_transformFeedbackBuffer = 0;
457 if (m_uniformBuffer == id)
458 m_uniformBuffer = 0;
459 if (m_atomicCounterBuffer == id)
460 m_atomicCounterBuffer = 0;
461 if (m_dispatchIndirectBuffer == id)
462 m_dispatchIndirectBuffer = 0;
463 if (m_drawIndirectBuffer == id)
464 m_drawIndirectBuffer = 0;
465 if (m_shaderStorageBuffer == id)
466 m_shaderStorageBuffer = 0;
Lingfeng Yangd3ae1062017-01-18 11:42:04 -0800467
468 sClearIndexedBufferBinding(id, m_indexedTransformFeedbackBuffers);
469 sClearIndexedBufferBinding(id, m_indexedUniformBuffers);
470 sClearIndexedBufferBinding(id, m_indexedAtomicCounterBuffers);
471 sClearIndexedBufferBinding(id, m_indexedShaderStorageBuffers);
472 sClearIndexedBufferBinding(id, m_currVaoState.bufferBindings());
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800473 m_vaoAttribBindingCacheInvalid = 0xffff;
Lingfeng Yangf8519c12019-11-09 09:35:23 -0800474 m_noClientArraysCache = 0;
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800475}
476
477int GLClientState::bindBuffer(GLenum target, GLuint id)
478{
479 int err = 0;
480 switch(target) {
481 case GL_ARRAY_BUFFER:
482 m_arrayBuffer = id;
483 break;
484 case GL_ELEMENT_ARRAY_BUFFER:
485 m_currVaoState.iboId() = id;
486 break;
487 case GL_COPY_READ_BUFFER:
488 m_copyReadBuffer = id;
489 break;
490 case GL_COPY_WRITE_BUFFER:
491 m_copyWriteBuffer = id;
492 break;
493 case GL_PIXEL_PACK_BUFFER:
494 m_pixelPackBuffer = id;
495 break;
496 case GL_PIXEL_UNPACK_BUFFER:
497 m_pixelUnpackBuffer = id;
498 break;
499 case GL_TRANSFORM_FEEDBACK_BUFFER:
500 m_transformFeedbackBuffer = id;
501 break;
502 case GL_UNIFORM_BUFFER:
503 m_uniformBuffer = id;
504 break;
505 case GL_ATOMIC_COUNTER_BUFFER:
506 m_atomicCounterBuffer = id;
507 break;
508 case GL_DISPATCH_INDIRECT_BUFFER:
509 m_dispatchIndirectBuffer = id;
510 break;
511 case GL_DRAW_INDIRECT_BUFFER:
512 m_drawIndirectBuffer = id;
513 break;
514 case GL_SHADER_STORAGE_BUFFER:
515 m_shaderStorageBuffer = id;
516 break;
517 default:
518 err = -1;
519 }
520 return err;
521}
522
523void GLClientState::bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) {
524 switch (target) {
525 case GL_TRANSFORM_FEEDBACK_BUFFER:
526 m_indexedTransformFeedbackBuffers[index].buffer = buffer;
527 m_indexedTransformFeedbackBuffers[index].offset = offset;
528 m_indexedTransformFeedbackBuffers[index].size = size;
529 m_indexedTransformFeedbackBuffers[index].stride = stride;
530 break;
531 case GL_UNIFORM_BUFFER:
532 m_indexedUniformBuffers[index].buffer = buffer;
533 m_indexedUniformBuffers[index].offset = offset;
534 m_indexedUniformBuffers[index].size = size;
535 m_indexedUniformBuffers[index].stride = stride;
536 break;
537 case GL_ATOMIC_COUNTER_BUFFER:
538 m_indexedAtomicCounterBuffers[index].buffer = buffer;
539 m_indexedAtomicCounterBuffers[index].offset = offset;
540 m_indexedAtomicCounterBuffers[index].size = size;
541 m_indexedAtomicCounterBuffers[index].stride = stride;
542 break;
543 case GL_SHADER_STORAGE_BUFFER:
544 m_indexedShaderStorageBuffers[index].buffer = buffer;
545 m_indexedShaderStorageBuffers[index].offset = offset;
546 m_indexedShaderStorageBuffers[index].size = size;
547 m_indexedShaderStorageBuffers[index].stride = stride;
548 break;
549 default:
550 m_currVaoState.bufferBinding(index).buffer = buffer;
551 m_currVaoState.bufferBinding(index).offset = offset;
552 m_currVaoState.bufferBinding(index).size = size;
553 m_currVaoState.bufferBinding(index).stride = stride;
554 m_currVaoState.bufferBinding(index).effectiveStride = effectiveStride;
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800555 m_vaoAttribBindingCacheInvalid |= (1 << m_currVaoState.bufferBinding(index).vertexAttribLoc);
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800556 return;
557 }
558}
559
560int GLClientState::getMaxIndexedBufferBindings(GLenum target) const {
561 switch (target) {
562 case GL_TRANSFORM_FEEDBACK_BUFFER:
563 return m_indexedTransformFeedbackBuffers.size();
564 case GL_UNIFORM_BUFFER:
565 return m_indexedUniformBuffers.size();
566 case GL_ATOMIC_COUNTER_BUFFER:
567 return m_indexedAtomicCounterBuffers.size();
568 case GL_SHADER_STORAGE_BUFFER:
569 return m_indexedShaderStorageBuffers.size();
570 default:
571 return m_currVaoState.bufferBindings_const().size();
572 }
573}
574
Lingfeng Yang2c3a0da2019-03-07 20:43:53 -0800575bool GLClientState::isNonIndexedBindNoOp(GLenum target, GLuint buffer) {
576 if (buffer != !getLastEncodedBufferBind(target)) return false;
577
578 int idOrError = getBuffer(target);
579 if (idOrError < 0) {
580 return false;
581 } else {
582 return buffer == (GLuint)idOrError;
583 }
584}
585
Lingfeng Yang554a5152019-02-21 20:20:48 -0800586bool GLClientState::isIndexedBindNoOp(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride) {
587
588 if (target == GL_TRANSFORM_FEEDBACK_BUFFER) return false;
589
590 if (buffer != getLastEncodedBufferBind(target)) return false;
591
592 switch (target) {
593 case GL_TRANSFORM_FEEDBACK_BUFFER:
594 return m_indexedTransformFeedbackBuffers[index].buffer == buffer &&
595 m_indexedTransformFeedbackBuffers[index].offset == offset &&
596 m_indexedTransformFeedbackBuffers[index].size == size &&
597 m_indexedTransformFeedbackBuffers[index].stride == stride;
598 case GL_UNIFORM_BUFFER:
599 return m_indexedUniformBuffers[index].buffer == buffer &&
600 m_indexedUniformBuffers[index].offset == offset &&
601 m_indexedUniformBuffers[index].size == size &&
602 m_indexedUniformBuffers[index].stride == stride;
603 case GL_ATOMIC_COUNTER_BUFFER:
604 return m_indexedAtomicCounterBuffers[index].buffer == buffer &&
605 m_indexedAtomicCounterBuffers[index].offset == offset &&
606 m_indexedAtomicCounterBuffers[index].size == size &&
607 m_indexedAtomicCounterBuffers[index].stride == stride;
608 case GL_SHADER_STORAGE_BUFFER:
609 return m_indexedShaderStorageBuffers[index].buffer == buffer &&
610 m_indexedShaderStorageBuffers[index].offset == offset &&
611 m_indexedShaderStorageBuffers[index].size == size &&
612 m_indexedShaderStorageBuffers[index].stride == stride;
613 default:
614 return m_currVaoState.bufferBinding(index).buffer == buffer &&
615 m_currVaoState.bufferBinding(index).offset == offset &&
616 m_currVaoState.bufferBinding(index).size == size &&
617 m_currVaoState.bufferBinding(index).stride == stride &&
618 m_currVaoState.bufferBinding(index).effectiveStride == effectiveStride;
619 }
620}
621
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800622int GLClientState::getBuffer(GLenum target) {
623 int ret=0;
624 switch (target) {
625 case GL_ARRAY_BUFFER:
626 ret = m_arrayBuffer;
627 break;
628 case GL_ELEMENT_ARRAY_BUFFER:
629 ret = m_currVaoState.iboId();
630 break;
631 case GL_COPY_READ_BUFFER:
632 ret = m_copyReadBuffer;
633 break;
634 case GL_COPY_WRITE_BUFFER:
635 ret = m_copyWriteBuffer;
636 break;
637 case GL_PIXEL_PACK_BUFFER:
638 ret = m_pixelPackBuffer;
639 break;
640 case GL_PIXEL_UNPACK_BUFFER:
641 ret = m_pixelUnpackBuffer;
642 break;
643 case GL_TRANSFORM_FEEDBACK_BUFFER:
644 ret = m_transformFeedbackBuffer;
645 break;
646 case GL_UNIFORM_BUFFER:
647 ret = m_uniformBuffer;
648 break;
649 case GL_ATOMIC_COUNTER_BUFFER:
650 ret = m_atomicCounterBuffer;
651 break;
652 case GL_DISPATCH_INDIRECT_BUFFER:
653 ret = m_dispatchIndirectBuffer;
654 break;
655 case GL_DRAW_INDIRECT_BUFFER:
656 ret = m_drawIndirectBuffer;
657 break;
658 case GL_SHADER_STORAGE_BUFFER:
659 ret = m_shaderStorageBuffer;
660 break;
661 default:
662 ret = -1;
663 }
664 return ret;
665}
666
Lingfeng Yang554a5152019-02-21 20:20:48 -0800667GLuint GLClientState::getLastEncodedBufferBind(GLenum target) {
668 GLuint ret;
669 switch (target)
670 {
671 case GL_ARRAY_BUFFER:
672 ret = m_arrayBuffer_lastEncode;
673 break;
674 case GL_ELEMENT_ARRAY_BUFFER:
675 ret = m_currVaoState.iboIdLastEncode();
676 break;
677 default:
678 {
679 int idOrError = getBuffer(target);
680 ret = (idOrError < 0) ? 0 : (GLuint)idOrError;
681 }
682 }
683
684 return ret;
685}
686
687void GLClientState::setLastEncodedBufferBind(GLenum target, GLuint id)
688{
689 switch (target)
690 {
691 case GL_ARRAY_BUFFER:
692 m_arrayBuffer_lastEncode = id;
693 break;
694 case GL_ELEMENT_ARRAY_BUFFER:
695 m_currVaoState.iboIdLastEncode() = id;
696 break;
697 default:
698 break;
699 }
700}
701
keunyoungb85b2752013-03-08 12:28:03 -0800702void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params)
703{
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800704 GLenum which_state = -1;
keunyoungb85b2752013-03-08 12:28:03 -0800705 switch (pname) {
706 case GL_VERTEX_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800707 which_state = GLClientState::VERTEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800708 break;
709 }
710 case GL_NORMAL_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800711 which_state = GLClientState::NORMAL_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800712 break;
713 }
714 case GL_COLOR_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800715 which_state = GLClientState::COLOR_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800716 break;
717 }
718 case GL_TEXTURE_COORD_ARRAY_POINTER: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800719 which_state = getActiveTexture() + GLClientState::TEXCOORD0_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800720 break;
721 }
722 case GL_POINT_SIZE_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800723 which_state = GLClientState::POINTSIZE_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800724 break;
725 }
726 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800727 which_state = GLClientState::MATRIXINDEX_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800728 break;
729 }
730 case GL_WEIGHT_ARRAY_POINTER_OES: {
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800731 which_state = GLClientState::WEIGHT_LOCATION;
keunyoungb85b2752013-03-08 12:28:03 -0800732 break;
733 }
734 }
Lingfeng Yangf654f3f2017-01-09 13:12:33 -0800735 if (which_state != -1)
Lingfeng Yang9a2fa6f2019-11-08 09:41:17 -0800736 *params = m_currVaoState[which_state].data;
keunyoungb85b2752013-03-08 12:28:03 -0800737}
738
739int GLClientState::setPixelStore(GLenum param, GLint value)
740{
741 int retval = 0;
742 switch(param) {
743 case GL_UNPACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800744 m_pixelStore.unpack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800745 break;
746 case GL_PACK_ALIGNMENT:
Lingfeng Yang74e29292017-01-10 14:54:38 -0800747 m_pixelStore.pack_alignment = value;
keunyoungb85b2752013-03-08 12:28:03 -0800748 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800749 case GL_UNPACK_ROW_LENGTH:
750 m_pixelStore.unpack_row_length = value;
751 break;
752 case GL_UNPACK_IMAGE_HEIGHT:
753 m_pixelStore.unpack_image_height = value;
754 break;
755 case GL_UNPACK_SKIP_PIXELS:
756 m_pixelStore.unpack_skip_pixels = value;
757 break;
758 case GL_UNPACK_SKIP_ROWS:
759 m_pixelStore.unpack_skip_rows = value;
760 break;
761 case GL_UNPACK_SKIP_IMAGES:
762 m_pixelStore.unpack_skip_images = value;
763 break;
764 case GL_PACK_ROW_LENGTH:
765 m_pixelStore.pack_row_length = value;
766 break;
767 case GL_PACK_SKIP_PIXELS:
768 m_pixelStore.pack_skip_pixels = value;
769 break;
770 case GL_PACK_SKIP_ROWS:
771 m_pixelStore.pack_skip_rows = value;
772 break;
773 default:
774 retval = GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800775 }
776 return retval;
777}
778
779
Lingfeng Yang74e29292017-01-10 14:54:38 -0800780size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
keunyoungb85b2752013-03-08 12:28:03 -0800781{
Lingfeng Yang74e29292017-01-10 14:54:38 -0800782 if (width <= 0 || height <= 0 || depth <= 0) return 0;
bohubd119bf2014-10-17 13:48:06 -0700783
Lingfeng Yang74e29292017-01-10 14:54:38 -0800784 ALOGV("%s: pack? %d", __FUNCTION__, pack);
785 if (pack) {
786 ALOGV("%s: pack stats", __FUNCTION__);
787 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
788 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
789 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
790 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
791 } else {
792 ALOGV("%s: unpack stats", __FUNCTION__);
793 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
794 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
795 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
796 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
797 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
798 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800799 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800800 return GLESTextureUtils::computeTotalImageSize(
801 width, height, depth,
802 format, type,
803 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
804 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
805 pack ? 0 : m_pixelStore.unpack_image_height,
806 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
807 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
808 pack ? 0 : m_pixelStore.unpack_skip_images);
809}
810
811size_t GLClientState::pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const
812{
813 if (width <= 0 || height <= 0 || depth <= 0) return 0;
814
815 ALOGV("%s: pack? %d", __FUNCTION__, pack);
816 if (pack) {
817 ALOGV("%s: pack stats", __FUNCTION__);
818 ALOGV("%s: pack align %d", __FUNCTION__, m_pixelStore.pack_alignment);
819 ALOGV("%s: pack rowlen %d", __FUNCTION__, m_pixelStore.pack_row_length);
820 ALOGV("%s: pack skippixels %d", __FUNCTION__, m_pixelStore.pack_skip_pixels);
821 ALOGV("%s: pack skiprows %d", __FUNCTION__, m_pixelStore.pack_skip_rows);
822 } else {
823 ALOGV("%s: unpack stats", __FUNCTION__);
824 ALOGV("%s: unpack align %d", __FUNCTION__, m_pixelStore.unpack_alignment);
825 ALOGV("%s: unpack rowlen %d", __FUNCTION__, m_pixelStore.unpack_row_length);
826 ALOGV("%s: unpack imgheight %d", __FUNCTION__, m_pixelStore.unpack_image_height);
827 ALOGV("%s: unpack skippixels %d", __FUNCTION__, m_pixelStore.unpack_skip_pixels);
828 ALOGV("%s: unpack skiprows %d", __FUNCTION__, m_pixelStore.unpack_skip_rows);
829 ALOGV("%s: unpack skipimages %d", __FUNCTION__, m_pixelStore.unpack_skip_images);
keunyoungb85b2752013-03-08 12:28:03 -0800830 }
Lingfeng Yang74e29292017-01-10 14:54:38 -0800831 return GLESTextureUtils::computeNeededBufferSize(
832 width, height, depth,
833 format, type,
834 pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment,
835 pack ? m_pixelStore.pack_row_length : m_pixelStore.unpack_row_length,
836 pack ? 0 : m_pixelStore.unpack_image_height,
837 pack ? m_pixelStore.pack_skip_pixels : m_pixelStore.unpack_skip_pixels,
838 pack ? m_pixelStore.pack_skip_rows : m_pixelStore.unpack_skip_rows,
839 pack ? 0 : m_pixelStore.unpack_skip_images);
840}
841
842
843size_t GLClientState::clearBufferNumElts(GLenum buffer) const
844{
845 switch (buffer) {
846 case GL_COLOR:
847 return 4;
848 case GL_DEPTH:
849 case GL_STENCIL:
850 return 1;
851 }
852 return 1;
853}
854
Lingfeng Yang22dc42d2018-05-29 10:11:38 -0700855void GLClientState::getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const
856{
857 if (width <= 0 || height <= 0) {
858 *startOffset = 0;
859 *pixelRowSize = 0;
860 *totalRowSize = 0;
861 return;
862 }
863
864 GLESTextureUtils::computePackingOffsets2D(
865 width, height,
866 format, type,
867 m_pixelStore.pack_alignment,
868 m_pixelStore.pack_row_length,
869 m_pixelStore.pack_skip_pixels,
870 m_pixelStore.pack_skip_rows,
871 startOffset,
872 pixelRowSize,
873 totalRowSize);
874
875 *skipRows = m_pixelStore.pack_skip_rows;
876}
877
Lingfeng Yang74e29292017-01-10 14:54:38 -0800878void GLClientState::setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms) {
879 UniformBlockInfoKey key;
880 key.program = program;
881 key.uniformBlockIndex = uniformBlockIndex;
882
883 UniformBlockUniformInfo info;
884 info.numActiveUniforms = (size_t)numActiveUniforms;
885
886 m_uniformBlockInfoMap[key] = info;
887}
888
889size_t GLClientState::numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const {
890 UniformBlockInfoKey key;
891 key.program = program;
892 key.uniformBlockIndex = uniformBlockIndex;
893 UniformBlockInfoMap::const_iterator it =
894 m_uniformBlockInfoMap.find(key);
895 if (it == m_uniformBlockInfoMap.end()) return 0;
896 return it->second.numActiveUniforms;
897}
898
Lingfeng Yangb3dc29f2017-01-09 13:25:31 -0800899void GLClientState::associateProgramWithPipeline(GLuint program, GLuint pipeline) {
900 m_programPipelines[program] = pipeline;
901}
902
903GLClientState::ProgramPipelineIterator GLClientState::programPipelineBegin() {
904 return m_programPipelines.begin();
905}
906
907GLClientState::ProgramPipelineIterator GLClientState::programPipelineEnd() {
908 return m_programPipelines.end();
keunyoungb85b2752013-03-08 12:28:03 -0800909}
910
911GLenum GLClientState::setActiveTextureUnit(GLenum texture)
912{
913 GLuint unit = texture - GL_TEXTURE0;
914 if (unit >= MAX_TEXTURE_UNITS) {
Yahan Zhoudb856572016-03-01 12:03:48 -0800915 return GL_INVALID_ENUM;
keunyoungb85b2752013-03-08 12:28:03 -0800916 }
917 m_tex.activeUnit = &m_tex.unit[unit];
918 return GL_NO_ERROR;
919}
920
921GLenum GLClientState::getActiveTextureUnit() const
922{
923 return GL_TEXTURE0 + (m_tex.activeUnit - &m_tex.unit[0]);
924}
925
926void GLClientState::enableTextureTarget(GLenum target)
927{
928 switch (target) {
929 case GL_TEXTURE_2D:
930 m_tex.activeUnit->enables |= (1u << TEXTURE_2D);
931 break;
932 case GL_TEXTURE_EXTERNAL_OES:
933 m_tex.activeUnit->enables |= (1u << TEXTURE_EXTERNAL);
934 break;
935 }
936}
937
938void GLClientState::disableTextureTarget(GLenum target)
939{
940 switch (target) {
941 case GL_TEXTURE_2D:
942 m_tex.activeUnit->enables &= ~(1u << TEXTURE_2D);
943 break;
944 case GL_TEXTURE_EXTERNAL_OES:
945 m_tex.activeUnit->enables &= ~(1u << TEXTURE_EXTERNAL);
946 break;
947 }
948}
949
Lingfeng Yang554a5152019-02-21 20:20:48 -0800950void GLClientState::bindSampler(GLuint unit, GLuint sampler) {
951 m_tex.unit[unit].boundSampler = sampler;
952}
953
954bool GLClientState::isSamplerBindNoOp(GLuint unit, GLuint sampler) {
955 return m_tex.unit[unit].boundSampler == sampler;
956}
957
958void GLClientState::onDeleteSamplers(GLsizei n, const GLuint* samplers) {
959 for (uint32_t i = 0; i < n; ++i) {
960 for (uint32_t j = 0; j < MAX_TEXTURE_UNITS; ++j) {
961 uint32_t currentSampler = m_tex.unit[j].boundSampler;
962 if (currentSampler == samplers[i]) {
963 m_tex.unit[j].boundSampler = 0;
964 }
965 }
966 }
967}
968
keunyoungb85b2752013-03-08 12:28:03 -0800969GLenum GLClientState::getPriorityEnabledTarget(GLenum allDisabled) const
970{
971 unsigned int enables = m_tex.activeUnit->enables;
972 if (enables & (1u << TEXTURE_EXTERNAL)) {
973 return GL_TEXTURE_EXTERNAL_OES;
974 } else if (enables & (1u << TEXTURE_2D)) {
975 return GL_TEXTURE_2D;
976 } else {
977 return allDisabled;
978 }
979}
980
981int GLClientState::compareTexId(const void* pid, const void* prec)
982{
983 const GLuint* id = (const GLuint*)pid;
984 const TextureRec* rec = (const TextureRec*)prec;
985 return (GLint)(*id) - (GLint)rec->id;
986}
987
988GLenum GLClientState::bindTexture(GLenum target, GLuint texture,
989 GLboolean* firstUse)
990{
991 GLboolean first = GL_FALSE;
Lingfeng Yang74e29292017-01-10 14:54:38 -0800992
993 TextureRec* texrec = getTextureRec(texture);
994 if (!texrec) {
995 texrec = addTextureRec(texture, target);
996 }
997
998 if (texture && target != texrec->target &&
999 (target != GL_TEXTURE_EXTERNAL_OES &&
1000 texrec->target != GL_TEXTURE_EXTERNAL_OES)) {
1001 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 -08001002 }
1003
1004 switch (target) {
1005 case GL_TEXTURE_2D:
1006 m_tex.activeUnit->texture[TEXTURE_2D] = texture;
1007 break;
1008 case GL_TEXTURE_EXTERNAL_OES:
1009 m_tex.activeUnit->texture[TEXTURE_EXTERNAL] = texture;
1010 break;
Lingfeng Yang74e29292017-01-10 14:54:38 -08001011 case GL_TEXTURE_CUBE_MAP:
1012 m_tex.activeUnit->texture[TEXTURE_CUBE_MAP] = texture;
1013 break;
1014 case GL_TEXTURE_2D_ARRAY:
1015 m_tex.activeUnit->texture[TEXTURE_2D_ARRAY] = texture;
1016 break;
1017 case GL_TEXTURE_3D:
1018 m_tex.activeUnit->texture[TEXTURE_3D] = texture;
1019 break;
1020 case GL_TEXTURE_2D_MULTISAMPLE:
1021 m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE] = texture;
1022 break;
keunyoungb85b2752013-03-08 12:28:03 -08001023 }
1024
1025 if (firstUse) {
1026 *firstUse = first;
1027 }
1028
1029 return GL_NO_ERROR;
1030}
1031
Lingfeng Yang74e29292017-01-10 14:54:38 -08001032void GLClientState::setBoundEGLImage(GLenum target, GLeglImageOES image) {
Lingfeng Yang764a1fc2019-08-22 12:16:11 -07001033 (void)image;
1034
Lingfeng Yang74e29292017-01-10 14:54:38 -08001035 GLuint texture = getBoundTexture(target);
1036 TextureRec* texrec = getTextureRec(texture);
1037 if (!texrec) return;
1038 texrec->boundEGLImage = true;
1039}
1040
1041TextureRec* GLClientState::addTextureRec(GLuint id, GLenum target)
keunyoungb85b2752013-03-08 12:28:03 -08001042{
Lingfeng Yang74e29292017-01-10 14:54:38 -08001043 TextureRec* tex = new TextureRec;
keunyoungb85b2752013-03-08 12:28:03 -08001044 tex->id = id;
1045 tex->target = target;
Lingfeng Yang69066602016-04-12 09:29:11 -07001046 tex->format = -1;
Lingfeng Yang74e29292017-01-10 14:54:38 -08001047 tex->multisamples = 0;
1048 tex->immutable = false;
1049 tex->boundEGLImage = false;
1050 tex->dims = new TextureDims;
keunyoungb85b2752013-03-08 12:28:03 -08001051
Lingfeng Yang74e29292017-01-10 14:54:38 -08001052 (*(m_tex.textureRecs))[id] = tex;
keunyoungb85b2752013-03-08 12:28:03 -08001053 return tex;
1054}
1055
Lingfeng Yang74e29292017-01-10 14:54:38 -08001056TextureRec* GLClientState::getTextureRec(GLuint id) const {
1057 SharedTextureDataMap::const_iterator it =
1058 m_tex.textureRecs->find(id);
1059 if (it == m_tex.textureRecs->end()) {
1060 return NULL;
1061 }
1062 return it->second;
1063}
1064
Lingfeng Yang69066602016-04-12 09:29:11 -07001065void GLClientState::setBoundTextureInternalFormat(GLenum target, GLint internalformat) {
1066 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -08001067 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001068 if (!texrec) return;
1069 texrec->internalformat = internalformat;
1070}
1071
1072void GLClientState::setBoundTextureFormat(GLenum target, GLenum format) {
1073 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -08001074 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001075 if (!texrec) return;
1076 texrec->format = format;
1077}
1078
1079void GLClientState::setBoundTextureType(GLenum target, GLenum type) {
1080 GLuint texture = getBoundTexture(target);
Lingfeng Yang74e29292017-01-10 14:54:38 -08001081 TextureRec* texrec = getTextureRec(texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001082 if (!texrec) return;
1083 texrec->type = type;
1084}
1085
Lingfeng Yang74e29292017-01-10 14:54:38 -08001086void GLClientState::setBoundTextureDims(GLenum target, GLsizei level, GLsizei width, GLsizei height, GLsizei depth) {
1087 GLuint texture = getBoundTexture(target);
1088 TextureRec* texrec = getTextureRec(texture);
1089 if (!texrec) {
1090 return;
1091 }
1092
1093 if (level == -1) {
1094 GLsizei curr_width = width;
1095 GLsizei curr_height = height;
1096 GLsizei curr_depth = depth;
1097 GLsizei curr_level = 0;
1098
1099 while (true) {
1100 texrec->dims->widths[curr_level] = curr_width;
1101 texrec->dims->heights[curr_level] = curr_height;
1102 texrec->dims->depths[curr_level] = curr_depth;
1103 if (curr_width >> 1 == 0 &&
1104 curr_height >> 1 == 0 &&
1105 ((target == GL_TEXTURE_3D && curr_depth == 0) ||
1106 true)) {
1107 break;
1108 }
1109 curr_width = (curr_width >> 1) ? (curr_width >> 1) : 1;
1110 curr_height = (curr_height >> 1) ? (curr_height >> 1) : 1;
1111 if (target == GL_TEXTURE_3D) {
1112 curr_depth = (curr_depth >> 1) ? (curr_depth >> 1) : 1;
1113 }
1114 curr_level++;
1115 }
1116
1117 } else {
1118 texrec->dims->widths[level] = width;
1119 texrec->dims->heights[level] = height;
1120 texrec->dims->depths[level] = depth;
1121 }
1122}
1123
1124void GLClientState::setBoundTextureSamples(GLenum target, GLsizei samples) {
1125 GLuint texture = getBoundTexture(target);
1126 TextureRec* texrec = getTextureRec(texture);
1127 if (!texrec) return;
1128 texrec->multisamples = samples;
1129}
1130
1131void GLClientState::setBoundTextureImmutableFormat(GLenum target) {
1132 GLuint texture = getBoundTexture(target);
1133 TextureRec* texrec = getTextureRec(texture);
1134 if (!texrec) return;
1135 texrec->immutable = true;
1136}
1137
1138bool GLClientState::isBoundTextureImmutableFormat(GLenum target) const {
1139 GLuint texture = getBoundTexture(target);
1140 TextureRec* texrec = getTextureRec(texture);
1141 if (!texrec) return false;
1142 return texrec->immutable;
1143}
1144
keunyoungb85b2752013-03-08 12:28:03 -08001145GLuint GLClientState::getBoundTexture(GLenum target) const
1146{
1147 switch (target) {
1148 case GL_TEXTURE_2D:
1149 return m_tex.activeUnit->texture[TEXTURE_2D];
1150 case GL_TEXTURE_EXTERNAL_OES:
1151 return m_tex.activeUnit->texture[TEXTURE_EXTERNAL];
Lingfeng Yang74e29292017-01-10 14:54:38 -08001152 case GL_TEXTURE_CUBE_MAP:
1153 return m_tex.activeUnit->texture[TEXTURE_CUBE_MAP];
1154 case GL_TEXTURE_2D_ARRAY:
1155 return m_tex.activeUnit->texture[TEXTURE_2D_ARRAY];
1156 case GL_TEXTURE_3D:
1157 return m_tex.activeUnit->texture[TEXTURE_3D];
1158 case GL_TEXTURE_2D_MULTISAMPLE:
1159 return m_tex.activeUnit->texture[TEXTURE_2D_MULTISAMPLE];
keunyoungb85b2752013-03-08 12:28:03 -08001160 default:
1161 return 0;
1162 }
1163}
1164
Lingfeng Yange00ec9d2016-09-16 08:54:03 -07001165// BEGIN driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1166// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
1167
1168static bool unreliableInternalFormat(GLenum internalformat) {
1169 switch (internalformat) {
1170 case GL_LUMINANCE:
1171 return true;
1172 default:
1173 return false;
1174 }
1175}
1176
1177void GLClientState::writeCopyTexImageState
1178 (GLenum target, GLint level, GLenum internalformat) {
1179 if (unreliableInternalFormat(internalformat)) {
1180 CubeMapDef entry;
1181 entry.id = getBoundTexture(GL_TEXTURE_2D);
1182 entry.target = target;
1183 entry.level = level;
1184 entry.internalformat = internalformat;
1185 m_cubeMapDefs.insert(entry);
1186 }
1187}
1188
1189static GLenum identifyPositiveCubeMapComponent(GLenum target) {
1190 switch (target) {
1191 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1192 return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
1193 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1194 return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
1195 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1196 return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
1197 default:
1198 return 0;
1199 }
1200}
1201
1202GLenum GLClientState::copyTexImageNeededTarget
1203 (GLenum target, GLint level, GLenum internalformat) {
1204 if (unreliableInternalFormat(internalformat)) {
1205 GLenum positiveComponent =
1206 identifyPositiveCubeMapComponent(target);
1207 if (positiveComponent) {
1208 CubeMapDef query;
1209 query.id = getBoundTexture(GL_TEXTURE_2D);
1210 query.target = positiveComponent;
1211 query.level = level;
1212 query.internalformat = internalformat;
1213 if (m_cubeMapDefs.find(query) ==
1214 m_cubeMapDefs.end()) {
1215 return positiveComponent;
1216 }
1217 }
1218 }
1219 return 0;
1220}
1221
1222GLenum GLClientState::copyTexImageLuminanceCubeMapAMDWorkaround
1223 (GLenum target, GLint level, GLenum internalformat) {
1224 writeCopyTexImageState(target, level, internalformat);
1225 return copyTexImageNeededTarget(target, level, internalformat);
1226}
1227
1228// (>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')><(' '<)(>' ')>
1229// END driver workarounds-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
1230
keunyoungb85b2752013-03-08 12:28:03 -08001231void GLClientState::deleteTextures(GLsizei n, const GLuint* textures)
1232{
1233 // Updating the textures array could be made more efficient when deleting
1234 // several textures:
1235 // - compacting the array could be done in a single pass once the deleted
1236 // textures are marked, or
1237 // - could swap deleted textures to the end and re-sort.
1238 TextureRec* texrec;
1239 for (const GLuint* texture = textures; texture != textures + n; texture++) {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001240 texrec = getTextureRec(*texture);
1241 if (texrec && texrec->dims) {
1242 delete texrec->dims;
1243 }
keunyoungb85b2752013-03-08 12:28:03 -08001244 if (texrec) {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001245 m_tex.textureRecs->erase(*texture);
1246 delete texrec;
keunyoungb85b2752013-03-08 12:28:03 -08001247 for (TextureUnit* unit = m_tex.unit;
1248 unit != m_tex.unit + MAX_TEXTURE_UNITS;
1249 unit++)
1250 {
1251 if (unit->texture[TEXTURE_2D] == *texture) {
1252 unit->texture[TEXTURE_2D] = 0;
1253 } else if (unit->texture[TEXTURE_EXTERNAL] == *texture) {
1254 unit->texture[TEXTURE_EXTERNAL] = 0;
1255 }
1256 }
1257 }
1258 }
1259}
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001260
1261// RBO//////////////////////////////////////////////////////////////////////////
1262
1263void GLClientState::addFreshRenderbuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001264 // if underlying opengl says these are fresh names,
1265 // but we are keeping a stale one, reset it.
1266 RboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001267 props.target = GL_RENDERBUFFER;
1268 props.name = name;
Lingfeng Yang69066602016-04-12 09:29:11 -07001269 props.format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001270 props.multisamples = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001271 props.previouslyBound = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001272
1273 if (usedRenderbufferName(name)) {
1274 mRboState.rboData[getRboIndex(name)] = props;
1275 } else {
1276 mRboState.rboData.push_back(props);
1277 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001278}
1279
1280void GLClientState::addRenderbuffers(GLsizei n, GLuint* renderbuffers) {
1281 for (size_t i = 0; i < n; i++) {
1282 addFreshRenderbuffer(renderbuffers[i]);
1283 }
1284}
1285
1286size_t GLClientState::getRboIndex(GLuint name) const {
1287 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1288 if (mRboState.rboData[i].name == name) {
1289 return i;
1290 }
1291 }
1292 return -1;
1293}
1294
1295void GLClientState::removeRenderbuffers(GLsizei n, const GLuint* renderbuffers) {
1296 size_t bound_rbo_idx = getRboIndex(boundRboProps_const().name);
1297
1298 std::vector<GLuint> to_remove;
1299 for (size_t i = 0; i < n; i++) {
1300 if (renderbuffers[i] != 0) { // Never remove the zero rb.
1301 to_remove.push_back(getRboIndex(renderbuffers[i]));
1302 }
1303 }
1304
1305 for (size_t i = 0; i < to_remove.size(); i++) {
1306 mRboState.rboData[to_remove[i]] = mRboState.rboData.back();
1307 mRboState.rboData.pop_back();
1308 }
1309
1310 // If we just deleted the currently bound rb,
1311 // bind the zero rb
1312 if (getRboIndex(boundRboProps_const().name) != bound_rbo_idx) {
1313 bindRenderbuffer(GL_RENDERBUFFER, 0);
1314 }
1315}
1316
1317bool GLClientState::usedRenderbufferName(GLuint name) const {
1318 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1319 if (mRboState.rboData[i].name == name) {
1320 return true;
1321 }
1322 }
1323 return false;
1324}
1325
1326void GLClientState::setBoundRenderbufferIndex() {
1327 for (size_t i = 0; i < mRboState.rboData.size(); i++) {
1328 if (mRboState.rboData[i].name == mRboState.boundRenderbuffer) {
1329 mRboState.boundRenderbufferIndex = i;
1330 break;
1331 }
1332 }
1333}
1334
1335RboProps& GLClientState::boundRboProps() {
1336 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1337}
1338
1339const RboProps& GLClientState::boundRboProps_const() const {
1340 return mRboState.rboData[mRboState.boundRenderbufferIndex];
1341}
1342
1343void GLClientState::bindRenderbuffer(GLenum target, GLuint name) {
1344 // If unused, add it.
1345 if (!usedRenderbufferName(name)) {
1346 addFreshRenderbuffer(name);
1347 }
1348 mRboState.boundRenderbuffer = name;
1349 setBoundRenderbufferIndex();
1350 boundRboProps().target = target;
1351 boundRboProps().previouslyBound = true;
1352}
1353
1354GLuint GLClientState::boundRenderbuffer() const {
1355 return boundRboProps_const().name;
1356}
1357
Lingfeng Yang69066602016-04-12 09:29:11 -07001358void GLClientState::setBoundRenderbufferFormat(GLenum format) {
1359 boundRboProps().format = format;
1360}
1361
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001362void GLClientState::setBoundRenderbufferSamples(GLsizei samples) {
1363 boundRboProps().multisamples = samples;
1364}
1365
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001366// FBO//////////////////////////////////////////////////////////////////////////
1367
Lingfeng Yang69066602016-04-12 09:29:11 -07001368// Format querying
1369
1370GLenum GLClientState::queryRboFormat(GLuint rbo_name) const {
1371 return mRboState.rboData[getRboIndex(rbo_name)].format;
1372}
1373
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001374GLsizei GLClientState::queryRboSamples(GLuint rbo_name) const {
1375 return mRboState.rboData[getRboIndex(rbo_name)].multisamples;
1376}
1377
Lingfeng Yang69066602016-04-12 09:29:11 -07001378GLint GLClientState::queryTexInternalFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001379 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001380 if (!texrec) return -1;
1381 return texrec->internalformat;
1382}
1383
Lingfeng Yang74e29292017-01-10 14:54:38 -08001384GLsizei GLClientState::queryTexWidth(GLsizei level, GLuint tex_name) const {
1385 TextureRec* texrec = getTextureRec(tex_name);
1386 if (!texrec) {
1387 return 0;
1388 }
1389 return texrec->dims->widths[level];
1390}
1391
1392GLsizei GLClientState::queryTexHeight(GLsizei level, GLuint tex_name) const {
1393 TextureRec* texrec = getTextureRec(tex_name);
1394 if (!texrec) return 0;
1395 return texrec->dims->heights[level];
1396}
1397
1398GLsizei GLClientState::queryTexDepth(GLsizei level, GLuint tex_name) const {
1399 TextureRec* texrec = getTextureRec(tex_name);
1400 if (!texrec) return 0;
1401 return texrec->dims->depths[level];
1402}
1403
1404bool GLClientState::queryTexEGLImageBacked(GLuint tex_name) const {
1405 TextureRec* texrec = getTextureRec(tex_name);
1406 if (!texrec) return false;
1407 return texrec->boundEGLImage;
1408}
1409
Lingfeng Yang69066602016-04-12 09:29:11 -07001410GLenum GLClientState::queryTexFormat(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001411 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001412 if (!texrec) return -1;
1413 return texrec->format;
1414}
1415
1416GLenum GLClientState::queryTexType(GLuint tex_name) const {
Lingfeng Yang74e29292017-01-10 14:54:38 -08001417 TextureRec* texrec = getTextureRec(tex_name);
Lingfeng Yang69066602016-04-12 09:29:11 -07001418 if (!texrec) return -1;
1419 return texrec->type;
1420}
1421
Lingfeng Yang74e29292017-01-10 14:54:38 -08001422GLsizei GLClientState::queryTexSamples(GLuint tex_name) const {
1423 TextureRec* texrec = getTextureRec(tex_name);
1424 if (!texrec) return 0;
1425 return texrec->multisamples;
1426}
1427
1428GLenum GLClientState::queryTexLastBoundTarget(GLuint tex_name) const {
1429 TextureRec* texrec = getTextureRec(tex_name);
1430 if (!texrec) return GL_NONE;
1431 return texrec->target;
1432}
1433
Lingfeng Yang69066602016-04-12 09:29:11 -07001434void GLClientState::getBoundFramebufferFormat(
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001435 GLenum target,
Lingfeng Yang69066602016-04-12 09:29:11 -07001436 GLenum attachment, FboFormatInfo* res_info) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001437 const FboProps& props = boundFboProps_const(target);
Lingfeng Yang69066602016-04-12 09:29:11 -07001438
1439 res_info->type = FBO_ATTACHMENT_NONE;
1440 res_info->rb_format = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001441 res_info->rb_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001442 res_info->tex_internalformat = -1;
1443 res_info->tex_format = GL_NONE;
1444 res_info->tex_type = GL_NONE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001445 res_info->tex_multisamples = 0;
Lingfeng Yang69066602016-04-12 09:29:11 -07001446
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001447 int colorAttachmentIndex =
1448 glUtilsColorAttachmentIndex(attachment);
1449
1450 if (colorAttachmentIndex != -1) {
1451 if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001452 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001453 res_info->rb_format =
1454 queryRboFormat(
1455 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1456 res_info->rb_multisamples =
1457 queryRboSamples(
1458 props.colorAttachmenti_rbos[colorAttachmentIndex]);
1459 } else if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001460 res_info->type = FBO_ATTACHMENT_TEXTURE;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001461 res_info->tex_internalformat =
1462 queryTexInternalFormat(
1463 props.colorAttachmenti_textures[colorAttachmentIndex]);
1464 res_info->tex_format =
1465 queryTexFormat(
1466 props.colorAttachmenti_textures[colorAttachmentIndex]);
1467 res_info->tex_type =
1468 queryTexType(props.colorAttachmenti_textures[colorAttachmentIndex]);
1469 res_info->tex_multisamples =
1470 queryTexSamples(props.colorAttachmenti_textures[colorAttachmentIndex]);
Lingfeng Yang69066602016-04-12 09:29:11 -07001471 } else {
1472 res_info->type = FBO_ATTACHMENT_NONE;
1473 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001474 }
1475
1476 switch (attachment) {
Lingfeng Yang69066602016-04-12 09:29:11 -07001477 case GL_DEPTH_ATTACHMENT:
1478 if (props.depthAttachment_hasRbo) {
1479 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1480 res_info->rb_format = queryRboFormat(props.depthAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001481 res_info->rb_multisamples =
1482 queryRboSamples(
Lingfeng Yang400bc512018-10-12 12:39:17 -07001483 props.depthAttachment_rbo);
Lingfeng Yang69066602016-04-12 09:29:11 -07001484 } else if (props.depthAttachment_hasTexObj) {
1485 res_info->type = FBO_ATTACHMENT_TEXTURE;
1486 res_info->tex_internalformat = queryTexInternalFormat(props.depthAttachment_texture);
1487 res_info->tex_format = queryTexFormat(props.depthAttachment_texture);
1488 res_info->tex_type = queryTexType(props.depthAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001489 res_info->tex_multisamples =
Lingfeng Yang400bc512018-10-12 12:39:17 -07001490 queryTexSamples(props.depthAttachment_texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001491 } else {
1492 res_info->type = FBO_ATTACHMENT_NONE;
1493 }
1494 break;
1495 case GL_STENCIL_ATTACHMENT:
1496 if (props.stencilAttachment_hasRbo) {
1497 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1498 res_info->rb_format = queryRboFormat(props.stencilAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001499 res_info->rb_multisamples =
1500 queryRboSamples(
Lingfeng Yang400bc512018-10-12 12:39:17 -07001501 props.stencilAttachment_rbo);
Lingfeng Yang69066602016-04-12 09:29:11 -07001502 } else if (props.stencilAttachment_hasTexObj) {
1503 res_info->type = FBO_ATTACHMENT_TEXTURE;
1504 res_info->tex_internalformat = queryTexInternalFormat(props.stencilAttachment_texture);
1505 res_info->tex_format = queryTexFormat(props.stencilAttachment_texture);
1506 res_info->tex_type = queryTexType(props.stencilAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001507 res_info->tex_multisamples =
Lingfeng Yang400bc512018-10-12 12:39:17 -07001508 queryTexSamples(props.stencilAttachment_texture);
Lingfeng Yang69066602016-04-12 09:29:11 -07001509 } else {
1510 res_info->type = FBO_ATTACHMENT_NONE;
1511 }
1512 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001513 case GL_DEPTH_STENCIL_ATTACHMENT:
1514 if (props.depthstencilAttachment_hasRbo) {
1515 res_info->type = FBO_ATTACHMENT_RENDERBUFFER;
1516 res_info->rb_format = queryRboFormat(props.depthstencilAttachment_rbo);
1517 res_info->rb_multisamples =
1518 queryRboSamples(
Lingfeng Yang400bc512018-10-12 12:39:17 -07001519 props.depthstencilAttachment_rbo);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001520 } else if (props.depthstencilAttachment_hasTexObj) {
1521 res_info->type = FBO_ATTACHMENT_TEXTURE;
1522 res_info->tex_internalformat = queryTexInternalFormat(props.depthstencilAttachment_texture);
1523 res_info->tex_format = queryTexFormat(props.depthstencilAttachment_texture);
1524 res_info->tex_type = queryTexType(props.depthstencilAttachment_texture);
1525 res_info->tex_multisamples =
Lingfeng Yang400bc512018-10-12 12:39:17 -07001526 queryTexSamples(props.depthstencilAttachment_texture);
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001527 } else {
1528 res_info->type = FBO_ATTACHMENT_NONE;
1529 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001530 break;
1531 }
1532}
1533
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001534FboAttachmentType GLClientState::getBoundFramebufferAttachmentType(GLenum target, GLenum attachment) const {
1535 FboFormatInfo info;
1536 getBoundFramebufferFormat(target, attachment, &info);
1537 return info.type;
1538}
1539
1540
1541int GLClientState::getMaxColorAttachments() const {
1542 return m_max_color_attachments;
1543}
1544
1545int GLClientState::getMaxDrawBuffers() const {
1546 return m_max_draw_buffers;
1547}
1548
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001549void GLClientState::addFreshFramebuffer(GLuint name) {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001550 FboProps props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001551 props.name = name;
1552 props.previouslyBound = false;
1553
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001554 props.colorAttachmenti_textures.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001555 props.depthAttachment_texture = 0;
1556 props.stencilAttachment_texture = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001557 props.depthstencilAttachment_texture = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001558
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001559 props.colorAttachmenti_hasTex.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001560 props.depthAttachment_hasTexObj = false;
1561 props.stencilAttachment_hasTexObj = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001562 props.depthstencilAttachment_hasTexObj = false;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001563
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001564 props.colorAttachmenti_rbos.resize(m_max_color_attachments, 0);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001565 props.depthAttachment_rbo = 0;
1566 props.stencilAttachment_rbo = 0;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001567 props.depthstencilAttachment_rbo = 0;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001568
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001569 props.colorAttachmenti_hasRbo.resize(m_max_color_attachments, false);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001570 props.depthAttachment_hasRbo = false;
1571 props.stencilAttachment_hasRbo = false;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001572 props.depthstencilAttachment_hasRbo = false;
1573 mFboState.fboData[name] = props;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001574}
1575
1576void GLClientState::addFramebuffers(GLsizei n, GLuint* framebuffers) {
1577 for (size_t i = 0; i < n; i++) {
1578 addFreshFramebuffer(framebuffers[i]);
1579 }
1580}
1581
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001582void GLClientState::removeFramebuffers(GLsizei n, const GLuint* framebuffers) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001583 for (size_t i = 0; i < n; i++) {
1584 if (framebuffers[i] != 0) { // Never remove the zero fb.
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001585 if (framebuffers[i] == mFboState.boundDrawFramebuffer) {
1586 bindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
1587 }
1588 if (framebuffers[i] == mFboState.boundReadFramebuffer) {
1589 bindFramebuffer(GL_READ_FRAMEBUFFER, 0);
1590 }
1591 mFboState.fboData.erase(framebuffers[i]);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001592 }
1593 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001594}
1595
1596bool GLClientState::usedFramebufferName(GLuint name) const {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001597 return mFboState.fboData.find(name) != mFboState.fboData.end();
1598}
1599
1600FboProps& GLClientState::boundFboProps(GLenum target) {
1601 switch (target) {
1602 case GL_DRAW_FRAMEBUFFER:
1603 return mFboState.fboData[mFboState.boundDrawFramebuffer];
1604 case GL_READ_FRAMEBUFFER:
1605 return mFboState.fboData[mFboState.boundReadFramebuffer];
1606 case GL_FRAMEBUFFER:
1607 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001608 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001609 return mFboState.fboData[mFboState.boundDrawFramebuffer];
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001610}
1611
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001612const FboProps& GLClientState::boundFboProps_const(GLenum target) const {
1613 switch (target) {
1614 case GL_DRAW_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001615 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001616 case GL_READ_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001617 return mFboState.fboData.find(mFboState.boundReadFramebuffer)->second;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001618 case GL_FRAMEBUFFER:
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001619 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001620 }
Lingfeng Yang26a8b4b2017-01-11 17:06:42 -08001621 return mFboState.fboData.find(mFboState.boundDrawFramebuffer)->second;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001622}
1623
1624void GLClientState::bindFramebuffer(GLenum target, GLuint name) {
1625 // If unused, add it.
1626 if (!usedFramebufferName(name)) {
1627 addFreshFramebuffer(name);
1628 }
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001629 switch (target) {
1630 case GL_DRAW_FRAMEBUFFER:
1631 mFboState.boundDrawFramebuffer = name;
1632 break;
1633 case GL_READ_FRAMEBUFFER:
1634 mFboState.boundReadFramebuffer = name;
1635 break;
1636 default: // case GL_FRAMEBUFFER:
1637 mFboState.boundDrawFramebuffer = name;
1638 mFboState.boundReadFramebuffer = name;
1639 break;
1640 }
1641 boundFboProps(target).previouslyBound = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001642}
1643
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001644void GLClientState::setCheckFramebufferStatus(GLenum target, GLenum status) {
1645 switch (target) {
1646 case GL_DRAW_FRAMEBUFFER:
1647 mFboState.drawFboCheckStatus = status;
1648 break;
1649 case GL_READ_FRAMEBUFFER:
1650 mFboState.readFboCheckStatus = status;
1651 break;
1652 case GL_FRAMEBUFFER:
1653 mFboState.drawFboCheckStatus = status;
1654 break;
1655 }
Lingfeng Yang69066602016-04-12 09:29:11 -07001656}
1657
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001658GLenum GLClientState::getCheckFramebufferStatus(GLenum target) const {
1659 switch (target) {
1660 case GL_DRAW_FRAMEBUFFER:
1661 return mFboState.drawFboCheckStatus;
1662 case GL_READ_FRAMEBUFFER:
1663 return mFboState.readFboCheckStatus;
1664 case GL_FRAMEBUFFER:
1665 return mFboState.drawFboCheckStatus;
1666 }
1667 return mFboState.drawFboCheckStatus;
Lingfeng Yang69066602016-04-12 09:29:11 -07001668}
1669
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001670GLuint GLClientState::boundFramebuffer(GLenum target) const {
1671 return boundFboProps_const(target).name;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001672}
1673
1674// Texture objects for FBOs/////////////////////////////////////////////////////
1675
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001676void GLClientState::attachTextureObject(
1677 GLenum target,
1678 GLenum attachment, GLuint texture) {
1679
1680 int colorAttachmentIndex =
1681 glUtilsColorAttachmentIndex(attachment);
1682
1683 if (colorAttachmentIndex != -1) {
1684 boundFboProps(target).colorAttachmenti_textures[colorAttachmentIndex] = texture;
1685 boundFboProps(target).colorAttachmenti_hasTex[colorAttachmentIndex] = true;
1686 }
1687
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001688 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001689 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001690 boundFboProps(target).depthAttachment_texture = texture;
1691 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001692 break;
1693 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001694 boundFboProps(target).stencilAttachment_texture = texture;
1695 boundFboProps(target).stencilAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001696 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001697 case GL_DEPTH_STENCIL_ATTACHMENT:
1698 boundFboProps(target).depthstencilAttachment_texture = texture;
1699 boundFboProps(target).depthstencilAttachment_hasTexObj = true;
1700 boundFboProps(target).stencilAttachment_texture = texture;
1701 boundFboProps(target).stencilAttachment_hasTexObj = true;
1702 boundFboProps(target).depthAttachment_texture = texture;
1703 boundFboProps(target).depthAttachment_hasTexObj = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001704 break;
1705 }
1706}
1707
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001708GLuint GLClientState::getFboAttachmentTextureId(GLenum target, GLenum attachment) const {
1709 GLuint res = 0; // conservative
1710
1711 int colorAttachmentIndex =
1712 glUtilsColorAttachmentIndex(attachment);
1713
1714 if (colorAttachmentIndex != -1) {
1715 res = boundFboProps_const(target).colorAttachmenti_textures[colorAttachmentIndex];
1716 }
1717
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001718 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001719 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001720 res = boundFboProps_const(target).depthAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001721 break;
1722 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001723 res = boundFboProps_const(target).stencilAttachment_texture;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001724 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001725 case GL_DEPTH_STENCIL_ATTACHMENT:
1726 res = boundFboProps_const(target).depthstencilAttachment_texture;
1727 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001728 }
1729 return res;
1730}
1731
1732// RBOs for FBOs////////////////////////////////////////////////////////////////
1733
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001734void GLClientState::detachRbo(GLuint renderbuffer) {
1735 for (int i = 0; i < m_max_color_attachments; i++) {
1736 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1737 detachRboFromFbo(GL_READ_FRAMEBUFFER, glUtilsColorAttachmentName(i), renderbuffer);
1738 }
1739
1740 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1741 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, renderbuffer);
1742
1743 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1744 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, renderbuffer);
1745
1746 detachRboFromFbo(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1747 detachRboFromFbo(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, renderbuffer);
1748}
1749
1750void GLClientState::detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1751 int colorAttachmentIndex =
1752 glUtilsColorAttachmentIndex(attachment);
1753
1754 if (colorAttachmentIndex != -1) {
1755 if (boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] &&
1756 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] == renderbuffer) {
1757 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = 0;
1758 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = false;
1759 }
1760 }
1761
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001762 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001763 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001764 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1765 boundFboProps(target).depthAttachment_hasRbo) {
1766 boundFboProps(target).depthAttachment_rbo = 0;
1767 boundFboProps(target).depthAttachment_hasRbo = false;
1768 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001769 break;
1770 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001771 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1772 boundFboProps(target).stencilAttachment_hasRbo) {
1773 boundFboProps(target).stencilAttachment_rbo = 0;
1774 boundFboProps(target).stencilAttachment_hasRbo = false;
1775 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001776 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001777 case GL_DEPTH_STENCIL_ATTACHMENT:
1778 if (boundFboProps(target).depthAttachment_rbo == renderbuffer &&
1779 boundFboProps(target).depthAttachment_hasRbo) {
1780 boundFboProps(target).depthAttachment_rbo = 0;
1781 boundFboProps(target).depthAttachment_hasRbo = false;
1782 }
1783 if (boundFboProps(target).stencilAttachment_rbo == renderbuffer &&
1784 boundFboProps(target).stencilAttachment_hasRbo) {
1785 boundFboProps(target).stencilAttachment_rbo = 0;
1786 boundFboProps(target).stencilAttachment_hasRbo = false;
1787 }
1788 if (boundFboProps(target).depthstencilAttachment_rbo == renderbuffer &&
1789 boundFboProps(target).depthstencilAttachment_hasRbo) {
1790 boundFboProps(target).depthstencilAttachment_rbo = 0;
1791 boundFboProps(target).depthstencilAttachment_hasRbo = false;
1792 }
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001793 break;
1794 }
1795}
1796
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001797void GLClientState::attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer) {
1798
1799 int colorAttachmentIndex =
1800 glUtilsColorAttachmentIndex(attachment);
1801
1802 if (colorAttachmentIndex != -1) {
1803 boundFboProps(target).colorAttachmenti_rbos[colorAttachmentIndex] = renderbuffer;
1804 boundFboProps(target).colorAttachmenti_hasRbo[colorAttachmentIndex] = true;
1805 }
1806
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001807 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001808 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001809 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1810 boundFboProps(target).depthAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001811 break;
1812 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001813 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1814 boundFboProps(target).stencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001815 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001816 case GL_DEPTH_STENCIL_ATTACHMENT:
1817 boundFboProps(target).depthAttachment_rbo = renderbuffer;
1818 boundFboProps(target).depthAttachment_hasRbo = true;
1819 boundFboProps(target).stencilAttachment_rbo = renderbuffer;
1820 boundFboProps(target).stencilAttachment_hasRbo = true;
1821 boundFboProps(target).depthstencilAttachment_rbo = renderbuffer;
1822 boundFboProps(target).depthstencilAttachment_hasRbo = true;
1823 break;
1824 }
1825}
1826
1827GLuint GLClientState::getFboAttachmentRboId(GLenum target, GLenum attachment) const {
1828 GLuint res = 0; // conservative
1829
1830 int colorAttachmentIndex =
1831 glUtilsColorAttachmentIndex(attachment);
1832
1833 if (colorAttachmentIndex != -1) {
1834 res = boundFboProps_const(target).colorAttachmenti_rbos[colorAttachmentIndex];
1835 }
1836
1837 switch (attachment) {
1838 case GL_DEPTH_ATTACHMENT:
1839 res = boundFboProps_const(target).depthAttachment_rbo;
1840 break;
1841 case GL_STENCIL_ATTACHMENT:
1842 res = boundFboProps_const(target).stencilAttachment_rbo;
1843 break;
1844 case GL_DEPTH_STENCIL_ATTACHMENT:
1845 res = boundFboProps_const(target).depthstencilAttachment_rbo;
1846 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001847 }
1848 return res;
1849}
1850
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001851bool GLClientState::attachmentHasObject(GLenum target, GLenum attachment) const {
1852 bool res = true; // liberal
1853
1854 int colorAttachmentIndex =
1855 glUtilsColorAttachmentIndex(attachment);
1856
1857 if (colorAttachmentIndex != -1) {
1858 res = boundFboProps_const(target).colorAttachmenti_hasTex[colorAttachmentIndex] ||
1859 boundFboProps_const(target).colorAttachmenti_hasRbo[colorAttachmentIndex];
1860 }
1861
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001862 switch (attachment) {
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001863 case GL_DEPTH_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001864 res = (boundFboProps_const(target).depthAttachment_hasTexObj) ||
1865 (boundFboProps_const(target).depthAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001866 break;
1867 case GL_STENCIL_ATTACHMENT:
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001868 res = (boundFboProps_const(target).stencilAttachment_hasTexObj) ||
1869 (boundFboProps_const(target).stencilAttachment_hasRbo);
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001870 break;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001871 case GL_DEPTH_STENCIL_ATTACHMENT:
1872 res = (boundFboProps_const(target).depthstencilAttachment_hasTexObj) ||
1873 (boundFboProps_const(target).depthstencilAttachment_hasRbo);
1874 break;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001875 }
1876 return res;
1877}
1878
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001879GLuint GLClientState::objectOfAttachment(GLenum target, GLenum attachment) const {
1880 const FboProps& props = boundFboProps_const(target);
1881
1882 int colorAttachmentIndex =
1883 glUtilsColorAttachmentIndex(attachment);
1884
1885 if (colorAttachmentIndex != -1) {
1886 if (props.colorAttachmenti_hasTex[colorAttachmentIndex]) {
1887 return props.colorAttachmenti_textures[colorAttachmentIndex];
1888 } else if (props.colorAttachmenti_hasRbo[colorAttachmentIndex]) {
1889 return props.colorAttachmenti_rbos[colorAttachmentIndex];
1890 } else {
1891 return 0;
1892 }
1893 }
1894
1895 switch (attachment) {
1896 case GL_DEPTH_ATTACHMENT:
1897 if (props.depthAttachment_hasTexObj) {
1898 return props.depthAttachment_texture;
1899 } else if (props.depthAttachment_hasRbo) {
1900 return props.depthAttachment_rbo;
1901 } else {
1902 return 0;
1903 }
1904 break;
1905 case GL_STENCIL_ATTACHMENT:
1906 if (props.stencilAttachment_hasTexObj) {
1907 return props.stencilAttachment_texture;
1908 } else if (props.stencilAttachment_hasRbo) {
1909 return props.stencilAttachment_rbo;
1910 } else {
1911 return 0;
1912 }
1913 case GL_DEPTH_STENCIL_ATTACHMENT:
1914 if (props.depthstencilAttachment_hasTexObj) {
1915 return props.depthstencilAttachment_texture;
1916 } else if (props.depthstencilAttachment_hasRbo) {
1917 return props.depthstencilAttachment_rbo;
1918 } else {
1919 return 0;
1920 }
1921 break;
1922 }
1923 return 0;
1924}
Lingfeng Yang4a66b312017-01-09 13:27:49 -08001925
1926void GLClientState::setTransformFeedbackActiveUnpaused(bool activeUnpaused) {
1927 m_transformFeedbackActiveUnpaused = activeUnpaused;
1928}
1929
1930bool GLClientState::getTransformFeedbackActiveUnpaused() const {
1931 return m_transformFeedbackActiveUnpaused;
1932}
1933
1934void GLClientState::setTextureData(SharedTextureDataMap* sharedTexData) {
1935 m_tex.textureRecs = sharedTexData;
1936}
1937
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001938void GLClientState::fromMakeCurrent() {
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001939 if (mFboState.fboData.find(0) == mFboState.fboData.end()) {
1940 addFreshFramebuffer(0);
1941 }
1942 FboProps& default_fb_props = mFboState.fboData[0];
1943 default_fb_props.colorAttachmenti_hasRbo[0] = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001944 default_fb_props.depthAttachment_hasRbo = true;
1945 default_fb_props.stencilAttachment_hasRbo = true;
Lingfeng Yang35d5f3b2017-01-09 13:23:25 -08001946 default_fb_props.depthstencilAttachment_hasRbo = true;
Lingfeng Yang57cb41b2016-04-08 14:42:34 -07001947}
Lingfeng Yangf654f3f2017-01-09 13:12:33 -08001948
1949void GLClientState::initFromCaps(
1950 int max_transform_feedback_separate_attribs,
1951 int max_uniform_buffer_bindings,
1952 int max_atomic_counter_buffer_bindings,
1953 int max_shader_storage_buffer_bindings,
1954 int max_vertex_attrib_bindings,
1955 int max_color_attachments,
1956 int max_draw_buffers) {
1957
1958 m_max_vertex_attrib_bindings = max_vertex_attrib_bindings;
1959
1960 if (m_glesMajorVersion >= 3) {
1961 m_max_transform_feedback_separate_attribs = max_transform_feedback_separate_attribs;
1962 m_max_uniform_buffer_bindings = max_uniform_buffer_bindings;
1963 m_max_atomic_counter_buffer_bindings = max_atomic_counter_buffer_bindings;
1964 m_max_shader_storage_buffer_bindings = max_shader_storage_buffer_bindings;
1965
1966 if (m_max_transform_feedback_separate_attribs)
1967 m_indexedTransformFeedbackBuffers.resize(m_max_transform_feedback_separate_attribs);
1968 if (m_max_uniform_buffer_bindings)
1969 m_indexedUniformBuffers.resize(m_max_uniform_buffer_bindings);
1970 if (m_max_atomic_counter_buffer_bindings)
1971 m_indexedAtomicCounterBuffers.resize(m_max_atomic_counter_buffer_bindings);
1972 if (m_max_shader_storage_buffer_bindings)
1973 m_indexedShaderStorageBuffers.resize(m_max_shader_storage_buffer_bindings);
1974
1975 BufferBinding buf0Binding;
1976 buf0Binding.buffer = 0;
1977 buf0Binding.offset = 0;
1978 buf0Binding.size = 0;
1979 buf0Binding.stride = 0;
1980 buf0Binding.effectiveStride = 0;
1981
1982 for (size_t i = 0; i < m_indexedTransformFeedbackBuffers.size(); ++i)
1983 m_indexedTransformFeedbackBuffers[i] = buf0Binding;
1984 for (size_t i = 0; i < m_indexedUniformBuffers.size(); ++i)
1985 m_indexedUniformBuffers[i] = buf0Binding;
1986 for (size_t i = 0; i < m_indexedAtomicCounterBuffers.size(); ++i)
1987 m_indexedAtomicCounterBuffers[i] = buf0Binding;
1988 for (size_t i = 0; i < m_indexedShaderStorageBuffers.size(); ++i)
1989 m_indexedShaderStorageBuffers[i] = buf0Binding;
1990 }
1991
1992 m_max_color_attachments = max_color_attachments;
1993 m_max_draw_buffers = max_draw_buffers;
1994
1995 addFreshRenderbuffer(0);
1996 addFreshFramebuffer(0);
1997
1998 m_initialized = true;
1999}
2000
2001bool GLClientState::needsInitFromCaps() const {
2002 return !m_initialized;
2003}