Merge "rework a bit how we manage EGL extensions" into ics-mr1

This commit is contained in:
Mathias Agopian
2011-11-15 18:12:00 -08:00
committed by Android (Google) Code Review
17 changed files with 82 additions and 4165 deletions

View File

@ -229,14 +229,6 @@ struct ANativeWindowBuffer;
#define EGL_NATIVE_BUFFER_ANDROID 0x3140 /* eglCreateImageKHR target */
#endif
#ifndef EGL_ANDROID_swap_rectangle
#define EGL_ANDROID_swap_rectangle 1
#ifdef EGL_EGLEXT_PROTOTYPES
EGLAPI EGLBoolean EGLAPIENTRY eglSetSwapRectangleANDROID (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height);
#endif /* EGL_EGLEXT_PROTOTYPES */
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSETSWAPRECTANGLEANDROIDPROC) (EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height);
#endif
#ifndef EGL_ANDROID_recordable
#define EGL_ANDROID_recordable 1
#define EGL_RECORDABLE_ANDROID 0x3142 /* EGLConfig attribute */

View File

@ -49,6 +49,11 @@
#undef NELEM
#define NELEM(x) (sizeof(x)/sizeof(*(x)))
EGLBoolean EGLAPI eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
EGLint left, EGLint top, EGLint width, EGLint height);
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------

View File

@ -1,56 +0,0 @@
LOCAL_PATH:= $(call my-dir)
#
# Build the software OpenGL ES library
#
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
src/api.cpp \
src/egl.cpp \
src/get.cpp \
src/shader.cpp \
src/state.cpp \
src/texture.cpp \
src/vertex.cpp
LOCAL_C_INCLUDES := \
$(LOCAL_PATH) \
external/mesa3d/include \
external/mesa3d/src \
external/stlport/stlport \
bionic
#LOCAL_CFLAGS += -DLOG_TAG=\"libagl2\"
#LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
#LOCAL_CFLAGS += -fvisibility=hidden
#LOCAL_CFLAGS += -O0 -g -DDEBUG -UNDEBUG
LOCAL_CFLAGS += -O3
LOCAL_STATIC_LIBRARIES := libMesa
LOCAL_SHARED_LIBRARIES := libstlport libcutils libhardware libutils libbcc libdl
LOCAL_LDLIBS := -lpthread
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -fstrict-aliasing
endif
ifeq ($(ARCH_ARM_HAVE_TLS_REGISTER),true)
LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
endif
# we need to access the private Bionic header <bionic_tls.h>
# on ARM platforms, we need to mirror the ARCH_ARM_HAVE_TLS_REGISTER
# behavior from the bionic Android.mk file
ifeq ($(TARGET_ARCH)-$(ARCH_ARM_HAVE_TLS_REGISTER),arm-true)
LOCAL_CFLAGS += -DHAVE_ARM_TLS_REGISTER
endif
LOCAL_C_INCLUDES += bionic/libc/private
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
#replace libagl for now
LOCAL_MODULE:= libGLES_android
LOCAL_MODULE_TAGS := eng
## Disable this makefile for now
## include $(BUILD_SHARED_LIBRARY)

View File

@ -1,26 +0,0 @@
libAgl2 provides software GL ES 2.0 implementation using Pixelflinger2 in external/mesa3d
To build, enable Android.mk, which builds libGLES_android.so, then replace the one built from libAgl in system/lib/egl.
ES 1.0 functions are not implemented and will cause exit, so do not setprop debug.egl.hw 0 until launcher is loaded.
All functions have little to none error checking.
Not thread safe, Pixelflinger2 uses some static data.
Most shader functions are implemented, however, most Get* functions for shaders/programs/uniforms/attribs are not.
No name system for shaders/programs, just using the pointers as names.
Basic glTexImage2D, glTexSubImage2D, glCopyImage2D and glCopySubImage2D are implemented, with a range of 8/16/24/32bpp formats.
Cube map support is minimal. No mipmapping.
TexParameter is mostly implemented, supports texcoord wrap modes, and only linear for both min and mag, or nearest for both min and mag filtering.
Texture names are implemented, but bad.
Frame buffer and render buffers are not implemented.
Depth and stencil are implemented, but not tested.
Blending seems to work.
Colorbuffer supports RGBA_8888 and RGB_565.
Vertex buffer objects are implemented.
Some GL_TRIANGLES and GL_TRIANGLE_STRIPS modes for glDrawArrays and glDrawElements are implemented, but vertex order is probably wrong so culling is disabled.
Basic apps should work, and some libhwui should work, except for frame buffer operations, which will cause exit.

View File

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<CodeLite_Project Name="libagl2" InternalType="Console">
<Plugins>
<Plugin Name="qmake">
<![CDATA[00010001N0005Debug000000000000]]>
</Plugin>
</Plugins>
<Description/>
<Dependencies/>
<Dependencies Name="Release"/>
<VirtualDirectory Name="src">
<File Name="src/egl.cpp"/>
<File Name="src/api.cpp"/>
<File Name="src/gles2context.h"/>
<File Name="src/shader.cpp"/>
<File Name="src/vertex.cpp"/>
<File Name="src/state.cpp"/>
<File Name="src/texture.cpp"/>
<File Name="src/get.cpp"/>
</VirtualDirectory>
<VirtualDirectory Name="include"/>
<Settings Type="Executable">
<Configuration Name="Debug" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="Executable" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
<Compiler Options="-g;-m32" Required="yes" PreCompiledHeader="">
<IncludePath Value="/usr/include/c++/4.4"/>
<IncludePath Value="/usr/include/c++/4.4/ext"/>
<IncludePath Value="."/>
<IncludePath Value="include"/>
<IncludePath Value="../../../../external/mesa3d/include"/>
<IncludePath Value="../../../../external/mesa3d/src"/>
<IncludePath Value="../../../../hardware/libhardware/include"/>
<IncludePath Value="../../../../system/core/include"/>
<IncludePath Value="../include"/>
<IncludePath Value="../../include"/>
<IncludePath Value="../../../../development/ndk/platforms/android-9/include"/>
<IncludePath Value="../../../../bionic/libc/include/"/>
<IncludePath Value="/../../../../development/ndk/platforms/android-5/arch-x86/include"/>
<IncludePath Value="../../../../bionic/libc/arch-x86/include"/>
<IncludePath Value="../../../../bionic/libc/kernel/arch-x86"/>
<IncludePath Value="/../../../../external/kernel-headers/original"/>
<IncludePath Value="../../../../prebuilt/ndk/android-ndk-r4/platforms/android-8/arch-x86/usr/include"/>
</Compiler>
<Linker Options="-m32;-lstdc++" Required="yes"/>
<ResourceCompiler Options="" Required="no"/>
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Debug" Command="./$(ProjectName)" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
<PostConnectCommands/>
<StartupCommands/>
</Debugger>
<PreBuild/>
<PostBuild/>
<CustomBuild Enabled="no">
<RebuildCommand/>
<CleanCommand/>
<BuildCommand/>
<PreprocessFileCommand/>
<SingleFileCommand/>
<MakefileGenerationCommand/>
<ThirdPartyToolName>None</ThirdPartyToolName>
<WorkingDirectory/>
</CustomBuild>
<AdditionalRules>
<CustomPostBuild/>
<CustomPreBuild/>
</AdditionalRules>
</Configuration>
<Configuration Name="Release" CompilerType="gnu gcc" DebuggerType="GNU gdb debugger" Type="" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
<Compiler Options="" Required="yes" PreCompiledHeader="">
<IncludePath Value="."/>
</Compiler>
<Linker Options="-O2" Required="yes"/>
<ResourceCompiler Options="" Required="no"/>
<General OutputFile="$(IntermediateDirectory)/$(ProjectName)" IntermediateDirectory="./Release" Command="./$(ProjectName)" CommandArguments="" WorkingDirectory="$(IntermediateDirectory)" PauseExecWhenProcTerminates="yes"/>
<Debugger IsRemote="no" RemoteHostName="" RemoteHostPort="" DebuggerPath="">
<PostConnectCommands/>
<StartupCommands/>
</Debugger>
<PreBuild/>
<PostBuild/>
<CustomBuild Enabled="no">
<RebuildCommand/>
<CleanCommand/>
<BuildCommand/>
<PreprocessFileCommand/>
<SingleFileCommand/>
<MakefileGenerationCommand/>
<ThirdPartyToolName>None</ThirdPartyToolName>
<WorkingDirectory/>
</CustomBuild>
<AdditionalRules>
<CustomPostBuild/>
<CustomPreBuild/>
</AdditionalRules>
</Configuration>
<GlobalSettings>
<Compiler Options="">
<IncludePath Value="."/>
</Compiler>
<Linker Options="">
<LibraryPath Value="."/>
</Linker>
<ResourceCompiler Options=""/>
</GlobalSettings>
</Settings>
<Dependencies Name="Debug">
<Project Name="libMesa"/>
</Dependencies>
</CodeLite_Project>

View File

@ -1,266 +0,0 @@
#include "gles2context.h"
#define API_ENTRY
#define CALL_GL_API(NAME,...) LOGD("?"#NAME); assert(0);
#define CALL_GL_API_RETURN(NAME,...) LOGD("?"#NAME); assert(0); return 0;
void API_ENTRY(glBindFramebuffer)(GLenum target, GLuint framebuffer)
{
CALL_GL_API(glBindFramebuffer, target, framebuffer);
}
void API_ENTRY(glBindRenderbuffer)(GLenum target, GLuint renderbuffer)
{
CALL_GL_API(glBindRenderbuffer, target, renderbuffer);
}
GLenum API_ENTRY(glCheckFramebufferStatus)(GLenum target)
{
CALL_GL_API_RETURN(glCheckFramebufferStatus, target);
}
void API_ENTRY(glColorMask)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
{
CALL_GL_API(glColorMask, red, green, blue, alpha);
}
void API_ENTRY(glDeleteFramebuffers)(GLsizei n, const GLuint* framebuffers)
{
CALL_GL_API(glDeleteFramebuffers, n, framebuffers);
}
void API_ENTRY(glDeleteRenderbuffers)(GLsizei n, const GLuint* renderbuffers)
{
CALL_GL_API(glDeleteRenderbuffers, n, renderbuffers);
}
void API_ENTRY(glDepthFunc)(GLenum func)
{
CALL_GL_API(glDepthFunc, func);
}
void API_ENTRY(glDepthMask)(GLboolean flag)
{
CALL_GL_API(glDepthMask, flag);
}
void API_ENTRY(glDepthRangef)(GLclampf zNear, GLclampf zFar)
{
CALL_GL_API(glDepthRangef, zNear, zFar);
}
void API_ENTRY(glFramebufferRenderbuffer)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
{
CALL_GL_API(glFramebufferRenderbuffer, target, attachment, renderbuffertarget, renderbuffer);
}
void API_ENTRY(glFramebufferTexture2D)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
{
CALL_GL_API(glFramebufferTexture2D, target, attachment, textarget, texture, level);
}
void glGenerateMipmap(GLenum target)
{
//CALL_GL_API(glGenerateMipmap, target);
LOGD("agl2: glGenerateMipmap not implemented");
}
void API_ENTRY(glGenFramebuffers)(GLsizei n, GLuint* framebuffers)
{
CALL_GL_API(glGenFramebuffers, n, framebuffers);
}
void API_ENTRY(glGenRenderbuffers)(GLsizei n, GLuint* renderbuffers)
{
CALL_GL_API(glGenRenderbuffers, n, renderbuffers);
}
void API_ENTRY(glGetActiveAttrib)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
CALL_GL_API(glGetActiveAttrib, program, index, bufsize, length, size, type, name);
}
void API_ENTRY(glGetActiveUniform)(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
{
CALL_GL_API(glGetActiveUniform, program, index, bufsize, length, size, type, name);
}
void API_ENTRY(glGetAttachedShaders)(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
{
CALL_GL_API(glGetAttachedShaders, program, maxcount, count, shaders);
}
void API_ENTRY(glGetBooleanv)(GLenum pname, GLboolean* params)
{
CALL_GL_API(glGetBooleanv, pname, params);
}
void API_ENTRY(glGetBufferParameteriv)(GLenum target, GLenum pname, GLint* params)
{
CALL_GL_API(glGetBufferParameteriv, target, pname, params);
}
GLenum glGetError(void)
{
puts("agl2: glGetError");
return GL_NO_ERROR;
//CALL_GL_API_RETURN(glGetError);
}
void API_ENTRY(glGetFloatv)(GLenum pname, GLfloat* params)
{
CALL_GL_API(glGetFloatv, pname, params);
}
void API_ENTRY(glGetFramebufferAttachmentParameteriv)(GLenum target, GLenum attachment, GLenum pname, GLint* params)
{
CALL_GL_API(glGetFramebufferAttachmentParameteriv, target, attachment, pname, params);
}
void API_ENTRY(glGetRenderbufferParameteriv)(GLenum target, GLenum pname, GLint* params)
{
CALL_GL_API(glGetRenderbufferParameteriv, target, pname, params);
}
void API_ENTRY(glGetShaderPrecisionFormat)(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
{
CALL_GL_API(glGetShaderPrecisionFormat, shadertype, precisiontype, range, precision);
}
void API_ENTRY(glGetShaderSource)(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
{
CALL_GL_API(glGetShaderSource, shader, bufsize, length, source);
}
void API_ENTRY(glGetUniformfv)(GLuint program, GLint location, GLfloat* params)
{
CALL_GL_API(glGetUniformfv, program, location, params);
}
void API_ENTRY(glGetUniformiv)(GLuint program, GLint location, GLint* params)
{
CALL_GL_API(glGetUniformiv, program, location, params);
}
void API_ENTRY(glGetVertexAttribfv)(GLuint index, GLenum pname, GLfloat* params)
{
CALL_GL_API(glGetVertexAttribfv, index, pname, params);
}
void API_ENTRY(glGetVertexAttribiv)(GLuint index, GLenum pname, GLint* params)
{
CALL_GL_API(glGetVertexAttribiv, index, pname, params);
}
void API_ENTRY(glGetVertexAttribPointerv)(GLuint index, GLenum pname, GLvoid** pointer)
{
CALL_GL_API(glGetVertexAttribPointerv, index, pname, pointer);
}
GLboolean API_ENTRY(glIsBuffer)(GLuint buffer)
{
CALL_GL_API_RETURN(glIsBuffer, buffer);
}
GLboolean API_ENTRY(glIsEnabled)(GLenum cap)
{
CALL_GL_API_RETURN(glIsEnabled, cap);
}
GLboolean API_ENTRY(glIsFramebuffer)(GLuint framebuffer)
{
CALL_GL_API_RETURN(glIsFramebuffer, framebuffer);
}
GLboolean API_ENTRY(glIsProgram)(GLuint program)
{
CALL_GL_API_RETURN(glIsProgram, program);
}
GLboolean API_ENTRY(glIsRenderbuffer)(GLuint renderbuffer)
{
CALL_GL_API_RETURN(glIsRenderbuffer, renderbuffer);
}
GLboolean API_ENTRY(glIsShader)(GLuint shader)
{
CALL_GL_API_RETURN(glIsShader, shader);
}
void API_ENTRY(glLineWidth)(GLfloat width)
{
CALL_GL_API(glLineWidth, width);
}
void API_ENTRY(glPolygonOffset)(GLfloat factor, GLfloat units)
{
CALL_GL_API(glPolygonOffset, factor, units);
}
void API_ENTRY(glReadPixels)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
{
CALL_GL_API(glReadPixels, x, y, width, height, format, type, pixels);
}
void API_ENTRY(glReleaseShaderCompiler)(void)
{
CALL_GL_API(glReleaseShaderCompiler);
}
void API_ENTRY(glRenderbufferStorage)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
{
CALL_GL_API(glRenderbufferStorage, target, internalformat, width, height);
}
void API_ENTRY(glSampleCoverage)(GLclampf value, GLboolean invert)
{
CALL_GL_API(glSampleCoverage, value, invert);
}
void API_ENTRY(glShaderBinary)(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
{
CALL_GL_API(glShaderBinary, n, shaders, binaryformat, binary, length);
}
void API_ENTRY(glStencilFunc)(GLenum func, GLint ref, GLuint mask)
{
CALL_GL_API(glStencilFunc, func, ref, mask);
}
void API_ENTRY(glStencilFuncSeparate)(GLenum face, GLenum func, GLint ref, GLuint mask)
{
CALL_GL_API(glStencilFuncSeparate, face, func, ref, mask);
}
void API_ENTRY(glStencilMask)(GLuint mask)
{
CALL_GL_API(glStencilMask, mask);
}
void API_ENTRY(glStencilMaskSeparate)(GLenum face, GLuint mask)
{
CALL_GL_API(glStencilMaskSeparate, face, mask);
}
void API_ENTRY(glStencilOp)(GLenum fail, GLenum zfail, GLenum zpass)
{
CALL_GL_API(glStencilOp, fail, zfail, zpass);
}
void API_ENTRY(glStencilOpSeparate)(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
{
CALL_GL_API(glStencilOpSeparate, face, fail, zfail, zpass);
}
void API_ENTRY(glUniform1fv)(GLint location, GLsizei count, const GLfloat* v)
{
CALL_GL_API(glUniform1fv, location, count, v);
}
void API_ENTRY(glUniform1iv)(GLint location, GLsizei count, const GLint* v)
{
CALL_GL_API(glUniform1iv, location, count, v);
}
void API_ENTRY(glUniform2fv)(GLint location, GLsizei count, const GLfloat* v)
{
CALL_GL_API(glUniform2fv, location, count, v);
}
void API_ENTRY(glUniform2i)(GLint location, GLint x, GLint y)
{
CALL_GL_API(glUniform2i, location, x, y);
}
void API_ENTRY(glUniform2iv)(GLint location, GLsizei count, const GLint* v)
{
CALL_GL_API(glUniform2iv, location, count, v);
}
void API_ENTRY(glUniform3f)(GLint location, GLfloat x, GLfloat y, GLfloat z)
{
CALL_GL_API(glUniform3f, location, x, y, z);
}
void API_ENTRY(glUniform3fv)(GLint location, GLsizei count, const GLfloat* v)
{
CALL_GL_API(glUniform3fv, location, count, v);
}
void API_ENTRY(glUniform3i)(GLint location, GLint x, GLint y, GLint z)
{
CALL_GL_API(glUniform3i, location, x, y, z);
}
void API_ENTRY(glUniform3iv)(GLint location, GLsizei count, const GLint* v)
{
CALL_GL_API(glUniform3iv, location, count, v);
}
void API_ENTRY(glUniform4fv)(GLint location, GLsizei count, const GLfloat* v)
{
CALL_GL_API(glUniform4fv, location, count, v);
}
void API_ENTRY(glUniform4i)(GLint location, GLint x, GLint y, GLint z, GLint w)
{
CALL_GL_API(glUniform4i, location, x, y, z, w);
}
void API_ENTRY(glUniform4iv)(GLint location, GLsizei count, const GLint* v)
{
CALL_GL_API(glUniform4iv, location, count, v);
}
void API_ENTRY(glUniformMatrix2fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
CALL_GL_API(glUniformMatrix2fv, location, count, transpose, value);
}
void API_ENTRY(glUniformMatrix3fv)(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
CALL_GL_API(glUniformMatrix3fv, location, count, transpose, value);
}
void API_ENTRY(glValidateProgram)(GLuint program)
{
CALL_GL_API(glValidateProgram, program);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,79 +0,0 @@
#include "gles2context.h"
static char const * const gVendorString = "Android";
static char const * const gRendererString = "Android PixelFlinger2 0.0";
static char const * const gVersionString = "OpenGL ES 2.0";
static char const * const gExtensionsString =
// "GL_OES_byte_coordinates " // OK
// "GL_OES_fixed_point " // OK
// "GL_OES_single_precision " // OK
// "GL_OES_read_format " // OK
// "GL_OES_compressed_paletted_texture " // OK
// "GL_OES_draw_texture " // OK
// "GL_OES_matrix_get " // OK
// "GL_OES_query_matrix " // OK
// // "GL_OES_point_size_array " // TODO
// // "GL_OES_point_sprite " // TODO
// "GL_OES_EGL_image " // OK
//#ifdef GL_OES_compressed_ETC1_RGB8_texture
// "GL_OES_compressed_ETC1_RGB8_texture " // OK
//#endif
// "GL_ARB_texture_compression " // OK
// "GL_ARB_texture_non_power_of_two " // OK
// "GL_ANDROID_user_clip_plane " // OK
// "GL_ANDROID_vertex_buffer_object " // OK
// "GL_ANDROID_generate_mipmap " // OK
""
;
void glGetIntegerv(GLenum pname, GLint* params)
{
switch (pname) {
case GL_MAX_TEXTURE_SIZE :
*params = 4096; // limit is in precision of texcoord calculation, which uses 16.16
break;
case GL_MAX_VERTEX_ATTRIBS:
*params = GGL_MAXVERTEXATTRIBS;
break;
case GL_MAX_VERTEX_UNIFORM_VECTORS:
*params = GGL_MAXVERTEXUNIFORMVECTORS;
break;
case GL_MAX_VARYING_VECTORS:
*params = GGL_MAXVARYINGVECTORS;
break;
case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
*params = GGL_MAXCOMBINEDTEXTUREIMAGEUNITS;
break;
case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
*params = GGL_MAXVERTEXTEXTUREIMAGEUNITS;
break;
case GL_MAX_TEXTURE_IMAGE_UNITS:
*params = GGL_MAXTEXTUREIMAGEUNITS;
break;
case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
*params = GGL_MAXFRAGMENTUNIFORMVECTORS;
break;
case GL_ALIASED_LINE_WIDTH_RANGE:
*params = 1; // TODO: not implemented
break;
default:
LOGD("agl2: glGetIntegerv 0x%.4X", pname);
assert(0);
}
}
const GLubyte* glGetString(GLenum name)
{
switch (name) {
case GL_VENDOR:
return (const GLubyte*)gVendorString;
case GL_RENDERER:
return (const GLubyte*)gRendererString;
case GL_VERSION:
return (const GLubyte*)gVersionString;
case GL_EXTENSIONS:
return (const GLubyte*)gExtensionsString;
}
assert(0); //(c, GL_INVALID_ENUM);
return 0;
}

View File

@ -1,166 +0,0 @@
#define _SIZE_T_DEFINED_
typedef unsigned int size_t;
#include <stdio.h>
#include <stdlib.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES/gl.h>
#include <GLES/glext.h>
#include <utils/threads.h>
#include <pthread.h>
#include <cutils/log.h>
#include <assert.h>
#ifdef __arm__
#ifndef __location__
#define __HIERALLOC_STRING_0__(s) #s
#define __HIERALLOC_STRING_1__(s) __HIERALLOC_STRING_0__(s)
#define __HIERALLOC_STRING_2__ __HIERALLOC_STRING_1__(__LINE__)
#define __location__ __FILE__ ":" __HIERALLOC_STRING_2__
#endif
#undef assert
#define assert(EXPR) { do { if (!(EXPR)) {LOGD("\n*\n*\n*\n* assert fail: '"#EXPR"' at "__location__"\n*\n*\n*\n*"); exit(EXIT_FAILURE); } } while (false); }
//#define printf LOGD
#else // #ifdef __arm__
//#define LOGD printf
#endif // #ifdef __arm__
#include <pixelflinger2/pixelflinger2_format.h>
#include <pixelflinger2/pixelflinger2.h>
#include <map>
typedef uint8_t GGLubyte; // ub
#define ggl_likely(x) __builtin_expect(!!(x), 1)
#define ggl_unlikely(x) __builtin_expect(!!(x), 0)
#undef NELEM
#define NELEM(x) (sizeof(x)/sizeof(*(x)))
template<typename T>
inline T max(T a, T b)
{
return a<b ? b : a;
}
template<typename T>
inline T min(T a, T b)
{
return a<b ? a : b;
}
struct egl_context_t {
enum {
IS_CURRENT = 0x00010000,
NEVER_CURRENT = 0x00020000
};
uint32_t flags;
EGLDisplay dpy;
EGLConfig config;
EGLSurface read;
EGLSurface draw;
unsigned frame;
clock_t lastSwapTime;
float accumulateSeconds;
static inline egl_context_t* context(EGLContext ctx);
};
struct GLES2Context;
#ifdef HAVE_ANDROID_OS
#include <bionic_tls.h>
// We have a dedicated TLS slot in bionic
inline void setGlThreadSpecific(GLES2Context *value)
{
((uint32_t *)__get_tls())[TLS_SLOT_OPENGL] = (uint32_t)value;
}
inline GLES2Context* getGlThreadSpecific()
{
return (GLES2Context *)(((unsigned *)__get_tls())[TLS_SLOT_OPENGL]);
}
#else
extern pthread_key_t gGLKey;
inline void setGlThreadSpecific(GLES2Context *value)
{
pthread_setspecific(gGLKey, value);
}
inline GLES2Context* getGlThreadSpecific()
{
return static_cast<GLES2Context*>(pthread_getspecific(gGLKey));
}
#endif
struct VBO {
unsigned size;
GLenum usage;
void * data;
};
struct GLES2Context {
GGLContext rasterizer;
egl_context_t egl;
GGLInterface * iface; // shortcut to &rasterizer.interface
struct VertexState {
struct VertAttribPointer {
unsigned size; // number of values per vertex
GLenum type; // data type
unsigned stride; // bytes
const void * ptr;
bool normalized :
1;
bool enabled :
1;
} attribs [GGL_MAXVERTEXATTRIBS];
VBO * vbo, * indices;
std::map<GLuint, VBO *> vbos;
GLuint free;
Vector4 defaultAttribs [GGL_MAXVERTEXATTRIBS];
} vert;
struct TextureState {
GGLTexture * tmus[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS];
int sampler2tmu[GGL_MAXCOMBINEDTEXTUREIMAGEUNITS]; // sampler2tmu[sampler] is index of tmu, -1 means not used
unsigned active;
std::map<GLuint, GGLTexture *> textures;
GLuint free; // first possible free name
GGLTexture * tex2D, * texCube; // default textures
unsigned unpack;
void UpdateSampler(GGLInterface * iface, unsigned tmu);
} tex;
GLES2Context();
void InitializeTextures();
void InitializeVertices();
~GLES2Context();
void UninitializeTextures();
void UninitializeVertices();
static inline GLES2Context* get() {
return getGlThreadSpecific();
}
};
inline egl_context_t* egl_context_t::context(EGLContext ctx)
{
GLES2Context* const gl = static_cast<GLES2Context*>(ctx);
return static_cast<egl_context_t*>(&gl->egl);
}
#define GLES2_GET_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
/*puts(__FUNCTION__);*/
#define GLES2_GET_CONST_CONTEXT(ctx) GLES2Context * ctx = GLES2Context::get(); \
/*puts(__FUNCTION__);*/

View File

@ -1,191 +0,0 @@
#include "gles2context.h"
//#undef LOGD
//#define LOGD(...)
static inline GLuint s2n(gl_shader * s)
{
return (GLuint)s ^ 0xaf3c532d;
}
static inline gl_shader * n2s(GLuint n)
{
return (gl_shader *)(n ^ 0xaf3c532d);
}
static inline GLuint p2n(gl_shader_program * p)
{
return (GLuint)p ^ 0x04dc18f9;
}
static inline gl_shader_program * n2p(GLuint n)
{
return (gl_shader_program *)(n ^ 0x04dc18f9);
}
void glAttachShader(GLuint program, GLuint shader)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderAttach(ctx->iface, n2p(program), n2s(shader));
}
void glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderAttributeBind(n2p(program), index, name);
// assert(0);
}
GLuint glCreateShader(GLenum type)
{
GLES2_GET_CONST_CONTEXT(ctx);
return s2n(ctx->iface->ShaderCreate(ctx->iface, type));
}
GLuint glCreateProgram(void)
{
GLES2_GET_CONST_CONTEXT(ctx);
return p2n(ctx->iface->ShaderProgramCreate(ctx->iface));
}
void glCompileShader(GLuint shader)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderCompile(ctx->iface, n2s(shader), NULL, NULL);
}
void glDeleteProgram(GLuint program)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderProgramDelete(ctx->iface, n2p(program));
}
void glDeleteShader(GLuint shader)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderDelete(ctx->iface, n2s(shader));
}
void glDetachShader(GLuint program, GLuint shader)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderDetach(ctx->iface, n2p(program), n2s(shader));
}
GLint glGetAttribLocation(GLuint program, const GLchar* name)
{
GLES2_GET_CONST_CONTEXT(ctx);
GLint location = ctx->iface->ShaderAttributeLocation(n2p(program), name);
// LOGD("\n*\n*\n* agl2: glGetAttribLocation program=%u name=%s location=%d \n*\n*",
// program, name, location);
return location;
}
void glGetProgramiv(GLuint program, GLenum pname, GLint* params)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderProgramGetiv(n2p(program), pname, params);
LOGD("agl2: glGetProgramiv 0x%.4X=%d \n", pname, *params);
}
void glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderProgramGetInfoLog(n2p(program), bufsize, length, infolog);
}
void glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderGetiv(n2s(shader), pname, params);
LOGD("agl2: glGetShaderiv 0x%.4X=%d \n", pname, *params);
}
void glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderGetInfoLog(n2s(shader), bufsize, length, infolog);
}
int glGetUniformLocation(GLuint program, const GLchar* name)
{
GLES2_GET_CONST_CONTEXT(ctx);
return ctx->iface->ShaderUniformLocation(n2p(program), name);
}
void glLinkProgram(GLuint program)
{
GLES2_GET_CONST_CONTEXT(ctx);
GLboolean linked = ctx->iface->ShaderProgramLink(n2p(program), NULL);
assert(linked);
}
void glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ShaderSource(n2s(shader), count, string, length);
}
void glUniform1f(GLint location, GLfloat x)
{
GLES2_GET_CONST_CONTEXT(ctx);
int sampler = ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, &x, GL_FLOAT);
assert(0 > sampler); // should be assigning to sampler
}
void glUniform1i(GLint location, GLint x)
{
GLES2_GET_CONST_CONTEXT(ctx);
const float params[1] = {x};
int sampler = ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_INT);
if (0 <= sampler) {
// LOGD("\n*\n* agl2: glUniform1i updated sampler=%d tmu=%d location=%d\n*", sampler, x, location);
assert(0 <= x && GGL_MAXCOMBINEDTEXTUREIMAGEUNITS > x);
// LOGD("tmu%u: format=0x%.2X w=%u h=%u levels=%p", x, ctx->tex.tmus[x]->format,
// ctx->tex.tmus[x]->width, ctx->tex.tmus[x]->height, ctx->tex.tmus[x]->format);
ctx->tex.sampler2tmu[sampler] = x;
ctx->tex.UpdateSampler(ctx->iface, x);
}
}
void glUniform2f(GLint location, GLfloat x, GLfloat y)
{
GLES2_GET_CONST_CONTEXT(ctx);
const float params[4] = {x, y};
ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_FLOAT_VEC2);
}
void glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
GLES2_GET_CONST_CONTEXT(ctx);
const float params[4] = {x, y, z, w};
// LOGD("agl2: glUniform4f location=%d %f,%f,%f,%f", location, x, y, z, w);
ctx->iface->ShaderUniform(ctx->rasterizer.CurrentProgram, location, 1, params, GL_FLOAT_VEC4);
}
void glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
{
GLES2_GET_CONST_CONTEXT(ctx);
// const gl_shader_program * program = ctx->rasterizer.CurrentProgram;
// if (strstr(program->Shaders[MESA_SHADER_FRAGMENT]->Source, ").a;")) {
// LOGD("agl2: glUniformMatrix4fv location=%d count=%d transpose=%d", location, count, transpose);
// for (unsigned i = 0; i < 4; i++)
// LOGD("agl2: glUniformMatrix4fv %.2f \t %.2f \t %.2f \t %.2f", value[i * 4 + 0],
// value[i * 4 + 1], value[i * 4 + 2], value[i * 4 + 3]);
// }
ctx->iface->ShaderUniformMatrix(ctx->rasterizer.CurrentProgram, 4, 4, location, count, transpose, value);
// while (true)
// ;
// assert(0);
}
void glUseProgram(GLuint program)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("\n*\n*\n* agl2: glUseProgram %d \n*\n*\n*", program);
ctx->iface->ShaderUse(ctx->iface, n2p(program));
ctx->iface->ShaderUniformGetSamplers(n2p(program), ctx->tex.sampler2tmu);
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
if (0 <= ctx->tex.sampler2tmu[i])
ctx->iface->SetSampler(ctx->iface, i, ctx->tex.tmus[ctx->tex.sampler2tmu[i]]);
}

View File

@ -1,129 +0,0 @@
#include "gles2context.h"
GLES2Context::GLES2Context()
{
memset(this, 0, sizeof *this);
assert((void *)&rasterizer == &rasterizer.interface);
InitializeGGLState(&rasterizer.interface);
iface = &rasterizer.interface;
printf("gl->rasterizer.PickScanLine(%p) = %p \n", &rasterizer.PickScanLine, rasterizer.PickScanLine);
assert(rasterizer.PickRaster);
assert(rasterizer.PickScanLine);
InitializeTextures();
InitializeVertices();
}
GLES2Context::~GLES2Context()
{
UninitializeTextures();
UninitializeVertices();
UninitializeGGLState(&rasterizer.interface);
}
void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->BlendColor(ctx->iface, red, green, blue, alpha);
}
void glBlendEquation( GLenum mode )
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->BlendEquationSeparate(ctx->iface, mode, mode);
}
void glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->BlendEquationSeparate(ctx->iface, modeRGB, modeAlpha);
}
void glBlendFunc(GLenum sfactor, GLenum dfactor)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->BlendFuncSeparate(ctx->iface, sfactor, dfactor, sfactor, dfactor);
}
void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->BlendFuncSeparate(ctx->iface, srcRGB, dstRGB, srcAlpha, dstAlpha);
}
void glClear(GLbitfield mask)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->Clear(ctx->iface, mask);
}
void glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ClearColor(ctx->iface, red, green, blue, alpha);
}
void glClearDepthf(GLclampf depth)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ClearDepthf(ctx->iface, depth);
}
void glClearStencil(GLint s)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->ClearStencil(ctx->iface, s);
}
void glCullFace(GLenum mode)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->CullFace(ctx->iface, mode);
}
void glDisable(GLenum cap)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->EnableDisable(ctx->iface, cap, false);
}
void glEnable(GLenum cap)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->EnableDisable(ctx->iface, cap, true);
}
void glFinish(void)
{
// do nothing
}
void glFrontFace(GLenum mode)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->iface->FrontFace(ctx->iface, mode);
}
void glFlush(void)
{
// do nothing
}
void glHint(GLenum target, GLenum mode)
{
// do nothing
}
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
{
// LOGD("agl2: glScissor not implemented x=%d y=%d width=%d height=%d", x, y, width, height);
//CALL_GL_API(glScissor, x, y, width, height);
}
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glViewport x=%d y=%d width=%d height=%d", x, y, width, height);
ctx->iface->Viewport(ctx->iface, x, y, width, height);
}

View File

@ -1,534 +0,0 @@
#include "gles2context.h"
//#undef LOGD
//#define LOGD(...)
#define API_ENTRY
#define CALL_GL_API(NAME,...) LOGD("?"#NAME); assert(0);
#define CALL_GL_API_RETURN(NAME,...) LOGD("?"#NAME); assert(0); return 0;
static inline GGLTexture * AllocTexture()
{
GGLTexture * tex = (GGLTexture *)calloc(1, sizeof(GGLTexture));
tex->minFilter = GGLTexture::GGL_LINEAR; // should be NEAREST_ MIPMAP_LINEAR
tex->magFilter = GGLTexture::GGL_LINEAR;
return tex;
}
void GLES2Context::InitializeTextures()
{
tex.textures = std::map<GLuint, GGLTexture *>(); // the entire struct has been zeroed in constructor
tex.tex2D = AllocTexture();
tex.textures[GL_TEXTURE_2D] = tex.tex2D;
tex.texCube = AllocTexture();
tex.textures[GL_TEXTURE_CUBE_MAP] = tex.texCube;
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++) {
tex.tmus[i] = NULL;
tex.sampler2tmu[i] = NULL;
}
tex.active = 0;
tex.free = max(GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP) + 1;
tex.tex2D->format = GGL_PIXEL_FORMAT_RGBA_8888;
tex.tex2D->type = GL_TEXTURE_2D;
tex.tex2D->levelCount = 1;
tex.tex2D->wrapS = tex.tex2D->wrapT = GGLTexture::GGL_REPEAT;
tex.tex2D->minFilter = tex.tex2D->magFilter = GGLTexture::GGL_NEAREST;
tex.tex2D->width = tex.tex2D->height = 1;
tex.tex2D->levels = malloc(4);
*(unsigned *)tex.tex2D->levels = 0xff000000;
tex.texCube->format = GGL_PIXEL_FORMAT_RGBA_8888;
tex.texCube->type = GL_TEXTURE_CUBE_MAP;
tex.texCube->levelCount = 1;
tex.texCube->wrapS = tex.texCube->wrapT = GGLTexture::GGL_REPEAT;
tex.texCube->minFilter = tex.texCube->magFilter = GGLTexture::GGL_NEAREST;
tex.texCube->width = tex.texCube->height = 1;
tex.texCube->levels = malloc(4 * 6);
static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
0xff00ffff, 0xffffff00, 0xffff00ff
};
memcpy(tex.texCube->levels, texels, sizeof texels);
//texture.levelCount = GenerateMipmaps(texture.levels, texture.width, texture.height);
// static unsigned texels [6] = {0xff0000ff, 0xff00ff00, 0xffff0000,
// 0xff00ffff, 0xffffff00, 0xffff00ff};
// memcpy(texture.levels[0], texels, sizeof texels);
// texture.format = GGL_PIXEL_FORMAT_RGBA_8888;
// texture.width = texture.height = 1;
//texture.height /= 6;
//texture.type = GL_TEXTURE_CUBE_MAP;
tex.unpack = 4;
}
void GLES2Context::TextureState::UpdateSampler(GGLInterface * iface, unsigned tmu)
{
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
if (tmu == sampler2tmu[i])
iface->SetSampler(iface, i, tmus[tmu]);
}
void GLES2Context::UninitializeTextures()
{
for (std::map<GLuint, GGLTexture *>::iterator it = tex.textures.begin(); it != tex.textures.end(); it++) {
if (!it->second)
continue;
free(it->second->levels);
free(it->second);
}
}
static inline void GetFormatAndBytesPerPixel(const GLenum format, unsigned * bytesPerPixel,
GGLPixelFormat * texFormat)
{
switch (format) {
case GL_ALPHA:
*texFormat = GGL_PIXEL_FORMAT_A_8;
*bytesPerPixel = 1;
break;
case GL_LUMINANCE:
*texFormat = GGL_PIXEL_FORMAT_L_8;
*bytesPerPixel = 1;
break;
case GL_LUMINANCE_ALPHA:
*texFormat = GGL_PIXEL_FORMAT_LA_88;
*bytesPerPixel = 2;
break;
case GL_RGB:
*texFormat = GGL_PIXEL_FORMAT_RGB_888;
*bytesPerPixel = 3;
break;
case GL_RGBA:
*texFormat = GGL_PIXEL_FORMAT_RGBA_8888;
*bytesPerPixel = 4;
break;
// internal formats to avoid conversion
case GL_UNSIGNED_SHORT_5_6_5:
*texFormat = GGL_PIXEL_FORMAT_RGB_565;
*bytesPerPixel = 2;
break;
default:
assert(0);
return;
}
}
static inline void CopyTexture(char * dst, const char * src, const unsigned bytesPerPixel,
const unsigned sx, const unsigned sy, const unsigned sw,
const unsigned dx, const unsigned dy, const unsigned dw,
const unsigned w, const unsigned h)
{
const unsigned bpp = bytesPerPixel;
if (dw == sw && dw == w && sx == 0 && dx == 0)
memcpy(dst + dy * dw * bpp, src + sy * sw * bpp, w * h * bpp);
else
for (unsigned y = 0; y < h; y++)
memcpy(dst + ((dy + y) * dw + dx) * bpp, src + ((sy + y) * sw + sx) * bpp, w * bpp);
}
void glActiveTexture(GLenum texture)
{
GLES2_GET_CONST_CONTEXT(ctx);
unsigned index = texture - GL_TEXTURE0;
assert(NELEM(ctx->tex.tmus) > index);
// LOGD("agl2: glActiveTexture %u", index);
ctx->tex.active = index;
}
void glBindTexture(GLenum target, GLuint texture)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glBindTexture target=0x%.4X texture=%u active=%u", target, texture, ctx->tex.active);
std::map<GLuint, GGLTexture *>::iterator it = ctx->tex.textures.find(texture);
GGLTexture * tex = NULL;
if (it != ctx->tex.textures.end()) {
tex = it->second;
if (!tex) {
tex = AllocTexture();
tex->type = target;
it->second = tex;
// LOGD("agl2: glBindTexture allocTexture");
}
// else
// LOGD("agl2: glBindTexture bind existing texture");
assert(target == tex->type);
} else if (0 == texture) {
if (GL_TEXTURE_2D == target)
{
tex = ctx->tex.tex2D;
// LOGD("agl2: glBindTexture bind default tex2D");
}
else if (GL_TEXTURE_CUBE_MAP == target)
{
tex = ctx->tex.texCube;
// LOGD("agl2: glBindTexture bind default texCube");
}
else
assert(0);
} else {
if (texture <= ctx->tex.free)
ctx->tex.free = texture + 1;
tex = AllocTexture();
tex->type = target;
ctx->tex.textures[texture] = tex;
// LOGD("agl2: glBindTexture new texture=%u", texture);
}
ctx->tex.tmus[ctx->tex.active] = tex;
// LOGD("agl2: glBindTexture format=0x%.2X w=%u h=%u levels=%p", tex->format,
// tex->width, tex->height, tex->levels);
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
}
void API_ENTRY(glCompressedTexImage2D)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid* data)
{
CALL_GL_API(glCompressedTexImage2D, target, level, internalformat, width, height, border, imageSize, data);
}
void API_ENTRY(glCompressedTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid* data)
{
CALL_GL_API(glCompressedTexSubImage2D, target, level, xoffset, yoffset, width, height, format, imageSize, data);
}
void glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat,
GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glCopyTexImage2D target=0x%.4X internalformat=0x%.4X", target, internalformat);
// LOGD("x=%d y=%d width=%d height=%d border=%d level=%d ", x, y, width, height, border, level);
assert(0 == border);
assert(0 == level);
unsigned bytesPerPixel = 0;
GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
GetFormatAndBytesPerPixel(internalformat, &bytesPerPixel, &texFormat);
assert(texFormat == ctx->rasterizer.frameSurface.format);
// LOGD("texFormat=0x%.2X bytesPerPixel=%d \n", texFormat, bytesPerPixel);
unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
assert(ctx->tex.tmus[ctx->tex.active]);
assert(y + height <= ctx->rasterizer.frameSurface.height);
assert(x + width <= ctx->rasterizer.frameSurface.width);
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
tex.width = width;
tex.height = height;
tex.levelCount = 1;
tex.format = texFormat;
switch (target) {
case GL_TEXTURE_2D:
tex.levels = realloc(tex.levels, totalSize);
CopyTexture((char *)tex.levels, (const char *)ctx->rasterizer.frameSurface.data, bytesPerPixel,
x, y, ctx->rasterizer.frameSurface.width, 0, 0, width, width, height);
break;
default:
assert(0);
return;
}
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
}
void glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
{
// x, y are src offset
// xoffset and yoffset are dst offset
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glCopyTexSubImage2D target=0x%.4X level=%d", target, level);
// LOGD("xoffset=%d yoffset=%d x=%d y=%d width=%d height=%d", xoffset, yoffset, x, y, width, height);
assert(0 == level);
unsigned bytesPerPixel = 4;
unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
assert(ctx->tex.tmus[ctx->tex.active]);
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
assert(tex.format == ctx->rasterizer.frameSurface.format);
assert(GGL_PIXEL_FORMAT_RGBA_8888 == tex.format);
const unsigned srcWidth = ctx->rasterizer.frameSurface.width;
const unsigned srcHeight = ctx->rasterizer.frameSurface.height;
assert(x >= 0 && y >= 0);
assert(xoffset >= 0 && yoffset >= 0);
assert(x + width <= srcWidth);
assert(y + height <= srcHeight);
assert(xoffset + width <= tex.width);
assert(yoffset + height <= tex.height);
switch (target) {
case GL_TEXTURE_2D:
CopyTexture((char *)tex.levels, (const char *)ctx->rasterizer.frameSurface.data, bytesPerPixel,
x, y, srcWidth, xoffset, yoffset, tex.width, width, height);
break;
default:
assert(0);
return;
}
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
}
void glDeleteTextures(GLsizei n, const GLuint* textures)
{
GLES2_GET_CONST_CONTEXT(ctx);
for (unsigned i = 0; i < n; i++) {
std::map<GLuint, GGLTexture *>::iterator it = ctx->tex.textures.find(textures[i]);
if (it == ctx->tex.textures.end())
continue;
ctx->tex.free = min(ctx->tex.free, textures[i]);
for (unsigned i = 0; i < GGL_MAXCOMBINEDTEXTUREIMAGEUNITS; i++)
if (ctx->tex.tmus[i] == it->second) {
if (GL_TEXTURE_2D == it->second->type)
ctx->tex.tmus[i] = ctx->tex.tex2D;
else if (GL_TEXTURE_CUBE_MAP == it->second->type)
ctx->tex.tmus[i] = ctx->tex.texCube;
else
assert(0);
ctx->tex.UpdateSampler(ctx->iface, i);
}
if (it->second) {
free(it->second->levels);
free(it->second);
}
ctx->tex.textures.erase(it);
}
}
void glGenTextures(GLsizei n, GLuint* textures)
{
GLES2_GET_CONST_CONTEXT(ctx);
for (unsigned i = 0; i < n; i++) {
textures[i] = 0;
for (ctx->tex.free; ctx->tex.free < 0xffffffffu; ctx->tex.free++)
if (ctx->tex.textures.find(ctx->tex.free) == ctx->tex.textures.end()) {
ctx->tex.textures[ctx->tex.free] = NULL;
textures[i] = ctx->tex.free;
ctx->tex.free++;
break;
}
assert(textures[i]);
}
}
void API_ENTRY(glGetTexParameterfv)(GLenum target, GLenum pname, GLfloat* params)
{
CALL_GL_API(glGetTexParameterfv, target, pname, params);
}
void API_ENTRY(glGetTexParameteriv)(GLenum target, GLenum pname, GLint* params)
{
CALL_GL_API(glGetTexParameteriv, target, pname, params);
}
GLboolean glIsTexture(GLuint texture)
{
GLES2_GET_CONST_CONTEXT(ctx);
if (ctx->tex.textures.find(texture) == ctx->tex.textures.end())
return GL_FALSE;
else
return GL_TRUE;
}
void glPixelStorei(GLenum pname, GLint param)
{
GLES2_GET_CONST_CONTEXT(ctx);
assert(GL_UNPACK_ALIGNMENT == pname);
assert(1 == param || 2 == param || 4 == param || 8 == param);
// LOGD("\n*\n* agl2: glPixelStorei not implemented pname=0x%.4X param=%d \n*", pname, param);
ctx->tex.unpack = param;
// CALL_GL_API(glPixelStorei, pname, param);
}
void glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width,
GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid* pixels)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glTexImage2D internalformat=0x%.4X format=0x%.4X type=0x%.4X \n", internalformat, format, type);
// LOGD("width=%d height=%d border=%d level=%d pixels=%p \n", width, height, border, level, pixels);
switch (type) {
case GL_UNSIGNED_BYTE:
break;
case GL_UNSIGNED_SHORT_5_6_5:
internalformat = format = GL_UNSIGNED_SHORT_5_6_5;
assert(4 == ctx->tex.unpack);
break;
default:
assert(0);
}
assert(internalformat == format);
assert(0 == border);
if (0 != level) {
LOGD("agl2: glTexImage2D level=%d", level);
return;
}
unsigned bytesPerPixel = 0;
GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
GetFormatAndBytesPerPixel(format, &bytesPerPixel, &texFormat);
assert(texFormat && bytesPerPixel);
// LOGD("texFormat=0x%.2X bytesPerPixel=%d active=%u", texFormat, bytesPerPixel, ctx->tex.active);
unsigned offset = 0, size = width * height * bytesPerPixel, totalSize = size;
assert(ctx->tex.tmus[ctx->tex.active]);
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
tex.width = width;
tex.height = height;
tex.levelCount = 1;
tex.format = texFormat;
switch (target) {
case GL_TEXTURE_2D:
assert(GL_TEXTURE_2D == ctx->tex.tmus[ctx->tex.active]->type);
offset = 0;
break;
break;
case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
assert(GL_TEXTURE_CUBE_MAP == ctx->tex.tmus[ctx->tex.active]->type);
assert(width == height);
offset = (target - GL_TEXTURE_CUBE_MAP_POSITIVE_X) * size;
totalSize = 6 * size;
break;
default:
assert(0);
return;
}
tex.levels = realloc(tex.levels, totalSize);
if (pixels)
CopyTexture((char *)tex.levels, (const char *)pixels, bytesPerPixel, 0, 0, width, 0, 0, width, width, height);
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
}
void glTexParameterf(GLenum target, GLenum pname, GLfloat param)
{
// LOGD("agl2: glTexParameterf target=0x%.4X pname=0x%.4X param=%f", target, pname, param);
glTexParameteri(target, pname, param);
}
void API_ENTRY(glTexParameterfv)(GLenum target, GLenum pname, const GLfloat* params)
{
CALL_GL_API(glTexParameterfv, target, pname, params);
}
void glTexParameteri(GLenum target, GLenum pname, GLint param)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("alg2: glTexParameteri target=0x%.0X pname=0x%.4X param=0x%.4X",
// target, pname, param);
assert(ctx->tex.tmus[ctx->tex.active]);
assert(target == ctx->tex.tmus[ctx->tex.active]->type);
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
switch (pname) {
case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T:
GGLTexture::GGLTextureWrap wrap;
switch (param) {
case GL_REPEAT:
wrap = GGLTexture::GGL_REPEAT;
break;
case GL_CLAMP_TO_EDGE:
wrap = GGLTexture::GGL_CLAMP_TO_EDGE;
break;
case GL_MIRRORED_REPEAT:
wrap = GGLTexture::GGL_MIRRORED_REPEAT;
break;
default:
assert(0);
return;
}
if (GL_TEXTURE_WRAP_S == pname)
tex.wrapS = wrap;
else
tex.wrapT = wrap;
break;
case GL_TEXTURE_MIN_FILTER:
switch (param) {
case GL_NEAREST:
tex.minFilter = GGLTexture::GGL_NEAREST;
break;
case GL_LINEAR:
tex.minFilter = GGLTexture::GGL_LINEAR;
break;
case GL_NEAREST_MIPMAP_NEAREST:
// tex.minFilter = GGLTexture::GGL_NEAREST_MIPMAP_NEAREST;
break;
case GL_NEAREST_MIPMAP_LINEAR:
// tex.minFilter = GGLTexture::GGL_NEAREST_MIPMAP_LINEAR;
break;
case GL_LINEAR_MIPMAP_NEAREST:
// tex.minFilter = GGLTexture::GGL_LINEAR_MIPMAP_NEAREST;
break;
case GL_LINEAR_MIPMAP_LINEAR:
// tex.minFilter = GGLTexture::GGL_LINEAR_MIPMAP_LINEAR;
break;
default:
assert(0);
return;
}
break;
case GL_TEXTURE_MAG_FILTER:
switch (param) {
case GL_NEAREST:
tex.minFilter = GGLTexture::GGL_NEAREST;
break;
case GL_LINEAR:
tex.minFilter = GGLTexture::GGL_LINEAR;
break;
default:
assert(0);
return;
}
break;
default:
assert(0);
return;
}
// implementation restriction
if (tex.magFilter != tex.minFilter)
tex.magFilter = tex.minFilter = GGLTexture::GGL_LINEAR;
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
}
void API_ENTRY(glTexParameteriv)(GLenum target, GLenum pname, const GLint* params)
{
CALL_GL_API(glTexParameteriv, target, pname, params);
}
void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid* pixels)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glTexSubImage2D target=0x%.4X level=%d xoffset=%d yoffset=%d width=%d height=%d format=0x%.4X type=0x%.4X pixels=%p",
// target, level, xoffset, yoffset, width, height, format, type, pixels);
assert(0 == level);
assert(target == ctx->tex.tmus[ctx->tex.active]->type);
switch (type) {
case GL_UNSIGNED_BYTE:
break;
case GL_UNSIGNED_SHORT_5_6_5:
format = GL_UNSIGNED_SHORT_5_6_5;
assert(4 == ctx->tex.unpack);
break;
default:
assert(0);
}
GGLTexture & tex = *ctx->tex.tmus[ctx->tex.active];
GGLPixelFormat texFormat = GGL_PIXEL_FORMAT_UNKNOWN;
unsigned bytesPerPixel = 0;
GetFormatAndBytesPerPixel(format, &bytesPerPixel, &texFormat);
assert(texFormat == tex.format);
assert(GL_UNSIGNED_BYTE == type);
switch (target) {
case GL_TEXTURE_2D:
CopyTexture((char *)tex.levels, (const char *)pixels, bytesPerPixel, 0, 0, width, xoffset,
yoffset, tex.width, width, height);
break;
default:
assert(0);
}
ctx->tex.UpdateSampler(ctx->iface, ctx->tex.active);
}

View File

@ -1,373 +0,0 @@
#include "gles2context.h"
//#undef LOGD
//#define LOGD(...)
void GLES2Context::InitializeVertices()
{
vert.vbos = std::map<GLuint, VBO *>(); // the entire struct has been zeroed in constructor
vert.free = 1;
vert.vbo = NULL;
vert.indices = NULL;
for (unsigned i = 0; i < GGL_MAXVERTEXATTRIBS; i++)
vert.defaultAttribs[i] = Vector4(0,0,0,1);
}
void GLES2Context::UninitializeVertices()
{
for (std::map<GLuint, VBO *>::iterator it = vert.vbos.begin(); it != vert.vbos.end(); it++) {
if (!it->second)
continue;
free(it->second->data);
free(it->second);
}
}
static inline void FetchElement(const GLES2Context * ctx, const unsigned index,
const unsigned maxAttrib, VertexInput * elem)
{
for (unsigned i = 0; i < maxAttrib; i++) {
{
unsigned size = 0;
if (ctx->vert.attribs[i].enabled) {
const char * ptr = (const char *)ctx->vert.attribs[i].ptr;
ptr += ctx->vert.attribs[i].stride * index;
memcpy(elem->attributes + i, ptr, ctx->vert.attribs[i].size * sizeof(float));
size = ctx->vert.attribs[i].size;
// LOGD("agl2: FetchElement %d attribs size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
} else {
// LOGD("agl2: FetchElement %d default %.2f,%.2f,%.2f,%.2f", i, ctx->vert.defaultAttribs[i].x,
// ctx->vert.defaultAttribs[i].y, ctx->vert.defaultAttribs[i].z, ctx->vert.defaultAttribs[i].w);
}
switch (size) {
case 0: // fall through
elem->attributes[i].x = ctx->vert.defaultAttribs[i].x;
case 1: // fall through
elem->attributes[i].y = ctx->vert.defaultAttribs[i].y;
case 2: // fall through
elem->attributes[i].z = ctx->vert.defaultAttribs[i].z;
case 3: // fall through
elem->attributes[i].w = ctx->vert.defaultAttribs[i].w;
case 4:
break;
default:
assert(0);
break;
}
// LOGD("agl2: FetchElement %d size=%d %.2f,%.2f,%.2f,%.2f", i, size, elem->attributes[i].x,
// elem->attributes[i].y, elem->attributes[i].z, elem->attributes[i].w);
}
}
}
template<typename IndexT> static void DrawElementsTriangles(const GLES2Context * ctx,
const unsigned count, const IndexT * indices, const unsigned maxAttrib)
{
VertexInput v[3];
if (ctx->vert.indices)
indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
for (unsigned i = 0; i < count; i += 3) {
for (unsigned j = 0; j < 3; j++)
FetchElement(ctx, indices[i + j], maxAttrib, v + j);
ctx->iface->DrawTriangle(ctx->iface, v, v + 1, v + 2);
}
}
static void DrawArraysTriangles(const GLES2Context * ctx, const unsigned first,
const unsigned count, const unsigned maxAttrib)
{
// LOGD("agl: DrawArraysTriangles=%p", DrawArraysTriangles);
VertexInput v[3];
for (unsigned i = 2; i < count; i+=3) {
// TODO: fix order
FetchElement(ctx, first + i - 2, maxAttrib, v + 0);
FetchElement(ctx, first + i - 1, maxAttrib, v + 1);
FetchElement(ctx, first + i - 0, maxAttrib, v + 2);
ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
}
// LOGD("agl: DrawArraysTriangles end");
}
template<typename IndexT> static void DrawElementsTriangleStrip(const GLES2Context * ctx,
const unsigned count, const IndexT * indices, const unsigned maxAttrib)
{
VertexInput v[3];
if (ctx->vert.indices)
indices = (IndexT *)((char *)ctx->vert.indices->data + (long)indices);
// LOGD("agl2: DrawElementsTriangleStrip");
// for (unsigned i = 0; i < count; i++)
// LOGD("indices[%d] = %d", i, indices[i]);
FetchElement(ctx, indices[0], maxAttrib, v + 0);
FetchElement(ctx, indices[1], maxAttrib, v + 1);
for (unsigned i = 2; i < count; i ++) {
FetchElement(ctx, indices[i], maxAttrib, v + i % 3);
ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
}
// for (unsigned i = 2; i < count; i++) {
// FetchElement(ctx, indices[i - 2], maxAttrib, v + 0);
// FetchElement(ctx, indices[i - 1], maxAttrib, v + 1);
// FetchElement(ctx, indices[i - 0], maxAttrib, v + 2);
// ctx->iface->DrawTriangle(ctx->iface, v + 0, v + 1, v + 2);
// }
}
static void DrawArraysTriangleStrip(const GLES2Context * ctx, const unsigned first,
const unsigned count, const unsigned maxAttrib)
{
VertexInput v[3];
FetchElement(ctx, first, maxAttrib, v + 0);
FetchElement(ctx, first + 1, maxAttrib, v + 1);
for (unsigned i = 2; i < count; i++) {
// TODO: fix order
FetchElement(ctx, first + i, maxAttrib, v + i % 3);
ctx->iface->DrawTriangle(ctx->iface, v + (i - 2) % 3, v + (i - 1) % 3 , v + (i + 0) % 3);
}
}
void glBindBuffer(GLenum target, GLuint buffer)
{
GLES2_GET_CONST_CONTEXT(ctx);
VBO * vbo = NULL;
if (0 != buffer) {
std::map<GLuint, VBO *>::iterator it = ctx->vert.vbos.find(buffer);
if (it != ctx->vert.vbos.end()) {
vbo = it->second;
if (!vbo)
vbo = (VBO *)calloc(1, sizeof(VBO));
it->second = vbo;
} else
assert(0);
}
if (GL_ARRAY_BUFFER == target)
ctx->vert.vbo = vbo;
else if (GL_ELEMENT_ARRAY_BUFFER == target)
ctx->vert.indices = vbo;
else
assert(0);
assert(vbo || buffer == 0);
// LOGD("\n*\n glBindBuffer 0x%.4X=%d ", target, buffer);
}
void glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
{
GLES2_GET_CONST_CONTEXT(ctx);
if (GL_ARRAY_BUFFER == target) {
assert(ctx->vert.vbo);
ctx->vert.vbo->data = realloc(ctx->vert.vbo->data, size);
ctx->vert.vbo->size = size;
ctx->vert.vbo->usage = usage;
if (data)
memcpy(ctx->vert.vbo->data, data, size);
} else if (GL_ELEMENT_ARRAY_BUFFER == target) {
assert(ctx->vert.indices);
ctx->vert.indices->data = realloc(ctx->vert.indices->data, size);
ctx->vert.indices->size = size;
ctx->vert.indices->usage = usage;
if (data)
memcpy(ctx->vert.indices->data, data, size);
} else
assert(0);
// LOGD("\n*\n glBufferData target=0x%.4X size=%u data=%p usage=0x%.4X \n",
// target, size, data, usage);
}
void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
{
GLES2_GET_CONST_CONTEXT(ctx);
if (GL_ARRAY_BUFFER == target)
{
assert(ctx->vert.vbo);
assert(0 <= offset);
assert(0 <= size);
assert(offset + size <= ctx->vert.vbo->size);
memcpy((char *)ctx->vert.vbo->data + offset, data, size);
}
else
assert(0);
}
void glDeleteBuffers(GLsizei n, const GLuint* buffers)
{
GLES2_GET_CONST_CONTEXT(ctx);
for (unsigned i = 0; i < n; i++) {
std::map<GLuint, VBO*>::iterator it = ctx->vert.vbos.find(buffers[i]);
if (it == ctx->vert.vbos.end())
continue;
ctx->vert.free = min(ctx->vert.free, buffers[i]);
if (it->second == ctx->vert.vbo)
ctx->vert.vbo = NULL;
else if (it->second == ctx->vert.indices)
ctx->vert.indices = NULL;
if (it->second) {
free(it->second->data);
free(it->second);
}
}
}
void glDisableVertexAttribArray(GLuint index)
{
GLES2_GET_CONST_CONTEXT(ctx);
assert(GGL_MAXVERTEXATTRIBS > index);
ctx->vert.attribs[index].enabled = false;
}
void glDrawArrays(GLenum mode, GLint first, GLsizei count)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glDrawArrays=%p", glDrawArrays);
assert(ctx->rasterizer.CurrentProgram);
assert(0 <= first);
int maxAttrib = -1;
ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
switch (mode) {
case GL_TRIANGLE_STRIP:
DrawArraysTriangleStrip(ctx, first, count, maxAttrib);
break;
case GL_TRIANGLES:
DrawArraysTriangles(ctx, first, count, maxAttrib);
break;
default:
LOGE("agl2: glDrawArrays unsupported mode: 0x%.4X \n", mode);
assert(0);
break;
}
// LOGD("agl2: glDrawArrays end");
}
void glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
{
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("agl2: glDrawElements=%p mode=0x%.4X count=%d type=0x%.4X indices=%p",
// glDrawElements, mode, count, type, indices);
if (!ctx->rasterizer.CurrentProgram)
return;
int maxAttrib = -1;
ctx->iface->ShaderProgramGetiv(ctx->rasterizer.CurrentProgram, GL_ACTIVE_ATTRIBUTES, &maxAttrib);
assert(0 <= maxAttrib && GGL_MAXVERTEXATTRIBS >= maxAttrib);
// LOGD("agl2: glDrawElements mode=0x%.4X type=0x%.4X count=%d program=%p indices=%p \n",
// mode, type, count, ctx->rasterizer.CurrentProgram, indices);
switch (mode) {
case GL_TRIANGLES:
if (GL_UNSIGNED_SHORT == type)
DrawElementsTriangles<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
else
assert(0);
break;
case GL_TRIANGLE_STRIP:
if (GL_UNSIGNED_SHORT == type)
DrawElementsTriangleStrip<unsigned short>(ctx, count, (unsigned short *)indices, maxAttrib);
else
assert(0);
break;
default:
assert(0);
}
// LOGD("agl2: glDrawElements end");
}
void glEnableVertexAttribArray(GLuint index)
{
GLES2_GET_CONST_CONTEXT(ctx);
ctx->vert.attribs[index].enabled = true;
// LOGD("agl2: glEnableVertexAttribArray %d \n", index);
}
void glGenBuffers(GLsizei n, GLuint* buffers)
{
GLES2_GET_CONST_CONTEXT(ctx);
for (unsigned i = 0; i < n; i++) {
buffers[i] = 0;
for (ctx->vert.free; ctx->vert.free < 0xffffffffu; ctx->vert.free++) {
if (ctx->vert.vbos.find(ctx->vert.free) == ctx->vert.vbos.end()) {
ctx->vert.vbos[ctx->vert.free] = NULL;
buffers[i] = ctx->vert.free;
// LOGD("glGenBuffers %d \n", buffers[i]);
ctx->vert.free++;
break;
}
}
assert(buffers[i]);
}
}
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid* ptr)
{
GLES2_GET_CONST_CONTEXT(ctx);
assert(GL_FLOAT == type);
assert(0 < size && 4 >= size);
ctx->vert.attribs[index].size = size;
ctx->vert.attribs[index].type = type;
ctx->vert.attribs[index].normalized = normalized;
if (0 == stride)
ctx->vert.attribs[index].stride = size * sizeof(float);
else if (stride > 0)
ctx->vert.attribs[index].stride = stride;
else
assert(0);
// LOGD("\n*\n*\n* agl2: glVertexAttribPointer program=%u index=%d size=%d stride=%d ptr=%p \n*\n*",
// unsigned(ctx->rasterizer.CurrentProgram) ^ 0x04dc18f9, index, size, stride, ptr);
if (ctx->vert.vbo)
ctx->vert.attribs[index].ptr = (char *)ctx->vert.vbo->data + (long)ptr;
else
ctx->vert.attribs[index].ptr = ptr;
// const float * attrib = (const float *)ctx->vert.attribs[index].ptr;
// for (unsigned i = 0; i < 3; i++)
// if (3 == size)
// LOGD("%.2f %.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1], attrib[i * 3 + 2]);
// else if (2 == size)
// LOGD("%.2f %.2f", attrib[i * 3 + 0], attrib[i * 3 + 1]);
}
void glVertexAttrib1f(GLuint indx, GLfloat x)
{
glVertexAttrib4f(indx, x,0,0,1);
}
void glVertexAttrib1fv(GLuint indx, const GLfloat* values)
{
glVertexAttrib4f(indx, values[0],0,0,1);
}
void glVertexAttrib2f(GLuint indx, GLfloat x, GLfloat y)
{
glVertexAttrib4f(indx, x,y,0,1);
}
void glVertexAttrib2fv(GLuint indx, const GLfloat* values)
{
glVertexAttrib4f(indx, values[0],values[1],0,1);
}
void glVertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z)
{
glVertexAttrib4f(indx, x,y,z,1);
}
void glVertexAttrib3fv(GLuint indx, const GLfloat* values)
{
glVertexAttrib4f(indx, values[0],values[1],values[2],1);
}
void glVertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
assert(GGL_MAXVERTEXATTRIBS > indx);
GLES2_GET_CONST_CONTEXT(ctx);
// LOGD("\n*\n*\n agl2: glVertexAttrib4f %d %.2f,%.2f,%.2f,%.2f \n*\n*", indx, x, y, z, w);
ctx->vert.defaultAttribs[indx] = Vector4(x,y,z,w);
assert(0);
}
void glVertexAttrib4fv(GLuint indx, const GLfloat* values)
{
glVertexAttrib4f(indx, values[0], values[1], values[2], values[3]);
}

View File

@ -49,22 +49,6 @@ using namespace android;
// ----------------------------------------------------------------------------
static char const * const sVendorString = "Android";
static char const * const sVersionString = "1.4 Android META-EGL";
static char const * const sClientApiString = "OpenGL ES";
static char const * const sExtensionString =
"EGL_KHR_image "
"EGL_KHR_image_base "
"EGL_KHR_image_pixmap "
"EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
"EGL_KHR_fence_sync "
"EGL_ANDROID_image_native_buffer "
"EGL_ANDROID_swap_rectangle "
"EGL_NV_system_time "
;
struct extention_map_t {
const char* name;
__eglMustCastToProperFunctionPointerType address;
@ -79,8 +63,6 @@ static const extention_map_t sExtentionMap[] = {
(__eglMustCastToProperFunctionPointerType)&eglCreateImageKHR },
{ "eglDestroyImageKHR",
(__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR },
{ "eglSetSwapRectangleANDROID",
(__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID },
{ "eglGetSystemTimeFrequencyNV",
(__eglMustCastToProperFunctionPointerType)&eglGetSystemTimeFrequencyNV },
{ "eglGetSystemTimeNV",
@ -978,13 +960,13 @@ const char* eglQueryString(EGLDisplay dpy, EGLint name)
switch (name) {
case EGL_VENDOR:
return sVendorString;
return dp->getVendorString();
case EGL_VERSION:
return sVersionString;
return dp->getVersionString();
case EGL_EXTENSIONS:
return sExtensionString;
return dp->getExtensionString();
case EGL_CLIENT_APIS:
return sClientApiString;
return dp->getClientApiString();
}
return setError(EGL_BAD_PARAMETER, (const char *)0);
}
@ -1447,25 +1429,7 @@ EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute
// ANDROID extensions
// ----------------------------------------------------------------------------
EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw,
EGLint left, EGLint top, EGLint width, EGLint height)
{
clearError();
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
SurfaceRef _s(dp, draw);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
egl_surface_t const * const s = get_surface(draw);
if (s->cnx->egl.eglSetSwapRectangleANDROID) {
return s->cnx->egl.eglSetSwapRectangleANDROID(
dp->disp[s->impl].dpy, s->surface, left, top, width, height);
}
return setError(EGL_BAD_DISPLAY, NULL);
}
/* ANDROID extensions entry-point go here */
// ----------------------------------------------------------------------------
// NVIDIA extensions

View File

@ -14,6 +14,8 @@
** limitations under the License.
*/
#include <string.h>
#include "egl_cache.h"
#include "egl_display.h"
#include "egl_object.h"
@ -25,6 +27,36 @@
namespace android {
// ----------------------------------------------------------------------------
static char const * const sVendorString = "Android";
static char const * const sVersionString = "1.4 Android META-EGL";
static char const * const sClientApiString = "OpenGL ES";
// this is the list of EGL extensions that are exposed to applications
// some of them are mandatory because used by the ANDROID system.
//
// mandatory extensions are required per the CDD and not explicitly
// checked during EGL initialization. the system *assumes* these extensions
// are present. the system may not function properly if some mandatory
// extensions are missing.
//
// NOTE: sExtensionString MUST be have a single space as the last character.
//
static char const * const sExtensionString =
"EGL_KHR_image " // mandatory
"EGL_KHR_image_base " // mandatory
"EGL_KHR_image_pixmap "
"EGL_KHR_gl_texture_2D_image "
"EGL_KHR_gl_texture_cubemap_image "
"EGL_KHR_gl_renderbuffer_image "
"EGL_KHR_fence_sync "
"EGL_NV_system_time "
"EGL_ANDROID_image_native_buffer " // mandatory
;
// extensions not exposed to applications but used by the ANDROID system
// "EGL_ANDROID_recordable " // mandatory
// "EGL_ANDROID_blob_cache " // strongly recommended
extern void initEglTraceLevel();
extern void setGLHooksThreadSpecific(gl_hooks_t const *value);
@ -174,6 +206,36 @@ EGLBoolean egl_display_t::initialize(EGLint *major, EGLint *minor) {
}
}
// the query strings are per-display
mVendorString.setTo(sVendorString);
mVersionString.setTo(sVersionString);
mClientApiString.setTo(sClientApiString);
// we only add extensions that exist in at least one implementation
char const* start = sExtensionString;
char const* end;
do {
// find the space separating this extension for the next one
end = strchr(start, ' ');
if (end) {
// length of the extension string
const size_t len = end - start;
// NOTE: we could avoid the copy if we had strnstr.
const String8 ext(start, len);
// now go through all implementations and look for this extension
for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
// if we find it, add this extension string to our list
// (and don't forget the space)
const char* match = strstr(disp[i].queryString.extensions, ext.string());
if (match && (match[len] == ' ' || match[len] == 0)) {
mExtensionString.append(start, len+1);
}
}
// process the next extension string, and skip the space.
start = end + 1;
}
} while (end);
egl_cache_t::get()->initialize(this);
EGLBoolean res = EGL_FALSE;

View File

@ -29,6 +29,7 @@
#include <utils/SortedVector.h>
#include <utils/threads.h>
#include <utils/String8.h>
#include "egldefs.h"
#include "hooks.h"
@ -91,6 +92,11 @@ public:
inline bool isValid() const { return magic == '_dpy'; }
inline bool isAlive() const { return isValid(); }
char const * getVendorString() const { return mVendorString.string(); }
char const * getVersionString() const { return mVersionString.string(); }
char const * getClientApiString() const { return mClientApiString.string(); }
char const * getExtensionString() const { return mExtensionString.string(); }
inline uint32_t getRefsCount() const { return refs; }
struct strings_t {
@ -122,6 +128,10 @@ private:
uint32_t refs;
mutable Mutex lock;
SortedVector<egl_object_t*> objects;
String8 mVendorString;
String8 mVersionString;
String8 mClientApiString;
String8 mExtensionString;
};
// ----------------------------------------------------------------------------

View File

@ -284,22 +284,6 @@ void DisplayHardware::init(uint32_t dpy)
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
#ifdef EGL_ANDROID_swap_rectangle
if (extensions.hasExtension("EGL_ANDROID_swap_rectangle")) {
if (eglSetSwapRectangleANDROID(display, surface,
0, 0, mWidth, mHeight) == EGL_TRUE) {
// This could fail if this extension is not supported by this
// specific surface (of config)
mFlags |= SWAP_RECTANGLE;
}
}
// when we have the choice between PARTIAL_UPDATES and SWAP_RECTANGLE
// choose PARTIAL_UPDATES, which should be more efficient
if (mFlags & PARTIAL_UPDATES)
mFlags &= ~SWAP_RECTANGLE;
#endif
LOGI("EGL informations:");
LOGI("# of configs : %d", numConfigs);
LOGI("vendor : %s", extensions.getEglVendor());