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