GL2Encoder.cpp revision 318ffd3798500fe100e0a16166cc0fa9e3790ca3
1#include "GL2Encoder.h" 2#include <assert.h> 3 4 5static GLubyte *gVendorString= (GLubyte *) "Android"; 6static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0"; 7static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0"; 8static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; 9 10GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) 11{ 12 m_state = NULL; 13 m_glFlush_enc = set_glFlush(s_glFlush); 14 m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei); 15 m_glGetString_enc = set_glGetString(s_glGetString); 16 m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer); 17 m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays); 18 m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); 19 m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv); 20 m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv); 21 m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv); 22 m_glVertexAttribPointer_enc = set_glVertexAttribPointer(s_glVertexAtrribPointer); 23 m_glEnableVertexAttribArray_enc = set_glEnableVertexAttribArray(s_glEnableVertexAttribArray); 24 m_glDisableVertexAttribArray_enc = set_glDisableVertexAttribArray(s_glDisableVertexAttribArray); 25 m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv); 26 m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv); 27 m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv); 28} 29 30GL2Encoder::~GL2Encoder() 31{ 32 delete m_compressedTextureFormats; 33} 34 35void GL2Encoder::s_glFlush(void *self) 36{ 37 GL2Encoder *ctx = (GL2Encoder *) self; 38 ctx->m_glFlush_enc(self); 39 ctx->m_stream->flush(); 40} 41 42GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name) 43{ 44 GLubyte *retval = (GLubyte *) ""; 45 switch(name) { 46 case GL_VENDOR: 47 retval = gVendorString; 48 break; 49 case GL_RENDERER: 50 retval = gRendererString; 51 break; 52 case GL_VERSION: 53 retval = gVersionString; 54 break; 55 case GL_EXTENSIONS: 56 retval = gExtensionsString; 57 break; 58 } 59 return retval; 60} 61 62void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value) 63{ 64 GL2Encoder *ctx = (GL2Encoder *)self; 65 ctx->m_glPixelStorei_enc(ctx, param, value); 66 assert(ctx->m_state != NULL); 67 ctx->m_state->setPixelStore(param, value); 68} 69 70 71void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id) 72{ 73 GL2Encoder *ctx = (GL2Encoder *) self; 74 assert(ctx->m_state != NULL); 75 ctx->m_state->bindBuffer(target, id); 76 // TODO set error state if needed; 77 ctx->m_glBindBuffer_enc(self, target, id); 78} 79 80void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid * ptr) 81{ 82 GL2Encoder *ctx = (GL2Encoder *)self; 83 assert(ctx->m_state != NULL); 84 ctx->m_state->setState(indx, size, type, normalized, stride, ptr); 85} 86 87void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *params) 88{ 89 GL2Encoder *ctx = (GL2Encoder *) self; 90 assert(ctx->m_state != NULL); 91 if (param == GL_NUM_SHADER_BINARY_FORMATS) { 92 *params = 0; 93 } else if (param == GL_SHADER_BINARY_FORMATS) { 94 // do nothing 95 } else if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 96 GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); 97 if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) { 98 memcpy(params, compressedTextureFormats, ctx->m_num_compressedTextureFormats * sizeof(GLint)); 99 } 100 } else if (!ctx->m_state->getClientStateParameter<GLint>(param, params)) { 101 ctx->m_glGetIntegerv_enc(self, param, params); 102 } 103} 104 105 106void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr) 107{ 108 GL2Encoder *ctx = (GL2Encoder *)self; 109 assert(ctx->m_state != NULL); 110 if (param == GL_NUM_SHADER_BINARY_FORMATS) { 111 *ptr = 0; 112 } else if (param == GL_SHADER_BINARY_FORMATS) { 113 // do nothing; 114 } else if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 115 GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); 116 if (ctx->m_num_compressedTextureFormats > 0 && compressedTextureFormats != NULL) { 117 for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { 118 ptr[i] = (GLfloat) compressedTextureFormats[i]; 119 } 120 } 121 } 122 else if (!ctx->m_state->getClientStateParameter<GLfloat>(param,ptr)) { 123 ctx->m_glGetFloatv_enc(self, param, ptr); 124 } 125} 126 127 128void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) 129{ 130 GL2Encoder *ctx = (GL2Encoder *)self; 131 assert(ctx->m_state != NULL); 132 if (param == GL_COMPRESSED_TEXTURE_FORMATS) { 133 // ignore the command, although we should have generated a GLerror; 134 } 135 else if (!ctx->m_state->getClientStateParameter<GLboolean>(param,ptr)) { 136 ctx->m_glGetBooleanv_enc(self, param, ptr); 137 } 138} 139 140 141void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index) 142{ 143 GL2Encoder *ctx = (GL2Encoder *)self; 144 assert(ctx->m_state); 145 ctx->m_state->enable(index, 1); 146} 147 148void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index) 149{ 150 GL2Encoder *ctx = (GL2Encoder *)self; 151 assert(ctx->m_state); 152 ctx->m_state->enable(index, 0); 153} 154 155 156void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params) 157{ 158 GL2Encoder *ctx = (GL2Encoder *)self; 159 assert(ctx->m_state); 160 161 if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) { 162 ctx->m_glGetVertexAttribiv_enc(self, index, pname, params); 163 } 164} 165 166void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params) 167{ 168 GL2Encoder *ctx = (GL2Encoder *)self; 169 assert(ctx->m_state); 170 171 if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) { 172 ctx->m_glGetVertexAttribfv_enc(self, index, pname, params); 173 } 174} 175 176void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer) 177{ 178 GL2Encoder *ctx = (GL2Encoder *)self; 179 if (ctx->m_state == NULL) return; 180 181 const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index); 182 if (va_state != NULL) { 183 *pointer = va_state->data; 184 } 185} 186 187 188void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count) 189{ 190 assert(m_state); 191 192 for (int i = 0; i < m_state->nLocations(); i++) { 193 bool enableDirty; 194 const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty); 195 196 if (!state) { 197 continue; 198 } 199 200 if (!enableDirty && !state->enabled) { 201 continue; 202 } 203 204 205 if (state->enabled) { 206 m_glEnableVertexAttribArray_enc(this, i); 207 208 unsigned int datalen = state->elementSize * count; 209 int stride = state->stride == 0 ? state->elementSize : state->stride; 210 int firstIndex = stride * first; 211 212 if (state->bufferObject == 0) { 213 this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride, 214 (unsigned char *)state->data + firstIndex, datalen); 215 } else { 216 this->glBindBuffer(this, GL_ARRAY_BUFFER, state->bufferObject); 217 this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride, 218 (GLuint) state->data + firstIndex); 219 } 220 } else { 221 this->m_glDisableVertexAttribArray_enc(this, i); 222 } 223 } 224} 225 226void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count) 227{ 228 GL2Encoder *ctx = (GL2Encoder *)self; 229 ctx->sendVertexAttributes(first, count); 230 ctx->m_glDrawArrays_enc(ctx, mode, 0, count); 231} 232 233 234void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, void *indices) 235{ 236 237 GL2Encoder *ctx = (GL2Encoder *)self; 238 assert(ctx->m_state != NULL); 239 240 bool has_immediate_arrays = false; 241 bool has_indirect_arrays = false; 242 int nLocations = ctx->m_state->nLocations(); 243 244 for (int i = 0; i < nLocations; i++) { 245 const GLClientState::VertexAttribState *state = ctx->m_state->getState(i); 246 if (state->enabled) { 247 if (state->bufferObject != 0) { 248 has_indirect_arrays = true; 249 } else { 250 has_immediate_arrays = true; 251 } 252 } 253 } 254 255 if (!has_immediate_arrays && !has_indirect_arrays) { 256 LOGE("glDrawElements: no data bound to the command - ignoring\n"); 257 return; 258 } 259 260 if (ctx->m_state->currentIndexVbo() != 0) { 261 if (!has_immediate_arrays) { 262 ctx->sendVertexAttributes(0, count); 263 ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices); 264 } else { 265 LOGE("glDrawElements: indirect index arrays, with immidate-mode data array is not supported\n"); 266 } 267 } else { 268 void *adjustedIndices = indices; 269 int minIndex = 0, maxIndex = 0; 270 271 switch(type) { 272 case GL_BYTE: 273 case GL_UNSIGNED_BYTE: 274 GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex); 275 if (minIndex != 0) { 276 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 277 GLUtils::shiftIndices<unsigned char>((unsigned char *)indices, 278 (unsigned char *)adjustedIndices, 279 count, -minIndex); 280 } 281 break; 282 case GL_SHORT: 283 case GL_UNSIGNED_SHORT: 284 GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex); 285 if (minIndex != 0) { 286 adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); 287 GLUtils::shiftIndices<unsigned short>((unsigned short *)indices, 288 (unsigned short *)adjustedIndices, 289 count, -minIndex); 290 } 291 break; 292 default: 293 LOGE("unsupported index buffer type %d\n", type); 294 } 295 if (has_indirect_arrays || 1) { 296 ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1); 297 ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, 298 count * glSizeof(type)); 299 // XXX - OPTIMIZATION (see the other else branch) should be implemented 300 if(!has_indirect_arrays) { 301 LOGD("unoptimized drawelements !!!\n"); 302 } 303 } else { 304 // we are all direct arrays and immidate mode index array - 305 // rebuild the arrays and the index array; 306 LOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n"); 307 } 308 } 309} 310 311 312GLint * GL2Encoder::getCompressedTextureFormats() 313{ 314 if (m_compressedTextureFormats == NULL) { 315 this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS, 316 &m_num_compressedTextureFormats); 317 if (m_num_compressedTextureFormats > 0) { 318 // get number of texture formats; 319 m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats]; 320 this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats); 321 } 322 } 323 return m_compressedTextureFormats; 324} 325