blob: 09ee57175e381fdc1bf0793dd1f4120cc7796ede [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#ifndef _GL_CLIENT_STATE_H_
17#define _GL_CLIENT_STATE_H_
18
19#define GL_API
20#ifndef ANDROID
21#define GL_APIENTRY
22#define GL_APIENTRYP
23#endif
24
25#include <GLES/gl.h>
26#include <GLES/glext.h>
27#include <GLES2/gl2.h>
28#include <GLES2/gl2ext.h>
29
30#include <stdio.h>
31#include <stdlib.h>
32#include "ErrorLog.h"
33#include "codec_defs.h"
34
35class GLClientState {
36public:
37 typedef enum {
38 VERTEX_LOCATION = 0,
39 NORMAL_LOCATION = 1,
40 COLOR_LOCATION = 2,
41 POINTSIZE_LOCATION = 3,
42 TEXCOORD0_LOCATION = 4,
43 TEXCOORD1_LOCATION = 5,
44 TEXCOORD2_LOCATION = 6,
45 TEXCOORD3_LOCATION = 7,
46 TEXCOORD4_LOCATION = 8,
47 TEXCOORD5_LOCATION = 9,
48 TEXCOORD6_LOCATION = 10,
49 TEXCOORD7_LOCATION = 11,
50 MATRIXINDEX_LOCATION = 12,
51 WEIGHT_LOCATION = 13,
52 LAST_LOCATION = 14
53 } StateLocation;
54
55 typedef struct {
56 GLint enabled;
57 GLint size;
58 GLenum type;
59 GLsizei stride;
60 void *data;
61 GLuint bufferObject;
62 GLenum glConst;
63 unsigned int elementSize;
64 bool enableDirty; // true if any enable state has changed since last draw
65 bool normalized;
66 } VertexAttribState;
67
68 typedef struct {
69 int unpack_alignment;
70 int pack_alignment;
71 } PixelStoreState;
72
73 enum {
74 MAX_TEXTURE_UNITS = 32,
75 };
76
77public:
78 GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
79 ~GLClientState();
80 int nLocations() { return m_nLocations; }
81 const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
82 int setPixelStore(GLenum param, GLint value);
83 GLuint currentArrayVbo() { return m_currentArrayVbo; }
84 GLuint currentIndexVbo() { return m_currentIndexVbo; }
85 void enable(int location, int state);
86 void setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
87 void setBufferObject(int location, GLuint id);
88 const VertexAttribState *getState(int location);
89 const VertexAttribState *getStateAndEnableDirty(int location, bool *enableChanged);
90 int getLocation(GLenum loc);
91 void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
92 int getActiveTexture() const { return m_activeTexture; }
93
bohub0f0cdf2014-11-06 18:08:07 -080094 void unBindBuffer(GLuint id)
95 {
96 if (m_currentArrayVbo == id) m_currentArrayVbo = 0;
97 else if (m_currentIndexVbo == id) m_currentIndexVbo = 0;
98 }
99
keunyoungb85b2752013-03-08 12:28:03 -0800100 int bindBuffer(GLenum target, GLuint id)
101 {
102 int err = 0;
103 switch(target) {
104 case GL_ARRAY_BUFFER:
105 m_currentArrayVbo = id;
106 break;
107 case GL_ELEMENT_ARRAY_BUFFER:
108 m_currentIndexVbo = id;
109 break;
110 default:
111 err = -1;
112 }
113 return err;
114 }
115
116 int getBuffer(GLenum target)
117 {
118 int ret=0;
119 switch (target) {
120 case GL_ARRAY_BUFFER:
121 ret = m_currentArrayVbo;
122 break;
123 case GL_ELEMENT_ARRAY_BUFFER:
124 ret = m_currentIndexVbo;
125 break;
126 default:
127 ret = -1;
128 }
129 return ret;
130 }
131 size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const;
132
133 void setCurrentProgram(GLint program) { m_currentProgram = program; }
134 GLint currentProgram() const { return m_currentProgram; }
135
136 /* OES_EGL_image_external
137 *
138 * These functions manipulate GL state which interacts with the
139 * OES_EGL_image_external extension, to support client-side emulation on
140 * top of host implementations that don't have it.
141 *
142 * Most of these calls should only be used with TEXTURE_2D or
143 * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
144 * targets should bypass this. An exception is bindTexture(), which should
145 * see all glBindTexture() calls for any target.
146 */
147
148 // glActiveTexture(GL_TEXTURE0 + i)
149 // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
150 GLenum setActiveTextureUnit(GLenum texture);
151 GLenum getActiveTextureUnit() const;
152
153 // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
154 void enableTextureTarget(GLenum target);
155
156 // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
157 void disableTextureTarget(GLenum target);
158
159 // Implements the target priority logic:
160 // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
161 // * Return GL_TEXTURE_2D if enabled, else
162 // * Return the allDisabled value.
163 // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
164 // simpler; for other cases passing a recognizable enum like GL_ZERO or
165 // GL_INVALID_ENUM is appropriate.
166 GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
167
168 // glBindTexture(GL_TEXTURE_*, ...)
169 // Set the target binding of the active texture unit to texture. Returns
170 // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
171 // previously been bound to a different target. If firstUse is not NULL,
172 // it is set to indicate whether this is the first use of the texture.
173 // For accurate error detection, bindTexture should be called for *all*
174 // targets, not just 2D and EXTERNAL_OES.
175 GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
176
177 // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
178 GLuint getBoundTexture(GLenum target) const;
179
180 // glDeleteTextures(...)
181 // Remove references to the to-be-deleted textures.
182 void deleteTextures(GLsizei n, const GLuint* textures);
183
184private:
185 PixelStoreState m_pixelStore;
186 VertexAttribState *m_states;
187 int m_nLocations;
188 GLuint m_currentArrayVbo;
189 GLuint m_currentIndexVbo;
190 int m_activeTexture;
191 GLint m_currentProgram;
192
193 bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }
194
195 enum TextureTarget {
196 TEXTURE_2D = 0,
197 TEXTURE_EXTERNAL = 1,
198 TEXTURE_TARGET_COUNT
199 };
200 struct TextureUnit {
201 unsigned int enables;
202 GLuint texture[TEXTURE_TARGET_COUNT];
203 };
204 struct TextureRec {
205 GLuint id;
206 GLenum target;
207 };
208 struct TextureState {
209 TextureUnit unit[MAX_TEXTURE_UNITS];
210 TextureUnit* activeUnit;
211 TextureRec* textures;
212 GLuint numTextures;
213 GLuint allocTextures;
214 };
215 TextureState m_tex;
216
217 static int compareTexId(const void* pid, const void* prec);
218 TextureRec* addTextureRec(GLuint id, GLenum target);
219
220public:
221 void getClientStatePointer(GLenum pname, GLvoid** params);
222
223 template <class T>
224 int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
225 {
226 bool handled = true;
227 const VertexAttribState *vertexAttrib = getState(index);
228 if (vertexAttrib == NULL) {
229 ERR("getVeterxAttriParameter for non existant index %d\n", index);
230 // set gl error;
231 return handled;
232 }
233
234 switch(param) {
235 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
236 *ptr = (T)(vertexAttrib->bufferObject);
237 break;
238 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
239 *ptr = (T)(vertexAttrib->enabled);
240 break;
241 case GL_VERTEX_ATTRIB_ARRAY_SIZE:
242 *ptr = (T)(vertexAttrib->size);
243 break;
244 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
245 *ptr = (T)(vertexAttrib->stride);
246 break;
247 case GL_VERTEX_ATTRIB_ARRAY_TYPE:
248 *ptr = (T)(vertexAttrib->type);
249 break;
250 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
251 *ptr = (T)(vertexAttrib->normalized);
252 break;
253 case GL_CURRENT_VERTEX_ATTRIB:
254 handled = false;
255 break;
256 default:
257 handled = false;
258 ERR("unknown vertex-attrib parameter param %d\n", param);
259 }
260 return handled;
261 }
262
263 template <class T>
264 bool getClientStateParameter(GLenum param, T* ptr)
265 {
266 bool isClientStateParam = false;
267 switch (param) {
268 case GL_CLIENT_ACTIVE_TEXTURE: {
269 GLint tex = getActiveTexture() + GL_TEXTURE0;
270 *ptr = tex;
271 isClientStateParam = true;
272 break;
273 }
274 case GL_VERTEX_ARRAY_SIZE: {
275 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
276 *ptr = state->size;
277 isClientStateParam = true;
278 break;
279 }
280 case GL_VERTEX_ARRAY_TYPE: {
281 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
282 *ptr = state->type;
283 isClientStateParam = true;
284 break;
285 }
286 case GL_VERTEX_ARRAY_STRIDE: {
287 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
288 *ptr = state->stride;
289 isClientStateParam = true;
290 break;
291 }
292 case GL_COLOR_ARRAY_SIZE: {
293 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
294 *ptr = state->size;
295 isClientStateParam = true;
296 break;
297 }
298 case GL_COLOR_ARRAY_TYPE: {
299 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
300 *ptr = state->type;
301 isClientStateParam = true;
302 break;
303 }
304 case GL_COLOR_ARRAY_STRIDE: {
305 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
306 *ptr = state->stride;
307 isClientStateParam = true;
308 break;
309 }
310 case GL_NORMAL_ARRAY_TYPE: {
311 const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
312 *ptr = state->type;
313 isClientStateParam = true;
314 break;
315 }
316 case GL_NORMAL_ARRAY_STRIDE: {
317 const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
318 *ptr = state->stride;
319 isClientStateParam = true;
320 break;
321 }
322 case GL_TEXTURE_COORD_ARRAY_SIZE: {
323 const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
324 *ptr = state->size;
325 isClientStateParam = true;
326 break;
327 }
328 case GL_TEXTURE_COORD_ARRAY_TYPE: {
329 const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
330 *ptr = state->type;
331 isClientStateParam = true;
332 break;
333 }
334 case GL_TEXTURE_COORD_ARRAY_STRIDE: {
335 const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
336 *ptr = state->stride;
337 isClientStateParam = true;
338 break;
339 }
340 case GL_POINT_SIZE_ARRAY_TYPE_OES: {
341 const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
342 *ptr = state->type;
343 isClientStateParam = true;
344 break;
345 }
346 case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
347 const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
348 *ptr = state->stride;
349 isClientStateParam = true;
350 break;
351 }
352 case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
353 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
354 *ptr = state->size;
355 isClientStateParam = true;
356 break;
357 }
358 case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
359 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
360 *ptr = state->type;
361 isClientStateParam = true;
362 break;
363 }
364 case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
365 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
366 *ptr = state->stride;
367 isClientStateParam = true;
368 break;
369 }
370 case GL_WEIGHT_ARRAY_SIZE_OES: {
371 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
372 *ptr = state->size;
373 isClientStateParam = true;
374 break;
375 }
376 case GL_WEIGHT_ARRAY_TYPE_OES: {
377 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
378 *ptr = state->type;
379 isClientStateParam = true;
380 break;
381 }
382 case GL_WEIGHT_ARRAY_STRIDE_OES: {
383 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
384 *ptr = state->stride;
385 isClientStateParam = true;
386 break;
387 }
388 case GL_VERTEX_ARRAY_BUFFER_BINDING: {
389 const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
390 *ptr = state->bufferObject;
391 isClientStateParam = true;
392 break;
393 }
394 case GL_NORMAL_ARRAY_BUFFER_BINDING: {
395 const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
396 *ptr = state->bufferObject;
397 isClientStateParam = true;
398 break;
399 }
400 case GL_COLOR_ARRAY_BUFFER_BINDING: {
401 const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
402 *ptr = state->bufferObject;
403 isClientStateParam = true;
404 break;
405 }
406 case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
407 const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
408 *ptr = state->bufferObject;
409 isClientStateParam = true;
410 break;
411 }
412 case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
413 const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
414 *ptr = state->bufferObject;
415 isClientStateParam = true;
416 break;
417 }
418 case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
419 const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
420 *ptr = state->bufferObject;
421 isClientStateParam = true;
422 break;
423 }
424 case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
425 const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
426 *ptr = state->bufferObject;
427 isClientStateParam = true;
428 break;
429 }
430 case GL_ARRAY_BUFFER_BINDING: {
431 int buffer = getBuffer(GL_ARRAY_BUFFER);
432 *ptr = buffer;
433 isClientStateParam = true;
434 break;
435 }
436 case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
437 int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
438 *ptr = buffer;
439 isClientStateParam = true;
440 break;
441 }
442 }
443 return isClientStateParam;
444 }
445
446};
447#endif