diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk b/tools/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk new file mode 100644 index 000000000..8c946707a --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/Android.mk @@ -0,0 +1,35 @@ +LOCAL_PATH := $(call my-dir) + +### GLES_CM host implementation (On top of OpenGL) ######################## +include $(CLEAR_VARS) + +translator_path := $(LOCAL_PATH)/.. +#exclude darwin builds +ifeq (, $(findstring $(HOST_OS), darwin)) + +LOCAL_SRC_FILES := \ + GLDispatch.cpp \ + GLEScontext.cpp \ + GLESimp.cpp \ + GLESpointer.cpp \ + GLESvalidate.cpp \ + GLESutils.cpp \ + GLESbuffer.cpp \ + TextureUtils.cpp \ + RangeManip.cpp + +LOCAL_C_INCLUDES += \ + $(translator_path)/include + +LOCAL_STATIC_LIBRARIES := \ + libGLcommon \ + libcutils + +LOCAL_CFLAGS := -g -O0 +LOCAL_MODULE_TAGS := debug +LOCAL_MODULE := libGLES_CM_translator +LOCAL_LDLIBS := -lGL + +include $(BUILD_HOST_SHARED_LIBRARY) + +endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp new file mode 100644 index 000000000..27bc98bc6 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.cpp @@ -0,0 +1,171 @@ +/* +* 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 "GLDispatch.h" +#include + +#ifdef __linux__ +#include +#elif defined(WIN32) +#include +#endif + +typedef void (*GL_FUNC_PTR)(); + +static GL_FUNC_PTR getGLFuncAddress(const char *funcName) { +#ifdef __linux__ + return (GL_FUNC_PTR)glXGetProcAddress((const GLubyte*)funcName); +#elif defined(WIN32) + return (GL_FUNC_PTR)wglGetProcAddress(funcName); +#endif +} + +#define LOAD_GL_FUNC(name) { void * funcAddrs = NULL; \ + funcAddrs = (void *)getGLFuncAddress(#name); \ + if(funcAddrs) \ + *(void**)(&name) = funcAddrs; \ + else \ + fprintf(stderr,"could not load func %s\n",#name); } + +GLDispatch::GLDispatch():m_isLoaded(false){}; + + +void GLDispatch::dispatchFuncs() { + android::Mutex::Autolock mutex(m_lock); + if(m_isLoaded) + return; + + LOAD_GL_FUNC(glActiveTexture); + LOAD_GL_FUNC(glAlphaFunc); + LOAD_GL_FUNC(glBegin); + LOAD_GL_FUNC(glBindBuffer); + LOAD_GL_FUNC(glBindTexture); + LOAD_GL_FUNC(glBlendFunc); + LOAD_GL_FUNC(glBufferData); + LOAD_GL_FUNC(glBufferSubData); + LOAD_GL_FUNC(glClear); + LOAD_GL_FUNC(glClearColor); + LOAD_GL_FUNC(glClearDepthf); + LOAD_GL_FUNC(glClearStencil); + LOAD_GL_FUNC(glClientActiveTexture); + LOAD_GL_FUNC(glClipPlane); + LOAD_GL_FUNC(glColor4d); + LOAD_GL_FUNC(glColor4f); + LOAD_GL_FUNC(glColor4fv); + LOAD_GL_FUNC(glColor4ub); + LOAD_GL_FUNC(glColor4ubv); + LOAD_GL_FUNC(glColorMask); + LOAD_GL_FUNC(glColorPointer); + LOAD_GL_FUNC(glCompressedTexImage2D); + LOAD_GL_FUNC(glCompressedTexSubImage2D); + LOAD_GL_FUNC(glCopyTexImage2D); + LOAD_GL_FUNC(glCopyTexSubImage2D); + LOAD_GL_FUNC(glCullFace); + LOAD_GL_FUNC(glDeleteBuffers); + LOAD_GL_FUNC(glDeleteTextures); + LOAD_GL_FUNC(glDepthFunc); + LOAD_GL_FUNC(glDepthMask); + LOAD_GL_FUNC(glDepthRange); + LOAD_GL_FUNC(glDisable); + LOAD_GL_FUNC(glDisableClientState); + LOAD_GL_FUNC(glDrawArrays); + LOAD_GL_FUNC(glDrawElements); + LOAD_GL_FUNC(glEnable); + LOAD_GL_FUNC(glEnableClientState); + LOAD_GL_FUNC(glEnd); + LOAD_GL_FUNC(glFinish); + LOAD_GL_FUNC(glFlush); + LOAD_GL_FUNC(glFogf); + LOAD_GL_FUNC(glFogfv); + LOAD_GL_FUNC(glFrontFace); + LOAD_GL_FUNC(glFrustum); + LOAD_GL_FUNC(glGenBuffers); + LOAD_GL_FUNC(glGenTextures); + LOAD_GL_FUNC(glGetBooleanv); + LOAD_GL_FUNC(glGetBufferParameteriv); + LOAD_GL_FUNC(glGetClipPlane); + LOAD_GL_FUNC(glGetDoublev); + LOAD_GL_FUNC(glGetError); + LOAD_GL_FUNC(glGetFloatv); + LOAD_GL_FUNC(glGetIntegerv); + LOAD_GL_FUNC(glGetLightfv); + LOAD_GL_FUNC(glGetMaterialfv); + LOAD_GL_FUNC(glGetPointerv); + LOAD_GL_FUNC(glGetString); + LOAD_GL_FUNC(glGetTexEnvfv); + LOAD_GL_FUNC(glGetTexEnviv); + LOAD_GL_FUNC(glGetTexParameterfv); + LOAD_GL_FUNC(glGetTexParameteriv); + LOAD_GL_FUNC(glHint); + LOAD_GL_FUNC(glIsBuffer); + LOAD_GL_FUNC(glIsEnabled); + LOAD_GL_FUNC(glIsTexture); + LOAD_GL_FUNC(glLightf); + LOAD_GL_FUNC(glLightfv); + LOAD_GL_FUNC(glLightModelf); + LOAD_GL_FUNC(glLightModelfv); + LOAD_GL_FUNC(glLineWidth); + LOAD_GL_FUNC(glLoadIdentity); + LOAD_GL_FUNC(glLoadMatrixf); + LOAD_GL_FUNC(glLogicOp); + LOAD_GL_FUNC(glMaterialf); + LOAD_GL_FUNC(glMaterialfv); + LOAD_GL_FUNC(glMultiTexCoord2fv); + LOAD_GL_FUNC(glMultiTexCoord2sv); + LOAD_GL_FUNC(glMultiTexCoord3fv); + LOAD_GL_FUNC(glMultiTexCoord3sv); + LOAD_GL_FUNC(glMultiTexCoord4fv); + LOAD_GL_FUNC(glMultiTexCoord4sv); + LOAD_GL_FUNC(glMultiTexCoord4f); + LOAD_GL_FUNC(glMultMatrixf); + LOAD_GL_FUNC(glNormal3f); + LOAD_GL_FUNC(glNormal3fv); + LOAD_GL_FUNC(glNormal3sv); + LOAD_GL_FUNC(glOrtho); + LOAD_GL_FUNC(glPointParameterf); + LOAD_GL_FUNC(glPointParameterfv); + LOAD_GL_FUNC(glPointSize); + LOAD_GL_FUNC(glPolygonOffset); + LOAD_GL_FUNC(glRotatef); + LOAD_GL_FUNC(glScalef); + LOAD_GL_FUNC(glTexEnvf); + LOAD_GL_FUNC(glTexEnvfv); + LOAD_GL_FUNC(glTexParameterf); + LOAD_GL_FUNC(glTexParameterfv); + LOAD_GL_FUNC(glMatrixMode); + LOAD_GL_FUNC(glNormalPointer); + LOAD_GL_FUNC(glPixelStorei); + LOAD_GL_FUNC(glPopMatrix); + LOAD_GL_FUNC(glPushMatrix); + LOAD_GL_FUNC(glReadPixels); + LOAD_GL_FUNC(glSampleCoverage); + LOAD_GL_FUNC(glScissor); + LOAD_GL_FUNC(glShadeModel); + LOAD_GL_FUNC(glStencilFunc); + LOAD_GL_FUNC(glStencilMask); + LOAD_GL_FUNC(glStencilOp); + LOAD_GL_FUNC(glTexCoordPointer); + LOAD_GL_FUNC(glTexEnvi); + LOAD_GL_FUNC(glTexEnviv); + LOAD_GL_FUNC(glTexImage2D); + LOAD_GL_FUNC(glTexParameteri); + LOAD_GL_FUNC(glTexParameteriv); + LOAD_GL_FUNC(glTexSubImage2D); + LOAD_GL_FUNC(glTranslatef); + LOAD_GL_FUNC(glVertexPointer); + LOAD_GL_FUNC(glViewport); + + m_isLoaded = true; +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h new file mode 100644 index 000000000..af1518380 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLDispatch.h @@ -0,0 +1,158 @@ +/* +* 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 GLDISPATCHH +#define GLDISPATCHH + +#include +#include + +#define GLAPIENTRY GL_APIENTRY + +typedef double GLclampd; /* double precision float in [0,1] */ +typedef double GLdouble; /* double precision float */ + +class GLDispatch +{ +public: + + GLDispatch(); + void dispatchFuncs(); + + void (GLAPIENTRY *glActiveTexture) ( GLenum texture ); + void (GLAPIENTRY *glAlphaFunc) (GLenum func, GLclampf ref); + void (GLAPIENTRY *glBegin)( GLenum mode ); + void (GLAPIENTRY *glBindBuffer) (GLenum target, GLuint buffer); + void (GLAPIENTRY *glBindTexture) (GLenum target, GLuint texture); + void (GLAPIENTRY *glBlendFunc) (GLenum sfactor, GLenum dfactor); + void (GLAPIENTRY *glBufferData) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); + void (GLAPIENTRY *glBufferSubData) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); + void (GLAPIENTRY *glClear) (GLbitfield mask); + void (GLAPIENTRY *glClearColor) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void (GLAPIENTRY *glClearDepthf) (GLclampd depth); + void (GLAPIENTRY *glClearStencil) (GLint s); + void (GLAPIENTRY *glClientActiveTexture) ( GLenum texture ); + void (GLAPIENTRY *glClipPlane) (GLenum plane, const GLdouble *equation); + void (GLAPIENTRY *glColor4d) (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); + void (GLAPIENTRY *glColor4f) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void (GLAPIENTRY *glColor4fv) ( const GLfloat *v ); + void (GLAPIENTRY *glColor4ub) (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + void (GLAPIENTRY *glColor4ubv) ( const GLubyte *v ); + void (GLAPIENTRY *glColorMask) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void (GLAPIENTRY *glColorPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + void (GLAPIENTRY *glCompressedTexImage2D) ( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data ); + void (GLAPIENTRY *glCompressedTexSubImage2D) ( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data ); + void (GLAPIENTRY *glCopyTexImage2D) (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + void (GLAPIENTRY *glCopyTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void (GLAPIENTRY *glCullFace) (GLenum mode); + void (GLAPIENTRY *glDeleteBuffers) (GLsizei n, const GLuint *buffers); + void (GLAPIENTRY *glDeleteTextures) (GLsizei n, const GLuint *textures); + void (GLAPIENTRY *glDepthFunc) (GLenum func); + void (GLAPIENTRY *glDepthMask) (GLboolean flag); + void (GLAPIENTRY *glDepthRange) (GLclampd zNear, GLclampd zFar); + void (GLAPIENTRY *glDisable) (GLenum cap); + void (GLAPIENTRY *glDisableClientState) (GLenum array); + void (GLAPIENTRY *glDrawArrays) (GLenum mode, GLint first, GLsizei count); + void (GLAPIENTRY *glDrawElements) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); + void (GLAPIENTRY *glEnable) (GLenum cap); + void (GLAPIENTRY *glEnableClientState) (GLenum array); + void (GLAPIENTRY *glEnd) ( void ); + void (GLAPIENTRY *glFinish) (void); + void (GLAPIENTRY *glFlush) (void); + void (GLAPIENTRY *glFogf) (GLenum pname, GLfloat param); + void (GLAPIENTRY *glFogfv) (GLenum pname, const GLfloat *params); + void (GLAPIENTRY *glFrontFace) (GLenum mode); + void (GLAPIENTRY *glFrustum) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + void (GLAPIENTRY *glGenBuffers) (GLsizei n, GLuint *buffers); + void (GLAPIENTRY *glGenTextures) (GLsizei n, GLuint *textures); + void (GLAPIENTRY *glGetBooleanv) (GLenum pname, GLboolean *params); + void (GLAPIENTRY *glGetBufferParameteriv) (GLenum, GLenum, GLint *); + void (GLAPIENTRY *glGetClipPlane) (GLenum plane, GLdouble *equation); + void (GLAPIENTRY *glGetDoublev) ( GLenum pname, GLdouble *params ); + GLenum (GLAPIENTRY *glGetError) (void); + void (GLAPIENTRY *glGetFloatv) (GLenum pname, GLfloat *params); + void (GLAPIENTRY *glGetIntegerv) (GLenum pname, GLint *params); + void (GLAPIENTRY *glGetLightfv) (GLenum light, GLenum pname, GLfloat *params); + void (GLAPIENTRY *glGetMaterialfv) (GLenum face, GLenum pname, GLfloat *params); + void (GLAPIENTRY *glGetPointerv) (GLenum pname, GLvoid* *params); + const GLubyte * (GLAPIENTRY *glGetString) (GLenum name); + void (GLAPIENTRY *glGetTexEnvfv) (GLenum target, GLenum pname, GLfloat *params); + void (GLAPIENTRY *glGetTexEnviv) (GLenum target, GLenum pname, GLint *params); + void (GLAPIENTRY *glGetTexParameterfv) (GLenum target, GLenum pname, GLfloat *params); + void (GLAPIENTRY *glGetTexParameteriv) (GLenum target, GLenum pname, GLint *params); + void (GLAPIENTRY *glHint) (GLenum target, GLenum mode); + GLboolean (GLAPIENTRY *glIsBuffer) (GLuint); + GLboolean (GLAPIENTRY *glIsEnabled) (GLenum cap); + GLboolean (GLAPIENTRY *glIsTexture) (GLuint texture); + void (GLAPIENTRY *glLightf) (GLenum light, GLenum pname, GLfloat param); + void (GLAPIENTRY *glLightfv) (GLenum light, GLenum pname, const GLfloat *params); + void (GLAPIENTRY *glLightModelf) (GLenum pname, GLfloat param); + void (GLAPIENTRY *glLightModelfv) (GLenum pname, const GLfloat *params); + void (GLAPIENTRY *glLineWidth) (GLfloat width); + void (GLAPIENTRY *glLoadIdentity) (void); + void (GLAPIENTRY *glLoadMatrixf) (const GLfloat *m); + void (GLAPIENTRY *glLogicOp) (GLenum opcode); + void (GLAPIENTRY *glMaterialf) (GLenum face, GLenum pname, GLfloat param); + void (GLAPIENTRY *glMaterialfv) (GLenum face, GLenum pname, const GLfloat *params); + void (GLAPIENTRY *glMultiTexCoord2fv) ( GLenum target, const GLfloat *v ); + void (GLAPIENTRY *glMultiTexCoord2sv) ( GLenum target, const GLshort *v ); + void (GLAPIENTRY *glMultiTexCoord3fv) ( GLenum target, const GLfloat *v ); + void (GLAPIENTRY *glMultiTexCoord3sv) ( GLenum target, const GLshort *v ); + void (GLAPIENTRY *glMultiTexCoord4f) ( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q ); + void (GLAPIENTRY *glMultiTexCoord4fv) ( GLenum target, const GLfloat *v ); + void (GLAPIENTRY *glMultiTexCoord4sv) ( GLenum target, const GLshort *v ); + void (GLAPIENTRY *glMultMatrixf) (const GLfloat *m); + void (GLAPIENTRY *glNormal3f) (GLfloat nx, GLfloat ny, GLfloat nz); + void (GLAPIENTRY *glNormal3fv) ( const GLfloat *v ); + void (GLAPIENTRY *glNormal3sv) ( const GLshort *v ); + void (GLAPIENTRY *glOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + void (GLAPIENTRY *glPointParameterf) (GLenum, GLfloat); + void (GLAPIENTRY *glPointParameterfv) (GLenum, const GLfloat *); + void (GLAPIENTRY *glPointSize) (GLfloat size); + void (GLAPIENTRY *glPolygonOffset) (GLfloat factor, GLfloat units); + void (GLAPIENTRY *glRotatef) (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + void (GLAPIENTRY *glScalef) (GLfloat x, GLfloat y, GLfloat z); + void (GLAPIENTRY *glTexEnvf) (GLenum target, GLenum pname, GLfloat param); + void (GLAPIENTRY *glTexEnvfv) (GLenum target, GLenum pname, const GLfloat *params); + void (GLAPIENTRY *glTexParameterf) (GLenum target, GLenum pname, GLfloat param); + void (GLAPIENTRY *glTexParameterfv) (GLenum target, GLenum pname, const GLfloat *params); + void (GLAPIENTRY *glMatrixMode) (GLenum mode); + void (GLAPIENTRY *glNormalPointer) (GLenum type, GLsizei stride, const GLvoid *pointer); + void (GLAPIENTRY *glPixelStorei) (GLenum pname, GLint param); + void (GLAPIENTRY *glPopMatrix) (void); + void (GLAPIENTRY *glPushMatrix) (void); + void (GLAPIENTRY *glReadPixels) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels); + void (GLAPIENTRY *glSampleCoverage) ( GLclampf value, GLboolean invert ); + void (GLAPIENTRY *glScissor) (GLint x, GLint y, GLsizei width, GLsizei height); + void (GLAPIENTRY *glShadeModel) (GLenum mode); + void (GLAPIENTRY *glStencilFunc) (GLenum func, GLint ref, GLuint mask); + void (GLAPIENTRY *glStencilMask) (GLuint mask); + void (GLAPIENTRY *glStencilOp) (GLenum fail, GLenum zfail, GLenum zpass); + void (GLAPIENTRY *glTexCoordPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + void (GLAPIENTRY *glTexEnvi) (GLenum target, GLenum pname, GLint param); + void (GLAPIENTRY *glTexEnviv) (GLenum target, GLenum pname, const GLint *params); + void (GLAPIENTRY *glTexImage2D) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + void (GLAPIENTRY *glTexParameteri) (GLenum target, GLenum pname, GLint param); + void (GLAPIENTRY *glTexParameteriv) (GLenum target, GLenum pname, const GLint *params); + void (GLAPIENTRY *glTexSubImage2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); + void (GLAPIENTRY *glTranslatef) (GLfloat x, GLfloat y, GLfloat z); + void (GLAPIENTRY *glVertexPointer) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + void (GLAPIENTRY *glViewport) (GLint x, GLint y, GLsizei width, GLsizei height); +private: + bool m_isLoaded; + android::Mutex m_lock; +}; + +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.cpp new file mode 100644 index 000000000..531e79d0f --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.cpp @@ -0,0 +1,53 @@ +/* +* 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 "GLESbuffer.h" +#include + +bool GLESbuffer::setBuffer(GLuint size,GLuint usage,const GLvoid* data) { + m_size = size; + m_usage = usage; + if(m_data) { + delete [] m_data; + m_data = NULL; + } + m_data = new unsigned char[size]; + if(m_data) { + memcpy(m_data,data,size); + m_conversionManager.clear(); + m_conversionManager.addRange(Range(0,m_size)); + return true; + } + return false; +} + +bool GLESbuffer::setSubBuffer(GLint offset,GLuint size,const GLvoid* data) { + if(offset + size > m_size) return false; + memcpy(m_data+offset,data,size); + m_conversionManager.addRange(Range(offset,size)); + m_conversionManager.merge(); + return true; +} + +void GLESbuffer::getConversions(const RangeList& rIn,RangeList& rOut) { + m_conversionManager.delRanges(rIn,rOut); + rOut.merge(); +} + +GLESbuffer::~GLESbuffer() { + if(m_data) { + delete [] m_data; + } +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h new file mode 100644 index 000000000..e1326fc66 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESbuffer.h @@ -0,0 +1,42 @@ +/* +* 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 GLES_BUFFER_H +#define GLES_BUFFER_H + +#include +#include +#include "RangeManip.h" + +class GLESbuffer { +public: + GLESbuffer():m_size(0),m_usage(GL_STATIC_DRAW),m_data(NULL){} + GLuint getSize(){return m_size;}; + GLuint getUsage(){return m_usage;}; + GLvoid* getData(){ return m_data;} + bool setBuffer(GLuint size,GLuint usage,const GLvoid* data); + bool setSubBuffer(GLint offset,GLuint size,const GLvoid* data); + void getConversions(const RangeList& rIn,RangeList& rOut); + bool fullyConverted(){return m_conversionManager.size() == 0;}; + ~GLESbuffer(); + +private: + GLuint m_size; + GLuint m_usage; + unsigned char* m_data; + RangeList m_conversionManager; +}; + +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp new file mode 100644 index 000000000..1f9a1e511 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.cpp @@ -0,0 +1,528 @@ +/* +* 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 "GLEScontext.h" +#include "GLESutils.h" +#include "GLfixed_ops.h" +#include "RangeManip.h" +#include +#include +#include + +//declerations +static void convertDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize); +static void convertIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize); +static int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices); + + +GLDispatch GLEScontext::s_glDispatch; +GLsupport GLEScontext::s_glSupport; +android::Mutex GLEScontext::s_lock; + +GLESFloatArrays::~GLESFloatArrays() { + for(std::map::iterator it = arrays.begin(); it != arrays.end();it++) { + GLfloat* p = (*it).second; + if(p) { + delete[] p; + } + } +} + +GLEScontext::~GLEScontext() { + for(ArraysMap::iterator it = m_map.begin(); it != m_map.end();it++) { + GLESpointer* p = (*it).second; + if(p) { + delete[] p; + } + } +} + +void GLEScontext::init() { + android::Mutex::Autolock mutex(s_lock); + if(!m_initialized) { + int maxTexUnits; + s_glDispatch.glGetIntegerv(GL_MAX_CLIP_PLANES,&s_glSupport.maxClipPlane); + s_glDispatch.glGetIntegerv(GL_MAX_LIGHTS,&s_glSupport.maxLights); + s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize); + s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTexUnits); + s_glSupport.maxTexUnits = maxTexUnits < MAX_TEX_UNITS ? maxTexUnits:MAX_TEX_UNITS; + } + + m_texCoords = new GLESpointer[s_glSupport.maxTexUnits]; + m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_activeTexture]; + m_initialized = true; +} + +GLEScontext::GLEScontext():m_glError(GL_NO_ERROR),m_activeTexture(0),m_arrayBuffer(0),m_elementBuffer(0),m_minAvailableBuffer(1),m_pointsIndex(-1),m_initialized(false) { + + s_glDispatch.dispatchFuncs(); + + m_map[GL_COLOR_ARRAY] = new GLESpointer(); + m_map[GL_NORMAL_ARRAY] = new GLESpointer(); + m_map[GL_VERTEX_ARRAY] = new GLESpointer(); + m_map[GL_POINT_SIZE_ARRAY_OES] = new GLESpointer(); +} + +GLDispatch& GLEScontext::dispatcher() { + return s_glDispatch; +} + +GLenum GLEScontext::getGLerror() { + return m_glError; +} + +void GLEScontext::setGLerror(GLenum err) { + m_glError = err; +} + +void GLEScontext::setActiveTexture(GLenum tex) { + m_activeTexture = tex - GL_TEXTURE0; + m_map[GL_TEXTURE_COORD_ARRAY] = &m_texCoords[m_activeTexture]; +} + +const GLvoid* GLEScontext::setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data) { + GLuint bufferName = m_arrayBuffer; + if(bufferName) { + unsigned int offset = reinterpret_cast(data); + m_map[arrType]->setBuffer(size,type,stride,m_vbos[bufferName],offset); + return static_cast(m_vbos[bufferName]->getData()) + offset; + } + m_map[arrType]->setArray(size,type,stride,data); + return data; +} + + +void GLEScontext::enableArr(GLenum arr,bool enable) { + m_map[arr]->enable(enable); +} + +bool GLEScontext::isArrEnabled(GLenum arr) { + return m_map[arr]->isEnable(); +} + +const GLESpointer* GLEScontext::getPointer(GLenum arrType) { + if(m_map.find(arrType) != m_map.end()) return m_map[arrType]; + return NULL; +} + +//sending data to server side +void GLEScontext::sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int index) { + switch(arrayType) { + case GL_VERTEX_ARRAY: + s_glDispatch.glVertexPointer(size,GL_FLOAT,stride,arr); + break; + case GL_NORMAL_ARRAY: + s_glDispatch.glNormalPointer(GL_FLOAT,stride,arr); + break; + case GL_TEXTURE_COORD_ARRAY: + s_glDispatch.glTexCoordPointer(size,GL_FLOAT,stride,arr); + break; + case GL_COLOR_ARRAY: + s_glDispatch.glColorPointer(size,GL_FLOAT,stride,arr); + break; + case GL_POINT_SIZE_ARRAY_OES: + m_pointsIndex = index; + break; + } +} + +static void convertDirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,unsigned int nBytes,unsigned int strideOut,int attribSize) { + + for(unsigned int i = 0; i < nBytes;i+=strideOut) { + const GLfixed* fixed_data = (const GLfixed *)dataIn; + //filling attrib + for(int j=0;j(&static_cast(dataOut)[i])[j] = X2F(fixed_data[j]); + } + dataIn += strideIn; + } +} + +static void convertIndirectLoop(const char* dataIn,unsigned int strideIn,void* dataOut,GLsizei count,GLenum indices_type,const GLvoid* indices,unsigned int strideOut,int attribSize) { + for(int i = 0 ;i < count ;i++) { + unsigned short index = indices_type == GL_UNSIGNED_BYTE? ((GLubyte *)indices)[i]: + ((GLushort *)indices)[i]; + const GLfixed* fixed_data = (GLfixed *)(dataIn + index*strideIn); + GLfloat* float_data = reinterpret_cast(static_cast(dataOut) + index*strideOut); + + for(int j=0;jgetSize()*4; //4 is the sizeof GLfixed or GLfloat in bytes + int stride = p->getStride()?p->getStride():attribSize; + int start = p->getBufferOffset()+first*attribSize; + if(!p->getStride()) { + list.addRange(Range(start,count*attribSize)); + } else { + for(int i = 0 ;i < count; i++,start+=stride) { + list.addRange(Range(start,attribSize)); + } + } +} + +static void indirectToBytesRanges(const GLvoid* indices,GLenum indices_type,GLsizei count,GLESpointer* p,RangeList& list) { + + int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes + int stride = p->getStride()?p->getStride():attribSize; + int start = p->getBufferOffset(); + for(int i=0 ; i < count; i++) { + GLushort index = (indices_type == GL_UNSIGNED_SHORT? + static_cast(indices)[i]: + static_cast(indices)[i]); + list.addRange(Range(start+index*stride,attribSize)); + + } +} + +int bytesRangesToIndices(RangeList& ranges,GLESpointer* p,GLushort* indices) { + + int attribSize = p->getSize() * 4; //4 is the sizeof GLfixed or GLfloat in bytes + int stride = p->getStride()?p->getStride():attribSize; + int offset = p->getBufferOffset(); + + int n = 0; + for(int i=0;igetType(); + if(isArrEnabled(array_id) && type == GL_FIXED) { + int attribSize = p->getSize(); + unsigned int size = attribSize*count + first; + fArrs.arrays[index] = new GLfloat[size]; + int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; + const char* data = (const char*)p->getArrayData() + (first*stride); + + convertDirectLoop(data,stride,fArrs.arrays[index],size*sizeof(GLfloat),attribSize*sizeof(GLfloat),attribSize); + sendArr(fArrs.arrays[index],array_id,attribSize,0,index); + index++; + } +} + +void GLEScontext::convertDirectVBO(GLint first,GLsizei count,GLenum array_id,GLESpointer* p) { + GLenum type = p->getType(); + if(isArrEnabled(array_id) && type == GL_FIXED) { + RangeList ranges; + RangeList conversions; + GLushort* indices = NULL; + int attribSize = p->getSize(); + int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; + unsigned int size = p->getStride()?p->getStride()*count:attribSize*count*sizeof(GLfixed); + char* data = (char*)p->getBufferData() + (first*stride); + + if(p->bufferNeedConversion()) { + directToBytesRanges(first,count,p,ranges); //converting indices range to buffer bytes ranges by offset + p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted + + if(conversions.size()) { // there are some elements to convert + indices = new GLushort[count]; + int nIndices = bytesRangesToIndices(conversions,p,indices); //converting bytes ranges by offset to indices in this array + convertIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,indices,stride,attribSize); + } + } + + sendArr(data,array_id,attribSize,p->getStride()); + if(indices) delete[] indices; + } +} + +void GLEScontext::convertIndirect(GLESFloatArrays& fArrs,GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p,unsigned int& index_out) { + GLenum type = p->getType(); + int maxElements = findMaxIndex(count,type,indices) + 1; + + if(isArrEnabled(array_id) && type == GL_FIXED) { + int attribSize = p->getSize(); + int size = attribSize * maxElements; + fArrs.arrays[index_out] = new GLfloat[size]; + int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; + + const char* data = (const char*)p->getArrayData(); + convertIndirectLoop(data,stride,fArrs.arrays[index_out],count,indices_type,indices,attribSize*sizeof(GLfloat),attribSize); + sendArr(fArrs.arrays[index_out],array_id,attribSize,0,index_out); + index_out++; + } +} + +void GLEScontext::convertIndirectVBO(GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p) { + GLenum type = p->getType(); + + if(isArrEnabled(array_id) && type == GL_FIXED) { + RangeList ranges; + RangeList conversions; + GLushort* conversionIndices = NULL; + int attribSize = p->getSize(); + int stride = p->getStride()?p->getStride():sizeof(GLfixed)*attribSize; + char* data = static_cast(p->getBufferData()); + if(p->bufferNeedConversion()) { + indirectToBytesRanges(indices,indices_type,count,p,ranges); //converting indices range to buffer bytes ranges by offset + p->getBufferConversions(ranges,conversions); // getting from the buffer the relevant ranges that still needs to be converted + if(conversions.size()) { // there are some elements to convert + conversionIndices = new GLushort[count]; + int nIndices = bytesRangesToIndices(conversions,p,conversionIndices); //converting bytes ranges by offset to indices in this array + convertIndirectLoop(data,stride,data,nIndices,GL_UNSIGNED_SHORT,conversionIndices,stride,attribSize); + } + } + sendArr(data,array_id,attribSize,p->getStride()); + if(conversionIndices) delete[] conversionIndices; + } +} + +void GLEScontext::chooseConvertMethod(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id, unsigned int& index) { + + bool vertexVBO = m_arrayBuffer!= 0; + if(direct) { + if(vertexVBO) { + convertDirectVBO(first,count,array_id,p); + } else { + convertDirect(fArrs,first,count,array_id,p,index); + } + } else { + if(vertexVBO) { + convertIndirectVBO(count,type,indices,array_id,p); + } else { + convertIndirect(fArrs,count,type,indices,array_id,p,index); + } + } +} + +void GLEScontext::convertArrs(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct) { + ArraysMap::iterator it; + unsigned int index = 0; + m_pointsIndex = -1; + + //going over all clients arrays Pointers + for ( it=m_map.begin() ; it != m_map.end(); it++ ) { + GLenum array_id = (*it).first; + GLESpointer* p = (*it).second; + + if(array_id == GL_TEXTURE_COORD_ARRAY) continue; //handling textures later + chooseConvertMethod(fArrs,first,count,type,indices,direct,p,array_id,index); + } + + unsigned int activeTexture = m_activeTexture + GL_TEXTURE0; + + s_lock.lock(); + int maxTexUnits = s_glSupport.maxTexUnits; + s_lock.unlock(); + + //converting all texture coords arrays + for(int i=0; i< maxTexUnits;i++) { + + unsigned int tex = GL_TEXTURE0+i; + setActiveTexture(tex); + s_glDispatch.glClientActiveTexture(tex); + + GLenum array_id = GL_TEXTURE_COORD_ARRAY; + GLESpointer* p = m_map[array_id]; + chooseConvertMethod(fArrs,first,count,type,indices,direct,p,array_id,index); + } + + setActiveTexture(activeTexture); + s_glDispatch.glClientActiveTexture(activeTexture); +} + + +static int findMaxIndex(GLsizei count,GLenum type,const GLvoid* indices) { + //finding max index + int max = 0; + if(type == GL_UNSIGNED_BYTE) { + GLubyte* b_indices =(GLubyte *)indices; + for(int i=0;i max) max = b_indices[i]; + } + } else { + GLushort* us_indices =(GLushort *)indices; + for(int i=0;i max) max = us_indices[i]; + } + } + return max; +} + +//TODO change it into merge sort to work in O(nlogn) +void sortPoints(GLfloat* sortedPoints,GLushort* sortedIndices,int size) { + + int flag = 1; // set flag to 1 to start first pass + for(int i = 1; (i <= size) && flag; i++) { + flag = 0; + for (int j=0; j < (size -1); j++) { + if (sortedPoints[j+1] < sortedPoints[j]) { + swap(sortedPoints[j],sortedPoints[j+1]); + swap(sortedIndices[j],sortedIndices[j+1]); + flag = 1; // indicates that a swap occurred. + } + } + } +} + + +void GLEScontext::drawPoints(PointSizeIndices* points) { + + GLushort* indices = NULL; + int last_size = 0; + + //drawing each group of vertices by the points size + for(PointSizeIndices::iterator it = points->begin();it != points->end(); it++) { + int count = (*it).second.size(); + int pointSize = (*it).first; + std::vector& arr = (*it).second; + + if(count > last_size) { + if(indices) delete [] indices; + indices = new GLushort[count]; + } + int i = 0 ; + for(std::vector::iterator it2 = arr.begin();it2 != arr.end();it2++) { + indices[i++] = (*it2); + } + s_glDispatch.glPointSize(pointSize); + s_glDispatch.glDrawElements(GL_POINTS,count,GL_UNSIGNED_SHORT,indices); + } + if(indices) delete [] indices; +} + +void GLEScontext::drawPointsData(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw) { + const GLfloat *pointsArr = NULL; + int stride = 0; //steps in GLfloats + + //choosing the right points sizes array source + if(m_pointsIndex >= 0) { //point size array was converted + pointsArr=fArrs.arrays[m_pointsIndex]; + stride = 1; + } else { + GLESpointer* p = m_map[GL_POINT_SIZE_ARRAY_OES]; + pointsArr = static_cast(isBindedBuffer(GL_ARRAY_BUFFER)?p->getBufferData():p->getArrayData()); + stride = p->getStride()?p->getStride()/sizeof(GLfloat):1; + } + + //filling arrays before sorting them + PointSizeIndices points; + if(isElemsDraw) { + for(int i=0; i< count; i++) { + GLushort index = (type == GL_UNSIGNED_SHORT? + static_cast(indices_in)[i]: + static_cast(indices_in)[i]); + points[pointsArr[index*stride]].push_back(index); + } + } else { + for(int i=0; i< count; i++) { + points[pointsArr[first+i*stride]].push_back(i+first); + } + } + drawPoints(&points); +} + +void GLEScontext::drawPointsArrs(GLESFloatArrays& arrs,GLint first,GLsizei count) { + drawPointsData(arrs,first,count,0,NULL,false); +} + +void GLEScontext::drawPointsElems(GLESFloatArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices_in) { + drawPointsData(arrs,0,count,type,indices_in,true); +} + +void GLEScontext:: genBuffers(GLsizei n,GLuint* buffers) +{ + int i = 0; + while(i < n) { + if(m_vbos.find(m_minAvailableBuffer) == m_vbos.end()) { + buffers[i++] = m_minAvailableBuffer;; + m_vbos[m_minAvailableBuffer] = new GLESbuffer(); + } + m_minAvailableBuffer++; + } +} + +void GLEScontext::deleteBuffers(GLsizei n,const GLuint* buffers) { + for(int i = 0; i < n ;i++) { + if(m_vbos.find(buffers[i]) != m_vbos.end()) { + if(m_vbos[buffers[i]]) delete m_vbos[buffers[i]]; + if(buffers[i] < m_minAvailableBuffer) m_minAvailableBuffer = buffers[i]; + m_vbos.erase(buffers[i]); + } + } +} + +void GLEScontext::bindBuffer(GLenum target,GLuint buffer) { + if(target == GL_ARRAY_BUFFER) { + m_arrayBuffer = buffer; + } else { + m_elementBuffer = buffer; + } + if(m_vbos.find(buffer) == m_vbos.end()) { // buffer name wasn't generated before + m_vbos[buffer] = new GLESbuffer(); + } +} + +//checks if there is buffer named "buffer" and if this buffer is binded +bool GLEScontext::isBuffer(GLuint buffer) { + if(m_vbos.find(buffer) != m_vbos.end()) { + if(m_elementBuffer == buffer || m_arrayBuffer == buffer) return true; + } + return false; +} + +//checks if any buffer is binded to target +bool GLEScontext::isBindedBuffer(GLenum target) { + if(target == GL_ARRAY_BUFFER) { + return m_arrayBuffer != 0; + } else { + return m_elementBuffer != 0; + } +} + +GLuint GLEScontext::getBuffer(GLenum target) { + return target == GL_ARRAY_BUFFER ? m_arrayBuffer:m_elementBuffer; +} + +GLvoid* GLEScontext::getBindedBuffer(GLenum target) { + GLuint bufferName = getBuffer(target); + if(!bufferName) return NULL; + return m_vbos[bufferName]->getData(); +} + +void GLEScontext::getBufferSize(GLenum target,GLint* param) { + GLuint bufferName = getBuffer(target); + *param = m_vbos[bufferName]->getSize(); +} + +void GLEScontext::getBufferUsage(GLenum target,GLint* param) { + GLuint bufferName = getBuffer(target); + *param = m_vbos[bufferName]->getUsage(); +} + +bool GLEScontext::setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage) { + GLuint bufferName = getBuffer(target); + if(!bufferName) return false; + return m_vbos[bufferName]->setBuffer(size,usage,data); +} + +bool GLEScontext::setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data) { + + GLuint bufferName = getBuffer(target); + if(!bufferName) return false; + return m_vbos[bufferName]->setSubBuffer(offset,size,data); +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h new file mode 100644 index 000000000..73226095d --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScontext.h @@ -0,0 +1,116 @@ +/* +* 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 GLES_CONTEX_H +#define GLES_CONTEX_H + +#include "GLDispatch.h" +#include "GLESpointer.h" +#include "GLESbuffer.h" +#include +#include +#include + +#define MAX_TEX_UNITS 8 + +typedef std::map ArraysMap; +typedef std::map BuffersMap; +typedef std::map > PointSizeIndices; + +struct GLESFloatArrays +{ + GLESFloatArrays(){}; + ~GLESFloatArrays(); + std::map arrays; +}; + + +struct GLsupport { + GLsupport():maxLights(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0){}; + int maxLights; + int maxClipPlane; + int maxTexUnits; + int maxTexSize; +}; + +class GLEScontext +{ +public: + void init(); + GLEScontext(); + GLenum getGLerror(); + + bool isArrEnabled(GLenum); + void enableArr(GLenum arr,bool enable); + void setGLerror(GLenum err); + void setActiveTexture(GLenum tex); + const GLvoid* setPointer(GLenum arrType,GLint size,GLenum type,GLsizei stride,const GLvoid* data); + const GLESpointer* getPointer(GLenum arrType); + + void convertArrs(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct); + void drawPointsArrs(GLESFloatArrays& arrs,GLint first,GLsizei count); + void drawPointsElems(GLESFloatArrays& arrs,GLsizei count,GLenum type,const GLvoid* indices); + + void genBuffers(GLsizei n,GLuint* buffers); + void deleteBuffers(GLsizei n,const GLuint* buffers); + void bindBuffer(GLenum target,GLuint buffer); + bool isBuffer(GLuint buffer); + bool isBindedBuffer(GLenum target); + GLvoid* getBindedBuffer(GLenum target); + void getBufferSize(GLenum target,GLint* param); + void getBufferUsage(GLenum target,GLint* param); + bool setBufferData(GLenum target,GLsizeiptr size,const GLvoid* data,GLenum usage); + bool setBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid* data); + + static GLDispatch& dispatcher(); + static int getMaxLights(){return s_glSupport.maxLights;} + static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;} + static int getMaxTexUnits(){return s_glSupport.maxTexUnits;} + static int getMaxTexSize(){return s_glSupport.maxTexSize;} + + ~GLEScontext(); +private: + + GLuint getBuffer(GLenum target); + void sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int pointsIndex = -1); + void drawPoints(PointSizeIndices* points); + void drawPointsData(GLESFloatArrays& arrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices_in,bool isElemsDraw); + + void chooseConvertMethod(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum type,const GLvoid* indices,bool direct,GLESpointer* p,GLenum array_id,unsigned int& index); + void convertDirect(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p,unsigned int& index); + void convertDirectVBO(GLint first,GLsizei count,GLenum array_id,GLESpointer* p); + void convertIndirect(GLESFloatArrays& fArrs,GLsizei count,GLenum type,const GLvoid* indices,GLenum array_id,GLESpointer* p,unsigned int& index); + void convertIndirectVBO(GLsizei count,GLenum indices_type,const GLvoid* indices,GLenum array_id,GLESpointer* p); + + static GLDispatch s_glDispatch; + static GLsupport s_glSupport; + static android::Mutex s_lock; + + ArraysMap m_map; + GLESpointer* m_texCoords; + GLenum m_glError; + unsigned int m_activeTexture; + unsigned int m_arrayBuffer; + unsigned int m_elementBuffer; + + unsigned int m_minAvailableBuffer; + BuffersMap m_vbos; + + int m_pointsIndex; + bool m_initialized; +}; + +#endif + diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp new file mode 100644 index 000000000..ab10a0419 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESimp.cpp @@ -0,0 +1,1128 @@ +/* +* 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 +#include "GLDispatch.h" +#include "GLEScontext.h" +#include "GLESvalidate.h" +#include "GLESutils.h" +#include "GLfixed_ops.h" +#include "TextureUtils.h" + +#include +#include +#include +#include + + +extern "C" { + +//decleration +static void initContext(GLEScontext* ctx); +static GLEScontext* createGLESContext(); +static void deleteGLESContext(GLEScontext* ctx); + +} + +static EGLiface* s_eglIface = NULL; +static GLESiface s_glesIface = { + createGLESContext:createGLESContext, + initContext :initContext, + deleteGLESContext:deleteGLESContext, + flush :glFlush, + finish :glFinish +}; + +extern "C" { + +static void initContext(GLEScontext* ctx) { + ctx->init(); +} +static GLEScontext* createGLESContext() { + GLEScontext* ctx = new GLEScontext(); + return ctx; +} + +static void deleteGLESContext(GLEScontext* ctx) { + if(ctx) delete ctx; +} + +GLESiface* __translator_getIfaces(EGLiface* eglIface){ + s_eglIface = eglIface; + return & s_glesIface; +} + +} + +#define GET_THREAD() \ + ThreadInfo* thrd = NULL; \ + if(s_eglIface) { \ + thrd = s_eglIface->getThreadInfo(); \ + } else { \ + fprintf(stderr,"Context wasn't initialized yet \n"); \ + } + + +#define GET_CTX() \ + GET_THREAD(); \ + if(!thrd) return; \ + GLEScontext *ctx = static_cast(thrd->glesContext); + +#define GET_CTX_RET(failure_ret) \ + GET_THREAD(); \ + if(!thrd) return failure_ret; \ + GLEScontext *ctx = static_cast(thrd->glesContext); + + +#define SET_ERROR_IF(condition,err) if((condition)) { \ + ctx->setGLerror(err); \ + return; \ + } + + +#define RET_AND_SET_ERROR_IF(condition,err,ret) if((condition)) { \ + ctx->setGLerror(err); \ + return ret; \ + } + + +GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) { + GET_CTX_RET(GL_FALSE) + return ctx->isBuffer(buffer); +} + +GL_API GLboolean GL_APIENTRY glIsEnabled( GLenum cap) { + GET_CTX_RET(GL_FALSE) + RET_AND_SET_ERROR_IF(!GLESvalidate::capability(cap,ctx->getMaxLights(),ctx->getMaxClipPlanes()),GL_INVALID_ENUM,GL_FALSE); + + if(cap == GL_POINT_SIZE_ARRAY_OES) return ctx->isArrEnabled(cap); + return ctx->dispatcher().glIsEnabled(cap); +} + +GL_API GLboolean GL_APIENTRY glIsTexture( GLuint texture) { + GET_CTX_RET(GL_FALSE) + return ctx->dispatcher().glIsTexture(texture); +} + +GL_API GLenum GL_APIENTRY glGetError(void) { + GET_CTX_RET(GL_NO_ERROR) + GLenum err = ctx->getGLerror(); + if(err != GL_NO_ERROR) { + ctx->setGLerror(GL_NO_ERROR); + return err; + } + + return ctx->dispatcher().glGetError(); +} + +GL_API const GLubyte * GL_APIENTRY glGetString( GLenum name) { + + GET_CTX_RET(NULL) + static GLubyte VENDOR[] = "Google"; + static GLubyte RENDERER[] = "OpenGL ES-CM 1.1"; + static GLubyte VERSION[] = "OpenGL ES-CM 1.1"; + static GLubyte EXTENSIONS[] = "GL_OES_compressed_paletted_texture " + "GL_OES_point_size_array"; + switch(name) { + case GL_VENDOR: + return VENDOR; + case GL_RENDERER: + return RENDERER; + case GL_VERSION: + return VERSION; + case GL_EXTENSIONS: + return EXTENSIONS; + default: + RET_AND_SET_ERROR_IF(true,GL_INVALID_ENUM,NULL); + } +} + +GL_API void GL_APIENTRY glActiveTexture( GLenum texture) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM); + ctx->dispatcher().glActiveTexture(texture); +} + +GL_API void GL_APIENTRY glAlphaFunc( GLenum func, GLclampf ref) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::alphaFunc(func),GL_INVALID_ENUM); + ctx->dispatcher().glAlphaFunc(func,ref); +} + + +GL_API void GL_APIENTRY glAlphaFuncx( GLenum func, GLclampx ref) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::alphaFunc(func),GL_INVALID_ENUM); + ctx->dispatcher().glAlphaFunc(func,X2F(ref)); +} + + +GL_API void GL_APIENTRY glBindBuffer( GLenum target, GLuint buffer) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM); + ctx->bindBuffer(target,buffer); +} + +GL_API void GL_APIENTRY glBindTexture( GLenum target, GLuint texture) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::textureTarget(target),GL_INVALID_ENUM) + ctx->dispatcher().glBindTexture(target,texture); +} + +GL_API void GL_APIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::blendSrc(sfactor) || !GLESvalidate::blendDst(dfactor),GL_INVALID_ENUM) + ctx->dispatcher().glBlendFunc(sfactor,dfactor); +} + +GL_API void GL_APIENTRY glBufferData( GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM); + SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION); + ctx->setBufferData(target,size,data,usage); +} + +GL_API void GL_APIENTRY glBufferSubData( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) { + GET_CTX() + SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION); + SET_ERROR_IF(!GLESvalidate::bufferTarget(target),GL_INVALID_ENUM); + SET_ERROR_IF(!ctx->setBufferSubData(target,offset,size,data),GL_INVALID_VALUE); +} + +GL_API void GL_APIENTRY glClear( GLbitfield mask) { + GET_CTX() + ctx->dispatcher().glClear(mask); +} + +GL_API void GL_APIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { + GET_CTX() + ctx->dispatcher().glClearColor(red,green,blue,alpha); +} + +GL_API void GL_APIENTRY glClearColorx( GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) { + GET_CTX() + ctx->dispatcher().glClearColor(X2F(red),X2F(green),X2F(blue),X2F(alpha)); +} + + +GL_API void GL_APIENTRY glClearDepthf( GLclampf depth) { + GET_CTX() + ctx->dispatcher().glClearDepthf(depth); +} + +GL_API void GL_APIENTRY glClearDepthx( GLclampx depth) { + GET_CTX() + ctx->dispatcher().glClearDepthf(X2F(depth)); +} + +GL_API void GL_APIENTRY glClearStencil( GLint s) { + GET_CTX() + ctx->dispatcher().glClearStencil(s); +} + +GL_API void GL_APIENTRY glClientActiveTexture( GLenum texture) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::textureEnum(texture,ctx->getMaxTexUnits()),GL_INVALID_ENUM); + ctx->setActiveTexture(texture); + ctx->dispatcher().glClientActiveTexture(texture); + +} + +GL_API void GL_APIENTRY glClipPlanef( GLenum plane, const GLfloat *equation) { + GET_CTX() + GLdouble tmpEquation[4]; + + for(int i = 0; i < 4; i++) { + tmpEquation[i] = static_cast(equation[i]); + } + ctx->dispatcher().glClipPlane(plane,tmpEquation); +} + +GL_API void GL_APIENTRY glClipPlanex( GLenum plane, const GLfixed *equation) { + GET_CTX() + GLdouble tmpEquation[4]; + for(int i = 0; i < 4; i++) { + tmpEquation[i] = X2D(equation[i]); + } + ctx->dispatcher().glClipPlane(plane,tmpEquation); +} + +GL_API void GL_APIENTRY glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { + GET_CTX() + ctx->dispatcher().glColor4f(red,green,blue,alpha); +} + +GL_API void GL_APIENTRY glColor4ub( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) { + GET_CTX() + ctx->dispatcher().glColor4ub(red,green,blue,alpha); +} + +GL_API void GL_APIENTRY glColor4x( GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) { + GET_CTX() + ctx->dispatcher().glColor4f(X2F(red),X2F(green),X2F(blue),X2F(alpha)); +} + +GL_API void GL_APIENTRY glColorMask( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + GET_CTX() + ctx->dispatcher().glColorMask(red,green,blue,alpha); +} + +GL_API void GL_APIENTRY glColorPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::colorPointerParams(size,stride),GL_INVALID_VALUE); + + const GLvoid* data = ctx->setPointer(GL_COLOR_ARRAY,size,type,stride,pointer); + if(type != GL_FIXED) ctx->dispatcher().glColorPointer(size,type,stride,data); +} + +GL_API void GL_APIENTRY glCompressedTexImage2D( GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) { + GET_CTX() + SET_ERROR_IF(!(GLESvalidate::texCompImgFrmt(internalformat) && GLESvalidate::textureTarget(target)),GL_INVALID_ENUM); + SET_ERROR_IF(level > log2(ctx->getMaxTexSize())|| border !=0 || level > 0 || !GLESvalidate::texImgDim(width,height,ctx->getMaxTexSize()+2),GL_INVALID_VALUE) + + int nMipmaps = -level + 1; + GLsizei tmpWidth = width; + GLsizei tmpHeight = height; + + for(int i = 0; i < nMipmaps ; i++) + { + GLenum uncompressedFrmt; + unsigned char* uncompressed = uncompressTexture(internalformat,uncompressedFrmt,width,height,imageSize,data,i); + ctx->dispatcher().glTexImage2D(target,i,uncompressedFrmt,width,height,border,uncompressedFrmt,GL_UNSIGNED_BYTE,uncompressed); + tmpWidth/=2; + tmpHeight/=2; + delete uncompressed; + } + ctx->dispatcher().glCompressedTexImage2D(target,level,internalformat,width,height,border,imageSize,data); +} + +GL_API void GL_APIENTRY glCompressedTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { + GET_CTX() + SET_ERROR_IF(!(GLESvalidate::texCompImgFrmt(format) && GLESvalidate::textureTarget(target)),GL_INVALID_ENUM); + SET_ERROR_IF(level < 0 || level > log2(ctx->getMaxTexSize()),GL_INVALID_VALUE) + + GLenum uncompressedFrmt; + unsigned char* uncompressed = uncompressTexture(format,uncompressedFrmt,width,height,imageSize,data,level); + ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,uncompressedFrmt,GL_UNSIGNED_BYTE,uncompressed); + delete uncompressed; +} + +GL_API void GL_APIENTRY glCopyTexImage2D( GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { + GET_CTX() + SET_ERROR_IF(!(GLESvalidate::pixelFrmt(internalformat) && GLESvalidate::textureTarget(target)),GL_INVALID_ENUM); + SET_ERROR_IF(border != 0,GL_INVALID_VALUE); + ctx->dispatcher().glCopyTexImage2D(target,level,internalformat,x,y,width,height,border); +} + +GL_API void GL_APIENTRY glCopyTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::textureTarget(target),GL_INVALID_ENUM); + ctx->dispatcher().glCopyTexSubImage2D(target,level,xoffset,yoffset,x,y,width,height); +} + +GL_API void GL_APIENTRY glCullFace( GLenum mode) { + GET_CTX() + ctx->dispatcher().glCullFace(mode); +} + +GL_API void GL_APIENTRY glDeleteBuffers( GLsizei n, const GLuint *buffers) { + GET_CTX() + SET_ERROR_IF(n<0,GL_INVALID_VALUE); + ctx->deleteBuffers(n,buffers); +} + +GL_API void GL_APIENTRY glDeleteTextures( GLsizei n, const GLuint *textures) { + GET_CTX() + ctx->dispatcher().glDeleteTextures(n,textures); +} + +GL_API void GL_APIENTRY glDepthFunc( GLenum func) { + GET_CTX() + ctx->dispatcher().glDepthFunc(func); +} + +GL_API void GL_APIENTRY glDepthMask( GLboolean flag) { + GET_CTX() + ctx->dispatcher().glDepthMask(flag); +} + +GL_API void GL_APIENTRY glDepthRangef( GLclampf zNear, GLclampf zFar) { + GET_CTX() + ctx->dispatcher().glDepthRange(zNear,zFar); +} + +GL_API void GL_APIENTRY glDepthRangex( GLclampx zNear, GLclampx zFar) { + GET_CTX() + ctx->dispatcher().glDepthRange(X2F(zNear),X2F(zFar)); +} + +GL_API void GL_APIENTRY glDisable( GLenum cap) { + GET_CTX() + ctx->dispatcher().glDisable(cap); +} + +GL_API void GL_APIENTRY glDisableClientState( GLenum array) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::supportedArrays(array),GL_INVALID_ENUM) + + ctx->enableArr(array,false); + if(array != GL_POINT_SIZE_ARRAY_OES) ctx->dispatcher().glDisableClientState(array); +} + + +GL_API void GL_APIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count) { + GET_CTX() + SET_ERROR_IF(count < 0,GL_INVALID_VALUE) + SET_ERROR_IF(!GLESvalidate::drawMode(mode),GL_INVALID_ENUM) + + if(!ctx->isArrEnabled(GL_VERTEX_ARRAY)) return; + + GLESFloatArrays tmpArrs; + ctx->convertArrs(tmpArrs,first,count,0,NULL,true); + if(mode != GL_POINTS || !ctx->isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){ + ctx->dispatcher().glDrawArrays(mode,first,count); + } + else{ + ctx->drawPointsArrs(tmpArrs,first,count); + } +} + +GL_API void GL_APIENTRY glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *elementsIndices) { + GET_CTX() + SET_ERROR_IF(count < 0,GL_INVALID_VALUE) + SET_ERROR_IF((!GLESvalidate::drawMode(mode) || !GLESvalidate::drawType(type)),GL_INVALID_ENUM) + const GLvoid* indices = elementsIndices; + GLESFloatArrays tmpArrs; + if(ctx->isBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)) { // if vbo is binded take the indices from the vbo + const unsigned char* buf = static_cast(ctx->getBindedBuffer(GL_ELEMENT_ARRAY_BUFFER)); + indices = buf+reinterpret_cast(elementsIndices); + } + + ctx->convertArrs(tmpArrs,0,count,type,indices,false); + if(mode != GL_POINTS || !ctx->isArrEnabled(GL_POINT_SIZE_ARRAY_OES)){ + ctx->dispatcher().glDrawElements(mode,count,type,indices); + } + else{ + ctx->drawPointsElems(tmpArrs,count,type,indices); + } +} + +GL_API void GL_APIENTRY glEnable( GLenum cap) { + GET_CTX() + ctx->dispatcher().glEnable(cap); +} + +GL_API void GL_APIENTRY glEnableClientState( GLenum array) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::supportedArrays(array),GL_INVALID_ENUM) + + ctx->enableArr(array,true); + if(array != GL_POINT_SIZE_ARRAY_OES) ctx->dispatcher().glEnableClientState(array); +} + +GL_API void GL_APIENTRY glFinish( void) { + GET_CTX() + ctx->dispatcher().glFinish(); +} + +GL_API void GL_APIENTRY glFlush( void) { + GET_CTX() + ctx->dispatcher().glFlush(); +} + +GL_API void GL_APIENTRY glFogf( GLenum pname, GLfloat param) { + GET_CTX() + ctx->dispatcher().glFogf(pname,param); +} + +GL_API void GL_APIENTRY glFogfv( GLenum pname, const GLfloat *params) { + GET_CTX() + ctx->dispatcher().glFogfv(pname,params); +} + +GL_API void GL_APIENTRY glFogx( GLenum pname, GLfixed param) { + GET_CTX() + ctx->dispatcher().glFogf(pname,(pname == GL_FOG_MODE)? static_cast(param):X2F(param)); +} + +GL_API void GL_APIENTRY glFogxv( GLenum pname, const GLfixed *params) { + GET_CTX() + if(pname == GL_FOG_MODE) { + GLfloat tmpParam = static_cast(params[0]); + ctx->dispatcher().glFogfv(pname,&tmpParam); + } else { + GLfloat tmpParams[4]; + for(int i=0; i< 4; i++) { + tmpParams[i] = X2F(params[i]); + } + ctx->dispatcher().glFogfv(pname,tmpParams); + } + +} + +GL_API void GL_APIENTRY glFrontFace( GLenum mode) { + GET_CTX() + ctx->dispatcher().glFrontFace(mode); +} + +GL_API void GL_APIENTRY glFrustumf( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) { + GET_CTX() + ctx->dispatcher().glFrustum(left,right,bottom,top,zNear,zFar); +} + +GL_API void GL_APIENTRY glFrustumx( GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) { + GET_CTX() + ctx->dispatcher().glFrustum(X2F(left),X2F(right),X2F(bottom),X2F(top),X2F(zNear),X2F(zFar)); +} + +GL_API void GL_APIENTRY glGenBuffers( GLsizei n, GLuint *buffers) { + GET_CTX() + SET_ERROR_IF(n<0,GL_INVALID_VALUE); + ctx->genBuffers(n,buffers); +} + +GL_API void GL_APIENTRY glGenTextures( GLsizei n, GLuint *textures) { + GET_CTX() + ctx->dispatcher().glGenTextures(n,textures); +} + +GL_API void GL_APIENTRY glGetBooleanv( GLenum pname, GLboolean *params) { + GET_CTX() + ctx->dispatcher().glGetBooleanv(pname,params); +} + +GL_API void GL_APIENTRY glGetBufferParameteriv( GLenum target, GLenum pname, GLint *params) { + GET_CTX() + SET_ERROR_IF(!(GLESvalidate::bufferTarget(target) && GLESvalidate::bufferParam(pname)),GL_INVALID_ENUM); + SET_ERROR_IF(!ctx->isBindedBuffer(target),GL_INVALID_OPERATION); + bool ret = true; + switch(pname) { + case GL_BUFFER_SIZE: + ctx->getBufferSize(target,params); + break; + case GL_BUFFER_USAGE: + ctx->getBufferUsage(target,params); + break; + } + +} + +GL_API void GL_APIENTRY glGetClipPlanef( GLenum pname, GLfloat eqn[4]) { + GET_CTX() + GLdouble tmpEqn[4]; + + ctx->dispatcher().glGetClipPlane(pname,tmpEqn); + for(int i =0 ;i < 4; i++){ + eqn[i] = static_cast(tmpEqn[i]); + } +} + +GL_API void GL_APIENTRY glGetClipPlanex( GLenum pname, GLfixed eqn[4]) { + GET_CTX() + GLdouble tmpEqn[4]; + + ctx->dispatcher().glGetClipPlane(pname,tmpEqn); + for(int i =0 ;i < 4; i++){ + eqn[i] = F2X(tmpEqn[i]); + } +} + +GL_API void GL_APIENTRY glGetFixedv( GLenum pname, GLfixed *params) { + GET_CTX() + size_t nParams = glParamSize(pname); + GLfloat fParams[16]; + ctx->dispatcher().glGetFloatv(pname,fParams); + for(size_t i =0 ; i < nParams;i++) { + params[i] = F2X(fParams[i]); + } +} + +GL_API void GL_APIENTRY glGetFloatv( GLenum pname, GLfloat *params) { + GET_CTX() + ctx->dispatcher().glGetFloatv(pname,params); +} + +GL_API void GL_APIENTRY glGetIntegerv( GLenum pname, GLint *params) { + GET_CTX() + ctx->dispatcher().glGetIntegerv(pname,params); +} + +GL_API void GL_APIENTRY glGetLightfv( GLenum light, GLenum pname, GLfloat *params) { + GET_CTX() + ctx->dispatcher().glGetLightfv(light,pname,params); +} + +GL_API void GL_APIENTRY glGetLightxv( GLenum light, GLenum pname, GLfixed *params) { + GET_CTX() + GLfloat tmpParams[4]; + + ctx->dispatcher().glGetLightfv(light,pname,tmpParams); + switch (pname){ + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_POSITION: + params[3] = F2X(tmpParams[3]); + case GL_SPOT_DIRECTION: + params[2] = F2X(tmpParams[2]); + params[1] = F2X(tmpParams[1]); + break; + default:{ + ctx->setGLerror(GL_INVALID_ENUM); + return; + } + + } + params[0] = F2X(tmpParams[0]); +} + +GL_API void GL_APIENTRY glGetMaterialfv( GLenum face, GLenum pname, GLfloat *params) { + GET_CTX() + ctx->dispatcher().glGetMaterialfv(face,pname,params); +} + +GL_API void GL_APIENTRY glGetMaterialxv( GLenum face, GLenum pname, GLfixed *params) { + GET_CTX() + GLfloat tmpParams[4]; + ctx->dispatcher().glGetMaterialfv(face,pname,tmpParams); + switch(pname){ + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_EMISSION: + case GL_AMBIENT_AND_DIFFUSE: + params[3] = tmpParams[3]; + params[2] = tmpParams[2]; + params[1] = tmpParams[1]; + case GL_SHININESS: + params[0] = tmpParams[0]; + default:{ + ctx->setGLerror(GL_INVALID_ENUM); + return; + } + } +} + +GL_API void GL_APIENTRY glGetPointerv( GLenum pname, void **params) { + GET_CTX() + const GLESpointer* p = ctx->getPointer(pname); + if(p) { + *params = const_cast( p->getArrayData()); + } else { + ctx->setGLerror(GL_INVALID_ENUM); + } + +} + +GL_API void GL_APIENTRY glGetTexEnvfv( GLenum env, GLenum pname, GLfloat *params) { + GET_CTX() + ctx->dispatcher().glGetTexEnvfv(env,pname,params); +} + +GL_API void GL_APIENTRY glGetTexEnviv( GLenum env, GLenum pname, GLint *params) { + GET_CTX() + ctx->dispatcher().glGetTexEnviv(env,pname,params); +} + +GL_API void GL_APIENTRY glGetTexEnvxv( GLenum env, GLenum pname, GLfixed *params) { + GET_CTX() + GLfloat tmpParams[4]; + + ctx->dispatcher().glGetTexEnvfv(env,pname,tmpParams); + if(pname == GL_TEXTURE_ENV_MODE) { + params[0] = static_cast(tmpParams[0]); + } else { + for(int i=0 ; i < 4 ; i++) + params[i] = F2X(tmpParams[i]); + } +} + +GL_API void GL_APIENTRY glGetTexParameterfv( GLenum target, GLenum pname, GLfloat *params) { + GET_CTX() + ctx->dispatcher().glGetTexParameterfv(target,pname,params); +} + +GL_API void GL_APIENTRY glGetTexParameteriv( GLenum target, GLenum pname, GLint *params) { + GET_CTX() + ctx->dispatcher().glGetTexParameteriv(target,pname,params); +} + +GL_API void GL_APIENTRY glGetTexParameterxv( GLenum target, GLenum pname, GLfixed *params) { + GET_CTX() + GLfloat tmpParam; + ctx->dispatcher().glGetTexParameterfv(target,pname,&tmpParam); + params[0] = static_cast(tmpParam); +} + +GL_API void GL_APIENTRY glHint( GLenum target, GLenum mode) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::hintTargetMode(target,mode),GL_INVALID_ENUM); + ctx->dispatcher().glHint(target,mode); +} + +GL_API void GL_APIENTRY glLightModelf( GLenum pname, GLfloat param) { + GET_CTX() + ctx->dispatcher().glLightModelf(pname,param); +} + +GL_API void GL_APIENTRY glLightModelfv( GLenum pname, const GLfloat *params) { + GET_CTX() + ctx->dispatcher().glLightModelfv(pname,params); +} + +GL_API void GL_APIENTRY glLightModelx( GLenum pname, GLfixed param) { + GET_CTX() + GLfloat tmpParam = static_cast(param); + ctx->dispatcher().glLightModelf(pname,tmpParam); +} + +GL_API void GL_APIENTRY glLightModelxv( GLenum pname, const GLfixed *params) { + GET_CTX() + GLfloat tmpParams[4]; + if(pname == GL_LIGHT_MODEL_TWO_SIDE) { + tmpParams[0] = X2F(params[0]); + } else if (pname == GL_LIGHT_MODEL_AMBIENT) { + for(int i=0;i<4;i++) { + tmpParams[i] = X2F(params[i]); + } + } + + ctx->dispatcher().glLightModelfv(pname,tmpParams); +} + +GL_API void GL_APIENTRY glLightf( GLenum light, GLenum pname, GLfloat param) { + GET_CTX() + ctx->dispatcher().glLightf(light,pname,param); +} + +GL_API void GL_APIENTRY glLightfv( GLenum light, GLenum pname, const GLfloat *params) { + GET_CTX() + ctx->dispatcher().glLightfv(light,pname,params); +} + +GL_API void GL_APIENTRY glLightx( GLenum light, GLenum pname, GLfixed param) { + GET_CTX() + ctx->dispatcher().glLightf(light,pname,X2F(param)); +} + +GL_API void GL_APIENTRY glLightxv( GLenum light, GLenum pname, const GLfixed *params) { + GET_CTX() + GLfloat tmpParams[4]; + + switch (pname) { + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_POSITION: + tmpParams[3] = X2F(params[3]); + case GL_SPOT_DIRECTION: + tmpParams[2] = X2F(params[2]); + tmpParams[1] = X2F(params[1]); + break; + default: { + ctx->setGLerror(GL_INVALID_ENUM); + return; + } + } + tmpParams[0] = X2F(params[0]); + ctx->dispatcher().glLightfv(light,pname,tmpParams); +} + +GL_API void GL_APIENTRY glLineWidth( GLfloat width) { + GET_CTX() + ctx->dispatcher().glLineWidth(width); +} + +GL_API void GL_APIENTRY glLineWidthx( GLfixed width) { + GET_CTX() + ctx->dispatcher().glLineWidth(X2F(width)); +} + +GL_API void GL_APIENTRY glLoadIdentity( void) { + GET_CTX() + ctx->dispatcher().glLoadIdentity(); +} + +GL_API void GL_APIENTRY glLoadMatrixf( const GLfloat *m) { + GET_CTX() + ctx->dispatcher().glLoadMatrixf(m); +} + +GL_API void GL_APIENTRY glLoadMatrixx( const GLfixed *m) { + GET_CTX() + GLfloat mat[16]; + for(int i=0; i< 16 ; i++) { + mat[i] = X2F(m[i]); + } + ctx->dispatcher().glLoadMatrixf(mat); +} + +GL_API void GL_APIENTRY glLogicOp( GLenum opcode) { + GET_CTX() + ctx->dispatcher().glLogicOp(opcode); +} + +GL_API void GL_APIENTRY glMaterialf( GLenum face, GLenum pname, GLfloat param) { + GET_CTX() + ctx->dispatcher().glMaterialf(face,pname,param); +} + +GL_API void GL_APIENTRY glMaterialfv( GLenum face, GLenum pname, const GLfloat *params) { + GET_CTX() + ctx->dispatcher().glMaterialfv(face,pname,params); +} + +GL_API void GL_APIENTRY glMaterialx( GLenum face, GLenum pname, GLfixed param) { + GET_CTX() + ctx->dispatcher().glMaterialf(face,pname,X2F(param)); +} + +GL_API void GL_APIENTRY glMaterialxv( GLenum face, GLenum pname, const GLfixed *params) { + GET_CTX() + GLfloat tmpParams[4]; + + for(int i=0; i< 4; i++) { + tmpParams[i] = X2F(params[i]); + } + ctx->dispatcher().glMaterialfv(face,pname,tmpParams); +} + +GL_API void GL_APIENTRY glMatrixMode( GLenum mode) { + GET_CTX() + ctx->dispatcher().glMatrixMode(mode); +} + +GL_API void GL_APIENTRY glMultMatrixf( const GLfloat *m) { + GET_CTX() + ctx->dispatcher().glMultMatrixf(m); +} + +GL_API void GL_APIENTRY glMultMatrixx( const GLfixed *m) { + GET_CTX() + GLfloat mat[16]; + for(int i=0; i< 16 ; i++) { + mat[i] = X2F(m[i]); + } + ctx->dispatcher().glMultMatrixf(mat); +} + +GL_API void GL_APIENTRY glMultiTexCoord4f( GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::textureEnum(target,ctx->getMaxTexUnits()),GL_INVALID_ENUM); + ctx->dispatcher().glMultiTexCoord4f(target,s,t,r,q); +} + +GL_API void GL_APIENTRY glMultiTexCoord4x( GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::textureEnum(target,ctx->getMaxTexUnits()),GL_INVALID_ENUM); + ctx->dispatcher().glMultiTexCoord4f(target,X2F(s),X2F(t),X2F(r),X2F(q)); +} + +GL_API void GL_APIENTRY glNormal3f( GLfloat nx, GLfloat ny, GLfloat nz) { + GET_CTX() + ctx->dispatcher().glNormal3f(nx,ny,nz); +} + +GL_API void GL_APIENTRY glNormal3x( GLfixed nx, GLfixed ny, GLfixed nz) { + GET_CTX() + ctx->dispatcher().glNormal3f(X2F(nx),X2F(ny),X2F(nz)); +} + +GL_API void GL_APIENTRY glNormalPointer( GLenum type, GLsizei stride, const GLvoid *pointer) { + GET_CTX() + SET_ERROR_IF(stride < 0,GL_INVALID_VALUE); + const GLvoid* data = ctx->setPointer(GL_NORMAL_ARRAY,3,type,stride,pointer);//3 normal verctor + if(type != GL_FIXED) ctx->dispatcher().glNormalPointer(type,stride,data); +} + +GL_API void GL_APIENTRY glOrthof( GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar) { + GET_CTX() + ctx->dispatcher().glOrtho(left,right,bottom,top,zNear,zFar); +} + +GL_API void GL_APIENTRY glOrthox( GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar) { + GET_CTX() + ctx->dispatcher().glOrtho(X2F(left),X2F(right),X2F(bottom),X2F(top),X2F(zNear),X2F(zFar)); +} + +GL_API void GL_APIENTRY glPixelStorei( GLenum pname, GLint param) { + GET_CTX() + ctx->dispatcher().glPixelStorei(pname,param); +} + +GL_API void GL_APIENTRY glPointParameterf( GLenum pname, GLfloat param) { + GET_CTX() + ctx->dispatcher().glPointParameterf(pname,param); +} + +GL_API void GL_APIENTRY glPointParameterfv( GLenum pname, const GLfloat *params) { + GET_CTX() + ctx->dispatcher().glPointParameterfv(pname,params); +} + +GL_API void GL_APIENTRY glPointParameterx( GLenum pname, GLfixed param) +{ + GET_CTX() + ctx->dispatcher().glPointParameterf(pname,X2F(param)); +} + +GL_API void GL_APIENTRY glPointParameterxv( GLenum pname, const GLfixed *params) { + GET_CTX() + GLfloat tmpParams[3]; + int i = 0; + + do { + tmpParams[i] = X2F(params[i]); + i++; + }while(pname != GL_POINT_DISTANCE_ATTENUATION); + ctx->dispatcher().glPointParameterfv(pname,tmpParams); +} + +GL_API void GL_APIENTRY glPointSize( GLfloat size) { + GET_CTX() + ctx->dispatcher().glPointSize(size); +} + +GL_API void GL_APIENTRY glPointSizePointerOES( GLenum type, GLsizei stride, const GLvoid *pointer) { + GET_CTX() + SET_ERROR_IF(stride < 0,GL_INVALID_VALUE); + ctx->setPointer(GL_POINT_SIZE_ARRAY_OES,1,type,stride,pointer); +} + +GL_API void GL_APIENTRY glPointSizex( GLfixed size) { + GET_CTX() + ctx->dispatcher().glPointSize(X2F(size)); +} + +GL_API void GL_APIENTRY glPolygonOffset( GLfloat factor, GLfloat units) { + GET_CTX() + ctx->dispatcher().glPolygonOffset(factor,units); +} + +GL_API void GL_APIENTRY glPolygonOffsetx( GLfixed factor, GLfixed units) { + GET_CTX() + ctx->dispatcher().glPolygonOffset(X2F(factor),X2F(units)); +} + +GL_API void GL_APIENTRY glPopMatrix(void) { + GET_CTX() + ctx->dispatcher().glPopMatrix(); +} + +GL_API void GL_APIENTRY glPushMatrix(void) { + GET_CTX() + ctx->dispatcher().glPushMatrix(); +} + +GL_API void GL_APIENTRY glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) { + GET_CTX() + SET_ERROR_IF(!(GLESvalidate::pixelFrmt(format) && GLESvalidate::pixelType(type)),GL_INVALID_ENUM); + SET_ERROR_IF(!(GLESvalidate::pixelOp(format,type)),GL_INVALID_OPERATION); + + ctx->dispatcher().glReadPixels(x,y,width,height,format,type,pixels); +} + +GL_API void GL_APIENTRY glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + GET_CTX() + ctx->dispatcher().glRotatef(angle,x,y,z); +} + +GL_API void GL_APIENTRY glRotatex( GLfixed angle, GLfixed x, GLfixed y, GLfixed z) { + GET_CTX() + ctx->dispatcher().glRotatef(angle,X2F(x),X2F(y),X2F(z)); +} + +GL_API void GL_APIENTRY glSampleCoverage( GLclampf value, GLboolean invert) { + GET_CTX() + ctx->dispatcher().glSampleCoverage(value,invert); +} + +GL_API void GL_APIENTRY glSampleCoveragex( GLclampx value, GLboolean invert) { + GET_CTX() + ctx->dispatcher().glSampleCoverage(X2F(value),invert); +} + +GL_API void GL_APIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z) { + GET_CTX() + ctx->dispatcher().glScalef(x,y,z); +} + +GL_API void GL_APIENTRY glScalex( GLfixed x, GLfixed y, GLfixed z) { + GET_CTX() + ctx->dispatcher().glScalef(X2F(x),X2F(y),X2F(z)); +} + +GL_API void GL_APIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height) { + GET_CTX() + ctx->dispatcher().glScissor(x,y,width,height); +} + +GL_API void GL_APIENTRY glShadeModel( GLenum mode) { + GET_CTX() + ctx->dispatcher().glShadeModel(mode); +} + +GL_API void GL_APIENTRY glStencilFunc( GLenum func, GLint ref, GLuint mask) { + GET_CTX() + ctx->dispatcher().glStencilFunc(func,ref,mask); +} + +GL_API void GL_APIENTRY glStencilMask( GLuint mask) { + GET_CTX() + ctx->dispatcher().glStencilMask(mask); +} + +GL_API void GL_APIENTRY glStencilOp( GLenum fail, GLenum zfail, GLenum zpass) { + GET_CTX() + ctx->dispatcher().glStencilOp(fail,zfail,zpass); +} + +GL_API void GL_APIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texCoordPointerParams(size,stride),GL_INVALID_VALUE); + + const GLvoid* data = ctx->setPointer(GL_TEXTURE_COORD_ARRAY,size,type,stride,pointer); + if(type != GL_FIXED) ctx->dispatcher().glTexCoordPointer(size,type,stride,data); +} + +GL_API void GL_APIENTRY glTexEnvf( GLenum target, GLenum pname, GLfloat param) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexEnvf(target,pname,param); +} + +GL_API void GL_APIENTRY glTexEnvfv( GLenum target, GLenum pname, const GLfloat *params) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexEnvfv(target,pname,params); +} + +GL_API void GL_APIENTRY glTexEnvi( GLenum target, GLenum pname, GLint param) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexEnvi(target,pname,param); +} + +GL_API void GL_APIENTRY glTexEnviv( GLenum target, GLenum pname, const GLint *params) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexEnviv(target,pname,params); +} + +GL_API void GL_APIENTRY glTexEnvx( GLenum target, GLenum pname, GLfixed param) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM); + GLfloat tmpParam = static_cast(param); + ctx->dispatcher().glTexEnvf(target,pname,tmpParam); +} + +GL_API void GL_APIENTRY glTexEnvxv( GLenum target, GLenum pname, const GLfixed *params) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texEnv(target,pname),GL_INVALID_ENUM); + + GLfloat tmpParams[4]; + if(pname == GL_TEXTURE_ENV_COLOR) { + for(int i =0;i<4;i++) { + tmpParams[i] = X2F(params[i]); + } + } else { + tmpParams[0] = static_cast(params[0]); + } + ctx->dispatcher().glTexEnvfv(target,pname,tmpParams); +} + +GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) { + GET_CTX() + + SET_ERROR_IF(!(GLESvalidate::textureTarget(target) && + GLESvalidate::pixelFrmt(internalformat) && + GLESvalidate::pixelFrmt(format)&& + GLESvalidate::pixelType(type)),GL_INVALID_ENUM); + + //SET_ERROR_IF(level < 0 || border !=0 || level > log2(ctx->getMaxTexSize()) || !GLESvalidate::texImgDim(width,height,ctx->getMaxTexSize()),GL_INVALID_VALUE); + SET_ERROR_IF(!(GLESvalidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION); + + ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels); +} + +GL_API void GL_APIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexParameterf(target,pname,param); +} + +GL_API void GL_APIENTRY glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexParameterfv(target,pname,params); +} + +GL_API void GL_APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexParameteri(target,pname,param); +} + +GL_API void GL_APIENTRY glTexParameteriv( GLenum target, GLenum pname, const GLint *params) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexParameteriv(target,pname,params); +} + +GL_API void GL_APIENTRY glTexParameterx( GLenum target, GLenum pname, GLfixed param) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM); + ctx->dispatcher().glTexParameterf(target,pname,static_cast(param)); +} + +GL_API void GL_APIENTRY glTexParameterxv( GLenum target, GLenum pname, const GLfixed *params) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::texParams(target,pname),GL_INVALID_ENUM); + GLfloat param = static_cast(params[0]); + ctx->dispatcher().glTexParameterfv(target,pname,¶m); +} + +GL_API void GL_APIENTRY glTexSubImage2D( GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) { + GET_CTX() + SET_ERROR_IF(!(GLESvalidate::textureTarget(target) && + GLESvalidate::pixelFrmt(format)&& + GLESvalidate::pixelType(type)),GL_INVALID_ENUM); + SET_ERROR_IF(!GLESvalidate::pixelOp(format,type),GL_INVALID_OPERATION); + + ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels); +} + +GL_API void GL_APIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z) { + GET_CTX() + ctx->dispatcher().glTranslatef(x,y,z); +} + +GL_API void GL_APIENTRY glTranslatex( GLfixed x, GLfixed y, GLfixed z) { + GET_CTX() + ctx->dispatcher().glTranslatef(x,y,z); +} + +GL_API void GL_APIENTRY glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { + GET_CTX() + SET_ERROR_IF(!GLESvalidate::vertexPointerParams(size,stride),GL_INVALID_VALUE); + + const GLvoid* data = ctx->setPointer(GL_VERTEX_ARRAY,size,type,stride,pointer); + if(type != GL_FIXED) ctx->dispatcher().glVertexPointer(size,type,stride,data); +} + +GL_API void GL_APIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei height) { + GET_CTX() + ctx->dispatcher().glViewport(x,y,width,height); +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.cpp new file mode 100644 index 000000000..55b4dcdfa --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.cpp @@ -0,0 +1,75 @@ +/* +* 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 "GLESpointer.h" +#include + +GLESpointer::GLESpointer():m_size(0),m_type(0),m_stride(0),m_enabled(false),m_data(NULL),m_buffer(NULL),m_buffOffset(0){}; + + +GLenum GLESpointer:: getType() const { + return m_type; +} + +GLint GLESpointer::getSize() const { + return m_size; +} + +GLsizei GLESpointer::getStride() const { + return m_stride; +} + +const GLvoid* GLESpointer::getArrayData() const { + return m_data; +} + +GLvoid* GLESpointer::getBufferData() const { + + return static_cast(m_buffer->getData()) + m_buffOffset; +} + +unsigned int GLESpointer::getBufferOffset() const { + + return m_buffOffset; +} + +bool GLESpointer::isEnable() const { + return m_enabled; +} + +void GLESpointer::enable(bool b) { + m_enabled = b; +} + +void GLESpointer::setArray(GLint size,GLenum type,GLsizei stride,const GLvoid* data) { + m_size = size; + m_type = type; + m_stride = stride; + m_data = data; + m_buffer = NULL; +} + +void GLESpointer::setBuffer(GLint size,GLenum type,GLsizei stride,GLESbuffer* buf,int offset) { + m_size = size; + m_type = type; + m_stride = stride; + m_data = NULL; + m_buffer = buf; + m_buffOffset = offset; +} + +void GLESpointer::getBufferConversions(const RangeList& rl,RangeList& rlOut) { + m_buffer->getConversions(rl,rlOut); +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.h new file mode 100644 index 000000000..9d897e427 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESpointer.h @@ -0,0 +1,49 @@ +/* +* 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 GLES_POINTER_H +#define GLES_POINTER_H + +#include +#include "GLESbuffer.h" + +class GLESpointer +{ + +public: + GLESpointer(); + GLenum getType() const; + GLint getSize() const; + GLsizei getStride() const; + const GLvoid* getArrayData() const; + GLvoid* getBufferData() const; + unsigned int getBufferOffset() const; + void getBufferConversions(const RangeList& rl,RangeList& rlOut); + bool bufferNeedConversion(){ return !m_buffer->fullyConverted();} + void setArray (GLint size,GLenum type,GLsizei stride,const GLvoid* data); + void setBuffer(GLint size,GLenum type,GLsizei stride,GLESbuffer* buf,int offset); + bool isEnable() const; + void enable(bool b); + +private: + GLint m_size; + GLenum m_type; + GLsizei m_stride; + bool m_enabled; + const GLvoid* m_data; + GLESbuffer* m_buffer; + unsigned int m_buffOffset; +}; +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.cpp new file mode 100644 index 000000000..08c2d6a8c --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.cpp @@ -0,0 +1,101 @@ +/* +* 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 "GLESutils.h" + + +size_t glParamSize(GLenum param) +{ + size_t s = 0; + + switch(param) + { + case GL_MAX_TEXTURE_SIZE: + //case GL_TEXTURE_GEN_MODE_OES: + case GL_TEXTURE_ENV_MODE: + case GL_FOG_MODE: + case GL_FOG_DENSITY: + case GL_FOG_START: + case GL_FOG_END: + case GL_SPOT_EXPONENT: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + case GL_SHININESS: + case GL_LIGHT_MODEL_TWO_SIDE: + case GL_POINT_SIZE: + case GL_POINT_SIZE_MIN: + case GL_POINT_SIZE_MAX: + case GL_POINT_FADE_THRESHOLD_SIZE: + case GL_CULL_FACE_MODE: + case GL_FRONT_FACE: + case GL_SHADE_MODEL: + case GL_DEPTH_WRITEMASK: + case GL_DEPTH_CLEAR_VALUE: + case GL_STENCIL_FAIL: + case GL_STENCIL_PASS_DEPTH_FAIL: + case GL_STENCIL_PASS_DEPTH_PASS: + case GL_STENCIL_REF: + case GL_STENCIL_WRITEMASK: + case GL_MATRIX_MODE: + case GL_MODELVIEW_STACK_DEPTH: + case GL_PROJECTION_STACK_DEPTH: + case GL_TEXTURE_STACK_DEPTH: + case GL_ALPHA_TEST_FUNC: + case GL_ALPHA_TEST_REF: + case GL_BLEND_DST: + case GL_BLEND_SRC: + case GL_LOGIC_OP_MODE: + case GL_SCISSOR_TEST: + case GL_MAX_TEXTURE_UNITS: + s = 1; + break; + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_ALIASED_POINT_SIZE_RANGE: + case GL_DEPTH_RANGE: + case GL_MAX_VIEWPORT_DIMS: + case GL_SMOOTH_POINT_SIZE_RANGE: + case GL_SMOOTH_LINE_WIDTH_RANGE: + s= 2; + break; + case GL_SPOT_DIRECTION: + case GL_POINT_DISTANCE_ATTENUATION: + case GL_CURRENT_NORMAL: + s = 3; + break; + case GL_CURRENT_TEXTURE_COORDS: + case GL_CURRENT_COLOR: + case GL_FOG_COLOR: + case GL_AMBIENT: + case GL_DIFFUSE: + case GL_SPECULAR: + case GL_EMISSION: + case GL_POSITION: + case GL_LIGHT_MODEL_AMBIENT: + case GL_TEXTURE_ENV_COLOR: + case GL_SCISSOR_BOX: + case GL_VIEWPORT: + //case GL_TEXTURE_CROP_RECT_OES: + s = 4; + break; + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: + case GL_TEXTURE_MATRIX: + s = 16; + default: + s = 1; // assume 1 + } + return s; +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.h new file mode 100644 index 000000000..38ad6bc65 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESutils.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 GLES_UTILS_H +#define GLES_UTILS_H +#include +#include + +size_t glParamSize(GLenum param); +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.cpp new file mode 100644 index 000000000..6bc211f4a --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.cpp @@ -0,0 +1,281 @@ +/* +* 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 "GLESvalidate.h" +#include + +bool GLESvalidate::textureEnum(GLenum e,unsigned int maxTex) { + return e >= GL_TEXTURE0 && e <= (GL_TEXTURE0 + maxTex); +} + +bool GLESvalidate::lightEnum(GLenum e,unsigned int maxLights) { + return e >=GL_LIGHT0 && e <= (GL_LIGHT0+maxLights); +} + +bool GLESvalidate::clipPlaneEnum(GLenum e,unsigned int maxClipPlanes) { + return e >=GL_CLIP_PLANE0 && e <= (GL_CLIP_PLANE0+maxClipPlanes); +} + +bool GLESvalidate::textureTarget(GLenum target) { + return target == GL_TEXTURE_2D; +} + + +bool GLESvalidate::alphaFunc(GLenum f) { + switch(f) { + case GL_NEVER: + case GL_LESS: + case GL_EQUAL: + case GL_LEQUAL: + case GL_GREATER: + case GL_NOTEQUAL: + case GL_GEQUAL: + case GL_ALWAYS: + return true; + } + return false; +} + +bool GLESvalidate::blendSrc(GLenum s) { + switch(s) { + case GL_ZERO: + case GL_ONE: + case GL_DST_COLOR: + case GL_ONE_MINUS_DST_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + return true; + } + return false; +} + +bool GLESvalidate::blendDst(GLenum d) { + switch(d) { + case GL_ZERO: + case GL_ONE: + case GL_SRC_COLOR: + case GL_ONE_MINUS_SRC_COLOR: + case GL_SRC_ALPHA: + case GL_ONE_MINUS_SRC_ALPHA: + case GL_DST_ALPHA: + case GL_ONE_MINUS_DST_ALPHA: + return true; + } + return false; +} + +bool GLESvalidate::vertexPointerParams(GLint size,GLsizei stride) { + return ((size >=2) && (size <= 4)) && (stride >=0) ; +} + +bool GLESvalidate::colorPointerParams(GLint size,GLsizei stride) { + return ((size >=3) && (size <= 4)) && (stride >=0) ; +} + +bool GLESvalidate::texCoordPointerParams(GLint size,GLsizei stride) { + return ((size >=1) && (size <= 4)) && (stride >=0) ; +} + +bool GLESvalidate::supportedArrays(GLenum arr) { + switch(arr) { + case GL_COLOR_ARRAY: + case GL_NORMAL_ARRAY: + case GL_POINT_SIZE_ARRAY_OES: + case GL_TEXTURE_COORD_ARRAY: + case GL_VERTEX_ARRAY: + return true; + } + return false; +} + +bool GLESvalidate::drawMode(GLenum mode) { + switch(mode) { + case GL_POINTS: + case GL_LINE_STRIP: + case GL_LINE_LOOP: + case GL_LINES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_TRIANGLES: + return true; + } + return false; +} + +bool GLESvalidate::drawType(GLenum mode) { + return mode == GL_UNSIGNED_BYTE || mode == GL_UNSIGNED_SHORT; +} + +bool GLESvalidate::hintTargetMode(GLenum target,GLenum mode) { + switch(target) { + case GL_FOG_HINT: + case GL_GENERATE_MIPMAP_HINT: + case GL_LINE_SMOOTH_HINT: + case GL_PERSPECTIVE_CORRECTION_HINT: + case GL_POINT_SMOOTH_HINT: + break; + default: return false; + } + switch(mode) { + case GL_FASTEST: + case GL_NICEST: + case GL_DONT_CARE: + break; + default: return false; + } + return true; +} + +bool GLESvalidate::texParams(GLenum target,GLenum pname) { + switch(pname) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + break; + default: + return false; + } + return target == GL_TEXTURE_2D; +} + +bool GLESvalidate::texEnv(GLenum target,GLenum pname) { + switch(pname) { + case GL_TEXTURE_ENV_MODE: + case GL_COMBINE_RGB: + case GL_COMBINE_ALPHA: + case GL_SRC0_RGB: + case GL_SRC1_RGB: + case GL_SRC2_RGB: + case GL_SRC0_ALPHA: + case GL_SRC1_ALPHA: + case GL_SRC2_ALPHA: + case GL_OPERAND0_RGB: + case GL_OPERAND1_RGB: + case GL_OPERAND2_RGB: + case GL_OPERAND0_ALPHA: + case GL_OPERAND1_ALPHA: + case GL_OPERAND2_ALPHA: + case GL_RGB_SCALE: + case GL_ALPHA_SCALE: + case GL_COORD_REPLACE_OES: + break; + default: + return false; + } + return (target == GL_TEXTURE_ENV || target == GL_POINT_SPRITE_OES); +} + +bool GLESvalidate::capability(GLenum cap,int maxLights,int maxClipPlanes) { + switch(cap) { + case GL_ALPHA_TEST: + case GL_BLEND: + case GL_COLOR_ARRAY: + case GL_COLOR_LOGIC_OP: + case GL_COLOR_MATERIAL: + case GL_CULL_FACE: + case GL_DEPTH_TEST: + case GL_DITHER: + case GL_FOG: + case GL_LIGHTING: + case GL_LINE_SMOOTH: + case GL_MULTISAMPLE: + case GL_NORMAL_ARRAY: + case GL_NORMALIZE: + case GL_POINT_SIZE_ARRAY_OES: + case GL_POINT_SMOOTH: + case GL_POINT_SPRITE_OES: + case GL_POLYGON_OFFSET_FILL: + case GL_RESCALE_NORMAL: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_ALPHA_TO_ONE: + case GL_SAMPLE_COVERAGE: + case GL_SCISSOR_TEST: + case GL_STENCIL_TEST: + case GL_TEXTURE_2D: + case GL_TEXTURE_COORD_ARRAY: + case GL_VERTEX_ARRAY: + return true; + } + return GLESvalidate::lightEnum(cap,maxLights) || GLESvalidate::clipPlaneEnum(cap,maxClipPlanes); +} + +bool GLESvalidate::pixelType(GLenum type) { + switch(type) { + case GL_UNSIGNED_BYTE: + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + return true; + } + return false; +} + +bool GLESvalidate::pixelFrmt(GLenum format) { + switch(format) { + case GL_ALPHA: + case GL_RGB: + case GL_RGBA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + return true; + } + return false; +} + +bool GLESvalidate::texCompImgFrmt(GLenum format) { + switch(format) { + case GL_PALETTE4_RGB8_OES: + case GL_PALETTE4_RGBA8_OES: + case GL_PALETTE4_R5_G6_B5_OES: + case GL_PALETTE4_RGBA4_OES: + case GL_PALETTE4_RGB5_A1_OES: + case GL_PALETTE8_RGB8_OES: + case GL_PALETTE8_RGBA8_OES: + case GL_PALETTE8_R5_G6_B5_OES: + case GL_PALETTE8_RGBA4_OES: + case GL_PALETTE8_RGB5_A1_OES: + return true; + } + return false; +} + +bool GLESvalidate::pixelOp(GLenum format,GLenum type) { + switch(type) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_5_5_5_1: + return format == GL_RGBA; + case GL_UNSIGNED_SHORT_5_6_5: + return format == GL_RGB; + } + return true; +} + +bool GLESvalidate::texImgDim(GLsizei width,GLsizei height,int maxTexSize) { + + if( width < 0 || height < 0 || width > maxTexSize || height > maxTexSize) + return false; + return isPowerOf2(width) && isPowerOf2(height); +} + +bool GLESvalidate::bufferTarget(GLenum target) { + return target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER; +} + +bool GLESvalidate::bufferParam(GLenum param) { + return (param == GL_BUFFER_SIZE) || (param == GL_BUFFER_USAGE); +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.h new file mode 100644 index 000000000..a4f785bf9 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLESvalidate.h @@ -0,0 +1,50 @@ +/* +* 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 GLES_VALIDATE_H +#define GLES_VALIDATE_H + +#include + +struct GLESvalidate +{ + +static bool lightEnum(GLenum e,unsigned int maxLIghts); +static bool clipPlaneEnum(GLenum e,unsigned int maxClipPlanes); +static bool alphaFunc(GLenum f); +static bool blendSrc(GLenum s); +static bool blendDst(GLenum d); +static bool vertexPointerParams(GLint size,GLsizei stride); +static bool colorPointerParams(GLint size,GLsizei stride); +static bool supportedArrays(GLenum arr); +static bool drawMode(GLenum mode); +static bool drawType(GLenum mode); +static bool hintTargetMode(GLenum target,GLenum mode); +static bool capability(GLenum cap,int maxLights,int maxClipPlanes); +static bool texParams(GLenum target,GLenum pname); +static bool texCoordPointerParams(GLint size,GLsizei stride); +static bool textureTarget(GLenum target); +static bool textureEnum(GLenum e,unsigned int maxTex); +static bool texEnv(GLenum target,GLenum pname); +static bool pixelFrmt(GLenum format); +static bool pixelType(GLenum type); +static bool pixelOp(GLenum format,GLenum type); +static bool texCompImgFrmt(GLenum format); +static bool texImgDim(GLsizei width,GLsizei height,int maxTexSize); +static bool bufferTarget(GLenum target); +static bool bufferParam(GLenum param); +}; + +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLfixed_ops.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLfixed_ops.h new file mode 100644 index 000000000..824bb94e4 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLfixed_ops.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 _GL_FIXED_OPS_H +#define _GL_FIXED_OPS_H + +#define X2F(x) (((float)(x))/65536.0f) +#define X2D(x) (((double)(x))/65536.0) +#define X2I(x) ((x) /65536) + + +#define F2X(d) ((d) > 32767.65535 ? 32767 * 65536 + 65535 : \ + (d) < -32768.65535 ? -32768 * 65536 + 65535 : \ + ((GLfixed) ((d) * 65536))) + + +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.cpp new file mode 100644 index 000000000..6c41e6f0e --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.cpp @@ -0,0 +1,126 @@ +/* +* 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 "RangeManip.h" + + +bool Range::rangeIntersection(const Range& r,Range& rOut) const { + if(m_start > r.getEnd() || r.getStart() > m_end) return false; + int max_start = (m_start > r.getStart())? m_start:r.getStart(); + int min_end = (m_end < r.getEnd())?m_end:r.getEnd(); + int size = min_end - max_start; + if(size) { + rOut.setRange(max_start,min_end-max_start); + return true; + } + return false; +} + +bool Range::rangeUnion(const Range& r,Range& rOut) const { + if(m_start > r.getEnd() || r.getStart() > m_end) return false; + int min_start = (m_start < r.getStart())?m_start:r.getStart(); + int max_end = (m_end > r.getEnd())?m_end:r.getEnd(); + int size = max_end - min_start; + if(size) { + rOut.setRange(min_start,max_end-min_start); + return false; + } + return false; +} + +void RangeList::addRange(const Range& r) { + list.push_back(r); +} + +void RangeList::addRanges(const RangeList& rl) { + for(int i =0; i< rl.size();i++) { + addRange(rl.list[i]); + } +} + +void RangeList::delRanges(const RangeList& rl,RangeList& deleted) { + for(int i =0; i< rl.size();i++) { + delRange(rl.list[i],deleted); + } +} + +bool RangeList::empty() const{ + return list.empty(); +} + +int RangeList::size() const{ + return list.size(); +} +void RangeList::clear() { + return list.clear(); +} + +void RangeList::erase(unsigned int i) { + if(i > list.size()) return; + list.erase(list.begin() +i); +} + +void RangeList::delRange(const Range& r,RangeList& deleted) { + if(r.getSize() == 0) return; + + Range intersection; + Range temp; + // compare new rect to each and any of the rects on the list + for (int i=0;i<(int)list.size();i++) { // i must be signed for i-- below + // if there is intersection + if (r.rangeIntersection(list[i],intersection)) { + Range old=list[i]; + // remove old as it is about to be split + erase(i); + i--; + if (intersection!=old) { // otherwise split: + //intersection on right side + if(old.getStart() != intersection.getStart()) { + list.insert(list.begin(),Range(old.getStart(),intersection.getStart() - old.getStart())); + } + + //intersection on left side + if(old.getEnd() != intersection.getEnd()) { + list.insert(list.begin(),Range(intersection.getEnd(),old.getEnd() - intersection.getEnd())); + } + deleted.addRange(intersection); + } + } + } +} + +void RangeList::merge() { + if(list.empty()) return; + + Range temp; + bool changed; + + do { // re-run if changed in last run + changed=0; + // run for each combinations of two rects in the list + for (int i=0;i<(((int)list.size())-1) && !changed ;i++) + { + for (int j=i+1;j<(int)list.size() && !changed ;j++) + { + if (list[i].rangeUnion(list[j],temp)) { + // are them exactly one on left of the other + list[i] = temp; + erase(j); + changed=1; + } + } + } + } while (changed); +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.h new file mode 100644 index 000000000..e3162b8d6 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/RangeManip.h @@ -0,0 +1,69 @@ +/* +* 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 RANGE_H +#define RANGE_H + +#include + +class Range { + +public: + Range():m_start(0),m_end(0),m_size(0){}; + Range(int start,int size):m_start(start),m_end(start+size),m_size(size){}; + Range(const Range& r):m_start(r.m_start),m_end(r.m_end),m_size(r.m_size){}; + void setRange(int start,int size){m_start = start; m_end = start+size; m_size = size;}; + inline int getStart() const{return m_start;}; + inline int getEnd() const{return m_end;}; + inline int getSize() const{return m_size;}; + Range& operator=(const Range& r) { + m_start = r.m_start; + m_end = r.m_end; + m_size = r.m_size; + return *this; + } + bool operator ==(const Range& r) const { + return m_start == r.m_start && m_size == r.m_size && m_end == r.m_end; + } + bool operator !=(const Range& r) const {return !((*this) == r);}; + bool rangeIntersection(const Range& r,Range& rOut) const ; + bool rangeUnion(const Range& r,Range& rOut) const ; + +private: + int m_start; + int m_end; + int m_size; +}; + +class RangeList { +public: + void addRange(const Range& r); + void addRanges(const RangeList& rl); + void delRange(const Range& r,RangeList& deleted); + void delRanges(const RangeList& rl,RangeList& deleted); + bool empty() const; + void merge(); + int size() const; + void clear(); + Range& operator[](unsigned int i){return list[i];}; +private: + void erase(unsigned int i); + std::vector list; +}; + + + + +#endif diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.cpp new file mode 100644 index 000000000..28dff1c22 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.cpp @@ -0,0 +1,158 @@ +/* +* 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 "TextureUtils.h" +#include + + +struct Color +{ + Color(unsigned char r, unsigned char g,unsigned char b, unsigned char a):red(r),green(g),blue(b),alpha(a){}; + unsigned char red; + unsigned char green; + unsigned char blue; + unsigned char alpha; +}; + +void getPaletteInfo(GLenum internalFormat,unsigned int& indexSizeBits,unsigned int& colorSizeBytes,GLenum& colorFrmt) { + + colorFrmt = GL_RGB; + switch(internalFormat) + { + case GL_PALETTE4_RGB8_OES: + indexSizeBits = 4; + colorSizeBytes = 3; + break; + + case GL_PALETTE4_RGBA8_OES: + indexSizeBits = 4; + colorSizeBytes = 4; + colorFrmt = GL_RGBA; + break; + + case GL_PALETTE4_RGBA4_OES: + colorFrmt = GL_RGBA; + case GL_PALETTE4_R5_G6_B5_OES: + case GL_PALETTE4_RGB5_A1_OES: + indexSizeBits = 4; + colorSizeBytes = 2; + break; + + case GL_PALETTE8_RGB8_OES: + indexSizeBits = 8; + colorSizeBytes = 3; + break; + + case GL_PALETTE8_RGBA8_OES: + indexSizeBits = 8; + colorSizeBytes = 4; + colorFrmt = GL_RGBA; + break; + + case GL_PALETTE8_R5_G6_B5_OES: + case GL_PALETTE8_RGB5_A1_OES: + indexSizeBits = 8; + colorSizeBytes = 2; + break; + } +} + + +Color paletteColor(const unsigned char* pallete,unsigned int index,GLenum format) +{ + short s; + switch(format) { + //RGB + case GL_PALETTE4_RGB8_OES: + case GL_PALETTE8_RGB8_OES: + return Color(pallete[index],pallete[index+1],pallete[index+2],0); + case GL_PALETTE8_R5_G6_B5_OES: + case GL_PALETTE4_R5_G6_B5_OES: + s = *((short *)(pallete+index)); + return Color(s >> 10,(s >> 5) & 0x3f ,s & 0x1f,0); + + //RGBA + case GL_PALETTE4_RGBA8_OES: + case GL_PALETTE8_RGBA8_OES: + return Color(pallete[index],pallete[index+1],pallete[index+2],pallete[index+3]); + case GL_PALETTE4_RGBA4_OES: + s = *((short *)(pallete+index)); + return Color((s >> 12) & 0xf,(s >> 8) & 0xf,(s >> 4) & 0xf ,s & 0xf); + case GL_PALETTE4_RGB5_A1_OES: + case GL_PALETTE8_RGB5_A1_OES: + s = *((short *)(pallete+index)); + return Color((s >> 11) & 0x1f,(s >> 6) & 0x1f,(s >> 1) & 0x1f ,s & 0x1 * 255); + default: + return Color(255,255,255,255); + } +} + +unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level) { + + unsigned int indexSizeBits; //the size of the color index in the pallete + unsigned int colorSizeBytes; //the size of each color cell in the pallete + + const unsigned char* palette = static_cast(data); + + getPaletteInfo(internalformat,indexSizeBits,colorSizeBytes,formatOut); + + //the pallete positioned in the begininng of the data + // so we jump over it to get to the colos indices in the palette + + int nColors = 2 << (indexSizeBits -1); //2^indexSizeBits + int paletteSizeBytes = nColors*colorSizeBytes; + const unsigned char* imageIndices = palette + paletteSizeBytes; + + //jumping to the the correct mipmap level + for(int i=0;i> 1; + height = height >> 1; + } + + int colorSizeOut = (formatOut == GL_RGB? 3:4); + int nPixels = width*height; + unsigned char* pixelsOut = new unsigned char[nPixels*colorSizeOut]; + if(!pixelsOut) return NULL; + + int leftBytes = ((palette + imageSize) /* the end of data pointer*/ + - imageIndices); + int leftPixels = (leftBytes * 8 )/indexSizeBits; + + int maxIndices = (leftPixels < nPixels) ? leftPixels:nPixels; + + //filling the pixels array + for(int i =0 ; i < maxIndices ; i++) { + int paletteIndex = 0; + int indexOut = i*colorSizeOut; + if(indexSizeBits == 4) { + paletteIndex = (i%2)? imageIndices[i/2] >> 4: //upper bits + imageIndices[i/2] & 0xf; //lower bits + } else { + paletteIndex = imageIndices[i]; + } + + paletteIndex*=colorSizeBytes; + Color c = paletteColor(palette,paletteIndex,internalformat); + + pixelsOut[indexOut] = c.red; + pixelsOut[indexOut+1] = c.green; + pixelsOut[indexOut+2] = c.blue; + if(formatOut == GL_RGBA) { + pixelsOut[indexOut+3] = c.alpha; + } + } + return pixelsOut; +} diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.h b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.h new file mode 100644 index 000000000..21094aff9 --- /dev/null +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/TextureUtils.h @@ -0,0 +1,23 @@ +/* +* 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 _TEXTURE_UTILS_H +#define _TEXTURE_UTILS_H + +#include + +unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level); + +#endif