diff options
Diffstat (limited to 'emulator/opengl/system')
50 files changed, 9076 insertions, 0 deletions
diff --git a/emulator/opengl/system/GLESv1/Android.mk b/emulator/opengl/system/GLESv1/Android.mk new file mode 100644 index 0000000..97356b7 --- /dev/null +++ b/emulator/opengl/system/GLESv1/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +### GLESv1 implementation ########################################### +$(call emugl-begin-shared-library,libGLESv1_CM_emulation) +$(call emugl-import,libOpenglSystemCommon libGLESv1_enc lib_renderControl_enc) + +LOCAL_CFLAGS += -DLOG_TAG=\"GLES_emulation\" -DGL_GLEXT_PROTOTYPES + +LOCAL_SRC_FILES := gl.cpp +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl + +$(call emugl-end-module) diff --git a/emulator/opengl/system/GLESv1/gl.cpp b/emulator/opengl/system/GLESv1/gl.cpp new file mode 100644 index 0000000..8ecb504 --- /dev/null +++ b/emulator/opengl/system/GLESv1/gl.cpp @@ -0,0 +1,146 @@ +/* +* Copyright 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "EGLClientIface.h" +#include "HostConnection.h" +#include "GLEncoder.h" +#include "GLES/gl.h" +#include "GLES/glext.h" +#include "ErrorLog.h" +#include "gralloc_cb.h" +#include "ThreadInfo.h" + + +//XXX: fix this macro to get the context from fast tls path +#define GET_CONTEXT GLEncoder * ctx = getEGLThreadInfo()->hostConn->glEncoder(); + +#include "gl_entry.cpp" + +//The functions table +#include "gl_ftable.h" + +static EGLClient_eglInterface * s_egl = NULL; +static EGLClient_glesInterface * s_gl = NULL; + +#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ + HostConnection *hostCon = HostConnection::get(); \ + if (!hostCon) { \ + ALOGE("egl: Failed to get host connection\n"); \ + return ret; \ + } \ + renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ + if (!rcEnc) { \ + ALOGE("egl: Failed to get renderControl encoder context\n"); \ + return ret; \ + } + +//GL extensions +void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image) +{ + DBG("glEGLImageTargetTexture2DOES v1 target=%#x image=%p", target, image); + //TODO: check error - we don't have a way to set gl error + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + return; + } + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + return; + } + + GET_CONTEXT; + DEFINE_AND_VALIDATE_HOST_CONNECTION(); + + ctx->override2DTextureTarget(target); + rcEnc->rcBindTexture(rcEnc, + ((cb_handle_t *)(native_buffer->handle))->hostHandle); + ctx->restore2DTextureTarget(); + + return; +} + +void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImageOES image) +{ + DBG("glEGLImageTargetRenderbufferStorageOES v1 target=%#x image=%p", + target, image); + //TODO: check error - we don't have a way to set gl error + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + return; + } + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + return; + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(); + rcEnc->rcBindRenderbuffer(rcEnc, + ((cb_handle_t *)(native_buffer->handle))->hostHandle); + + return; +} + +void * getProcAddress(const char * procname) +{ + // search in GL function table + for (int i=0; i<gl_num_funcs; i++) { + if (!strcmp(gl_funcs_by_name[i].name, procname)) { + return gl_funcs_by_name[i].proc; + } + } + return NULL; +} + +void finish() +{ + glFinish(); +} + +const GLubyte *my_glGetString (void *self, GLenum name) +{ + if (s_egl) { + return (const GLubyte*)s_egl->getGLString(name); + } + return NULL; +} + +void init() +{ + GET_CONTEXT; + ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES); + ctx->set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES); + ctx->set_glGetString(my_glGetString); +} + +extern "C" { +EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface) +{ + s_egl = eglIface; + + if (!s_gl) { + s_gl = new EGLClient_glesInterface(); + s_gl->getProcAddress = getProcAddress; + s_gl->finish = finish; + s_gl->init = init; + } + + return s_gl; +} +} //extern + + diff --git a/emulator/opengl/system/GLESv1_enc/Android.mk b/emulator/opengl/system/GLESv1_enc/Android.mk new file mode 100644 index 0000000..25c8c49 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH := $(call my-dir) + +### GLESv1_enc Encoder ########################################### +$(call emugl-begin-shared-library,libGLESv1_enc) + +LOCAL_CFLAGS += -DLOG_TAG=\"emuglGLESv1_enc\" + +LOCAL_SRC_FILES := \ + GLEncoder.cpp \ + GLEncoderUtils.cpp + +$(call emugl-gen-encoder,$(LOCAL_PATH),gl) + +$(call emugl-import,libOpenglCodecCommon) +$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) +$(call emugl-export,C_INCLUDES,$(intermediates)) + +$(call emugl-end-module) diff --git a/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp new file mode 100644 index 0000000..4414f24 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp @@ -0,0 +1,989 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "GLEncoder.h" +#include "glUtils.h" +#include "FixedBuffer.h" +#include <cutils/log.h> +#include <assert.h> + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +static GLubyte *gVendorString= (GLubyte *) "Android"; +static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0"; +static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0"; +static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; + +#define SET_ERROR_IF(condition,err) if((condition)) { \ + ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ + ctx->setError(err); \ + return; \ + } + + +#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \ + ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ + ctx->setError(err); \ + return ret; \ + } + +GLenum GLEncoder::s_glGetError(void * self) +{ + GLEncoder *ctx = (GLEncoder *)self; + GLenum err = ctx->getError(); + if(err != GL_NO_ERROR) { + ctx->setError(GL_NO_ERROR); + return err; + } + + return ctx->m_glGetError_enc(self); + +} + +GLint * GLEncoder::getCompressedTextureFormats() +{ + if (m_compressedTextureFormats == NULL) { + this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS, + &m_num_compressedTextureFormats); + if (m_num_compressedTextureFormats > 0) { + // get number of texture formats; + m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats]; + this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats); + } + } + return m_compressedTextureFormats; +} + +void GLEncoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + memcpy(ptr, compressedTextureFormats, + ctx->m_num_compressedTextureFormats * sizeof(GLint)); + } + break; + } + + case GL_MAX_TEXTURE_UNITS: + ctx->m_glGetIntegerv_enc(self, param, ptr); + *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS); + break; + + case GL_TEXTURE_BINDING_2D: + *ptr = state->getBoundTexture(GL_TEXTURE_2D); + break; + + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); + break; + + default: + if (!state->getClientStateParameter<GLint>(param,ptr)) { + ctx->m_glGetIntegerv_enc(self, param, ptr); + } + break; + } +} + +void GLEncoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { + ptr[i] = (GLfloat) compressedTextureFormats[i]; + } + } + break; + } + + case GL_MAX_TEXTURE_UNITS: + ctx->m_glGetFloatv_enc(self, param, ptr); + *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS); + break; + + case GL_TEXTURE_BINDING_2D: + *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D); + break; + + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); + break; + + default: + if (!state->getClientStateParameter<GLfloat>(param,ptr)) { + ctx->m_glGetFloatv_enc(self, param, ptr); + } + break; + } +} + +void GLEncoder::s_glGetFixedv(void *self, GLenum param, GLfixed *ptr) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint * compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { + ptr[i] = compressedTextureFormats[i] << 16; + } + } + break; + } + + case GL_MAX_TEXTURE_UNITS: + ctx->m_glGetFixedv_enc(self, param, ptr); + *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS << 16); + break; + + case GL_TEXTURE_BINDING_2D: + *ptr = state->getBoundTexture(GL_TEXTURE_2D) << 16; + break; + + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) << 16; + break; + + default: + if (!state->getClientStateParameter<GLfixed>(param,ptr)) { + ctx->m_glGetFixedv_enc(self, param, ptr); + } + break; + } +} + +void GLEncoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint* compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { + ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE; + } + } + break; + } + + case GL_TEXTURE_BINDING_2D: + *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE; + break; + + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0 + ? GL_TRUE : GL_FALSE; + break; + + default: + if (!state->getClientStateParameter<GLboolean>(param,ptr)) { + ctx->m_glGetBooleanv_enc(self, param, ptr); + } + break; + } +} + +void GLEncoder::s_glGetPointerv(void * self, GLenum param, GLvoid **params) +{ + GLEncoder * ctx = (GLEncoder *) self; + assert(ctx->m_state != NULL); + ctx->m_state->getClientStatePointer(param,params); +} + +void GLEncoder::s_glFlush(void *self) +{ + GLEncoder *ctx = (GLEncoder *)self; + ctx->m_glFlush_enc(self); + ctx->m_stream->flush(); +} + +const GLubyte *GLEncoder::s_glGetString(void *self, GLenum name) +{ + GLubyte *retval = (GLubyte *) ""; + switch(name) { + case GL_VENDOR: + retval = gVendorString; + break; + case GL_RENDERER: + retval = gRendererString; + break; + case GL_VERSION: + retval = gVersionString; + break; + case GL_EXTENSIONS: + retval = gExtensionsString; + break; + } + return retval; +} + +void GLEncoder::s_glPixelStorei(void *self, GLenum param, GLint value) +{ + GLEncoder *ctx = (GLEncoder *)self; + ctx->m_glPixelStorei_enc(ctx, param, value); + ALOG_ASSERT(ctx->m_state, "GLEncoder::s_glPixelStorei"); + ctx->m_state->setPixelStore(param, value); +} + +void GLEncoder::s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + ctx->m_state->setState(GLClientState::VERTEX_LOCATION, size, type, false, stride, data); +} + +void GLEncoder::s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + ctx->m_state->setState(GLClientState::NORMAL_LOCATION, 3, type, false, stride, data); +} + +void GLEncoder::s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + ctx->m_state->setState(GLClientState::COLOR_LOCATION, size, type, false, stride, data); +} + +void GLEncoder::s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + ctx->m_state->setState(GLClientState::POINTSIZE_LOCATION, 1, type, false, stride, data); +} + +void GLEncoder::s_glClientActiveTexture(void *self, GLenum texture) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + ctx->m_state->setActiveTexture(texture - GL_TEXTURE0); +} + +void GLEncoder::s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + int loc = ctx->m_state->getLocation(GL_TEXTURE_COORD_ARRAY); + ctx->m_state->setState(loc, size, type, false, stride, data); +} + +void GLEncoder::s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + int loc = ctx->m_state->getLocation(GL_MATRIX_INDEX_ARRAY_OES); + ctx->m_state->setState(loc, size, type, false, stride, data); +} + +void GLEncoder::s_glWeightPointerOES(void * self, int size, GLenum type, GLsizei stride, const void * data) +{ + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + int loc = ctx->m_state->getLocation(GL_WEIGHT_ARRAY_OES); + ctx->m_state->setState(loc, size, type, false, stride, data); +} + +void GLEncoder::s_glEnableClientState(void *self, GLenum state) +{ + GLEncoder *ctx = (GLEncoder *) self; + assert(ctx->m_state != NULL); + int loc = ctx->m_state->getLocation(state); + ctx->m_state->enable(loc, 1); +} + +void GLEncoder::s_glDisableClientState(void *self, GLenum state) +{ + GLEncoder *ctx = (GLEncoder *) self; + assert(ctx->m_state != NULL); + int loc = ctx->m_state->getLocation(state); + ctx->m_state->enable(loc, 0); +} + +GLboolean GLEncoder::s_glIsEnabled(void *self, GLenum cap) +{ + GLEncoder *ctx = (GLEncoder *) self; + assert(ctx->m_state != NULL); + int loc = ctx->m_state->getLocation(cap); + const GLClientState::VertexAttribState *state = ctx->m_state->getState(loc); + + if (state!=NULL) + return state->enabled; + + return ctx->m_glIsEnabled_enc(self,cap); +} + +void GLEncoder::s_glBindBuffer(void *self, GLenum target, GLuint id) +{ + GLEncoder *ctx = (GLEncoder *) self; + assert(ctx->m_state != NULL); + ctx->m_state->bindBuffer(target, id); + // TODO set error state if needed; + ctx->m_glBindBuffer_enc(self, target, id); +} + +void GLEncoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) +{ + GLEncoder *ctx = (GLEncoder *) self; + GLuint bufferId = ctx->m_state->getBuffer(target); + SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); + SET_ERROR_IF(size<0, GL_INVALID_VALUE); + + ctx->m_shared->updateBufferData(bufferId, size, (void*)data); + ctx->m_glBufferData_enc(self, target, size, data, usage); +} + +void GLEncoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) +{ + GLEncoder *ctx = (GLEncoder *) self; + GLuint bufferId = ctx->m_state->getBuffer(target); + SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); + + GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data); + SET_ERROR_IF(res, res); + + ctx->m_glBufferSubData_enc(self, target, offset, size, data); +} + +void GLEncoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers) +{ + GLEncoder *ctx = (GLEncoder *) self; + SET_ERROR_IF(n<0, GL_INVALID_VALUE); + for (int i=0; i<n; i++) { + ctx->m_shared->deleteBufferData(buffers[i]); + ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]); + } +} + +void GLEncoder::sendVertexData(unsigned int first, unsigned int count) +{ + assert(m_state != NULL); + for (int i = 0; i < GLClientState::LAST_LOCATION; i++) { + bool enableDirty; + const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty); + + // do not process if state not valid + if (!state) continue; + + // do not send disable state if state was already disabled + if (!enableDirty && !state->enabled) continue; + + if ( i >= GLClientState::TEXCOORD0_LOCATION && + i <= GLClientState::TEXCOORD7_LOCATION ) { + m_glClientActiveTexture_enc(this, GL_TEXTURE0 + i - GLClientState::TEXCOORD0_LOCATION); + } + + if (state->enabled) { + + if (enableDirty) + m_glEnableClientState_enc(this, state->glConst); + + unsigned int datalen = state->elementSize * count; + int stride = state->stride; + if (stride == 0) stride = state->elementSize; + int firstIndex = stride * first; + + if (state->bufferObject == 0) { + + switch(i) { + case GLClientState::VERTEX_LOCATION: + this->glVertexPointerData(this, state->size, state->type, state->stride, + (unsigned char *)state->data + firstIndex, datalen); + break; + case GLClientState::NORMAL_LOCATION: + this->glNormalPointerData(this, state->type, state->stride, + (unsigned char *)state->data + firstIndex, datalen); + break; + case GLClientState::COLOR_LOCATION: + this->glColorPointerData(this, state->size, state->type, state->stride, + (unsigned char *)state->data + firstIndex, datalen); + break; + case GLClientState::TEXCOORD0_LOCATION: + case GLClientState::TEXCOORD1_LOCATION: + case GLClientState::TEXCOORD2_LOCATION: + case GLClientState::TEXCOORD3_LOCATION: + case GLClientState::TEXCOORD4_LOCATION: + case GLClientState::TEXCOORD5_LOCATION: + case GLClientState::TEXCOORD6_LOCATION: + case GLClientState::TEXCOORD7_LOCATION: + this->glTexCoordPointerData(this, i - GLClientState::TEXCOORD0_LOCATION, state->size, state->type, state->stride, + (unsigned char *)state->data + firstIndex, datalen); + break; + case GLClientState::POINTSIZE_LOCATION: + this->glPointSizePointerData(this, state->type, state->stride, + (unsigned char *) state->data + firstIndex, datalen); + break; + case GLClientState::WEIGHT_LOCATION: + this->glWeightPointerData(this, state->size, state->type, state->stride, + (unsigned char * ) state->data + firstIndex, datalen); + break; + case GLClientState::MATRIXINDEX_LOCATION: + this->glMatrixIndexPointerData(this, state->size, state->type, state->stride, + (unsigned char *)state->data + firstIndex, datalen); + break; + } + } else { + this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); + + switch(i) { + case GLClientState::VERTEX_LOCATION: + this->glVertexPointerOffset(this, state->size, state->type, state->stride, + (GLuint)state->data + firstIndex); + break; + case GLClientState::NORMAL_LOCATION: + this->glNormalPointerOffset(this, state->type, state->stride, + (GLuint) state->data + firstIndex); + break; + case GLClientState::POINTSIZE_LOCATION: + this->glPointSizePointerOffset(this, state->type, state->stride, + (GLuint) state->data + firstIndex); + break; + case GLClientState::COLOR_LOCATION: + this->glColorPointerOffset(this, state->size, state->type, state->stride, + (GLuint) state->data + firstIndex); + break; + case GLClientState::TEXCOORD0_LOCATION: + case GLClientState::TEXCOORD1_LOCATION: + case GLClientState::TEXCOORD2_LOCATION: + case GLClientState::TEXCOORD3_LOCATION: + case GLClientState::TEXCOORD4_LOCATION: + case GLClientState::TEXCOORD5_LOCATION: + case GLClientState::TEXCOORD6_LOCATION: + case GLClientState::TEXCOORD7_LOCATION: + this->glTexCoordPointerOffset(this, state->size, state->type, state->stride, + (GLuint) state->data + firstIndex); + break; + case GLClientState::WEIGHT_LOCATION: + this->glWeightPointerOffset(this,state->size,state->type,state->stride, + (GLuint)state->data+firstIndex); + break; + case GLClientState::MATRIXINDEX_LOCATION: + this->glMatrixIndexPointerOffset(this,state->size,state->type,state->stride, + (GLuint)state->data+firstIndex); + break; + } + this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); + } + } else { + this->m_glDisableClientState_enc(this, state->glConst); + } + } +} + +void GLEncoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count) +{ + GLEncoder *ctx = (GLEncoder *)self; + + ctx->sendVertexData(first, count); + ctx->m_glDrawArrays_enc(ctx, mode, /*first*/ 0, count); +} + +void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices) +{ + + GLEncoder *ctx = (GLEncoder *)self; + assert(ctx->m_state != NULL); + SET_ERROR_IF(count<0, GL_INVALID_VALUE); + + bool has_immediate_arrays = false; + bool has_indirect_arrays = false; + + for (int i = 0; i < GLClientState::LAST_LOCATION; i++) { + const GLClientState::VertexAttribState *state = ctx->m_state->getState(i); + if (state->enabled) { + if (state->bufferObject != 0) { + has_indirect_arrays = true; + } else { + has_immediate_arrays = true; + } + } + } + + if (!has_immediate_arrays && !has_indirect_arrays) { + ALOGE("glDrawElements: no data bound to the command - ignoring\n"); + return; + } + + bool adjustIndices = true; + if (ctx->m_state->currentIndexVbo() != 0) { + if (!has_immediate_arrays) { + ctx->sendVertexData(0, count); + ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); + ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices); + adjustIndices = false; + } else { + BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); + ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); + indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); + } + } + if (adjustIndices) { + void *adjustedIndices = (void*)indices; + int minIndex = 0, maxIndex = 0; + + switch(type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex); + if (minIndex != 0) { + adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); + GLUtils::shiftIndices<unsigned char>((unsigned char *)indices, + (unsigned char *)adjustedIndices, + count, -minIndex); + } + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex); + if (minIndex != 0) { + adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); + GLUtils::shiftIndices<unsigned short>((unsigned short *)indices, + (unsigned short *)adjustedIndices, + count, -minIndex); + } + break; + default: + ALOGE("unsupported index buffer type %d\n", type); + } + if (has_indirect_arrays || 1) { + ctx->sendVertexData(minIndex, maxIndex - minIndex + 1); + ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, + count * glSizeof(type)); + // XXX - OPTIMIZATION (see the other else branch) should be implemented + if(!has_indirect_arrays) { + //ALOGD("unoptimized drawelements !!!\n"); + } + } else { + // we are all direct arrays and immidate mode index array - + // rebuild the arrays and the index array; + ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n"); + } + } +} + +void GLEncoder::s_glActiveTexture(void* self, GLenum texture) +{ + GLEncoder* ctx = (GLEncoder*)self; + GLClientState* state = ctx->m_state; + GLenum err; + + if ((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR) { + ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err); + ctx->setError(err); + return; + } + + ctx->m_glActiveTexture_enc(ctx, texture); +} + +void GLEncoder::s_glBindTexture(void* self, GLenum target, GLuint texture) +{ + GLEncoder* ctx = (GLEncoder*)self; + GLClientState* state = ctx->m_state; + GLenum err; + + GLboolean firstUse; + if ((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR) { + ALOGE("%s:%s:%d GL error %#x\n", __FILE__, __FUNCTION__, __LINE__, err); + ctx->setError(err); + return; + } + + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) { + ctx->m_glBindTexture_enc(ctx, target, texture); + return; + } + + GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D); + + if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) { + // set TEXTURE_EXTERNAL_OES default states which differ from TEXTURE_2D + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (target != priorityTarget) { + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, + state->getBoundTexture(GL_TEXTURE_2D)); + } + } + + if (target == priorityTarget) { + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); + } +} + +void GLEncoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures) +{ + GLEncoder* ctx = (GLEncoder*)self; + GLClientState* state = ctx->m_state; + + state->deleteTextures(n, textures); + ctx->m_glDeleteTextures_enc(ctx, n, textures); +} + +void GLEncoder::s_glDisable(void* self, GLenum cap) +{ + GLEncoder* ctx = (GLEncoder*)self; + GLClientState* state = ctx->m_state; + + if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) { + GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); + state->disableTextureTarget(cap); + GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); + + if (prevTarget != currTarget) { + if (currTarget == GL_INVALID_ENUM) { + ctx->m_glDisable_enc(ctx, GL_TEXTURE_2D); + currTarget = GL_TEXTURE_2D; + } + // maintain the invariant that when TEXTURE_EXTERNAL_OES is + // disabled, the TEXTURE_2D binding is active, even if + // TEXTURE_2D is also disabled. + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, + state->getBoundTexture(currTarget)); + } + + } else { + ctx->m_glDisable_enc(ctx, cap); + } +} + +void GLEncoder::s_glEnable(void* self, GLenum cap) +{ + GLEncoder* ctx = (GLEncoder*)self; + GLClientState* state = ctx->m_state; + + if (cap == GL_TEXTURE_2D || cap == GL_TEXTURE_EXTERNAL_OES) { + GLenum prevTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); + state->enableTextureTarget(cap); + GLenum currTarget = state->getPriorityEnabledTarget(GL_INVALID_ENUM); + + if (prevTarget != currTarget) { + if (prevTarget == GL_INVALID_ENUM) { + ctx->m_glEnable_enc(ctx, GL_TEXTURE_2D); + } + if (currTarget == GL_TEXTURE_EXTERNAL_OES) { + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, + state->getBoundTexture(currTarget)); + } + } + + } else { + ctx->m_glEnable_enc(ctx, cap); + } +} + +void GLEncoder::s_glGetTexParameterfv(void* self, + GLenum target, GLenum pname, GLfloat* params) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params); + } +} + +void GLEncoder::s_glGetTexParameteriv(void* self, + GLenum target, GLenum pname, GLint* params) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + switch (pname) { + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: + *params = 1; + break; + + default: + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params); + } + break; + } +} + +void GLEncoder::s_glGetTexParameterxv(void* self, + GLenum target, GLenum pname, GLfixed* params) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glGetTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glGetTexParameterxv_enc(ctx, target, pname, params); + } +} + +static bool isValidTextureExternalParam(GLenum pname, GLenum param) +{ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + return param == GL_NEAREST || param == GL_LINEAR; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + return param == GL_CLAMP_TO_EDGE; + + case GL_GENERATE_MIPMAP: + return param == GL_FALSE; + + default: + return true; + } +} + +void GLEncoder::s_glTexParameterf(void* self, + GLenum target, GLenum pname, GLfloat param) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)param)), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameterf_enc(ctx, target, pname, param); + } +} + +void GLEncoder::s_glTexParameterfv(void* self, + GLenum target, GLenum pname, const GLfloat* params) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)params[0])), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameterfv_enc(ctx, target, pname, params); + } +} + +void GLEncoder::s_glTexParameteri(void* self, + GLenum target, GLenum pname, GLint param) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)param)), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameteri_enc(ctx, target, pname, param); + } +} + +void GLEncoder::s_glTexParameterx(void* self, + GLenum target, GLenum pname, GLfixed param) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)param)), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameterx_enc(ctx, GL_TEXTURE_2D, pname, param); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameterx_enc(ctx, target, pname, param); + } +} + +void GLEncoder::s_glTexParameteriv(void* self, + GLenum target, GLenum pname, const GLint* params) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)params[0])), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameteriv_enc(ctx, target, pname, params); + } +} + +void GLEncoder::s_glTexParameterxv(void* self, + GLenum target, GLenum pname, const GLfixed* params) +{ + GLEncoder* ctx = (GLEncoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)params[0])), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameterxv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameterxv_enc(ctx, target, pname, params); + } +} + +void GLEncoder::override2DTextureTarget(GLenum target) +{ + if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) && + target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) { + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture(target)); + } +} + +void GLEncoder::restore2DTextureTarget() +{ + GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture(priorityTarget)); +} + +GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream) +{ + m_initialized = false; + m_state = NULL; + m_error = GL_NO_ERROR; + m_num_compressedTextureFormats = 0; + m_compressedTextureFormats = NULL; + // overrides; + m_glFlush_enc = set_glFlush(s_glFlush); + m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei); + m_glVertexPointer_enc = set_glVertexPointer(s_glVertexPointer); + m_glNormalPointer_enc = set_glNormalPointer(s_glNormalPointer); + m_glColorPointer_enc = set_glColorPointer(s_glColorPointer); + m_glPointSizePointerOES_enc = set_glPointSizePointerOES(s_glPointsizePointer); + m_glClientActiveTexture_enc = set_glClientActiveTexture(s_glClientActiveTexture); + m_glTexCoordPointer_enc = set_glTexCoordPointer(s_glTexcoordPointer); + m_glMatrixIndexPointerOES_enc = set_glMatrixIndexPointerOES(s_glMatrixIndexPointerOES); + m_glWeightPointerOES_enc = set_glWeightPointerOES(s_glWeightPointerOES); + + m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv); + m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv); + m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv); + m_glGetFixedv_enc = set_glGetFixedv(s_glGetFixedv); + m_glGetPointerv_enc = set_glGetPointerv(s_glGetPointerv); + + m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer); + m_glBufferData_enc = set_glBufferData(s_glBufferData); + m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData); + m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers); + + m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState); + m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState); + m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled); + m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays); + m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); + set_glGetString(s_glGetString); + set_glFinish(s_glFinish); + m_glGetError_enc = set_glGetError(s_glGetError); + + m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture); + m_glBindTexture_enc = set_glBindTexture(s_glBindTexture); + m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures); + m_glDisable_enc = set_glDisable(s_glDisable); + m_glEnable_enc = set_glEnable(s_glEnable); + m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv); + m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv); + m_glGetTexParameterxv_enc = set_glGetTexParameterxv(s_glGetTexParameterxv); + m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf); + m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv); + m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri); + m_glTexParameterx_enc = set_glTexParameterx(s_glTexParameterx); + m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv); + m_glTexParameterxv_enc = set_glTexParameterxv(s_glTexParameterxv); +} + +GLEncoder::~GLEncoder() +{ + delete [] m_compressedTextureFormats; +} + +size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) +{ + assert(m_state != NULL); + return m_state->pixelDataSize(width, height, format, type, pack); +} + +void GLEncoder::s_glFinish(void *self) +{ + GLEncoder *ctx = (GLEncoder *)self; + ctx->glFinishRoundTrip(self); +} diff --git a/emulator/opengl/system/GLESv1_enc/GLEncoder.h b/emulator/opengl/system/GLESv1_enc/GLEncoder.h new file mode 100644 index 0000000..effc53f --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/GLEncoder.h @@ -0,0 +1,149 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _GL_ENCODER_H_ +#define _GL_ENCODER_H_ + +#include "gl_enc.h" +#include "GLClientState.h" +#include "GLSharedGroup.h" +#include "FixedBuffer.h" + +class GLEncoder : public gl_encoder_context_t { + +public: + GLEncoder(IOStream *stream); + virtual ~GLEncoder(); + void setClientState(GLClientState *state) { + m_state = state; + } + void setSharedGroup(GLSharedGroupPtr shared) { m_shared = shared; } + void flush() { m_stream->flush(); } + size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack); + + void setInitialized(){ m_initialized = true; }; + bool isInitialized(){ return m_initialized; }; + + virtual void setError(GLenum error){ m_error = error; }; + virtual GLenum getError() { return m_error; }; + + void override2DTextureTarget(GLenum target); + void restore2DTextureTarget(); + +private: + + bool m_initialized; + GLClientState *m_state; + GLSharedGroupPtr m_shared; + GLenum m_error; + FixedBuffer m_fixedBuffer; + GLint *m_compressedTextureFormats; + GLint m_num_compressedTextureFormats; + + GLint *getCompressedTextureFormats(); + // original functions; + glGetError_client_proc_t m_glGetError_enc; + glGetIntegerv_client_proc_t m_glGetIntegerv_enc; + glGetFloatv_client_proc_t m_glGetFloatv_enc; + glGetFixedv_client_proc_t m_glGetFixedv_enc; + glGetBooleanv_client_proc_t m_glGetBooleanv_enc; + glGetPointerv_client_proc_t m_glGetPointerv_enc; + + glPixelStorei_client_proc_t m_glPixelStorei_enc; + glVertexPointer_client_proc_t m_glVertexPointer_enc; + glNormalPointer_client_proc_t m_glNormalPointer_enc; + glColorPointer_client_proc_t m_glColorPointer_enc; + glPointSizePointerOES_client_proc_t m_glPointSizePointerOES_enc; + glTexCoordPointer_client_proc_t m_glTexCoordPointer_enc; + glClientActiveTexture_client_proc_t m_glClientActiveTexture_enc; + glMatrixIndexPointerOES_client_proc_t m_glMatrixIndexPointerOES_enc; + glWeightPointerOES_client_proc_t m_glWeightPointerOES_enc; + + glBindBuffer_client_proc_t m_glBindBuffer_enc; + glBufferData_client_proc_t m_glBufferData_enc; + glBufferSubData_client_proc_t m_glBufferSubData_enc; + glDeleteBuffers_client_proc_t m_glDeleteBuffers_enc; + + glEnableClientState_client_proc_t m_glEnableClientState_enc; + glDisableClientState_client_proc_t m_glDisableClientState_enc; + glIsEnabled_client_proc_t m_glIsEnabled_enc; + glDrawArrays_client_proc_t m_glDrawArrays_enc; + glDrawElements_client_proc_t m_glDrawElements_enc; + glFlush_client_proc_t m_glFlush_enc; + + glActiveTexture_client_proc_t m_glActiveTexture_enc; + glBindTexture_client_proc_t m_glBindTexture_enc; + glDeleteTextures_client_proc_t m_glDeleteTextures_enc; + glDisable_client_proc_t m_glDisable_enc; + glEnable_client_proc_t m_glEnable_enc; + glGetTexParameterfv_client_proc_t m_glGetTexParameterfv_enc; + glGetTexParameteriv_client_proc_t m_glGetTexParameteriv_enc; + glGetTexParameterxv_client_proc_t m_glGetTexParameterxv_enc; + glTexParameterf_client_proc_t m_glTexParameterf_enc; + glTexParameterfv_client_proc_t m_glTexParameterfv_enc; + glTexParameteri_client_proc_t m_glTexParameteri_enc; + glTexParameterx_client_proc_t m_glTexParameterx_enc; + glTexParameteriv_client_proc_t m_glTexParameteriv_enc; + glTexParameterxv_client_proc_t m_glTexParameterxv_enc; + + // statics + static GLenum s_glGetError(void * self); + static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr); + static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr); + static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr); + static void s_glGetFixedv(void *self, GLenum pname, GLfixed *ptr); + static void s_glGetPointerv(void *self, GLenum pname, GLvoid **params); + + static void s_glFlush(void * self); + static const GLubyte * s_glGetString(void *self, GLenum name); + static void s_glVertexPointer(void *self, int size, GLenum type, GLsizei stride, const void *data); + static void s_glNormalPointer(void *self, GLenum type, GLsizei stride, const void *data); + static void s_glColorPointer(void *self, int size, GLenum type, GLsizei stride, const void *data); + static void s_glPointsizePointer(void *self, GLenum type, GLsizei stride, const void *data); + static void s_glClientActiveTexture(void *self, GLenum texture); + static void s_glTexcoordPointer(void *self, int size, GLenum type, GLsizei stride, const void *data); + static void s_glMatrixIndexPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data); + static void s_glWeightPointerOES(void *self, int size, GLenum type, GLsizei stride, const void * data); + static void s_glDisableClientState(void *self, GLenum state); + static void s_glEnableClientState(void *self, GLenum state); + static GLboolean s_glIsEnabled(void *self, GLenum cap); + static void s_glBindBuffer(void *self, GLenum target, GLuint id); + static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); + static void s_glBufferSubData(void *self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); + static void s_glDeleteBuffers(void *self, GLsizei n, const GLuint * buffers); + + static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count); + static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices); + static void s_glPixelStorei(void *self, GLenum param, GLint value); + + static void s_glFinish(void *self); + void sendVertexData(unsigned first, unsigned count); + + static void s_glActiveTexture(void* self, GLenum texture); + static void s_glBindTexture(void* self, GLenum target, GLuint texture); + static void s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures); + static void s_glDisable(void* self, GLenum cap); + static void s_glEnable(void* self, GLenum cap); + static void s_glGetTexParameterfv(void* self, GLenum target, GLenum pname, GLfloat* params); + static void s_glGetTexParameteriv(void* self, GLenum target, GLenum pname, GLint* params); + static void s_glGetTexParameterxv(void* self, GLenum target, GLenum pname, GLfixed* params); + static void s_glTexParameterf(void* self, GLenum target, GLenum pname, GLfloat param); + static void s_glTexParameterfv(void* self, GLenum target, GLenum pname, const GLfloat* params); + static void s_glTexParameteri(void* self, GLenum target, GLenum pname, GLint param); + static void s_glTexParameterx(void* self, GLenum target, GLenum pname, GLfixed param); + static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params); + static void s_glTexParameterxv(void* self, GLenum target, GLenum pname, const GLfixed* params); +}; +#endif diff --git a/emulator/opengl/system/GLESv1_enc/GLEncoderUtils.cpp b/emulator/opengl/system/GLESv1_enc/GLEncoderUtils.cpp new file mode 100644 index 0000000..7866d53 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/GLEncoderUtils.cpp @@ -0,0 +1,24 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include <stdio.h> +#include <stdlib.h> +#include "GLEncoder.h" + +size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) +{ + GLEncoder *ctx = (GLEncoder *)self; + return ctx->pixelDataSize(width, height, format, type, pack); +} diff --git a/emulator/opengl/system/GLESv1_enc/GLEncoderUtils.h b/emulator/opengl/system/GLESv1_enc/GLEncoderUtils.h new file mode 100644 index 0000000..1d0c847 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/GLEncoderUtils.h @@ -0,0 +1,22 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef GL_ENCODER_UTILS_H +#define GL_ENCLODER_UTILS_H + +extern "C" { + size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack); +}; +#endif diff --git a/emulator/opengl/system/GLESv1_enc/gl.addon b/emulator/opengl/system/GLESv1_enc/gl.addon new file mode 100644 index 0000000..2331f87 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/gl.addon @@ -0,0 +1,15 @@ +GL_ENTRY(void, glVertexPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glColorPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glNormalPointerOffset, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glPointSizePointerOffset, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glTexCoordPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) + +GL_ENTRY(void, glVertexPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glColorPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glNormalPointerData, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glTexCoordPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glPointSizePointerData, GLenum type, GLsizei stride, void * data, GLuint datalen) + +GL_ENTRY(void, glDrawElementsOffset, GLenum mode, GLsizei count, GLenum type, GLuint offset); +GL_ENTRY(void, glDrawElementsData, GLenum mode, GLsizei count, GLenum type, void *data, GLuint datalen); + diff --git a/emulator/opengl/system/GLESv1_enc/gl.attrib b/emulator/opengl/system/GLESv1_enc/gl.attrib new file mode 100644 index 0000000..9b84f89 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/gl.attrib @@ -0,0 +1,691 @@ +GLOBAL + base_opcode 1024 + encoder_headers "glUtils.h" "GLEncoderUtils.h" + +#void glClipPlanef(GLenum plane, GLfloat *equation) +glClipPlanef + dir equation in + len equation (4 * sizeof(float)) + +#void glFogfv(GLenum pname, GLfloat *params) +glFogfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetFloatv(GLenum pname, GLfloat *params) +glGetFloatv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetLightfv(GLenum light, GLenum pname, GLfloat *params) +glGetLightfv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params) +glGetMaterialfv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetTexEnvfv(GLenum env, GLenum pname, GLfloat *params) +glGetTexEnvfv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +glGetTexParameterfv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glLightModelfv(GLenum pname, GLfloat *params) +glLightModelfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glLightfv(GLenum light, GLenum pname, GLfloat *params) +glLightfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glLoadMatrixf(GLfloat *m) +glLoadMatrixf + len m (16 * sizeof(GLfloat)) + +#void glMaterialfv(GLenum face, GLenum pname, GLfloat *params) +glMaterialfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glMultMatrixf(GLfloat *m) +glMultMatrixf + len m (16 * sizeof(GLfloat)) + +#void glPointParameterfv(GLenum pname, GLfloat *params) +glPointParameterfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glTexEnvfv(GLenum target, GLenum pname, GLfloat *params) +glTexEnvfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +glTexParameterfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glBufferData(GLenum target, GLsizeiptr size, GLvoid *data, GLenum usage) +glBufferData + len data size + +#void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) +glBufferSubData + dir data in + len data size + +#void glClipPlanex(GLenum plane, GLfixed *eqn) +glClipPlanex + dir eqn in + len eqn (4 * sizeof(GLfixed)) + +#void glColorPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer) +#we treat the pointer as offset to a VBO +glColorPointer + len pointer (sizeof(unsigned int)) + flag unsupported + +#void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLvoid *data) +glCompressedTexImage2D + len data imageSize + var_flag data nullAllowed + +#void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLvoid *data) +glCompressedTexSubImage2D + len data imageSize + +#void glDeleteBuffers(GLsizei n, GLuint *buffers) +glDeleteBuffers + len buffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glDeleteTextures(GLsizei n, GLuint *textures) +glDeleteTextures + len textures (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#this function is marked as unsupported - it shouldn't be called directly +#instead it translated into - glDrawDirectElements and glDrawIndirectElements +#void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid *indices) +glDrawElements + flag unsupported + + +#void glFogxv(GLenum pname, GLfixed *params) +glFogxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetBooleanv(GLenum pname, GLboolean *params) +glGetBooleanv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLboolean)) + +#void glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params) +glGetBufferParameteriv + len params (sizeof(GLint)) + dir params out + +#void glGenBuffers(GLsizei n, GLuint *buffers) +glGenBuffers + len buffers (n * sizeof(GLuint)) + dir buffers out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenTextures(GLsizei n, GLuint *textures) +glGenTextures + len textures (n * sizeof(GLuint)) + dir textures out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGetFixedv(GLenum pname, GLfixed *params) +glGetFixedv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetIntegerv(GLenum pname, GLint *params) +glGetIntegerv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glGetLightxv(GLenum light, GLenum pname, GLfixed *params) +glGetLightxv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetMaterialxv(GLenum face, GLenum pname, GLfixed *params) +glGetMaterialxv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetPointerv(GLenum pname, void **params) +glGetPointerv + flag unsupported + +#GLubyte* glGetString(GLenum name) +glGetString + flag unsupported + +#void glGetTexEnviv(GLenum env, GLenum pname, GLint *params) +glGetTexEnviv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glGetTexEnvxv(GLenum env, GLenum pname, GLfixed *params) +glGetTexEnvxv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) +glGetTexParameteriv + dir params out + len params (sizeof(GLint)) + +#void glGetTexParameterxv(GLenum target, GLenum pname, GLfixed *params) +glGetTexParameterxv + dir params out + len params (sizeof(GLfixed)) + +#void glLightModelxv(GLenum pname, GLfixed *params) +glLightModelxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glLightxv(GLenum light, GLenum pname, GLfixed *params) +glLightxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glLoadMatrixx(GLfixed *m) +glLoadMatrixx + len m (16 * sizeof(GLfixed)) + +#void glMaterialxv(GLenum face, GLenum pname, GLfixed *params) +glMaterialxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glMultMatrixx(GLfixed *m) +glMultMatrixx + len m (16 * sizeof(GLfixed)) + +#void glNormalPointer(GLenum type, GLsizei stride, GLvoid *pointer) +#we treat the pointer as an offset to a VBO +glNormalPointer + len pointer (sizeof(unsigned int)) + flag unsupported + +#void glPointParameterxv(GLenum pname, GLfixed *params) +glPointParameterxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +glReadPixels + dir pixels out + len pixels pixelDataSize(self, width, height, format, type, 1) + +#void glTexCoordPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer) +glTexCoordPointer + len pointer (sizeof(unsigned int)) + flag unsupported + +#void glTexEnviv(GLenum target, GLenum pname, GLint *params) +glTexEnviv + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glTexEnvxv(GLenum target, GLenum pname, GLfixed *params) +glTexEnvxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid *pixels) +glTexImage2D + dir pixels in + len pixels pixelDataSize(self, width, height, format, type, 0) + var_flag pixels nullAllowed isLarge + +#void glTexParameteriv(GLenum target, GLenum pname, GLint *params) +glTexParameteriv + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glTexParameterxv(GLenum target, GLenum pname, GLfixed *params) +glTexParameterxv + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +glTexSubImage2D + len pixels pixelDataSize(self, width, height, format, type, 0) + var_flag pixels isLarge + +#void glVertexPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer) +# we treat the pointer as an offset to a VBO +glVertexPointer + flag unsupported + +#void glPointSizePointerOES(GLenum type, GLsizei stride, GLvoid *pointer) +glPointSizePointerOES + len pointer (sizeof(unsigned int)) + flag unsupported + +#void glGetClipPlanef(GLenum pname, GLfloat * eqn) +glGetClipPlanef + dir eqn out + len eqn (4 * sizeof(GLfloat)) + +#void glVertexPointerData(GLint size, GLenum type, GLsizei stride, void *data, GLuint datalen) +glVertexPointerData + len data datalen + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen) + flag custom_decoder + flag not_api + +#void glColorPointerData(GLint size, GLenum type, GLsizei stride, void *data, GLuint datalen) +glColorPointerData + len data datalen + flag custom_decoder + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen) + flag not_api + +#void glNormalPointerData(GLenum type, GLsizei stride, void *data, GLuint datalen) +glNormalPointerData + len data datalen + flag custom_decoder + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, 3, type, stride, datalen) + flag not_api + +#void glPointSizePointerData(GLenum type, GLsizei stride, void *data, GLuint datalen) +glPointSizePointerData + len data datalen + flag custom_decoder + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, 1, type, stride, datalen) + flag not_api + +#void glTexCoordPointerData(GLint size, GLenum type, GLsizei stride, void *data, GLuint datalen) +glTexCoordPointerData + len data datalen + flag custom_decoder + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen) + flag not_api + +#void glWeightPointerData(GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +glWeightPointerData + len data datalen + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char*)data, size, type, stride, datalen) + flag custom_decoder + flag not_api + +#void glMatrixIndexPointerData(GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +glMatrixIndexPointerData + len data datalen + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char*)data, size, type, stride, datalen) + flag custom_decoder + flag not_api + +glVertexPointerOffset + flag custom_decoder + flag not_api +glNormalPointerOffset + flag custom_decoder + flag not_api +glTexCoordPointerOffset + flag custom_decoder + flag not_api +glPointSizePointerOffset + flag custom_decoder + flag not_api +glColorPointerOffset + flag custom_decoder + flag not_api +glWeightPointerOffset + flag custom_decoder + flag not_api +glMatrixIndexPointerOffset + flag custom_decoder + flag not_api + +glDrawElementsData + len data datalen + flag custom_decoder + flag not_api + +glDrawElementsOffset + flag custom_decoder + flag not_api + +glGetCompressedTextureFormats + dir formats out + len formats (count * sizeof(GLint)) + flag custom_decoder + flag not_api + +glFinishRoundTrip + flag custom_decoder + flag not_api + +#gles1 extensions + +#void glDrawTexsvOES(GLshort *coords) +glDrawTexsvOES + len coords (5 * sizeof(GLshort)) + +#void glDrawTexivOES(GLint *coords) +glDrawTexivOES + len coords (5 * sizeof(GLint)) + +#void glDrawTexxvOES(GLfixed *coords) +glDrawTexxvOES + len coords (5 * sizeof(GLfixed)) + +#void glDrawTexfvOES(GLfloat *coords) +glDrawTexfvOES + len coords (5 * sizeof(GLfloat)) + +#glClipPlanexOES(GLenum plane, const GLfixed * equation) +glClipPlanexOES + dir equation in + len equation (4 * sizeof(GLfixed)) + +#glClipPlanexIMG(GLenum plane, const GLfixed * equation) +glClipPlanexIMG + dir equation in + len equation (4 * sizeof(GLfixed)) + +#void glFogxvOES(GLenum pname, GLfixed *params) +glFogxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetClipPlanexOES(GLenum pname, GLfixed * eqn) +glGetClipPlanexOES + dir eqn out + len eqn (4 * sizeof(GLfixed)) + +#void glGetClipPlanex(GLenum pname, GLfixed * eqn) +glGetClipPlanex + dir eqn out + len eqn (4 * sizeof(GLfixed)) + +#void glGetFixedvOES(GLenum pname, GLfixed *params) +glGetFixedvOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetLightxvOES(GLenum light, GLenum pname, GLfixed *params) +glGetLightxvOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetMaterialxvOES(GLenum face, GLenum pname, GLfixed *params) +glGetMaterialxvOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetTexEnvxvOES(GLenum env, GLenum pname, GLfixed *params) +glGetTexEnvxvOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params) +glGetTexParameterxvOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glLightModelxvOES(GLenum pname, GLfixed *params) +glLightModelxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glLightxvOES(GLenum light, GLenum pname, GLfixed *params) +glLightxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glLoadMatrixxOES(GLfixed *m) +glLoadMatrixxOES + dir m in + len m (16 * sizeof(GLfixed)) + +#void glMaterialxvOES(GLenum face, GLenum pname, GLfixed *params) +glMaterialxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glMultMatrixxOES(GLfixed *m) +glMultMatrixxOES + dir m in + len m (16 * sizeof(GLfixed)) + +#void glPointParameterxvOES(GLenum pname, GLfixed *params) +glPointParameterxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glTexEnvxvOES(GLenum target, GLenum pname, GLfixed *params) +glTexEnvxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glTexParameterxvOES(GLenum target, GLenum pname, GLfixed *params) +glTexParameterxvOES + dir params in + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glDeleteRenderbuffersOES(GLsizei n, GLuint *renderbuffers) +glDeleteRenderbuffersOES + dir renderbuffers in + len renderbuffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenRenderbuffersOES(GLsizei n, GLuint *renderbuffers) +glGenRenderbuffersOES + dir renderbuffers out + len renderbuffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint *params) +glGetRenderbufferParameterivOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glDeleteFramebuffersOES(GLsizei n, GLuint *framebuffers) +glDeleteFramebuffersOES + dir framebuffers in + len framebuffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenFramebuffersOES(GLsizei n, GLuint *framebuffers) +glGenFramebuffersOES + dir framebuffers out + len framebuffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint *params) +glGetFramebufferAttachmentParameterivOES + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void* glMapBufferOES(GLenum target, GLenum access) +glMapBufferOES + flag unsupported + +#void glGetBufferPointervOES(GLenum target, GLenum pname, GLvoid ** params) +glGetBufferPointervOES + flag unsupported + +#void glMatrixIndexPointerOES(GLint size, GLenum type, GLsizei stride, GLvoid *pointer) +glMatrixIndexPointerOES + len pointer (sizeof(unsigned int)) + flag unsupported + +#void glWeightPointerOES(GLint size, GLenum type, GLsizei stride, GLvoid *pointer) +glWeightPointerOES + len pointer (sizeof(unsigned int)) + flag unsupported + +#glQueryMatrixxOES(GLfixed * mantissa, GLint * exponent) +glQueryMatrixxOES + dir mantissa out + len mantissa (16 * sizeof(GLfixed)) + dir exponent out + len exponent (16 * sizeof(GLfixed)) + +#void glClipPlanefOES(GLenum plane, GLfloat *equation) +glClipPlanefOES + dir equation in + len equation (4 * sizeof(GLfloat)) + +#void glClipPlanefIMG(GLenum plane, GLfloat *equation) +glClipPlanefIMG + dir equation in + len equation (4 * sizeof(GLfloat)) + +#void glGetClipPlanefOES(GLenum pname, GLfloat * eqn) +glGetClipPlanefOES + dir eqn out + len eqn (4 * sizeof(GLfloat)) + +#void glTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params) +glTexGenfvOES + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glTexGenivOES(GLenum coord, GLenum pname, GLint *params) +glTexGenivOES + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params) +glTexGenxvOES + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glGetTexGenfvOES(GLenum coord, GLenum pname, GLfloat *params) +glGetTexGenfvOES + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetTexGenivOES(GLenum coord, GLenum pname, GLint *params) +glGetTexGenivOES + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glGetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params) +glGetTexGenxvOES + len params (glUtilsParamSize(pname) * sizeof(GLfixed)) + +#void glDeleteVertexArraysOES(GLsizei n, const GLuint *arrays) +glDeleteVertexArraysOES + dir arrays in + len arrays (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenVertexArraysOES(GLsizei n, GLuint *arrays) +glGenVertexArraysOES + dir arrays out + len arrays (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, const GLenum *attachments) +glDiscardFramebufferEXT + dir attachments in + len attachments (numAttachments * sizeof(const GLenum)) + +#void glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) +glMultiDrawArraysEXT + flag unsupported + +#void glMultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) +glMultiDrawElementsEXT + flag unsupported + +#void glMultiDrawArraysSUN(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) +glMultiDrawArraysSUN + flag unsupported + +#void glMultiDrawElementsSUN(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) +glMultiDrawElementsSUN + flag unsupported + +#void glDeleteFencesNV(GLsizei n, const GLuint *fences) +glDeleteFencesNV + dir fences in + len fences (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenFencesNV(GLsizei n, GLuint *fences) +glGenFencesNV + dir fences in + len fences (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) +glGetFenceivNV + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls) +glGetDriverControlsQCOM + dir num out + len num (1 * sizeof(GLint)) + dir driverControls out + len driverControls (size * sizeof(GLuint)) + +#void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) +glGetDriverControlStringQCOM + dir length out + len length (1 * sizeof(GLsizei)) + dir driverControlString out + len driverControlString (1 * sizeof(GLchar)) + +#void glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *numTextures) +glExtGetTexturesQCOM + dir textures out + len textures (maxTextures * sizeof(GLuint)) + dir numTextures out + len numTextures (1 * sizeof(GLint)) + +#void glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) +glExtGetBuffersQCOM + dir buffers out + len buffers (maxBuffers * sizeof(GLuint)) + dir numBuffers out + len numBuffers (1 * sizeof(GLint)) + +#void glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) +glExtGetRenderbuffersQCOM + dir renderbuffers out + len renderbuffers (maxRenderbuffers * sizeof(GLuint)) + dir numRenderbuffers out + len numRenderbuffers (1 * sizeof(GLint)) + +#void glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) +glExtGetFramebuffersQCOM + dir framebuffers out + len framebuffers (maxFramebuffers * sizeof(GLuint)) + dir numFramebuffers out + len numFramebuffers (1 * sizeof(GLint)) + +#void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) +glExtGetTexLevelParameterivQCOM + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) +glExtGetTexSubImageQCOM + dir texels out + len texels (depth * pixelDataSize(self, width, height, format, type, 0)) + +#void glExtGetBufferPointervQCOM(GLenum target, GLvoid **params) +glExtGetBufferPointervQCOM + flag unsupported + +#void glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numShaders) +glExtGetShadersQCOM + dir shaders out + len shaders (maxShaders * sizeof(GLuint)) + dir numShaders out + len numShaders (1 * sizeof(GLint)) + +#void glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *numPrograms) +glExtGetProgramsQCOM + dir programs out + len programs (maxPrograms * sizeof(GLuint)) + dir numPrograms out + len numPrograms (1 * sizeof(GLint)) + +#void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length) +glExtGetProgramBinarySourceQCOM + flag unsupported diff --git a/emulator/opengl/system/GLESv1_enc/gl.in b/emulator/opengl/system/GLESv1_enc/gl.in new file mode 100644 index 0000000..4340608 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/gl.in @@ -0,0 +1,299 @@ +GL_ENTRY(void, glAlphaFunc, GLenum func, GLclampf ref) +GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glClearDepthf, GLclampf depth) +GL_ENTRY(void, glClipPlanef, GLenum plane, const GLfloat *equation) +GL_ENTRY(void, glColor4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) +GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) +GL_ENTRY(void, glFogf, GLenum pname, GLfloat param) +GL_ENTRY(void, glFogfv, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glFrustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glGetClipPlanef, GLenum pname, GLfloat* eqn) +GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetLightfv, GLenum light, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetMaterialfv, GLenum face, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetTexEnvfv, GLenum env, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat *params) +GL_ENTRY(void, glLightModelf, GLenum pname, GLfloat param) +GL_ENTRY(void, glLightModelfv, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glLightf, GLenum light, GLenum pname, GLfloat param) +GL_ENTRY(void, glLightfv, GLenum light, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glLineWidth, GLfloat width) +GL_ENTRY(void, glLoadMatrixf, const GLfloat *m) +GL_ENTRY(void, glMaterialf, GLenum face, GLenum pname, GLfloat param) +GL_ENTRY(void, glMaterialfv, GLenum face, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glMultMatrixf, const GLfloat *m) +GL_ENTRY(void, glMultiTexCoord4f, GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) +GL_ENTRY(void, glNormal3f, GLfloat nx, GLfloat ny, GLfloat nz) +GL_ENTRY(void, glOrthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glPointParameterf, GLenum pname, GLfloat param) +GL_ENTRY(void, glPointParameterfv, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glPointSize, GLfloat size) +GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) +GL_ENTRY(void, glRotatef, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glScalef, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glTexEnvf, GLenum target, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexEnvfv, GLenum target, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glTranslatef, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glActiveTexture, GLenum texture) +GL_ENTRY(void, glAlphaFuncx, GLenum func, GLclampx ref) +GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer) +GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture) +GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) +GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) +GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) +GL_ENTRY(void, glClear, GLbitfield mask) +GL_ENTRY(void, glClearColorx, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) +GL_ENTRY(void, glClearDepthx, GLclampx depth) +GL_ENTRY(void, glClearStencil, GLint s) +GL_ENTRY(void, glClientActiveTexture, GLenum texture) +GL_ENTRY(void, glColor4ub, GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) +GL_ENTRY(void, glColor4x, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +GL_ENTRY(void, glColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) +GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) +GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glCullFace, GLenum mode) +GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint *buffers) +GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint *textures) +GL_ENTRY(void, glDepthFunc, GLenum func) +GL_ENTRY(void, glDepthMask, GLboolean flag) +GL_ENTRY(void, glDepthRangex, GLclampx zNear, GLclampx zFar) +GL_ENTRY(void, glDisable, GLenum cap) +GL_ENTRY(void, glDisableClientState, GLenum array) +GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) +GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) +GL_ENTRY(void, glEnable, GLenum cap) +GL_ENTRY(void, glEnableClientState, GLenum array) +GL_ENTRY(void, glFinish, void) +GL_ENTRY(void, glFlush, void) +GL_ENTRY(void, glFogx, GLenum pname, GLfixed param) +GL_ENTRY(void, glFogxv, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glFrontFace, GLenum mode) +GL_ENTRY(void, glFrustumx, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean *params) +GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint *params) +GL_ENTRY(void, glClipPlanex, GLenum pname, const GLfixed * eqn) +GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint *buffers) +GL_ENTRY(void, glGenTextures, GLsizei n, GLuint *textures) +GL_ENTRY(GLenum, glGetError, void) +GL_ENTRY(void, glGetFixedv, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint *params) +GL_ENTRY(void, glGetLightxv, GLenum light, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetMaterialxv, GLenum face, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetPointerv, GLenum pname, GLvoid **params) +GL_ENTRY(const GLubyte *, glGetString, GLenum name) +GL_ENTRY(void, glGetTexEnviv, GLenum env, GLenum pname, GLint *params) +GL_ENTRY(void, glGetTexEnvxv, GLenum env, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint *params) +GL_ENTRY(void, glGetTexParameterxv, GLenum target, GLenum pname, GLfixed *params) +GL_ENTRY(void, glHint, GLenum target, GLenum mode) +GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer) +GL_ENTRY(GLboolean, glIsEnabled, GLenum cap) +GL_ENTRY(GLboolean, glIsTexture, GLuint texture) +GL_ENTRY(void, glLightModelx, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightModelxv, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLightx, GLenum light, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightxv, GLenum light, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLineWidthx, GLfixed width) +GL_ENTRY(void, glLoadIdentity, void) +GL_ENTRY(void, glLoadMatrixx, const GLfixed *m) +GL_ENTRY(void, glLogicOp, GLenum opcode) +GL_ENTRY(void, glMaterialx, GLenum face, GLenum pname, GLfixed param) +GL_ENTRY(void, glMaterialxv, GLenum face, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glMatrixMode, GLenum mode) +GL_ENTRY(void, glMultMatrixx, const GLfixed *m) +GL_ENTRY(void, glMultiTexCoord4x, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) +GL_ENTRY(void, glNormal3x, GLfixed nx, GLfixed ny, GLfixed nz) +GL_ENTRY(void, glNormalPointer, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glOrthox, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param) +GL_ENTRY(void, glPointParameterx, GLenum pname, GLfixed param) +GL_ENTRY(void, glPointParameterxv, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glPointSizex, GLfixed size) +GL_ENTRY(void, glPolygonOffsetx, GLfixed factor, GLfixed units) +GL_ENTRY(void, glPopMatrix, void) +GL_ENTRY(void, glPushMatrix, void) +GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +GL_ENTRY(void, glRotatex, GLfixed angle, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) +GL_ENTRY(void, glSampleCoveragex, GLclampx value, GLboolean invert) +GL_ENTRY(void, glScalex, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glShadeModel, GLenum mode) +GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilMask, GLuint mask) +GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(void, glTexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glTexEnvi, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glTexEnvx, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexEnviv, GLenum target, GLenum pname, const GLint *params) +GL_ENTRY(void, glTexEnvxv, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glTexParameterx, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint *params) +GL_ENTRY(void, glTexParameterxv, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +GL_ENTRY(void, glTranslatex, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glVertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) +GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glPointSizePointerOES, GLenum type, GLsizei stride, const GLvoid *pointer) + +GL_ENTRY(void, glVertexPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glColorPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glNormalPointerOffset, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glPointSizePointerOffset, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glTexCoordPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glWeightPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) +GL_ENTRY(void, glMatrixIndexPointerOffset, GLint size, GLenum type, GLsizei stride, GLuint offset) + +GL_ENTRY(void, glVertexPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glColorPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glNormalPointerData, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glTexCoordPointerData, GLint unit, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glPointSizePointerData, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glWeightPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glMatrixIndexPointerData, GLint size, GLenum type, GLsizei stride, void * data, GLuint datalen) + +GL_ENTRY(void, glDrawElementsOffset, GLenum mode, GLsizei count, GLenum type, GLuint offset) +GL_ENTRY(void, glDrawElementsData, GLenum mode, GLsizei count, GLenum type, void *data, GLuint datalen) +GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats); + +GL_ENTRY(int, glFinishRoundTrip, void) + +#opengl extensions + +GL_ENTRY(void, glBlendEquationSeparateOES, GLenum modeRGB, GLenum modeAlpha) +GL_ENTRY(void, glBlendFuncSeparateOES, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +GL_ENTRY(void, glBlendEquationOES, GLenum mode) +GL_ENTRY(void, glDrawTexsOES, GLshort x, GLshort y, GLshort z, GLshort width, GLshort height) +GL_ENTRY(void, glDrawTexiOES, GLint x, GLint y, GLint z, GLint width, GLint height) +GL_ENTRY(void, glDrawTexxOES, GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) +GL_ENTRY(void, glDrawTexsvOES, const GLshort *coords) +GL_ENTRY(void, glDrawTexivOES, const GLint *coords) +GL_ENTRY(void, glDrawTexxvOES, const GLfixed *coords) +GL_ENTRY(void, glDrawTexfOES, GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height) +GL_ENTRY(void, glDrawTexfvOES, const GLfloat *coords) +GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glAlphaFuncxOES, GLenum func, GLclampx ref) +GL_ENTRY(void, glClearColorxOES, GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) +GL_ENTRY(void, glClearDepthxOES, GLclampx depth) +GL_ENTRY(void, glClipPlanexOES, GLenum plane, const GLfixed * equation) +GL_ENTRY(void, glClipPlanexIMG, GLenum plane, const GLfixed * equation) +GL_ENTRY(void, glColor4xOES, GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) +GL_ENTRY(void, glDepthRangexOES, GLclampx zNear, GLclampx zFar) +GL_ENTRY(void, glFogxOES, GLenum pname, GLfixed param) +GL_ENTRY(void, glFogxvOES, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glFrustumxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glGetClipPlanexOES, GLenum pname, GLfixed* eqn) +GL_ENTRY(void, glGetClipPlanex, GLenum pname, GLfixed* eqn) +GL_ENTRY(void, glGetFixedvOES, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetLightxvOES, GLenum light, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetMaterialxvOES, GLenum face, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexEnvxvOES, GLenum env, GLenum pname, GLfixed *params) +GL_ENTRY(void, glGetTexParameterxvOES, GLenum target, GLenum pname, GLfixed *params) +GL_ENTRY(void, glLightModelxOES, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightModelxvOES, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLightxOES, GLenum light, GLenum pname, GLfixed param) +GL_ENTRY(void, glLightxvOES, GLenum light, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glLineWidthxOES, GLfixed width) +GL_ENTRY(void, glLoadMatrixxOES, const GLfixed *m) +GL_ENTRY(void, glMaterialxOES, GLenum face, GLenum pname, GLfixed param) +GL_ENTRY(void, glMaterialxvOES, GLenum face, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glMultMatrixxOES, const GLfixed *m) +GL_ENTRY(void, glMultiTexCoord4xOES, GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) +GL_ENTRY(void, glNormal3xOES, GLfixed nx, GLfixed ny, GLfixed nz) +GL_ENTRY(void, glOrthoxOES, GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) +GL_ENTRY(void, glPointParameterxOES, GLenum pname, GLfixed param) +GL_ENTRY(void, glPointParameterxvOES, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glPointSizexOES, GLfixed size) +GL_ENTRY(void, glPolygonOffsetxOES, GLfixed factor, GLfixed units) +GL_ENTRY(void, glRotatexOES, GLfixed angle, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glSampleCoveragexOES, GLclampx value, GLboolean invert) +GL_ENTRY(void, glScalexOES, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(void, glTexEnvxOES, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexEnvxvOES, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTexParameterxOES, GLenum target, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexParameterxvOES, GLenum target, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glTranslatexOES, GLfixed x, GLfixed y, GLfixed z) +GL_ENTRY(GLboolean, glIsRenderbufferOES, GLuint renderbuffer) +GL_ENTRY(void, glBindRenderbufferOES, GLenum target, GLuint renderbuffer) +GL_ENTRY(void, glDeleteRenderbuffersOES, GLsizei n, const GLuint* renderbuffers) +GL_ENTRY(void, glGenRenderbuffersOES, GLsizei n, GLuint* renderbuffers) +GL_ENTRY(void, glRenderbufferStorageOES, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glGetRenderbufferParameterivOES, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(GLboolean, glIsFramebufferOES, GLuint framebuffer) +GL_ENTRY(void, glBindFramebufferOES, GLenum target, GLuint framebuffer) +GL_ENTRY(void, glDeleteFramebuffersOES, GLsizei n, const GLuint* framebuffers) +GL_ENTRY(void, glGenFramebuffersOES, GLsizei n, GLuint* framebuffers) +GL_ENTRY(GLenum, glCheckFramebufferStatusOES, GLenum target) +GL_ENTRY(void, glFramebufferRenderbufferOES, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +GL_ENTRY(void, glFramebufferTexture2DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +GL_ENTRY(void, glGetFramebufferAttachmentParameterivOES, GLenum target, GLenum attachment, GLenum pname, GLint* params) +GL_ENTRY(void, glGenerateMipmapOES, GLenum target) +GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access) +GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target) +GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, GLvoid* *params) +GL_ENTRY(void, glCurrentPaletteMatrixOES, GLuint matrixpaletteindex) +GL_ENTRY(void, glLoadPaletteFromModelViewMatrixOES, void) +GL_ENTRY(void, glMatrixIndexPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) +GL_ENTRY(void, glWeightPointerOES, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) +GL_ENTRY(GLbitfield, glQueryMatrixxOES, GLfixed * mantissa, GLint * exponent) +GL_ENTRY(void, glDepthRangefOES, GLclampf zNear, GLclampf zFar) +GL_ENTRY(void, glFrustumfOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glOrthofOES, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) +GL_ENTRY(void, glClipPlanefOES, GLenum plane, const GLfloat *equation) +GL_ENTRY(void, glClipPlanefIMG, GLenum plane, const GLfloat *equation) +GL_ENTRY(void, glGetClipPlanefOES, GLenum pname, GLfloat * eqn) +GL_ENTRY(void, glClearDepthfOES, GLclampf depth) +GL_ENTRY(void, glTexGenfOES, GLenum coord, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexGenfvOES, GLenum coord, GLenum pname, const GLfloat *params) +GL_ENTRY(void, glTexGeniOES, GLenum coord, GLenum pname, GLint param) +GL_ENTRY(void, glTexGenivOES, GLenum coord, GLenum pname, const GLint *params) +GL_ENTRY(void, glTexGenxOES, GLenum coord, GLenum pname, GLfixed param) +GL_ENTRY(void, glTexGenxvOES, GLenum coord, GLenum pname, const GLfixed *params) +GL_ENTRY(void, glGetTexGenfvOES, GLenum coord, GLenum pname, GLfloat *params) +GL_ENTRY(void, glGetTexGenivOES, GLenum coord, GLenum pname, GLint *params) +GL_ENTRY(void, glGetTexGenxvOES, GLenum coord, GLenum pname, GLfixed *params) +GL_ENTRY(void, glBindVertexArrayOES, GLuint array) +GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays) +GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays) +GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array) +GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments) +GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) +GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount) +GL_ENTRY(void, glMultiDrawArraysSUN, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) +GL_ENTRY(void, glMultiDrawElementsSUN, GLenum mode, const GLsizei *count, GLenum type, const GLvoid **indices, GLsizei primcount) +GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) +GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences) +GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences) +GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence) +GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence) +GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params) +GL_ENTRY(void, glFinishFenceNV, GLuint fence) +GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition) +GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls) +GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) +GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glExtGetTexturesQCOM, GLuint *textures, GLint maxTextures, GLint *numTextures) +GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers) +GL_ENTRY(void, glExtGetRenderbuffersQCOM, GLuint * renderbuffers, GLint maxRenderbuffers, GLint * numRenderbuffers) +GL_ENTRY(void, glExtGetFramebuffersQCOM, GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) +GL_ENTRY(void, glExtGetTexLevelParameterivQCOM, GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) +GL_ENTRY(void, glExtTexObjectStateOverrideiQCOM, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glExtGetTexSubImageQCOM, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) +GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoid* *params) +GL_ENTRY(void, glExtGetShadersQCOM, GLuint *shaders, GLint maxShaders, GLint *numShaders) +GL_ENTRY(void, glExtGetProgramsQCOM, GLuint *programs, GLint maxPrograms, GLint *numPrograms) +GL_ENTRY(GLboolean, glExtIsProgramBinaryQCOM, GLuint program) +GL_ENTRY(void, glExtGetProgramBinarySourceQCOM, GLuint program, GLenum shadertype, GLchar *source, GLint *length) +GL_ENTRY(void, glStartTilingQCOM, GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) +GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask) + diff --git a/emulator/opengl/system/GLESv1_enc/gl.types b/emulator/opengl/system/GLESv1_enc/gl.types new file mode 100644 index 0000000..b269c01 --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/gl.types @@ -0,0 +1,33 @@ +GLbitfield 32 0x%08x false +GLboolean 8 %d false +GLclampf 32 %f false +GLclampx 32 0x%08x false +GLeglImageOES 32 %p false +GLenum 32 0x%08x false +GLfixed 32 0x%08x false +GLfloat 32 %f false +GLint 32 %d false +GLintptr 32 %p false +GLshort 16 %d false +GLsizei 32 %d false +GLsizeiptr 32 %p false +GLubyte 8 0x%02x false +GLuint 32 %u false +GLvoid 0 %x false +GLchar 8 %d false +GLenum* 32 0x%08x true +GLboolean* 32 0x%08x true +GLclampf* 32 0x%08x true +GLclampx* 32 0x%08x true +GLeglImageOES* 32 0x%08x true +GLfixed* 32 0x%08x true +GLfloat* 32 0x%08x true +GLint* 32 0x%08x true +GLshort* 32 0x%08x true +GLsizei* 32 0x%08x true +GLubyte* 32 0x%08x true +GLuint* 32 0x%08x true +GLvoid* 32 0x%08x true +GLchar* 32 0x%08x true +GLvoid** 32 0x%08x true +void* 32 0x%08x true diff --git a/emulator/opengl/system/GLESv1_enc/gl_types.h b/emulator/opengl/system/GLESv1_enc/gl_types.h new file mode 100644 index 0000000..36fabfb --- /dev/null +++ b/emulator/opengl/system/GLESv1_enc/gl_types.h @@ -0,0 +1,20 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __GL_TYPES__H +#define __GL_TYPES__H + +#include "gl_base_types.h" +#endif diff --git a/emulator/opengl/system/GLESv2/Android.mk b/emulator/opengl/system/GLESv2/Android.mk new file mode 100644 index 0000000..c299522 --- /dev/null +++ b/emulator/opengl/system/GLESv2/Android.mk @@ -0,0 +1,12 @@ +LOCAL_PATH := $(call my-dir) + +### GLESv2 implementation ########################################### +$(call emugl-begin-shared-library,libGLESv2_emulation) +$(call emugl-import,libOpenglSystemCommon libGLESv2_enc lib_renderControl_enc) + +LOCAL_CFLAGS += -DLOG_TAG=\"GLESv2_emulation\" -DGL_GLEXT_PROTOTYPES + +LOCAL_SRC_FILES := gl2.cpp +LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl + +$(call emugl-end-module) diff --git a/emulator/opengl/system/GLESv2/gl2.cpp b/emulator/opengl/system/GLESv2/gl2.cpp new file mode 100644 index 0000000..b32dd74 --- /dev/null +++ b/emulator/opengl/system/GLESv2/gl2.cpp @@ -0,0 +1,143 @@ +/* +* Copyright 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "EGLClientIface.h" +#include "HostConnection.h" +#include "GL2Encoder.h" +#include "GLES/gl.h" +#include "GLES/glext.h" +#include "ErrorLog.h" +#include "gralloc_cb.h" +#include "ThreadInfo.h" + +//XXX: fix this macro to get the context from fast tls path +#define GET_CONTEXT GL2Encoder * ctx = getEGLThreadInfo()->hostConn->gl2Encoder(); + +#include "gl2_entry.cpp" + +//The functions table +#include "gl2_ftable.h" + + +static EGLClient_eglInterface * s_egl = NULL; +static EGLClient_glesInterface * s_gl = NULL; + +#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ + HostConnection *hostCon = HostConnection::get(); \ + if (!hostCon) { \ + ALOGE("egl: Failed to get host connection\n"); \ + return ret; \ + } \ + renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ + if (!rcEnc) { \ + ALOGE("egl: Failed to get renderControl encoder context\n"); \ + return ret; \ + } + +//GL extensions +void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image) +{ + DBG("glEGLImageTargetTexture2DOES v2 target=%#x img=%p\n", target, image); + //TODO: check error - we don't have a way to set gl error + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + return; + } + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + return; + } + + GET_CONTEXT; + DEFINE_AND_VALIDATE_HOST_CONNECTION(); + + ctx->override2DTextureTarget(target); + rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle); + ctx->restore2DTextureTarget(); + + return; +} + +void glEGLImageTargetRenderbufferStorageOES(void *self, GLenum target, GLeglImageOES image) +{ + DBG("glEGLImageTargetRenderbufferStorageOES v2 image=%p\n", image); + //TODO: check error - we don't have a way to set gl error + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + return; + } + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + return; + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(); + rcEnc->rcBindRenderbuffer(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle); + + return; +} + +void * getProcAddress(const char * procname) +{ + // search in GL function table + for (int i=0; i<gl2_num_funcs; i++) { + if (!strcmp(gl2_funcs_by_name[i].name, procname)) { + return gl2_funcs_by_name[i].proc; + } + } + return NULL; +} + +void finish() +{ + glFinish(); +} + +const GLubyte *my_glGetString (void *self, GLenum name) +{ + if (s_egl) { + return (const GLubyte*)s_egl->getGLString(name); + } + return NULL; +} + +void init() +{ + GET_CONTEXT; + ctx->set_glEGLImageTargetTexture2DOES(glEGLImageTargetTexture2DOES); + ctx->set_glEGLImageTargetRenderbufferStorageOES(glEGLImageTargetRenderbufferStorageOES); + ctx->set_glGetString(my_glGetString); +} + +extern "C" { +EGLClient_glesInterface * init_emul_gles(EGLClient_eglInterface *eglIface) +{ + s_egl = eglIface; + + if (!s_gl) { + s_gl = new EGLClient_glesInterface(); + s_gl->getProcAddress = getProcAddress; + s_gl->finish = finish; + s_gl->init = init; + } + + return s_gl; +} +} //extern + + diff --git a/emulator/opengl/system/GLESv2_enc/Android.mk b/emulator/opengl/system/GLESv2_enc/Android.mk new file mode 100644 index 0000000..2a4d2f4 --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/Android.mk @@ -0,0 +1,18 @@ +LOCAL_PATH := $(call my-dir) + +### GLESv2_enc Encoder ########################################### +$(call emugl-begin-shared-library,libGLESv2_enc) + +LOCAL_SRC_FILES := \ + GL2EncoderUtils.cpp \ + GL2Encoder.cpp + +LOCAL_CFLAGS += -DLOG_TAG=\"emuglGLESv2_enc\" + +$(call emugl-gen-encoder,$(LOCAL_PATH),gl2) +$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) +$(call emugl-import,libOpenglCodecCommon) + +$(call emugl-end-module) + + diff --git a/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp new file mode 100644 index 0000000..d8fedf3 --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -0,0 +1,1197 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include "GL2Encoder.h" +#include <assert.h> +#include <ctype.h> + +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +static GLubyte *gVendorString= (GLubyte *) "Android"; +static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 2.0"; +static GLubyte *gVersionString= (GLubyte *) "OpenGL ES 2.0"; +static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; + +#define SET_ERROR_IF(condition,err) if((condition)) { \ + ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ + ctx->setError(err); \ + return; \ + } + + +#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \ + ALOGE("%s:%s:%d GL error 0x%x\n", __FILE__, __FUNCTION__, __LINE__, err); \ + ctx->setError(err); \ + return ret; \ + } + + +GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) +{ + m_initialized = false; + m_state = NULL; + m_error = GL_NO_ERROR; + m_num_compressedTextureFormats = 0; + m_compressedTextureFormats = NULL; + //overrides + m_glFlush_enc = set_glFlush(s_glFlush); + m_glPixelStorei_enc = set_glPixelStorei(s_glPixelStorei); + m_glGetString_enc = set_glGetString(s_glGetString); + m_glBindBuffer_enc = set_glBindBuffer(s_glBindBuffer); + m_glBufferData_enc = set_glBufferData(s_glBufferData); + m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData); + m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers); + m_glDrawArrays_enc = set_glDrawArrays(s_glDrawArrays); + m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); + m_glGetIntegerv_enc = set_glGetIntegerv(s_glGetIntegerv); + m_glGetFloatv_enc = set_glGetFloatv(s_glGetFloatv); + m_glGetBooleanv_enc = set_glGetBooleanv(s_glGetBooleanv); + m_glVertexAttribPointer_enc = set_glVertexAttribPointer(s_glVertexAtrribPointer); + m_glEnableVertexAttribArray_enc = set_glEnableVertexAttribArray(s_glEnableVertexAttribArray); + m_glDisableVertexAttribArray_enc = set_glDisableVertexAttribArray(s_glDisableVertexAttribArray); + m_glGetVertexAttribiv_enc = set_glGetVertexAttribiv(s_glGetVertexAttribiv); + m_glGetVertexAttribfv_enc = set_glGetVertexAttribfv(s_glGetVertexAttribfv); + m_glGetVertexAttribPointerv = set_glGetVertexAttribPointerv(s_glGetVertexAttribPointerv); + set_glShaderSource(s_glShaderSource); + set_glFinish(s_glFinish); + m_glGetError_enc = set_glGetError(s_glGetError); + m_glLinkProgram_enc = set_glLinkProgram(s_glLinkProgram); + m_glDeleteProgram_enc = set_glDeleteProgram(s_glDeleteProgram); + m_glGetUniformiv_enc = set_glGetUniformiv(s_glGetUniformiv); + m_glGetUniformfv_enc = set_glGetUniformfv(s_glGetUniformfv); + m_glCreateProgram_enc = set_glCreateProgram(s_glCreateProgram); + m_glCreateShader_enc = set_glCreateShader(s_glCreateShader); + m_glDeleteShader_enc = set_glDeleteShader(s_glDeleteShader); + m_glAttachShader_enc = set_glAttachShader(s_glAttachShader); + m_glDetachShader_enc = set_glDetachShader(s_glDetachShader); + m_glGetUniformLocation_enc = set_glGetUniformLocation(s_glGetUniformLocation); + m_glUseProgram_enc = set_glUseProgram(s_glUseProgram); + + m_glUniform1f_enc = set_glUniform1f(s_glUniform1f); + m_glUniform1fv_enc = set_glUniform1fv(s_glUniform1fv); + m_glUniform1i_enc = set_glUniform1i(s_glUniform1i); + m_glUniform1iv_enc = set_glUniform1iv(s_glUniform1iv); + m_glUniform2f_enc = set_glUniform2f(s_glUniform2f); + m_glUniform2fv_enc = set_glUniform2fv(s_glUniform2fv); + m_glUniform2i_enc = set_glUniform2i(s_glUniform2i); + m_glUniform2iv_enc = set_glUniform2iv(s_glUniform2iv); + m_glUniform3f_enc = set_glUniform3f(s_glUniform3f); + m_glUniform3fv_enc = set_glUniform3fv(s_glUniform3fv); + m_glUniform3i_enc = set_glUniform3i(s_glUniform3i); + m_glUniform3iv_enc = set_glUniform3iv(s_glUniform3iv); + m_glUniform4f_enc = set_glUniform4f(s_glUniform4f); + m_glUniform4fv_enc = set_glUniform4fv(s_glUniform4fv); + m_glUniform4i_enc = set_glUniform4i(s_glUniform4i); + m_glUniform4iv_enc = set_glUniform4iv(s_glUniform4iv); + m_glUniformMatrix2fv_enc = set_glUniformMatrix2fv(s_glUniformMatrix2fv); + m_glUniformMatrix3fv_enc = set_glUniformMatrix3fv(s_glUniformMatrix3fv); + m_glUniformMatrix4fv_enc = set_glUniformMatrix4fv(s_glUniformMatrix4fv); + + m_glActiveTexture_enc = set_glActiveTexture(s_glActiveTexture); + m_glBindTexture_enc = set_glBindTexture(s_glBindTexture); + m_glDeleteTextures_enc = set_glDeleteTextures(s_glDeleteTextures); + m_glGetTexParameterfv_enc = set_glGetTexParameterfv(s_glGetTexParameterfv); + m_glGetTexParameteriv_enc = set_glGetTexParameteriv(s_glGetTexParameteriv); + m_glTexParameterf_enc = set_glTexParameterf(s_glTexParameterf); + m_glTexParameterfv_enc = set_glTexParameterfv(s_glTexParameterfv); + m_glTexParameteri_enc = set_glTexParameteri(s_glTexParameteri); + m_glTexParameteriv_enc = set_glTexParameteriv(s_glTexParameteriv); +} + +GL2Encoder::~GL2Encoder() +{ + delete m_compressedTextureFormats; +} + +GLenum GL2Encoder::s_glGetError(void * self) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + GLenum err = ctx->getError(); + if(err != GL_NO_ERROR) { + ctx->setError(GL_NO_ERROR); + return err; + } + + return ctx->m_glGetError_enc(self); + +} + +void GL2Encoder::s_glFlush(void *self) +{ + GL2Encoder *ctx = (GL2Encoder *) self; + ctx->m_glFlush_enc(self); + ctx->m_stream->flush(); +} + +const GLubyte *GL2Encoder::s_glGetString(void *self, GLenum name) +{ + GLubyte *retval = (GLubyte *) ""; + switch(name) { + case GL_VENDOR: + retval = gVendorString; + break; + case GL_RENDERER: + retval = gRendererString; + break; + case GL_VERSION: + retval = gVersionString; + break; + case GL_EXTENSIONS: + retval = gExtensionsString; + break; + } + return retval; +} + +void GL2Encoder::s_glPixelStorei(void *self, GLenum param, GLint value) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + ctx->m_glPixelStorei_enc(ctx, param, value); + assert(ctx->m_state != NULL); + ctx->m_state->setPixelStore(param, value); +} + + +void GL2Encoder::s_glBindBuffer(void *self, GLenum target, GLuint id) +{ + GL2Encoder *ctx = (GL2Encoder *) self; + assert(ctx->m_state != NULL); + ctx->m_state->bindBuffer(target, id); + // TODO set error state if needed; + ctx->m_glBindBuffer_enc(self, target, id); +} + +void GL2Encoder::s_glBufferData(void * self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage) +{ + GL2Encoder *ctx = (GL2Encoder *) self; + GLuint bufferId = ctx->m_state->getBuffer(target); + SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); + SET_ERROR_IF(size<0, GL_INVALID_VALUE); + + ctx->m_shared->updateBufferData(bufferId, size, (void*)data); + ctx->m_glBufferData_enc(self, target, size, data, usage); +} + +void GL2Encoder::s_glBufferSubData(void * self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data) +{ + GL2Encoder *ctx = (GL2Encoder *) self; + GLuint bufferId = ctx->m_state->getBuffer(target); + SET_ERROR_IF(bufferId==0, GL_INVALID_OPERATION); + + GLenum res = ctx->m_shared->subUpdateBufferData(bufferId, offset, size, (void*)data); + SET_ERROR_IF(res, res); + + ctx->m_glBufferSubData_enc(self, target, offset, size, data); +} + +void GL2Encoder::s_glDeleteBuffers(void * self, GLsizei n, const GLuint * buffers) +{ + GL2Encoder *ctx = (GL2Encoder *) self; + SET_ERROR_IF(n<0, GL_INVALID_VALUE); + for (int i=0; i<n; i++) { + ctx->m_shared->deleteBufferData(buffers[i]); + ctx->m_glDeleteBuffers_enc(self,1,&buffers[i]); + } +} + +void GL2Encoder::s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * ptr) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state != NULL); + ctx->m_state->setState(indx, size, type, normalized, stride, ptr); +} + +void GL2Encoder::s_glGetIntegerv(void *self, GLenum param, GLint *ptr) +{ + GL2Encoder *ctx = (GL2Encoder *) self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_NUM_SHADER_BINARY_FORMATS: + *ptr = 0; + break; + case GL_SHADER_BINARY_FORMATS: + // do nothing + break; + + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + memcpy(ptr, compressedTextureFormats, + ctx->m_num_compressedTextureFormats * sizeof(GLint)); + } + break; + } + + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case GL_MAX_TEXTURE_IMAGE_UNITS: + ctx->m_glGetIntegerv_enc(self, param, ptr); + *ptr = MIN(*ptr, GLClientState::MAX_TEXTURE_UNITS); + break; + + case GL_TEXTURE_BINDING_2D: + *ptr = state->getBoundTexture(GL_TEXTURE_2D); + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); + break; + + default: + if (!ctx->m_state->getClientStateParameter<GLint>(param, ptr)) { + ctx->m_glGetIntegerv_enc(self, param, ptr); + } + break; + } +} + + +void GL2Encoder::s_glGetFloatv(void *self, GLenum param, GLfloat *ptr) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_NUM_SHADER_BINARY_FORMATS: + *ptr = 0; + break; + case GL_SHADER_BINARY_FORMATS: + // do nothing + break; + + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { + ptr[i] = (GLfloat) compressedTextureFormats[i]; + } + } + break; + } + + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case GL_MAX_TEXTURE_IMAGE_UNITS: + ctx->m_glGetFloatv_enc(self, param, ptr); + *ptr = MIN(*ptr, (GLfloat)GLClientState::MAX_TEXTURE_UNITS); + break; + + case GL_TEXTURE_BINDING_2D: + *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_2D); + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = (GLfloat)state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES); + break; + + default: + if (!ctx->m_state->getClientStateParameter<GLfloat>(param, ptr)) { + ctx->m_glGetFloatv_enc(self, param, ptr); + } + break; + } +} + + +void GL2Encoder::s_glGetBooleanv(void *self, GLenum param, GLboolean *ptr) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state != NULL); + GLClientState* state = ctx->m_state; + + switch (param) { + case GL_NUM_SHADER_BINARY_FORMATS: + *ptr = GL_FALSE; + break; + case GL_SHADER_BINARY_FORMATS: + // do nothing + break; + + case GL_COMPRESSED_TEXTURE_FORMATS: { + GLint *compressedTextureFormats = ctx->getCompressedTextureFormats(); + if (ctx->m_num_compressedTextureFormats > 0 && + compressedTextureFormats != NULL) { + for (int i = 0; i < ctx->m_num_compressedTextureFormats; i++) { + ptr[i] = compressedTextureFormats[i] != 0 ? GL_TRUE : GL_FALSE; + } + } + break; + } + + case GL_TEXTURE_BINDING_2D: + *ptr = state->getBoundTexture(GL_TEXTURE_2D) != 0 ? GL_TRUE : GL_FALSE; + break; + case GL_TEXTURE_BINDING_EXTERNAL_OES: + *ptr = state->getBoundTexture(GL_TEXTURE_EXTERNAL_OES) != 0 + ? GL_TRUE : GL_FALSE; + break; + + default: + if (!ctx->m_state->getClientStateParameter<GLboolean>(param, ptr)) { + ctx->m_glGetBooleanv_enc(self, param, ptr); + } + break; + } +} + + +void GL2Encoder::s_glEnableVertexAttribArray(void *self, GLuint index) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state); + ctx->m_state->enable(index, 1); +} + +void GL2Encoder::s_glDisableVertexAttribArray(void *self, GLuint index) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state); + ctx->m_state->enable(index, 0); +} + + +void GL2Encoder::s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state); + + if (!ctx->m_state->getVertexAttribParameter<GLint>(index, pname, params)) { + ctx->m_glGetVertexAttribiv_enc(self, index, pname, params); + } +} + +void GL2Encoder::s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state); + + if (!ctx->m_state->getVertexAttribParameter<GLfloat>(index, pname, params)) { + ctx->m_glGetVertexAttribfv_enc(self, index, pname, params); + } +} + +void GL2Encoder::s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + if (ctx->m_state == NULL) return; + + const GLClientState::VertexAttribState *va_state = ctx->m_state->getState(index); + if (va_state != NULL) { + *pointer = va_state->data; + } +} + + +void GL2Encoder::sendVertexAttributes(GLint first, GLsizei count) +{ + assert(m_state); + + for (int i = 0; i < m_state->nLocations(); i++) { + bool enableDirty; + const GLClientState::VertexAttribState *state = m_state->getStateAndEnableDirty(i, &enableDirty); + + if (!state) { + continue; + } + + if (!enableDirty && !state->enabled) { + continue; + } + + + if (state->enabled) { + m_glEnableVertexAttribArray_enc(this, i); + + unsigned int datalen = state->elementSize * count; + int stride = state->stride == 0 ? state->elementSize : state->stride; + int firstIndex = stride * first; + + if (state->bufferObject == 0) { + this->glVertexAttribPointerData(this, i, state->size, state->type, state->normalized, state->stride, + (unsigned char *)state->data + firstIndex, datalen); + } else { + this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, state->bufferObject); + this->glVertexAttribPointerOffset(this, i, state->size, state->type, state->normalized, state->stride, + (GLuint) state->data + firstIndex); + this->m_glBindBuffer_enc(this, GL_ARRAY_BUFFER, m_state->currentArrayVbo()); + } + } else { + this->m_glDisableVertexAttribArray_enc(this, i); + } + } +} + +void GL2Encoder::s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + ctx->sendVertexAttributes(first, count); + ctx->m_glDrawArrays_enc(ctx, mode, 0, count); +} + + +void GL2Encoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices) +{ + + GL2Encoder *ctx = (GL2Encoder *)self; + assert(ctx->m_state != NULL); + SET_ERROR_IF(count<0, GL_INVALID_VALUE); + + bool has_immediate_arrays = false; + bool has_indirect_arrays = false; + int nLocations = ctx->m_state->nLocations(); + + for (int i = 0; i < nLocations; i++) { + const GLClientState::VertexAttribState *state = ctx->m_state->getState(i); + if (state->enabled) { + if (state->bufferObject != 0) { + has_indirect_arrays = true; + } else { + has_immediate_arrays = true; + } + } + } + + if (!has_immediate_arrays && !has_indirect_arrays) { + ALOGE("glDrawElements: no data bound to the command - ignoring\n"); + return; + } + + bool adjustIndices = true; + if (ctx->m_state->currentIndexVbo() != 0) { + if (!has_immediate_arrays) { + ctx->sendVertexAttributes(0, count); + ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, ctx->m_state->currentIndexVbo()); + ctx->glDrawElementsOffset(ctx, mode, count, type, (GLuint)indices); + adjustIndices = false; + } else { + BufferData * buf = ctx->m_shared->getBufferData(ctx->m_state->currentIndexVbo()); + ctx->m_glBindBuffer_enc(self, GL_ELEMENT_ARRAY_BUFFER, 0); + indices = (void*)((GLintptr)buf->m_fixedBuffer.ptr() + (GLintptr)indices); + } + } + if (adjustIndices) { + void *adjustedIndices = (void*)indices; + int minIndex = 0, maxIndex = 0; + + switch(type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + GLUtils::minmax<unsigned char>((unsigned char *)indices, count, &minIndex, &maxIndex); + if (minIndex != 0) { + adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); + GLUtils::shiftIndices<unsigned char>((unsigned char *)indices, + (unsigned char *)adjustedIndices, + count, -minIndex); + } + break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + GLUtils::minmax<unsigned short>((unsigned short *)indices, count, &minIndex, &maxIndex); + if (minIndex != 0) { + adjustedIndices = ctx->m_fixedBuffer.alloc(glSizeof(type) * count); + GLUtils::shiftIndices<unsigned short>((unsigned short *)indices, + (unsigned short *)adjustedIndices, + count, -minIndex); + } + break; + default: + ALOGE("unsupported index buffer type %d\n", type); + } + if (has_indirect_arrays || 1) { + ctx->sendVertexAttributes(minIndex, maxIndex - minIndex + 1); + ctx->glDrawElementsData(ctx, mode, count, type, adjustedIndices, + count * glSizeof(type)); + // XXX - OPTIMIZATION (see the other else branch) should be implemented + if(!has_indirect_arrays) { + //ALOGD("unoptimized drawelements !!!\n"); + } + } else { + // we are all direct arrays and immidate mode index array - + // rebuild the arrays and the index array; + ALOGE("glDrawElements: direct index & direct buffer data - will be implemented in later versions;\n"); + } + } +} + + +GLint * GL2Encoder::getCompressedTextureFormats() +{ + if (m_compressedTextureFormats == NULL) { + this->glGetIntegerv(this, GL_NUM_COMPRESSED_TEXTURE_FORMATS, + &m_num_compressedTextureFormats); + if (m_num_compressedTextureFormats > 0) { + // get number of texture formats; + m_compressedTextureFormats = new GLint[m_num_compressedTextureFormats]; + this->glGetCompressedTextureFormats(this, m_num_compressedTextureFormats, m_compressedTextureFormats); + } + } + return m_compressedTextureFormats; +} + +// Replace uses of samplerExternalOES with sampler2D, recording the names of +// modified shaders in data. Also remove +// #extension GL_OES_EGL_image_external : require +// statements. +// +// This implementation assumes the input has already been pre-processed. If not, +// a few cases will be mishandled: +// +// 1. "mySampler" will be incorrectly recorded as being a samplerExternalOES in +// the following code: +// #if 1 +// uniform sampler2D mySampler; +// #else +// uniform samplerExternalOES mySampler; +// #endif +// +// 2. Comments that look like sampler declarations will be incorrectly modified +// and recorded: +// // samplerExternalOES hahaFooledYou +// +// 3. However, GLSL ES does not have a concatentation operator, so things like +// this (valid in C) are invalid and not a problem: +// #define SAMPLER(TYPE, NAME) uniform sampler#TYPE NAME +// SAMPLER(ExternalOES, mySampler); +// +static bool replaceSamplerExternalWith2D(char* const str, ShaderData* const data) +{ + static const char STR_HASH_EXTENSION[] = "#extension"; + static const char STR_GL_OES_EGL_IMAGE_EXTERNAL[] = "GL_OES_EGL_image_external"; + static const char STR_SAMPLER_EXTERNAL_OES[] = "samplerExternalOES"; + static const char STR_SAMPLER2D_SPACE[] = "sampler2D "; + + // -- overwrite all "#extension GL_OES_EGL_image_external : xxx" statements + char* c = str; + while ((c = strstr(c, STR_HASH_EXTENSION))) { + char* start = c; + c += sizeof(STR_HASH_EXTENSION)-1; + while (isspace(*c) && *c != '\0') { + c++; + } + if (strncmp(c, STR_GL_OES_EGL_IMAGE_EXTERNAL, + sizeof(STR_GL_OES_EGL_IMAGE_EXTERNAL)-1) == 0) + { + // #extension statements are terminated by end of line + c = start; + while (*c != '\0' && *c != '\r' && *c != '\n') { + *c++ = ' '; + } + } + } + + // -- replace "samplerExternalOES" with "sampler2D" and record name + c = str; + while ((c = strstr(c, STR_SAMPLER_EXTERNAL_OES))) { + // Make sure "samplerExternalOES" isn't a substring of a larger token + if (c == str || !isspace(*(c-1))) { + c++; + continue; + } + char* sampler_start = c; + c += sizeof(STR_SAMPLER_EXTERNAL_OES)-1; + if (!isspace(*c) && *c != '\0') { + continue; + } + + // capture sampler name + while (isspace(*c) && *c != '\0') { + c++; + } + if (!isalpha(*c) && *c != '_') { + // not an identifier + return false; + } + char* name_start = c; + do { + c++; + } while (isalnum(*c) || *c == '_'); + data->samplerExternalNames.push_back( + android::String8(name_start, c - name_start)); + + // memcpy instead of strcpy since we don't want the NUL terminator + memcpy(sampler_start, STR_SAMPLER2D_SPACE, sizeof(STR_SAMPLER2D_SPACE)-1); + } + + return true; +} + +void GL2Encoder::s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + ShaderData* shaderData = ctx->m_shared->getShaderData(shader); + SET_ERROR_IF(!shaderData, GL_INVALID_VALUE); + + int len = glUtilsCalcShaderSourceLen((char**)string, (GLint*)length, count); + char *str = new char[len + 1]; + glUtilsPackStrings(str, (char**)string, (GLint*)length, count); + + // TODO: pre-process str before calling replaceSamplerExternalWith2D(). + // Perhaps we can borrow Mesa's pre-processor? + + if (!replaceSamplerExternalWith2D(str, shaderData)) { + delete str; + ctx->setError(GL_OUT_OF_MEMORY); + return; + } + + ctx->glShaderString(ctx, shader, str, len + 1); + delete str; +} + +void GL2Encoder::s_glFinish(void *self) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + ctx->glFinishRoundTrip(self); +} + +void GL2Encoder::s_glLinkProgram(void * self, GLuint program) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + ctx->m_glLinkProgram_enc(self, program); + + GLint linkStatus = 0; + ctx->glGetProgramiv(self,program,GL_LINK_STATUS,&linkStatus); + if (!linkStatus) + return; + + //get number of active uniforms in the program + GLint numUniforms=0; + ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORMS, &numUniforms); + ctx->m_shared->initProgramData(program,numUniforms); + + //get the length of the longest uniform name + GLint maxLength=0; + ctx->glGetProgramiv(self, program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength); + + GLint size; + GLenum type; + GLchar *name = new GLchar[maxLength+1]; + GLint location; + //for each active uniform, get its size and starting location. + for (GLint i=0 ; i<numUniforms ; ++i) + { + ctx->glGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name); + location = ctx->m_glGetUniformLocation_enc(self, program, name); + ctx->m_shared->setProgramIndexInfo(program, i, location, size, type, name); + } + ctx->m_shared->setupLocationShiftWAR(program); + + delete[] name; +} + +void GL2Encoder::s_glDeleteProgram(void *self, GLuint program) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + ctx->m_glDeleteProgram_enc(self, program); + + ctx->m_shared->deleteProgramData(program); +} + +void GL2Encoder::s_glGetUniformiv(void *self, GLuint program, GLint location, GLint* params) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION); + GLint hostLoc = ctx->m_shared->locationWARAppToHost(program, location); + SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION); + ctx->m_glGetUniformiv_enc(self, program, hostLoc, params); +} +void GL2Encoder::s_glGetUniformfv(void *self, GLuint program, GLint location, GLfloat* params) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + SET_ERROR_IF(!ctx->m_shared->isProgram(program), GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION); + GLint hostLoc = ctx->m_shared->locationWARAppToHost(program,location); + SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,hostLoc)==0, GL_INVALID_OPERATION); + ctx->m_glGetUniformfv_enc(self, program, hostLoc, params); +} + +GLuint GL2Encoder::s_glCreateProgram(void * self) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLuint program = ctx->m_glCreateProgram_enc(self); + if (program!=0) + ctx->m_shared->addProgramData(program); + return program; +} + +GLuint GL2Encoder::s_glCreateShader(void *self, GLenum shaderType) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLuint shader = ctx->m_glCreateShader_enc(self, shaderType); + if (shader != 0) { + if (!ctx->m_shared->addShaderData(shader)) { + ctx->m_glDeleteShader_enc(self, shader); + return 0; + } + } + return shader; +} + +void GL2Encoder::s_glDeleteShader(void *self, GLenum shader) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + ctx->m_glDeleteShader_enc(self,shader); + ctx->m_shared->unrefShaderData(shader); +} + +void GL2Encoder::s_glAttachShader(void *self, GLuint program, GLuint shader) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + ctx->m_glAttachShader_enc(self, program, shader); + ctx->m_shared->attachShader(program, shader); +} + +void GL2Encoder::s_glDetachShader(void *self, GLuint program, GLuint shader) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + ctx->m_glDetachShader_enc(self, program, shader); + ctx->m_shared->detachShader(program, shader); +} + +int GL2Encoder::s_glGetUniformLocation(void *self, GLuint program, const GLchar *name) +{ + if (!name) return -1; + + GL2Encoder *ctx = (GL2Encoder*)self; + + // if we need the uniform location WAR + // parse array index from the end of the name string + int arrIndex = 0; + bool needLocationWAR = ctx->m_shared->needUniformLocationWAR(program); + if (needLocationWAR) { + int namelen = strlen(name); + if (name[namelen-1] == ']') { + char *brace = strrchr(name,'['); + if (!brace || sscanf(brace+1,"%d",&arrIndex) != 1) { + return -1; + } + + } + } + + int hostLoc = ctx->m_glGetUniformLocation_enc(self, program, name); + if (hostLoc >= 0 && needLocationWAR) { + return ctx->m_shared->locationWARHostToApp(program, hostLoc, arrIndex); + } + return hostLoc; +} + +bool GL2Encoder::updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget) +{ + if (newTarget != GL_TEXTURE_2D && newTarget != GL_TEXTURE_EXTERNAL_OES) + return false; + + m_state->setActiveTextureUnit(texUnit); + + GLenum oldTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); + if (newTarget != oldTarget) { + if (newTarget == GL_TEXTURE_EXTERNAL_OES) { + m_state->disableTextureTarget(GL_TEXTURE_2D); + m_state->enableTextureTarget(GL_TEXTURE_EXTERNAL_OES); + } else { + m_state->disableTextureTarget(GL_TEXTURE_EXTERNAL_OES); + m_state->enableTextureTarget(GL_TEXTURE_2D); + } + m_glActiveTexture_enc(this, texUnit); + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture(newTarget)); + return true; + } + + return false; +} + +void GL2Encoder::s_glUseProgram(void *self, GLuint program) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLClientState* state = ctx->m_state; + GLSharedGroupPtr shared = ctx->m_shared; + + ctx->m_glUseProgram_enc(self, program); + ctx->m_state->setCurrentProgram(program); + + GLenum origActiveTexture = state->getActiveTextureUnit(); + GLenum hostActiveTexture = origActiveTexture; + GLint samplerIdx = -1; + GLint samplerVal; + GLenum samplerTarget; + while ((samplerIdx = shared->getNextSamplerUniform(program, samplerIdx, &samplerVal, &samplerTarget)) != -1) { + if (samplerVal < 0 || samplerVal >= GLClientState::MAX_TEXTURE_UNITS) + continue; + if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + samplerVal, + samplerTarget)) + { + hostActiveTexture = GL_TEXTURE0 + samplerVal; + } + } + state->setActiveTextureUnit(origActiveTexture); + if (hostActiveTexture != origActiveTexture) { + ctx->m_glActiveTexture_enc(self, origActiveTexture); + } +} + +void GL2Encoder::s_glUniform1f(void *self , GLint location, GLfloat x) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform1f_enc(self, hostLoc, x); +} + +void GL2Encoder::s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform1fv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform1i(void *self , GLint location, GLint x) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLClientState* state = ctx->m_state; + GLSharedGroupPtr shared = ctx->m_shared; + + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform1i_enc(self, hostLoc, x); + + GLenum target; + if (shared->setSamplerUniform(state->currentProgram(), location, x, &target)) { + GLenum origActiveTexture = state->getActiveTextureUnit(); + if (ctx->updateHostTexture2DBinding(GL_TEXTURE0 + x, target)) { + ctx->m_glActiveTexture_enc(self, origActiveTexture); + } + state->setActiveTextureUnit(origActiveTexture); + } +} + +void GL2Encoder::s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform1iv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform2f_enc(self, hostLoc, x, y); +} + +void GL2Encoder::s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform2fv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform2i(void *self , GLint location, GLint x, GLint y) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform2i_enc(self, hostLoc, x, y); +} + +void GL2Encoder::s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform2iv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform3f_enc(self, hostLoc, x, y, z); +} + +void GL2Encoder::s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform3fv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform3i_enc(self, hostLoc, x, y, z); +} + +void GL2Encoder::s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform3iv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform4f_enc(self, hostLoc, x, y, z, w); +} + +void GL2Encoder::s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform4fv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform4i_enc(self, hostLoc, x, y, z, w); +} + +void GL2Encoder::s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniform4iv_enc(self, hostLoc, count, v); +} + +void GL2Encoder::s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniformMatrix2fv_enc(self, hostLoc, count, transpose, value); +} + +void GL2Encoder::s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniformMatrix3fv_enc(self, hostLoc, count, transpose, value); +} + +void GL2Encoder::s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + GLint hostLoc = ctx->m_shared->locationWARAppToHost(ctx->m_state->currentProgram(),location); + ctx->m_glUniformMatrix4fv_enc(self, hostLoc, count, transpose, value); +} + +void GL2Encoder::s_glActiveTexture(void* self, GLenum texture) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + GLClientState* state = ctx->m_state; + GLenum err; + + SET_ERROR_IF((err = state->setActiveTextureUnit(texture)) != GL_NO_ERROR, err); + + ctx->m_glActiveTexture_enc(ctx, texture); +} + +void GL2Encoder::s_glBindTexture(void* self, GLenum target, GLuint texture) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + GLClientState* state = ctx->m_state; + GLenum err; + GLboolean firstUse; + + SET_ERROR_IF((err = state->bindTexture(target, texture, &firstUse)) != GL_NO_ERROR, err); + + if (target != GL_TEXTURE_2D && target != GL_TEXTURE_EXTERNAL_OES) { + ctx->m_glBindTexture_enc(ctx, target, texture); + return; + } + + GLenum priorityTarget = state->getPriorityEnabledTarget(GL_TEXTURE_2D); + + if (target == GL_TEXTURE_EXTERNAL_OES && firstUse) { + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, + GL_TEXTURE_MIN_FILTER, GL_LINEAR); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, + GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, + GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + if (target != priorityTarget) { + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, + state->getBoundTexture(GL_TEXTURE_2D)); + } + } + + if (target == priorityTarget) { + ctx->m_glBindTexture_enc(ctx, GL_TEXTURE_2D, texture); + } +} + +void GL2Encoder::s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + GLClientState* state = ctx->m_state; + + state->deleteTextures(n, textures); + ctx->m_glDeleteTextures_enc(ctx, n, textures); +} + +void GL2Encoder::s_glGetTexParameterfv(void* self, + GLenum target, GLenum pname, GLfloat* params) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + const GLClientState* state = ctx->m_state; + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params); + } +} + +void GL2Encoder::s_glGetTexParameteriv(void* self, + GLenum target, GLenum pname, GLint* params) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + const GLClientState* state = ctx->m_state; + + switch (pname) { + case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: + *params = 1; + break; + + default: + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params); + } + break; + } +} + +static bool isValidTextureExternalParam(GLenum pname, GLenum param) +{ + switch (pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + return param == GL_NEAREST || param == GL_LINEAR; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + return param == GL_CLAMP_TO_EDGE; + + default: + return true; + } +} + +void GL2Encoder::s_glTexParameterf(void* self, + GLenum target, GLenum pname, GLfloat param) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)param)), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameterf_enc(ctx, target, pname, param); + } +} + +void GL2Encoder::s_glTexParameterfv(void* self, + GLenum target, GLenum pname, const GLfloat* params) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)params[0])), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameterfv_enc(ctx, target, pname, params); + } +} + +void GL2Encoder::s_glTexParameteri(void* self, + GLenum target, GLenum pname, GLint param) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)param)), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameteri_enc(ctx, target, pname, param); + } +} + +void GL2Encoder::s_glTexParameteriv(void* self, + GLenum target, GLenum pname, const GLint* params) +{ + GL2Encoder* ctx = (GL2Encoder*)self; + const GLClientState* state = ctx->m_state; + + SET_ERROR_IF((target == GL_TEXTURE_EXTERNAL_OES && + !isValidTextureExternalParam(pname, (GLenum)params[0])), + GL_INVALID_ENUM); + + if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { + ctx->override2DTextureTarget(target); + ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); + ctx->restore2DTextureTarget(); + } else { + ctx->m_glTexParameteriv_enc(ctx, target, pname, params); + } +} + +void GL2Encoder::override2DTextureTarget(GLenum target) +{ + if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) && + target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) { + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture(target)); + } +} + +void GL2Encoder::restore2DTextureTarget() +{ + GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture(priorityTarget)); +} diff --git a/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/emulator/opengl/system/GLESv2_enc/GL2Encoder.h new file mode 100644 index 0000000..f9235d7 --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/GL2Encoder.h @@ -0,0 +1,216 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _GL2_ENCODER_H_ +#define _GL2_ENCODER_H_ + +#include "gl2_enc.h" +#include "GLClientState.h" +#include "GLSharedGroup.h" +#include "FixedBuffer.h" + + +class GL2Encoder : public gl2_encoder_context_t { +public: + GL2Encoder(IOStream *stream); + virtual ~GL2Encoder(); + void setClientState(GLClientState *state) { + m_state = state; + } + void setSharedGroup(GLSharedGroupPtr shared){ m_shared = shared; } + const GLClientState *state() { return m_state; } + const GLSharedGroupPtr shared() { return m_shared; } + void flush() { m_stream->flush(); } + + void setInitialized(){ m_initialized = true; }; + bool isInitialized(){ return m_initialized; }; + + virtual void setError(GLenum error){ m_error = error; }; + virtual GLenum getError() { return m_error; }; + + void override2DTextureTarget(GLenum target); + void restore2DTextureTarget(); + +private: + + bool m_initialized; + GLClientState *m_state; + GLSharedGroupPtr m_shared; + GLenum m_error; + + GLint *m_compressedTextureFormats; + GLint m_num_compressedTextureFormats; + GLint *getCompressedTextureFormats(); + + FixedBuffer m_fixedBuffer; + + void sendVertexAttributes(GLint first, GLsizei count); + bool updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget); + + glGetError_client_proc_t m_glGetError_enc; + static GLenum s_glGetError(void * self); + + glFlush_client_proc_t m_glFlush_enc; + static void s_glFlush(void * self); + + glPixelStorei_client_proc_t m_glPixelStorei_enc; + static void s_glPixelStorei(void *self, GLenum param, GLint value); + + glGetString_client_proc_t m_glGetString_enc; + static const GLubyte * s_glGetString(void *self, GLenum name); + + glBindBuffer_client_proc_t m_glBindBuffer_enc; + static void s_glBindBuffer(void *self, GLenum target, GLuint id); + + + glBufferData_client_proc_t m_glBufferData_enc; + static void s_glBufferData(void *self, GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage); + glBufferSubData_client_proc_t m_glBufferSubData_enc; + static void s_glBufferSubData(void *self, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid * data); + glDeleteBuffers_client_proc_t m_glDeleteBuffers_enc; + static void s_glDeleteBuffers(void *self, GLsizei n, const GLuint * buffers); + + glDrawArrays_client_proc_t m_glDrawArrays_enc; + static void s_glDrawArrays(void *self, GLenum mode, GLint first, GLsizei count); + + glDrawElements_client_proc_t m_glDrawElements_enc; + static void s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum type, const void *indices); + + + glGetIntegerv_client_proc_t m_glGetIntegerv_enc; + static void s_glGetIntegerv(void *self, GLenum pname, GLint *ptr); + + glGetFloatv_client_proc_t m_glGetFloatv_enc; + static void s_glGetFloatv(void *self, GLenum pname, GLfloat *ptr); + + glGetBooleanv_client_proc_t m_glGetBooleanv_enc; + static void s_glGetBooleanv(void *self, GLenum pname, GLboolean *ptr); + + glVertexAttribPointer_client_proc_t m_glVertexAttribPointer_enc; + static void s_glVertexAtrribPointer(void *self, GLuint indx, GLint size, GLenum type, + GLboolean normalized, GLsizei stride, const GLvoid * ptr); + + glEnableVertexAttribArray_client_proc_t m_glEnableVertexAttribArray_enc; + static void s_glEnableVertexAttribArray(void *self, GLuint index); + + glDisableVertexAttribArray_client_proc_t m_glDisableVertexAttribArray_enc; + static void s_glDisableVertexAttribArray(void *self, GLuint index); + + glGetVertexAttribiv_client_proc_t m_glGetVertexAttribiv_enc; + static void s_glGetVertexAttribiv(void *self, GLuint index, GLenum pname, GLint *params); + + glGetVertexAttribfv_client_proc_t m_glGetVertexAttribfv_enc; + static void s_glGetVertexAttribfv(void *self, GLuint index, GLenum pname, GLfloat *params); + + glGetVertexAttribPointerv_client_proc_t m_glGetVertexAttribPointerv; + static void s_glGetVertexAttribPointerv(void *self, GLuint index, GLenum pname, GLvoid **pointer); + + static void s_glShaderSource(void *self, GLuint shader, GLsizei count, const GLchar **string, const GLint *length); + + static void s_glFinish(void *self); + + glLinkProgram_client_proc_t m_glLinkProgram_enc; + static void s_glLinkProgram(void *self, GLuint program); + + glDeleteProgram_client_proc_t m_glDeleteProgram_enc; + static void s_glDeleteProgram(void * self, GLuint program); + + glGetUniformiv_client_proc_t m_glGetUniformiv_enc; + static void s_glGetUniformiv(void *self, GLuint program, GLint location , GLint *params); + + glGetUniformfv_client_proc_t m_glGetUniformfv_enc; + static void s_glGetUniformfv(void *self, GLuint program, GLint location , GLfloat *params); + + glCreateProgram_client_proc_t m_glCreateProgram_enc; + static GLuint s_glCreateProgram(void *self); + + glCreateShader_client_proc_t m_glCreateShader_enc; + static GLuint s_glCreateShader(void *self, GLenum shaderType); + + glDeleteShader_client_proc_t m_glDeleteShader_enc; + static void s_glDeleteShader(void *self, GLuint shader); + + glAttachShader_client_proc_t m_glAttachShader_enc; + static void s_glAttachShader(void *self, GLuint program, GLuint shader); + + glDetachShader_client_proc_t m_glDetachShader_enc; + static void s_glDetachShader(void *self, GLuint program, GLuint shader); + + glGetUniformLocation_client_proc_t m_glGetUniformLocation_enc; + static int s_glGetUniformLocation(void *self, GLuint program, const GLchar *name); + glUseProgram_client_proc_t m_glUseProgram_enc; + + glUniform1f_client_proc_t m_glUniform1f_enc; + glUniform1fv_client_proc_t m_glUniform1fv_enc; + glUniform1i_client_proc_t m_glUniform1i_enc; + glUniform1iv_client_proc_t m_glUniform1iv_enc; + glUniform2f_client_proc_t m_glUniform2f_enc; + glUniform2fv_client_proc_t m_glUniform2fv_enc; + glUniform2i_client_proc_t m_glUniform2i_enc; + glUniform2iv_client_proc_t m_glUniform2iv_enc; + glUniform3f_client_proc_t m_glUniform3f_enc; + glUniform3fv_client_proc_t m_glUniform3fv_enc; + glUniform3i_client_proc_t m_glUniform3i_enc; + glUniform3iv_client_proc_t m_glUniform3iv_enc; + glUniform4f_client_proc_t m_glUniform4f_enc; + glUniform4fv_client_proc_t m_glUniform4fv_enc; + glUniform4i_client_proc_t m_glUniform4i_enc; + glUniform4iv_client_proc_t m_glUniform4iv_enc; + glUniformMatrix2fv_client_proc_t m_glUniformMatrix2fv_enc; + glUniformMatrix3fv_client_proc_t m_glUniformMatrix3fv_enc; + glUniformMatrix4fv_client_proc_t m_glUniformMatrix4fv_enc; + + static void s_glUseProgram(void *self, GLuint program); + static void s_glUniform1f(void *self , GLint location, GLfloat x); + static void s_glUniform1fv(void *self , GLint location, GLsizei count, const GLfloat* v); + static void s_glUniform1i(void *self , GLint location, GLint x); + static void s_glUniform1iv(void *self , GLint location, GLsizei count, const GLint* v); + static void s_glUniform2f(void *self , GLint location, GLfloat x, GLfloat y); + static void s_glUniform2fv(void *self , GLint location, GLsizei count, const GLfloat* v); + static void s_glUniform2i(void *self , GLint location, GLint x, GLint y); + static void s_glUniform2iv(void *self , GLint location, GLsizei count, const GLint* v); + static void s_glUniform3f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z); + static void s_glUniform3fv(void *self , GLint location, GLsizei count, const GLfloat* v); + static void s_glUniform3i(void *self , GLint location, GLint x, GLint y, GLint z); + static void s_glUniform3iv(void *self , GLint location, GLsizei count, const GLint* v); + static void s_glUniform4f(void *self , GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + static void s_glUniform4fv(void *self , GLint location, GLsizei count, const GLfloat* v); + static void s_glUniform4i(void *self , GLint location, GLint x, GLint y, GLint z, GLint w); + static void s_glUniform4iv(void *self , GLint location, GLsizei count, const GLint* v); + static void s_glUniformMatrix2fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + static void s_glUniformMatrix3fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + static void s_glUniformMatrix4fv(void *self , GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + + glActiveTexture_client_proc_t m_glActiveTexture_enc; + glBindTexture_client_proc_t m_glBindTexture_enc; + glDeleteTextures_client_proc_t m_glDeleteTextures_enc; + glGetTexParameterfv_client_proc_t m_glGetTexParameterfv_enc; + glGetTexParameteriv_client_proc_t m_glGetTexParameteriv_enc; + glTexParameterf_client_proc_t m_glTexParameterf_enc; + glTexParameterfv_client_proc_t m_glTexParameterfv_enc; + glTexParameteri_client_proc_t m_glTexParameteri_enc; + glTexParameteriv_client_proc_t m_glTexParameteriv_enc; + + static void s_glActiveTexture(void* self, GLenum texture); + static void s_glBindTexture(void* self, GLenum target, GLuint texture); + static void s_glDeleteTextures(void* self, GLsizei n, const GLuint* textures); + static void s_glGetTexParameterfv(void* self, GLenum target, GLenum pname, GLfloat* params); + static void s_glGetTexParameteriv(void* self, GLenum target, GLenum pname, GLint* params); + static void s_glTexParameterf(void* self, GLenum target, GLenum pname, GLfloat param); + static void s_glTexParameterfv(void* self, GLenum target, GLenum pname, const GLfloat* params); + static void s_glTexParameteri(void* self, GLenum target, GLenum pname, GLint param); + static void s_glTexParameteriv(void* self, GLenum target, GLenum pname, const GLint* params); +}; +#endif diff --git a/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp b/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp new file mode 100644 index 0000000..57d65c0 --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp @@ -0,0 +1,39 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include <stdio.h> +#include <stdlib.h> +#include "GL2Encoder.h" +#include <assert.h> + +size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) +{ + GL2Encoder *ctx = (GL2Encoder *)self; + assert (ctx->state() != NULL); + return ctx->state()->pixelDataSize(width, height, format, type, pack); +} + +size_t pixelDataSize3D(void *self, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) +{ + size_t layerSize = pixelDataSize(self, width, height, format, type, pack); + return layerSize * depth; +} + +GLenum uniformType(void * self, GLuint program, GLint location) +{ + GL2Encoder * ctx = (GL2Encoder *) self; + assert (ctx->shared() != NULL); + return ctx->shared()->getProgramUniformType(program, location); +} diff --git a/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h b/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h new file mode 100644 index 0000000..8e91aeb --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h @@ -0,0 +1,24 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef GL2_ENCODER_UTILS_H +#define GL2_ENCLODER_UTILS_H + +extern "C" { + size_t pixelDataSize(void *self, GLsizei width, GLsizei height, GLenum format, GLenum type, int pack); + size_t pixelDataSize3D(void *self, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack); + GLenum uniformType(void * self, GLuint program, GLint location); +}; +#endif diff --git a/emulator/opengl/system/GLESv2_enc/gl2.attrib b/emulator/opengl/system/GLESv2_enc/gl2.attrib new file mode 100644 index 0000000..7fe9a66 --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/gl2.attrib @@ -0,0 +1,590 @@ +GLOBAL + base_opcode 2048 + encoder_headers <string.h> "glUtils.h" "GL2EncoderUtils.h" + +#void glBindAttribLocation(GLuint program, GLuint index, GLchar *name) +glBindAttribLocation + len name (strlen(name) + 1) + +#void glBufferData(GLenum target, GLsizeiptr size, GLvoid *data, GLenum usage) +glBufferData + len data size + var_flag data nullAllowed isLarge + +#void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) +glBufferSubData + len data size + var_flag data isLarge + +#void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLvoid *data) +glCompressedTexImage2D + len data imageSize + var_flag data nullAllowed isLarge + +#void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLvoid *data) +glCompressedTexSubImage2D + len data imageSize + var_flag data isLarge + +#void glDeleteBuffers(GLsizei n, GLuint *buffers) +glDeleteBuffers + len buffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) +glDeleteFramebuffers + len framebuffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) +glDeleteRenderbuffers + len renderbuffers (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glDeleteTextures(GLsizei n, GLuint *textures) +glDeleteTextures + len textures (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glDrawElements(GLenum mode, GLsizei count, GLenum type, GLvoid *indices) +glDrawElements + flag unsupported + +#void glGenBuffers(GLsizei n, GLuint *buffers) +glGenBuffers + len buffers (n * sizeof(GLuint)) + dir buffers out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenFramebuffers(GLsizei n, GLuint *framebuffers) +glGenFramebuffers + len framebuffers (n * sizeof(GLuint)) + dir framebuffers out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) +glGenRenderbuffers + len renderbuffers (n * sizeof(GLuint)) + dir renderbuffers out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenTextures(GLsizei n, GLuint *textures) +glGenTextures + len textures (n * sizeof(GLuint)) + dir textures out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +glGetActiveAttrib + len name bufsize + dir name out + var_flag name nullAllowed + dir length out + len length (sizeof(GLsizei)) + var_flag length nullAllowed + dir size out + len size (sizeof(GLint)) + dir type out + len type (sizeof(GLenum)) + +#void glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) +glGetActiveUniform + len name bufsize + dir name out + var_flag name nullAllowed + dir length out + len length (sizeof(GLsizei)) + var_flag length nullAllowed + dir size out + len size (sizeof(GLint)) + dir type out + len type (sizeof(GLenum)) + + +#void glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei *count, GLuint *shaders) +glGetAttachedShaders + len shaders (maxcount*sizeof(GLuint)) + dir shaders out + dir count out + var_flag count nullAllowed + len count (sizeof(GLsizei)) + +#int glGetAttribLocation(GLuint program, GLchar *name) +glGetAttribLocation + len name (strlen(name) + 1) + +#void glGetBooleanv(GLenum pname, GLboolean *params) +glGetBooleanv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLboolean)) + +#void glGetBufferParameteriv(GLenum target, GLenum pname, GLint *params) +glGetBufferParameteriv + len params (sizeof(GLint)) + dir params out + +#void glGetFloatv(GLenum pname, GLfloat *params) +glGetFloatv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint *params) +glGetFramebufferAttachmentParameteriv + dir params out + len params (sizeof(GLint)) + +#void glGetIntegerv(GLenum pname, GLint *params) +glGetIntegerv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glGetProgramiv(GLuint program, GLenum pname, GLint *params) +glGetProgramiv + dir params out + len params sizeof(GLint) +#XXX - might change if extension constants that return more then one value + + +#void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei *length, GLchar *infolog) +glGetProgramInfoLog + dir infolog out + len infolog bufsize + dir length out + len length sizeof(GLsizei) + +#void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint *params) +glGetRenderbufferParameteriv + dir params out + len params sizeof(GLint) +# XXX - might change if pname with value larger then one is added + +#void glGetShaderiv(GLuint shader, GLenum pname, GLint *params) +glGetShaderiv + dir params out + len params sizeof(GLint) +# XXX - might change if pname with value larger then one is added + +#void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *infolog) +glGetShaderInfoLog + dir length out + len length (sizeof(GLsizei)) + var_flag length nullAllowed + dir infolog out + len infolog bufsize + + +#void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) +glGetShaderPrecisionFormat + dir range out + len range (2 * sizeof(GLint)) + dir precision out + len precision (sizeof(GLint)) + +#void glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei *length, GLchar *source) +glGetShaderSource + dir length out + len length (sizeof(GLsizei)) + var_flag length nullAllowed + dir source out + len source bufsize + +#GLubyte* glGetString(GLenum name) +glGetString + flag unsupported + +#void glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +glGetTexParameterfv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) +glGetTexParameteriv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glGetUniformfv(GLuint program, GLint location, GLfloat *params) +glGetUniformfv + dir params out + len params glSizeof(uniformType(self, program, location)) + +#void glGetUniformiv(GLuint program, GLint location, GLint *params) +glGetUniformiv + dir params out + len params glSizeof(uniformType(self, program, location)) + +#int glGetUniformLocation(GLuint program, GLchar *name) +glGetUniformLocation + len name (strlen(name) + 1) + +# client-state shall be handled locally by the encoder in most cases. +# however, GL_CURRENT_VERTEX_ATTRIB and potential others are handled by the server side, +# thus we still need to implement it. +#void glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params) +glGetVertexAttribfv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) + +#see glGetVertexAttribfv for comments +#void glGetVertexAttribiv(GLuint index, GLenum pname, GLint *params) +glGetVertexAttribiv + dir params out + len params (glUtilsParamSize(pname) * sizeof(GLint)) + + + +#void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +glReadPixels + dir pixels out + len pixels pixelDataSize(self, width, height, format, type, 1) + +#void glShaderBinary(GLsizei n, GLuint *shaders, GLenum binaryformat, GLvoid *binary, GLsizei length) +glShaderBinary + flag unsupported + +#void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid *pixels) +glTexImage2D + dir pixels in + len pixels pixelDataSize(self, width, height, format, type, 0) + var_flag pixels nullAllowed isLarge + +#void glTexParameterfv(GLenum target, GLenum pname, GLfloat *params) +glTexParameterfv + len params (glUtilsParamSize(pname) * sizeof(GLfloat)) +#void glTexParameteriv(GLenum target, GLenum pname, GLint *params) +glTexParameteriv + len params (glUtilsParamSize(pname) * sizeof(GLint)) + +#void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) +glTexSubImage2D + len pixels pixelDataSize(self, width, height, format, type, 0) + var_flag pixels isLarge + +#void glUniform1fv(GLint location, GLsizei count, GLfloat *v) +glUniform1fv + len v (count * sizeof(GLfloat)) + +#void glUniform1iv(GLint location, GLsizei count, GLint *v) +glUniform1iv + len v (count * sizeof(GLint)) + +#void glUniform2fv(GLint location, GLsizei count, GLfloat *v) +glUniform2fv + len v (count * 2 * sizeof(GLfloat)) + +#void glUniform2iv(GLint location, GLsizei count, GLint *v) +glUniform2iv + len v (count * 2 * sizeof(GLint)) + +#void glUniform3fv(GLint location, GLsizei count, GLfloat *v) +glUniform3fv + len v (count * 3 * sizeof(GLfloat)) + +#void glUniform3iv(GLint location, GLsizei count, GLint *v) +glUniform3iv + len v (3 * count * sizeof(GLint)) + +#void glUniform4fv(GLint location, GLsizei count, GLfloat *v) +glUniform4fv + len v (4 * count * sizeof(GLfloat)) + +#void glUniform4iv(GLint location, GLsizei count, GLint *v) +glUniform4iv + len v (4 * count * sizeof(GLint)) + +#void glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, GLfloat *value) +glUniformMatrix2fv + len value (count * 4 * sizeof(GLfloat)) + +#void glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, GLfloat *value) +glUniformMatrix3fv + len value (count * 9 * sizeof(GLfloat)) + +#void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, GLfloat *value) +glUniformMatrix4fv + len value (count * 16 * sizeof(GLfloat)) + +#void glVertexAttrib1fv(GLuint indx, GLfloat *values) +glVertexAttrib1fv + len values (sizeof(GLfloat)) +#void glVertexAttrib2fv(GLuint indx, GLfloat *values) +glVertexAttrib2fv + len values (2 * sizeof(GLfloat)) + +#void glVertexAttrib3fv(GLuint indx, GLfloat *values) +glVertexAttrib3fv + len values (3 * sizeof(GLfloat)) + +#void glVertexAttrib4fv(GLuint indx, GLfloat *values) +glVertexAttrib4fv + len values (4 * sizeof(GLfloat)) + +#void glVertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLvoid *ptr) +glVertexAttribPointer + flag unsupported + +#void glGetProgramBinaryOES(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) +glGetProgramBinaryOES + flag unsupported + +#void glProgramBinaryOES(GLuint program, GLenum binaryFormat, GLvoid *binary, GLint length) +glProgramBinaryOES + flag unsupported + +#void* glMapBufferOES(GLenum target, GLenum access) +glMapBufferOES + flag unsupported + +#void glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLvoid *pixels) +glTexImage3DOES + len pixels pixelDataSize3D(self, width, height, depth, format, type, 0) + var_flag pixels nullAllowed isLarge + +#void glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *pixels) +glTexSubImage3DOES + len pixels pixelDataSize3D(self, width, height, depth, format, type, 0) + var_flag pixels isLarge + +#void glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLvoid *data) +glCompressedTexImage3DOES + len data imageSize + var_flag data isLarge + +#void glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLvoid *data) +glCompressedTexSubImage3DOES + len data imageSize + var_flag data isLarge + +#void glDeleteVertexArraysOES(GLsizei n, GLuint *arrays) +glDeleteVertexArraysOES + len arrays (n * sizeof(GLuint)) + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + +#void glGenVertexArraysOES(GLsizei n, GLuint *arrays) +glGenVertexArraysOES + len arrays (n * sizeof(GLuint)) + dir arrays out + param_check n if(n<0){ ctx->setError(GL_INVALID_VALUE); return; } + + +#void glDiscardFramebufferEXT(GLenum target, GLsizei numAttachments, GLenum *attachments) +glDiscardFramebufferEXT + len attachments (numAttachments * sizeof(GLenum)) + +#void glMultiDrawArraysEXT(GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) +glMultiDrawArraysEXT + flag unsupported +#void glMultiDrawElementsEXT(GLenum mode, GLsizei *count, GLenum type, GLvoid *indices, GLsizei primcount) +glMultiDrawElementsEXT + flag unsupported + + +# handled by encoder +#void glShaderSource(GLuint shader, GLsizei count, GLstr *string, const GLint *length) +glShaderSource + flag unsupported + + + +#void glGetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, GLuint *groups) +glGetPerfMonitorGroupsAMD + flag unsupported + +#void glGetPerfMonitorCountersAMD(GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) +glGetPerfMonitorCountersAMD + flag unsupported + +#void glGetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString) +glGetPerfMonitorGroupStringAMD + flag unsupported + +#void glGetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString) +glGetPerfMonitorCounterStringAMD + flag unsupported + +#void glGetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname, GLvoid *data) +glGetPerfMonitorCounterInfoAMD + flag unsupported + +#void glGenPerfMonitorsAMD(GLsizei n, GLuint *monitors) +glGenPerfMonitorsAMD + flag unsupported + +#void glDeletePerfMonitorsAMD(GLsizei n, GLuint *monitors) +glDeletePerfMonitorsAMD + flag unsupported + +#void glSelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) +glSelectPerfMonitorCountersAMD + flag unsupported + +#void glBeginPerfMonitorAMD(GLuint monitor) +glBeginPerfMonitorAMD + flag unsupported + +#void glEndPerfMonitorAMD(GLuint monitor) +glEndPerfMonitorAMD + flag unsupported + +#void glGetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) +glGetPerfMonitorCounterDataAMD + flag unsupported + +#void glRenderbufferStorageMultisampleIMG(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +glRenderbufferStorageMultisampleIMG + flag unsupported + +#void glFramebufferTexture2DMultisampleIMG(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) +glFramebufferTexture2DMultisampleIMG + flag unsupported + +#void glDeleteFencesNV(GLsizei n, GLuint *fences) +glDeleteFencesNV + flag unsupported + +#void glGenFencesNV(GLsizei n, GLuint *fences) +glGenFencesNV + flag unsupported + +#GLboolean glIsFenceNV(GLuint fence) +glIsFenceNV + flag unsupported + +#GLboolean glTestFenceNV(GLuint fence) +glTestFenceNV + flag unsupported + +#void glGetFenceivNV(GLuint fence, GLenum pname, GLint *params) +glGetFenceivNV + flag unsupported + +#void glFinishFenceNV(GLuint fence) +glFinishFenceNV + flag unsupported + +#void glSetFenceNV(GLuint fence, GLenum condition) +glSetFenceNV + flag unsupported + +#void glCoverageMaskNV(GLboolean mask) +glCoverageMaskNV + flag unsupported + +#void glCoverageOperationNV(GLenum operation) +glCoverageOperationNV + flag unsupported + +#void glGetDriverControlsQCOM(GLint *num, GLsizei size, GLuint *driverControls) +glGetDriverControlsQCOM + flag unsupported + +#void glGetDriverControlStringQCOM(GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) +glGetDriverControlStringQCOM + flag unsupported + +#void glEnableDriverControlQCOM(GLuint driverControl) +glEnableDriverControlQCOM + flag unsupported + +#void glDisableDriverControlQCOM(GLuint driverControl) +glDisableDriverControlQCOM + flag unsupported + +#void glExtGetTexturesQCOM(GLuint *textures, GLint maxTextures, GLint *numTextures) +glExtGetTexturesQCOM + flag unsupported + +#void glExtGetBuffersQCOM(GLuint *buffers, GLint maxBuffers, GLint *numBuffers) +glExtGetBuffersQCOM + flag unsupported + +#void glExtGetRenderbuffersQCOM(GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) +glExtGetRenderbuffersQCOM + flag unsupported + +#void glExtGetFramebuffersQCOM(GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) +glExtGetFramebuffersQCOM + flag unsupported + +#void glExtGetTexLevelParameterivQCOM(GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) +glExtGetTexLevelParameterivQCOM + flag unsupported + +#void glExtTexObjectStateOverrideiQCOM(GLenum target, GLenum pname, GLint param) +glExtTexObjectStateOverrideiQCOM + flag unsupported + +#void glExtGetTexSubImageQCOM(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) +glExtGetTexSubImageQCOM + flag unsupported + +#void glExtGetBufferPointervQCOM(GLenum target, GLvoidptr *params) +glExtGetBufferPointervQCOM + flag unsupported + +#void glExtGetShadersQCOM(GLuint *shaders, GLint maxShaders, GLint *numShaders) +glExtGetShadersQCOM + flag unsupported + +#void glExtGetProgramsQCOM(GLuint *programs, GLint maxPrograms, GLint *numPrograms) +glExtGetProgramsQCOM + flag unsupported + +#GLboolean glExtIsProgramBinaryQCOM(GLuint program) +glExtIsProgramBinaryQCOM + flag unsupported + +#void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length) +glExtGetProgramBinarySourceQCOM + flag unsupported + +#void glStartTilingQCOM(GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) +glStartTilingQCOM + flag unsupported + +#void glEndTilingQCOM(GLbitfield preserveMask) +glEndTilingQCOM + flag unsupported + + +#void glVertexAttribPointerData(GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void * data, GLuint datalen) +glVertexAttribPointerData + len data datalen + custom_pack data glUtilsPackPointerData((unsigned char *)ptr, (unsigned char *)data, size, type, stride, datalen) + flag custom_decoder + flag not_api + +glVertexAttribPointerOffset + flag custom_decoder + flag not_api + +#client-state, handled by the encoder +#GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer) +glGetVertexAttribPointerv + flag unsupported + +glDrawElementsData + len data datalen + flag custom_decoder + flag not_api + +glDrawElementsOffset + flag custom_decoder + flag not_api + +#GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats) +glGetCompressedTextureFormats + dir formats out + len formats (count * sizeof(GLint)) + flag custom_decoder + flag not_api + +#GL_ENTRY(void, glShaderString, GLuint shader, GLchar *string, GLsizei len) +glShaderString + len string len + flag custom_decoder + flag not_api + +glFinishRoundTrip + flag custom_decoder + flag not_api + diff --git a/emulator/opengl/system/GLESv2_enc/gl2.in b/emulator/opengl/system/GLESv2_enc/gl2.in new file mode 100644 index 0000000..916153b --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/gl2.in @@ -0,0 +1,214 @@ +GL_ENTRY(void, glActiveTexture, GLenum texture) +GL_ENTRY(void, glAttachShader, GLuint program, GLuint shader) +GL_ENTRY(void, glBindAttribLocation, GLuint program, GLuint index, const GLchar* name) +GL_ENTRY(void, glBindBuffer, GLenum target, GLuint buffer) +GL_ENTRY(void, glBindFramebuffer, GLenum target, GLuint framebuffer) +GL_ENTRY(void, glBindRenderbuffer, GLenum target, GLuint renderbuffer) +GL_ENTRY(void, glBindTexture, GLenum target, GLuint texture) +GL_ENTRY(void, glBlendColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glBlendEquation, GLenum mode ) +GL_ENTRY(void, glBlendEquationSeparate, GLenum modeRGB, GLenum modeAlpha) +GL_ENTRY(void, glBlendFunc, GLenum sfactor, GLenum dfactor) +GL_ENTRY(void, glBlendFuncSeparate, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) +GL_ENTRY(void, glBufferData, GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) +GL_ENTRY(void, glBufferSubData, GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data) +GL_ENTRY(GLenum, glCheckFramebufferStatus, GLenum target) +GL_ENTRY(void, glClear, GLbitfield mask) +GL_ENTRY(void, glClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) +GL_ENTRY(void, glClearDepthf, GLclampf depth) +GL_ENTRY(void, glClearStencil, GLint s) +GL_ENTRY(void, glColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +GL_ENTRY(void, glCompileShader, GLuint shader) +GL_ENTRY(void, glCompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data) +GL_ENTRY(void, glCompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data) +GL_ENTRY(void, glCopyTexImage2D, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +GL_ENTRY(void, glCopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(GLuint, glCreateProgram, void) +GL_ENTRY(GLuint, glCreateShader, GLenum type) +GL_ENTRY(void, glCullFace, GLenum mode) +GL_ENTRY(void, glDeleteBuffers, GLsizei n, const GLuint* buffers) +GL_ENTRY(void, glDeleteFramebuffers, GLsizei n, const GLuint* framebuffers) +GL_ENTRY(void, glDeleteProgram, GLuint program) +GL_ENTRY(void, glDeleteRenderbuffers, GLsizei n, const GLuint* renderbuffers) +GL_ENTRY(void, glDeleteShader, GLuint shader) +GL_ENTRY(void, glDeleteTextures, GLsizei n, const GLuint* textures) +GL_ENTRY(void, glDepthFunc, GLenum func) +GL_ENTRY(void, glDepthMask, GLboolean flag) +GL_ENTRY(void, glDepthRangef, GLclampf zNear, GLclampf zFar) +GL_ENTRY(void, glDetachShader, GLuint program, GLuint shader) +GL_ENTRY(void, glDisable, GLenum cap) +GL_ENTRY(void, glDisableVertexAttribArray, GLuint index) +GL_ENTRY(void, glDrawArrays, GLenum mode, GLint first, GLsizei count) +GL_ENTRY(void, glDrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) +GL_ENTRY(void, glEnable, GLenum cap) +GL_ENTRY(void, glEnableVertexAttribArray, GLuint index) +GL_ENTRY(void, glFinish, void) +GL_ENTRY(void, glFlush, void) +GL_ENTRY(void, glFramebufferRenderbuffer, GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +GL_ENTRY(void, glFramebufferTexture2D, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) +GL_ENTRY(void, glFrontFace, GLenum mode) +GL_ENTRY(void, glGenBuffers, GLsizei n, GLuint* buffers) +GL_ENTRY(void, glGenerateMipmap, GLenum target) +GL_ENTRY(void, glGenFramebuffers, GLsizei n, GLuint* framebuffers) +GL_ENTRY(void, glGenRenderbuffers, GLsizei n, GLuint* renderbuffers) +GL_ENTRY(void, glGenTextures, GLsizei n, GLuint* textures) +GL_ENTRY(void, glGetActiveAttrib, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +GL_ENTRY(void, glGetActiveUniform, GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) +GL_ENTRY(void, glGetAttachedShaders, GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders) +GL_ENTRY(int, glGetAttribLocation, GLuint program, const GLchar* name) +GL_ENTRY(void, glGetBooleanv, GLenum pname, GLboolean* params) +GL_ENTRY(void, glGetBufferParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(GLenum, glGetError, void) +GL_ENTRY(void, glGetFloatv, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetFramebufferAttachmentParameteriv, GLenum target, GLenum attachment, GLenum pname, GLint* params) +GL_ENTRY(void, glGetIntegerv, GLenum pname, GLint* params) +GL_ENTRY(void, glGetProgramiv, GLuint program, GLenum pname, GLint* params) +GL_ENTRY(void, glGetProgramInfoLog, GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog) +GL_ENTRY(void, glGetRenderbufferParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(void, glGetShaderiv, GLuint shader, GLenum pname, GLint* params) +GL_ENTRY(void, glGetShaderInfoLog, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog) +GL_ENTRY(void, glGetShaderPrecisionFormat, GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) +GL_ENTRY(void, glGetShaderSource, GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source) +GL_ENTRY(const GLubyte*, glGetString, GLenum name) +GL_ENTRY(void, glGetTexParameterfv, GLenum target, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetTexParameteriv, GLenum target, GLenum pname, GLint* params) +GL_ENTRY(void, glGetUniformfv, GLuint program, GLint location, GLfloat* params) +GL_ENTRY(void, glGetUniformiv, GLuint program, GLint location, GLint* params) +GL_ENTRY(int, glGetUniformLocation, GLuint program, const GLchar* name) +GL_ENTRY(void, glGetVertexAttribfv, GLuint index, GLenum pname, GLfloat* params) +GL_ENTRY(void, glGetVertexAttribiv, GLuint index, GLenum pname, GLint* params) +GL_ENTRY(void, glGetVertexAttribPointerv, GLuint index, GLenum pname, GLvoid** pointer) +GL_ENTRY(void, glHint, GLenum target, GLenum mode) +GL_ENTRY(GLboolean, glIsBuffer, GLuint buffer) +GL_ENTRY(GLboolean, glIsEnabled, GLenum cap) +GL_ENTRY(GLboolean, glIsFramebuffer, GLuint framebuffer) +GL_ENTRY(GLboolean, glIsProgram, GLuint program) +GL_ENTRY(GLboolean, glIsRenderbuffer, GLuint renderbuffer) +GL_ENTRY(GLboolean, glIsShader, GLuint shader) +GL_ENTRY(GLboolean, glIsTexture, GLuint texture) +GL_ENTRY(void, glLineWidth, GLfloat width) +GL_ENTRY(void, glLinkProgram, GLuint program) +GL_ENTRY(void, glPixelStorei, GLenum pname, GLint param) +GL_ENTRY(void, glPolygonOffset, GLfloat factor, GLfloat units) +GL_ENTRY(void, glReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels) +GL_ENTRY(void, glReleaseShaderCompiler, void) +GL_ENTRY(void, glRenderbufferStorage, GLenum target, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glSampleCoverage, GLclampf value, GLboolean invert) +GL_ENTRY(void, glScissor, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glShaderBinary, GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length) +GL_ENTRY(void, glShaderSource, GLuint shader, GLsizei count, const GLchar** string, const GLint* length) +GL_ENTRY(void, glStencilFunc, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilFuncSeparate, GLenum face, GLenum func, GLint ref, GLuint mask) +GL_ENTRY(void, glStencilMask, GLuint mask) +GL_ENTRY(void, glStencilMaskSeparate, GLenum face, GLuint mask) +GL_ENTRY(void, glStencilOp, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(void, glStencilOpSeparate, GLenum face, GLenum fail, GLenum zfail, GLenum zpass) +GL_ENTRY(void, glTexImage2D, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +GL_ENTRY(void, glTexParameterf, GLenum target, GLenum pname, GLfloat param) +GL_ENTRY(void, glTexParameterfv, GLenum target, GLenum pname, const GLfloat* params) +GL_ENTRY(void, glTexParameteri, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glTexParameteriv, GLenum target, GLenum pname, const GLint* params) +GL_ENTRY(void, glTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels) +GL_ENTRY(void, glUniform1f, GLint location, GLfloat x) +GL_ENTRY(void, glUniform1fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform1i, GLint location, GLint x) +GL_ENTRY(void, glUniform1iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform2f, GLint location, GLfloat x, GLfloat y) +GL_ENTRY(void, glUniform2fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform2i, GLint location, GLint x, GLint y) +GL_ENTRY(void, glUniform2iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform3f, GLint location, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glUniform3fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform3i, GLint location, GLint x, GLint y, GLint z) +GL_ENTRY(void, glUniform3iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniform4f, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GL_ENTRY(void, glUniform4fv, GLint location, GLsizei count, const GLfloat* v) +GL_ENTRY(void, glUniform4i, GLint location, GLint x, GLint y, GLint z, GLint w) +GL_ENTRY(void, glUniform4iv, GLint location, GLsizei count, const GLint* v) +GL_ENTRY(void, glUniformMatrix2fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUniformMatrix3fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUniformMatrix4fv, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) +GL_ENTRY(void, glUseProgram, GLuint program) +GL_ENTRY(void, glValidateProgram, GLuint program) +GL_ENTRY(void, glVertexAttrib1f, GLuint indx, GLfloat x) +GL_ENTRY(void, glVertexAttrib1fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib2f, GLuint indx, GLfloat x, GLfloat y) +GL_ENTRY(void, glVertexAttrib2fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib3f, GLuint indx, GLfloat x, GLfloat y, GLfloat z) +GL_ENTRY(void, glVertexAttrib3fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttrib4f, GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +GL_ENTRY(void, glVertexAttrib4fv, GLuint indx, const GLfloat* values) +GL_ENTRY(void, glVertexAttribPointer, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr) +GL_ENTRY(void, glViewport, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glEGLImageTargetTexture2DOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glEGLImageTargetRenderbufferStorageOES, GLenum target, GLeglImageOES image) +GL_ENTRY(void, glGetProgramBinaryOES, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary) +GL_ENTRY(void, glProgramBinaryOES, GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length) +GL_ENTRY(void*, glMapBufferOES, GLenum target, GLenum access) +GL_ENTRY(GLboolean, glUnmapBufferOES, GLenum target) +#GL_ENTRY(void, glGetBufferPointervOES, GLenum target, GLenum pname, GLvoid** params) +GL_ENTRY(void, glTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels) +GL_ENTRY(void, glTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels) +GL_ENTRY(void, glCopyTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) +GL_ENTRY(void, glCompressedTexImage3DOES, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data) +GL_ENTRY(void, glCompressedTexSubImage3DOES, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data) +GL_ENTRY(void, glFramebufferTexture3DOES, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) +GL_ENTRY(void, glBindVertexArrayOES, GLuint array) +GL_ENTRY(void, glDeleteVertexArraysOES, GLsizei n, const GLuint *arrays) +GL_ENTRY(void, glGenVertexArraysOES, GLsizei n, GLuint *arrays) +GL_ENTRY(GLboolean, glIsVertexArrayOES, GLuint array) +GL_ENTRY(void, glDiscardFramebufferEXT, GLenum target, GLsizei numAttachments, const GLenum *attachments) +GL_ENTRY(void, glMultiDrawArraysEXT, GLenum mode, GLint *first, GLsizei *count, GLsizei primcount) +GL_ENTRY(void, glMultiDrawElementsEXT, GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) + +#not supported +GL_ENTRY(void, glGetPerfMonitorGroupsAMD, GLint *numGroups, GLsizei groupsSize, GLuint *groups) +GL_ENTRY(void, glGetPerfMonitorCountersAMD, GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters) +GL_ENTRY(void, glGetPerfMonitorGroupStringAMD, GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString) +GL_ENTRY(void, glGetPerfMonitorCounterStringAMD, GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString) +GL_ENTRY(void, glGetPerfMonitorCounterInfoAMD, GLuint group, GLuint counter, GLenum pname, GLvoid *data) +GL_ENTRY(void, glGenPerfMonitorsAMD, GLsizei n, GLuint *monitors) +GL_ENTRY(void, glDeletePerfMonitorsAMD, GLsizei n, GLuint *monitors) +GL_ENTRY(void, glSelectPerfMonitorCountersAMD, GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList) +GL_ENTRY(void, glBeginPerfMonitorAMD, GLuint monitor) +GL_ENTRY(void, glEndPerfMonitorAMD, GLuint monitor) +GL_ENTRY(void, glGetPerfMonitorCounterDataAMD, GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten) + +GL_ENTRY(void, glRenderbufferStorageMultisampleIMG, GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +GL_ENTRY(void, glFramebufferTexture2DMultisampleIMG, GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples) +GL_ENTRY(void, glDeleteFencesNV, GLsizei n, const GLuint *fences) +GL_ENTRY(void, glGenFencesNV, GLsizei n, GLuint *fences) +GL_ENTRY(GLboolean, glIsFenceNV, GLuint fence) +GL_ENTRY(GLboolean, glTestFenceNV, GLuint fence) +GL_ENTRY(void, glGetFenceivNV, GLuint fence, GLenum pname, GLint *params) +GL_ENTRY(void, glFinishFenceNV, GLuint fence) +GL_ENTRY(void, glSetFenceNV, GLuint fence, GLenum condition) +GL_ENTRY(void, glCoverageMaskNV, GLboolean mask) +GL_ENTRY(void, glCoverageOperationNV, GLenum operation) +GL_ENTRY(void, glGetDriverControlsQCOM, GLint *num, GLsizei size, GLuint *driverControls) +GL_ENTRY(void, glGetDriverControlStringQCOM, GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString) +GL_ENTRY(void, glEnableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glDisableDriverControlQCOM, GLuint driverControl) +GL_ENTRY(void, glExtGetTexturesQCOM, GLuint *textures, GLint maxTextures, GLint *numTextures) +GL_ENTRY(void, glExtGetBuffersQCOM, GLuint *buffers, GLint maxBuffers, GLint *numBuffers) +GL_ENTRY(void, glExtGetRenderbuffersQCOM, GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers) +GL_ENTRY(void, glExtGetFramebuffersQCOM, GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers) +GL_ENTRY(void, glExtGetTexLevelParameterivQCOM, GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params) +GL_ENTRY(void, glExtTexObjectStateOverrideiQCOM, GLenum target, GLenum pname, GLint param) +GL_ENTRY(void, glExtGetTexSubImageQCOM, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels) +GL_ENTRY(void, glExtGetBufferPointervQCOM, GLenum target, GLvoidptr *params) +GL_ENTRY(void, glExtGetShadersQCOM, GLuint *shaders, GLint maxShaders, GLint *numShaders) +GL_ENTRY(void, glExtGetProgramsQCOM, GLuint *programs, GLint maxPrograms, GLint *numPrograms) +GL_ENTRY(GLboolean, glExtIsProgramBinaryQCOM, GLuint program) +GL_ENTRY(void, glExtGetProgramBinarySourceQCOM, GLuint program, GLenum shadertype, GLchar *source, GLint *length) +GL_ENTRY(void, glStartTilingQCOM, GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask) +GL_ENTRY(void, glEndTilingQCOM, GLbitfield preserveMask) + +# add-ons +GL_ENTRY(void, glVertexAttribPointerData, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, void * data, GLuint datalen) +GL_ENTRY(void, glVertexAttribPointerOffset, GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint offset) +GL_ENTRY(void, glDrawElementsOffset, GLenum mode, GLsizei count, GLenum type, GLuint offset) +GL_ENTRY(void, glDrawElementsData, GLenum mode, GLsizei count, GLenum type, void *data, GLuint datalen) +GL_ENTRY(void, glGetCompressedTextureFormats, int count, GLint *formats) +GL_ENTRY(void, glShaderString, GLuint shader, const GLchar* string, GLsizei len) +GL_ENTRY(int, glFinishRoundTrip, void) diff --git a/emulator/opengl/system/GLESv2_enc/gl2.types b/emulator/opengl/system/GLESv2_enc/gl2.types new file mode 100644 index 0000000..4cee99e --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/gl2.types @@ -0,0 +1,37 @@ +GLbitfield 32 0x%08x false +GLboolean 8 %d false +GLclampf 32 %f false +GLclampx 32 0x%08x false +GLeglImageOES 32 %p false +GLenum 32 0x%08x false +GLfixed 32 0x%08x false +GLfloat 32 %f false +GLint 32 %d false +GLintptr 32 %p false +GLshort 16 %d false +GLsizei 32 %d false +GLsizeiptr 32 %p false +GLubyte 8 0x%02x false +GLuint 32 %u false +GLvoid 0 %x false +GLchar 8 %d false +GLenum* 32 0x%08x true +GLboolean* 32 0x%08x true +GLclampf* 32 0x%08x true +GLclampx* 32 0x%08x true +GLeglImageOES* 32 0x%08x true +GLfixed* 32 0x%08x true +GLfloat* 32 0x%08x true +GLint* 32 0x%08x true +GLshort* 32 0x%08x true +GLsizei* 32 0x%08x true +GLubyte* 32 0x%08x true +GLuint* 32 0x%08x true +GLvoid* 32 0x%08x true +GLchar* 32 0x%08x true +GLchar** 32 0x%08x true +GLvoid** 32 0x%08x true +void* 32 0x%08x true +GLstr 32 %s true +GLstr* 32 0x%08x true +GLvoidptr* 32 0x%08x true
\ No newline at end of file diff --git a/emulator/opengl/system/GLESv2_enc/gl2_types.h b/emulator/opengl/system/GLESv2_enc/gl2_types.h new file mode 100644 index 0000000..bfff61d --- /dev/null +++ b/emulator/opengl/system/GLESv2_enc/gl2_types.h @@ -0,0 +1,21 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _GL_2_TYPES_H_ +#define _GL_2_TYPES_H_ +#include "gl_base_types.h" + +typedef void *GLvoidptr; +#endif diff --git a/emulator/opengl/system/OpenglSystemCommon/Android.mk b/emulator/opengl/system/OpenglSystemCommon/Android.mk new file mode 100644 index 0000000..6198748 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH := $(call my-dir) + +$(call emugl-begin-shared-library,libOpenglSystemCommon) +$(call emugl-import,libGLESv1_enc libGLESv2_enc lib_renderControl_enc) + +LOCAL_SRC_FILES := \ + HostConnection.cpp \ + QemuPipeStream.cpp \ + ThreadInfo.cpp + +$(call emugl-export,C_INCLUDES,$(LOCAL_PATH) bionic/libc/private) + +$(call emugl-end-module) diff --git a/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h b/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h new file mode 100644 index 0000000..3c8cb55 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/EGLClientIface.h @@ -0,0 +1,41 @@ +/* +* Copyright 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef _SYSTEM_COMMON_EGL_CLIENT_IFACE_H +#define _SYSTEM_COMMON_EGL_CLIENT_IFACE_H + +struct EGLThreadInfo; // defined in ThreadInfo.h + +typedef struct { + EGLThreadInfo* (*getThreadInfo)(); + const char* (*getGLString)(int glEnum); +} EGLClient_eglInterface; + +typedef struct { + void* (*getProcAddress)(const char *funcName); + void (*init)(); + void (*finish)(); +} EGLClient_glesInterface; + +// +// Any GLES/GLES2 client API library should define a function named "init_emul_gles" +// with the following prototype, +// It will be called by EGL after loading the GLES library for initialization +// and exchanging interface function pointers. +// +typedef EGLClient_glesInterface *(*init_emul_gles_t)(EGLClient_eglInterface *eglIface); + +#endif diff --git a/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp b/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp new file mode 100644 index 0000000..940f5ae --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp @@ -0,0 +1,153 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "HostConnection.h" +#include "TcpStream.h" +#include "QemuPipeStream.h" +#include "ThreadInfo.h" +#include <cutils/log.h> +#include "GLEncoder.h" +#include "GL2Encoder.h" + +#define STREAM_BUFFER_SIZE 4*1024*1024 +#define STREAM_PORT_NUM 22468 + +/* Set to 1 to use a QEMU pipe, or 0 for a TCP connection */ +#define USE_QEMU_PIPE 1 + +HostConnection::HostConnection() : + m_stream(NULL), + m_glEnc(NULL), + m_gl2Enc(NULL), + m_rcEnc(NULL) +{ +} + +HostConnection::~HostConnection() +{ + delete m_stream; + delete m_glEnc; + delete m_gl2Enc; + delete m_rcEnc; +} + +HostConnection *HostConnection::get() +{ + /* TODO: Make this configurable with a system property */ + const int useQemuPipe = USE_QEMU_PIPE; + + // Get thread info + EGLThreadInfo *tinfo = getEGLThreadInfo(); + if (!tinfo) { + return NULL; + } + + if (tinfo->hostConn == NULL) { + HostConnection *con = new HostConnection(); + if (NULL == con) { + return NULL; + } + + if (useQemuPipe) { + QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE); + if (!stream) { + ALOGE("Failed to create QemuPipeStream for host connection!!!\n"); + delete con; + return NULL; + } + if (stream->connect() < 0) { + ALOGE("Failed to connect to host (QemuPipeStream)!!!\n"); + delete stream; + delete con; + return NULL; + } + con->m_stream = stream; + } + else /* !useQemuPipe */ + { + TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE); + if (!stream) { + ALOGE("Failed to create TcpStream for host connection!!!\n"); + delete con; + return NULL; + } + + if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) { + ALOGE("Failed to connect to host (TcpStream)!!!\n"); + delete stream; + delete con; + return NULL; + } + con->m_stream = stream; + } + + // send zero 'clientFlags' to the host. + unsigned int *pClientFlags = + (unsigned int *)con->m_stream->allocBuffer(sizeof(unsigned int)); + *pClientFlags = 0; + con->m_stream->commitBuffer(sizeof(unsigned int)); + + ALOGD("HostConnection::get() New Host Connection established %p, tid %d\n", con, gettid()); + tinfo->hostConn = con; + } + + return tinfo->hostConn; +} + +GLEncoder *HostConnection::glEncoder() +{ + if (!m_glEnc) { + m_glEnc = new GLEncoder(m_stream); + DBG("HostConnection::glEncoder new encoder %p, tid %d", m_glEnc, gettid()); + m_glEnc->setContextAccessor(s_getGLContext); + } + return m_glEnc; +} + +GL2Encoder *HostConnection::gl2Encoder() +{ + if (!m_gl2Enc) { + m_gl2Enc = new GL2Encoder(m_stream); + DBG("HostConnection::gl2Encoder new encoder %p, tid %d", m_gl2Enc, gettid()); + m_gl2Enc->setContextAccessor(s_getGL2Context); + } + return m_gl2Enc; +} + +renderControl_encoder_context_t *HostConnection::rcEncoder() +{ + if (!m_rcEnc) { + m_rcEnc = new renderControl_encoder_context_t(m_stream); + } + return m_rcEnc; +} + +gl_client_context_t *HostConnection::s_getGLContext() +{ + EGLThreadInfo *ti = getEGLThreadInfo(); + if (ti->hostConn) { + return ti->hostConn->m_glEnc; + } + return NULL; +} + +gl2_client_context_t *HostConnection::s_getGL2Context() +{ + EGLThreadInfo *ti = getEGLThreadInfo(); + if (ti->hostConn) { + return ti->hostConn->m_gl2Enc; + } + return NULL; +} diff --git a/emulator/opengl/system/OpenglSystemCommon/HostConnection.h b/emulator/opengl/system/OpenglSystemCommon/HostConnection.h new file mode 100644 index 0000000..e7a5ac4 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/HostConnection.h @@ -0,0 +1,55 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __COMMON_HOST_CONNECTION_H +#define __COMMON_HOST_CONNECTION_H + +#include "IOStream.h" +#include "renderControl_enc.h" + +class GLEncoder; +class gl_client_context_t; +class GL2Encoder; +class gl2_client_context_t; + +class HostConnection +{ +public: + static HostConnection *get(); + ~HostConnection(); + + GLEncoder *glEncoder(); + GL2Encoder *gl2Encoder(); + renderControl_encoder_context_t *rcEncoder(); + + void flush() { + if (m_stream) { + m_stream->flush(); + } + } + +private: + HostConnection(); + static gl_client_context_t *s_getGLContext(); + static gl2_client_context_t *s_getGL2Context(); + +private: + IOStream *m_stream; + GLEncoder *m_glEnc; + GL2Encoder *m_gl2Enc; + renderControl_encoder_context_t *m_rcEnc; +}; + +#endif diff --git a/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp new file mode 100644 index 0000000..50c3d8b --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp @@ -0,0 +1,190 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "QemuPipeStream.h" +#include <hardware/qemu_pipe.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> + +QemuPipeStream::QemuPipeStream(size_t bufSize) : + IOStream(bufSize), + m_sock(-1), + m_bufsize(bufSize), + m_buf(NULL) +{ +} + +QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) : + IOStream(bufSize), + m_sock(sock), + m_bufsize(bufSize), + m_buf(NULL) +{ +} + +QemuPipeStream::~QemuPipeStream() +{ + if (m_sock >= 0) { + ::close(m_sock); + } + if (m_buf != NULL) { + free(m_buf); + } +} + + +int QemuPipeStream::connect(void) +{ + m_sock = qemu_pipe_open("opengles"); + if (!valid()) return -1; + return 0; +} + +void *QemuPipeStream::allocBuffer(size_t minSize) +{ + size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize); + if (!m_buf) { + m_buf = (unsigned char *)malloc(allocSize); + } + else if (m_bufsize < allocSize) { + unsigned char *p = (unsigned char *)realloc(m_buf, allocSize); + if (p != NULL) { + m_buf = p; + m_bufsize = allocSize; + } else { + ERR("realloc (%d) failed\n", allocSize); + free(m_buf); + m_buf = NULL; + m_bufsize = 0; + } + } + + return m_buf; +}; + +int QemuPipeStream::commitBuffer(size_t size) +{ + return writeFully(m_buf, size); +} + +int QemuPipeStream::writeFully(const void *buf, size_t len) +{ + //DBG(">> QemuPipeStream::writeFully %d\n", len); + if (!valid()) return -1; + + size_t res = len; + int retval = 0; + + while (res > 0) { + ssize_t stat = ::write(m_sock, (const char *)(buf) + (len - res), res); + if (stat > 0) { + res -= stat; + continue; + } + if (stat == 0) { /* EOF */ + ERR("QemuPipeStream::writeFully failed: premature EOF\n"); + retval = -1; + break; + } + if (errno == EINTR) { + continue; + } + retval = stat; + ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno)); + break; + } + //DBG("<< QemuPipeStream::writeFully %d\n", len ); + return retval; +} + +const unsigned char *QemuPipeStream::readFully(void *buf, size_t len) +{ + //DBG(">> QemuPipeStream::readFully %d\n", len); + if (!valid()) return NULL; + if (!buf) { + if (len>0) ERR("QemuPipeStream::readFully failed, buf=NULL, len %d", len); + return NULL; // do not allow NULL buf in that implementation + } + size_t res = len; + while (res > 0) { + ssize_t stat = ::read(m_sock, (char *)(buf) + len - res, len); + if (stat == 0) { + // client shutdown; + return NULL; + } else if (stat < 0) { + if (errno == EINTR) { + continue; + } else { + ERR("QemuPipeStream::readFully failed (buf %p): %s\n", + buf, strerror(errno)); + return NULL; + } + } else { + res -= stat; + } + } + //DBG("<< QemuPipeStream::readFully %d\n", len); + return (const unsigned char *)buf; +} + +const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len) +{ + //DBG(">> QemuPipeStream::read %d\n", *inout_len); + if (!valid()) return NULL; + if (!buf) { + ERR("QemuPipeStream::read failed, buf=NULL"); + return NULL; // do not allow NULL buf in that implementation + } + + int n = recv(buf, *inout_len); + + if (n > 0) { + *inout_len = n; + return (const unsigned char *)buf; + } + + //DBG("<< QemuPipeStream::read %d\n", *inout_len); + return NULL; +} + +int QemuPipeStream::recv(void *buf, size_t len) +{ + if (!valid()) return int(ERR_INVALID_SOCKET); + char* p = (char *)buf; + int ret = 0; + while(len > 0) { + int res = ::read(m_sock, p, len); + if (res > 0) { + p += res; + ret += res; + len -= res; + continue; + } + if (res == 0) { /* EOF */ + break; + } + if (errno == EINTR) + continue; + + /* A real error */ + if (ret == 0) + ret = -1; + break; + } + return ret; +} diff --git a/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h new file mode 100644 index 0000000..57ee399 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h @@ -0,0 +1,51 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef __QEMU_PIPE_STREAM_H +#define __QEMU_PIPE_STREAM_H + +/* This file implements an IOStream that uses a QEMU fast-pipe + * to communicate with the emulator's 'opengles' service. See + * <hardware/qemu_pipe.h> for more details. + */ +#include <stdlib.h> +#include "IOStream.h" + +class QemuPipeStream : public IOStream { +public: + typedef enum { ERR_INVALID_SOCKET = -1000 } QemuPipeStreamError; + + explicit QemuPipeStream(size_t bufsize = 10000); + ~QemuPipeStream(); + int connect(void); + + virtual void *allocBuffer(size_t minSize); + virtual int commitBuffer(size_t size); + virtual const unsigned char *readFully( void *buf, size_t len); + virtual const unsigned char *read( void *buf, size_t *inout_len); + + bool valid() { return m_sock >= 0; } + int recv(void *buf, size_t len); + + virtual int writeFully(const void *buf, size_t len); + +private: + int m_sock; + size_t m_bufsize; + unsigned char *m_buf; + QemuPipeStream(int sock, size_t bufSize); +}; + +#endif diff --git a/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp new file mode 100644 index 0000000..75da8f2 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.cpp @@ -0,0 +1,39 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "ThreadInfo.h" +#include "cutils/threads.h" + +thread_store_t s_tls = THREAD_STORE_INITIALIZER; + +static void tlsDestruct(void *ptr) +{ + if (ptr) { + EGLThreadInfo *ti = (EGLThreadInfo *)ptr; + delete ti->hostConn; + delete ti; + } +} + +EGLThreadInfo *slow_getEGLThreadInfo() +{ + EGLThreadInfo *ti = (EGLThreadInfo *)thread_store_get(&s_tls); + if (ti) return ti; + + ti = new EGLThreadInfo(); + thread_store_set(&s_tls, ti, tlsDestruct); + + return ti; +} diff --git a/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h new file mode 100644 index 0000000..0328733 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/ThreadInfo.h @@ -0,0 +1,59 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _THREAD_INFO_H +#define _THREAD_INFO_H + +#include "HostConnection.h" +#include <pthread.h> +#ifdef HAVE_ANDROID_OS +#include <bionic_tls.h> +#endif + +struct EGLContext_t; + +struct EGLThreadInfo +{ + EGLThreadInfo() : currentContext(NULL), hostConn(NULL), eglError(EGL_SUCCESS) {} + + EGLContext_t *currentContext; + HostConnection *hostConn; + int eglError; +}; + + +EGLThreadInfo *slow_getEGLThreadInfo(); + +#ifdef HAVE_ANDROID_OS + // We have a dedicated TLS slot in bionic + inline EGLThreadInfo* getEGLThreadInfo() { + EGLThreadInfo *tInfo = + (EGLThreadInfo *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]); + if (!tInfo) { + tInfo = slow_getEGLThreadInfo(); + ((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)tInfo; + } + return tInfo; + } +#else + inline EGLThreadInfo* getEGLThreadInfo() { + return slow_getEGLThreadInfo(); + } +#endif + + + + +#endif // of _THREAD_INFO_H diff --git a/emulator/opengl/system/OpenglSystemCommon/gralloc_cb.h b/emulator/opengl/system/OpenglSystemCommon/gralloc_cb.h new file mode 100644 index 0000000..e879409 --- /dev/null +++ b/emulator/opengl/system/OpenglSystemCommon/gralloc_cb.h @@ -0,0 +1,106 @@ +/* +* Copyright 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef __GRALLOC_CB_H__ +#define __GRALLOC_CB_H__ + +#include <hardware/hardware.h> +#include <hardware/gralloc.h> +#include <cutils/native_handle.h> + +#define BUFFER_HANDLE_MAGIC ((int)0xabfabfab) +#define CB_HANDLE_NUM_INTS(nfds) (int)((sizeof(cb_handle_t) - (nfds)*sizeof(int)) / sizeof(int)) + +// +// Our buffer handle structure +// +struct cb_handle_t : public native_handle { + + cb_handle_t(int p_fd, int p_ashmemSize, int p_usage, + int p_width, int p_height, + int p_glFormat, int p_glType) : + fd(p_fd), + magic(BUFFER_HANDLE_MAGIC), + usage(p_usage), + width(p_width), + height(p_height), + glFormat(p_glFormat), + glType(p_glType), + ashmemSize(p_ashmemSize), + ashmemBase(NULL), + ashmemBasePid(0), + mappedPid(0), + lockedLeft(0), + lockedTop(0), + lockedWidth(0), + lockedHeight(0), + hostHandle(0) + { + version = sizeof(native_handle); + numFds = 0; + numInts = CB_HANDLE_NUM_INTS(numFds); + } + + ~cb_handle_t() { + magic = 0; + } + + void setFd(int p_fd) { + if (p_fd >= 0) { + numFds = 1; + } + else { + numFds = 0; + } + fd = p_fd; + numInts = CB_HANDLE_NUM_INTS(numFds); + } + + static bool validate(cb_handle_t * hnd) { + return (hnd && + hnd->version == sizeof(native_handle) && + hnd->magic == BUFFER_HANDLE_MAGIC && + hnd->numInts == CB_HANDLE_NUM_INTS(hnd->numFds)); + } + + bool canBePosted() { + return (0 != (usage & GRALLOC_USAGE_HW_FB)); + } + + // file-descriptors + int fd; // ashmem fd (-1 of ashmem region did not allocated, i.e. no SW access needed) + + // ints + int magic; // magic number in order to validate a pointer to be a cb_handle_t + int usage; // usage bits the buffer was created with + int width; // buffer width + int height; // buffer height + int glFormat; // OpenGL format enum used for host h/w color buffer + int glType; // OpenGL type enum used when uploading to host + int ashmemSize; // ashmem region size for the buffer (0 unless is HW_FB buffer or + // s/w access is needed) + int ashmemBase; // CPU address of the mapped ashmem region + int ashmemBasePid; // process id which mapped the ashmem region + int mappedPid; // process id which succeeded gralloc_register call + int lockedLeft; // region of buffer locked for s/w write + int lockedTop; + int lockedWidth; + int lockedHeight; + uint32_t hostHandle; +}; + + +#endif //__GRALLOC_CB_H__ diff --git a/emulator/opengl/system/egl/Android.mk b/emulator/opengl/system/egl/Android.mk new file mode 100644 index 0000000..da9398f --- /dev/null +++ b/emulator/opengl/system/egl/Android.mk @@ -0,0 +1,42 @@ +ifneq (false,$(BUILD_EMULATOR_OPENGL_DRIVER)) + +LOCAL_PATH := $(call my-dir) + +$(call emugl-begin-shared-library,libEGL_emulation) +$(call emugl-import,libOpenglSystemCommon) +$(call emugl-set-shared-library-subpath,egl) + +LOCAL_CFLAGS += -DLOG_TAG=\"EGL_emulation\" -DEGL_EGLEXT_PROTOTYPES -DWITH_GLES2 + +LOCAL_SRC_FILES := \ + eglDisplay.cpp \ + egl.cpp \ + ClientAPIExts.cpp + +LOCAL_SHARED_LIBRARIES += libdl + +# Used to access the Bionic private OpenGL TLS slot +LOCAL_C_INCLUDES += bionic/libc/private + +$(call emugl-end-module) + +#### egl.cfg #### + +# Ensure that this file is only copied to emulator-specific builds. +# Other builds are device-specific and will provide their own +# version of this file to point to the appropriate HW EGL libraries. +# +ifneq (,$(filter full full_x86 sdk sdk_x86 google_sdk google_sdk_x86,$(TARGET_PRODUCT))) +include $(CLEAR_VARS) + +LOCAL_MODULE := egl.cfg +LOCAL_SRC_FILES := $(LOCAL_MODULE) + +LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/egl +LOCAL_MODULE_TAGS := debug +LOCAL_MODULE_CLASS := ETC + +include $(BUILD_PREBUILT) +endif # TARGET_PRODUCT in 'full sdk full_x86 sdk_x86 google_sdk google_sdk_x86) + +endif # BUILD_EMULATOR_OPENGL_DRIVER != false diff --git a/emulator/opengl/system/egl/ClientAPIExts.cpp b/emulator/opengl/system/egl/ClientAPIExts.cpp new file mode 100644 index 0000000..5e81afe --- /dev/null +++ b/emulator/opengl/system/egl/ClientAPIExts.cpp @@ -0,0 +1,157 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "ClientAPIExts.h" +#include "ThreadInfo.h" +#include <GLES/gl.h> +#include <GLES/glext.h> +#include "eglContext.h" + +namespace ClientAPIExts +{ + +// +// define function pointer type for each extention function +// typename has the form __egl_{funcname}_t +// +#define FUNC_TYPE(fname) __egl_ ## fname ## _t +#define API_ENTRY(fname,params,args) \ + typedef void (GL_APIENTRY *FUNC_TYPE(fname)) params; + +#define API_ENTRY_RET(rtype,fname,params,args) \ + typedef rtype (GL_APIENTRY *FUNC_TYPE(fname)) params; + +#include "ClientAPIExts.in" +#undef API_ENTRY +#undef API_ENTRY_RET + +///// +// Define static table to store the function value for each +// client API. functions pointers will get initialized through +// ClientAPIExts::initClientFuncs function after each client API has been +// loaded. +///// +#define API_ENTRY(fname,params,args) \ + FUNC_TYPE(fname) fname; + +#define API_ENTRY_RET(rtype,fname,params,args) \ + API_ENTRY(fname,params,args) + +static struct _ext_table +{ +#include "ClientAPIExts.in" +} s_client_extensions[2]; + +#undef API_ENTRY +#undef API_ENTRY_RET + +// +// This function initialized each entry in the s_client_extensions +// struct at the givven index using the givven client interface +// +void initClientFuncs(const EGLClient_glesInterface *iface, int idx) +{ +#define API_ENTRY(fname,params,args) \ + s_client_extensions[idx].fname = \ + (FUNC_TYPE(fname))iface->getProcAddress(#fname); + +#define API_ENTRY_RET(rtype,fname,params,args) \ + API_ENTRY(fname,params,args) + + // + // reset all func pointers to NULL + // + memset(&s_client_extensions[idx], 0, sizeof(struct _ext_table)); + + // + // And now query the GLES library for each proc address + // +#include "ClientAPIExts.in" +#undef API_ENTRY +#undef API_ENTRY_RET +} + +// +// Define implementation for each extension function which checks +// the current context version and calls to the correct client API +// function. +// +#define API_ENTRY(fname,params,args) \ + static void _egl_ ## fname params \ + { \ + EGLThreadInfo* thread = getEGLThreadInfo(); \ + if (!thread->currentContext) { \ + return; \ + } \ + int idx = (int)thread->currentContext->version - 1; \ + if (!s_client_extensions[idx].fname) { \ + return; \ + } \ + (*s_client_extensions[idx].fname) args; \ + } + +#define API_ENTRY_RET(rtype,fname,params,args) \ + static rtype _egl_ ## fname params \ + { \ + EGLThreadInfo* thread = getEGLThreadInfo(); \ + if (!thread->currentContext) { \ + return (rtype)0; \ + } \ + int idx = (int)thread->currentContext->version - 1; \ + if (!s_client_extensions[idx].fname) { \ + return (rtype)0; \ + } \ + return (*s_client_extensions[idx].fname) args; \ + } + +#include "ClientAPIExts.in" +#undef API_ENTRY +#undef API_ENTRY_RET + +// +// Define a table to map function names to the local _egl_ version of +// the extension function, to be used in eglGetProcAddress. +// +#define API_ENTRY(fname,params,args) \ + { #fname, (void*)_egl_ ## fname}, +#define API_ENTRY_RET(rtype,fname,params,args) \ + API_ENTRY(fname,params,args) + +static const struct _client_ext_funcs { + const char *fname; + void* proc; +} s_client_ext_funcs[] = { +#include "ClientAPIExts.in" +}; +static const int numExtFuncs = sizeof(s_client_ext_funcs) / + sizeof(s_client_ext_funcs[0]); + +#undef API_ENTRY +#undef API_ENTRY_RET + +// +// returns the __egl_ version of the givven extension function name. +// +void* getProcAddress(const char *fname) +{ + for (int i=0; i<numExtFuncs; i++) { + if (!strcmp(fname, s_client_ext_funcs[i].fname)) { + return s_client_ext_funcs[i].proc; + } + } + return NULL; +} + +} // of namespace ClientAPIExts diff --git a/emulator/opengl/system/egl/ClientAPIExts.h b/emulator/opengl/system/egl/ClientAPIExts.h new file mode 100644 index 0000000..eee9172 --- /dev/null +++ b/emulator/opengl/system/egl/ClientAPIExts.h @@ -0,0 +1,29 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _CLIENT_APIS_EXTS_H +#define _CLIENT_APIS_EXTS_H + +#include "EGLClientIface.h" + +namespace ClientAPIExts +{ + +void initClientFuncs(const EGLClient_glesInterface *iface, int idx); +void* getProcAddress(const char *fname); + +} // of namespace ClientAPIExts + +#endif diff --git a/emulator/opengl/system/egl/ClientAPIExts.in b/emulator/opengl/system/egl/ClientAPIExts.in new file mode 100644 index 0000000..5850701 --- /dev/null +++ b/emulator/opengl/system/egl/ClientAPIExts.in @@ -0,0 +1,201 @@ +// +// Each extension function should have one of the following +// macro definitions: +// API_ENTRY(funcname, paramlist, arglist) +// -or- (if the function has a return value) +// API_ENTRY_RET(return_type,funcname, paramlist, arglist) +// +API_ENTRY(glEGLImageTargetTexture2DOES, + (GLenum target, GLeglImageOES image), + (target, image)) + +API_ENTRY(glEGLImageTargetRenderbufferStorageOES, + (GLenum target, GLeglImageOES image), + (target, image)) + +API_ENTRY(glBlendEquationSeparateOES, + (GLenum modeRGB, GLenum modeAlpha), + (modeRGB, modeAlpha)) + +API_ENTRY(glBlendFuncSeparateOES, + (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), + (srcRGB, dstRGB, srcAlpha, dstAlpha)) + +API_ENTRY(glBlendEquationOES, + (GLenum mode), + (mode)) + +API_ENTRY(glCurrentPaletteMatrixOES, + (GLuint matrixpaletteindex), + (matrixpaletteindex)) + +API_ENTRY(glLoadPaletteFromModelViewMatrixOES, + (void), + ()) + +API_ENTRY(glMatrixIndexPointerOES, + (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer), + (size, type, stride, pointer)) + +API_ENTRY(glWeightPointerOES, + (GLint size, GLenum type, GLsizei stride, const GLvoid * pointer), + (size, type, stride, pointer)) + +API_ENTRY(glDepthRangefOES, + (GLclampf zNear, GLclampf zFar), + (zNear, zFar)) + +API_ENTRY(glFrustumfOES, + (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), + (left, right, bottom, top, zNear, zFar)) + +API_ENTRY(glOrthofOES, + (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), + (left, right, bottom, top, zNear, zFar)) + +API_ENTRY(glClipPlanefOES, + (GLenum plane, const GLfloat *equation), + (plane, equation)) + +API_ENTRY(glGetClipPlanefOES, + (GLenum pname, GLfloat * eqn), + (pname, eqn)) + +API_ENTRY(glClearDepthfOES, + (GLclampf depth), + (depth)) + +API_ENTRY(glPointSizePointerOES, + (GLenum type, GLsizei stride, const GLvoid *pointer), + (type, stride, pointer)) + +API_ENTRY(glTexGenfOES, + (GLenum coord, GLenum pname, GLfloat param), + (coord, pname, param)) + +API_ENTRY(glTexGenfvOES, + (GLenum coord, GLenum pname, const GLfloat *params), + (coord, pname, params)) + +API_ENTRY(glTexGeniOES, + (GLenum coord, GLenum pname, GLint param), + (coord, pname, param)) + +API_ENTRY(glTexGenivOES, + (GLenum coord, GLenum pname, const GLint *params), + (coord, pname, params)) + +API_ENTRY(glTexGenxOES, + (GLenum coord, GLenum pname, GLfixed param), + (coord, pname, param)) + +API_ENTRY(glTexGenxvOES, + (GLenum coord, GLenum pname, const GLfixed *params), + (coord, pname, params)) + +API_ENTRY(glGetTexGenfvOES, + (GLenum coord, GLenum pname, GLfloat *params), + (coord, pname, params)) + +API_ENTRY(glGetTexGenivOES, + (GLenum coord, GLenum pname, GLint *params), + (coord, pname, params)) + +API_ENTRY(glGetTexGenxvOES, + (GLenum coord, GLenum pname, GLfixed *params), + (coord, pname, params)) + +API_ENTRY_RET(GLboolean, + glIsRenderbufferOES, + (GLuint renderbuffer), + (renderbuffer)) + +API_ENTRY(glBindRenderbufferOES, + (GLenum target, GLuint renderbuffer), + (target, renderbuffer)) + +API_ENTRY(glDeleteRenderbuffersOES, + (GLsizei n, const GLuint* renderbuffers), + (n, renderbuffers)) + +API_ENTRY(glGenRenderbuffersOES, + (GLsizei n, GLuint* renderbuffers), + (n, renderbuffers)) + +API_ENTRY(glRenderbufferStorageOES, + (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), + (target, internalformat, width, height)) + +API_ENTRY(glGetRenderbufferParameterivOES, + (GLenum target, GLenum pname, GLint* params), + (target, pname, params)) + +API_ENTRY_RET(GLboolean, + glIsFramebufferOES, + (GLuint framebuffer), + (framebuffer)) + +API_ENTRY(glBindFramebufferOES, + (GLenum target, GLuint framebuffer), + (target, framebuffer)) + +API_ENTRY(glDeleteFramebuffersOES, + (GLsizei n, const GLuint* framebuffers), + (n, framebuffers)) + +API_ENTRY(glGenFramebuffersOES, + (GLsizei n, GLuint* framebuffers), + (n, framebuffers)) + +API_ENTRY_RET(GLenum, + glCheckFramebufferStatusOES, + (GLenum target), + (target)) + +API_ENTRY(glFramebufferTexture2DOES, + (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), + (target, attachment, textarget, texture, level)) + +API_ENTRY(glFramebufferRenderbufferOES, + (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), + (target, attachment, renderbuffertarget, renderbuffer)) + +API_ENTRY(glGetFramebufferAttachmentParameterivOES, + (GLenum target, GLenum attachment, GLenum pname, GLint* params), + (target, attachment, pname, params)) + +API_ENTRY(glGenerateMipmapOES, + (GLenum target), + (target)) + +API_ENTRY(glDrawTexsOES, + (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height), + (x, y, z, width, height)) + +API_ENTRY(glDrawTexiOES, + (GLint x, GLint y, GLint z, GLint width, GLint height), + (x, y, z, width, height)) + +API_ENTRY(glDrawTexfOES, + (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height), + (x, y, z, width, height)) + +API_ENTRY(glDrawTexxOES, + (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height), + (x, y, z, width, height)) + +API_ENTRY(glDrawTexsvOES, + (const GLshort *coords), + (coords)) + +API_ENTRY(glDrawTexivOES, + (const GLint *coords), + (coords)) + +API_ENTRY(glDrawTexfvOES, + (const GLfloat *coords), + (coords)) + +API_ENTRY(glDrawTexxvOES, + (const GLfixed *coords), + (coords)) diff --git a/emulator/opengl/system/egl/egl.cfg b/emulator/opengl/system/egl/egl.cfg new file mode 100644 index 0000000..9d3f2dc --- /dev/null +++ b/emulator/opengl/system/egl/egl.cfg @@ -0,0 +1 @@ +0 0 emulation diff --git a/emulator/opengl/system/egl/egl.cpp b/emulator/opengl/system/egl/egl.cpp new file mode 100644 index 0000000..5aa5bda --- /dev/null +++ b/emulator/opengl/system/egl/egl.cpp @@ -0,0 +1,1211 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "HostConnection.h" +#include "ThreadInfo.h" +#include "eglDisplay.h" +#include "egl_ftable.h" +#include <cutils/log.h> +#include "gralloc_cb.h" +#include "GLClientState.h" +#include "GLSharedGroup.h" +#include "eglContext.h" +#include "ClientAPIExts.h" + +#include "GLEncoder.h" +#ifdef WITH_GLES2 +#include "GL2Encoder.h" +#endif + +#include <system/window.h> + +template<typename T> +static T setErrorFunc(GLint error, T returnValue) { + getEGLThreadInfo()->eglError = error; + return returnValue; +} + +const char * eglStrError(EGLint err) +{ + switch (err){ + case EGL_SUCCESS: return "EGL_SUCCESS"; + case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; + case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; + case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; + case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; + case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; + case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; + case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; + case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; + case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; + case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; + case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; + case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; + case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; + case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; + default: return "UNKNOWN"; + } +} + +#define LOG_EGL_ERRORS 1 + +#ifdef LOG_EGL_ERRORS + +#define setErrorReturn(error, retVal) \ + { \ + ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error)); \ + return setErrorFunc(error, retVal); \ + } + +#define RETURN_ERROR(ret,err) \ + ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err)); \ + getEGLThreadInfo()->eglError = err; \ + return ret; + +#else //!LOG_EGL_ERRORS + +#define setErrorReturn(error, retVal) return setErrorFunc(error, retVal); + +#define RETURN_ERROR(ret,err) \ + getEGLThreadInfo()->eglError = err; \ + return ret; + +#endif //LOG_EGL_ERRORS + +#define VALIDATE_CONFIG(cfg,ret) \ + if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \ + RETURN_ERROR(ret,EGL_BAD_CONFIG); \ + } + +#define VALIDATE_DISPLAY(dpy,ret) \ + if ((dpy) != (EGLDisplay)&s_display) { \ + RETURN_ERROR(ret, EGL_BAD_DISPLAY); \ + } + +#define VALIDATE_DISPLAY_INIT(dpy,ret) \ + VALIDATE_DISPLAY(dpy, ret) \ + if (!s_display.initialized()) { \ + RETURN_ERROR(ret, EGL_NOT_INITIALIZED); \ + } + +#define DEFINE_HOST_CONNECTION \ + HostConnection *hostCon = HostConnection::get(); \ + renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL) + +#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ + HostConnection *hostCon = HostConnection::get(); \ + if (!hostCon) { \ + ALOGE("egl: Failed to get host connection\n"); \ + return ret; \ + } \ + renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ + if (!rcEnc) { \ + ALOGE("egl: Failed to get renderControl encoder context\n"); \ + return ret; \ + } + +#define VALIDATE_CONTEXT_RETURN(context,ret) \ + if (!context) { \ + RETURN_ERROR(ret,EGL_BAD_CONTEXT); \ + } + +#define VALIDATE_SURFACE_RETURN(surface, ret) \ + if (surface != EGL_NO_SURFACE) { \ + egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \ + if (s->dpy != (EGLDisplay)&s_display) \ + setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \ + } + + +EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx) : + dpy(dpy), + config(config), + read(EGL_NO_SURFACE), + draw(EGL_NO_SURFACE), + shareCtx(shareCtx), + rcContext(0), + versionString(NULL), + vendorString(NULL), + rendererString(NULL), + extensionString(NULL) +{ + flags = 0; + version = 1; + clientState = new GLClientState(); + if (shareCtx) + sharedGroup = shareCtx->getSharedGroup(); + else + sharedGroup = GLSharedGroupPtr(new GLSharedGroup()); +}; + +EGLContext_t::~EGLContext_t() +{ + delete clientState; + delete [] versionString; + delete [] vendorString; + delete [] rendererString; + delete [] extensionString; +} + +// ---------------------------------------------------------------------------- +//egl_surface_t + +//we don't need to handle depth since it's handled when window created on the host + +struct egl_surface_t { + + EGLDisplay dpy; + EGLConfig config; + + + egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType); + virtual ~egl_surface_t(); + + virtual void setSwapInterval(int interval) = 0; + virtual EGLBoolean swapBuffers() = 0; + + EGLint getSwapBehavior() const; + uint32_t getRcSurface() { return rcSurface; } + EGLint getSurfaceType() { return surfaceType; } + + EGLint getWidth(){ return width; } + EGLint getHeight(){ return height; } + void setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; } + EGLint getTextureFormat() { return texFormat; } + void setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; } + EGLint getTextureTarget() { return texTarget; } + +private: + // + //Surface attributes + // + EGLint width; + EGLint height; + EGLint texFormat; + EGLint texTarget; + +protected: + void setWidth(EGLint w) { width = w; } + void setHeight(EGLint h) { height = h; } + + EGLint surfaceType; + uint32_t rcSurface; //handle to surface created via remote control +}; + +egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType) + : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0) +{ + width = 0; + height = 0; + texFormat = EGL_NO_TEXTURE; + texTarget = EGL_NO_TEXTURE; +} + +EGLint egl_surface_t::getSwapBehavior() const { + return EGL_BUFFER_PRESERVED; +} + +egl_surface_t::~egl_surface_t() +{ +} + +// ---------------------------------------------------------------------------- +// egl_window_surface_t + +struct egl_window_surface_t : public egl_surface_t { + static egl_window_surface_t* create( + EGLDisplay dpy, EGLConfig config, EGLint surfType, + ANativeWindow* window); + + virtual ~egl_window_surface_t(); + + virtual void setSwapInterval(int interval); + virtual EGLBoolean swapBuffers(); + +private: + egl_window_surface_t( + EGLDisplay dpy, EGLConfig config, EGLint surfType, + ANativeWindow* window); + EGLBoolean init(); + + ANativeWindow* nativeWindow; + android_native_buffer_t* buffer; +}; + +egl_window_surface_t::egl_window_surface_t ( + EGLDisplay dpy, EGLConfig config, EGLint surfType, + ANativeWindow* window) +: egl_surface_t(dpy, config, surfType), + nativeWindow(window), + buffer(NULL) +{ + // keep a reference on the window + nativeWindow->common.incRef(&nativeWindow->common); + EGLint w,h; + nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &w); + setWidth(w); + nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &h); + setHeight(h); +} + +EGLBoolean egl_window_surface_t::init() +{ + if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { + setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); + } + nativeWindow->lockBuffer(nativeWindow, buffer); + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, + getWidth(), getHeight()); + if (!rcSurface) { + ALOGE("rcCreateWindowSurface returned 0"); + return EGL_FALSE; + } + rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, + ((cb_handle_t*)(buffer->handle))->hostHandle); + + return EGL_TRUE; +} + +egl_window_surface_t* egl_window_surface_t::create( + EGLDisplay dpy, EGLConfig config, EGLint surfType, + ANativeWindow* window) +{ + egl_window_surface_t* wnd = new egl_window_surface_t( + dpy, config, surfType, window); + if (wnd && !wnd->init()) { + delete wnd; + wnd = NULL; + } + return wnd; +} + +egl_window_surface_t::~egl_window_surface_t() { + DEFINE_HOST_CONNECTION; + if (rcSurface && rcEnc) { + rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface); + } + if (buffer) { + nativeWindow->cancelBuffer(nativeWindow, buffer); + } + nativeWindow->common.decRef(&nativeWindow->common); +} + +void egl_window_surface_t::setSwapInterval(int interval) +{ + nativeWindow->setSwapInterval(nativeWindow, interval); +} + +EGLBoolean egl_window_surface_t::swapBuffers() +{ + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + + rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface); + + nativeWindow->queueBuffer(nativeWindow, buffer); + if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) { + buffer = NULL; + setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); + } + nativeWindow->lockBuffer(nativeWindow, buffer); + + rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, + ((cb_handle_t *)(buffer->handle))->hostHandle); + + return EGL_TRUE; +} + +// ---------------------------------------------------------------------------- +//egl_pbuffer_surface_t + +struct egl_pbuffer_surface_t : public egl_surface_t { + static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config, + EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat); + + virtual ~egl_pbuffer_surface_t(); + + virtual void setSwapInterval(int interval) {} + virtual EGLBoolean swapBuffers() { return EGL_TRUE; } + + uint32_t getRcColorBuffer() { return rcColorBuffer; } + +private: + egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType, + int32_t w, int32_t h); + EGLBoolean init(GLenum format); + + uint32_t rcColorBuffer; +}; + +egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, + EGLint surfType, int32_t w, int32_t h) +: egl_surface_t(dpy, config, surfType), + rcColorBuffer(0) +{ + setWidth(w); + setHeight(h); +} + +egl_pbuffer_surface_t::~egl_pbuffer_surface_t() +{ + DEFINE_HOST_CONNECTION; + if (rcEnc) { + if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer); + if (rcSurface) rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface); + } +} + +EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat) +{ + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + + rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, + getWidth(), getHeight()); + if (!rcSurface) { + ALOGE("rcCreateWindowSurface returned 0"); + return EGL_FALSE; + } + + rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), + pixelFormat); + if (!rcColorBuffer) { + ALOGE("rcCreateColorBuffer returned 0"); + return EGL_FALSE; + } + + rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer); + + return EGL_TRUE; +} + +egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy, + EGLConfig config, EGLint surfType, int32_t w, int32_t h, + GLenum pixelFormat) +{ + egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType, + w, h); + if (pb && !pb->init(pixelFormat)) { + delete pb; + pb = NULL; + } + return pb; +} + +static const char *getGLString(int glEnum) +{ + EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (!tInfo || !tInfo->currentContext) { + return NULL; + } + + const char** strPtr = NULL; + +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + + switch(glEnum) { + case GL_VERSION: + strPtr = &tInfo->currentContext->versionString; + break; + case GL_VENDOR: + strPtr = &tInfo->currentContext->vendorString; + break; + case GL_RENDERER: + strPtr = &tInfo->currentContext->rendererString; + break; + case GL_EXTENSIONS: + strPtr = &tInfo->currentContext->extensionString; + break; + } + + if (!strPtr) { + return NULL; + } + + if (*strPtr != NULL) { + // + // string is already cached + // + return *strPtr; + } + + // + // first query of that string - need to query host + // + DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL); + char *hostStr = NULL; + int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0); + if (n < 0) { + hostStr = new char[-n+1]; + n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n); + if (n <= 0) { + delete [] hostStr; + hostStr = NULL; + } + } + + // + // keep the string in the context and return its value + // + *strPtr = hostStr; + return hostStr; +} + +// ---------------------------------------------------------------------------- + +// The one and only supported display object. +static eglDisplay s_display; + +static EGLClient_eglInterface s_eglIface = { + getThreadInfo: getEGLThreadInfo, + getGLString: getGLString +}; + +#define DBG_FUNC DBG("%s\n", __FUNCTION__) +EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) +{ + // + // we support only EGL_DEFAULT_DISPLAY. + // + if (display_id != EGL_DEFAULT_DISPLAY) { + return EGL_NO_DISPLAY; + } + + return (EGLDisplay)&s_display; +} + +EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + VALIDATE_DISPLAY(dpy,EGL_FALSE); + + if (!s_display.initialize(&s_eglIface)) { + return EGL_FALSE; + } + if (major!=NULL) + *major = s_display.getVersionMajor(); + if (minor!=NULL) + *minor = s_display.getVersionMinor(); + return EGL_TRUE; +} + +EGLBoolean eglTerminate(EGLDisplay dpy) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + + s_display.terminate(); + return EGL_TRUE; +} + +EGLint eglGetError() +{ + EGLint error = getEGLThreadInfo()->eglError; + getEGLThreadInfo()->eglError = EGL_SUCCESS; + return error; +} + +__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) +{ + // search in EGL function table + for (int i=0; i<egl_num_funcs; i++) { + if (!strcmp(egl_funcs_by_name[i].name, procname)) { + return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc; + } + } + + // + // Make sure display is initialized before searching in client APIs + // + if (!s_display.initialized()) { + if (!s_display.initialize(&s_eglIface)) { + return NULL; + } + } + + // look in gles client api's extensions table + return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname); + + // Fail - function not found. + return NULL; +} + +const char* eglQueryString(EGLDisplay dpy, EGLint name) +{ + VALIDATE_DISPLAY_INIT(dpy, NULL); + + return s_display.queryString(name); +} + +EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) +{ + VALIDATE_DISPLAY_INIT(dpy, NULL); + + if(!num_config) { + RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER); + } + + GLint numConfigs = s_display.getNumConfigs(); + if (!configs) { + *num_config = numConfigs; + return EGL_TRUE; + } + + int i=0; + for (i=0 ; i<numConfigs && i<config_size ; i++) { + *configs++ = (EGLConfig)i; + } + *num_config = i; + return EGL_TRUE; +} + +EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + + int attribs_size = 0; + if (attrib_list) { + const EGLint * attrib_p = attrib_list; + while (attrib_p[0] != EGL_NONE) { + attribs_size += 2; + attrib_p += 2; + } + attribs_size++; //for the terminating EGL_NONE + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size); + + return EGL_TRUE; +} + +EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) +{ + VALIDATE_DISPLAY_INIT(dpy, NULL); + VALIDATE_CONFIG(config, EGL_FALSE); + + if (s_display.getConfigAttrib(config, attribute, value)) + { + return EGL_TRUE; + } + else + { + RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE); + } +} + +EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) +{ + VALIDATE_DISPLAY_INIT(dpy, NULL); + VALIDATE_CONFIG(config, EGL_FALSE); + if (win == 0) { + setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + EGLint surfaceType; + if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; + + if (!(surfaceType & EGL_WINDOW_BIT)) { + setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { + setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); + } + + egl_surface_t* surface = egl_window_surface_t::create( + &s_display, config, surfaceType, static_cast<ANativeWindow*>(win)); + if (!surface) { + setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); + } + + return surface; +} + +EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +{ + VALIDATE_DISPLAY_INIT(dpy, NULL); + VALIDATE_CONFIG(config, EGL_FALSE); + + EGLint surfaceType; + if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; + + if (!(surfaceType & EGL_PBUFFER_BIT)) { + setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + + int32_t w = 0; + int32_t h = 0; + EGLint texFormat = EGL_NO_TEXTURE; + EGLint texTarget = EGL_NO_TEXTURE; + while (attrib_list[0]) { + switch (attrib_list[0]) { + case EGL_WIDTH: + w = attrib_list[1]; + break; + case EGL_HEIGHT: + h = attrib_list[1]; + break; + case EGL_TEXTURE_FORMAT: + texFormat = attrib_list[1]; + break; + case EGL_TEXTURE_TARGET: + texTarget = attrib_list[1]; + break; + default: + break; + }; + attrib_list+=2; + } + if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) || + ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) { + setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); + } + // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage + + GLenum pixelFormat; + if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE) + setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); + + egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config, + surfaceType, w, h, pixelFormat); + if (!surface) { + setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); + } + + //setup attributes + surface->setTextureFormat(texFormat); + surface->setTextureTarget(texTarget); + + return surface; +} + +EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) +{ + //XXX: Pixmap not supported. The host cannot render to a pixmap resource + // located on host. In order to support Pixmaps we should either punt + // to s/w rendering -or- let the host render to a buffer that will be + // copied back to guest at some sync point. None of those methods not + // implemented and pixmaps are not used with OpenGL anyway ... + return EGL_NO_SURFACE; +} + +EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); + + egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface)); + delete surface; + + return EGL_TRUE; +} + +EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); + + egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); + EGLBoolean ret = EGL_TRUE; + switch (attribute) { + case EGL_CONFIG_ID: + ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value); + break; + case EGL_WIDTH: + *value = surface->getWidth(); + break; + case EGL_HEIGHT: + *value = surface->getHeight(); + break; + case EGL_TEXTURE_FORMAT: + *value = surface->getTextureFormat(); + break; + case EGL_TEXTURE_TARGET: + *value = surface->getTextureTarget(); + break; + case EGL_SWAP_BEHAVIOR: + *value = surface->getSwapBehavior(); + break; + case EGL_LARGEST_PBUFFER: + // not modified for a window or pixmap surface + // and we ignore it when creating a PBuffer surface (default is EGL_FALSE) + if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE; + break; + //TODO: complete other attributes + default: + ALOGE("eglQuerySurface %x EGL_BAD_ATTRIBUTE", attribute); + ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE); + break; + } + + return ret; +} + +EGLBoolean eglBindAPI(EGLenum api) +{ + if (api != EGL_OPENGL_ES_API) + setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); + return EGL_TRUE; +} + +EGLenum eglQueryAPI() +{ + return EGL_OPENGL_ES_API; +} + +EGLBoolean eglWaitClient() +{ + return eglWaitGL(); +} + +EGLBoolean eglReleaseThread() +{ + EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (tInfo && tInfo->currentContext) { + return eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); + } + return EGL_TRUE; +} + +EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) +{ + //TODO + ALOGW("%s not implemented", __FUNCTION__); + return 0; +} + +EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) +{ + //TODO + ALOGW("%s not implemented", __FUNCTION__); + return 0; +} + +EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); + if (eglSurface == EGL_NO_SURFACE) { + setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (buffer != EGL_BACK_BUFFER) { + setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); + } + + egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); + + if (surface->getTextureFormat() == EGL_NO_TEXTURE) { + setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); + } + + if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) { + setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); + } + + //It's now safe to cast to pbuffer surface + egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface; + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer()); + + return GL_TRUE; +} + +EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) +{ + //TODO + ALOGW("%s not implemented", __FUNCTION__); + return 0; +} + +EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + + EGLContext_t* ctx = getEGLThreadInfo()->currentContext; + if (!ctx) { + setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); + } + if (!ctx->draw) { + setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); + } + egl_surface_t* draw(static_cast<egl_surface_t*>(ctx->draw)); + draw->setSwapInterval(interval); + + rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host + + return EGL_TRUE; +} + +EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT); + VALIDATE_CONFIG(config, EGL_NO_CONTEXT); + + EGLint version = 1; //default + while (attrib_list && attrib_list[0]) { + if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1]; + attrib_list+=2; + } + + uint32_t rcShareCtx = 0; + EGLContext_t * shareCtx = NULL; + if (share_context) { + shareCtx = static_cast<EGLContext_t*>(share_context); + rcShareCtx = shareCtx->rcContext; + if (shareCtx->dpy != dpy) + setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT); + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT); + uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version); + if (!rcContext) { + ALOGE("rcCreateContext returned 0"); + setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); + } + + EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx); + if (!context) + setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); + + context->version = version; + context->rcContext = rcContext; + + + return context; +} + +EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); + + EGLContext_t * context = static_cast<EGLContext_t*>(ctx); + + if (getEGLThreadInfo()->currentContext == context) + { + eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); + } + + if (context->rcContext) { + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + rcEnc->rcDestroyContext(rcEnc, context->rcContext); + context->rcContext = 0; + } + + delete context; + return EGL_TRUE; +} + +EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_SURFACE_RETURN(draw, EGL_FALSE); + VALIDATE_SURFACE_RETURN(read, EGL_FALSE); + + if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) + setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); + if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT)) + setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); + + EGLContext_t * context = static_cast<EGLContext_t*>(ctx); + uint32_t ctxHandle = (context) ? context->rcContext : 0; + egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw); + uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0; + egl_surface_t * readSurf = static_cast<egl_surface_t *>(read); + uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0; + + // + // Nothing to do if no binding change has made + // + EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (tInfo->currentContext == context && + (context == NULL || + (context && context->draw == draw && context->read == read))) { + return EGL_TRUE; + } + + if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { + //context is current to another thread + setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) { + ALOGE("rcMakeCurrent returned EGL_FALSE"); + setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); + } + + //Now make the local bind + if (context) { + context->draw = draw; + context->read = read; + context->flags |= EGLContext_t::IS_CURRENT; + //set the client state + if (context->version == 2) { + hostCon->gl2Encoder()->setClientState(context->getClientState()); + hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup()); + } + else { + hostCon->glEncoder()->setClientState(context->getClientState()); + hostCon->glEncoder()->setSharedGroup(context->getSharedGroup()); + } + } + else { + //release ClientState & SharedGroup + if (tInfo->currentContext->version == 2) { + hostCon->gl2Encoder()->setClientState(NULL); + hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL)); + } + else { + hostCon->glEncoder()->setClientState(NULL); + hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL)); + } + + } + + if (tInfo->currentContext) + tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT; + + //Now make current + tInfo->currentContext = context; + + //Check maybe we need to init the encoder, if it's first eglMakeCurrent + if (tInfo->currentContext) { + if (tInfo->currentContext->version == 2) { + if (!hostCon->gl2Encoder()->isInitialized()) { + s_display.gles2_iface()->init(); + hostCon->gl2Encoder()->setInitialized(); + ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1); + } + } + else { + if (!hostCon->glEncoder()->isInitialized()) { + s_display.gles_iface()->init(); + hostCon->glEncoder()->setInitialized(); + ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0); + } + } + } + + return EGL_TRUE; +} + +EGLContext eglGetCurrentContext() +{ + return getEGLThreadInfo()->currentContext; +} + +EGLSurface eglGetCurrentSurface(EGLint readdraw) +{ + EGLContext_t * context = getEGLThreadInfo()->currentContext; + if (!context) + return EGL_NO_SURFACE; //not an error + + switch (readdraw) { + case EGL_READ: + return context->read; + case EGL_DRAW: + return context->draw; + default: + setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + } +} + +EGLDisplay eglGetCurrentDisplay() +{ + EGLContext_t * context = getEGLThreadInfo()->currentContext; + if (!context) + return EGL_NO_DISPLAY; //not an error + + return context->dpy; +} + +EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); + + EGLContext_t * context = static_cast<EGLContext_t*>(ctx); + + EGLBoolean ret = EGL_TRUE; + switch (attribute) { + case EGL_CONFIG_ID: + ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value); + break; + case EGL_CONTEXT_CLIENT_TYPE: + *value = EGL_OPENGL_ES_API; + break; + case EGL_CONTEXT_CLIENT_VERSION: + *value = context->version; + break; + case EGL_RENDER_BUFFER: + if (!context->draw) + *value = EGL_NONE; + else + *value = EGL_BACK_BUFFER; //single buffer not supported + break; + default: + ALOGE("eglQueryContext %x EGL_BAD_ATTRIBUTE", attribute); + setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); + break; + } + + return ret; +} + +EGLBoolean eglWaitGL() +{ + EGLThreadInfo *tInfo = getEGLThreadInfo(); + if (!tInfo || !tInfo->currentContext) { + return EGL_FALSE; + } + + if (tInfo->currentContext->version == 2) { + s_display.gles2_iface()->finish(); + } + else { + s_display.gles_iface()->finish(); + } + + return EGL_TRUE; +} + +EGLBoolean eglWaitNative(EGLint engine) +{ + return EGL_TRUE; +} + +EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + if (eglSurface == EGL_NO_SURFACE) + setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + + egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface); + if (d->dpy != dpy) + setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); + + // post the surface + d->swapBuffers(); + + hostCon->flush(); + return EGL_TRUE; +} + +EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) +{ + //TODO :later + return 0; +} + +EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) +{ + //TODO later + return 0; +} + +EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) +{ + //TODO later + return 0; +} + +EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR); + if (ctx != EGL_NO_CONTEXT) { + setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); + } + if (target != EGL_NATIVE_BUFFER_ANDROID) { + setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + } + + android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) + setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) + setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + + switch (native_buffer->format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_RGB_888: + case HAL_PIXEL_FORMAT_RGB_565: + case HAL_PIXEL_FORMAT_BGRA_8888: + case HAL_PIXEL_FORMAT_RGBA_5551: + case HAL_PIXEL_FORMAT_RGBA_4444: + break; + default: + setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); + } + + native_buffer->common.incRef(&native_buffer->common); + return (EGLImageKHR)native_buffer; +} + +EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) +{ + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + android_native_buffer_t* native_buffer = (android_native_buffer_t*)img; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) + setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) + setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); + + native_buffer->common.decRef(&native_buffer->common); + + return EGL_TRUE; +} + +EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + //TODO later + return 0; +} + +EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + //TODO later + return 0; +} + +EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + //TODO + return 0; +} + +EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) +{ + //TODO later + return 0; +} + +EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + //TODO later + return 0; +} diff --git a/emulator/opengl/system/egl/eglContext.h b/emulator/opengl/system/egl/eglContext.h new file mode 100644 index 0000000..2ca6d0c --- /dev/null +++ b/emulator/opengl/system/egl/eglContext.h @@ -0,0 +1,51 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _EGL_CONTEXT_H +#define _EGL_CONTEXT_H + +#include "GLClientState.h" +#include "GLSharedGroup.h" + +struct EGLContext_t { + + enum { + IS_CURRENT = 0x00010000, + NEVER_CURRENT = 0x00020000 + }; + + EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx); + ~EGLContext_t(); + uint32_t flags; + EGLDisplay dpy; + EGLConfig config; + EGLSurface read; + EGLSurface draw; + EGLContext_t * shareCtx; + EGLint version; + uint32_t rcContext; + const char* versionString; + const char* vendorString; + const char* rendererString; + const char* extensionString; + + GLClientState * getClientState(){ return clientState; } + GLSharedGroupPtr getSharedGroup(){ return sharedGroup; } +private: + GLClientState * clientState; + GLSharedGroupPtr sharedGroup; +}; + +#endif diff --git a/emulator/opengl/system/egl/eglDisplay.cpp b/emulator/opengl/system/egl/eglDisplay.cpp new file mode 100644 index 0000000..2497548 --- /dev/null +++ b/emulator/opengl/system/egl/eglDisplay.cpp @@ -0,0 +1,496 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include "eglDisplay.h" +#include "HostConnection.h" +#include <dlfcn.h> + +static const int systemEGLVersionMajor = 1; +static const int systemEGLVersionMinor = 4; +static const char systemEGLVendor[] = "Google Android emulator"; + +// list of extensions supported by this EGL implementation +// NOTE that each extension name should be suffixed with space +static const char systemStaticEGLExtensions[] = + "EGL_ANDROID_image_native_buffer "; + +// list of extensions supported by this EGL implementation only if supported +// on the host implementation. +// NOTE that each extension name should be suffixed with space +static const char systemDynamicEGLExtensions[] = + "EGL_KHR_image_base " + "EGL_KHR_gl_texture_2d_image "; + + +static void *s_gles_lib = NULL; +static void *s_gles2_lib = NULL; + +// The following function will be called when we (libEGL) +// gets unloaded +// At this point we want to unload the gles libraries we +// might have loaded during initialization +static void __attribute__ ((destructor)) do_on_unload(void) +{ + if (s_gles_lib) { + dlclose(s_gles_lib); + } + + if (s_gles2_lib) { + dlclose(s_gles2_lib); + } +} + +eglDisplay::eglDisplay() : + m_initialized(false), + m_major(0), + m_minor(0), + m_hostRendererVersion(0), + m_numConfigs(0), + m_numConfigAttribs(0), + m_attribs(DefaultKeyedVector<EGLint, EGLint>(ATTRIBUTE_NONE)), + m_configs(NULL), + m_gles_iface(NULL), + m_gles2_iface(NULL), + m_versionString(NULL), + m_vendorString(NULL), + m_extensionString(NULL) +{ + pthread_mutex_init(&m_lock, NULL); +} + +eglDisplay::~eglDisplay() +{ + pthread_mutex_destroy(&m_lock); +} + +bool eglDisplay::initialize(EGLClient_eglInterface *eglIface) +{ + pthread_mutex_lock(&m_lock); + if (!m_initialized) { + + // + // load GLES client API + // + m_gles_iface = loadGLESClientAPI("/system/lib/egl/libGLESv1_CM_emulation.so", + eglIface, + &s_gles_lib); + if (!m_gles_iface) { + pthread_mutex_unlock(&m_lock); + ALOGE("Failed to load gles1 iface"); + return false; + } + +#ifdef WITH_GLES2 + m_gles2_iface = loadGLESClientAPI("/system/lib/egl/libGLESv2_emulation.so", + eglIface, + &s_gles2_lib); + // Note that if loading gles2 failed, we can still run with no + // GLES2 support, having GLES2 is not mandatory. +#endif + + // + // establish connection with the host + // + HostConnection *hcon = HostConnection::get(); + if (!hcon) { + pthread_mutex_unlock(&m_lock); + ALOGE("Failed to establish connection with the host\n"); + return false; + } + + // + // get renderControl encoder instance + // + renderControl_encoder_context_t *rcEnc = hcon->rcEncoder(); + if (!rcEnc) { + pthread_mutex_unlock(&m_lock); + ALOGE("Failed to get renderControl encoder instance"); + return false; + } + + // + // Query host reneder and EGL version + // + m_hostRendererVersion = rcEnc->rcGetRendererVersion(rcEnc); + EGLint status = rcEnc->rcGetEGLVersion(rcEnc, &m_major, &m_minor); + if (status != EGL_TRUE) { + // host EGL initialization failed !! + pthread_mutex_unlock(&m_lock); + return false; + } + + // + // Take minimum version beween what we support and what the host support + // + if (m_major > systemEGLVersionMajor) { + m_major = systemEGLVersionMajor; + m_minor = systemEGLVersionMinor; + } + else if (m_major == systemEGLVersionMajor && + m_minor > systemEGLVersionMinor) { + m_minor = systemEGLVersionMinor; + } + + // + // Query the host for the set of configs + // + m_numConfigs = rcEnc->rcGetNumConfigs(rcEnc, (uint32_t*)&m_numConfigAttribs); + if (m_numConfigs <= 0 || m_numConfigAttribs <= 0) { + // just sanity check - should never happen + pthread_mutex_unlock(&m_lock); + return false; + } + + uint32_t nInts = m_numConfigAttribs * (m_numConfigs + 1); + EGLint tmp_buf[nInts]; + m_configs = new EGLint[nInts-m_numConfigAttribs]; + if (!m_configs) { + pthread_mutex_unlock(&m_lock); + return false; + } + + //EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), m_configs); + EGLint n = rcEnc->rcGetConfigs(rcEnc, nInts*sizeof(EGLint), (GLuint*)tmp_buf); + if (n != m_numConfigs) { + pthread_mutex_unlock(&m_lock); + return false; + } + + //Fill the attributes vector. + //The first m_numConfigAttribs values of tmp_buf are the actual attributes enums. + for (int i=0; i<m_numConfigAttribs; i++) { + m_attribs.add(tmp_buf[i], i); + } + + //Copy the actual configs data to m_configs + memcpy(m_configs, tmp_buf + m_numConfigAttribs, m_numConfigs*m_numConfigAttribs*sizeof(EGLint)); + + m_initialized = true; + } + pthread_mutex_unlock(&m_lock); + + processConfigs(); + + return true; +} + +void eglDisplay::processConfigs() +{ + for (int i=0; i<m_numConfigs; i++) { + EGLConfig config = (EGLConfig)i; + //Setup the EGL_NATIVE_VISUAL_ID attribute + PixelFormat format; + if (getConfigNativePixelFormat(config, &format)) { + setConfigAttrib(config, EGL_NATIVE_VISUAL_ID, format); + } + } +} + +void eglDisplay::terminate() +{ + pthread_mutex_lock(&m_lock); + if (m_initialized) { + m_initialized = false; + delete [] m_configs; + m_configs = NULL; + + if (m_versionString) { + free(m_versionString); + m_versionString = NULL; + } + if (m_vendorString) { + free(m_vendorString); + m_vendorString = NULL; + } + if (m_extensionString) { + free(m_extensionString); + m_extensionString = NULL; + } + } + pthread_mutex_unlock(&m_lock); +} + +EGLClient_glesInterface *eglDisplay::loadGLESClientAPI(const char *libName, + EGLClient_eglInterface *eglIface, + void **libHandle) +{ + void *lib = dlopen(libName, RTLD_NOW); + if (!lib) { + ALOGE("Failed to dlopen %s", libName); + return NULL; + } + + init_emul_gles_t init_gles_func = (init_emul_gles_t)dlsym(lib,"init_emul_gles"); + if (!init_gles_func) { + ALOGE("Failed to find init_emul_gles"); + dlclose((void*)lib); + return NULL; + } + + *libHandle = lib; + return (*init_gles_func)(eglIface); +} + +static char *queryHostEGLString(EGLint name) +{ + HostConnection *hcon = HostConnection::get(); + if (hcon) { + renderControl_encoder_context_t *rcEnc = hcon->rcEncoder(); + if (rcEnc) { + int n = rcEnc->rcQueryEGLString(rcEnc, name, NULL, 0); + if (n < 0) { + // allocate space for the string with additional + // space charachter to be suffixed at the end. + char *str = (char *)malloc(-n+2); + n = rcEnc->rcQueryEGLString(rcEnc, name, str, -n); + if (n > 0) { + // add extra space at end of string which will be + // needed later when filtering the extension list. + strcat(str, " "); + return str; + } + + free(str); + } + } + } + + return NULL; +} + +static bool findExtInList(const char* token, int tokenlen, const char* list) +{ + const char* p = list; + while (*p != '\0') { + const char* q = strchr(p, ' '); + if (q == NULL) { + /* should not happen, list must be space-terminated */ + break; + } + if (tokenlen == (q - p) && !memcmp(token, p, tokenlen)) { + return true; /* found it */ + } + p = q+1; + } + return false; /* not found */ +} + +static char *buildExtensionString() +{ + //Query host extension string + char *hostExt = queryHostEGLString(EGL_EXTENSIONS); + if (!hostExt || (hostExt[1] == '\0')) { + // no extensions on host - only static extension list supported + return strdup(systemStaticEGLExtensions); + } + + // + // Filter host extension list to include only extensions + // we can support (in the systemDynamicEGLExtensions list) + // + char *ext = (char *)hostExt; + char *c = ext; + char *insert = ext; + while(*c != '\0') { + if (*c == ' ') { + int len = c - ext; + if (findExtInList(ext, len, systemDynamicEGLExtensions)) { + if (ext != insert) { + memcpy(insert, ext, len+1); // including space + } + insert += (len + 1); + } + ext = c + 1; + } + c++; + } + *insert = '\0'; + + int n = strlen(hostExt); + if (n > 0) { + char *str; + asprintf(&str,"%s%s", systemStaticEGLExtensions, hostExt); + free((char*)hostExt); + return str; + } + else { + free((char*)hostExt); + return strdup(systemStaticEGLExtensions); + } +} + +const char *eglDisplay::queryString(EGLint name) +{ + if (name == EGL_CLIENT_APIS) { + return "OpenGL_ES"; + } + else if (name == EGL_VERSION) { + pthread_mutex_lock(&m_lock); + if (m_versionString) { + pthread_mutex_unlock(&m_lock); + return m_versionString; + } + + // build version string + asprintf(&m_versionString, "%d.%d", m_major, m_minor); + pthread_mutex_unlock(&m_lock); + + return m_versionString; + } + else if (name == EGL_VENDOR) { + pthread_mutex_lock(&m_lock); + if (m_vendorString) { + pthread_mutex_unlock(&m_lock); + return m_vendorString; + } + + // build vendor string + const char *hostVendor = queryHostEGLString(EGL_VENDOR); + + if (hostVendor) { + asprintf(&m_vendorString, "%s Host: %s", + systemEGLVendor, hostVendor); + free((char*)hostVendor); + } + else { + m_vendorString = (char *)systemEGLVendor; + } + pthread_mutex_unlock(&m_lock); + + return m_vendorString; + } + else if (name == EGL_EXTENSIONS) { + pthread_mutex_lock(&m_lock); + if (m_extensionString) { + pthread_mutex_unlock(&m_lock); + return m_extensionString; + } + + // build extension string + m_extensionString = buildExtensionString(); + pthread_mutex_unlock(&m_lock); + + return m_extensionString; + } + else { + ALOGE("[%s] Unknown name %d\n", __FUNCTION__, name); + return NULL; + } +} + +/* To get the value of attribute <a> of config <c> use the following formula: + * value = *(m_configs + (int)c*m_numConfigAttribs + a); + */ +EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint * value) +{ + if (attribIdx == ATTRIBUTE_NONE) + { + ALOGE("[%s] Bad attribute idx\n", __FUNCTION__); + return EGL_FALSE; + } + *value = *(m_configs + (int)config*m_numConfigAttribs + attribIdx); + return EGL_TRUE; +} + +EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value) +{ + //Though it seems that valueFor() is thread-safe, we don't take chanses + pthread_mutex_lock(&m_lock); + EGLBoolean ret = getAttribValue(config, m_attribs.valueFor(attrib), value); + pthread_mutex_unlock(&m_lock); + return ret; +} + +void eglDisplay::dumpConfig(EGLConfig config) +{ + EGLint value = 0; + DBG("^^^^^^^^^^ dumpConfig %d ^^^^^^^^^^^^^^^^^^", (int)config); + for (int i=0; i<m_numConfigAttribs; i++) { + getAttribValue(config, i, &value); + DBG("{%d}[%d] %d\n", (int)config, i, value); + } +} + +/* To set the value of attribute <a> of config <c> use the following formula: + * *(m_configs + (int)c*m_numConfigAttribs + a) = value; + */ +EGLBoolean eglDisplay::setAttribValue(EGLConfig config, EGLint attribIdx, EGLint value) +{ + if (attribIdx == ATTRIBUTE_NONE) + { + ALOGE("[%s] Bad attribute idx\n", __FUNCTION__); + return EGL_FALSE; + } + *(m_configs + (int)config*m_numConfigAttribs + attribIdx) = value; + return EGL_TRUE; +} + +EGLBoolean eglDisplay::setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value) +{ + //Though it seems that valueFor() is thread-safe, we don't take chanses + pthread_mutex_lock(&m_lock); + EGLBoolean ret = setAttribValue(config, m_attribs.valueFor(attrib), value); + pthread_mutex_unlock(&m_lock); + return ret; +} + + +EGLBoolean eglDisplay::getConfigNativePixelFormat(EGLConfig config, PixelFormat * format) +{ + EGLint redSize, blueSize, greenSize, alphaSize; + + if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) && + getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) && + getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) && + getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) ) + { + ALOGE("Couldn't find value for one of the pixel format attributes"); + return EGL_FALSE; + } + + //calculate the GL internal format + if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = PIXEL_FORMAT_RGBA_8888; //XXX: BGR? + else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGBX_8888; //XXX or PIXEL_FORMAT_RGB_888 + else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = PIXEL_FORMAT_RGB_565; + else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = PIXEL_FORMAT_RGBA_5551; + else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = PIXEL_FORMAT_RGBA_4444; + else { + return EGL_FALSE; + } + return EGL_TRUE; +} +EGLBoolean eglDisplay::getConfigGLPixelFormat(EGLConfig config, GLenum * format) +{ + EGLint redSize, blueSize, greenSize, alphaSize; + + if ( !(getAttribValue(config, m_attribs.valueFor(EGL_RED_SIZE), &redSize) && + getAttribValue(config, m_attribs.valueFor(EGL_BLUE_SIZE), &blueSize) && + getAttribValue(config, m_attribs.valueFor(EGL_GREEN_SIZE), &greenSize) && + getAttribValue(config, m_attribs.valueFor(EGL_ALPHA_SIZE), &alphaSize)) ) + { + ALOGE("Couldn't find value for one of the pixel format attributes"); + return EGL_FALSE; + } + + //calculate the GL internal format + if ((redSize==8)&&(blueSize==8)&&(blueSize==8)&&(alphaSize==8)) *format = GL_RGBA; + else if ((redSize==8)&&(greenSize==8)&&(blueSize==8)&&(alphaSize==0)) *format = GL_RGB; + else if ((redSize==5)&&(greenSize==6)&&(blueSize==5)&&(alphaSize==0)) *format = GL_RGB565_OES; + else if ((redSize==5)&&(greenSize==5)&&(blueSize==5)&&(alphaSize==1)) *format = GL_RGB5_A1_OES; + else if ((redSize==4)&&(greenSize==4)&&(blueSize==4)&&(alphaSize==4)) *format = GL_RGBA4_OES; + else return EGL_FALSE; + + return EGL_TRUE; +} diff --git a/emulator/opengl/system/egl/eglDisplay.h b/emulator/opengl/system/egl/eglDisplay.h new file mode 100644 index 0000000..9d979d9 --- /dev/null +++ b/emulator/opengl/system/egl/eglDisplay.h @@ -0,0 +1,89 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#ifndef _SYSTEM_EGL_DISPLAY_H +#define _SYSTEM_EGL_DISPLAY_H + +#include <pthread.h> +#include "glUtils.h" +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include "EGLClientIface.h" +#include <utils/KeyedVector.h> + +#include <ui/PixelFormat.h> + +#define ATTRIBUTE_NONE -1 +//FIXME: are we in this namespace? +using namespace android; + +class eglDisplay +{ +public: + eglDisplay(); + ~eglDisplay(); + + bool initialize(EGLClient_eglInterface *eglIface); + void terminate(); + + int getVersionMajor() const { return m_major; } + int getVersionMinor() const { return m_minor; } + bool initialized() const { return m_initialized; } + + const char *queryString(EGLint name); + + const EGLClient_glesInterface *gles_iface() const { return m_gles_iface; } + const EGLClient_glesInterface *gles2_iface() const { return m_gles2_iface; } + + int getNumConfigs(){ return m_numConfigs; } + EGLBoolean getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value); + EGLBoolean setConfigAttrib(EGLConfig config, EGLint attrib, EGLint value); + EGLBoolean getConfigGLPixelFormat(EGLConfig config, GLenum * format); + EGLBoolean getConfigNativePixelFormat(EGLConfig config, PixelFormat * format); + + void dumpConfig(EGLConfig config); +private: + EGLClient_glesInterface *loadGLESClientAPI(const char *libName, + EGLClient_eglInterface *eglIface, + void **libHandle); + EGLBoolean getAttribValue(EGLConfig config, EGLint attribIdxi, EGLint * value); + EGLBoolean setAttribValue(EGLConfig config, EGLint attribIdxi, EGLint value); + void processConfigs(); + +private: + pthread_mutex_t m_lock; + bool m_initialized; + int m_major; + int m_minor; + int m_hostRendererVersion; + int m_numConfigs; + int m_numConfigAttribs; + + /* This is the mapping between an attribute name to it's index in any given config */ + DefaultKeyedVector<EGLint, EGLint> m_attribs; + /* This is an array of all config's attributes values stored in the following sequencial fasion (read: v[c,a] = the value of attribute <a> of config <c>) + * v[0,0],..,v[0,m_numConfigAttribs-1], + *... + * v[m_numConfigs-1,0],..,v[m_numConfigs-1,m_numConfigAttribs-1] + */ + EGLint *m_configs; + EGLClient_glesInterface *m_gles_iface; + EGLClient_glesInterface *m_gles2_iface; + char *m_versionString; + char *m_vendorString; + char *m_extensionString; +}; + +#endif diff --git a/emulator/opengl/system/egl/egl_ftable.h b/emulator/opengl/system/egl/egl_ftable.h new file mode 100644 index 0000000..b21da72 --- /dev/null +++ b/emulator/opengl/system/egl/egl_ftable.h @@ -0,0 +1,65 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +static const struct _egl_funcs_by_name { + const char *name; + void *proc; +} egl_funcs_by_name[] = { + {"eglGetError", (void *)eglGetError}, + {"eglGetDisplay", (void *)eglGetDisplay}, + {"eglInitialize", (void *)eglInitialize}, + {"eglTerminate", (void *)eglTerminate}, + {"eglQueryString", (void *)eglQueryString}, + {"eglGetConfigs", (void *)eglGetConfigs}, + {"eglChooseConfig", (void *)eglChooseConfig}, + {"eglGetConfigAttrib", (void *)eglGetConfigAttrib}, + {"eglCreateWindowSurface", (void *)eglCreateWindowSurface}, + {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface}, + {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface}, + {"eglDestroySurface", (void *)eglDestroySurface}, + {"eglQuerySurface", (void *)eglQuerySurface}, + {"eglBindAPI", (void *)eglBindAPI}, + {"eglQueryAPI", (void *)eglQueryAPI}, + {"eglWaitClient", (void *)eglWaitClient}, + {"eglReleaseThread", (void *)eglReleaseThread}, + {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer}, + {"eglSurfaceAttrib", (void *)eglSurfaceAttrib}, + {"eglBindTexImage", (void *)eglBindTexImage}, + {"eglReleaseTexImage", (void *)eglReleaseTexImage}, + {"eglSwapInterval", (void *)eglSwapInterval}, + {"eglCreateContext", (void *)eglCreateContext}, + {"eglDestroyContext", (void *)eglDestroyContext}, + {"eglMakeCurrent", (void *)eglMakeCurrent}, + {"eglGetCurrentContext", (void *)eglGetCurrentContext}, + {"eglGetCurrentSurface", (void *)eglGetCurrentSurface}, + {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay}, + {"eglQueryContext", (void *)eglQueryContext}, + {"eglWaitGL", (void *)eglWaitGL}, + {"eglWaitNative", (void *)eglWaitNative}, + {"eglSwapBuffers", (void *)eglSwapBuffers}, + {"eglCopyBuffers", (void *)eglCopyBuffers}, + {"eglGetProcAddress", (void *)eglGetProcAddress}, + {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR}, + {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR}, + {"eglCreateImageKHR", (void *)eglCreateImageKHR}, + {"eglDestroyImageKHR", (void *)eglDestroyImageKHR}, + {"eglCreateSyncKHR", (void *)eglCreateSyncKHR}, + {"eglDestroySyncKHR", (void *)eglDestroySyncKHR}, + {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR}, + {"eglSignalSyncKHR", (void *)eglSignalSyncKHR}, + {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR} +}; + +static const int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name); diff --git a/emulator/opengl/system/gralloc/Android.mk b/emulator/opengl/system/gralloc/Android.mk new file mode 100644 index 0000000..8705602 --- /dev/null +++ b/emulator/opengl/system/gralloc/Android.mk @@ -0,0 +1,19 @@ +ifneq (false,$(BUILD_EMULATOR_OPENGL_DRIVER)) + +LOCAL_PATH := $(call my-dir) + +$(call emugl-begin-shared-library,gralloc.goldfish) +$(call emugl-import,libGLESv1_enc lib_renderControl_enc libOpenglSystemCommon) +$(call emugl-set-shared-library-subpath,hw) + +LOCAL_CFLAGS += -DLOG_TAG=\"gralloc_goldfish\" + +LOCAL_SRC_FILES := gralloc.cpp + +# Need to access the special OPENGL TLS Slot +LOCAL_C_INCLUDES += bionic/libc/private +LOCAL_SHARED_LIBRARIES += libdl + +$(call emugl-end-module) + +endif # BUILD_EMULATOR_OPENGL_DRIVER != false diff --git a/emulator/opengl/system/gralloc/gralloc.cpp b/emulator/opengl/system/gralloc/gralloc.cpp new file mode 100644 index 0000000..baad99b --- /dev/null +++ b/emulator/opengl/system/gralloc/gralloc.cpp @@ -0,0 +1,831 @@ +/* +* Copyright (C) 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +#include <string.h> +#include <pthread.h> +#ifdef HAVE_ANDROID_OS // just want PAGE_SIZE define +# include <asm/page.h> +#else +# include <sys/user.h> +#endif +#include <cutils/ashmem.h> +#include <unistd.h> +#include <errno.h> +#include <dlfcn.h> +#include <sys/mman.h> +#include "gralloc_cb.h" +#include "HostConnection.h" +#include "glUtils.h" +#include <cutils/log.h> +#include <cutils/properties.h> + +/* Set to 1 or 2 to enable debug traces */ +#define DEBUG 0 + +#if DEBUG >= 1 +# define D(...) ALOGD(__VA_ARGS__) +#else +# define D(...) ((void)0) +#endif + +#if DEBUG >= 2 +# define DD(...) ALOGD(__VA_ARGS__) +#else +# define DD(...) ((void)0) +#endif + +#define DBG_FUNC DBG("%s\n", __FUNCTION__) +// +// our private gralloc module structure +// +struct private_module_t { + gralloc_module_t base; +}; + +/* If not NULL, this is a pointer to the fallback module. + * This really is gralloc.default, which we'll use if we detect + * that the emulator we're running in does not support GPU emulation. + */ +static gralloc_module_t* sFallback; +static pthread_once_t sFallbackOnce = PTHREAD_ONCE_INIT; + +static void fallback_init(void); // forward + + +typedef struct _alloc_list_node { + buffer_handle_t handle; + _alloc_list_node *next; + _alloc_list_node *prev; +} AllocListNode; + +// +// Our gralloc device structure (alloc interface) +// +struct gralloc_device_t { + alloc_device_t device; + + AllocListNode *allocListHead; // double linked list of allocated buffers + pthread_mutex_t lock; +}; + +// +// Our framebuffer device structure +// +struct fb_device_t { + framebuffer_device_t device; +}; + +static int map_buffer(cb_handle_t *cb, void **vaddr) +{ + if (cb->fd < 0 || cb->ashmemSize <= 0) { + return -EINVAL; + } + + void *addr = mmap(0, cb->ashmemSize, PROT_READ | PROT_WRITE, + MAP_SHARED, cb->fd, 0); + if (addr == MAP_FAILED) { + return -errno; + } + + cb->ashmemBase = intptr_t(addr); + cb->ashmemBasePid = getpid(); + + *vaddr = addr; + return 0; +} + +#define DEFINE_HOST_CONNECTION \ + HostConnection *hostCon = HostConnection::get(); \ + renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL) + +#define DEFINE_AND_VALIDATE_HOST_CONNECTION \ + HostConnection *hostCon = HostConnection::get(); \ + if (!hostCon) { \ + ALOGE("gralloc: Failed to get host connection\n"); \ + return -EIO; \ + } \ + renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ + if (!rcEnc) { \ + ALOGE("gralloc: Failed to get renderControl encoder context\n"); \ + return -EIO; \ + } + + +// +// gralloc device functions (alloc interface) +// +static int gralloc_alloc(alloc_device_t* dev, + int w, int h, int format, int usage, + buffer_handle_t* pHandle, int* pStride) +{ + D("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage); + + gralloc_device_t *grdev = (gralloc_device_t *)dev; + if (!grdev || !pHandle || !pStride) + return -EINVAL; + + // + // Validate usage: buffer cannot be written both by s/w and h/w access. + // + bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK)); + bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER); + if (hw_write && sw_write) { + return -EINVAL; + } + + int ashmem_size = 0; + *pStride = 0; + GLenum glFormat = 0; + GLenum glType = 0; + + int bpp = 0; + switch (format) { + case HAL_PIXEL_FORMAT_RGBA_8888: + case HAL_PIXEL_FORMAT_RGBX_8888: + case HAL_PIXEL_FORMAT_BGRA_8888: + bpp = 4; + glFormat = GL_RGBA; + glType = GL_UNSIGNED_BYTE; + break; + case HAL_PIXEL_FORMAT_RGB_888: + bpp = 3; + glFormat = GL_RGB; + glType = GL_UNSIGNED_BYTE; + break; + case HAL_PIXEL_FORMAT_RGB_565: + bpp = 2; + glFormat = GL_RGB; + glType = GL_UNSIGNED_SHORT_5_6_5; + break; + case HAL_PIXEL_FORMAT_RGBA_5551: + bpp = 2; + glFormat = GL_RGB5_A1_OES; + glType = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case HAL_PIXEL_FORMAT_RGBA_4444: + bpp = 2; + glFormat = GL_RGBA4_OES; + glType = GL_UNSIGNED_SHORT_4_4_4_4; + break; + + default: + return -EINVAL; + } + + if (usage & GRALLOC_USAGE_HW_FB) { + // keep space for postCounter + ashmem_size += sizeof(uint32_t); + } + + if (usage & (GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK)) { + // keep space for image on guest memory if SW access is needed + int align = 1; + size_t bpr = (w*bpp + (align-1)) & ~(align-1); + ashmem_size += (bpr * h); + *pStride = bpr / bpp; + } + + D("gralloc_alloc ashmem_size=%d, tid %d\n", ashmem_size, gettid()); + + // + // Allocate space in ashmem if needed + // + int fd = -1; + if (ashmem_size > 0) { + // round to page size; + ashmem_size = (ashmem_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); + + fd = ashmem_create_region("gralloc-buffer", ashmem_size); + if (fd < 0) { + ALOGE("gralloc_alloc failed to create ashmem region: %s\n", strerror(errno)); + return -errno; + } + } + + cb_handle_t *cb = new cb_handle_t(fd, ashmem_size, usage, + w, h, glFormat, glType); + + if (ashmem_size > 0) { + // + // map ashmem region if exist + // + void *vaddr; + int err = map_buffer(cb, &vaddr); + if (err) { + close(fd); + delete cb; + return err; + } + + cb->setFd(fd); + } + + // + // Allocate ColorBuffer handle on the host (only if h/w access is allowed) + // + if (usage & GRALLOC_USAGE_HW_MASK) { + DEFINE_HOST_CONNECTION; + if (hostCon && rcEnc) { + cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat); + D("Created host ColorBuffer 0x%x\n", cb->hostHandle); + } + + if (!cb->hostHandle) { + // Could not create colorbuffer on host !!! + close(fd); + delete cb; + return -EIO; + } + } + + // + // alloc succeeded - insert the allocated handle to the allocated list + // + AllocListNode *node = new AllocListNode(); + pthread_mutex_lock(&grdev->lock); + node->handle = cb; + node->next = grdev->allocListHead; + node->prev = NULL; + if (grdev->allocListHead) { + grdev->allocListHead->prev = node; + } + grdev->allocListHead = node; + pthread_mutex_unlock(&grdev->lock); + + *pHandle = cb; + return 0; +} + +static int gralloc_free(alloc_device_t* dev, + buffer_handle_t handle) +{ + const cb_handle_t *cb = (const cb_handle_t *)handle; + if (!cb_handle_t::validate((cb_handle_t*)cb)) { + ERR("gralloc_free: invalid handle"); + return -EINVAL; + } + + if (cb->hostHandle != 0) { + DEFINE_AND_VALIDATE_HOST_CONNECTION; + D("Closing host ColorBuffer 0x%x\n", cb->hostHandle); + rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle); + } + + // + // detach and unmap ashmem area if present + // + if (cb->fd > 0) { + if (cb->ashmemSize > 0 && cb->ashmemBase) { + munmap((void *)cb->ashmemBase, cb->ashmemSize); + } + close(cb->fd); + } + + // remove it from the allocated list + gralloc_device_t *grdev = (gralloc_device_t *)dev; + pthread_mutex_lock(&grdev->lock); + AllocListNode *n = grdev->allocListHead; + while( n && n->handle != cb ) { + n = n->next; + } + if (n) { + // buffer found on list - remove it from list + if (n->next) { + n->next->prev = n->prev; + } + if (n->prev) { + n->prev->next = n->next; + } + else { + grdev->allocListHead = n->next; + } + + delete n; + } + pthread_mutex_unlock(&grdev->lock); + + delete cb; + + return 0; +} + +static int gralloc_device_close(struct hw_device_t *dev) +{ + gralloc_device_t* d = reinterpret_cast<gralloc_device_t*>(dev); + if (d) { + + // free still allocated buffers + while( d->allocListHead != NULL ) { + gralloc_free(&d->device, d->allocListHead->handle); + } + + // free device + free(d); + } + return 0; +} + +static int fb_compositionComplete(struct framebuffer_device_t* dev) +{ + return 0; +} + +// +// Framebuffer device functions +// +static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer) +{ + fb_device_t *fbdev = (fb_device_t *)dev; + cb_handle_t *cb = (cb_handle_t *)buffer; + + if (!fbdev || !cb_handle_t::validate(cb) || !cb->canBePosted()) { + return -EINVAL; + } + + // Make sure we have host connection + DEFINE_AND_VALIDATE_HOST_CONNECTION; + + // increment the post count of the buffer + uint32_t *postCountPtr = (uint32_t *)cb->ashmemBase; + if (!postCountPtr) { + // This should not happen + return -EINVAL; + } + (*postCountPtr)++; + + // send post request to host + rcEnc->rcFBPost(rcEnc, cb->hostHandle); + hostCon->flush(); + + return 0; +} + +static int fb_setUpdateRect(struct framebuffer_device_t* dev, + int l, int t, int w, int h) +{ + fb_device_t *fbdev = (fb_device_t *)dev; + + if (!fbdev) { + return -EINVAL; + } + + // Make sure we have host connection + DEFINE_AND_VALIDATE_HOST_CONNECTION; + + // send request to host + // TODO: XXX - should be implemented + //rcEnc->rc_XXX + + return 0; +} + +static int fb_setSwapInterval(struct framebuffer_device_t* dev, + int interval) +{ + fb_device_t *fbdev = (fb_device_t *)dev; + + if (!fbdev) { + return -EINVAL; + } + + // Make sure we have host connection + DEFINE_AND_VALIDATE_HOST_CONNECTION; + + // send request to host + rcEnc->rcFBSetSwapInterval(rcEnc, interval); + hostCon->flush(); + + return 0; +} + +static int fb_close(struct hw_device_t *dev) +{ + fb_device_t *fbdev = (fb_device_t *)dev; + + delete fbdev; + + return 0; +} + + +// +// gralloc module functions - refcount + locking interface +// +static int gralloc_register_buffer(gralloc_module_t const* module, + buffer_handle_t handle) +{ + pthread_once(&sFallbackOnce, fallback_init); + if (sFallback != NULL) { + return sFallback->registerBuffer(sFallback, handle); + } + + D("gralloc_register_buffer(%p) called", handle); + + private_module_t *gr = (private_module_t *)module; + cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { + ERR("gralloc_register_buffer(%p): invalid buffer", cb); + return -EINVAL; + } + + if (cb->hostHandle != 0) { + DEFINE_AND_VALIDATE_HOST_CONNECTION; + D("Opening host ColorBuffer 0x%x\n", cb->hostHandle); + rcEnc->rcOpenColorBuffer(rcEnc, cb->hostHandle); + } + + // + // if the color buffer has ashmem region and it is not mapped in this + // process map it now. + // + if (cb->ashmemSize > 0 && cb->mappedPid != getpid()) { + void *vaddr; + int err = map_buffer(cb, &vaddr); + if (err) { + ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err)); + return -err; + } + cb->mappedPid = getpid(); + } + + return 0; +} + +static int gralloc_unregister_buffer(gralloc_module_t const* module, + buffer_handle_t handle) +{ + if (sFallback != NULL) { + return sFallback->unregisterBuffer(sFallback, handle); + } + + private_module_t *gr = (private_module_t *)module; + cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { + ERR("gralloc_unregister_buffer(%p): invalid buffer", cb); + return -EINVAL; + } + + if (cb->hostHandle != 0) { + DEFINE_AND_VALIDATE_HOST_CONNECTION; + D("Closing host ColorBuffer 0x%x\n", cb->hostHandle); + rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle); + } + + // + // unmap ashmem region if it was previously mapped in this process + // (through register_buffer) + // + if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) { + void *vaddr; + int err = munmap((void *)cb->ashmemBase, cb->ashmemSize); + if (err) { + ERR("gralloc_unregister_buffer(%p): unmap failed", cb); + return -EINVAL; + } + cb->ashmemBase = NULL; + cb->mappedPid = 0; + } + + D("gralloc_unregister_buffer(%p) done\n", cb); + + return 0; +} + +static int gralloc_lock(gralloc_module_t const* module, + buffer_handle_t handle, int usage, + int l, int t, int w, int h, + void** vaddr) +{ + if (sFallback != NULL) { + return sFallback->lock(sFallback, handle, usage, l, t, w, h, vaddr); + } + + private_module_t *gr = (private_module_t *)module; + cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { + ALOGE("gralloc_lock bad handle\n"); + return -EINVAL; + } + + // Validate usage, + // 1. cannot be locked for hw access + // 2. lock for either sw read or write. + // 3. locked sw access must match usage during alloc time. + bool sw_read = (0 != (usage & GRALLOC_USAGE_SW_READ_MASK)); + bool sw_write = (0 != (usage & GRALLOC_USAGE_SW_WRITE_MASK)); + bool hw_read = (usage & GRALLOC_USAGE_HW_TEXTURE); + bool hw_write = (usage & GRALLOC_USAGE_HW_RENDER); + bool sw_read_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_READ_MASK)); + bool sw_write_allowed = (0 != (cb->usage & GRALLOC_USAGE_SW_WRITE_MASK)); + + if ( (hw_read || hw_write) || + (!sw_read && !sw_write) || + (sw_read && !sw_read_allowed) || + (sw_write && !sw_write_allowed) ) { + ALOGE("gralloc_lock usage mismatch usage=0x%x cb->usage=0x%x\n", usage, cb->usage); + return -EINVAL; + } + + EGLint postCount = 0; + void *cpu_addr = NULL; + + // + // make sure ashmem area is mapped if needed + // + if (cb->canBePosted() || sw_read || sw_write) { + if (cb->ashmemBasePid != getpid() || !cb->ashmemBase) { + return -EACCES; + } + + if (cb->canBePosted()) { + postCount = *((int *)cb->ashmemBase); + cpu_addr = (void *)(cb->ashmemBase + sizeof(int)); + } + else { + cpu_addr = (void *)(cb->ashmemBase); + } + } + + if (cb->hostHandle) { + // Make sure we have host connection + DEFINE_AND_VALIDATE_HOST_CONNECTION; + + // + // flush color buffer write cache on host and get its sync status. + // + int hostSyncStatus = rcEnc->rcColorBufferCacheFlush(rcEnc, cb->hostHandle, + postCount, + sw_read); + if (hostSyncStatus < 0) { + // host failed the color buffer sync - probably since it was already + // locked for write access. fail the lock. + ALOGE("gralloc_lock cacheFlush failed postCount=%d sw_read=%d\n", + postCount, sw_read); + return -EBUSY; + } + + // + // is virtual address required ? + // + if (sw_read || sw_write) { + *vaddr = cpu_addr; + } + } + + if (sw_write) { + // + // Keep locked region if locked for s/w write access. + // + cb->lockedLeft = l; + cb->lockedTop = t; + cb->lockedWidth = w; + cb->lockedHeight = h; + } + + return 0; +} + +static int gralloc_unlock(gralloc_module_t const* module, + buffer_handle_t handle) +{ + if (sFallback != NULL) { + return sFallback->unlock(sFallback, handle); + } + + private_module_t *gr = (private_module_t *)module; + cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { + return -EINVAL; + } + + // + // if buffer was locked for s/w write, we need to update the host with + // the updated data + // + if (cb->lockedWidth > 0 && cb->lockedHeight > 0 && cb->hostHandle) { + + // Make sure we have host connection + DEFINE_AND_VALIDATE_HOST_CONNECTION; + + void *cpu_addr; + if (cb->canBePosted()) { + cpu_addr = (void *)(cb->ashmemBase + sizeof(int)); + } + else { + cpu_addr = (void *)(cb->ashmemBase); + } + + if (cb->lockedWidth < cb->width || cb->lockedHeight < cb->height) { + int bpp = glUtilsPixelBitSize(cb->glFormat, cb->glType) >> 3; + char *tmpBuf = new char[cb->lockedWidth * cb->lockedHeight * bpp]; + + int dst_line_len = cb->lockedWidth * bpp; + int src_line_len = cb->width * bpp; + char *src = (char *)cpu_addr + cb->lockedTop*src_line_len + cb->lockedLeft*bpp; + char *dst = tmpBuf; + for (int y=0; y<cb->lockedHeight; y++) { + memcpy(dst, src, dst_line_len); + src += src_line_len; + dst += dst_line_len; + } + + rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle, + cb->lockedLeft, cb->lockedTop, + cb->lockedWidth, cb->lockedHeight, + cb->glFormat, cb->glType, + tmpBuf); + + delete [] tmpBuf; + } + else { + rcEnc->rcUpdateColorBuffer(rcEnc, cb->hostHandle, 0, 0, + cb->width, cb->height, + cb->glFormat, cb->glType, + cpu_addr); + } + } + + cb->lockedWidth = cb->lockedHeight = 0; + return 0; +} + + +static int gralloc_device_open(const hw_module_t* module, + const char* name, + hw_device_t** device) +{ + int status = -EINVAL; + + D("gralloc_device_open %s\n", name); + + pthread_once( &sFallbackOnce, fallback_init ); + if (sFallback != NULL) { + return sFallback->common.methods->open(&sFallback->common, name, device); + } + + if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) { + + // Create host connection and keep it in the TLS. + // return error if connection with host can not be established + HostConnection *hostCon = HostConnection::get(); + if (!hostCon) { + ALOGE("gralloc: failed to get host connection while opening %s\n", name); + return -EIO; + } + + // + // Allocate memory for the gralloc device (alloc interface) + // + gralloc_device_t *dev; + dev = (gralloc_device_t*)malloc(sizeof(gralloc_device_t)); + if (NULL == dev) { + return -ENOMEM; + } + + // Initialize our device structure + // + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = gralloc_device_close; + + dev->device.alloc = gralloc_alloc; + dev->device.free = gralloc_free; + dev->allocListHead = NULL; + pthread_mutex_init(&dev->lock, NULL); + + *device = &dev->device.common; + status = 0; + } + else if (!strcmp(name, GRALLOC_HARDWARE_FB0)) { + + // return error if connection with host can not be established + DEFINE_AND_VALIDATE_HOST_CONNECTION; + + // + // Query the host for Framebuffer attributes + // + D("gralloc: query Frabuffer attribs\n"); + EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH); + D("gralloc: width=%d\n", width); + EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT); + D("gralloc: height=%d\n", height); + EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI); + D("gralloc: xdpi=%d\n", xdpi); + EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI); + D("gralloc: ydpi=%d\n", ydpi); + EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS); + D("gralloc: fps=%d\n", fps); + EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL); + D("gralloc: min_swap=%d\n", min_si); + EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL); + D("gralloc: max_swap=%d\n", max_si); + + // + // Allocate memory for the framebuffer device + // + fb_device_t *dev; + dev = (fb_device_t*)malloc(sizeof(fb_device_t)); + if (NULL == dev) { + return -ENOMEM; + } + memset(dev, 0, sizeof(fb_device_t)); + + // Initialize our device structure + // + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = const_cast<hw_module_t*>(module); + dev->device.common.close = fb_close; + dev->device.setSwapInterval = fb_setSwapInterval; + dev->device.post = fb_post; + dev->device.setUpdateRect = 0; //fb_setUpdateRect; + dev->device.compositionComplete = fb_compositionComplete; //XXX: this is a dummy + + const_cast<uint32_t&>(dev->device.flags) = 0; + const_cast<uint32_t&>(dev->device.width) = width; + const_cast<uint32_t&>(dev->device.height) = height; + const_cast<int&>(dev->device.stride) = width; + const_cast<int&>(dev->device.format) = HAL_PIXEL_FORMAT_RGBA_8888; + const_cast<float&>(dev->device.xdpi) = xdpi; + const_cast<float&>(dev->device.ydpi) = ydpi; + const_cast<float&>(dev->device.fps) = fps; + const_cast<int&>(dev->device.minSwapInterval) = min_si; + const_cast<int&>(dev->device.maxSwapInterval) = max_si; + *device = &dev->device.common; + + status = 0; + } + + return status; +} + +// +// define the HMI symbol - our module interface +// +static struct hw_module_methods_t gralloc_module_methods = { + open: gralloc_device_open +}; + +struct private_module_t HAL_MODULE_INFO_SYM = { + base: { + common: { + tag: HARDWARE_MODULE_TAG, + version_major: 1, + version_minor: 0, + id: GRALLOC_HARDWARE_MODULE_ID, + name: "Graphics Memory Allocator Module", + author: "The Android Open Source Project", + methods: &gralloc_module_methods, + dso: NULL, + reserved: {0, } + }, + registerBuffer: gralloc_register_buffer, + unregisterBuffer: gralloc_unregister_buffer, + lock: gralloc_lock, + unlock: gralloc_unlock, + perform: NULL, + reserved_proc : {NULL, } + } +}; + +/* This function is called once to detect whether the emulator supports + * GPU emulation (this is done by looking at the qemu.gles kernel + * parameter, which must be > 0 if this is the case). + * + * If not, then load gralloc.default instead as a fallback. + */ +static void +fallback_init(void) +{ + char prop[PROPERTY_VALUE_MAX]; + void* module; + + property_get("ro.kernel.qemu.gles", prop, "0"); + if (atoi(prop) > 0) { + return; + } + ALOGD("Emulator without GPU emulation detected."); + module = dlopen("/system/lib/hw/gralloc.default.so", RTLD_LAZY|RTLD_LOCAL); + if (module != NULL) { + sFallback = reinterpret_cast<gralloc_module_t*>(dlsym(module, HAL_MODULE_INFO_SYM_AS_STR)); + if (sFallback == NULL) { + dlclose(module); + } + } + if (sFallback == NULL) { + ALOGE("Could not find software fallback module!?"); + } +} diff --git a/emulator/opengl/system/renderControl_enc/Android.mk b/emulator/opengl/system/renderControl_enc/Android.mk new file mode 100644 index 0000000..96f15a2 --- /dev/null +++ b/emulator/opengl/system/renderControl_enc/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH := $(call my-dir) + +$(call emugl-begin-shared-library,lib_renderControl_enc) +$(call emugl-gen-encoder,$(LOCAL_PATH),renderControl) +$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) +$(call emugl-import,libOpenglCodecCommon) +$(call emugl-end-module) diff --git a/emulator/opengl/system/renderControl_enc/README b/emulator/opengl/system/renderControl_enc/README new file mode 100644 index 0000000..2ee1a57 --- /dev/null +++ b/emulator/opengl/system/renderControl_enc/README @@ -0,0 +1,136 @@ +The renderControl.in file in this directory defines an API which is decoded +on the android guest into a stream and get decoded and executed on the host. +It is used in order to query the host renderer as well as send the host renderer +control commands. + +The following describes each of the entries defined by this renderControl API. + + +GLint rcGetRendererVersion(); + This function queries the host renderer version number. + +EGLint rcGetEGLVersion(EGLint* major, EGLint* minor); + This function queries the host renderer for the EGL version + it supports. returns EGL_FALSE on failure. + +EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize); + This function queries the host for EGL string (.i.e EGL_EXTENSIONS). + if buffer is NULL or the bufferSize is not big enough the return value + is the negative number of bytes required to store the string value + otherwise the string value is copied to buffer and its size is + returned. + +EGLint rcGetNumConfigs(uint32_t* numAttribs); + queries the host for the number of supported EGL configs. + The function returns the number of supported configs and returns in + numAttribs the number of attributes available for each config. + +EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer); + This function queries the host for the all set of supported configs + with their attribute values. + bufSize is the size of buffer, the size should be at least equal to + (numConfigs + 1) * numAttribs * sizeof(GLuint) + where numConfigs and numAttribs are the values returned in + rcGetNumConfigs. if bufSize is not big enough then the negative number + of required bytes is returned otherwise the function returns the number + of configs and buffer is filled as follows: The first 'numAttribs' + integer values are filled with the EGL enumerant describing a config + attribute, next for each config there are 'numAttribs' integer values + holding the attribute values for that config, the values are specified + in the same order as the attribute vector. + +EGLint rcChooseConfig(EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size) + This function triggers an eglChooseConfig on the host, to get a list of + configs matching the given attribs values. + attribs - a list of attribute names followed by the desired values, terminated by EGL_NONE + attribs_size - the size of the list + configs - the returned matching configuration names (same names as familiar to the client in rcGetConfigs) + configs_size - the size of the configs buffers + returns - the actual number of matching configurations (<= configs_size) + +EGLint rcGetFBParam(EGLint param); + queries the host for framebuffer parameter, see renderControl_types.h + for possible values of 'param'. + +uint32_t rcCreateContext(uint32_t config, uint32_t share, uint32_t glVersion); + This function creates a rendering context on the host and returns its + handle. config is the config index for the context, share is either zero + or a handle to a sharing context. glVersion is either 1 or 2 for GLES1 + or GLES2 context respectively. + + +void rcDestroyContext(uint32_t context); + This function destroys a rendering context on the host. + context is a handle returned in rcCreateContext. + +uint32_t rcCreateWindowSurface(uint32_t config, uint32_t width, uint32_t height); + This function creates a 'window' surface on the host which can be then + bind for rendering through rcMakeCurrent. + The function returns a handle to the created window surface. + +void rcDestroyWindowSurface(uint32_t windowSurface); + This function destoys a window surface. + +uint32_t rcCreateColorBuffer(uint32_t width, uint32_t height, GLenum internalFormat); + This function creates a colorBuffer object on the host which can be then + be specified as a render target for a window surface through + rcSetWindowColorBuffer or to be displayed on the framebuffer window + through rcFBPost. + The function returns a handle to the colorBuffer object, with an initial + reference count of 1. + +void rcOpenColorBuffer(uint32_t colorbuffer); + Adds an additional reference to the colorbuffer, typically from a + different Android process than the one which created it. + +void rcCloseColorBuffer(uint32_t colorbuffer); + Removes a reference to the colorbuffer. When the reference count drops + to zero the colorbuffer is automatically destroyed. + +void rcFlushWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer); + This flushes the current window color buffer + +void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer); + This set the target color buffer for a windowSurface, when set the + previous target colorBuffer gets updated before switching to the new + colorBuffer. + +EGLint rcMakeCurrent(uint32_t context, uint32_t drawSurf, uint32_t readSurf); + Binds a windowSurface(s) and current rendering context for the + calling thread. + +void rcFBPost(uint32_t colorBuffer); + This function causes the content of the colorBuffer object to be + displayed on the host framebuffer window. The function returns + immediatly, the buffer will be displayed at the next swap interval. + +void rcFBSetSwapInterval(EGLint interval); + Sets the swap interval for the host framebuffer window. + +void rcBindTexture(uint32_t colorBuffer); + This function instruct the host to bind the content of the specified + colorBuffer to the current binded texture object of the calling thread. + This function should be used to implement eglBindTexImage. + +EGLint rcColorBufferCacheFlush(uint32_t colorbuffer, EGLint postCount, int forRead); + This function returns only after all rendering requests for the specified + colorBuffer rendering target has been processed and after all 'postCount' + posts for the buffer requested previously through rcFBPost has been + processed. + if 'forRead' is not-zero, the function returns positive value in case + there was rendering done to the buffer since the last CacheFlush request + with non-zero 'forRead' value, otherwise the function returns zero or + negative value on failure. + +void rcReadColorBuffer(uint32_t colorbuffer, GLint x, GLint y, + GLint width, GLint height, GLenum format, + GLenum type, void* pixels); + This function queries the host for the pixel content of a colorBuffer's + subregion. It act the same as OpenGL glReadPixels however pixels + are always packed with alignment of 1. + +void rcUpdateColorBuffer(uint32_t colorbuffer, GLint x, GLint y, + GLint width, GLint height, GLenum format, + GLenum type, void* pixels); + Updates the content of a subregion of a colorBuffer object. + pixels are always unpacked with alignment of 1. diff --git a/emulator/opengl/system/renderControl_enc/renderControl.attrib b/emulator/opengl/system/renderControl_enc/renderControl.attrib new file mode 100644 index 0000000..8b9972f --- /dev/null +++ b/emulator/opengl/system/renderControl_enc/renderControl.attrib @@ -0,0 +1,41 @@ +GLOBAL + base_opcode 10000 + encoder_headers <stdint.h> <EGL/egl.h> "glUtils.h" + +rcGetEGLVersion + dir major out + len major sizeof(EGLint) + dir minor out + len minor sizeof(EGLint) + +rcQueryEGLString + dir buffer out + len buffer bufferSize + +rcGetGLString + dir buffer out + len buffer bufferSize + +rcGetNumConfigs + dir numAttribs out + len numAttribs sizeof(uint32_t) + +rcGetConfigs + dir buffer out + len buffer bufSize + +rcChooseConfig + dir attribs in + len attribs attribs_size + dir configs out + var_flag configs nullAllowed + len configs configs_size*sizeof(uint32_t) + +rcReadColorBuffer + dir pixels out + len pixels (((glUtilsPixelBitSize(format, type) * width) >> 3) * height) + +rcUpdateColorBuffer + dir pixels in + len pixels (((glUtilsPixelBitSize(format, type) * width) >> 3) * height) + var_flag pixels isLarge diff --git a/emulator/opengl/system/renderControl_enc/renderControl.in b/emulator/opengl/system/renderControl_enc/renderControl.in new file mode 100644 index 0000000..8281fd9 --- /dev/null +++ b/emulator/opengl/system/renderControl_enc/renderControl.in @@ -0,0 +1,25 @@ +GL_ENRTY(GLint, rcGetRendererVersion) +GL_ENTRY(EGLint, rcGetEGLVersion, EGLint *major, EGLint *minor) +GL_ENTRY(EGLint, rcQueryEGLString, EGLenum name, void *buffer, EGLint bufferSize) +GL_ENTRY(EGLint, rcGetGLString, EGLenum name, void *buffer, EGLint bufferSize) +GL_ENTRY(EGLint, rcGetNumConfigs, uint32_t *numAttribs) +GL_ENTRY(EGLint, rcGetConfigs, uint32_t bufSize, GLuint *buffer) +GL_ENTRY(EGLint, rcChooseConfig, EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size) +GL_ENTRY(EGLint, rcGetFBParam, EGLint param) +GL_ENTRY(uint32_t, rcCreateContext, uint32_t config, uint32_t share, uint32_t glVersion) +GL_ENTRY(void, rcDestroyContext, uint32_t context) +GL_ENTRY(uint32_t, rcCreateWindowSurface, uint32_t config, uint32_t width, uint32_t height) +GL_ENTRY(void, rcDestroyWindowSurface, uint32_t windowSurface) +GL_ENTRY(uint32_t, rcCreateColorBuffer, uint32_t width, uint32_t height, GLenum internalFormat) +GL_ENTRY(void, rcOpenColorBuffer, uint32_t colorbuffer) +GL_ENTRY(void, rcCloseColorBuffer, uint32_t colorbuffer) +GL_ENTRY(void, rcSetWindowColorBuffer, uint32_t windowSurface, uint32_t colorBuffer) +GL_ENTRY(int, rcFlushWindowColorBuffer, uint32_t windowSurface) +GL_ENTRY(EGLint, rcMakeCurrent, uint32_t context, uint32_t drawSurf, uint32_t readSurf) +GL_ENTRY(void, rcFBPost, uint32_t colorBuffer) +GL_ENTRY(void, rcFBSetSwapInterval, EGLint interval) +GL_ENTRY(void, rcBindTexture, uint32_t colorBuffer) +GL_ENTRY(void, rcBindRenderbuffer, uint32_t colorBuffer) +GL_ENTRY(EGLint, rcColorBufferCacheFlush, uint32_t colorbuffer, EGLint postCount,int forRead) +GL_ENTRY(void, rcReadColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels) +GL_ENTRY(int, rcUpdateColorBuffer, uint32_t colorbuffer, GLint x, GLint y, GLint width, GLint height, GLenum format, GLenum type, void *pixels) diff --git a/emulator/opengl/system/renderControl_enc/renderControl.types b/emulator/opengl/system/renderControl_enc/renderControl.types new file mode 100644 index 0000000..a7d96ab --- /dev/null +++ b/emulator/opengl/system/renderControl_enc/renderControl.types @@ -0,0 +1,11 @@ +uint32_t 32 0x%08x false +EGLint 32 0x%08x false +GLint 32 0x%08x false +GLuint 32 0x%08x false +GLenum 32 0x%08x false +EGLenum 32 0x%08x false +uint32_t* 32 0x%08x true +EGLint* 32 0x%08x true +GLint* 32 0x%08x true +GLuint* 32 0x%08x true +void* 32 0x%08x true diff --git a/emulator/opengl/system/renderControl_enc/renderControl_types.h b/emulator/opengl/system/renderControl_enc/renderControl_types.h new file mode 100644 index 0000000..da215bb --- /dev/null +++ b/emulator/opengl/system/renderControl_enc/renderControl_types.h @@ -0,0 +1,28 @@ +/* +* Copyright 2011 The Android Open Source Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#include <stdint.h> +#include <EGL/egl.h> +#include "glUtils.h" + +// values for 'param' argument of rcGetFBParam +#define FB_WIDTH 1 +#define FB_HEIGHT 2 +#define FB_XDPI 3 +#define FB_YDPI 4 +#define FB_FPS 5 +#define FB_MIN_SWAP_INTERVAL 6 +#define FB_MAX_SWAP_INTERVAL 7 |