diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h b/tools/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h index b7fcff565..bc895d750 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLClientState.h @@ -167,6 +167,7 @@ public: handled = false; break; default: + handled = false; ERR("unknown vertex-attrib parameter param %d\n", param); } return handled; diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp index 84a73ef34..768e3c9ab 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.cpp @@ -10,16 +10,75 @@ BufferData::BufferData(GLsizeiptr size, void * data) : m_size(size) if (data) memcpy(buffer, data, size); } +/**** ProgramData ****/ +ProgramData::ProgramData() : m_numIndexes(0), m_initialized(false) +{ + m_Indexes = NULL; +} + +void ProgramData::initProgramData(GLuint numIndexes) +{ + m_initialized = true; + m_numIndexes = numIndexes; + delete[] m_Indexes; + m_Indexes = new IndexInfo[numIndexes]; +} + +bool ProgramData::isInitialized() +{ + return m_initialized; +} + +ProgramData::~ProgramData() +{ + delete[] m_Indexes; + m_Indexes = NULL; +} + +void ProgramData::setIndexInfo(GLuint index, GLint base, GLint size, GLenum type) +{ + if (index>=m_numIndexes) + return; + m_Indexes[index].base = base; + m_Indexes[index].size = size; + m_Indexes[index].type = type; +} + +GLuint ProgramData::getIndexForLocation(GLint location) +{ + GLuint i=0; + for (i=0;i= low && location < high) + break; + } + return i; +} + +GLenum ProgramData::getTypeForLocation(GLint location) +{ + GLuint index = getIndexForLocation(location); + if (index(NULL)) + m_buffers(android::DefaultKeyedVector(NULL)), + m_programs(android::DefaultKeyedVector(NULL)), + m_shaders(android::List()) { } GLSharedGroup::~GLSharedGroup() { m_buffers.clear(); + m_programs.clear(); } BufferData * GLSharedGroup::getBufferData(GLuint bufferId) @@ -56,3 +115,111 @@ void GLSharedGroup::deleteBufferData(GLuint bufferId) android::AutoMutex _lock(m_lock); m_buffers.removeItem(bufferId); } + +void GLSharedGroup::addProgramData(GLuint program) +{ + android::AutoMutex _lock(m_lock); + ProgramData *pData = m_programs.valueFor(program); + if (pData) + { + m_programs.removeItem(program); + delete pData; + } + + m_programs.add(program,new ProgramData()); +} + +void GLSharedGroup::initProgramData(GLuint program, GLuint numIndexes) +{ + android::AutoMutex _lock(m_lock); + ProgramData *pData = m_programs.valueFor(program); + if (pData) + { + pData->initProgramData(numIndexes); + } +} + +bool GLSharedGroup::isProgramInitialized(GLuint program) +{ + android::AutoMutex _lock(m_lock); + ProgramData* pData = m_programs.valueFor(program); + if (pData) + { + return pData->isInitialized(); + } + return false; +} + +void GLSharedGroup::deleteProgramData(GLuint program) +{ + android::AutoMutex _lock(m_lock); + ProgramData *pData = m_programs.valueFor(program); + if (pData) + delete pData; + m_programs.removeItem(program); +} + +void GLSharedGroup::setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type) +{ + android::AutoMutex _lock(m_lock); + ProgramData* pData = m_programs.valueFor(program); + if (pData) + { + pData->setIndexInfo(index,base,size,type); + } +} + +GLenum GLSharedGroup::getProgramUniformType(GLuint program, GLint location) +{ + android::AutoMutex _lock(m_lock); + ProgramData* pData = m_programs.valueFor(program); + GLenum type=0; + if (pData) + { + type = pData->getTypeForLocation(location); + } + return type; +} + +bool GLSharedGroup::isProgram(GLuint program) +{ + android::AutoMutex _lock(m_lock); + ProgramData* pData = m_programs.valueFor(program); + return (pData!=NULL); +} + + +void GLSharedGroup::addShaderData(GLuint shader) +{ + android::AutoMutex _lock(m_lock); + m_shaders.push_front(shader); + +} +bool GLSharedGroup::isShader(GLuint shader) +{ + android::AutoMutex _lock(m_lock); + android::List::iterator iter; + iter = m_shaders.begin(); + while (iter!=m_shaders.end()) + { + if (*iter==shader) + return true; + iter++; + } + return false; +} +void GLSharedGroup::deleteShaderData(GLuint shader) +{ + android::AutoMutex _lock(m_lock); + android::List::iterator iter; + iter = m_shaders.begin(); + while (iter!=m_shaders.end()) + { + if (*iter==shader) + { + m_shaders.erase(iter); + return; + } + iter++; + } +} diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h index 0f07f47e0..46e91f893 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/GLSharedGroup.h @@ -32,6 +32,7 @@ #include "ErrorLog.h" #include #include +#include #include "FixedBuffer.h" #include "SmartPtr.h" @@ -42,10 +43,32 @@ struct BufferData { FixedBuffer m_fixedBuffer; }; +class ProgramData { +private: + typedef struct _IndexInfo { + GLint base; + GLint size; + GLenum type; + }IndexInfo; + + GLuint m_numIndexes; + IndexInfo* m_Indexes; + bool m_initialized; +public: + ProgramData(); + void initProgramData(GLuint numIndexes); + bool isInitialized(); + virtual ~ProgramData(); + void setIndexInfo(GLuint index, GLint base, GLint size, GLenum type); + GLuint getIndexForLocation(GLint location); + GLenum getTypeForLocation(GLint location); +}; class GLSharedGroup { private: android::DefaultKeyedVector m_buffers; + android::DefaultKeyedVector m_programs; + android::List m_shaders; mutable android::Mutex m_lock; public: GLSharedGroup(); @@ -55,6 +78,19 @@ public: void updateBufferData(GLuint bufferId, GLsizeiptr size, void * data); GLenum subUpdateBufferData(GLuint bufferId, GLintptr offset, GLsizeiptr size, void * data); void deleteBufferData(GLuint); + + bool isProgram(GLuint program); + bool isProgramInitialized(GLuint program); + void addProgramData(GLuint program); + void initProgramData(GLuint program, GLuint numIndexes); + void deleteProgramData(GLuint program); + void setProgramIndexInfo(GLuint program, GLuint index, GLint base, GLint size, GLenum type); + GLenum getProgramUniformType(GLuint program, GLint location); + + void addShaderData(GLuint shader); + bool isShader(GLuint shader); + void deleteShaderData(GLuint shader); + }; typedef SmartPtr GLSharedGroupPtr; diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp index 4376b6abf..b0702a76d 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp @@ -30,8 +30,10 @@ size_t glSizeof(GLenum type) case GL_HALF_FLOAT_OES: retval = 2; break; + case GL_INT: case GL_FLOAT: case GL_FIXED: + case GL_BOOL: retval = 4; break; #ifdef GL_DOUBLE @@ -39,6 +41,32 @@ size_t glSizeof(GLenum type) retval = 8; break; #endif + case GL_FLOAT_VEC2: + case GL_INT_VEC2: + case GL_BOOL_VEC2: + retval = 8; + break; + case GL_INT_VEC3: + case GL_BOOL_VEC3: + case GL_FLOAT_VEC3: + retval = 12; + break; + case GL_FLOAT_VEC4: + case GL_BOOL_VEC4: + case GL_INT_VEC4: + case GL_FLOAT_MAT2: + retval = 16; + break; + case GL_FLOAT_MAT3: + retval = 36; + break; + case GL_FLOAT_MAT4: + retval = 64; + break; + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + retval = 4; + break; default: ERR("**** ERROR unknown type 0x%x (%s,%d)\n", type, __FUNCTION__,__LINE__); } @@ -250,6 +278,7 @@ size_t glUtilsParamSize(GLenum param) case GL_MAX_TEXTURE_IMAGE_UNITS: case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES: case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: + case GL_LINE_WIDTH: s = 1; break; case GL_ALIASED_LINE_WIDTH_RANGE: @@ -282,6 +311,7 @@ size_t glUtilsParamSize(GLenum param) case GL_COLOR_CLEAR_VALUE: case GL_COLOR_WRITEMASK: case GL_AMBIENT_AND_DIFFUSE: + case GL_BLEND_COLOR: s = 4; break; case GL_MODELVIEW_MATRIX: @@ -320,9 +350,12 @@ int glUtilsPixelBitSize(GLenum format, GLenum type) int componentsize = 0; int pixelsize = 0; switch(type) { + case GL_BYTE: case GL_UNSIGNED_BYTE: componentsize = 8; break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_5_5_5_1: @@ -331,6 +364,13 @@ int glUtilsPixelBitSize(GLenum format, GLenum type) case GL_RGBA4_OES: pixelsize = 16; break; + case GL_INT: + case GL_UNSIGNED_INT: + case GL_FLOAT: + case GL_FIXED: + case GL_UNSIGNED_INT_24_8_OES: + pixelsize = 32; + break; default: ERR("glUtilsPixelBitSize: unknown pixel type - assuming pixel data 0\n"); componentsize = 0; @@ -345,6 +385,8 @@ int glUtilsPixelBitSize(GLenum format, GLenum type) #endif case GL_ALPHA: case GL_LUMINANCE: + case GL_DEPTH_COMPONENT: + case GL_DEPTH_STENCIL_OES: components = 1; break; case GL_LUMINANCE_ALPHA: diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp index eda8f984e..225d4ff68 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.cpp @@ -47,6 +47,13 @@ GL2Encoder::GL2Encoder(IOStream *stream) : gl2_encoder_context_t(stream) 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); } GL2Encoder::~GL2Encoder() @@ -416,3 +423,86 @@ void GL2Encoder::s_glFinish(void *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 ; iglGetActiveUniform(self, program, i, maxLength, NULL, &size, &type, name); + location = ctx->glGetUniformLocation(self, program, name); + ctx->m_shared->setProgramIndexInfo(program, i, location, size, type); + } + + 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) || ctx->m_shared->isShader(program)), GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION); + SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,location)==0, GL_INVALID_OPERATION); + ctx->m_glGetUniformiv_enc(self, program, location, 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) || ctx->m_shared->isShader(program)), GL_INVALID_VALUE); + SET_ERROR_IF(!ctx->m_shared->isProgramInitialized(program), GL_INVALID_OPERATION); + SET_ERROR_IF(ctx->m_shared->getProgramUniformType(program,location)==0, GL_INVALID_OPERATION); + ctx->m_glGetUniformfv_enc(self, program, location, 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) + ctx->m_shared->addShaderData(shader); + return shader; +} + +void GL2Encoder::s_glDeleteShader(void *self, GLenum shader) +{ + GL2Encoder *ctx = (GL2Encoder*)self; + ctx->m_glDeleteShader_enc(self,shader); + ctx->m_shared->deleteShaderData(shader); +} diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h index d47ddcaad..3e2dccf4b 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2Encoder.h @@ -32,6 +32,7 @@ public: } void setSharedGroup(GLSharedGroupPtr shared){ m_shared = shared; } const GLClientState *state() { return m_state; } + const GLSharedGroupPtr shared() { return m_shared; } void flush() { gl2_encoder_context_t::m_stream->flush(); } @@ -118,5 +119,27 @@ private: 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); + }; #endif diff --git a/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp b/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp index 1984401f7..57d65c092 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.cpp @@ -30,3 +30,10 @@ size_t pixelDataSize3D(void *self, GLsizei width, GLsizei height, GLsizei depth, 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/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h b/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h index 7f7f5c4d4..8e91aeb14 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h +++ b/tools/emulator/opengl/system/GLESv2_enc/GL2EncoderUtils.h @@ -19,5 +19,6 @@ 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/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib index 10e2987d7..a90eadf34 100644 --- a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib +++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib @@ -76,8 +76,10 @@ glGenTextures 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 @@ -87,8 +89,10 @@ glGetActiveAttrib 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 @@ -168,7 +172,9 @@ glGetShaderInfoLog #void glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) glGetShaderPrecisionFormat - len range (sizeof(GLint)) + 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) @@ -195,11 +201,13 @@ glGetTexParameteriv #void glGetUniformfv(GLuint program, GLint location, GLfloat *params) glGetUniformfv - flag unsupported + dir params out + len params glSizeof(uniformType(self, program, location)) #void glGetUniformiv(GLuint program, GLint location, GLint *params) glGetUniformiv - flag unsupported + dir params out + len params glSizeof(uniformType(self, program, location)) #int glGetUniformLocation(GLuint program, GLchar *name) glGetUniformLocation @@ -210,11 +218,13 @@ glGetUniformLocation # 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))