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 #include "GLClientState.h" 17 #include "ErrorLog.h" 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include "glUtils.h" 22 #include <cutils/log.h> 23 24 GLClientState::GLClientState(int nLocations) 25 { 26 if (nLocations < LAST_LOCATION) { 27 nLocations = LAST_LOCATION; 28 } 29 m_nLocations = nLocations; 30 m_states = new VertexAttribState[m_nLocations]; 31 for (int i = 0; i < m_nLocations; i++) { 32 m_states[i].enabled = 0; 33 m_states[i].enableDirty = false; 34 } 35 m_currentArrayVbo = 0; 36 m_currentIndexVbo = 0; 37 // init gl constans; 38 m_states[VERTEX_LOCATION].glConst = GL_VERTEX_ARRAY; 39 m_states[NORMAL_LOCATION].glConst = GL_NORMAL_ARRAY; 40 m_states[COLOR_LOCATION].glConst = GL_COLOR_ARRAY; 41 m_states[POINTSIZE_LOCATION].glConst = GL_POINT_SIZE_ARRAY_OES; 42 m_states[TEXCOORD0_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 43 m_states[TEXCOORD1_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 44 m_states[TEXCOORD2_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 45 m_states[TEXCOORD3_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 46 m_states[TEXCOORD4_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 47 m_states[TEXCOORD5_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 48 m_states[TEXCOORD6_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 49 m_states[TEXCOORD7_LOCATION].glConst = GL_TEXTURE_COORD_ARRAY; 50 m_states[MATRIXINDEX_LOCATION].glConst = GL_MATRIX_INDEX_ARRAY_OES; 51 m_states[WEIGHT_LOCATION].glConst = GL_WEIGHT_ARRAY_OES; 52 m_activeTexture = 0; 53 m_currentProgram = 0; 54 55 m_pixelStore.unpack_alignment = 4; 56 m_pixelStore.pack_alignment = 4; 57 } 58 59 GLClientState::~GLClientState() 60 { 61 delete m_states; 62 } 63 64 void GLClientState::enable(int location, int state) 65 { 66 if (!validLocation(location)) { 67 return; 68 } 69 70 m_states[location].enableDirty |= (state != m_states[location].enabled); 71 m_states[location].enabled = state; 72 } 73 74 void GLClientState::setState(int location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data) 75 { 76 if (!validLocation(location)) { 77 return; 78 } 79 m_states[location].size = size; 80 m_states[location].type = type; 81 m_states[location].stride = stride; 82 m_states[location].data = (void*)data; 83 m_states[location].bufferObject = m_currentArrayVbo; 84 m_states[location].elementSize = glSizeof(type) * size; 85 m_states[location].normalized = normalized; 86 } 87 88 void GLClientState::setBufferObject(int location, GLuint id) 89 { 90 if (!validLocation(location)) { 91 return; 92 } 93 94 m_states[location].bufferObject = id; 95 } 96 97 const GLClientState::VertexAttribState * GLClientState::getState(int location) 98 { 99 if (!validLocation(location)) { 100 return NULL; 101 } 102 return & m_states[location]; 103 } 104 105 const GLClientState::VertexAttribState * GLClientState::getStateAndEnableDirty(int location, bool *enableChanged) 106 { 107 if (!validLocation(location)) { 108 return NULL; 109 } 110 111 if (enableChanged) { 112 *enableChanged = m_states[location].enableDirty; 113 } 114 115 m_states[location].enableDirty = false; 116 return & m_states[location]; 117 } 118 119 int GLClientState::getLocation(GLenum loc) 120 { 121 int retval; 122 123 switch(loc) { 124 case GL_VERTEX_ARRAY: 125 retval = int(VERTEX_LOCATION); 126 break; 127 case GL_NORMAL_ARRAY: 128 retval = int(NORMAL_LOCATION); 129 break; 130 case GL_COLOR_ARRAY: 131 retval = int(COLOR_LOCATION); 132 break; 133 case GL_POINT_SIZE_ARRAY_OES: 134 retval = int(POINTSIZE_LOCATION); 135 break; 136 case GL_TEXTURE_COORD_ARRAY: 137 retval = int (TEXCOORD0_LOCATION + m_activeTexture); 138 break; 139 case GL_MATRIX_INDEX_ARRAY_OES: 140 retval = int (MATRIXINDEX_LOCATION); 141 break; 142 case GL_WEIGHT_ARRAY_OES: 143 retval = int (WEIGHT_LOCATION); 144 break; 145 default: 146 retval = loc; 147 } 148 return retval; 149 } 150 151 void GLClientState::getClientStatePointer(GLenum pname, GLvoid** params) 152 { 153 const GLClientState::VertexAttribState *state = NULL; 154 switch (pname) { 155 case GL_VERTEX_ARRAY_POINTER: { 156 state = getState(GLClientState::VERTEX_LOCATION); 157 break; 158 } 159 case GL_NORMAL_ARRAY_POINTER: { 160 state = getState(GLClientState::NORMAL_LOCATION); 161 break; 162 } 163 case GL_COLOR_ARRAY_POINTER: { 164 state = getState(GLClientState::COLOR_LOCATION); 165 break; 166 } 167 case GL_TEXTURE_COORD_ARRAY_POINTER: { 168 state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION); 169 break; 170 } 171 case GL_POINT_SIZE_ARRAY_POINTER_OES: { 172 state = getState(GLClientState::POINTSIZE_LOCATION); 173 break; 174 } 175 case GL_MATRIX_INDEX_ARRAY_POINTER_OES: { 176 state = getState(GLClientState::MATRIXINDEX_LOCATION); 177 break; 178 } 179 case GL_WEIGHT_ARRAY_POINTER_OES: { 180 state = getState(GLClientState::WEIGHT_LOCATION); 181 break; 182 } 183 } 184 if (state && params) 185 *params = state->data; 186 } 187 188 int GLClientState::setPixelStore(GLenum param, GLint value) 189 { 190 int retval = 0; 191 switch(param) { 192 case GL_UNPACK_ALIGNMENT: 193 if (value == 1 || value == 2 || value == 4 || value == 8) { 194 m_pixelStore.unpack_alignment = value; 195 } else { 196 retval = GL_INVALID_VALUE; 197 } 198 break; 199 case GL_PACK_ALIGNMENT: 200 if (value == 1 || value == 2 || value == 4 || value == 8) { 201 m_pixelStore.pack_alignment = value; 202 } else { 203 retval = GL_INVALID_VALUE; 204 } 205 break; 206 default: 207 retval = GL_INVALID_ENUM; 208 } 209 return retval; 210 } 211 212 213 214 215 size_t GLClientState::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const 216 { 217 int pixelsize = glUtilsPixelBitSize(format, type) >> 3; 218 219 int alignment = pack ? m_pixelStore.pack_alignment : m_pixelStore.unpack_alignment; 220 221 if (pixelsize == 0 ) { 222 ERR("unknown pixel size: width: %d height: %d format: %d type: %d pack: %d align: %d\n", 223 width, height, format, type, pack, alignment); 224 } 225 size_t linesize = pixelsize * width; 226 size_t aligned_linesize = int(linesize / alignment) * alignment; 227 if (aligned_linesize < linesize) { 228 aligned_linesize += alignment; 229 } 230 return aligned_linesize * height; 231 } 232 233