am 9d4ac946: Merge "Emulator\'s GLES translator implementation."

* commit '9d4ac946f32d23a4c8ce5723a4e7cb1153f4abb5':
  Emulator's GLES translator implementation.
This commit is contained in:
David Turner
2011-05-02 12:33:01 -07:00
committed by Android Git Automerger
19 changed files with 3214 additions and 0 deletions

View File

@@ -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

View File

@@ -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 <stdio.h>
#ifdef __linux__
#include <GL/glx.h>
#elif defined(WIN32)
#include <windows.h>
#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;
}

View File

@@ -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 <GLES/gl.h>
#include <utils/threads.h>
#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

View File

@@ -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 <string.h>
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;
}
}

View File

@@ -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 <stdio.h>
#include <GLES/gl.h>
#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

View File

@@ -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 <GLcommon/GLutils.h>
#include <string.h>
#include <GLES/gl.h>
//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<GLenum,GLfloat*>::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<unsigned int>(data);
m_map[arrType]->setBuffer(size,type,stride,m_vbos[bufferName],offset);
return static_cast<const unsigned char*>(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<attribSize;j++) {
reinterpret_cast<GLfloat*>(&static_cast<unsigned char*>(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<GLfloat*>(static_cast<unsigned char*>(dataOut) + index*strideOut);
for(int j=0;j<attribSize;j++) {
float_data[j] = X2F(fixed_data[j]);
}
}
}
static void directToBytesRanges(GLint first,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()+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<const GLushort*>(indices)[i]:
static_cast<const GLubyte*>(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;i<ranges.size();i++) {
int startIndex = (ranges[i].getStart() - offset) / stride;
int nElements = ranges[i].getSize()/attribSize;
for(int j=0;j<nElements;j++) {
indices[n++] = startIndex+j;
}
}
return n;
}
void GLEScontext::convertDirect(GLESFloatArrays& fArrs,GLint first,GLsizei count,GLenum array_id,GLESpointer* p,unsigned int& index) {
GLenum type = p->getType();
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<char*>(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<count;i++) {
if(b_indices[i] > max) max = b_indices[i];
}
} else {
GLushort* us_indices =(GLushort *)indices;
for(int i=0;i<count;i++) {
if(us_indices[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<GLfloat>(sortedPoints[j],sortedPoints[j+1]);
swap<GLushort>(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<int>& arr = (*it).second;
if(count > last_size) {
if(indices) delete [] indices;
indices = new GLushort[count];
}
int i = 0 ;
for(std::vector<int>::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<const GLfloat*>(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<const GLushort*>(indices_in)[i]:
static_cast<const GLubyte*>(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);
}

View File

@@ -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 <map>
#include <vector>
#include <utils/threads.h>
#define MAX_TEX_UNITS 8
typedef std::map<GLenum,GLESpointer*> ArraysMap;
typedef std::map<GLuint,GLESbuffer*> BuffersMap;
typedef std::map<GLfloat,std::vector<int> > PointSizeIndices;
struct GLESFloatArrays
{
GLESFloatArrays(){};
~GLESFloatArrays();
std::map<GLenum,GLfloat*> 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

File diff suppressed because it is too large Load Diff

View File

@@ -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 <stdlib.h>
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<unsigned char*>(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);
}

View File

@@ -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 <GLES/gl.h>
#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

View File

@@ -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;
}

View File

@@ -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 <GLES/gl.h>
#include <stdlib.h>
size_t glParamSize(GLenum param);
#endif

View File

@@ -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 <GLcommon/GLutils.h>
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);
}

View File

@@ -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 <GLES/gl.h>
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

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 <vector>
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<Range> list;
};
#endif

View File

@@ -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 <stdio.h>
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<const unsigned char *>(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<level;i++) {
imageIndices+= (width*height*indexSizeBits)/8;
width = width >> 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;
}

View File

@@ -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 <GLES/gl.h>
unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level);
#endif