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