diff options
Diffstat (limited to 'opengl')
47 files changed, 6056 insertions, 15 deletions
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 41207f77285a..8f2f974ba2d5 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -155,6 +155,8 @@ import android.view.SurfaceView; * */ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback { + private final static String TAG = "GLSurfaceView"; + private final static boolean LOG_ATTACH_DETACH = false; private final static boolean LOG_THREADS = false; private final static boolean LOG_PAUSE_RESUME = false; private final static boolean LOG_SURFACE = false; @@ -306,6 +308,7 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback if (mEGLWindowSurfaceFactory == null) { mEGLWindowSurfaceFactory = new DefaultWindowSurfaceFactory(); } + mRenderer = renderer; mGLThread = new GLThread(renderer); mGLThread.start(); } @@ -525,12 +528,42 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback /** * This method is used as part of the View class and is not normally * called or subclassed by clients of GLSurfaceView. + */ + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (LOG_ATTACH_DETACH) { + Log.d(TAG, "onAttachedToWindow reattach =" + mDetached); + } + if (mDetached && (mRenderer != null)) { + int renderMode = RENDERMODE_CONTINUOUSLY; + if (mGLThread != null) { + renderMode = mGLThread.getRenderMode(); + } + mGLThread = new GLThread(mRenderer); + if (renderMode != RENDERMODE_CONTINUOUSLY) { + mGLThread.setRenderMode(renderMode); + } + mGLThread.start(); + } + mDetached = false; + } + + /** + * This method is used as part of the View class and is not normally + * called or subclassed by clients of GLSurfaceView. * Must not be called before a renderer has been set. */ @Override protected void onDetachedFromWindow() { + if (LOG_ATTACH_DETACH) { + Log.d(TAG, "onDetachedFromWindow"); + } + if (mGLThread != null) { + mGLThread.requestExitAndWait(); + } + mDetached = true; super.onDetachedFromWindow(); - mGLThread.requestExitAndWait(); } // ---------------------------------------------------------------------- @@ -1727,6 +1760,8 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback private boolean mSizeChanged = true; private GLThread mGLThread; + private Renderer mRenderer; + private boolean mDetached; private EGLConfigChooser mEGLConfigChooser; private EGLContextFactory mEGLContextFactory; private EGLWindowSurfaceFactory mEGLWindowSurfaceFactory; diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp index 5c09dcc1a10e..7c496e7f097e 100644 --- a/opengl/libagl/egl.cpp +++ b/opengl/libagl/egl.cpp @@ -546,7 +546,9 @@ EGLBoolean egl_window_surface_v2_t::swapBuffers() if (!dirtyRegion.isEmpty()) { dirtyRegion.andSelf(Rect(buffer->width, buffer->height)); if (previousBuffer) { - const Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); + // This was const Region copyBack, but that causes an + // internal compile error on simulator builds + /*const*/ Region copyBack(Region::subtract(oldDirtyRegion, dirtyRegion)); if (!copyBack.isEmpty()) { void* prevBits; if (lock(previousBuffer, @@ -1980,7 +1982,7 @@ EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) if (egl_display_t::is_valid(dpy) == EGL_FALSE) return setError(EGL_BAD_DISPLAY, EGL_FALSE); // TODO: eglSwapInterval() - return setError(EGL_BAD_PARAMETER, EGL_FALSE); + return EGL_TRUE; } // ---------------------------------------------------------------------------- diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk index ae924cd6e5ba..c8041fc7f69e 100644 --- a/opengl/libs/Android.mk +++ b/opengl/libs/Android.mk @@ -8,6 +8,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ EGL/egl.cpp \ + EGL/trace.cpp \ EGL/getProcAddress.cpp.arm \ EGL/hooks.cpp \ EGL/Loader.cpp \ @@ -33,6 +34,7 @@ endif LOCAL_CFLAGS += -DLOG_TAG=\"libEGL\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES LOCAL_CFLAGS += -fvisibility=hidden +LOCAL_CFLAGS += -DEGL_TRACE=1 ifeq ($(TARGET_BOARD_PLATFORM),msm7k) LOCAL_CFLAGS += -DADRENO130=1 diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index ab260d582a70..f744b72df26f 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -59,6 +59,8 @@ static char const * const gExtensionString = "EGL_KHR_image " "EGL_KHR_image_base " "EGL_KHR_image_pixmap " + "EGL_KHR_gl_texture_2D_image " + "EGL_KHR_fence_sync " "EGL_ANDROID_image_native_buffer " "EGL_ANDROID_swap_rectangle " ; @@ -243,9 +245,23 @@ struct egl_image_t : public egl_object_t EGLImageKHR images[IMPL_NUM_IMPLEMENTATIONS]; }; +struct egl_sync_t : public egl_object_t +{ + typedef egl_object_t::LocalRef<egl_sync_t, EGLSyncKHR> Ref; + + egl_sync_t(EGLDisplay dpy, EGLContext context, EGLSyncKHR sync) + : dpy(dpy), context(context), sync(sync) + { + } + EGLDisplay dpy; + EGLContext context; + EGLSyncKHR sync; +}; + typedef egl_surface_t::Ref SurfaceRef; typedef egl_context_t::Ref ContextRef; typedef egl_image_t::Ref ImageRef; +typedef egl_sync_t::Ref SyncRef; struct tls_t { @@ -269,6 +285,58 @@ EGLAPI gl_hooks_t gHooks[2][IMPL_NUM_IMPLEMENTATIONS]; EGLAPI gl_hooks_t gHooksNoContext; EGLAPI pthread_key_t gGLWrapperKey = -1; +#if EGL_TRACE + +EGLAPI pthread_key_t gGLTraceKey = -1; + +// ---------------------------------------------------------------------------- + +static int gEGLTraceLevel; +static int gEGLApplicationTraceLevel; +extern EGLAPI gl_hooks_t gHooksTrace; + +static inline void setGlTraceThreadSpecific(gl_hooks_t const *value) { + pthread_setspecific(gGLTraceKey, value); +} + +gl_hooks_t const* getGLTraceThreadSpecific() { + return static_cast<gl_hooks_t*>(pthread_getspecific(gGLTraceKey)); +} + +static void initEglTraceLevel() { + char value[PROPERTY_VALUE_MAX]; + property_get("debug.egl.trace", value, "0"); + int propertyLevel = atoi(value); + int applicationLevel = gEGLApplicationTraceLevel; + gEGLTraceLevel = propertyLevel > applicationLevel ? propertyLevel : applicationLevel; +} + +static void setGLHooksThreadSpecific(gl_hooks_t const *value) { + if (gEGLTraceLevel > 0) { + setGlTraceThreadSpecific(value); + setGlThreadSpecific(&gHooksTrace); + } else { + setGlThreadSpecific(value); + } +} + +/* + * Global entry point to allow applications to modify their own trace level. + * The effective trace level is the max of this level and the value of debug.egl.trace. + */ +extern "C" +void setGLTraceLevel(int level) { + gEGLApplicationTraceLevel = level; +} + +#else + +static inline void setGLHooksThreadSpecific(gl_hooks_t const *value) { + setGlThreadSpecific(value); +} + +#endif + // ---------------------------------------------------------------------------- static __attribute__((noinline)) @@ -407,10 +475,6 @@ static const extention_map_t gExtentionMap[] = { (__eglMustCastToProperFunctionPointerType)&eglDestroyImageKHR }, { "eglSetSwapRectangleANDROID", (__eglMustCastToProperFunctionPointerType)&eglSetSwapRectangleANDROID }, - { "glEGLImageTargetTexture2DOES", - (__eglMustCastToProperFunctionPointerType)NULL }, - { "glEGLImageTargetRenderbufferStorageOES", - (__eglMustCastToProperFunctionPointerType)NULL }, }; extern const __eglMustCastToProperFunctionPointerType gExtensionForwarders[MAX_NUMBER_OF_GL_EXTENSIONS]; @@ -447,13 +511,17 @@ static void early_egl_init(void) #if !USE_FAST_TLS_KEY pthread_key_create(&gGLWrapperKey, NULL); #endif +#if EGL_TRACE + pthread_key_create(&gGLTraceKey, NULL); + initEglTraceLevel(); +#endif uint32_t addr = (uint32_t)((void*)gl_no_context); android_memset32( (uint32_t*)(void*)&gHooksNoContext, addr, sizeof(gHooksNoContext)); - setGlThreadSpecific(&gHooksNoContext); + setGLHooksThreadSpecific(&gHooksNoContext); } static pthread_once_t once_control = PTHREAD_ONCE_INIT; @@ -487,6 +555,11 @@ egl_image_t* get_image(EGLImageKHR image) { return egl_to_native_cast<egl_image_t>(image); } +static inline +egl_sync_t* get_sync(EGLSyncKHR sync) { + return egl_to_native_cast<egl_sync_t>(sync); +} + static egl_connection_t* validate_display_config( EGLDisplay dpy, EGLConfig config, egl_display_t const*& dp) @@ -660,9 +733,17 @@ EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) dp->refs++; return EGL_TRUE; } - - setGlThreadSpecific(&gHooksNoContext); - + +#if EGL_TRACE + + // Called both at early_init time and at this time. (Early_init is pre-zygote, so + // the information from that call may be stale.) + initEglTraceLevel(); + +#endif + + setGLHooksThreadSpecific(&gHooksNoContext); + // initialize each EGL and // build our own extension string first, based on the extension we know // and the extension supported by our client implementation @@ -1221,11 +1302,11 @@ EGLBoolean eglMakeCurrent( EGLDisplay dpy, EGLSurface draw, // cur_c has to be valid here (but could be terminated) if (ctx != EGL_NO_CONTEXT) { - setGlThreadSpecific(c->cnx->hooks[c->version]); + setGLHooksThreadSpecific(c->cnx->hooks[c->version]); setContext(ctx); _c.acquire(); } else { - setGlThreadSpecific(&gHooksNoContext); + setGLHooksThreadSpecific(&gHooksNoContext); setContext(EGL_NO_CONTEXT); } _cur_c.release(); @@ -1417,6 +1498,9 @@ __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) // Extensions are independent of the bound context cnx->hooks[GLESv1_INDEX]->ext.extensions[slot] = cnx->hooks[GLESv2_INDEX]->ext.extensions[slot] = +#if EGL_TRACE + gHooksTrace.ext.extensions[slot] = +#endif cnx->egl.eglGetProcAddress(procname); } } @@ -1794,6 +1878,111 @@ EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) return EGL_TRUE; } +// ---------------------------------------------------------------------------- +// EGL_EGLEXT_VERSION 5 +// ---------------------------------------------------------------------------- + + +EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + EGLContext ctx = eglGetCurrentContext(); + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR); + if (!validate_display_context(dpy, ctx)) + return EGL_NO_SYNC_KHR; + egl_display_t const * const dp = get_display(dpy); + egl_context_t * const c = get_context(ctx); + EGLSyncKHR result = EGL_NO_SYNC_KHR; + if (c->cnx->egl.eglCreateSyncKHR) { + EGLSyncKHR sync = c->cnx->egl.eglCreateSyncKHR( + dp->disp[c->impl].dpy, type, attrib_list); + if (sync == EGL_NO_SYNC_KHR) + return sync; + result = (egl_sync_t*)new egl_sync_t(dpy, ctx, sync); + } + return (EGLSyncKHR)result; +} + +EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + SyncRef _s(sync); + if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE); + egl_sync_t* syncObject = get_sync(sync); + + EGLContext ctx = syncObject->context; + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); + if (!validate_display_context(dpy, ctx)) + return EGL_FALSE; + + egl_context_t * const c = get_context(ctx); + + if (c->cnx->egl.eglDestroySyncKHR) { + return c->cnx->egl.eglDestroySyncKHR( + dp->disp[c->impl].dpy, syncObject->sync); + } + + return EGL_FALSE; +} + +EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + SyncRef _s(sync); + if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE); + egl_sync_t* syncObject = get_sync(sync); + + EGLContext ctx = syncObject->context; + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); + if (!validate_display_context(dpy, ctx)) + return EGL_FALSE; + + egl_context_t * const c = get_context(ctx); + + if (c->cnx->egl.eglClientWaitSyncKHR) { + return c->cnx->egl.eglClientWaitSyncKHR( + dp->disp[c->impl].dpy, syncObject->sync, flags, timeout); + } + + return EGL_FALSE; +} + +EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + egl_display_t const * const dp = get_display(dpy); + if (dp == 0) { + return setError(EGL_BAD_DISPLAY, EGL_FALSE); + } + + SyncRef _s(sync); + if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE); + egl_sync_t* syncObject = get_sync(sync); + + EGLContext ctx = syncObject->context; + ContextRef _c(ctx); + if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE); + if (!validate_display_context(dpy, ctx)) + return EGL_FALSE; + + egl_context_t * const c = get_context(ctx); + + if (c->cnx->egl.eglGetSyncAttribKHR) { + return c->cnx->egl.eglGetSyncAttribKHR( + dp->disp[c->impl].dpy, syncObject->sync, attribute, value); + } + + return EGL_FALSE; +} // ---------------------------------------------------------------------------- // ANDROID extensions diff --git a/opengl/libs/EGL/egl_entries.in b/opengl/libs/EGL/egl_entries.in index 5d892872806a..63c3c1905f37 100644 --- a/opengl/libs/EGL/egl_entries.in +++ b/opengl/libs/EGL/egl_entries.in @@ -51,6 +51,13 @@ EGL_ENTRY(EGLBoolean, eglUnlockSurfaceKHR, EGLDisplay, EGLSurface) EGL_ENTRY(EGLImageKHR, eglCreateImageKHR, EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint *) EGL_ENTRY(EGLBoolean, eglDestroyImageKHR, EGLDisplay, EGLImageKHR) +/* EGL_EGLEXT_VERSION 5 */ + +EGL_ENTRY(EGLSyncKHR, eglCreateSyncKHR, EGLDisplay, EGLenum, const EGLint *) +EGL_ENTRY(EGLBoolean, eglDestroySyncKHR, EGLDisplay, EGLSyncKHR) +EGL_ENTRY(EGLint, eglClientWaitSyncKHR, EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR) +EGL_ENTRY(EGLBoolean, eglGetSyncAttribKHR, EGLDisplay, EGLSyncKHR, EGLint, EGLint *) + /* ANDROID extensions */ EGL_ENTRY(EGLBoolean, eglSetSwapRectangleANDROID, EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint) diff --git a/opengl/libs/EGL/trace.cpp b/opengl/libs/EGL/trace.cpp new file mode 100644 index 000000000000..d3e96ba9d6e7 --- /dev/null +++ b/opengl/libs/EGL/trace.cpp @@ -0,0 +1,355 @@ +/* + ** Copyright 2010, 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. + */ + +#if EGL_TRACE + +#include <stdarg.h> +#include <stdlib.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <cutils/log.h> + +#include "hooks.h" + +// ---------------------------------------------------------------------------- +namespace android { +// ---------------------------------------------------------------------------- + +struct GLenumString { + GLenum e; + const char* s; +}; + +#undef GL_ENUM +#define GL_ENUM(VAL,NAME) {VAL, #NAME}, + +static GLenumString g_enumnames[] = { +#include "enums.in" +}; +#undef GL_ENUM + +static int compareGLEnum(const void* a, const void* b) { + return ((const GLenumString*) a)->e - ((const GLenumString*) b)->e; +} + +static const char* GLEnumToString(GLenum e) { + GLenumString key = {e, ""}; + const GLenumString* result = (const GLenumString*) bsearch( + &key, g_enumnames, + sizeof(g_enumnames) / sizeof(g_enumnames[0]), + sizeof(g_enumnames[0]), compareGLEnum); + if (result) { + return result->s; + } + return NULL; +} + +static const char* GLbooleanToString(GLboolean arg) { + return arg ? "GL_TRUE" : "GL_FALSE"; +} + +static GLenumString g_bitfieldNames[] = { + {0x00004000, "GL_COLOR_BUFFER_BIT"}, + {0x00000400, "GL_STENCIL_BUFFER_BIT"}, + {0x00000100, "GL_DEPTH_BUFFER_BIT"} +}; + +class StringBuilder { + static const int lineSize = 500; + char line[lineSize]; + int line_index; +public: + StringBuilder() { + line_index = 0; + line[0] = '\0'; + } + void append(const char* fmt, ...) { + va_list argp; + va_start(argp, fmt); + line_index += vsnprintf(line + line_index, lineSize-line_index, fmt, argp); + va_end(argp); + } + const char* getString() { + line_index = 0; + line[lineSize-1] = '\0'; + return line; + } +}; + + +static void TraceGLShaderSource(GLuint shader, GLsizei count, + const GLchar** string, const GLint* length) { + LOGD("const char* shaderSrc[] = {"); + for (GLsizei i = 0; i < count; i++) { + const char* comma = i < count-1 ? "," : ""; + const GLchar* s = string[i]; + if (length) { + GLint len = length[i]; + LOGD(" \"%*s\"%s", len, s, comma); + } else { + LOGD(" \"%s\"%s", s, comma); + } + } + LOGD("};"); + if (length) { + LOGD("const GLint* shaderLength[] = {"); + for (GLsizei i = 0; i < count; i++) { + const char* comma = i < count-1 ? "," : ""; + GLint len = length[i]; + LOGD(" \"%d\"%s", len, comma); + } + LOGD("};"); + LOGD("glShaderSource(%u, %u, shaderSrc, shaderLength);", + shader, count); + } else { + LOGD("glShaderSource(%u, %u, shaderSrc, (const GLint*) 0);", + shader, count); + } +} + +static void TraceValue(int elementCount, char type, + GLsizei chunkCount, GLsizei chunkSize, const void* value) { + StringBuilder stringBuilder; + GLsizei count = chunkCount * chunkSize; + bool isFloat = type == 'f'; + const char* typeString = isFloat ? "GLfloat" : "GLint"; + LOGD("const %s value[] = {", typeString); + for (GLsizei i = 0; i < count; i++) { + StringBuilder builder; + builder.append(" "); + for (int e = 0; e < elementCount; e++) { + const char* comma = ", "; + if (e == elementCount-1) { + if (i == count - 1) { + comma = ""; + } else { + comma = ","; + } + } + if (isFloat) { + builder.append("%g%s", * (GLfloat*) value, comma); + value = (void*) (((GLfloat*) value) + 1); + } else { + builder.append("%d%s", * (GLint*) value, comma); + value = (void*) (((GLint*) value) + 1); + } + } + LOGD("%s", builder.getString()); + if (chunkSize > 1 && i < count-1 + && (i % chunkSize) == (chunkSize-1)) { + LOGD("%s", ""); // Print a blank line. + } + } + LOGD("};"); +} + +static void TraceUniformv(int elementCount, char type, + GLuint location, GLsizei count, const void* value) { + TraceValue(elementCount, type, count, 1, value); + LOGD("glUniform%d%c(%u, %u, value);", elementCount, type, location, count); +} + +static void TraceUniformMatrix(int matrixSideLength, + GLuint location, GLsizei count, GLboolean transpose, const void* value) { + TraceValue(matrixSideLength, 'f', count, matrixSideLength, value); + LOGD("glUniformMatrix%dfv(%u, %u, %s, value);", matrixSideLength, location, count, + GLbooleanToString(transpose)); +} + +static void TraceGL(const char* name, int numArgs, ...) { + va_list argp; + va_start(argp, numArgs); + int nameLen = strlen(name); + + // glShaderSource + if (nameLen == 14 && strcmp(name, "glShaderSource") == 0) { + va_arg(argp, const char*); + GLuint shader = va_arg(argp, GLuint); + va_arg(argp, const char*); + GLsizei count = va_arg(argp, GLsizei); + va_arg(argp, const char*); + const GLchar** string = (const GLchar**) va_arg(argp, void*); + va_arg(argp, const char*); + const GLint* length = (const GLint*) va_arg(argp, void*); + va_end(argp); + TraceGLShaderSource(shader, count, string, length); + return; + } + + // glUniformXXv + + if (nameLen == 12 && strncmp(name, "glUniform", 9) == 0 && name[11] == 'v') { + int elementCount = name[9] - '0'; // 1..4 + char type = name[10]; // 'f' or 'i' + va_arg(argp, const char*); + GLuint location = va_arg(argp, GLuint); + va_arg(argp, const char*); + GLsizei count = va_arg(argp, GLsizei); + va_arg(argp, const char*); + const void* value = (const void*) va_arg(argp, void*); + va_end(argp); + TraceUniformv(elementCount, type, location, count, value); + return; + } + + // glUniformMatrixXfv + + if (nameLen == 18 && strncmp(name, "glUniformMatrix", 15) == 0 + && name[16] == 'f' && name[17] == 'v') { + int matrixSideLength = name[15] - '0'; // 2..4 + va_arg(argp, const char*); + GLuint location = va_arg(argp, GLuint); + va_arg(argp, const char*); + GLsizei count = va_arg(argp, GLsizei); + va_arg(argp, const char*); + GLboolean transpose = (GLboolean) va_arg(argp, int); + va_arg(argp, const char*); + const void* value = (const void*) va_arg(argp, void*); + va_end(argp); + TraceUniformMatrix(matrixSideLength, location, count, transpose, value); + return; + } + + StringBuilder builder; + builder.append("%s(", name); + for (int i = 0; i < numArgs; i++) { + if (i > 0) { + builder.append(", "); + } + const char* type = va_arg(argp, const char*); + bool isPtr = type[strlen(type)-1] == '*' + || strcmp(type, "GLeglImageOES") == 0; + if (isPtr) { + const void* arg = va_arg(argp, const void*); + builder.append("(%s) 0x%08x", type, (size_t) arg); + } else if (strcmp(type, "GLbitfield") == 0) { + size_t arg = va_arg(argp, size_t); + bool first = true; + for (size_t i = 0; i < sizeof(g_bitfieldNames) / sizeof(g_bitfieldNames[0]); i++) { + const GLenumString* b = &g_bitfieldNames[i]; + if (b->e & arg) { + if (first) { + first = false; + } else { + builder.append(" | "); + } + builder.append("%s", b->s); + arg &= ~b->e; + } + } + if (first || arg != 0) { + if (!first) { + builder.append(" | "); + } + builder.append("0x%08x", arg); + } + } else if (strcmp(type, "GLboolean") == 0) { + GLboolean arg = va_arg(argp, int); + builder.append("%s", GLbooleanToString(arg)); + } else if (strcmp(type, "GLclampf") == 0) { + double arg = va_arg(argp, double); + builder.append("%g", arg); + } else if (strcmp(type, "GLenum") == 0) { + GLenum arg = va_arg(argp, int); + const char* s = GLEnumToString(arg); + if (s) { + builder.append("%s", s); + } else { + builder.append("0x%x", arg); + } + } else if (strcmp(type, "GLfixed") == 0) { + int arg = va_arg(argp, int); + builder.append("0x%08x", arg); + } else if (strcmp(type, "GLfloat") == 0) { + double arg = va_arg(argp, double); + builder.append("%g", arg); + } else if (strcmp(type, "GLint") == 0) { + int arg = va_arg(argp, int); + const char* s = NULL; + if (strcmp(name, "glTexParameteri") == 0) { + s = GLEnumToString(arg); + } + if (s) { + builder.append("%s", s); + } else { + builder.append("%d", arg); + } + } else if (strcmp(type, "GLintptr") == 0) { + int arg = va_arg(argp, unsigned int); + builder.append("%u", arg); + } else if (strcmp(type, "GLsizei") == 0) { + int arg = va_arg(argp, size_t); + builder.append("%u", arg); + } else if (strcmp(type, "GLsizeiptr") == 0) { + int arg = va_arg(argp, size_t); + builder.append("%u", arg); + } else if (strcmp(type, "GLuint") == 0) { + int arg = va_arg(argp, unsigned int); + builder.append("%u", arg); + } else { + builder.append("/* ??? %s */", type); + break; + } + } + builder.append(");"); + LOGD("%s", builder.getString()); + va_end(argp); +} + +#undef TRACE_GL_VOID +#undef TRACE_GL + +#define TRACE_GL_VOID(_api, _args, _argList, ...) \ +static void Tracing_ ## _api _args { \ + TraceGL(#_api, __VA_ARGS__); \ + gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ + _c->_api _argList; \ +} + +#define TRACE_GL(_type, _api, _args, _argList, ...) \ +static _type Tracing_ ## _api _args { \ + TraceGL(#_api, __VA_ARGS__); \ + gl_hooks_t::gl_t const * const _c = &getGLTraceThreadSpecific()->gl; \ + return _c->_api _argList; \ +} + +extern "C" { +#include "../trace.in" +} +#undef TRACE_GL_VOID +#undef TRACE_GL + +#define GL_ENTRY(_r, _api, ...) Tracing_ ## _api, + +EGLAPI gl_hooks_t gHooksTrace = { + { + #include "entries.in" + }, + { + {0} + } +}; +#undef GL_ENTRY + +// ---------------------------------------------------------------------------- +}; // namespace android +// ---------------------------------------------------------------------------- + +#endif // EGL_TRACE diff --git a/opengl/libs/GLES2/gl2.cpp b/opengl/libs/GLES2/gl2.cpp index 18dd4834f7a9..fee4609378b0 100644 --- a/opengl/libs/GLES2/gl2.cpp +++ b/opengl/libs/GLES2/gl2.cpp @@ -39,6 +39,8 @@ using namespace android; #undef CALL_GL_API #undef CALL_GL_API_RETURN +#define DEBUG_CALL_GL_API 0 + #if USE_FAST_TLS_KEY #ifdef HAVE_ARM_TLS_REGISTER @@ -74,10 +76,24 @@ using namespace android; #define API_ENTRY(_api) _api +#if DEBUG_CALL_GL_API + + #define CALL_GL_API(_api, ...) \ + gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ + _c->_api(__VA_ARGS__); \ + GLenum status = GL_NO_ERROR; \ + while ((status = glGetError()) != GL_NO_ERROR) { \ + LOGD("[" #_api "] 0x%x", status); \ + } + +#else + #define CALL_GL_API(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ - _c->_api(__VA_ARGS__) - + _c->_api(__VA_ARGS__); + +#endif + #define CALL_GL_API_RETURN(_api, ...) \ gl_hooks_t::gl_t const * const _c = &getGlThreadSpecific()->gl; \ return _c->_api(__VA_ARGS__) diff --git a/opengl/libs/enums.in b/opengl/libs/enums.in new file mode 100644 index 000000000000..f9752c24ae7e --- /dev/null +++ b/opengl/libs/enums.in @@ -0,0 +1,594 @@ +GL_ENUM(0x0000,GL_POINTS) +GL_ENUM(0x0001,GL_LINES) +GL_ENUM(0x0002,GL_LINE_LOOP) +GL_ENUM(0x0003,GL_LINE_STRIP) +GL_ENUM(0x0004,GL_TRIANGLES) +GL_ENUM(0x0005,GL_TRIANGLE_STRIP) +GL_ENUM(0x0006,GL_TRIANGLE_FAN) +GL_ENUM(0x0104,GL_ADD) +GL_ENUM(0x0200,GL_NEVER) +GL_ENUM(0x0201,GL_LESS) +GL_ENUM(0x0202,GL_EQUAL) +GL_ENUM(0x0203,GL_LEQUAL) +GL_ENUM(0x0204,GL_GREATER) +GL_ENUM(0x0205,GL_NOTEQUAL) +GL_ENUM(0x0206,GL_GEQUAL) +GL_ENUM(0x0207,GL_ALWAYS) +GL_ENUM(0x0300,GL_SRC_COLOR) +GL_ENUM(0x0301,GL_ONE_MINUS_SRC_COLOR) +GL_ENUM(0x0302,GL_SRC_ALPHA) +GL_ENUM(0x0303,GL_ONE_MINUS_SRC_ALPHA) +GL_ENUM(0x0304,GL_DST_ALPHA) +GL_ENUM(0x0305,GL_ONE_MINUS_DST_ALPHA) +GL_ENUM(0x0306,GL_DST_COLOR) +GL_ENUM(0x0307,GL_ONE_MINUS_DST_COLOR) +GL_ENUM(0x0308,GL_SRC_ALPHA_SATURATE) +GL_ENUM(0x0404,GL_FRONT) +GL_ENUM(0x0405,GL_BACK) +GL_ENUM(0x0408,GL_FRONT_AND_BACK) +GL_ENUM(0x0500,GL_INVALID_ENUM) +GL_ENUM(0x0501,GL_INVALID_VALUE) +GL_ENUM(0x0502,GL_INVALID_OPERATION) +GL_ENUM(0x0503,GL_STACK_OVERFLOW) +GL_ENUM(0x0504,GL_STACK_UNDERFLOW) +GL_ENUM(0x0505,GL_OUT_OF_MEMORY) +GL_ENUM(0x0506,GL_INVALID_FRAMEBUFFER_OPERATION_OES) +GL_ENUM(0x0800,GL_EXP) +GL_ENUM(0x0801,GL_EXP2) +GL_ENUM(0x0900,GL_CW) +GL_ENUM(0x0901,GL_CCW) +GL_ENUM(0x0B00,GL_CURRENT_COLOR) +GL_ENUM(0x0B02,GL_CURRENT_NORMAL) +GL_ENUM(0x0B03,GL_CURRENT_TEXTURE_COORDS) +GL_ENUM(0x0B10,GL_POINT_SMOOTH) +GL_ENUM(0x0B11,GL_POINT_SIZE) +GL_ENUM(0x0B12,GL_SMOOTH_POINT_SIZE_RANGE) +GL_ENUM(0x0B20,GL_LINE_SMOOTH) +GL_ENUM(0x0B21,GL_LINE_WIDTH) +GL_ENUM(0x0B22,GL_SMOOTH_LINE_WIDTH_RANGE) +GL_ENUM(0x0B44,GL_CULL_FACE) +GL_ENUM(0x0B45,GL_CULL_FACE_MODE) +GL_ENUM(0x0B46,GL_FRONT_FACE) +GL_ENUM(0x0B50,GL_LIGHTING) +GL_ENUM(0x0B52,GL_LIGHT_MODEL_TWO_SIDE) +GL_ENUM(0x0B53,GL_LIGHT_MODEL_AMBIENT) +GL_ENUM(0x0B54,GL_SHADE_MODEL) +GL_ENUM(0x0B57,GL_COLOR_MATERIAL) +GL_ENUM(0x0B60,GL_FOG) +GL_ENUM(0x0B62,GL_FOG_DENSITY) +GL_ENUM(0x0B63,GL_FOG_START) +GL_ENUM(0x0B64,GL_FOG_END) +GL_ENUM(0x0B65,GL_FOG_MODE) +GL_ENUM(0x0B66,GL_FOG_COLOR) +GL_ENUM(0x0B70,GL_DEPTH_RANGE) +GL_ENUM(0x0B71,GL_DEPTH_TEST) +GL_ENUM(0x0B72,GL_DEPTH_WRITEMASK) +GL_ENUM(0x0B73,GL_DEPTH_CLEAR_VALUE) +GL_ENUM(0x0B74,GL_DEPTH_FUNC) +GL_ENUM(0x0B90,GL_STENCIL_TEST) +GL_ENUM(0x0B91,GL_STENCIL_CLEAR_VALUE) +GL_ENUM(0x0B92,GL_STENCIL_FUNC) +GL_ENUM(0x0B93,GL_STENCIL_VALUE_MASK) +GL_ENUM(0x0B94,GL_STENCIL_FAIL) +GL_ENUM(0x0B95,GL_STENCIL_PASS_DEPTH_FAIL) +GL_ENUM(0x0B96,GL_STENCIL_PASS_DEPTH_PASS) +GL_ENUM(0x0B97,GL_STENCIL_REF) +GL_ENUM(0x0B98,GL_STENCIL_WRITEMASK) +GL_ENUM(0x0BA0,GL_MATRIX_MODE) +GL_ENUM(0x0BA1,GL_NORMALIZE) +GL_ENUM(0x0BA2,GL_VIEWPORT) +GL_ENUM(0x0BA3,GL_MODELVIEW_STACK_DEPTH) +GL_ENUM(0x0BA4,GL_PROJECTION_STACK_DEPTH) +GL_ENUM(0x0BA5,GL_TEXTURE_STACK_DEPTH) +GL_ENUM(0x0BA6,GL_MODELVIEW_MATRIX) +GL_ENUM(0x0BA7,GL_PROJECTION_MATRIX) +GL_ENUM(0x0BA8,GL_TEXTURE_MATRIX) +GL_ENUM(0x0BC0,GL_ALPHA_TEST) +GL_ENUM(0x0BC1,GL_ALPHA_TEST_FUNC) +GL_ENUM(0x0BC2,GL_ALPHA_TEST_REF) +GL_ENUM(0x0BD0,GL_DITHER) +GL_ENUM(0x0BE0,GL_BLEND_DST) +GL_ENUM(0x0BE1,GL_BLEND_SRC) +GL_ENUM(0x0BE2,GL_BLEND) +GL_ENUM(0x0BF0,GL_LOGIC_OP_MODE) +GL_ENUM(0x0BF2,GL_COLOR_LOGIC_OP) +GL_ENUM(0x0C10,GL_SCISSOR_BOX) +GL_ENUM(0x0C11,GL_SCISSOR_TEST) +GL_ENUM(0x0C22,GL_COLOR_CLEAR_VALUE) +GL_ENUM(0x0C23,GL_COLOR_WRITEMASK) +GL_ENUM(0x0C50,GL_PERSPECTIVE_CORRECTION_HINT) +GL_ENUM(0x0C51,GL_POINT_SMOOTH_HINT) +GL_ENUM(0x0C52,GL_LINE_SMOOTH_HINT) +GL_ENUM(0x0C54,GL_FOG_HINT) +GL_ENUM(0x0CF5,GL_UNPACK_ALIGNMENT) +GL_ENUM(0x0D05,GL_PACK_ALIGNMENT) +GL_ENUM(0x0D1C,GL_ALPHA_SCALE) +GL_ENUM(0x0D31,GL_MAX_LIGHTS) +GL_ENUM(0x0D32,GL_MAX_CLIP_PLANES) +GL_ENUM(0x0D33,GL_MAX_TEXTURE_SIZE) +GL_ENUM(0x0D36,GL_MAX_MODELVIEW_STACK_DEPTH) +GL_ENUM(0x0D38,GL_MAX_PROJECTION_STACK_DEPTH) +GL_ENUM(0x0D39,GL_MAX_TEXTURE_STACK_DEPTH) +GL_ENUM(0x0D3A,GL_MAX_VIEWPORT_DIMS) +GL_ENUM(0x0D50,GL_SUBPIXEL_BITS) +GL_ENUM(0x0D52,GL_RED_BITS) +GL_ENUM(0x0D53,GL_GREEN_BITS) +GL_ENUM(0x0D54,GL_BLUE_BITS) +GL_ENUM(0x0D55,GL_ALPHA_BITS) +GL_ENUM(0x0D56,GL_DEPTH_BITS) +GL_ENUM(0x0D57,GL_STENCIL_BITS) +GL_ENUM(0x0DE1,GL_TEXTURE_2D) +GL_ENUM(0x1100,GL_DONT_CARE) +GL_ENUM(0x1101,GL_FASTEST) +GL_ENUM(0x1102,GL_NICEST) +GL_ENUM(0x1200,GL_AMBIENT) +GL_ENUM(0x1201,GL_DIFFUSE) +GL_ENUM(0x1202,GL_SPECULAR) +GL_ENUM(0x1203,GL_POSITION) +GL_ENUM(0x1204,GL_SPOT_DIRECTION) +GL_ENUM(0x1205,GL_SPOT_EXPONENT) +GL_ENUM(0x1206,GL_SPOT_CUTOFF) +GL_ENUM(0x1207,GL_CONSTANT_ATTENUATION) +GL_ENUM(0x1208,GL_LINEAR_ATTENUATION) +GL_ENUM(0x1209,GL_QUADRATIC_ATTENUATION) +GL_ENUM(0x1400,GL_BYTE) +GL_ENUM(0x1401,GL_UNSIGNED_BYTE) +GL_ENUM(0x1402,GL_SHORT) +GL_ENUM(0x1403,GL_UNSIGNED_SHORT) +GL_ENUM(0x1404,GL_INT) +GL_ENUM(0x1405,GL_UNSIGNED_INT) +GL_ENUM(0x1406,GL_FLOAT) +GL_ENUM(0x140C,GL_FIXED) +GL_ENUM(0x1500,GL_CLEAR) +GL_ENUM(0x1501,GL_AND) +GL_ENUM(0x1502,GL_AND_REVERSE) +GL_ENUM(0x1503,GL_COPY) +GL_ENUM(0x1504,GL_AND_INVERTED) +GL_ENUM(0x1505,GL_NOOP) +GL_ENUM(0x1506,GL_XOR) +GL_ENUM(0x1507,GL_OR) +GL_ENUM(0x1508,GL_NOR) +GL_ENUM(0x1509,GL_EQUIV) +GL_ENUM(0x150A,GL_INVERT) +GL_ENUM(0x150B,GL_OR_REVERSE) +GL_ENUM(0x150C,GL_COPY_INVERTED) +GL_ENUM(0x150D,GL_OR_INVERTED) +GL_ENUM(0x150E,GL_NAND) +GL_ENUM(0x150F,GL_SET) +GL_ENUM(0x1600,GL_EMISSION) +GL_ENUM(0x1601,GL_SHININESS) +GL_ENUM(0x1602,GL_AMBIENT_AND_DIFFUSE) +GL_ENUM(0x1700,GL_MODELVIEW) +GL_ENUM(0x1701,GL_PROJECTION) +GL_ENUM(0x1702,GL_TEXTURE) +GL_ENUM(0x1800,GL_COLOR_EXT) +GL_ENUM(0x1801,GL_DEPTH_EXT) +GL_ENUM(0x1802,GL_STENCIL_EXT) +GL_ENUM(0x1901,GL_STENCIL_INDEX) +GL_ENUM(0x1902,GL_DEPTH_COMPONENT) +GL_ENUM(0x1906,GL_ALPHA) +GL_ENUM(0x1907,GL_RGB) +GL_ENUM(0x1908,GL_RGBA) +GL_ENUM(0x1909,GL_LUMINANCE) +GL_ENUM(0x190A,GL_LUMINANCE_ALPHA) +GL_ENUM(0x1D00,GL_FLAT) +GL_ENUM(0x1D01,GL_SMOOTH) +GL_ENUM(0x1E00,GL_KEEP) +GL_ENUM(0x1E01,GL_REPLACE) +GL_ENUM(0x1E02,GL_INCR) +GL_ENUM(0x1E03,GL_DECR) +GL_ENUM(0x1F00,GL_VENDOR) +GL_ENUM(0x1F01,GL_RENDERER) +GL_ENUM(0x1F02,GL_VERSION) +GL_ENUM(0x1F03,GL_EXTENSIONS) +GL_ENUM(0x2100,GL_MODULATE) +GL_ENUM(0x2101,GL_DECAL) +GL_ENUM(0x2200,GL_TEXTURE_ENV_MODE) +GL_ENUM(0x2201,GL_TEXTURE_ENV_COLOR) +GL_ENUM(0x2300,GL_TEXTURE_ENV) +GL_ENUM(0x2500,GL_TEXTURE_GEN_MODE_OES) +GL_ENUM(0x2600,GL_NEAREST) +GL_ENUM(0x2601,GL_LINEAR) +GL_ENUM(0x2700,GL_NEAREST_MIPMAP_NEAREST) +GL_ENUM(0x2701,GL_LINEAR_MIPMAP_NEAREST) +GL_ENUM(0x2702,GL_NEAREST_MIPMAP_LINEAR) +GL_ENUM(0x2703,GL_LINEAR_MIPMAP_LINEAR) +GL_ENUM(0x2800,GL_TEXTURE_MAG_FILTER) +GL_ENUM(0x2801,GL_TEXTURE_MIN_FILTER) +GL_ENUM(0x2802,GL_TEXTURE_WRAP_S) +GL_ENUM(0x2803,GL_TEXTURE_WRAP_T) +GL_ENUM(0x2901,GL_REPEAT) +GL_ENUM(0x2A00,GL_POLYGON_OFFSET_UNITS) +GL_ENUM(0x3000,GL_CLIP_PLANE0) +GL_ENUM(0x3001,GL_CLIP_PLANE1) +GL_ENUM(0x3002,GL_CLIP_PLANE2) +GL_ENUM(0x3003,GL_CLIP_PLANE3) +GL_ENUM(0x3004,GL_CLIP_PLANE4) +GL_ENUM(0x3005,GL_CLIP_PLANE5) +GL_ENUM(0x4000,GL_LIGHT0) +GL_ENUM(0x4001,GL_LIGHT1) +GL_ENUM(0x4002,GL_LIGHT2) +GL_ENUM(0x4003,GL_LIGHT3) +GL_ENUM(0x4004,GL_LIGHT4) +GL_ENUM(0x4005,GL_LIGHT5) +GL_ENUM(0x4006,GL_LIGHT6) +GL_ENUM(0x4007,GL_LIGHT7) +GL_ENUM(0x8000,GL_COVERAGE_BUFFER_BIT_NV) +GL_ENUM(0x8001,GL_CONSTANT_COLOR) +GL_ENUM(0x8002,GL_ONE_MINUS_CONSTANT_COLOR) +GL_ENUM(0x8003,GL_CONSTANT_ALPHA) +GL_ENUM(0x8004,GL_ONE_MINUS_CONSTANT_ALPHA) +GL_ENUM(0x8005,GL_BLEND_COLOR) +GL_ENUM(0x8006,GL_FUNC_ADD_OES) +GL_ENUM(0x8007,GL_MIN_EXT) +GL_ENUM(0x8008,GL_MAX_EXT) +GL_ENUM(0x8009,GL_BLEND_EQUATION_RGB_OES) +GL_ENUM(0x800A,GL_FUNC_SUBTRACT_OES) +GL_ENUM(0x800B,GL_FUNC_REVERSE_SUBTRACT_OES) +GL_ENUM(0x8033,GL_UNSIGNED_SHORT_4_4_4_4) +GL_ENUM(0x8034,GL_UNSIGNED_SHORT_5_5_5_1) +GL_ENUM(0x8037,GL_POLYGON_OFFSET_FILL) +GL_ENUM(0x8038,GL_POLYGON_OFFSET_FACTOR) +GL_ENUM(0x803A,GL_RESCALE_NORMAL) +GL_ENUM(0x8051,GL_RGB8_OES) +GL_ENUM(0x8056,GL_RGBA4_OES) +GL_ENUM(0x8057,GL_RGB5_A1_OES) +GL_ENUM(0x8058,GL_RGBA8_OES) +GL_ENUM(0x8069,GL_TEXTURE_BINDING_2D) +GL_ENUM(0x806A,GL_TEXTURE_BINDING_3D_OES) +GL_ENUM(0x806F,GL_TEXTURE_3D_OES) +GL_ENUM(0x8072,GL_TEXTURE_WRAP_R_OES) +GL_ENUM(0x8073,GL_MAX_3D_TEXTURE_SIZE_OES) +GL_ENUM(0x8074,GL_VERTEX_ARRAY) +GL_ENUM(0x8075,GL_NORMAL_ARRAY) +GL_ENUM(0x8076,GL_COLOR_ARRAY) +GL_ENUM(0x8078,GL_TEXTURE_COORD_ARRAY) +GL_ENUM(0x807A,GL_VERTEX_ARRAY_SIZE) +GL_ENUM(0x807B,GL_VERTEX_ARRAY_TYPE) +GL_ENUM(0x807C,GL_VERTEX_ARRAY_STRIDE) +GL_ENUM(0x807E,GL_NORMAL_ARRAY_TYPE) +GL_ENUM(0x807F,GL_NORMAL_ARRAY_STRIDE) +GL_ENUM(0x8081,GL_COLOR_ARRAY_SIZE) +GL_ENUM(0x8082,GL_COLOR_ARRAY_TYPE) +GL_ENUM(0x8083,GL_COLOR_ARRAY_STRIDE) +GL_ENUM(0x8088,GL_TEXTURE_COORD_ARRAY_SIZE) +GL_ENUM(0x8089,GL_TEXTURE_COORD_ARRAY_TYPE) +GL_ENUM(0x808A,GL_TEXTURE_COORD_ARRAY_STRIDE) +GL_ENUM(0x808E,GL_VERTEX_ARRAY_POINTER) +GL_ENUM(0x808F,GL_NORMAL_ARRAY_POINTER) +GL_ENUM(0x8090,GL_COLOR_ARRAY_POINTER) +GL_ENUM(0x8092,GL_TEXTURE_COORD_ARRAY_POINTER) +GL_ENUM(0x809D,GL_MULTISAMPLE) +GL_ENUM(0x809E,GL_SAMPLE_ALPHA_TO_COVERAGE) +GL_ENUM(0x809F,GL_SAMPLE_ALPHA_TO_ONE) +GL_ENUM(0x80A0,GL_SAMPLE_COVERAGE) +GL_ENUM(0x80A8,GL_SAMPLE_BUFFERS) +GL_ENUM(0x80A9,GL_SAMPLES) +GL_ENUM(0x80AA,GL_SAMPLE_COVERAGE_VALUE) +GL_ENUM(0x80AB,GL_SAMPLE_COVERAGE_INVERT) +GL_ENUM(0x80C8,GL_BLEND_DST_RGB_OES) +GL_ENUM(0x80C9,GL_BLEND_SRC_RGB_OES) +GL_ENUM(0x80CA,GL_BLEND_DST_ALPHA_OES) +GL_ENUM(0x80CB,GL_BLEND_SRC_ALPHA_OES) +GL_ENUM(0x80E1,GL_BGRA_EXT) +GL_ENUM(0x8126,GL_POINT_SIZE_MIN) +GL_ENUM(0x8127,GL_POINT_SIZE_MAX) +GL_ENUM(0x8128,GL_POINT_FADE_THRESHOLD_SIZE) +GL_ENUM(0x8129,GL_POINT_DISTANCE_ATTENUATION) +GL_ENUM(0x812F,GL_CLAMP_TO_EDGE) +GL_ENUM(0x8191,GL_GENERATE_MIPMAP) +GL_ENUM(0x8192,GL_GENERATE_MIPMAP_HINT) +GL_ENUM(0x81A5,GL_DEPTH_COMPONENT16_OES) +GL_ENUM(0x81A6,GL_DEPTH_COMPONENT24_OES) +GL_ENUM(0x81A7,GL_DEPTH_COMPONENT32_OES) +GL_ENUM(0x8363,GL_UNSIGNED_SHORT_5_6_5) +GL_ENUM(0x8365,GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) +GL_ENUM(0x8366,GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT) +GL_ENUM(0x8368,GL_UNSIGNED_INT_2_10_10_10_REV_EXT) +GL_ENUM(0x8370,GL_MIRRORED_REPEAT_OES) +GL_ENUM(0x83F0,GL_COMPRESSED_RGB_S3TC_DXT1_EXT) +GL_ENUM(0x83F1,GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) +GL_ENUM(0x846D,GL_ALIASED_POINT_SIZE_RANGE) +GL_ENUM(0x846E,GL_ALIASED_LINE_WIDTH_RANGE) +GL_ENUM(0x84C0,GL_TEXTURE0) +GL_ENUM(0x84C1,GL_TEXTURE1) +GL_ENUM(0x84C2,GL_TEXTURE2) +GL_ENUM(0x84C3,GL_TEXTURE3) +GL_ENUM(0x84C4,GL_TEXTURE4) +GL_ENUM(0x84C5,GL_TEXTURE5) +GL_ENUM(0x84C6,GL_TEXTURE6) +GL_ENUM(0x84C7,GL_TEXTURE7) +GL_ENUM(0x84C8,GL_TEXTURE8) +GL_ENUM(0x84C9,GL_TEXTURE9) +GL_ENUM(0x84CA,GL_TEXTURE10) +GL_ENUM(0x84CB,GL_TEXTURE11) +GL_ENUM(0x84CC,GL_TEXTURE12) +GL_ENUM(0x84CD,GL_TEXTURE13) +GL_ENUM(0x84CE,GL_TEXTURE14) +GL_ENUM(0x84CF,GL_TEXTURE15) +GL_ENUM(0x84D0,GL_TEXTURE16) +GL_ENUM(0x84D1,GL_TEXTURE17) +GL_ENUM(0x84D2,GL_TEXTURE18) +GL_ENUM(0x84D3,GL_TEXTURE19) +GL_ENUM(0x84D4,GL_TEXTURE20) +GL_ENUM(0x84D5,GL_TEXTURE21) +GL_ENUM(0x84D6,GL_TEXTURE22) +GL_ENUM(0x84D7,GL_TEXTURE23) +GL_ENUM(0x84D8,GL_TEXTURE24) +GL_ENUM(0x84D9,GL_TEXTURE25) +GL_ENUM(0x84DA,GL_TEXTURE26) +GL_ENUM(0x84DB,GL_TEXTURE27) +GL_ENUM(0x84DC,GL_TEXTURE28) +GL_ENUM(0x84DD,GL_TEXTURE29) +GL_ENUM(0x84DE,GL_TEXTURE30) +GL_ENUM(0x84DF,GL_TEXTURE31) +GL_ENUM(0x84E0,GL_ACTIVE_TEXTURE) +GL_ENUM(0x84E1,GL_CLIENT_ACTIVE_TEXTURE) +GL_ENUM(0x84E2,GL_MAX_TEXTURE_UNITS) +GL_ENUM(0x84E7,GL_SUBTRACT) +GL_ENUM(0x84E8,GL_MAX_RENDERBUFFER_SIZE_OES) +GL_ENUM(0x84F2,GL_ALL_COMPLETED_NV) +GL_ENUM(0x84F3,GL_FENCE_STATUS_NV) +GL_ENUM(0x84F4,GL_FENCE_CONDITION_NV) +GL_ENUM(0x84F9,GL_DEPTH_STENCIL_OES) +GL_ENUM(0x84FA,GL_UNSIGNED_INT_24_8_OES) +GL_ENUM(0x84FD,GL_MAX_TEXTURE_LOD_BIAS_EXT) +GL_ENUM(0x84FE,GL_TEXTURE_MAX_ANISOTROPY_EXT) +GL_ENUM(0x84FF,GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT) +GL_ENUM(0x8500,GL_TEXTURE_FILTER_CONTROL_EXT) +GL_ENUM(0x8501,GL_TEXTURE_LOD_BIAS_EXT) +GL_ENUM(0x8507,GL_INCR_WRAP_OES) +GL_ENUM(0x8508,GL_DECR_WRAP_OES) +GL_ENUM(0x8511,GL_NORMAL_MAP_OES) +GL_ENUM(0x8512,GL_REFLECTION_MAP_OES) +GL_ENUM(0x8513,GL_TEXTURE_CUBE_MAP_OES) +GL_ENUM(0x8514,GL_TEXTURE_BINDING_CUBE_MAP_OES) +GL_ENUM(0x8515,GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES) +GL_ENUM(0x8516,GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES) +GL_ENUM(0x8517,GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES) +GL_ENUM(0x8518,GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES) +GL_ENUM(0x8519,GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES) +GL_ENUM(0x851A,GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_OES) +GL_ENUM(0x851C,GL_MAX_CUBE_MAP_TEXTURE_SIZE_OES) +GL_ENUM(0x8570,GL_COMBINE) +GL_ENUM(0x8571,GL_COMBINE_RGB) +GL_ENUM(0x8572,GL_COMBINE_ALPHA) +GL_ENUM(0x8573,GL_RGB_SCALE) +GL_ENUM(0x8574,GL_ADD_SIGNED) +GL_ENUM(0x8575,GL_INTERPOLATE) +GL_ENUM(0x8576,GL_CONSTANT) +GL_ENUM(0x8577,GL_PRIMARY_COLOR) +GL_ENUM(0x8578,GL_PREVIOUS) +GL_ENUM(0x8580,GL_SRC0_RGB) +GL_ENUM(0x8581,GL_SRC1_RGB) +GL_ENUM(0x8582,GL_SRC2_RGB) +GL_ENUM(0x8588,GL_SRC0_ALPHA) +GL_ENUM(0x8589,GL_SRC1_ALPHA) +GL_ENUM(0x858A,GL_SRC2_ALPHA) +GL_ENUM(0x8590,GL_OPERAND0_RGB) +GL_ENUM(0x8591,GL_OPERAND1_RGB) +GL_ENUM(0x8592,GL_OPERAND2_RGB) +GL_ENUM(0x8598,GL_OPERAND0_ALPHA) +GL_ENUM(0x8599,GL_OPERAND1_ALPHA) +GL_ENUM(0x859A,GL_OPERAND2_ALPHA) +GL_ENUM(0x85B5,GL_VERTEX_ARRAY_BINDING_OES) +GL_ENUM(0x8622,GL_VERTEX_ATTRIB_ARRAY_ENABLED) +GL_ENUM(0x8623,GL_VERTEX_ATTRIB_ARRAY_SIZE) +GL_ENUM(0x8624,GL_VERTEX_ATTRIB_ARRAY_STRIDE) +GL_ENUM(0x8625,GL_VERTEX_ATTRIB_ARRAY_TYPE) +GL_ENUM(0x8626,GL_CURRENT_VERTEX_ATTRIB) +GL_ENUM(0x8645,GL_VERTEX_ATTRIB_ARRAY_POINTER) +GL_ENUM(0x86A2,GL_NUM_COMPRESSED_TEXTURE_FORMATS) +GL_ENUM(0x86A3,GL_COMPRESSED_TEXTURE_FORMATS) +GL_ENUM(0x86A4,GL_MAX_VERTEX_UNITS_OES) +GL_ENUM(0x86A9,GL_WEIGHT_ARRAY_TYPE_OES) +GL_ENUM(0x86AA,GL_WEIGHT_ARRAY_STRIDE_OES) +GL_ENUM(0x86AB,GL_WEIGHT_ARRAY_SIZE_OES) +GL_ENUM(0x86AC,GL_WEIGHT_ARRAY_POINTER_OES) +GL_ENUM(0x86AD,GL_WEIGHT_ARRAY_OES) +GL_ENUM(0x86AE,GL_DOT3_RGB) +GL_ENUM(0x86AF,GL_DOT3_RGBA) +GL_ENUM(0x8740,GL_Z400_BINARY_AMD) +GL_ENUM(0x8741,GL_PROGRAM_BINARY_LENGTH_OES) +GL_ENUM(0x8764,GL_BUFFER_SIZE) +GL_ENUM(0x8765,GL_BUFFER_USAGE) +GL_ENUM(0x87EE,GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD) +GL_ENUM(0x87F9,GL_3DC_X_AMD) +GL_ENUM(0x87FA,GL_3DC_XY_AMD) +GL_ENUM(0x87FE,GL_NUM_PROGRAM_BINARY_FORMATS_OES) +GL_ENUM(0x87FF,GL_PROGRAM_BINARY_FORMATS_OES) +GL_ENUM(0x8800,GL_STENCIL_BACK_FUNC) +GL_ENUM(0x8801,GL_STENCIL_BACK_FAIL) +GL_ENUM(0x8802,GL_STENCIL_BACK_PASS_DEPTH_FAIL) +GL_ENUM(0x8803,GL_STENCIL_BACK_PASS_DEPTH_PASS) +GL_ENUM(0x8823,GL_WRITEONLY_RENDERING_QCOM) +GL_ENUM(0x883D,GL_BLEND_EQUATION_ALPHA_OES) +GL_ENUM(0x8840,GL_MATRIX_PALETTE_OES) +GL_ENUM(0x8842,GL_MAX_PALETTE_MATRICES_OES) +GL_ENUM(0x8843,GL_CURRENT_PALETTE_MATRIX_OES) +GL_ENUM(0x8844,GL_MATRIX_INDEX_ARRAY_OES) +GL_ENUM(0x8846,GL_MATRIX_INDEX_ARRAY_SIZE_OES) +GL_ENUM(0x8847,GL_MATRIX_INDEX_ARRAY_TYPE_OES) +GL_ENUM(0x8848,GL_MATRIX_INDEX_ARRAY_STRIDE_OES) +GL_ENUM(0x8849,GL_MATRIX_INDEX_ARRAY_POINTER_OES) +GL_ENUM(0x8861,GL_POINT_SPRITE_OES) +GL_ENUM(0x8862,GL_COORD_REPLACE_OES) +GL_ENUM(0x8869,GL_MAX_VERTEX_ATTRIBS) +GL_ENUM(0x886A,GL_VERTEX_ATTRIB_ARRAY_NORMALIZED) +GL_ENUM(0x8872,GL_MAX_TEXTURE_IMAGE_UNITS) +GL_ENUM(0x8892,GL_ARRAY_BUFFER) +GL_ENUM(0x8893,GL_ELEMENT_ARRAY_BUFFER) +GL_ENUM(0x8894,GL_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8895,GL_ELEMENT_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8896,GL_VERTEX_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8897,GL_NORMAL_ARRAY_BUFFER_BINDING) +GL_ENUM(0x8898,GL_COLOR_ARRAY_BUFFER_BINDING) +GL_ENUM(0x889A,GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING) +GL_ENUM(0x889E,GL_WEIGHT_ARRAY_BUFFER_BINDING_OES) +GL_ENUM(0x889F,GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) +GL_ENUM(0x88B9,GL_WRITE_ONLY_OES) +GL_ENUM(0x88BB,GL_BUFFER_ACCESS_OES) +GL_ENUM(0x88BC,GL_BUFFER_MAPPED_OES) +GL_ENUM(0x88BD,GL_BUFFER_MAP_POINTER_OES) +GL_ENUM(0x88E0,GL_STREAM_DRAW) +GL_ENUM(0x88E4,GL_STATIC_DRAW) +GL_ENUM(0x88E8,GL_DYNAMIC_DRAW) +GL_ENUM(0x88F0,GL_DEPTH24_STENCIL8_OES) +GL_ENUM(0x898A,GL_POINT_SIZE_ARRAY_TYPE_OES) +GL_ENUM(0x898B,GL_POINT_SIZE_ARRAY_STRIDE_OES) +GL_ENUM(0x898C,GL_POINT_SIZE_ARRAY_POINTER_OES) +GL_ENUM(0x898D,GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES) +GL_ENUM(0x898E,GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES) +GL_ENUM(0x898F,GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES) +GL_ENUM(0x8B30,GL_FRAGMENT_SHADER) +GL_ENUM(0x8B31,GL_VERTEX_SHADER) +GL_ENUM(0x8B4C,GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS) +GL_ENUM(0x8B4D,GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS) +GL_ENUM(0x8B4F,GL_SHADER_TYPE) +GL_ENUM(0x8B50,GL_FLOAT_VEC2) +GL_ENUM(0x8B51,GL_FLOAT_VEC3) +GL_ENUM(0x8B52,GL_FLOAT_VEC4) +GL_ENUM(0x8B53,GL_INT_VEC2) +GL_ENUM(0x8B54,GL_INT_VEC3) +GL_ENUM(0x8B55,GL_INT_VEC4) +GL_ENUM(0x8B56,GL_BOOL) +GL_ENUM(0x8B57,GL_BOOL_VEC2) +GL_ENUM(0x8B58,GL_BOOL_VEC3) +GL_ENUM(0x8B59,GL_BOOL_VEC4) +GL_ENUM(0x8B5A,GL_FLOAT_MAT2) +GL_ENUM(0x8B5B,GL_FLOAT_MAT3) +GL_ENUM(0x8B5C,GL_FLOAT_MAT4) +GL_ENUM(0x8B5E,GL_SAMPLER_2D) +GL_ENUM(0x8B5F,GL_SAMPLER_3D_OES) +GL_ENUM(0x8B60,GL_SAMPLER_CUBE) +GL_ENUM(0x8B80,GL_DELETE_STATUS) +GL_ENUM(0x8B81,GL_COMPILE_STATUS) +GL_ENUM(0x8B82,GL_LINK_STATUS) +GL_ENUM(0x8B83,GL_VALIDATE_STATUS) +GL_ENUM(0x8B84,GL_INFO_LOG_LENGTH) +GL_ENUM(0x8B85,GL_ATTACHED_SHADERS) +GL_ENUM(0x8B86,GL_ACTIVE_UNIFORMS) +GL_ENUM(0x8B87,GL_ACTIVE_UNIFORM_MAX_LENGTH) +GL_ENUM(0x8B88,GL_SHADER_SOURCE_LENGTH) +GL_ENUM(0x8B89,GL_ACTIVE_ATTRIBUTES) +GL_ENUM(0x8B8A,GL_ACTIVE_ATTRIBUTE_MAX_LENGTH) +GL_ENUM(0x8B8B,GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES) +GL_ENUM(0x8B8C,GL_SHADING_LANGUAGE_VERSION) +GL_ENUM(0x8B8D,GL_CURRENT_PROGRAM) +GL_ENUM(0x8B90,GL_PALETTE4_RGB8_OES) +GL_ENUM(0x8B91,GL_PALETTE4_RGBA8_OES) +GL_ENUM(0x8B92,GL_PALETTE4_R5_G6_B5_OES) +GL_ENUM(0x8B93,GL_PALETTE4_RGBA4_OES) +GL_ENUM(0x8B94,GL_PALETTE4_RGB5_A1_OES) +GL_ENUM(0x8B95,GL_PALETTE8_RGB8_OES) +GL_ENUM(0x8B96,GL_PALETTE8_RGBA8_OES) +GL_ENUM(0x8B97,GL_PALETTE8_R5_G6_B5_OES) +GL_ENUM(0x8B98,GL_PALETTE8_RGBA4_OES) +GL_ENUM(0x8B99,GL_PALETTE8_RGB5_A1_OES) +GL_ENUM(0x8B9A,GL_IMPLEMENTATION_COLOR_READ_TYPE_OES) +GL_ENUM(0x8B9B,GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES) +GL_ENUM(0x8B9C,GL_POINT_SIZE_ARRAY_OES) +GL_ENUM(0x8B9D,GL_TEXTURE_CROP_RECT_OES) +GL_ENUM(0x8B9E,GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES) +GL_ENUM(0x8B9F,GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES) +GL_ENUM(0x8BC0,GL_COUNTER_TYPE_AMD) +GL_ENUM(0x8BC1,GL_COUNTER_RANGE_AMD) +GL_ENUM(0x8BC2,GL_UNSIGNED_INT64_AMD) +GL_ENUM(0x8BC3,GL_PERCENTAGE_AMD) +GL_ENUM(0x8BC4,GL_PERFMON_RESULT_AVAILABLE_AMD) +GL_ENUM(0x8BC5,GL_PERFMON_RESULT_SIZE_AMD) +GL_ENUM(0x8BC6,GL_PERFMON_RESULT_AMD) +GL_ENUM(0x8BD2,GL_TEXTURE_WIDTH_QCOM) +GL_ENUM(0x8BD3,GL_TEXTURE_HEIGHT_QCOM) +GL_ENUM(0x8BD4,GL_TEXTURE_DEPTH_QCOM) +GL_ENUM(0x8BD5,GL_TEXTURE_INTERNAL_FORMAT_QCOM) +GL_ENUM(0x8BD6,GL_TEXTURE_FORMAT_QCOM) +GL_ENUM(0x8BD7,GL_TEXTURE_TYPE_QCOM) +GL_ENUM(0x8BD8,GL_TEXTURE_IMAGE_VALID_QCOM) +GL_ENUM(0x8BD9,GL_TEXTURE_NUM_LEVELS_QCOM) +GL_ENUM(0x8BDA,GL_TEXTURE_TARGET_QCOM) +GL_ENUM(0x8BDB,GL_TEXTURE_OBJECT_VALID_QCOM) +GL_ENUM(0x8BDC,GL_STATE_RESTORE) +GL_ENUM(0x8C00,GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG) +GL_ENUM(0x8C01,GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG) +GL_ENUM(0x8C02,GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG) +GL_ENUM(0x8C03,GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG) +GL_ENUM(0x8C04,GL_MODULATE_COLOR_IMG) +GL_ENUM(0x8C05,GL_RECIP_ADD_SIGNED_ALPHA_IMG) +GL_ENUM(0x8C06,GL_TEXTURE_ALPHA_MODULATE_IMG) +GL_ENUM(0x8C07,GL_FACTOR_ALPHA_MODULATE_IMG) +GL_ENUM(0x8C08,GL_FRAGMENT_ALPHA_MODULATE_IMG) +GL_ENUM(0x8C09,GL_ADD_BLEND_IMG) +GL_ENUM(0x8C0A,GL_SGX_BINARY_IMG) +GL_ENUM(0x8C92,GL_ATC_RGB_AMD) +GL_ENUM(0x8C93,GL_ATC_RGBA_EXPLICIT_ALPHA_AMD) +GL_ENUM(0x8CA3,GL_STENCIL_BACK_REF) +GL_ENUM(0x8CA4,GL_STENCIL_BACK_VALUE_MASK) +GL_ENUM(0x8CA5,GL_STENCIL_BACK_WRITEMASK) +GL_ENUM(0x8CA6,GL_FRAMEBUFFER_BINDING_OES) +GL_ENUM(0x8CA7,GL_RENDERBUFFER_BINDING_OES) +GL_ENUM(0x8CD0,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES) +GL_ENUM(0x8CD1,GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES) +GL_ENUM(0x8CD2,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES) +GL_ENUM(0x8CD3,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_OES) +GL_ENUM(0x8CD4,GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES) +GL_ENUM(0x8CD5,GL_FRAMEBUFFER_COMPLETE_OES) +GL_ENUM(0x8CD6,GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES) +GL_ENUM(0x8CD7,GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES) +GL_ENUM(0x8CD9,GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES) +GL_ENUM(0x8CDA,GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES) +GL_ENUM(0x8CDD,GL_FRAMEBUFFER_UNSUPPORTED_OES) +GL_ENUM(0x8CE0,GL_COLOR_ATTACHMENT0_OES) +GL_ENUM(0x8D00,GL_DEPTH_ATTACHMENT_OES) +GL_ENUM(0x8D20,GL_STENCIL_ATTACHMENT_OES) +GL_ENUM(0x8D40,GL_FRAMEBUFFER_OES) +GL_ENUM(0x8D41,GL_RENDERBUFFER_OES) +GL_ENUM(0x8D42,GL_RENDERBUFFER_WIDTH_OES) +GL_ENUM(0x8D43,GL_RENDERBUFFER_HEIGHT_OES) +GL_ENUM(0x8D44,GL_RENDERBUFFER_INTERNAL_FORMAT_OES) +GL_ENUM(0x8D46,GL_STENCIL_INDEX1_OES) +GL_ENUM(0x8D47,GL_STENCIL_INDEX4_OES) +GL_ENUM(0x8D48,GL_STENCIL_INDEX8_OES) +GL_ENUM(0x8D50,GL_RENDERBUFFER_RED_SIZE_OES) +GL_ENUM(0x8D51,GL_RENDERBUFFER_GREEN_SIZE_OES) +GL_ENUM(0x8D52,GL_RENDERBUFFER_BLUE_SIZE_OES) +GL_ENUM(0x8D53,GL_RENDERBUFFER_ALPHA_SIZE_OES) +GL_ENUM(0x8D54,GL_RENDERBUFFER_DEPTH_SIZE_OES) +GL_ENUM(0x8D55,GL_RENDERBUFFER_STENCIL_SIZE_OES) +GL_ENUM(0x8D60,GL_TEXTURE_GEN_STR_OES) +GL_ENUM(0x8D61,GL_HALF_FLOAT_OES) +GL_ENUM(0x8D62,GL_RGB565_OES) +GL_ENUM(0x8D64,GL_ETC1_RGB8_OES) +GL_ENUM(0x8D65,GL_TEXTURE_EXTERNAL_OES) +GL_ENUM(0x8D66,GL_SAMPLER_EXTERNAL_OES) +GL_ENUM(0x8D67,GL_TEXTURE_BINDING_EXTERNAL_OES) +GL_ENUM(0x8D68,GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES) +GL_ENUM(0x8DF0,GL_LOW_FLOAT) +GL_ENUM(0x8DF1,GL_MEDIUM_FLOAT) +GL_ENUM(0x8DF2,GL_HIGH_FLOAT) +GL_ENUM(0x8DF3,GL_LOW_INT) +GL_ENUM(0x8DF4,GL_MEDIUM_INT) +GL_ENUM(0x8DF5,GL_HIGH_INT) +GL_ENUM(0x8DF6,GL_UNSIGNED_INT_10_10_10_2_OES) +GL_ENUM(0x8DF7,GL_INT_10_10_10_2_OES) +GL_ENUM(0x8DF8,GL_SHADER_BINARY_FORMATS) +GL_ENUM(0x8DF9,GL_NUM_SHADER_BINARY_FORMATS) +GL_ENUM(0x8DFA,GL_SHADER_COMPILER) +GL_ENUM(0x8DFB,GL_MAX_VERTEX_UNIFORM_VECTORS) +GL_ENUM(0x8DFC,GL_MAX_VARYING_VECTORS) +GL_ENUM(0x8DFD,GL_MAX_FRAGMENT_UNIFORM_VECTORS) +GL_ENUM(0x8E2C,GL_DEPTH_COMPONENT16_NONLINEAR_NV) +GL_ENUM(0x8ED0,GL_COVERAGE_COMPONENT_NV) +GL_ENUM(0x8ED1,GL_COVERAGE_COMPONENT4_NV) +GL_ENUM(0x8ED2,GL_COVERAGE_ATTACHMENT_NV) +GL_ENUM(0x8ED3,GL_COVERAGE_BUFFERS_NV) +GL_ENUM(0x8ED4,GL_COVERAGE_SAMPLES_NV) +GL_ENUM(0x8ED5,GL_COVERAGE_ALL_FRAGMENTS_NV) +GL_ENUM(0x8ED6,GL_COVERAGE_EDGE_FRAGMENTS_NV) +GL_ENUM(0x8ED7,GL_COVERAGE_AUTOMATIC_NV) +GL_ENUM(0x8FA0,GL_PERFMON_GLOBAL_MODE_QCOM) +GL_ENUM(0x9130,GL_SGX_PROGRAM_BINARY_IMG) +GL_ENUM(0x9133,GL_RENDERBUFFER_SAMPLES_IMG) +GL_ENUM(0x9134,GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG) +GL_ENUM(0x9135,GL_MAX_SAMPLES_IMG) +GL_ENUM(0x9136,GL_TEXTURE_SAMPLES_IMG) diff --git a/opengl/libs/hooks.h b/opengl/libs/hooks.h index 1ab58cc83349..812e26d10cb8 100644 --- a/opengl/libs/hooks.h +++ b/opengl/libs/hooks.h @@ -141,6 +141,11 @@ static gl_hooks_t const* getGlThreadSpecific() { #endif +#if EGL_TRACE + +extern gl_hooks_t const* getGLTraceThreadSpecific(); + +#endif // ---------------------------------------------------------------------------- }; // namespace android diff --git a/opengl/libs/tools/genfiles b/opengl/libs/tools/genfiles index 120cb4be8699..50bbf08441f7 100755 --- a/opengl/libs/tools/genfiles +++ b/opengl/libs/tools/genfiles @@ -31,3 +31,14 @@ cat /tmp/gl_entries.in \ | sort -t, -k2 \ | awk -F, '!_[$2]++' \ > ../entries.in + +./gltracegen ../entries.in >../trace.in + +cat ../../include/GLES/gl.h \ + ../../include/GLES/glext.h \ + ../../include/GLES2/gl2.h \ + ../../include/GLES2/gl2ext.h \ + | ./glenumsgen \ + | sort \ + > ../enums.in + diff --git a/opengl/libs/tools/glenumsgen b/opengl/libs/tools/glenumsgen new file mode 100755 index 000000000000..2ae5fbfa258d --- /dev/null +++ b/opengl/libs/tools/glenumsgen @@ -0,0 +1,38 @@ +#! /usr/bin/perl +# +# Copyright (C) 2010 Google Inc. +# +# 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. + +use strict; + +my %enumHash = (); + +while (my $line = <STDIN>) { + next if $line =~ /^\//; + # Skip bitfield definitions. + next if $line =~ /_BIT(\d+_|\s+)/; + if ($line !~ /^#define\s+(\S+)\s+(0x\S+)/) { + next; + } + my $enumName = $1; + my $enumValue = $2; + next if exists($enumHash { $enumValue }); + $enumHash { $enumValue } = $enumName; + printf("GL_ENUM(%s,%s)\n", $enumValue, $enumName); +} + + + + + diff --git a/opengl/libs/tools/gltracegen b/opengl/libs/tools/gltracegen new file mode 100755 index 000000000000..da42653e64d6 --- /dev/null +++ b/opengl/libs/tools/gltracegen @@ -0,0 +1,95 @@ +#! /usr/bin/perl +# +# Copyright (C) 2010 Google Inc. +# +# 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. + +use strict; + +sub rtrim($) +{ + my $string = shift; + $string =~ s/\s+$//; + return $string; +} + +while (my $line = <>) { + next if $line =~ /^\//; + next if $line =~ /^#/; + next if $line =~ /^\s*$/; + if ($line !~ /^GL_ENTRY\(([^,]+), ([^,]+), ([^\)]+)\)/) { + next; + } + my $type = $1; + my $name = $2; + my $args = $3; + + my @args = split ',', $args; + my $len = scalar(@args); + my $nonVoidArgLen = 0; + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + $nonVoidArgLen++; + } + } + if ($type eq "void") { + printf("TRACE_GL_VOID("); + } else { + printf("TRACE_GL(%s, ", $type); + } + + printf("%s, (%s), (", $name, $args); + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + if ($num > 0) { + print ", "; + } + # + # extract the name from the parameter + # type name + # const type *name + # type *name + # type name[4] + # + if ($args[$num] =~ /(\S+\s)+\**\s*([\w]+)/) { + printf("%s", $2); + } + } + } + printf("), %d", $nonVoidArgLen); + for (my $num = 0; $num < $len; $num++) { + if ($args[$num] ne "void") { + # + # extract the name from the parameter + # type name + # const type *name + # type *name + # type name[4] + # + my $arg = $args[$num]; + if ($arg =~ /(\S+\s)+\**\s*([\w]+)/) { + my $name = $2; + if ($arg =~ /((const )*(\S+\s)+\**)\s*([\w]+)/) { + my $type = rtrim($1); + printf(", \"%s\", %s", $type, $name); + } + } + } + } + printf(")\n"); +} + + + + + diff --git a/opengl/libs/trace.in b/opengl/libs/trace.in new file mode 100644 index 000000000000..3d492af4ee93 --- /dev/null +++ b/opengl/libs/trace.in @@ -0,0 +1,376 @@ +TRACE_GL_VOID(glActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture) +TRACE_GL_VOID(glAlphaFunc, (GLenum func, GLclampf ref), (func, ref), 2, "GLenum", func, "GLclampf", ref) +TRACE_GL_VOID(glAlphaFuncx, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref) +TRACE_GL_VOID(glAlphaFuncxOES, (GLenum func, GLclampx ref), (func, ref), 2, "GLenum", func, "GLclampx", ref) +TRACE_GL_VOID(glAttachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader) +TRACE_GL_VOID(glBeginPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor) +TRACE_GL_VOID(glBindAttribLocation, (GLuint program, GLuint index, const GLchar* name), (program, index, name), 3, "GLuint", program, "GLuint", index, "const GLchar*", name) +TRACE_GL_VOID(glBindBuffer, (GLenum target, GLuint buffer), (target, buffer), 2, "GLenum", target, "GLuint", buffer) +TRACE_GL_VOID(glBindFramebuffer, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer) +TRACE_GL_VOID(glBindFramebufferOES, (GLenum target, GLuint framebuffer), (target, framebuffer), 2, "GLenum", target, "GLuint", framebuffer) +TRACE_GL_VOID(glBindRenderbuffer, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer) +TRACE_GL_VOID(glBindRenderbufferOES, (GLenum target, GLuint renderbuffer), (target, renderbuffer), 2, "GLenum", target, "GLuint", renderbuffer) +TRACE_GL_VOID(glBindTexture, (GLenum target, GLuint texture), (target, texture), 2, "GLenum", target, "GLuint", texture) +TRACE_GL_VOID(glBindVertexArrayOES, (GLuint array), (array), 1, "GLuint", array) +TRACE_GL_VOID(glBlendColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), (red, green, blue, alpha), 4, "GLclampf", red, "GLclampf", green, "GLclampf", blue, "GLclampf", alpha) +TRACE_GL_VOID(glBlendEquation, ( GLenum mode ), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glBlendEquationOES, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glBlendEquationSeparate, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha) +TRACE_GL_VOID(glBlendEquationSeparateOES, (GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), 2, "GLenum", modeRGB, "GLenum", modeAlpha) +TRACE_GL_VOID(glBlendFunc, (GLenum sfactor, GLenum dfactor), (sfactor, dfactor), 2, "GLenum", sfactor, "GLenum", dfactor) +TRACE_GL_VOID(glBlendFuncSeparate, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha) +TRACE_GL_VOID(glBlendFuncSeparateOES, (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha), (srcRGB, dstRGB, srcAlpha, dstAlpha), 4, "GLenum", srcRGB, "GLenum", dstRGB, "GLenum", srcAlpha, "GLenum", dstAlpha) +TRACE_GL_VOID(glBufferData, (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage), (target, size, data, usage), 4, "GLenum", target, "GLsizeiptr", size, "const GLvoid *", data, "GLenum", usage) +TRACE_GL_VOID(glBufferSubData, (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data), (target, offset, size, data), 4, "GLenum", target, "GLintptr", offset, "GLsizeiptr", size, "const GLvoid *", data) +TRACE_GL(GLenum, glCheckFramebufferStatus, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL(GLenum, glCheckFramebufferStatusOES, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glClear, (GLbitfield mask), (mask), 1, "GLbitfield", mask) +TRACE_GL_VOID(glClearColor, (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha), (red, green, blue, alpha), 4, "GLclampf", red, "GLclampf", green, "GLclampf", blue, "GLclampf", alpha) +TRACE_GL_VOID(glClearColorx, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha) +TRACE_GL_VOID(glClearColorxOES, (GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha), (red, green, blue, alpha), 4, "GLclampx", red, "GLclampx", green, "GLclampx", blue, "GLclampx", alpha) +TRACE_GL_VOID(glClearDepthf, (GLclampf depth), (depth), 1, "GLclampf", depth) +TRACE_GL_VOID(glClearDepthfOES, (GLclampf depth), (depth), 1, "GLclampf", depth) +TRACE_GL_VOID(glClearDepthx, (GLclampx depth), (depth), 1, "GLclampx", depth) +TRACE_GL_VOID(glClearDepthxOES, (GLclampx depth), (depth), 1, "GLclampx", depth) +TRACE_GL_VOID(glClearStencil, (GLint s), (s), 1, "GLint", s) +TRACE_GL_VOID(glClientActiveTexture, (GLenum texture), (texture), 1, "GLenum", texture) +TRACE_GL_VOID(glClipPlanef, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation) +TRACE_GL_VOID(glClipPlanefIMG, (GLenum p, const GLfloat *eqn), (p, eqn), 2, "GLenum", p, "const GLfloat *", eqn) +TRACE_GL_VOID(glClipPlanefOES, (GLenum plane, const GLfloat *equation), (plane, equation), 2, "GLenum", plane, "const GLfloat *", equation) +TRACE_GL_VOID(glClipPlanex, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation) +TRACE_GL_VOID(glClipPlanexIMG, (GLenum p, const GLfixed *eqn), (p, eqn), 2, "GLenum", p, "const GLfixed *", eqn) +TRACE_GL_VOID(glClipPlanexOES, (GLenum plane, const GLfixed *equation), (plane, equation), 2, "GLenum", plane, "const GLfixed *", equation) +TRACE_GL_VOID(glColor4f, (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha), (red, green, blue, alpha), 4, "GLfloat", red, "GLfloat", green, "GLfloat", blue, "GLfloat", alpha) +TRACE_GL_VOID(glColor4ub, (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha), (red, green, blue, alpha), 4, "GLubyte", red, "GLubyte", green, "GLubyte", blue, "GLubyte", alpha) +TRACE_GL_VOID(glColor4x, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha) +TRACE_GL_VOID(glColor4xOES, (GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha), (red, green, blue, alpha), 4, "GLfixed", red, "GLfixed", green, "GLfixed", blue, "GLfixed", alpha) +TRACE_GL_VOID(glColorMask, (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha), (red, green, blue, alpha), 4, "GLboolean", red, "GLboolean", green, "GLboolean", blue, "GLboolean", alpha) +TRACE_GL_VOID(glColorPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glCompileShader, (GLuint shader), (shader), 1, "GLuint", shader) +TRACE_GL_VOID(glCompressedTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data), (target, level, internalformat, width, height, border, imageSize, data), 8, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLint", border, "GLsizei", imageSize, "const GLvoid *", data) +TRACE_GL_VOID(glCompressedTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid* data), (target, level, internalformat, width, height, depth, border, imageSize, data), 9, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLsizei", imageSize, "const GLvoid*", data) +TRACE_GL_VOID(glCompressedTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data), (target, level, xoffset, yoffset, width, height, format, imageSize, data), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLsizei", imageSize, "const GLvoid *", data) +TRACE_GL_VOID(glCompressedTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid* data), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLsizei", imageSize, "const GLvoid*", data) +TRACE_GL_VOID(glCopyTexImage2D, (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border), (target, level, internalformat, x, y, width, height, border), 8, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLint", border) +TRACE_GL_VOID(glCopyTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, x, y, width, height), 8, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glCopyTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, zoffset, x, y, width, height), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glCoverageMaskNV, (GLboolean mask), (mask), 1, "GLboolean", mask) +TRACE_GL_VOID(glCoverageOperationNV, (GLenum operation), (operation), 1, "GLenum", operation) +TRACE_GL(GLuint, glCreateProgram, (void), (), 0) +TRACE_GL(GLuint, glCreateShader, (GLenum type), (type), 1, "GLenum", type) +TRACE_GL_VOID(glCullFace, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glCurrentPaletteMatrixOES, (GLuint matrixpaletteindex), (matrixpaletteindex), 1, "GLuint", matrixpaletteindex) +TRACE_GL_VOID(glDeleteBuffers, (GLsizei n, const GLuint *buffers), (n, buffers), 2, "GLsizei", n, "const GLuint *", buffers) +TRACE_GL_VOID(glDeleteFencesNV, (GLsizei n, const GLuint *fences), (n, fences), 2, "GLsizei", n, "const GLuint *", fences) +TRACE_GL_VOID(glDeleteFramebuffers, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers) +TRACE_GL_VOID(glDeleteFramebuffersOES, (GLsizei n, const GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "const GLuint*", framebuffers) +TRACE_GL_VOID(glDeletePerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors) +TRACE_GL_VOID(glDeleteProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glDeleteRenderbuffers, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers) +TRACE_GL_VOID(glDeleteRenderbuffersOES, (GLsizei n, const GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "const GLuint*", renderbuffers) +TRACE_GL_VOID(glDeleteShader, (GLuint shader), (shader), 1, "GLuint", shader) +TRACE_GL_VOID(glDeleteTextures, (GLsizei n, const GLuint *textures), (n, textures), 2, "GLsizei", n, "const GLuint *", textures) +TRACE_GL_VOID(glDeleteVertexArraysOES, (GLsizei n, const GLuint *arrays), (n, arrays), 2, "GLsizei", n, "const GLuint *", arrays) +TRACE_GL_VOID(glDepthFunc, (GLenum func), (func), 1, "GLenum", func) +TRACE_GL_VOID(glDepthMask, (GLboolean flag), (flag), 1, "GLboolean", flag) +TRACE_GL_VOID(glDepthRangef, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar) +TRACE_GL_VOID(glDepthRangefOES, (GLclampf zNear, GLclampf zFar), (zNear, zFar), 2, "GLclampf", zNear, "GLclampf", zFar) +TRACE_GL_VOID(glDepthRangex, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar) +TRACE_GL_VOID(glDepthRangexOES, (GLclampx zNear, GLclampx zFar), (zNear, zFar), 2, "GLclampx", zNear, "GLclampx", zFar) +TRACE_GL_VOID(glDetachShader, (GLuint program, GLuint shader), (program, shader), 2, "GLuint", program, "GLuint", shader) +TRACE_GL_VOID(glDisable, (GLenum cap), (cap), 1, "GLenum", cap) +TRACE_GL_VOID(glDisableClientState, (GLenum array), (array), 1, "GLenum", array) +TRACE_GL_VOID(glDisableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl) +TRACE_GL_VOID(glDisableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index) +TRACE_GL_VOID(glDiscardFramebufferEXT, (GLenum target, GLsizei numAttachments, const GLenum *attachments), (target, numAttachments, attachments), 3, "GLenum", target, "GLsizei", numAttachments, "const GLenum *", attachments) +TRACE_GL_VOID(glDrawArrays, (GLenum mode, GLint first, GLsizei count), (mode, first, count), 3, "GLenum", mode, "GLint", first, "GLsizei", count) +TRACE_GL_VOID(glDrawElements, (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices), (mode, count, type, indices), 4, "GLenum", mode, "GLsizei", count, "GLenum", type, "const GLvoid *", indices) +TRACE_GL_VOID(glDrawTexfOES, (GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height), (x, y, z, width, height), 5, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", width, "GLfloat", height) +TRACE_GL_VOID(glDrawTexfvOES, (const GLfloat *coords), (coords), 1, "const GLfloat *", coords) +TRACE_GL_VOID(glDrawTexiOES, (GLint x, GLint y, GLint z, GLint width, GLint height), (x, y, z, width, height), 5, "GLint", x, "GLint", y, "GLint", z, "GLint", width, "GLint", height) +TRACE_GL_VOID(glDrawTexivOES, (const GLint *coords), (coords), 1, "const GLint *", coords) +TRACE_GL_VOID(glDrawTexsOES, (GLshort x, GLshort y, GLshort z, GLshort width, GLshort height), (x, y, z, width, height), 5, "GLshort", x, "GLshort", y, "GLshort", z, "GLshort", width, "GLshort", height) +TRACE_GL_VOID(glDrawTexsvOES, (const GLshort *coords), (coords), 1, "const GLshort *", coords) +TRACE_GL_VOID(glDrawTexxOES, (GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height), (x, y, z, width, height), 5, "GLfixed", x, "GLfixed", y, "GLfixed", z, "GLfixed", width, "GLfixed", height) +TRACE_GL_VOID(glDrawTexxvOES, (const GLfixed *coords), (coords), 1, "const GLfixed *", coords) +TRACE_GL_VOID(glEGLImageTargetRenderbufferStorageOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image) +TRACE_GL_VOID(glEGLImageTargetTexture2DOES, (GLenum target, GLeglImageOES image), (target, image), 2, "GLenum", target, "GLeglImageOES", image) +TRACE_GL_VOID(glEnable, (GLenum cap), (cap), 1, "GLenum", cap) +TRACE_GL_VOID(glEnableClientState, (GLenum array), (array), 1, "GLenum", array) +TRACE_GL_VOID(glEnableDriverControlQCOM, (GLuint driverControl), (driverControl), 1, "GLuint", driverControl) +TRACE_GL_VOID(glEnableVertexAttribArray, (GLuint index), (index), 1, "GLuint", index) +TRACE_GL_VOID(glEndPerfMonitorAMD, (GLuint monitor), (monitor), 1, "GLuint", monitor) +TRACE_GL_VOID(glEndTilingQCOM, (GLbitfield preserveMask), (preserveMask), 1, "GLbitfield", preserveMask) +TRACE_GL_VOID(glExtGetBufferPointervQCOM, (GLenum target, GLvoid **params), (target, params), 2, "GLenum", target, "GLvoid **", params) +TRACE_GL_VOID(glExtGetBuffersQCOM, (GLuint *buffers, GLint maxBuffers, GLint *numBuffers), (buffers, maxBuffers, numBuffers), 3, "GLuint *", buffers, "GLint", maxBuffers, "GLint *", numBuffers) +TRACE_GL_VOID(glExtGetFramebuffersQCOM, (GLuint *framebuffers, GLint maxFramebuffers, GLint *numFramebuffers), (framebuffers, maxFramebuffers, numFramebuffers), 3, "GLuint *", framebuffers, "GLint", maxFramebuffers, "GLint *", numFramebuffers) +TRACE_GL_VOID(glExtGetProgramBinarySourceQCOM, (GLuint program, GLenum shadertype, GLchar *source, GLint *length), (program, shadertype, source, length), 4, "GLuint", program, "GLenum", shadertype, "GLchar *", source, "GLint *", length) +TRACE_GL_VOID(glExtGetProgramsQCOM, (GLuint *programs, GLint maxPrograms, GLint *numPrograms), (programs, maxPrograms, numPrograms), 3, "GLuint *", programs, "GLint", maxPrograms, "GLint *", numPrograms) +TRACE_GL_VOID(glExtGetRenderbuffersQCOM, (GLuint *renderbuffers, GLint maxRenderbuffers, GLint *numRenderbuffers), (renderbuffers, maxRenderbuffers, numRenderbuffers), 3, "GLuint *", renderbuffers, "GLint", maxRenderbuffers, "GLint *", numRenderbuffers) +TRACE_GL_VOID(glExtGetShadersQCOM, (GLuint *shaders, GLint maxShaders, GLint *numShaders), (shaders, maxShaders, numShaders), 3, "GLuint *", shaders, "GLint", maxShaders, "GLint *", numShaders) +TRACE_GL_VOID(glExtGetTexLevelParameterivQCOM, (GLuint texture, GLenum face, GLint level, GLenum pname, GLint *params), (texture, face, level, pname, params), 5, "GLuint", texture, "GLenum", face, "GLint", level, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glExtGetTexSubImageQCOM, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *texels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "GLvoid *", texels) +TRACE_GL_VOID(glExtGetTexturesQCOM, (GLuint *textures, GLint maxTextures, GLint *numTextures), (textures, maxTextures, numTextures), 3, "GLuint *", textures, "GLint", maxTextures, "GLint *", numTextures) +TRACE_GL(GLboolean, glExtIsProgramBinaryQCOM, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glExtTexObjectStateOverrideiQCOM, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glFinish, (void), (), 0) +TRACE_GL_VOID(glFinishFenceNV, (GLuint fence), (fence), 1, "GLuint", fence) +TRACE_GL_VOID(glFlush, (void), (), 0) +TRACE_GL_VOID(glFogf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glFogfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glFogx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glFogxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glFogxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glFogxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glFramebufferRenderbuffer, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer) +TRACE_GL_VOID(glFramebufferRenderbufferOES, (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer), (target, attachment, renderbuffertarget, renderbuffer), 4, "GLenum", target, "GLenum", attachment, "GLenum", renderbuffertarget, "GLuint", renderbuffer) +TRACE_GL_VOID(glFramebufferTexture2D, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level) +TRACE_GL_VOID(glFramebufferTexture2DMultisampleIMG, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLsizei samples), (target, attachment, textarget, texture, level, samples), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLsizei", samples) +TRACE_GL_VOID(glFramebufferTexture2DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level), (target, attachment, textarget, texture, level), 5, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level) +TRACE_GL_VOID(glFramebufferTexture3DOES, (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset), (target, attachment, textarget, texture, level, zoffset), 6, "GLenum", target, "GLenum", attachment, "GLenum", textarget, "GLuint", texture, "GLint", level, "GLint", zoffset) +TRACE_GL_VOID(glFrontFace, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glFrustumf, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glFrustumfOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glFrustumx, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glFrustumxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glGenBuffers, (GLsizei n, GLuint *buffers), (n, buffers), 2, "GLsizei", n, "GLuint *", buffers) +TRACE_GL_VOID(glGenFencesNV, (GLsizei n, GLuint *fences), (n, fences), 2, "GLsizei", n, "GLuint *", fences) +TRACE_GL_VOID(glGenFramebuffers, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers) +TRACE_GL_VOID(glGenFramebuffersOES, (GLsizei n, GLuint* framebuffers), (n, framebuffers), 2, "GLsizei", n, "GLuint*", framebuffers) +TRACE_GL_VOID(glGenPerfMonitorsAMD, (GLsizei n, GLuint *monitors), (n, monitors), 2, "GLsizei", n, "GLuint *", monitors) +TRACE_GL_VOID(glGenRenderbuffers, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers) +TRACE_GL_VOID(glGenRenderbuffersOES, (GLsizei n, GLuint* renderbuffers), (n, renderbuffers), 2, "GLsizei", n, "GLuint*", renderbuffers) +TRACE_GL_VOID(glGenTextures, (GLsizei n, GLuint *textures), (n, textures), 2, "GLsizei", n, "GLuint *", textures) +TRACE_GL_VOID(glGenVertexArraysOES, (GLsizei n, GLuint *arrays), (n, arrays), 2, "GLsizei", n, "GLuint *", arrays) +TRACE_GL_VOID(glGenerateMipmap, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glGenerateMipmapOES, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glGetActiveAttrib, (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name), 7, "GLuint", program, "GLuint", index, "GLsizei", bufsize, "GLsizei*", length, "GLint*", size, "GLenum*", type, "GLchar*", name) +TRACE_GL_VOID(glGetActiveUniform, (GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name), (program, index, bufsize, length, size, type, name), 7, "GLuint", program, "GLuint", index, "GLsizei", bufsize, "GLsizei*", length, "GLint*", size, "GLenum*", type, "GLchar*", name) +TRACE_GL_VOID(glGetAttachedShaders, (GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders), (program, maxcount, count, shaders), 4, "GLuint", program, "GLsizei", maxcount, "GLsizei*", count, "GLuint*", shaders) +TRACE_GL(int, glGetAttribLocation, (GLuint program, const GLchar* name), (program, name), 2, "GLuint", program, "const GLchar*", name) +TRACE_GL_VOID(glGetBooleanv, (GLenum pname, GLboolean *params), (pname, params), 2, "GLenum", pname, "GLboolean *", params) +TRACE_GL_VOID(glGetBufferParameteriv, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetBufferPointervOES, (GLenum target, GLenum pname, GLvoid ** params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLvoid **", params) +TRACE_GL_VOID(glGetClipPlanef, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn) +TRACE_GL_VOID(glGetClipPlanefOES, (GLenum pname, GLfloat eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfloat", eqn) +TRACE_GL_VOID(glGetClipPlanex, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn) +TRACE_GL_VOID(glGetClipPlanexOES, (GLenum pname, GLfixed eqn[4]), (pname, eqn), 2, "GLenum", pname, "GLfixed", eqn) +TRACE_GL_VOID(glGetDriverControlStringQCOM, (GLuint driverControl, GLsizei bufSize, GLsizei *length, GLchar *driverControlString), (driverControl, bufSize, length, driverControlString), 4, "GLuint", driverControl, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", driverControlString) +TRACE_GL_VOID(glGetDriverControlsQCOM, (GLint *num, GLsizei size, GLuint *driverControls), (num, size, driverControls), 3, "GLint *", num, "GLsizei", size, "GLuint *", driverControls) +TRACE_GL(GLenum, glGetError, (void), (), 0) +TRACE_GL_VOID(glGetFenceivNV, (GLuint fence, GLenum pname, GLint *params), (fence, pname, params), 3, "GLuint", fence, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetFixedv, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetFixedvOES, (GLenum pname, GLfixed *params), (pname, params), 2, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetFloatv, (GLenum pname, GLfloat *params), (pname, params), 2, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetFramebufferAttachmentParameteriv, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetFramebufferAttachmentParameterivOES, (GLenum target, GLenum attachment, GLenum pname, GLint* params), (target, attachment, pname, params), 4, "GLenum", target, "GLenum", attachment, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetIntegerv, (GLenum pname, GLint *params), (pname, params), 2, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetLightfv, (GLenum light, GLenum pname, GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetLightxv, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetLightxvOES, (GLenum light, GLenum pname, GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetMaterialfv, (GLenum face, GLenum pname, GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetMaterialxv, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetMaterialxvOES, (GLenum face, GLenum pname, GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetPerfMonitorCounterDataAMD, (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten), (monitor, pname, dataSize, data, bytesWritten), 5, "GLuint", monitor, "GLenum", pname, "GLsizei", dataSize, "GLuint *", data, "GLint *", bytesWritten) +TRACE_GL_VOID(glGetPerfMonitorCounterInfoAMD, (GLuint group, GLuint counter, GLenum pname, GLvoid *data), (group, counter, pname, data), 4, "GLuint", group, "GLuint", counter, "GLenum", pname, "GLvoid *", data) +TRACE_GL_VOID(glGetPerfMonitorCounterStringAMD, (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString), (group, counter, bufSize, length, counterString), 5, "GLuint", group, "GLuint", counter, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", counterString) +TRACE_GL_VOID(glGetPerfMonitorCountersAMD, (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters), (group, numCounters, maxActiveCounters, counterSize, counters), 5, "GLuint", group, "GLint *", numCounters, "GLint *", maxActiveCounters, "GLsizei", counterSize, "GLuint *", counters) +TRACE_GL_VOID(glGetPerfMonitorGroupStringAMD, (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString), (group, bufSize, length, groupString), 4, "GLuint", group, "GLsizei", bufSize, "GLsizei *", length, "GLchar *", groupString) +TRACE_GL_VOID(glGetPerfMonitorGroupsAMD, (GLint *numGroups, GLsizei groupsSize, GLuint *groups), (numGroups, groupsSize, groups), 3, "GLint *", numGroups, "GLsizei", groupsSize, "GLuint *", groups) +TRACE_GL_VOID(glGetPointerv, (GLenum pname, GLvoid **params), (pname, params), 2, "GLenum", pname, "GLvoid **", params) +TRACE_GL_VOID(glGetProgramBinaryOES, (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary), (program, bufSize, length, binaryFormat, binary), 5, "GLuint", program, "GLsizei", bufSize, "GLsizei *", length, "GLenum *", binaryFormat, "GLvoid *", binary) +TRACE_GL_VOID(glGetProgramInfoLog, (GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog), (program, bufsize, length, infolog), 4, "GLuint", program, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog) +TRACE_GL_VOID(glGetProgramiv, (GLuint program, GLenum pname, GLint* params), (program, pname, params), 3, "GLuint", program, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetRenderbufferParameteriv, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetRenderbufferParameterivOES, (GLenum target, GLenum pname, GLint* params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glGetShaderInfoLog, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog), (shader, bufsize, length, infolog), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", infolog) +TRACE_GL_VOID(glGetShaderPrecisionFormat, (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision), (shadertype, precisiontype, range, precision), 4, "GLenum", shadertype, "GLenum", precisiontype, "GLint*", range, "GLint*", precision) +TRACE_GL_VOID(glGetShaderSource, (GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source), (shader, bufsize, length, source), 4, "GLuint", shader, "GLsizei", bufsize, "GLsizei*", length, "GLchar*", source) +TRACE_GL_VOID(glGetShaderiv, (GLuint shader, GLenum pname, GLint* params), (shader, pname, params), 3, "GLuint", shader, "GLenum", pname, "GLint*", params) +TRACE_GL(const GLubyte *, glGetString, (GLenum name), (name), 1, "GLenum", name) +TRACE_GL_VOID(glGetTexEnvfv, (GLenum env, GLenum pname, GLfloat *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetTexEnviv, (GLenum env, GLenum pname, GLint *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetTexEnvxv, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexEnvxvOES, (GLenum env, GLenum pname, GLfixed *params), (env, pname, params), 3, "GLenum", env, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexGenfvOES, (GLenum coord, GLenum pname, GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetTexGenivOES, (GLenum coord, GLenum pname, GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetTexGenxvOES, (GLenum coord, GLenum pname, GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexParameterfv, (GLenum target, GLenum pname, GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfloat *", params) +TRACE_GL_VOID(glGetTexParameteriv, (GLenum target, GLenum pname, GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLint *", params) +TRACE_GL_VOID(glGetTexParameterxv, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params) +TRACE_GL_VOID(glGetTexParameterxvOES, (GLenum target, GLenum pname, GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "GLfixed *", params) +TRACE_GL(int, glGetUniformLocation, (GLuint program, const GLchar* name), (program, name), 2, "GLuint", program, "const GLchar*", name) +TRACE_GL_VOID(glGetUniformfv, (GLuint program, GLint location, GLfloat* params), (program, location, params), 3, "GLuint", program, "GLint", location, "GLfloat*", params) +TRACE_GL_VOID(glGetUniformiv, (GLuint program, GLint location, GLint* params), (program, location, params), 3, "GLuint", program, "GLint", location, "GLint*", params) +TRACE_GL_VOID(glGetVertexAttribPointerv, (GLuint index, GLenum pname, GLvoid** pointer), (index, pname, pointer), 3, "GLuint", index, "GLenum", pname, "GLvoid**", pointer) +TRACE_GL_VOID(glGetVertexAttribfv, (GLuint index, GLenum pname, GLfloat* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLfloat*", params) +TRACE_GL_VOID(glGetVertexAttribiv, (GLuint index, GLenum pname, GLint* params), (index, pname, params), 3, "GLuint", index, "GLenum", pname, "GLint*", params) +TRACE_GL_VOID(glHint, (GLenum target, GLenum mode), (target, mode), 2, "GLenum", target, "GLenum", mode) +TRACE_GL(GLboolean, glIsBuffer, (GLuint buffer), (buffer), 1, "GLuint", buffer) +TRACE_GL(GLboolean, glIsEnabled, (GLenum cap), (cap), 1, "GLenum", cap) +TRACE_GL(GLboolean, glIsFenceNV, (GLuint fence), (fence), 1, "GLuint", fence) +TRACE_GL(GLboolean, glIsFramebuffer, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer) +TRACE_GL(GLboolean, glIsFramebufferOES, (GLuint framebuffer), (framebuffer), 1, "GLuint", framebuffer) +TRACE_GL(GLboolean, glIsProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL(GLboolean, glIsRenderbuffer, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer) +TRACE_GL(GLboolean, glIsRenderbufferOES, (GLuint renderbuffer), (renderbuffer), 1, "GLuint", renderbuffer) +TRACE_GL(GLboolean, glIsShader, (GLuint shader), (shader), 1, "GLuint", shader) +TRACE_GL(GLboolean, glIsTexture, (GLuint texture), (texture), 1, "GLuint", texture) +TRACE_GL(GLboolean, glIsVertexArrayOES, (GLuint array), (array), 1, "GLuint", array) +TRACE_GL_VOID(glLightModelf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glLightModelfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glLightModelx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightModelxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightModelxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLightModelxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLightf, (GLenum light, GLenum pname, GLfloat param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glLightfv, (GLenum light, GLenum pname, const GLfloat *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glLightx, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightxOES, (GLenum light, GLenum pname, GLfixed param), (light, pname, param), 3, "GLenum", light, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glLightxv, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLightxvOES, (GLenum light, GLenum pname, const GLfixed *params), (light, pname, params), 3, "GLenum", light, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glLineWidth, (GLfloat width), (width), 1, "GLfloat", width) +TRACE_GL_VOID(glLineWidthx, (GLfixed width), (width), 1, "GLfixed", width) +TRACE_GL_VOID(glLineWidthxOES, (GLfixed width), (width), 1, "GLfixed", width) +TRACE_GL_VOID(glLinkProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glLoadIdentity, (void), (), 0) +TRACE_GL_VOID(glLoadMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m) +TRACE_GL_VOID(glLoadMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glLoadMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glLoadPaletteFromModelViewMatrixOES, (void), (), 0) +TRACE_GL_VOID(glLogicOp, (GLenum opcode), (opcode), 1, "GLenum", opcode) +TRACE_GL(void*, glMapBufferOES, (GLenum target, GLenum access), (target, access), 2, "GLenum", target, "GLenum", access) +TRACE_GL_VOID(glMaterialf, (GLenum face, GLenum pname, GLfloat param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glMaterialfv, (GLenum face, GLenum pname, const GLfloat *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glMaterialx, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glMaterialxOES, (GLenum face, GLenum pname, GLfixed param), (face, pname, param), 3, "GLenum", face, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glMaterialxv, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glMaterialxvOES, (GLenum face, GLenum pname, const GLfixed *params), (face, pname, params), 3, "GLenum", face, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glMatrixIndexPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glMatrixMode, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glMultMatrixf, (const GLfloat *m), (m), 1, "const GLfloat *", m) +TRACE_GL_VOID(glMultMatrixx, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glMultMatrixxOES, (const GLfixed *m), (m), 1, "const GLfixed *", m) +TRACE_GL_VOID(glMultiDrawArraysEXT, (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount), (mode, first, count, primcount), 4, "GLenum", mode, "GLint *", first, "GLsizei *", count, "GLsizei", primcount) +TRACE_GL_VOID(glMultiDrawElementsEXT, (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount), (mode, count, type, indices, primcount), 5, "GLenum", mode, "const GLsizei *", count, "GLenum", type, "const GLvoid* *", indices, "GLsizei", primcount) +TRACE_GL_VOID(glMultiTexCoord4f, (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q), (target, s, t, r, q), 5, "GLenum", target, "GLfloat", s, "GLfloat", t, "GLfloat", r, "GLfloat", q) +TRACE_GL_VOID(glMultiTexCoord4x, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q) +TRACE_GL_VOID(glMultiTexCoord4xOES, (GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q), (target, s, t, r, q), 5, "GLenum", target, "GLfixed", s, "GLfixed", t, "GLfixed", r, "GLfixed", q) +TRACE_GL_VOID(glNormal3f, (GLfloat nx, GLfloat ny, GLfloat nz), (nx, ny, nz), 3, "GLfloat", nx, "GLfloat", ny, "GLfloat", nz) +TRACE_GL_VOID(glNormal3x, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz) +TRACE_GL_VOID(glNormal3xOES, (GLfixed nx, GLfixed ny, GLfixed nz), (nx, ny, nz), 3, "GLfixed", nx, "GLfixed", ny, "GLfixed", nz) +TRACE_GL_VOID(glNormalPointer, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glOrthof, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glOrthofOES, (GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfloat", left, "GLfloat", right, "GLfloat", bottom, "GLfloat", top, "GLfloat", zNear, "GLfloat", zFar) +TRACE_GL_VOID(glOrthox, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glOrthoxOES, (GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar), (left, right, bottom, top, zNear, zFar), 6, "GLfixed", left, "GLfixed", right, "GLfixed", bottom, "GLfixed", top, "GLfixed", zNear, "GLfixed", zFar) +TRACE_GL_VOID(glPixelStorei, (GLenum pname, GLint param), (pname, param), 2, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glPointParameterf, (GLenum pname, GLfloat param), (pname, param), 2, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glPointParameterfv, (GLenum pname, const GLfloat *params), (pname, params), 2, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glPointParameterx, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glPointParameterxOES, (GLenum pname, GLfixed param), (pname, param), 2, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glPointParameterxv, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glPointParameterxvOES, (GLenum pname, const GLfixed *params), (pname, params), 2, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glPointSize, (GLfloat size), (size), 1, "GLfloat", size) +TRACE_GL_VOID(glPointSizePointerOES, (GLenum type, GLsizei stride, const GLvoid *pointer), (type, stride, pointer), 3, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glPointSizex, (GLfixed size), (size), 1, "GLfixed", size) +TRACE_GL_VOID(glPointSizexOES, (GLfixed size), (size), 1, "GLfixed", size) +TRACE_GL_VOID(glPolygonOffset, (GLfloat factor, GLfloat units), (factor, units), 2, "GLfloat", factor, "GLfloat", units) +TRACE_GL_VOID(glPolygonOffsetx, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units) +TRACE_GL_VOID(glPolygonOffsetxOES, (GLfixed factor, GLfixed units), (factor, units), 2, "GLfixed", factor, "GLfixed", units) +TRACE_GL_VOID(glPopMatrix, (void), (), 0) +TRACE_GL_VOID(glProgramBinaryOES, (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLint length), (program, binaryFormat, binary, length), 4, "GLuint", program, "GLenum", binaryFormat, "const GLvoid *", binary, "GLint", length) +TRACE_GL_VOID(glPushMatrix, (void), (), 0) +TRACE_GL(GLbitfield, glQueryMatrixxOES, (GLfixed mantissa[16], GLint exponent[16]), (mantissa, exponent), 2, "GLfixed", mantissa, "GLint", exponent) +TRACE_GL_VOID(glReadPixels, (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels), (x, y, width, height, format, type, pixels), 7, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "GLvoid *", pixels) +TRACE_GL_VOID(glReleaseShaderCompiler, (void), (), 0) +TRACE_GL_VOID(glRenderbufferStorage, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glRenderbufferStorageMultisampleIMG, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height), (target, samples, internalformat, width, height), 5, "GLenum", target, "GLsizei", samples, "GLenum", internalformat, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glRenderbufferStorageOES, (GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), 4, "GLenum", target, "GLenum", internalformat, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glRotatef, (GLfloat angle, GLfloat x, GLfloat y, GLfloat z), (angle, x, y, z), 4, "GLfloat", angle, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glRotatex, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glRotatexOES, (GLfixed angle, GLfixed x, GLfixed y, GLfixed z), (angle, x, y, z), 4, "GLfixed", angle, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glSampleCoverage, (GLclampf value, GLboolean invert), (value, invert), 2, "GLclampf", value, "GLboolean", invert) +TRACE_GL_VOID(glSampleCoveragex, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert) +TRACE_GL_VOID(glSampleCoveragexOES, (GLclampx value, GLboolean invert), (value, invert), 2, "GLclampx", value, "GLboolean", invert) +TRACE_GL_VOID(glScalef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glScalex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glScalexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glScissor, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height), 4, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glSelectPerfMonitorCountersAMD, (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *countersList), (monitor, enable, group, numCounters, countersList), 5, "GLuint", monitor, "GLboolean", enable, "GLuint", group, "GLint", numCounters, "GLuint *", countersList) +TRACE_GL_VOID(glSetFenceNV, (GLuint fence, GLenum condition), (fence, condition), 2, "GLuint", fence, "GLenum", condition) +TRACE_GL_VOID(glShadeModel, (GLenum mode), (mode), 1, "GLenum", mode) +TRACE_GL_VOID(glShaderBinary, (GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length), (n, shaders, binaryformat, binary, length), 5, "GLsizei", n, "const GLuint*", shaders, "GLenum", binaryformat, "const GLvoid*", binary, "GLsizei", length) +TRACE_GL_VOID(glShaderSource, (GLuint shader, GLsizei count, const GLchar** string, const GLint* length), (shader, count, string, length), 4, "GLuint", shader, "GLsizei", count, "const GLchar**", string, "const GLint*", length) +TRACE_GL_VOID(glStartTilingQCOM, (GLuint x, GLuint y, GLuint width, GLuint height, GLbitfield preserveMask), (x, y, width, height, preserveMask), 5, "GLuint", x, "GLuint", y, "GLuint", width, "GLuint", height, "GLbitfield", preserveMask) +TRACE_GL_VOID(glStencilFunc, (GLenum func, GLint ref, GLuint mask), (func, ref, mask), 3, "GLenum", func, "GLint", ref, "GLuint", mask) +TRACE_GL_VOID(glStencilFuncSeparate, (GLenum face, GLenum func, GLint ref, GLuint mask), (face, func, ref, mask), 4, "GLenum", face, "GLenum", func, "GLint", ref, "GLuint", mask) +TRACE_GL_VOID(glStencilMask, (GLuint mask), (mask), 1, "GLuint", mask) +TRACE_GL_VOID(glStencilMaskSeparate, (GLenum face, GLuint mask), (face, mask), 2, "GLenum", face, "GLuint", mask) +TRACE_GL_VOID(glStencilOp, (GLenum fail, GLenum zfail, GLenum zpass), (fail, zfail, zpass), 3, "GLenum", fail, "GLenum", zfail, "GLenum", zpass) +TRACE_GL_VOID(glStencilOpSeparate, (GLenum face, GLenum fail, GLenum zfail, GLenum zpass), (face, fail, zfail, zpass), 4, "GLenum", face, "GLenum", fail, "GLenum", zfail, "GLenum", zpass) +TRACE_GL(GLboolean, glTestFenceNV, (GLuint fence), (fence), 1, "GLuint", fence) +TRACE_GL_VOID(glTexCoordPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glTexEnvf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glTexEnvfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glTexEnvi, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glTexEnviv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params) +TRACE_GL_VOID(glTexEnvx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexEnvxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexEnvxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexEnvxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexGenfOES, (GLenum coord, GLenum pname, GLfloat param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glTexGenfvOES, (GLenum coord, GLenum pname, const GLfloat *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glTexGeniOES, (GLenum coord, GLenum pname, GLint param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glTexGenivOES, (GLenum coord, GLenum pname, const GLint *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLint *", params) +TRACE_GL_VOID(glTexGenxOES, (GLenum coord, GLenum pname, GLfixed param), (coord, pname, param), 3, "GLenum", coord, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexGenxvOES, (GLenum coord, GLenum pname, const GLfixed *params), (coord, pname, params), 3, "GLenum", coord, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexImage2D, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels), (target, level, internalformat, width, height, border, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", internalformat, "GLsizei", width, "GLsizei", height, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid *", pixels) +TRACE_GL_VOID(glTexImage3DOES, (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid* pixels), (target, level, internalformat, width, height, depth, border, format, type, pixels), 10, "GLenum", target, "GLint", level, "GLenum", internalformat, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLint", border, "GLenum", format, "GLenum", type, "const GLvoid*", pixels) +TRACE_GL_VOID(glTexParameterf, (GLenum target, GLenum pname, GLfloat param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfloat", param) +TRACE_GL_VOID(glTexParameterfv, (GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfloat *", params) +TRACE_GL_VOID(glTexParameteri, (GLenum target, GLenum pname, GLint param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLint", param) +TRACE_GL_VOID(glTexParameteriv, (GLenum target, GLenum pname, const GLint *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLint *", params) +TRACE_GL_VOID(glTexParameterx, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexParameterxOES, (GLenum target, GLenum pname, GLfixed param), (target, pname, param), 3, "GLenum", target, "GLenum", pname, "GLfixed", param) +TRACE_GL_VOID(glTexParameterxv, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexParameterxvOES, (GLenum target, GLenum pname, const GLfixed *params), (target, pname, params), 3, "GLenum", target, "GLenum", pname, "const GLfixed *", params) +TRACE_GL_VOID(glTexSubImage2D, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels), (target, level, xoffset, yoffset, width, height, format, type, pixels), 9, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLsizei", width, "GLsizei", height, "GLenum", format, "GLenum", type, "const GLvoid *", pixels) +TRACE_GL_VOID(glTexSubImage3DOES, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid* pixels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), 11, "GLenum", target, "GLint", level, "GLint", xoffset, "GLint", yoffset, "GLint", zoffset, "GLsizei", width, "GLsizei", height, "GLsizei", depth, "GLenum", format, "GLenum", type, "const GLvoid*", pixels) +TRACE_GL_VOID(glTranslatef, (GLfloat x, GLfloat y, GLfloat z), (x, y, z), 3, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glTranslatex, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glTranslatexOES, (GLfixed x, GLfixed y, GLfixed z), (x, y, z), 3, "GLfixed", x, "GLfixed", y, "GLfixed", z) +TRACE_GL_VOID(glUniform1f, (GLint location, GLfloat x), (location, x), 2, "GLint", location, "GLfloat", x) +TRACE_GL_VOID(glUniform1fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform1i, (GLint location, GLint x), (location, x), 2, "GLint", location, "GLint", x) +TRACE_GL_VOID(glUniform1iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniform2f, (GLint location, GLfloat x, GLfloat y), (location, x, y), 3, "GLint", location, "GLfloat", x, "GLfloat", y) +TRACE_GL_VOID(glUniform2fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform2i, (GLint location, GLint x, GLint y), (location, x, y), 3, "GLint", location, "GLint", x, "GLint", y) +TRACE_GL_VOID(glUniform2iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniform3f, (GLint location, GLfloat x, GLfloat y, GLfloat z), (location, x, y, z), 4, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glUniform3fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform3i, (GLint location, GLint x, GLint y, GLint z), (location, x, y, z), 4, "GLint", location, "GLint", x, "GLint", y, "GLint", z) +TRACE_GL_VOID(glUniform3iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniform4f, (GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (location, x, y, z, w), 5, "GLint", location, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w) +TRACE_GL_VOID(glUniform4fv, (GLint location, GLsizei count, const GLfloat* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLfloat*", v) +TRACE_GL_VOID(glUniform4i, (GLint location, GLint x, GLint y, GLint z, GLint w), (location, x, y, z, w), 5, "GLint", location, "GLint", x, "GLint", y, "GLint", z, "GLint", w) +TRACE_GL_VOID(glUniform4iv, (GLint location, GLsizei count, const GLint* v), (location, count, v), 3, "GLint", location, "GLsizei", count, "const GLint*", v) +TRACE_GL_VOID(glUniformMatrix2fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value) +TRACE_GL_VOID(glUniformMatrix3fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value) +TRACE_GL_VOID(glUniformMatrix4fv, (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value), (location, count, transpose, value), 4, "GLint", location, "GLsizei", count, "GLboolean", transpose, "const GLfloat*", value) +TRACE_GL(GLboolean, glUnmapBufferOES, (GLenum target), (target), 1, "GLenum", target) +TRACE_GL_VOID(glUseProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glValidateProgram, (GLuint program), (program), 1, "GLuint", program) +TRACE_GL_VOID(glVertexAttrib1f, (GLuint indx, GLfloat x), (indx, x), 2, "GLuint", indx, "GLfloat", x) +TRACE_GL_VOID(glVertexAttrib1fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttrib2f, (GLuint indx, GLfloat x, GLfloat y), (indx, x, y), 3, "GLuint", indx, "GLfloat", x, "GLfloat", y) +TRACE_GL_VOID(glVertexAttrib2fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttrib3f, (GLuint indx, GLfloat x, GLfloat y, GLfloat z), (indx, x, y, z), 4, "GLuint", indx, "GLfloat", x, "GLfloat", y, "GLfloat", z) +TRACE_GL_VOID(glVertexAttrib3fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttrib4f, (GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w), (indx, x, y, z, w), 5, "GLuint", indx, "GLfloat", x, "GLfloat", y, "GLfloat", z, "GLfloat", w) +TRACE_GL_VOID(glVertexAttrib4fv, (GLuint indx, const GLfloat* values), (indx, values), 2, "GLuint", indx, "const GLfloat*", values) +TRACE_GL_VOID(glVertexAttribPointer, (GLuint indx, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr), (indx, size, type, normalized, stride, ptr), 6, "GLuint", indx, "GLint", size, "GLenum", type, "GLboolean", normalized, "GLsizei", stride, "const GLvoid*", ptr) +TRACE_GL_VOID(glVertexPointer, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) +TRACE_GL_VOID(glViewport, (GLint x, GLint y, GLsizei width, GLsizei height), (x, y, width, height), 4, "GLint", x, "GLint", y, "GLsizei", width, "GLsizei", height) +TRACE_GL_VOID(glWeightPointerOES, (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer), (size, type, stride, pointer), 4, "GLint", size, "GLenum", type, "GLsizei", stride, "const GLvoid *", pointer) diff --git a/opengl/tests/gl2_yuvtex/Android.mk b/opengl/tests/gl2_yuvtex/Android.mk new file mode 100644 index 000000000000..6304700f17f9 --- /dev/null +++ b/opengl/tests/gl2_yuvtex/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + gl2_yuvtex.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui + +LOCAL_MODULE:= test-opengl-gl2_yuvtex + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp new file mode 100644 index 000000000000..602ea1aa277d --- /dev/null +++ b/opengl/tests/gl2_yuvtex/gl2_yuvtex.cpp @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2010 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 <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <utils/Timers.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +using namespace android; + +static void printGLString(const char *name, GLenum s) { + // fprintf(stderr, "printGLString %s, %d\n", name, s); + const char *v = (const char *) glGetString(s); + // int error = glGetError(); + // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error, + // (unsigned int) v); + // if ((v < (const char*) 0) || (v > (const char*) 0x10000)) + // fprintf(stderr, "GL %s = %s\n", name, v); + // else + // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v); + fprintf(stderr, "GL %s = %s\n", name, v); +} + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + fprintf(stderr, "after %s() glError (0x%x)\n", op, error); + } +} + +static const char gVertexShader[] = "attribute vec4 vPosition;\n" + "varying vec2 yuvTexCoords;\n" + "void main() {\n" + " yuvTexCoords = vPosition.xy + vec2(0.5, 0.5);\n" + " gl_Position = vPosition;\n" + "}\n"; + +static const char gFragmentShader[] = "#extension GL_OES_EGL_image_external : require\n" + "precision mediump float;\n" + "uniform samplerExternalOES yuvTexSampler;\n" + "varying vec2 yuvTexCoords;\n" + "void main() {\n" + " gl_FragColor = texture2D(yuvTexSampler, yuvTexCoords);\n" + "}\n"; + +GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = glCreateShader(shaderType); + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + fprintf(stderr, "Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + } else { + fprintf(stderr, "Guessing at GL_INFO_LOG_LENGTH size\n"); + char* buf = (char*) malloc(0x1000); + if (buf) { + glGetShaderInfoLog(shader, 0x1000, NULL, buf); + fprintf(stderr, "Could not compile shader %d:\n%s\n", + shaderType, buf); + free(buf); + } + } + glDeleteShader(shader); + shader = 0; + } + } + return shader; +} + +GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + return 0; + } + + GLuint program = glCreateProgram(); + if (program) { + glAttachShader(program, vertexShader); + checkGlError("glAttachShader"); + glAttachShader(program, pixelShader); + checkGlError("glAttachShader"); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + fprintf(stderr, "Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + return program; +} + +GLuint gProgram; +GLint gvPositionHandle; +GLint gYuvTexSamplerHandle; + +bool setupGraphics(int w, int h) { + gProgram = createProgram(gVertexShader, gFragmentShader); + if (!gProgram) { + return false; + } + gvPositionHandle = glGetAttribLocation(gProgram, "vPosition"); + checkGlError("glGetAttribLocation"); + fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n", + gvPositionHandle); + gYuvTexSamplerHandle = glGetUniformLocation(gProgram, "yuvTexSampler"); + checkGlError("glGetUniformLocation"); + fprintf(stderr, "glGetUniformLocation(\"yuvTexSampler\") = %d\n", + gYuvTexSamplerHandle); + + glViewport(0, 0, w, h); + checkGlError("glViewport"); + return true; +} + +int align(int x, int a) { + return (x + (a-1)) & (~(a-1)); +} + +const int yuvTexWidth = 608; +const int yuvTexHeight = 480; +const int yuvTexUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12; +const int yuvTexOffsetY = 0; +const int yuvTexStrideY = (yuvTexWidth + 0xf) & ~0xf; +const int yuvTexOffsetV = yuvTexStrideY * yuvTexHeight; +const int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; +const int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * yuvTexHeight/2; +const int yuvTexStrideU = yuvTexStrideV; +const bool yuvTexSameUV = false; +static sp<GraphicBuffer> yuvTexBuffer; +static GLuint yuvTex; + +bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) { + int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1; + int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1; + yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat, + yuvTexUsage); + char* buf = NULL; + status_t err = yuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->lock(...) failed: %d\n", err); + return false; + } + for (int x = 0; x < yuvTexWidth; x++) { + for (int y = 0; y < yuvTexHeight; y++) { + int parityX = (x / blockWidth) & 1; + int parityY = (y / blockHeight) & 1; + unsigned char intensity = (parityX ^ parityY) ? 63 : 191; + buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; + if (x < yuvTexWidth / 2 && y < yuvTexHeight / 2) { + buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; + if (yuvTexSameUV) { + buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = intensity; + } else if (x < yuvTexWidth / 4 && y < yuvTexHeight / 4) { + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = intensity; + } + } + } + } + + err = yuvTexBuffer->unlock(); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->unlock() failed: %d\n", err); + return false; + } + + EGLClientBuffer clientBuffer = (EGLClientBuffer)yuvTexBuffer->getNativeBuffer(); + EGLImageKHR img = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + clientBuffer, 0); + checkEglError("eglCreateImageKHR"); + if (img == EGL_NO_IMAGE_KHR) { + return false; + } + + glGenTextures(1, &yuvTex); + checkGlError("glGenTextures"); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img); + checkGlError("glEGLImageTargetTexture2DOES"); + + return true; +} + +const GLfloat gTriangleVertices[] = { + -0.5f, 0.5f, + -0.5f, -0.5f, + 0.5f, -0.5f, + 0.5f, 0.5f, +}; + +void renderFrame() { + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + checkGlError("glClearColor"); + glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + checkGlError("glClear"); + + glUseProgram(gProgram); + checkGlError("glUseProgram"); + + glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); + checkGlError("glVertexAttribPointer"); + glEnableVertexAttribArray(gvPositionHandle); + checkGlError("glEnableVertexAttribArray"); + + glUniform1i(gYuvTexSamplerHandle, 0); + checkGlError("glUniform1i"); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + checkGlError("glDrawArrays"); +} + +void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) { + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + printf(" %s: ", names[j].name); + printf("%d (0x%x)", value, value); + } + } + printf("\n"); +} + +int main(int argc, char** argv) { + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + + EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE }; + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLSurface surface; + EGLint w, h; + + EGLDisplay dpy; + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); + return 0; + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); + if (returnValue != EGL_TRUE) { + printf("eglInitialize failed\n"); + return 0; + } + + EGLNativeWindowType window = android_createDisplaySurface(); + returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); + if (returnValue) { + printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); + return 1; + } + + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + printf("Chose this configuration:\n"); + printEGLConfiguration(dpy, myConfig); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + printf("gelCreateWindowSurface failed.\n"); + return 1; + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + return 1; + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + return 1; + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + checkEglError("eglQuerySurface"); + GLint dim = w < h ? w : h; + + fprintf(stderr, "Window dimensions: %d x %d\n", w, h); + + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + + if(!setupYuvTexSurface(dpy, context)) { + fprintf(stderr, "Could not set up texture surface.\n"); + return 1; + } + + if(!setupGraphics(w, h)) { + fprintf(stderr, "Could not set up graphics.\n"); + return 1; + } + + for (;;) { + renderFrame(); + eglSwapBuffers(dpy, surface); + checkEglError("eglSwapBuffers"); + } + + return 0; +} diff --git a/opengl/tests/gl_perf/Android.mk b/opengl/tests/gl_perf/Android.mk new file mode 100644 index 000000000000..37647ca682c9 --- /dev/null +++ b/opengl/tests/gl_perf/Android.mk @@ -0,0 +1,20 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + gl2_perf.cpp \ + filltest.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui + +LOCAL_MODULE:= test-opengl-gl2_perf + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/gl_perf/fill_common.cpp b/opengl/tests/gl_perf/fill_common.cpp new file mode 100644 index 000000000000..a069f67ac8fd --- /dev/null +++ b/opengl/tests/gl_perf/fill_common.cpp @@ -0,0 +1,298 @@ +/* + * Copyright (C) 2007 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 "fragment_shaders.cpp" + +FILE * fOut = NULL; +void ptSwap(); + +static char gCurrentTestName[1024]; +static uint32_t gWidth = 0; +static uint32_t gHeight = 0; + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + LOGE("after %s() glError (0x%x)\n", op, error); + } +} + +GLuint loadShader(GLenum shaderType, const char* pSource) { + GLuint shader = glCreateShader(shaderType); + if (shader) { + glShaderSource(shader, 1, &pSource, NULL); + glCompileShader(shader); + GLint compiled = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); + if (!compiled) { + GLint infoLen = 0; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); + if (infoLen) { + char* buf = (char*) malloc(infoLen); + if (buf) { + glGetShaderInfoLog(shader, infoLen, NULL, buf); + LOGE("Could not compile shader %d:\n%s\n", shaderType, buf); + free(buf); + } + glDeleteShader(shader); + shader = 0; + } + } + } + return shader; +} + +enum { + A_POS, + A_COLOR, + A_TEX0, + A_TEX1 +}; + +GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) { + GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource); + if (!vertexShader) { + return 0; + } + + GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource); + if (!pixelShader) { + return 0; + } + + GLuint program = glCreateProgram(); + if (program) { + glAttachShader(program, vertexShader); + checkGlError("glAttachShader v"); + glAttachShader(program, pixelShader); + checkGlError("glAttachShader p"); + + glBindAttribLocation(program, A_POS, "a_pos"); + glBindAttribLocation(program, A_COLOR, "a_color"); + glBindAttribLocation(program, A_TEX0, "a_tex0"); + glBindAttribLocation(program, A_TEX1, "a_tex1"); + glLinkProgram(program); + GLint linkStatus = GL_FALSE; + glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); + if (linkStatus != GL_TRUE) { + GLint bufLength = 0; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); + if (bufLength) { + char* buf = (char*) malloc(bufLength); + if (buf) { + glGetProgramInfoLog(program, bufLength, NULL, buf); + LOGE("Could not link program:\n%s\n", buf); + free(buf); + } + } + glDeleteProgram(program); + program = 0; + } + } + checkGlError("createProgram"); + glUseProgram(program); + return program; +} + +uint64_t getTime() { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t); + return t.tv_nsec + ((uint64_t)t.tv_sec * 1000 * 1000 * 1000); +} + +uint64_t gTime; +void startTimer() { + gTime = getTime(); +} + + +static void endTimer(int count) { + uint64_t t2 = getTime(); + double delta = ((double)(t2 - gTime)) / 1000000000; + double pixels = (gWidth * gHeight) * count; + double mpps = pixels / delta / 1000000; + double dc60 = ((double)count) / delta / 60; + + if (fOut) { + fprintf(fOut, "%s, %f, %f\r\n", gCurrentTestName, mpps, dc60); + fflush(fOut); + } else { + printf("%s, %f, %f\n", gCurrentTestName, mpps, dc60); + } + LOGI("%s, %f, %f\r\n", gCurrentTestName, mpps, dc60); +} + + +static const char gVertexShader[] = + "attribute vec4 a_pos;\n" + "attribute vec4 a_color;\n" + "attribute vec2 a_tex0;\n" + "attribute vec2 a_tex1;\n" + "varying vec4 v_color;\n" + "varying vec2 v_tex0;\n" + "varying vec2 v_tex1;\n" + "uniform vec2 u_texOff;\n" + + "void main() {\n" + " v_color = a_color;\n" + " v_tex0 = a_tex0;\n" + " v_tex1 = a_tex1;\n" + " v_tex0.x += u_texOff.x;\n" + " v_tex1.y += u_texOff.y;\n" + " gl_Position = a_pos;\n" + "}\n"; + +static void setupVA() { + static const float vtx[] = { + -1.0f,-1.0f, + 1.0f,-1.0f, + -1.0f, 1.0f, + 1.0f, 1.0f }; + static const float color[] = { + 1.0f,0.0f,1.0f,1.0f, + 0.0f,0.0f,1.0f,1.0f, + 1.0f,1.0f,0.0f,1.0f, + 1.0f,1.0f,1.0f,1.0f }; + static const float tex0[] = { + 0.0f,0.0f, + 1.0f,0.0f, + 0.0f,1.0f, + 1.0f,1.0f }; + static const float tex1[] = { + 1.0f,0.0f, + 1.0f,1.0f, + 0.0f,1.0f, + 0.0f,0.0f }; + + glEnableVertexAttribArray(A_POS); + glEnableVertexAttribArray(A_COLOR); + glEnableVertexAttribArray(A_TEX0); + glEnableVertexAttribArray(A_TEX1); + + glVertexAttribPointer(A_POS, 2, GL_FLOAT, false, 8, vtx); + glVertexAttribPointer(A_COLOR, 4, GL_FLOAT, false, 16, color); + glVertexAttribPointer(A_TEX0, 2, GL_FLOAT, false, 8, tex0); + glVertexAttribPointer(A_TEX1, 2, GL_FLOAT, false, 8, tex1); +} + +static void randUniform(int pgm, const char *var) { + int loc = glGetUniformLocation(pgm, var); + if (loc >= 0) { + float x = ((float)rand()) / RAND_MAX; + float y = ((float)rand()) / RAND_MAX; + float z = ((float)rand()) / RAND_MAX; + float w = ((float)rand()) / RAND_MAX; + glUniform4f(loc, x, y, z, w); + } +} + +static void doLoop(bool warmup, int pgm, uint32_t passCount) { + if (warmup) { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + ptSwap(); + glFinish(); + return; + } + + startTimer(); + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + for (uint32_t ct=0; ct < passCount; ct++) { + int loc = glGetUniformLocation(pgm, "u_texOff"); + glUniform2f(loc, ((float)ct) / passCount, ((float)ct) / 2.f / passCount); + + randUniform(pgm, "u_color"); + randUniform(pgm, "u_0"); + randUniform(pgm, "u_1"); + randUniform(pgm, "u_2"); + randUniform(pgm, "u_3"); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + ptSwap(); + glFinish(); + endTimer(passCount); +} + + +static uint32_t rgb(uint32_t r, uint32_t g, uint32_t b) +{ + uint32_t ret = 0xff000000; + ret |= r & 0xff; + ret |= (g & 0xff) << 8; + ret |= (b & 0xff) << 16; + return ret; +} + +void genTextures() { + uint32_t *m = (uint32_t *)malloc(1024*1024*4); + for (int y=0; y < 1024; y++){ + for (int x=0; x < 1024; x++){ + m[y*1024 + x] = rgb(x, (((x+y) & 0xff) == 0x7f) * 0xff, y); + } + } + glBindTexture(GL_TEXTURE_2D, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1024, 1024, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + for (int y=0; y < 16; y++){ + for (int x=0; x < 16; x++){ + m[y*16 + x] = rgb(x << 4, (((x+y) & 0xf) == 0x7) * 0xff, y << 4); + } + } + glBindTexture(GL_TEXTURE_2D, 2); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, GL_UNSIGNED_BYTE, m); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + free(m); +} + +static void doSingleTest(uint32_t pgmNum, int tex) { + const char *pgmTxt = gFragmentTests[pgmNum]->txt; + int pgm = createProgram(gVertexShader, pgmTxt); + if (!pgm) { + printf("error running test\n"); + return; + } + int loc = glGetUniformLocation(pgm, "u_tex0"); + if (loc >= 0) glUniform1i(loc, 0); + loc = glGetUniformLocation(pgm, "u_tex1"); + if (loc >= 0) glUniform1i(loc, 1); + + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, tex); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, tex); + glActiveTexture(GL_TEXTURE0); + + glBlendFunc(GL_ONE, GL_ONE); + glDisable(GL_BLEND); + //sprintf(str2, "%i, %i, %i, %i, %i, 0", + //useVarColor, texCount, modulateFirstTex, extraMath, tex0); + //doLoop(true, pgm, w, h, str2); + //doLoop(false, pgm, w, h, str2); + + glEnable(GL_BLEND); + sprintf(gCurrentTestName, "%s, %i, %i, 1", gFragmentTests[pgmNum]->name, pgmNum, tex); + doLoop(true, pgm, 100); + doLoop(false, pgm, 100); +} + diff --git a/opengl/tests/gl_perf/filltest.cpp b/opengl/tests/gl_perf/filltest.cpp new file mode 100644 index 000000000000..3f8faca87d0e --- /dev/null +++ b/opengl/tests/gl_perf/filltest.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2007 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 <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> +#include <string.h> + +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <utils/Timers.h> +#include <EGL/egl.h> +#include <utils/Log.h> + + +using namespace android; + + +#include "fill_common.cpp" + + +bool doTest(uint32_t w, uint32_t h) { + gWidth = w; + gHeight = h; + setupVA(); + genTextures(); + + printf("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n"); + + for (uint32_t num = 0; num < gFragmentTestCount; num++) { + doSingleTest(num, 2); + if (gFragmentTests[num]->texCount) { + doSingleTest(num, 1); + } + } + + exit(0); + return true; +} diff --git a/opengl/tests/gl_perf/fragment_shaders.cpp b/opengl/tests/gl_perf/fragment_shaders.cpp new file mode 100644 index 000000000000..79d5ead3fdab --- /dev/null +++ b/opengl/tests/gl_perf/fragment_shaders.cpp @@ -0,0 +1,139 @@ + +typedef struct FragmentTestRec { + const char * name; + uint32_t texCount; + const char * txt; +} FragmentTest; + +static FragmentTest fpFill = { + "Solid color", 0, + + "precision mediump float;\n" + "uniform vec4 u_color;\n" + "void main() {\n" + " gl_FragColor = u_color;\n" + "}\n" +}; + +static FragmentTest fpGradient = { + "Solid gradient", 0, + + "precision mediump float;\n" + "varying lowp vec4 v_color;\n" + "void main() {\n" + " gl_FragColor = v_color;\n" + "}\n" +}; + +static FragmentTest fpCopyTex = { + "Texture copy", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " gl_FragColor = texture2D(u_tex0, v_tex0);\n" + "}\n" +}; + +static FragmentTest fpCopyTexGamma = { + "Texture copy with gamma", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " vec4 t = texture2D(u_tex0, v_tex0);\n" + " t.rgb = pow(t.rgb, vec3(1.4, 1.4, 1.4));\n" + " gl_FragColor = t;\n" + "}\n" +}; + +static FragmentTest fpTexSpec = { + "Texture spec", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " vec4 t = texture2D(u_tex0, v_tex0);\n" + " float simSpec = dot(gl_FragCoord.xyz, gl_FragCoord.xyz);\n" + " simSpec = pow(clamp(simSpec, 0.1, 1.0), 40.0);\n" + " gl_FragColor = t + vec4(simSpec, simSpec, simSpec, simSpec);\n" + "}\n" +}; + +static FragmentTest fpDepTex = { + "Dependent Lookup", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "void main() {\n" + " vec4 t = texture2D(u_tex0, v_tex0);\n" + " t += texture2D(u_tex0, t.xy);\n" + " gl_FragColor = t;\n" + "}\n" +}; + +static FragmentTest fpModulateConstantTex = { + "Texture modulate constant", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "uniform sampler2D u_tex0;\n" + "uniform vec4 u_color;\n" + + "void main() {\n" + " lowp vec4 c = texture2D(u_tex0, v_tex0);\n" + " c *= u_color;\n" + " gl_FragColor = c;\n" + "}\n" +}; + +static FragmentTest fpModulateVaryingTex = { + "Texture modulate gradient", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "varying lowp vec4 v_color;\n" + "uniform sampler2D u_tex0;\n" + + "void main() {\n" + " lowp vec4 c = texture2D(u_tex0, v_tex0);\n" + " c *= v_color;\n" + " gl_FragColor = c;\n" + "}\n" +}; + +static FragmentTest fpModulateVaryingConstantTex = { + "Texture modulate gradient constant", 1, + + "precision mediump float;\n" + "varying vec2 v_tex0;\n" + "varying lowp vec4 v_color;\n" + "uniform sampler2D u_tex0;\n" + "uniform vec4 u_color;\n" + + "void main() {\n" + " lowp vec4 c = texture2D(u_tex0, v_tex0);\n" + " c *= v_color;\n" + " c *= u_color;\n" + " gl_FragColor = c;\n" + "}\n" +}; + +static FragmentTest *gFragmentTests[] = { + &fpFill, + &fpGradient, + &fpCopyTex, + &fpCopyTexGamma, + &fpTexSpec, + &fpDepTex, + &fpModulateConstantTex, + &fpModulateVaryingTex, + &fpModulateVaryingConstantTex, + +}; + +static const size_t gFragmentTestCount = sizeof(gFragmentTests) / sizeof(gFragmentTests[0]); diff --git a/opengl/tests/gl_perf/gl2_perf.cpp b/opengl/tests/gl_perf/gl2_perf.cpp new file mode 100644 index 000000000000..9dfcf1cc0efe --- /dev/null +++ b/opengl/tests/gl_perf/gl2_perf.cpp @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2007 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 <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> + +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <utils/Timers.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/EGLUtils.h> + +using namespace android; + + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + fprintf(stderr, "after %s() glError (0x%x)\n", op, error); + } +} + +bool doTest(uint32_t w, uint32_t h); + +static EGLDisplay dpy; +static EGLSurface surface; + +int main(int argc, char** argv) { + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + + EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE }; + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLint w, h; + + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); + return 0; + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + if (returnValue != EGL_TRUE) { + printf("eglInitialize failed\n"); + return 0; + } + + EGLNativeWindowType window = android_createDisplaySurface();
+ returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); + if (returnValue) { + printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); + return 0; + } + + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + printf("gelCreateWindowSurface failed.\n"); + return 0; + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + return 0; + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + return 0; + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + checkEglError("eglQuerySurface"); + GLint dim = w < h ? w : h; + + glViewport(0, 0, w, h); + + for (;;) { + doTest(w, h); + eglSwapBuffers(dpy, surface); + checkEglError("eglSwapBuffers"); + } + + return 0; +} + +void ptSwap() { + eglSwapBuffers(dpy, surface); +} + diff --git a/opengl/tests/gl_perfapp/Android.mk b/opengl/tests/gl_perfapp/Android.mk new file mode 100644 index 000000000000..dd75a740cfa7 --- /dev/null +++ b/opengl/tests/gl_perfapp/Android.mk @@ -0,0 +1,54 @@ +######################################################################### +# OpenGL ES Perf App +# This makefile builds both an activity and a shared library. +######################################################################### +ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := GLPerf + +LOCAL_JNI_SHARED_LIBRARIES := libglperf + +# Run on Eclair +LOCAL_SDK_VERSION := 7 + +include $(BUILD_PACKAGE) + +######################################################################### +# Build JNI Shared Library +######################################################################### + +LOCAL_PATH:= $(LOCAL_PATH)/jni + +include $(CLEAR_VARS) + +# Optional tag would mean it doesn't get installed by default +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -Werror + +LOCAL_SRC_FILES:= \ + gl_code.cpp + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libEGL \ + libGLESv2 + +LOCAL_MODULE := libglperf + +LOCAL_PRELINK_MODULE := false + +include $(BUILD_SHARED_LIBRARY) + +endif # TARGET_SIMULATOR diff --git a/opengl/tests/gl_perfapp/AndroidManifest.xml b/opengl/tests/gl_perfapp/AndroidManifest.xml new file mode 100644 index 000000000000..305d95f21067 --- /dev/null +++ b/opengl/tests/gl_perfapp/AndroidManifest.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, 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. +*/ +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.glperf" + android:versionName="1.0.0" android:versionCode="10000" > + <uses-sdk android:targetSdkVersion="7" android:minSdkVersion="7" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <application + android:label="@string/glperf_activity"> + <activity android:name="GLPerfActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:launchMode="singleTask" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/gl_perfapp/jni/gl_code.cpp b/opengl/tests/gl_perfapp/jni/gl_code.cpp new file mode 100644 index 000000000000..f99337152c02 --- /dev/null +++ b/opengl/tests/gl_perfapp/jni/gl_code.cpp @@ -0,0 +1,103 @@ +// OpenGL ES 2.0 code + +#include <nativehelper/jni.h> +#define LOG_TAG "GLPerf gl_code.cpp" +#include <utils/Log.h> + +#include <EGL/egl.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> +#include <utils/Timers.h> + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> + +#include "../../gl_perf/fill_common.cpp" + + +////////////////////////// + +// Width and height of the screen + +uint32_t w; +uint32_t h; + +// The stateClock starts at zero and increments by 1 every time we draw a frame. It is used to control which phase of the test we are in. + +int stateClock; +const int doLoopStates = 2; +const int doSingleTestStates = 2; +bool done; + +// Saves the parameters of the test (so we can print them out when we finish the timing.) + + +int pgm; + +void ptSwap() { +} + +void doTest() { + uint32_t testNum = stateClock >> 2; + int texSize = ((stateClock >> 1) & 0x1) + 1; + + if (testNum >= gFragmentTestCount) { + LOGI("done\n"); + if (fOut) { + fclose(fOut); + fOut = NULL; + } + done = true; + return; + } + + // LOGI("doTest %d %d %d\n", texCount, extraMath, testSubState); + +// for (uint32_t num = 0; num < gFragmentTestCount; num++) { + doSingleTest(testNum, texSize); +} + +extern "C" { + JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj, jint width, jint height); + JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobject obj); +}; + +JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_init(JNIEnv * env, jobject obj, jint width, jint height) +{ + gWidth = width; + gHeight = height; + if (!done) { + stateClock = 0; + done = false; + setupVA(); + genTextures(); + const char* fileName = "/sdcard/glperf.csv"; + if (fOut != NULL) { + LOGI("Closing partially written output.n"); + fclose(fOut); + fOut = NULL; + } + LOGI("Writing to: %s\n",fileName); + fOut = fopen(fileName, "w"); + if (fOut == NULL) { + LOGE("Could not open: %s\n", fileName); + } + + LOGI("\nvarColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\n"); + if (fOut) fprintf(fOut,"varColor, texCount, modulate, extraMath, texSize, blend, Mpps, DC60\r\n"); + } +} + +JNIEXPORT void JNICALL Java_com_android_glperf_GLPerfLib_step(JNIEnv * env, jobject obj) +{ + if (! done) { + if (stateClock > 0 && ((stateClock & 1) == 0)) { + //endTimer(100); + } + doTest(); + stateClock++; + } else { + glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + } +} diff --git a/opengl/tests/gl_perfapp/res/values/strings.xml b/opengl/tests/gl_perfapp/res/values/strings.xml new file mode 100644 index 000000000000..dc21075b2393 --- /dev/null +++ b/opengl/tests/gl_perfapp/res/values/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2006, 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. +*/ +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="glperf_activity">GLPerf</string> + +</resources> + diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java new file mode 100644 index 000000000000..e3f3abf0296c --- /dev/null +++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfActivity.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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. + */ + +package com.android.glperf; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class GLPerfActivity extends Activity { + + GLPerfView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + mView = new GLPerfView(getApplication()); + setContentView(mView); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java new file mode 100644 index 000000000000..89a0e54d4c3c --- /dev/null +++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfLib.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2007 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. + */ + +package com.android.glperf; + +// Wrapper for native library + +public class GLPerfLib { + + static { + System.loadLibrary("glperf"); + } + + /** + * @param width the current view width + * @param height the current view height + */ + public static native void init(int width, int height); + public static native void step(); +} diff --git a/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java new file mode 100644 index 000000000000..4ce4a4d3ed9c --- /dev/null +++ b/opengl/tests/gl_perfapp/src/com/android/glperf/GLPerfView.java @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2009 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. + */ + +package com.android.glperf; +/* + * Copyright (C) 2008 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. + */ + + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying an OpenGL animation. This allows the animation to run in a + * separate thread, without requiring that it be driven by the update mechanism + * of the view hierarchy. + * + * The application-specific rendering code is delegated to a GLView.Renderer + * instance. + */ +class GLPerfView extends GLSurfaceView { + private static String TAG = "GLPerfView"; + + public GLPerfView(Context context) { + super(context); + init(false, 0, 0); + } + + public GLPerfView(Context context, boolean translucent, int depth, int stencil) { + super(context); + init(translucent, depth, stencil); + } + + private void init(boolean translucent, int depth, int stencil) { + setEGLContextFactory(new ContextFactory()); + setEGLConfigChooser( translucent ? + new ConfigChooser(8,8,8,8, depth, stencil) : + new ConfigChooser(5,6,5,0, depth, stencil)); + setRenderer(new Renderer()); + } + + private static class ContextFactory implements GLSurfaceView.EGLContextFactory { + private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; + public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { + Log.w(TAG, "creating OpenGL ES 2.0 context"); + checkEglError("Before eglCreateContext", egl); + int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; + EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list); + checkEglError("After eglCreateContext", egl); + return context; + } + + public void destroyContext(EGL10 egl, EGLDisplay display, EGLContext context) { + egl.eglDestroyContext(display, context); + } + } + + private static void checkEglError(String prompt, EGL10 egl) { + int error; + while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) { + Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error)); + } + } + + private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser { + private static int EGL_OPENGL_ES2_BIT = 4; + private static int[] s_configAttribs2 = + { + EGL10.EGL_RED_SIZE, 4, + EGL10.EGL_GREEN_SIZE, 4, + EGL10.EGL_BLUE_SIZE, 4, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL10.EGL_NONE + }; + + public ConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + mRedSize = r; + mGreenSize = g; + mBlueSize = b; + mAlphaSize = a; + mDepthSize = depth; + mStencilSize = stencil; + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { + + int[] num_config = new int[1]; + egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); + + int numConfigs = num_config[0]; + + if (numConfigs <= 0) { + throw new IllegalArgumentException("No configs match configSpec"); + } + EGLConfig[] configs = new EGLConfig[numConfigs]; + egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); + // printConfigs(egl, display, configs); + return chooseConfig(egl, display, configs); + } + + public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + EGLConfig closestConfig = null; + int closestDistance = 1000; + for(EGLConfig config : configs) { + int d = findConfigAttrib(egl, display, config, + EGL10.EGL_DEPTH_SIZE, 0); + int s = findConfigAttrib(egl, display, config, + EGL10.EGL_STENCIL_SIZE, 0); + if (d >= mDepthSize && s>= mStencilSize) { + int r = findConfigAttrib(egl, display, config, + EGL10.EGL_RED_SIZE, 0); + int g = findConfigAttrib(egl, display, config, + EGL10.EGL_GREEN_SIZE, 0); + int b = findConfigAttrib(egl, display, config, + EGL10.EGL_BLUE_SIZE, 0); + int a = findConfigAttrib(egl, display, config, + EGL10.EGL_ALPHA_SIZE, 0); + int distance = Math.abs(r - mRedSize) + + Math.abs(g - mGreenSize) + + Math.abs(b - mBlueSize) + + Math.abs(a - mAlphaSize); + if (distance < closestDistance) { + closestDistance = distance; + closestConfig = config; + } + } + } + return closestConfig; + } + + private int findConfigAttrib(EGL10 egl, EGLDisplay display, + EGLConfig config, int attribute, int defaultValue) { + + if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { + return mValue[0]; + } + return defaultValue; + } + + private void printConfigs(EGL10 egl, EGLDisplay display, + EGLConfig[] configs) { + int numConfigs = configs.length; + Log.w(TAG, String.format("%d configurations", numConfigs)); + for (int i = 0; i < numConfigs; i++) { + Log.w(TAG, String.format("Configuration %d:\n", i)); + printConfig(egl, display, configs[i]); + } + } + + private void printConfig(EGL10 egl, EGLDisplay display, + EGLConfig config) { + int[] attributes = { + EGL10.EGL_BUFFER_SIZE, + EGL10.EGL_ALPHA_SIZE, + EGL10.EGL_BLUE_SIZE, + EGL10.EGL_GREEN_SIZE, + EGL10.EGL_RED_SIZE, + EGL10.EGL_DEPTH_SIZE, + EGL10.EGL_STENCIL_SIZE, + EGL10.EGL_CONFIG_CAVEAT, + EGL10.EGL_CONFIG_ID, + EGL10.EGL_LEVEL, + EGL10.EGL_MAX_PBUFFER_HEIGHT, + EGL10.EGL_MAX_PBUFFER_PIXELS, + EGL10.EGL_MAX_PBUFFER_WIDTH, + EGL10.EGL_NATIVE_RENDERABLE, + EGL10.EGL_NATIVE_VISUAL_ID, + EGL10.EGL_NATIVE_VISUAL_TYPE, + 0x3030, // EGL10.EGL_PRESERVED_RESOURCES, + EGL10.EGL_SAMPLES, + EGL10.EGL_SAMPLE_BUFFERS, + EGL10.EGL_SURFACE_TYPE, + EGL10.EGL_TRANSPARENT_TYPE, + EGL10.EGL_TRANSPARENT_RED_VALUE, + EGL10.EGL_TRANSPARENT_GREEN_VALUE, + EGL10.EGL_TRANSPARENT_BLUE_VALUE, + 0x3039, // EGL10.EGL_BIND_TO_TEXTURE_RGB, + 0x303A, // EGL10.EGL_BIND_TO_TEXTURE_RGBA, + 0x303B, // EGL10.EGL_MIN_SWAP_INTERVAL, + 0x303C, // EGL10.EGL_MAX_SWAP_INTERVAL, + EGL10.EGL_LUMINANCE_SIZE, + EGL10.EGL_ALPHA_MASK_SIZE, + EGL10.EGL_COLOR_BUFFER_TYPE, + EGL10.EGL_RENDERABLE_TYPE, + 0x3042 // EGL10.EGL_CONFORMANT + }; + String[] names = { + "EGL_BUFFER_SIZE", + "EGL_ALPHA_SIZE", + "EGL_BLUE_SIZE", + "EGL_GREEN_SIZE", + "EGL_RED_SIZE", + "EGL_DEPTH_SIZE", + "EGL_STENCIL_SIZE", + "EGL_CONFIG_CAVEAT", + "EGL_CONFIG_ID", + "EGL_LEVEL", + "EGL_MAX_PBUFFER_HEIGHT", + "EGL_MAX_PBUFFER_PIXELS", + "EGL_MAX_PBUFFER_WIDTH", + "EGL_NATIVE_RENDERABLE", + "EGL_NATIVE_VISUAL_ID", + "EGL_NATIVE_VISUAL_TYPE", + "EGL_PRESERVED_RESOURCES", + "EGL_SAMPLES", + "EGL_SAMPLE_BUFFERS", + "EGL_SURFACE_TYPE", + "EGL_TRANSPARENT_TYPE", + "EGL_TRANSPARENT_RED_VALUE", + "EGL_TRANSPARENT_GREEN_VALUE", + "EGL_TRANSPARENT_BLUE_VALUE", + "EGL_BIND_TO_TEXTURE_RGB", + "EGL_BIND_TO_TEXTURE_RGBA", + "EGL_MIN_SWAP_INTERVAL", + "EGL_MAX_SWAP_INTERVAL", + "EGL_LUMINANCE_SIZE", + "EGL_ALPHA_MASK_SIZE", + "EGL_COLOR_BUFFER_TYPE", + "EGL_RENDERABLE_TYPE", + "EGL_CONFORMANT" + }; + int[] value = new int[1]; + for (int i = 0; i < attributes.length; i++) { + int attribute = attributes[i]; + String name = names[i]; + if ( egl.eglGetConfigAttrib(display, config, attribute, value)) { + Log.w(TAG, String.format(" %s: %d\n", name, value[0])); + } else { + // Log.w(TAG, String.format(" %s: failed\n", name)); + while (egl.eglGetError() != EGL10.EGL_SUCCESS); + } + } + } + + // Subclasses can adjust these values: + protected int mRedSize; + protected int mGreenSize; + protected int mBlueSize; + protected int mAlphaSize; + protected int mDepthSize; + protected int mStencilSize; + private int[] mValue = new int[1]; + } + + private static class Renderer implements GLSurfaceView.Renderer { + public void onDrawFrame(GL10 gl) { + GLPerfLib.step(); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLPerfLib.init(width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + // Do nothing. + } + } +} + diff --git a/opengl/tests/gl_yuvtex/Android.mk b/opengl/tests/gl_yuvtex/Android.mk new file mode 100644 index 000000000000..a78db25571f0 --- /dev/null +++ b/opengl/tests/gl_yuvtex/Android.mk @@ -0,0 +1,19 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + gl_yuvtex.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv1_CM \ + libui + +LOCAL_MODULE:= test-opengl-gl_yuvtex + +LOCAL_MODULE_TAGS := optional + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_EXECUTABLE) diff --git a/opengl/tests/gl_yuvtex/gl_yuvtex.cpp b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp new file mode 100644 index 000000000000..fbe65f12ed35 --- /dev/null +++ b/opengl/tests/gl_yuvtex/gl_yuvtex.cpp @@ -0,0 +1,333 @@ +/* + * Copyright (C) 2010 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 <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sched.h> +#include <sys/resource.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES/gl.h> +#include <GLES/glext.h> + +#include <utils/Timers.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +using namespace android; + +static void printGLString(const char *name, GLenum s) { + // fprintf(stderr, "printGLString %s, %d\n", name, s); + const char *v = (const char *) glGetString(s); + // int error = glGetError(); + // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error, + // (unsigned int) v); + // if ((v < (const char*) 0) || (v > (const char*) 0x10000)) + // fprintf(stderr, "GL %s = %s\n", name, v); + // else + // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v); + fprintf(stderr, "GL %s = %s\n", name, v); +} + +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) { + if (returnVal != EGL_TRUE) { + fprintf(stderr, "%s() returned %d\n", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error), + error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + fprintf(stderr, "after %s() glError (0x%x)\n", op, error); + } +} + +bool setupGraphics(int w, int h) { + glViewport(0, 0, w, h); + checkGlError("glViewport"); + return true; +} + +int align(int x, int a) { + return (x + (a-1)) & (~(a-1)); +} + +const int yuvTexWidth = 600; +const int yuvTexHeight = 480; +const int yuvTexUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +const int yuvTexFormat = HAL_PIXEL_FORMAT_YV12; +const int yuvTexOffsetY = 0; +const int yuvTexStrideY = (yuvTexWidth + 0xf) & ~0xf; +const int yuvTexOffsetV = yuvTexStrideY * yuvTexHeight; +const int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; +const int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * yuvTexHeight/2; +const int yuvTexStrideU = yuvTexStrideV; +const bool yuvTexSameUV = false; +static sp<GraphicBuffer> yuvTexBuffer; +static GLuint yuvTex; + +bool setupYuvTexSurface(EGLDisplay dpy, EGLContext context) { + int blockWidth = yuvTexWidth > 16 ? yuvTexWidth / 16 : 1; + int blockHeight = yuvTexHeight > 16 ? yuvTexHeight / 16 : 1; + yuvTexBuffer = new GraphicBuffer(yuvTexWidth, yuvTexHeight, yuvTexFormat, + yuvTexUsage); + char* buf = NULL; + status_t err = yuvTexBuffer->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->lock(...) failed: %d\n", err); + return false; + } + for (int x = 0; x < yuvTexWidth; x++) { + for (int y = 0; y < yuvTexHeight; y++) { + int parityX = (x / blockWidth) & 1; + int parityY = (y / blockHeight) & 1; + unsigned char intensity = (parityX ^ parityY) ? 63 : 191; + buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; + if (x < yuvTexWidth / 2 && y < yuvTexHeight / 2) { + buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; + if (yuvTexSameUV) { + buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = intensity; + } else if (x < yuvTexWidth / 4 && y < yuvTexHeight / 4) { + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = + buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = intensity; + } + } + } + } + + err = yuvTexBuffer->unlock(); + if (err != 0) { + fprintf(stderr, "yuvTexBuffer->unlock() failed: %d\n", err); + return false; + } + + EGLClientBuffer clientBuffer = (EGLClientBuffer)yuvTexBuffer->getNativeBuffer(); + EGLImageKHR img = eglCreateImageKHR(dpy, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, + clientBuffer, 0); + checkEglError("eglCreateImageKHR"); + if (img == EGL_NO_IMAGE_KHR) { + return false; + } + + glGenTextures(1, &yuvTex); + checkGlError("glGenTextures"); + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, (GLeglImageOES)img); + checkGlError("glEGLImageTargetTexture2DOES"); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + checkGlError("glTexParameteri"); + glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + checkGlError("glTexParameteri"); + glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + checkGlError("glTexEnvx"); + + GLint crop[4] = { 0, 0, yuvTexWidth, yuvTexHeight }; + glTexParameteriv(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_CROP_RECT_OES, crop); + checkGlError("glTexParameteriv"); + + return true; +} + +void renderFrame(int w, int h) { + glClearColor(0.0f, 0.0f, 1.0f, 1.0f); + checkGlError("glClearColor"); + glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + checkGlError("glClear"); + + glBindTexture(GL_TEXTURE_EXTERNAL_OES, yuvTex); + checkGlError("glBindTexture"); + glEnable(GL_TEXTURE_EXTERNAL_OES); + checkGlError("glEnable"); + + glDrawTexiOES(0, 0, 0, w, h); + checkGlError("glDrawTexiOES"); +} + +void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) { + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + printf(" %s: ", names[j].name); + printf("%d (0x%x)", value, value); + } + } + printf("\n"); +} + +int main(int argc, char** argv) { + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + + EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; + EGLint s_configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE }; + EGLint majorVersion; + EGLint minorVersion; + EGLContext context; + EGLSurface surface; + EGLint w, h; + + EGLDisplay dpy; + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + printf("eglGetDisplay returned EGL_NO_DISPLAY.\n"); + return 0; + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion); + if (returnValue != EGL_TRUE) { + printf("eglInitialize failed\n"); + return 0; + } + + EGLNativeWindowType window = android_createDisplaySurface(); + returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig); + if (returnValue) { + printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue); + return 1; + } + + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + printf("Chose this configuration:\n"); + printEGLConfiguration(dpy, myConfig); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + printf("gelCreateWindowSurface failed.\n"); + return 1; + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + printf("eglCreateContext failed\n"); + return 1; + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + return 1; + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &w); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &h); + checkEglError("eglQuerySurface"); + GLint dim = w < h ? w : h; + + fprintf(stderr, "Window dimensions: %d x %d\n", w, h); + + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + + if(!setupYuvTexSurface(dpy, context)) { + fprintf(stderr, "Could not set up texture surface.\n"); + return 1; + } + + if(!setupGraphics(w, h)) { + fprintf(stderr, "Could not set up graphics.\n"); + return 1; + } + + for (;;) { + static int dir = -1; + + renderFrame(w, h); + eglSwapBuffers(dpy, surface); + checkEglError("eglSwapBuffers"); + + if (w <= 10 || h <= 10) + { + dir = -dir; + } + + if (w >= 1300 || h >= 900) + { + dir = -dir; + } + + + w += dir; + h += dir; + } + + return 0; +} diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk new file mode 100644 index 000000000000..743dbf14f539 --- /dev/null +++ b/opengl/tests/hwc/Android.mk @@ -0,0 +1,27 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= hwc_stress.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libEGL \ + libGLESv2 \ + libui \ + libhardware \ + +LOCAL_STATIC_LIBRARIES := \ + libtestUtil \ + +LOCAL_C_INCLUDES += \ + system/extras/tests/include \ + hardware/libhardware/include \ + +LOCAL_MODULE:= hwc_stress +LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativestresstest + +LOCAL_MODULE_TAGS := tests + +LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES + +include $(BUILD_NATIVE_TEST) diff --git a/opengl/tests/hwc/hwc_stress.cpp b/opengl/tests/hwc/hwc_stress.cpp new file mode 100644 index 000000000000..d11973496006 --- /dev/null +++ b/opengl/tests/hwc/hwc_stress.cpp @@ -0,0 +1,1193 @@ +/* + * Copyright (C) 2010 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. + * + */ + +/* + * Hardware Composer stress test + * + * Performs a pseudo-random (prandom) sequence of operations to the + * Hardware Composer (HWC), for a specified number of passes or for + * a specified period of time. By default the period of time is FLT_MAX, + * so that the number of passes will take precedence. + * + * The passes are grouped together, where (pass / passesPerGroup) specifies + * which group a particular pass is in. This causes every passesPerGroup + * worth of sequential passes to be within the same group. Computationally + * intensive operations are performed just once at the beginning of a group + * of passes and then used by all the passes in that group. This is done + * so as to increase both the average and peak rate of graphic operations, + * by moving computationally intensive operations to the beginning of a group. + * In particular, at the start of each group of passes a set of + * graphic buffers are created, then used by the first and remaining + * passes of that group of passes. + * + * The per-group initialization of the graphic buffers is performed + * by a function called initFrames. This function creates an array + * of smart pointers to the graphic buffers, in the form of a vector + * of vectors. The array is accessed in row major order, so each + * row is a vector of smart pointers. All the pointers of a single + * row point to graphic buffers which use the same pixel format and + * have the same dimension, although it is likely that each one is + * filled with a different color. This is done so that after doing + * the first HWC prepare then set call, subsequent set calls can + * be made with each of the layer handles changed to a different + * graphic buffer within the same row. Since the graphic buffers + * in a particular row have the same pixel format and dimension, + * additional HWC set calls can be made, without having to perform + * an HWC prepare call. + * + * This test supports the following command-line options: + * + * -v Verbose + * -s num Starting pass + * -e num Ending pass + * -p num Execute the single pass specified by num + * -n num Number of set operations to perform after each prepare operation + * -t float Maximum time in seconds to execute the test + * -d float Delay in seconds performed after each set operation + * -D float Delay in seconds performed after the last pass is executed + * + * Typically the test is executed for a large range of passes. By default + * passes 0 through 99999 (100,000 passes) are executed. Although this test + * does not validate the generated image, at times it is useful to reexecute + * a particular pass and leave the displayed image on the screen for an + * extended period of time. This can be done either by setting the -s + * and -e options to the desired pass, along with a large value for -D. + * This can also be done via the -p option, again with a large value for + * the -D options. + * + * So far this test only contains code to create graphic buffers with + * a continuous solid color. Although this test is unable to validate the + * image produced, any image that contains other than rectangles of a solid + * color are incorrect. Note that the rectangles may use a transparent + * color and have a blending operation that causes the color in overlapping + * rectangles to be mixed. In such cases the overlapping portions may have + * a different color from the rest of the rectangle. + */ + +#include <algorithm> +#include <assert.h> +#include <cerrno> +#include <cmath> +#include <cstdlib> +#include <ctime> +#include <libgen.h> +#include <sched.h> +#include <sstream> +#include <stdint.h> +#include <string.h> +#include <unistd.h> +#include <vector> + +#include <arpa/inet.h> // For ntohl() and htonl() + +#include <sys/syscall.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES2/gl2.h> +#include <GLES2/gl2ext.h> + +#include <ui/FramebufferNativeWindow.h> +#include <ui/GraphicBuffer.h> +#include <ui/EGLUtils.h> + +#define LOG_TAG "hwcStressTest" +#include <utils/Log.h> +#include <testUtil.h> + +#include <hardware/hwcomposer.h> + +using namespace std; +using namespace android; + +const float maxSizeRatio = 1.3; // Graphic buffers can be upto this munch + // larger than the default screen size +const unsigned int passesPerGroup = 10; // A group of passes all use the same + // graphic buffers +const float rareRatio = 0.1; // Ratio at which rare conditions are produced. + +// Defaults for command-line options +const bool defaultVerbose = false; +const unsigned int defaultStartPass = 0; +const unsigned int defaultEndPass = 99999; +const unsigned int defaultPerPassNumSet = 10; +const float defaultPerPassDelay = 0.1; +const float defaultEndDelay = 2.0; // Default delay between completion of + // final pass and restart of framework +const float defaultDuration = FLT_MAX; // A fairly long time, so that + // range of passes will have + // precedence + +// Command-line option settings +static bool verbose = defaultVerbose; +static unsigned int startPass = defaultStartPass; +static unsigned int endPass = defaultEndPass; +static unsigned int numSet = defaultPerPassNumSet; +static float perSetDelay = defaultPerPassDelay; +static float endDelay = defaultEndDelay; +static float duration = defaultDuration; + +// Command-line mutual exclusion detection flags. +// Corresponding flag set true once an option is used. +bool eFlag, sFlag, pFlag; + +#define MAXSTR 100 +#define MAXCMD 200 +#define BITSPERBYTE 8 // TODO: Obtain from <values.h>, once + // it has been added + +#define CMD_STOP_FRAMEWORK "stop 2>&1" +#define CMD_START_FRAMEWORK "start 2>&1" + +#define NUMA(a) (sizeof(a) / sizeof(a [0])) +#define MEMCLR(addr, size) do { \ + memset((addr), 0, (size)); \ + } while (0) + +// Represent RGB color as fraction of color components. +// Each of the color components are expected in the range [0.0, 1.0] +class RGBColor { + public: + RGBColor(): _r(0.0), _g(0.0), _b(0.0) {}; + RGBColor(float f): _r(f), _g(f), _b(f) {}; // Gray + RGBColor(float r, float g, float b): _r(r), _g(g), _b(b) {}; + float r(void) const { return _r; } + float g(void) const { return _g; } + float b(void) const { return _b; } + + private: + float _r; + float _g; + float _b; +}; + +// Represent YUV color as fraction of color components. +// Each of the color components are expected in the range [0.0, 1.0] +class YUVColor { + public: + YUVColor(): _y(0.0), _u(0.0), _v(0.0) {}; + YUVColor(float f): _y(f), _u(0.0), _v(0.0) {}; // Gray + YUVColor(float y, float u, float v): _y(y), _u(u), _v(v) {}; + float y(void) const { return _y; } + float u(void) const { return _u; } + float v(void) const { return _v; } + + private: + float _y; + float _u; + float _v; +}; + +// File scope constants +static const struct { + unsigned int format; + const char *desc; +} graphicFormat[] = { + {HAL_PIXEL_FORMAT_RGBA_8888, "RGBA8888"}, + {HAL_PIXEL_FORMAT_RGBX_8888, "RGBX8888"}, +// {HAL_PIXEL_FORMAT_RGB_888, "RGB888"}, // Known issue: 3198458 + {HAL_PIXEL_FORMAT_RGB_565, "RGB565"}, + {HAL_PIXEL_FORMAT_BGRA_8888, "BGRA8888"}, + {HAL_PIXEL_FORMAT_RGBA_5551, "RGBA5551"}, + {HAL_PIXEL_FORMAT_RGBA_4444, "RGBA4444"}, +// {HAL_PIXEL_FORMAT_YV12, "YV12"}, // Currently not supported by HWC +}; +const unsigned int blendingOps[] = { + HWC_BLENDING_NONE, + HWC_BLENDING_PREMULT, + HWC_BLENDING_COVERAGE, +}; +const unsigned int layerFlags[] = { + HWC_SKIP_LAYER, +}; +const vector<unsigned int> vecLayerFlags(layerFlags, + layerFlags + NUMA(layerFlags)); + +const unsigned int transformFlags[] = { + HWC_TRANSFORM_FLIP_H, + HWC_TRANSFORM_FLIP_V, + HWC_TRANSFORM_ROT_90, + // ROT_180 & ROT_270 intentionally not listed, because they + // they are formed from combinations of the flags already listed. +}; +const vector<unsigned int> vecTransformFlags(transformFlags, + transformFlags + NUMA(transformFlags)); + +// File scope globals +static const int texUsage = GraphicBuffer::USAGE_HW_TEXTURE | + GraphicBuffer::USAGE_SW_WRITE_RARELY; +static hw_module_t const *hwcModule; +static hwc_composer_device_t *hwcDevice; +static vector <vector <sp<GraphicBuffer> > > frames; +static EGLDisplay dpy; +static EGLContext context; +static EGLSurface surface; +static EGLint width, height; + +// File scope prototypes +static void execCmd(const char *cmd); +static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE); +static void checkGlError(const char* op); +static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config); +static void printGLString(const char *name, GLenum s); +static hwc_layer_list_t *createLayerList(size_t numLayers); +static void freeLayerList(hwc_layer_list_t *list); +static void fillColor(GraphicBuffer *gBuf, RGBColor color, float trans); +static void fillColor(GraphicBuffer *gBuf, YUVColor color, float trans); +void init(void); +void initFrames(unsigned int seed); +void displayList(hwc_layer_list_t *list); +void displayListPrepareModifiable(hwc_layer_list_t *list); +void displayListHandles(hwc_layer_list_t *list); +const char *graphicFormat2str(unsigned int format); +template <class T> vector<T> vectorRandSelect(const vector<T>& vec, size_t num); +template <class T> T vectorOr(const vector<T>& vec); + +/* + * Main + * + * Performs the following high-level sequence of operations: + * + * 1. Command-line parsing + * + * 2. Initialization + * + * 3. For each pass: + * + * a. If pass is first pass or in a different group from the + * previous pass, initialize the array of graphic buffers. + * + * b. Create a HWC list with room to specify a prandomly + * selected number of layers. + * + * c. Select a subset of the rows from the graphic buffer array, + * such that there is a unique row to be used for each + * of the layers in the HWC list. + * + * d. Prandomly fill in the HWC list with handles + * selected from any of the columns of the selected row. + * + * e. Pass the populated list to the HWC prepare call. + * + * f. Pass the populated list to the HWC set call. + * + * g. If additional set calls are to be made, then for each + * additional set call, select a new set of handles and + * perform the set call. + */ +int +main(int argc, char *argv[]) +{ + int rv, opt; + char *chptr; + unsigned int pass; + char cmd[MAXCMD]; + struct timeval startTime, currentTime, delta; + + testSetLogCatTag(LOG_TAG); + + // Parse command line arguments + while ((opt = getopt(argc, argv, "vp:d:D:n:s:e:t:?h")) != -1) { + switch (opt) { + case 'd': // Delay after each set operation + perSetDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (perSetDelay < 0.0)) { + testPrintE("Invalid command-line specified per pass delay of: " + "%s", optarg); + exit(1); + } + break; + + case 'D': // End of test delay + // Delay between completion of final pass and restart + // of framework + endDelay = strtod(optarg, &chptr); + if ((*chptr != '\0') || (endDelay < 0.0)) { + testPrintE("Invalid command-line specified end of test delay " + "of: %s", optarg); + exit(2); + } + break; + + case 't': // Duration + duration = strtod(optarg, &chptr); + if ((*chptr != '\0') || (duration < 0.0)) { + testPrintE("Invalid command-line specified duration of: %s", + optarg); + exit(3); + } + break; + + case 'n': // Num set operations per pass + numSet = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified num set per pass " + "of: %s", optarg); + exit(4); + } + break; + + case 's': // Starting Pass + sFlag = true; + if (pFlag) { + testPrintE("Invalid combination of command-line options."); + testPrintE(" The -p option is mutually exclusive from the"); + testPrintE(" -s and -e options."); + exit(5); + } + startPass = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified starting pass " + "of: %s", optarg); + exit(6); + } + break; + + case 'e': // Ending Pass + eFlag = true; + if (pFlag) { + testPrintE("Invalid combination of command-line options."); + testPrintE(" The -p option is mutually exclusive from the"); + testPrintE(" -s and -e options."); + exit(7); + } + endPass = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified ending pass " + "of: %s", optarg); + exit(8); + } + break; + + case 'p': // Run a single specified pass + pFlag = true; + if (sFlag || eFlag) { + testPrintE("Invalid combination of command-line options."); + testPrintE(" The -p option is mutually exclusive from the"); + testPrintE(" -s and -e options."); + exit(9); + } + startPass = endPass = strtoul(optarg, &chptr, 10); + if (*chptr != '\0') { + testPrintE("Invalid command-line specified pass of: %s", + optarg); + exit(10); + } + break; + + case 'v': // Verbose + verbose = true; + break; + + case 'h': // Help + case '?': + default: + testPrintE(" %s [options]", basename(argv[0])); + testPrintE(" options:"); + testPrintE(" -p Execute specified pass"); + testPrintE(" -s Starting pass"); + testPrintE(" -e Ending pass"); + testPrintE(" -t Duration"); + testPrintE(" -d Delay after each set operation"); + testPrintE(" -D End of test delay"); + testPrintE(" -n Num set operations per pass"); + testPrintE(" -v Verbose"); + exit(((optopt == 0) || (optopt == '?')) ? 0 : 11); + } + } + if (endPass < startPass) { + testPrintE("Unexpected ending pass before starting pass"); + testPrintE(" startPass: %u endPass: %u", startPass, endPass); + exit(12); + } + if (argc != optind) { + testPrintE("Unexpected command-line postional argument"); + testPrintE(" %s [-s start_pass] [-e end_pass] [-t duration]", + basename(argv[0])); + exit(13); + } + testPrintI("duration: %g", duration); + testPrintI("startPass: %u", startPass); + testPrintI("endPass: %u", endPass); + testPrintI("numSet: %u", numSet); + + // Stop framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_STOP_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_STOP_FRAMEWORK); + exit(14); + } + execCmd(cmd); + testDelay(1.0); // TODO - needs means to query whether asyncronous stop + // framework operation has completed. For now, just wait + // a long time. + + init(); + + // For each pass + gettimeofday(&startTime, NULL); + for (pass = startPass; pass <= endPass; pass++) { + // Stop if duration of work has already been performed + gettimeofday(¤tTime, NULL); + delta = tvDelta(&startTime, ¤tTime); + if (tv2double(&delta) > duration) { break; } + + // Regenerate a new set of test frames when this pass is + // either the first pass or is in a different group then + // the previous pass. A group of passes are passes that + // all have the same quotient when their pass number is + // divided by passesPerGroup. + if ((pass == startPass) + || ((pass / passesPerGroup) != ((pass - 1) / passesPerGroup))) { + initFrames(pass / passesPerGroup); + } + + testPrintI("==== Starting pass: %u", pass); + + // Cause deterministic sequence of prandom numbers to be + // generated for this pass. + srand48(pass); + + hwc_layer_list_t *list; + list = createLayerList(testRandMod(frames.size()) + 1); + if (list == NULL) { + testPrintE("createLayerList failed"); + exit(20); + } + + // Prandomly select a subset of frames to be used by this pass. + vector <vector <sp<GraphicBuffer> > > selectedFrames; + selectedFrames = vectorRandSelect(frames, list->numHwLayers); + + // Any transform tends to create a layer that the hardware + // composer is unable to support and thus has to leave for + // SurfaceFlinger. Place heavy bias on specifying no transforms. + bool noTransform = testRandFract() > rareRatio; + + for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { + unsigned int idx = testRandMod(selectedFrames[n1].size()); + sp<GraphicBuffer> gBuf = selectedFrames[n1][idx]; + hwc_layer_t *layer = &list->hwLayers[n1]; + layer->handle = gBuf->handle; + + layer->blending = blendingOps[testRandMod(NUMA(blendingOps))]; + layer->flags = (testRandFract() > rareRatio) ? 0 + : vectorOr(vectorRandSelect(vecLayerFlags, + testRandMod(vecLayerFlags.size() + 1))); + layer->transform = (noTransform || testRandFract() > rareRatio) ? 0 + : vectorOr(vectorRandSelect(vecTransformFlags, + testRandMod(vecTransformFlags.size() + 1))); + layer->sourceCrop.left = testRandMod(gBuf->getWidth()); + layer->sourceCrop.top = testRandMod(gBuf->getHeight()); + layer->sourceCrop.right = layer->sourceCrop.left + + testRandMod(gBuf->getWidth() - layer->sourceCrop.left) + 1; + layer->sourceCrop.bottom = layer->sourceCrop.top + + testRandMod(gBuf->getHeight() - layer->sourceCrop.top) + 1; + layer->displayFrame.left = testRandMod(width); + layer->displayFrame.top = testRandMod(height); + layer->displayFrame.right = layer->displayFrame.left + + testRandMod(width - layer->displayFrame.left) + 1; + layer->displayFrame.bottom = layer->displayFrame.top + + testRandMod(height - layer->displayFrame.top) + 1; + layer->visibleRegionScreen.numRects = 1; + layer->visibleRegionScreen.rects = &layer->displayFrame; + } + + // Perform prepare operation + if (verbose) { testPrintI("Prepare:"); displayList(list); } + hwcDevice->prepare(hwcDevice, list); + if (verbose) { + testPrintI("Post Prepare:"); + displayListPrepareModifiable(list); + } + + // Turn off the geometry changed flag + list->flags &= ~HWC_GEOMETRY_CHANGED; + + // Perform the set operation(s) + if (verbose) {testPrintI("Set:"); } + for (unsigned int n1 = 0; n1 < numSet; n1++) { + if (verbose) {displayListHandles(list); } + hwcDevice->set(hwcDevice, dpy, surface, list); + + // Prandomly select a new set of handles + for (unsigned int n1 = 0; n1 < list->numHwLayers; n1++) { + unsigned int idx = testRandMod(selectedFrames[n1].size()); + sp<GraphicBuffer> gBuf = selectedFrames[n1][idx]; + hwc_layer_t *layer = &list->hwLayers[n1]; + layer->handle = (native_handle_t *) gBuf->handle; + } + + testDelay(perSetDelay); + } + + + freeLayerList(list); + testPrintI("==== Completed pass: %u", pass); + } + + testDelay(endDelay); + + // Start framework + rv = snprintf(cmd, sizeof(cmd), "%s", CMD_START_FRAMEWORK); + if (rv >= (signed) sizeof(cmd) - 1) { + testPrintE("Command too long for: %s", CMD_START_FRAMEWORK); + exit(21); + } + execCmd(cmd); + + testPrintI("Successfully completed %u passes", pass - startPass); + + return 0; +} + +/* + * Execute Command + * + * Executes the command pointed to by cmd. Output from the + * executed command is captured and sent to LogCat Info. Once + * the command has finished execution, it's exit status is captured + * and checked for an exit status of zero. Any other exit status + * causes diagnostic information to be printed and an immediate + * testcase failure. + */ +static void execCmd(const char *cmd) +{ + FILE *fp; + int rv; + int status; + char str[MAXSTR]; + + // Display command to be executed + testPrintI("cmd: %s", cmd); + + // Execute the command + fflush(stdout); + if ((fp = popen(cmd, "r")) == NULL) { + testPrintE("execCmd popen failed, errno: %i", errno); + exit(30); + } + + // Obtain and display each line of output from the executed command + while (fgets(str, sizeof(str), fp) != NULL) { + if ((strlen(str) > 1) && (str[strlen(str) - 1] == '\n')) { + str[strlen(str) - 1] = '\0'; + } + testPrintI(" out: %s", str); + } + + // Obtain and check return status of executed command. + // Fail on non-zero exit status + status = pclose(fp); + if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) { + testPrintE("Unexpected command failure"); + testPrintE(" status: %#x", status); + if (WIFEXITED(status)) { + testPrintE("WEXITSTATUS: %i", WEXITSTATUS(status)); + } + if (WIFSIGNALED(status)) { + testPrintE("WTERMSIG: %i", WTERMSIG(status)); + } + exit(31); + } +} + +static void checkEglError(const char* op, EGLBoolean returnVal) { + if (returnVal != EGL_TRUE) { + testPrintE("%s() returned %d", op, returnVal); + } + + for (EGLint error = eglGetError(); error != EGL_SUCCESS; error + = eglGetError()) { + testPrintE("after %s() eglError %s (0x%x)", + op, EGLUtils::strerror(error), error); + } +} + +static void checkGlError(const char* op) { + for (GLint error = glGetError(); error; error + = glGetError()) { + testPrintE("after %s() glError (0x%x)", op, error); + } +} + +static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) { + +#define X(VAL) {VAL, #VAL} + struct {EGLint attribute; const char* name;} names[] = { + X(EGL_BUFFER_SIZE), + X(EGL_ALPHA_SIZE), + X(EGL_BLUE_SIZE), + X(EGL_GREEN_SIZE), + X(EGL_RED_SIZE), + X(EGL_DEPTH_SIZE), + X(EGL_STENCIL_SIZE), + X(EGL_CONFIG_CAVEAT), + X(EGL_CONFIG_ID), + X(EGL_LEVEL), + X(EGL_MAX_PBUFFER_HEIGHT), + X(EGL_MAX_PBUFFER_PIXELS), + X(EGL_MAX_PBUFFER_WIDTH), + X(EGL_NATIVE_RENDERABLE), + X(EGL_NATIVE_VISUAL_ID), + X(EGL_NATIVE_VISUAL_TYPE), + X(EGL_SAMPLES), + X(EGL_SAMPLE_BUFFERS), + X(EGL_SURFACE_TYPE), + X(EGL_TRANSPARENT_TYPE), + X(EGL_TRANSPARENT_RED_VALUE), + X(EGL_TRANSPARENT_GREEN_VALUE), + X(EGL_TRANSPARENT_BLUE_VALUE), + X(EGL_BIND_TO_TEXTURE_RGB), + X(EGL_BIND_TO_TEXTURE_RGBA), + X(EGL_MIN_SWAP_INTERVAL), + X(EGL_MAX_SWAP_INTERVAL), + X(EGL_LUMINANCE_SIZE), + X(EGL_ALPHA_MASK_SIZE), + X(EGL_COLOR_BUFFER_TYPE), + X(EGL_RENDERABLE_TYPE), + X(EGL_CONFORMANT), + }; +#undef X + + for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) { + EGLint value = -1; + EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value); + EGLint error = eglGetError(); + if (returnVal && error == EGL_SUCCESS) { + testPrintI(" %s: %d (%#x)", names[j].name, value, value); + } + } + testPrintI(""); +} + +static void printGLString(const char *name, GLenum s) +{ + const char *v = (const char *) glGetString(s); + + if (v == NULL) { + testPrintI("GL %s unknown", name); + } else { + testPrintI("GL %s = %s", name, v); + } +} + +/* + * createLayerList + * dynamically creates layer list with numLayers worth + * of hwLayers entries. + */ +static hwc_layer_list_t *createLayerList(size_t numLayers) +{ + hwc_layer_list_t *list; + + size_t size = sizeof(hwc_layer_list) + numLayers * sizeof(hwc_layer_t); + if ((list = (hwc_layer_list_t *) calloc(1, size)) == NULL) { + return NULL; + } + list->flags = HWC_GEOMETRY_CHANGED; + list->numHwLayers = numLayers; + + return list; +} + +/* + * freeLayerList + * Frees memory previous allocated via createLayerList(). + */ +static void freeLayerList(hwc_layer_list_t *list) +{ + free(list); +} + +static void fillColor(GraphicBuffer *gBuf, RGBColor color, float trans) +{ + unsigned char* buf = NULL; + status_t err; + unsigned int numPixels = gBuf->getWidth() * gBuf->getHeight(); + uint32_t pixel; + + // RGB 2 YUV conversion ratios + const struct rgb2yuvRatios { + int format; + float weightRed; + float weightBlu; + float weightGrn; + } rgb2yuvRatios[] = { + { HAL_PIXEL_FORMAT_YV12, 0.299, 0.114, 0.587 }, + }; + + const struct rgbAttrib { + int format; + bool hostByteOrder; + size_t bytes; + size_t rOffset; + size_t rSize; + size_t gOffset; + size_t gSize; + size_t bOffset; + size_t bSize; + size_t aOffset; + size_t aSize; + } rgbAttributes[] = { + {HAL_PIXEL_FORMAT_RGBA_8888, false, 4, 0, 8, 8, 8, 16, 8, 24, 8}, + {HAL_PIXEL_FORMAT_RGBX_8888, false, 4, 0, 8, 8, 8, 16, 8, 0, 0}, + {HAL_PIXEL_FORMAT_RGB_888, false, 3, 0, 8, 8, 8, 16, 8, 0, 0}, + {HAL_PIXEL_FORMAT_RGB_565, true, 2, 0, 5, 5, 6, 11, 5, 0, 0}, + {HAL_PIXEL_FORMAT_BGRA_8888, false, 4, 16, 8, 8, 8, 0, 8, 24, 8}, + {HAL_PIXEL_FORMAT_RGBA_5551, true , 2, 0, 5, 5, 5, 10, 5, 15, 1}, + {HAL_PIXEL_FORMAT_RGBA_4444, false, 2, 12, 4, 0, 4, 4, 4, 8, 4}, + }; + + // If YUV format, convert color and pass work to YUV color fill + for (unsigned int n1 = 0; n1 < NUMA(rgb2yuvRatios); n1++) { + if (gBuf->getPixelFormat() == rgb2yuvRatios[n1].format) { + float wr = rgb2yuvRatios[n1].weightRed; + float wb = rgb2yuvRatios[n1].weightBlu; + float wg = rgb2yuvRatios[n1].weightGrn; + float y = wr * color.r() + wb * color.b() + wg * color.g(); + float u = 0.5 * ((color.b() - y) / (1 - wb)) + 0.5; + float v = 0.5 * ((color.r() - y) / (1 - wr)) + 0.5; + YUVColor yuvColor(y, u, v); + fillColor(gBuf, yuvColor, trans); + return; + } + } + + const struct rgbAttrib *attrib; + for (attrib = rgbAttributes; attrib < rgbAttributes + NUMA(rgbAttributes); + attrib++) { + if (attrib->format == gBuf->getPixelFormat()) { break; } + } + if (attrib >= rgbAttributes + NUMA(rgbAttributes)) { + testPrintE("fillColor rgb unsupported format of: %u", + gBuf->getPixelFormat()); + exit(50); + } + + pixel = htonl((uint32_t) (((1 << attrib->rSize) - 1) * color.r()) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->rOffset + attrib->rSize))); + pixel |= htonl((uint32_t) (((1 << attrib->gSize) - 1) * color.g()) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->gOffset + attrib->gSize))); + pixel |= htonl((uint32_t) (((1 << attrib->bSize) - 1) * color.b()) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->bOffset + attrib->bSize))); + if (attrib->aSize) { + pixel |= htonl((uint32_t) (((1 << attrib->aSize) - 1) * trans) + << ((sizeof(pixel) * BITSPERBYTE) + - (attrib->aOffset + attrib->aSize))); + } + if (attrib->hostByteOrder) { + pixel = ntohl(pixel); + pixel >>= sizeof(pixel) * BITSPERBYTE - attrib->bytes * BITSPERBYTE; + } + + err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + testPrintE("fillColor rgb lock failed: %d", err); + exit(51); + } + + for (unsigned int n1 = 0; n1 < numPixels; n1++) { + memmove(buf, &pixel, attrib->bytes); + buf += attrib->bytes; + } + + err = gBuf->unlock(); + if (err != 0) { + testPrintE("fillColor rgb unlock failed: %d", err); + exit(52); + } +} + +static void fillColor(GraphicBuffer *gBuf, YUVColor color, float trans) +{ + unsigned char* buf = NULL; + status_t err; + unsigned int width = gBuf->getWidth(); + unsigned int height = gBuf->getHeight(); + + const struct yuvAttrib { + int format; + size_t padWidth; + bool planar; + unsigned int uSubSampX; + unsigned int uSubSampY; + unsigned int vSubSampX; + unsigned int vSubSampY; + } yuvAttributes[] = { + { HAL_PIXEL_FORMAT_YV12, 16, true, 2, 2, 2, 2}, + }; + + const struct yuvAttrib *attrib; + for (attrib = yuvAttributes; attrib < yuvAttributes + NUMA(yuvAttributes); + attrib++) { + if (attrib->format == gBuf->getPixelFormat()) { break; } + } + if (attrib >= yuvAttributes + NUMA(yuvAttributes)) { + testPrintE("fillColor yuv unsupported format of: %u", + gBuf->getPixelFormat()); + exit(60); + } + + assert(attrib->planar == true); // So far, only know how to handle planar + + // If needed round width up to pad size + if (width % attrib->padWidth) { + width += attrib->padWidth - (width % attrib->padWidth); + } + assert((width % attrib->padWidth) == 0); + + err = gBuf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&buf)); + if (err != 0) { + testPrintE("fillColor lock failed: %d", err); + exit(61); + } + + // Fill in Y component + for (unsigned int x = 0; x < width; x++) { + for (unsigned int y = 0; y < height; y++) { + *buf++ = (x < gBuf->getWidth()) ? (255 * color.y()) : 0; + } + } + + // Fill in U component + for (unsigned int x = 0; x < width; x += attrib->uSubSampX) { + for (unsigned int y = 0; y < height; y += attrib->uSubSampY) { + *buf++ = (x < gBuf->getWidth()) ? (255 * color.u()) : 0; + } + } + + // Fill in V component + for (unsigned int x = 0; x < width; x += attrib->vSubSampX) { + for (unsigned int y = 0; y < height; y += attrib->vSubSampY) { + *buf++ = (x < gBuf->getWidth()) ? (255 * color.v()) : 0; + } + } + + err = gBuf->unlock(); + if (err != 0) { + testPrintE("fillColor unlock failed: %d", err); + exit(62); + } +} + +void init(void) +{ + int rv; + + EGLBoolean returnValue; + EGLConfig myConfig = {0}; + EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; + EGLint sConfigAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE }; + EGLint majorVersion, minorVersion; + + checkEglError("<init>"); + dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); + checkEglError("eglGetDisplay"); + if (dpy == EGL_NO_DISPLAY) { + testPrintE("eglGetDisplay returned EGL_NO_DISPLAY"); + exit(70); + } + + returnValue = eglInitialize(dpy, &majorVersion, &minorVersion); + checkEglError("eglInitialize", returnValue); + testPrintI("EGL version %d.%d", majorVersion, minorVersion); + if (returnValue != EGL_TRUE) { + testPrintE("eglInitialize failed"); + exit(71); + } + + EGLNativeWindowType window = android_createDisplaySurface(); + if (window == NULL) { + testPrintE("android_createDisplaySurface failed"); + exit(72); + } + returnValue = EGLUtils::selectConfigForNativeWindow(dpy, + sConfigAttribs, window, &myConfig); + if (returnValue) { + testPrintE("EGLUtils::selectConfigForNativeWindow() returned %d", + returnValue); + exit(73); + } + checkEglError("EGLUtils::selectConfigForNativeWindow"); + + testPrintI("Chose this configuration:"); + printEGLConfiguration(dpy, myConfig); + + surface = eglCreateWindowSurface(dpy, myConfig, window, NULL); + checkEglError("eglCreateWindowSurface"); + if (surface == EGL_NO_SURFACE) { + testPrintE("gelCreateWindowSurface failed."); + exit(74); + } + + context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, contextAttribs); + checkEglError("eglCreateContext"); + if (context == EGL_NO_CONTEXT) { + testPrintE("eglCreateContext failed"); + exit(75); + } + returnValue = eglMakeCurrent(dpy, surface, surface, context); + checkEglError("eglMakeCurrent", returnValue); + if (returnValue != EGL_TRUE) { + testPrintE("eglMakeCurrent failed"); + exit(76); + } + eglQuerySurface(dpy, surface, EGL_WIDTH, &width); + checkEglError("eglQuerySurface"); + eglQuerySurface(dpy, surface, EGL_HEIGHT, &height); + checkEglError("eglQuerySurface"); + + fprintf(stderr, "Window dimensions: %d x %d", width, height); + + printGLString("Version", GL_VERSION); + printGLString("Vendor", GL_VENDOR); + printGLString("Renderer", GL_RENDERER); + printGLString("Extensions", GL_EXTENSIONS); + + if ((rv = hw_get_module(HWC_HARDWARE_MODULE_ID, &hwcModule)) != 0) { + testPrintE("hw_get_module failed, rv: %i", rv); + errno = -rv; + perror(NULL); + exit(77); + } + if ((rv = hwc_open(hwcModule, &hwcDevice)) != 0) { + testPrintE("hwc_open failed, rv: %i", rv); + errno = -rv; + perror(NULL); + exit(78); + } + + testPrintI(""); +} + +/* + * Initialize Frames + * + * Creates an array of graphic buffers, within the global variable + * named frames. The graphic buffers are contained within a vector of + * verctors. All the graphic buffers in a particular row are of the same + * format and dimension. Each graphic buffer is uniformly filled with a + * prandomly selected color. It is likely that each buffer, even + * in the same row, will be filled with a unique color. + */ +void initFrames(unsigned int seed) +{ + const size_t maxRows = 5; + const size_t minCols = 2; // Need at least double buffering + const size_t maxCols = 4; // One more than triple buffering + + if (verbose) { testPrintI("initFrames seed: %u", seed); } + srand48(seed); + size_t rows = testRandMod(maxRows) + 1; + + frames.clear(); + frames.resize(rows); + + for (unsigned int row = 0; row < rows; row++) { + // All frames within a row have to have the same format and + // dimensions. Width and height need to be >= 1. + int format = graphicFormat[testRandMod(NUMA(graphicFormat))].format; + size_t w = (width * maxSizeRatio) * testRandFract(); + size_t h = (height * maxSizeRatio) * testRandFract(); + w = max(1u, w); + h = max(1u, h); + if (verbose) { + testPrintI(" frame %u width: %u height: %u format: %u %s", + row, w, h, format, graphicFormat2str(format)); + } + + size_t cols = testRandMod((maxCols + 1) - minCols) + minCols; + frames[row].resize(cols); + for (unsigned int col = 0; col < cols; col++) { + RGBColor color(testRandFract(), testRandFract(), testRandFract()); + float transp = testRandFract(); + + frames[row][col] = new GraphicBuffer(w, h, format, texUsage); + fillColor(frames[row][col].get(), color, transp); + if (verbose) { + testPrintI(" buf: %p handle: %p color: <%f, %f, %f> " + "transp: %f", + frames[row][col].get(), frames[row][col]->handle, + color.r(), color.g(), color.b(), transp); + } + } + } +} + +void displayList(hwc_layer_list_t *list) +{ + testPrintI(" flags: %#x%s", list->flags, + (list->flags & HWC_GEOMETRY_CHANGED) ? " GEOMETRY_CHANGED" : ""); + testPrintI(" numHwLayers: %u", list->numHwLayers); + + for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { + testPrintI(" layer %u compositionType: %#x%s%s", layer, + list->hwLayers[layer].compositionType, + (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER) + ? " FRAMEBUFFER" : "", + (list->hwLayers[layer].compositionType == HWC_OVERLAY) + ? " OVERLAY" : ""); + + testPrintI(" hints: %#x", + list->hwLayers[layer].hints, + (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER) + ? " TRIPLE_BUFFER" : "", + (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB) + ? " CLEAR_FB" : ""); + + testPrintI(" flags: %#x%s", + list->hwLayers[layer].flags, + (list->hwLayers[layer].flags & HWC_SKIP_LAYER) + ? " SKIP_LAYER" : ""); + + testPrintI(" handle: %p", + list->hwLayers[layer].handle); + + // Intentionally skipped display of ROT_180 & ROT_270, + // which are formed from combinations of the other flags. + testPrintI(" transform: %#x%s%s%s", + list->hwLayers[layer].transform, + (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_H) + ? " FLIP_H" : "", + (list->hwLayers[layer].transform & HWC_TRANSFORM_FLIP_V) + ? " FLIP_V" : "", + (list->hwLayers[layer].transform & HWC_TRANSFORM_ROT_90) + ? " ROT_90" : ""); + + testPrintI(" blending: %#x", + list->hwLayers[layer].blending, + (list->hwLayers[layer].blending == HWC_BLENDING_NONE) + ? " NONE" : "", + (list->hwLayers[layer].blending == HWC_BLENDING_PREMULT) + ? " PREMULT" : "", + (list->hwLayers[layer].blending == HWC_BLENDING_COVERAGE) + ? " COVERAGE" : ""); + + testPrintI(" sourceCrop: [%i, %i, %i, %i]", + list->hwLayers[layer].sourceCrop.left, + list->hwLayers[layer].sourceCrop.top, + list->hwLayers[layer].sourceCrop.right, + list->hwLayers[layer].sourceCrop.bottom); + + testPrintI(" displayFrame: [%i, %i, %i, %i]", + list->hwLayers[layer].displayFrame.left, + list->hwLayers[layer].displayFrame.top, + list->hwLayers[layer].displayFrame.right, + list->hwLayers[layer].displayFrame.bottom); + } +} + +/* + * Display List Prepare Modifiable + * + * Displays the portions of a list that are meant to be modified by + * a prepare call. + */ +void displayListPrepareModifiable(hwc_layer_list_t *list) +{ + for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { + testPrintI(" layer %u compositionType: %#x%s%s", layer, + list->hwLayers[layer].compositionType, + (list->hwLayers[layer].compositionType == HWC_FRAMEBUFFER) + ? " FRAMEBUFFER" : "", + (list->hwLayers[layer].compositionType == HWC_OVERLAY) + ? " OVERLAY" : ""); + testPrintI(" hints: %#x%s%s", + list->hwLayers[layer].hints, + (list->hwLayers[layer].hints & HWC_HINT_TRIPLE_BUFFER) + ? " TRIPLE_BUFFER" : "", + (list->hwLayers[layer].hints & HWC_HINT_CLEAR_FB) + ? " CLEAR_FB" : ""); + } +} + +/* + * Display List Handles + * + * Displays the handles of all the graphic buffers in the list. + */ +void displayListHandles(hwc_layer_list_t *list) +{ + const unsigned int maxLayersPerLine = 6; + + ostringstream str(" layers:"); + for (unsigned int layer = 0; layer < list->numHwLayers; layer++) { + str << ' ' << list->hwLayers[layer].handle; + if (((layer % maxLayersPerLine) == (maxLayersPerLine - 1)) + && (layer != list->numHwLayers - 1)) { + testPrintI("%s", str.str().c_str()); + str.str(" "); + } + } + testPrintI("%s", str.str().c_str()); +} + +const char *graphicFormat2str(unsigned int format) +{ + const static char *unknown = "unknown"; + + for (unsigned int n1 = 0; n1 < NUMA(graphicFormat); n1++) { + if (format == graphicFormat[n1].format) { + return graphicFormat[n1].desc; + } + } + + return unknown; +} + +/* + * Vector Random Select + * + * Prandomly selects and returns num elements from vec. + */ +template <class T> +vector<T> vectorRandSelect(const vector<T>& vec, size_t num) +{ + vector<T> rv = vec; + + while (rv.size() > num) { + rv.erase(rv.begin() + testRandMod(rv.size())); + } + + return rv; +} + +/* + * Vector Or + * + * Or's togethen the values of each element of vec and returns the result. + */ +template <class T> +T vectorOr(const vector<T>& vec) +{ + T rv = 0; + + for (size_t n1 = 0; n1 < vec.size(); n1++) { + rv |= vec[n1]; + } + + return rv; +} diff --git a/opengl/tests/testFramerate/Android.mk b/opengl/tests/testFramerate/Android.mk new file mode 100644 index 000000000000..500abf376a63 --- /dev/null +++ b/opengl/tests/testFramerate/Android.mk @@ -0,0 +1,19 @@ +######################################################################### +# Test framerate and look for hiccups +######################################################################### + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := TestFramerate + +include $(BUILD_PACKAGE) diff --git a/opengl/tests/testFramerate/AndroidManifest.xml b/opengl/tests/testFramerate/AndroidManifest.xml new file mode 100644 index 000000000000..e04342cee545 --- /dev/null +++ b/opengl/tests/testFramerate/AndroidManifest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, 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. +*/ +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.testframerate"> + <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" /> + + <application + android:label="@string/testFramerate_activity"> + <activity android:name="TestFramerateActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:launchMode="singleTask" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/testFramerate/res/values/strings.xml b/opengl/tests/testFramerate/res/values/strings.xml new file mode 100644 index 000000000000..e6b3088e6e23 --- /dev/null +++ b/opengl/tests/testFramerate/res/values/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2006, 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. +*/ +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="testFramerate_activity">TestFramerate</string> + +</resources> + diff --git a/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java new file mode 100644 index 000000000000..cbe279b07912 --- /dev/null +++ b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateActivity.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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. + */ + +package com.android.testframerate; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class TestFramerateActivity extends Activity { + + TestFramerateView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new TestFramerateView(getApplication()); + setContentView(mView); + mView.setFocusableInTouchMode(true); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java new file mode 100644 index 000000000000..f3fb5de414a9 --- /dev/null +++ b/opengl/tests/testFramerate/src/com/android/testframerate/TestFramerateView.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 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. + */ + +package com.android.testframerate; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.os.SystemProperties; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLES20; + +class TestFramerateView extends GLSurfaceView { + private static String TAG = "TestFramerateView"; + + public TestFramerateView(Context context) { + super(context); + setEGLContextClientVersion(2); + setRenderer(new Renderer()); + } + + private long mLastTime_us = 0; + private long mNumShortFramesElapsed = 0; + private void registerTime(long now_us) { + long longFrameTime_ms = Integer.parseInt(SystemProperties.get("debug.longframe_ms", "16")); + long elapsedTime_us = now_us - mLastTime_us; + float fps = 1000000.f / elapsedTime_us; + if (mLastTime_us > 0 && elapsedTime_us > longFrameTime_ms*1000) { + Log.v(TAG, "Long frame: " + elapsedTime_us/1000.f + " ms (" + fps + " fps)"); + if (mNumShortFramesElapsed > 0) { + Log.v(TAG, " Short frames since last long frame: " + mNumShortFramesElapsed); + mNumShortFramesElapsed = 0; + } + } else { + ++mNumShortFramesElapsed; + } + + mLastTime_us = now_us; + } + + private class Renderer implements GLSurfaceView.Renderer { + public Renderer() { + } + + + public void onDrawFrame(GL10 gl) { + long now_us = System.nanoTime() / 1000; + registerTime(now_us); + + float red = (now_us % 1000000) / 1000000.f; + float green = (now_us % 2000000) / 2000000.f; + float blue = (now_us % 3000000) / 3000000.f; + GLES20.glClearColor(red, green, blue, 1.0f); + GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLES20.glViewport(0, 0, width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + } + + } +} diff --git a/opengl/tests/testLatency/Android.mk b/opengl/tests/testLatency/Android.mk new file mode 100644 index 000000000000..96417c7ef52b --- /dev/null +++ b/opengl/tests/testLatency/Android.mk @@ -0,0 +1,20 @@ +######################################################################### +# Test end-to-end latency. +######################################################################### + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SDK_VERSION := 8 +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := TestLatency + +include $(BUILD_PACKAGE) diff --git a/opengl/tests/testLatency/AndroidManifest.xml b/opengl/tests/testLatency/AndroidManifest.xml new file mode 100644 index 000000000000..741266e954aa --- /dev/null +++ b/opengl/tests/testLatency/AndroidManifest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, 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. +*/ +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.testlatency"> + <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" /> + + <application + android:label="@string/testLatency_activity"> + <activity android:name="TestLatencyActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:launchMode="singleTask" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/testLatency/res/values/strings.xml b/opengl/tests/testLatency/res/values/strings.xml new file mode 100644 index 000000000000..0309991082d0 --- /dev/null +++ b/opengl/tests/testLatency/res/values/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2006, 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. +*/ +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="testLatency_activity">TestLatency</string> + +</resources> + diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java new file mode 100644 index 000000000000..ed993cb34cb6 --- /dev/null +++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyActivity.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2007 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. + */ + +package com.android.testlatency; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; +import android.view.WindowManager; + +import java.io.File; + + +public class TestLatencyActivity extends Activity { + + TestLatencyView mView; + + @Override protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new TestLatencyView(getApplication()); + setContentView(mView); + mView.setFocusableInTouchMode(true); + } + + @Override protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java new file mode 100644 index 000000000000..d62bf17487a4 --- /dev/null +++ b/opengl/tests/testLatency/src/com/android/testlatency/TestLatencyView.java @@ -0,0 +1,267 @@ +/* + * Copyright (C) 2009 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. + */ + +package com.android.testlatency; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.FloatBuffer; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.egl.EGLContext; +import javax.microedition.khronos.egl.EGLDisplay; +import javax.microedition.khronos.opengles.GL10; + +import android.opengl.GLES20; + +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying an OpenGL animation. This allows the animation to run in a + * separate thread, without requiring that it be driven by the update mechanism + * of the view hierarchy. + * + * The application-specific rendering code is delegated to a GLView.Renderer + * instance. + */ +class TestLatencyView extends GLSurfaceView { + private static String TAG = "TestLatencyiew"; + private float mX; + private float mY; + private float mDX; + private float mDY; + private long mT; + private long mDT; + + public TestLatencyView(Context context) { + super(context); + setEGLContextClientVersion(2); + setRenderer(new Renderer()); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + switch (event.getAction()) { + case MotionEvent.ACTION_MOVE: + float x = event.getX(); + float y = event.getY(); + long t = event.getEventTime(); + synchronized(this) { + mDT = t - mT; + mT = t; + mDX = x - mX; + mX = x; + mDY = y - mY; + mY = y; + } + break; + default: + break; + } + return true; + } + + private class Renderer implements GLSurfaceView.Renderer { + private float mScaleX, mScaleY, mOffsetX, mOffsetY; + private final float MS_PER_FRAME = 1000 / 60; + public Renderer() { + mTriangleVertices = ByteBuffer.allocateDirect(mTriangleVerticesData.length * 4) + .order(ByteOrder.nativeOrder()).asFloatBuffer(); + } + + + public void onDrawFrame(GL10 gl) { + GLES20.glClearColor(0.4f, 0.4f, 0.4f, 1.0f); + GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); + GLES20.glUseProgram(mProgram); + checkGlError("glUseProgram"); + + float x, y, dx, dy; + long t, dt; + synchronized(TestLatencyView.this) { + x = mX; + y = mY; + dx = mDX; + dy = mDY; + dt = mDT; + } + + if (dt > 0) { + dx = dx * MS_PER_FRAME / dt; + dy = dy * MS_PER_FRAME / dt; + } + + GLES20.glEnableVertexAttribArray(mvPositionHandle); + checkGlError("glEnableVertexAttribArray"); + GLES20.glEnableVertexAttribArray(mvColorHandle); + checkGlError("glEnableVertexAttribArray"); + for(int step = 0; step < 8; step++) { + float sx = (x + dx * step) * mScaleX + mOffsetX; + float sy = (y + dy * step) * mScaleY + mOffsetY; + int cbase = step * 4; + + for (int i = 0; i < mTriangleVerticesData.length; i += 6) { + mTriangleVerticesData2[i] = sx + mTriangleVerticesData[i]; + mTriangleVerticesData2[i+1] = -sy + mTriangleVerticesData[i+1]; + mTriangleVerticesData2[i+2] = mColors[cbase]; + mTriangleVerticesData2[i+3] = mColors[cbase+1]; + mTriangleVerticesData2[i+4] = mColors[cbase+2]; + mTriangleVerticesData2[i+5] = mColors[cbase+3]; + } + mTriangleVertices.position(0); + mTriangleVertices.put(mTriangleVerticesData2).position(0); + + GLES20.glVertexAttribPointer(mvPositionHandle, 2, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices); + checkGlError("glVertexAttribPointer mvPosition"); + mTriangleVertices.put(mTriangleVerticesData2).position(2); + GLES20.glVertexAttribPointer(mvColorHandle, 4, GLES20.GL_FLOAT, false, 6*4, mTriangleVertices); + checkGlError("glVertexAttribPointer mvColor"); + GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); + checkGlError("glDrawArrays"); + } + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + GLES20.glViewport(0, 0, width, height); + mScaleX = 2.0f / width; + mScaleY = 2.0f / height; + mOffsetX = -1f; + mOffsetY = -1f; + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + mProgram = createProgram(mVertexShader, mFragmentShader); + if (mProgram == 0) { + return; + } + mvPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition"); + checkGlError("glGetAttribLocation"); + if (mvPositionHandle == -1) { + throw new RuntimeException("Could not get attrib location for vPosition"); + } + mvColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor"); + checkGlError("glGetAttribLocation"); + if (mvColorHandle == -1) { + throw new RuntimeException("Could not get attrib location for vColor"); + } + } + + private int loadShader(int shaderType, String source) { + int shader = GLES20.glCreateShader(shaderType); + if (shader != 0) { + GLES20.glShaderSource(shader, source); + GLES20.glCompileShader(shader); + int[] compiled = new int[1]; + GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); + if (compiled[0] == 0) { + Log.e(TAG, "Could not compile shader " + shaderType + ":"); + Log.e(TAG, GLES20.glGetShaderInfoLog(shader)); + GLES20.glDeleteShader(shader); + shader = 0; + } + } + return shader; + } + + private int createProgram(String vertexSource, String fragmentSource) { + int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource); + if (vertexShader == 0) { + return 0; + } + + int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource); + if (pixelShader == 0) { + return 0; + } + + int program = GLES20.glCreateProgram(); + if (program != 0) { + GLES20.glAttachShader(program, vertexShader); + checkGlError("glAttachShader vertexShader"); + GLES20.glAttachShader(program, pixelShader); + checkGlError("glAttachShader pixelShader"); + GLES20.glLinkProgram(program); + int[] linkStatus = new int[1]; + GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0); + if (linkStatus[0] != GLES20.GL_TRUE) { + Log.e(TAG, "Could not link program: "); + Log.e(TAG, GLES20.glGetProgramInfoLog(program)); + GLES20.glDeleteProgram(program); + program = 0; + } + } + return program; + } + + private void checkGlError(String op) { + int error; + while ((error = GLES20.glGetError()) != GLES20.GL_NO_ERROR) { + Log.e(TAG, op + ": glError " + error); + throw new RuntimeException(op + ": glError " + error); + } + } + + // X, Y, R G B A + private final float[] mTriangleVerticesData = { + -0.025f, 0.3f, 0.0f, 1.0f, 0.0f, 1.0f, + 0.0f , 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, + 0.025f, 0.3f, 1.0f, 1.0f, 255.0f, 1.0f + }; + + // Color cascade: + private final float[] mColors = { + 0.0f, 0.0f, 0.0f, 1.0f, + 0.5f, 0.0f, 0.0f, 1.0f, + 0.0f, 0.5f, 0.0f, 1.0f, + 0.5f, 0.5f, 0.0f, 1.0f, + + 0.0f, 0.0f, 0.5f, 1.0f, + 1.0f, 0.0f, 0.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 0.0f, 1.0f, 0.0f, 1.0f + }; + + private float[] mTriangleVerticesData2 = new float[mTriangleVerticesData.length]; + private FloatBuffer mTriangleVertices; + + private final String mVertexShader = "attribute vec4 aPosition;\n" + + "attribute vec4 aColor;\n" + + "varying vec4 vColor;\n" + + "void main() {\n" + + " gl_Position = aPosition;\n" + + " vColor = aColor;\n" + + "}\n"; + + private final String mFragmentShader = "precision mediump float;\n" + + "varying vec4 vColor;\n" + + "void main() {\n" + + " gl_FragColor = vColor;\n" + + "}\n"; + + private int mProgram; + private int mvPositionHandle; + private int mvColorHandle; + + } +} + diff --git a/opengl/tests/testViewport/Android.mk b/opengl/tests/testViewport/Android.mk new file mode 100644 index 000000000000..ab3780961a36 --- /dev/null +++ b/opengl/tests/testViewport/Android.mk @@ -0,0 +1,26 @@ +######################################################################### +# OpenGL ES JNI sample +# This makefile builds both an activity and a shared library. +######################################################################### +ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean + +TOP_LOCAL_PATH:= $(call my-dir) + +# Build activity + +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := TestViewport + +# Set a specific SDK version so we can run on Froyo. + +LOCAL_SDK_VERSION := 8 + +include $(BUILD_PACKAGE) + +endif # TARGET_SIMULATOR diff --git a/opengl/tests/testViewport/AndroidManifest.xml b/opengl/tests/testViewport/AndroidManifest.xml new file mode 100644 index 000000000000..90a9d2d14529 --- /dev/null +++ b/opengl/tests/testViewport/AndroidManifest.xml @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2009, 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. +*/ +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.test"> + <uses-sdk android:targetSdkVersion="8" android:minSdkVersion="8" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <application + android:label="@string/test_activity"> + <activity android:name="TestActivity" + android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:configChanges="orientation|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/opengl/tests/testViewport/README b/opengl/tests/testViewport/README new file mode 100644 index 000000000000..c06abc9405db --- /dev/null +++ b/opengl/tests/testViewport/README @@ -0,0 +1,28 @@ +Repro steps: + +build, install and run the attached test program TestViewport.apk + +Run on Sapphire with Froyo. + +The program clears the screen to blue, then draws a full screen white quad that +is alligned to the screen. +(Therefore the whole screen should appear to be white.) + + +Note that screen is all white. + +Rotate screen 90 degrees. + +Expected: screen is still all white. + +Actual: screen is blue with offset white rectangle. + +This bug only happens on Sapphire, it works correctly on Passion. + +What happens: + +I think the bug is that the gl.glViewport() call in onSurfaceChanged() is +being ignored by the OpenGL driver. + +NOTE: If a gl.glViewport call is added at the beginning of the onDrawFrame() +call (which means it is called before every draw), the program runs correctly. diff --git a/opengl/tests/testViewport/res/values/strings.xml b/opengl/tests/testViewport/res/values/strings.xml new file mode 100644 index 000000000000..f4b8bbbdd05a --- /dev/null +++ b/opengl/tests/testViewport/res/values/strings.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 2006, 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. +*/ +--> + +<!-- This file contains resource definitions for displayed strings, allowing + them to be changed based on the locale and options. --> + +<resources> + <!-- Simple strings. --> + <string name="test_activity">Test Viewport</string> + +</resources> + diff --git a/opengl/tests/testViewport/src/com/android/test/TestActivity.java b/opengl/tests/testViewport/src/com/android/test/TestActivity.java new file mode 100644 index 000000000000..cc7e4500d60a --- /dev/null +++ b/opengl/tests/testViewport/src/com/android/test/TestActivity.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2007 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. + */ + +package com.android.test; + +import android.app.Activity; +import android.os.Bundle; +import android.util.Log; + +public class TestActivity extends Activity { + private final static String TAG = "TestActivity"; + TestView mView; + + @Override + protected void onCreate(Bundle icicle) { + super.onCreate(icicle); + mView = new TestView(getApplication()); + mView.setFocusableInTouchMode(true); + setContentView(mView); + } + + @Override + protected void onPause() { + super.onPause(); + mView.onPause(); + } + + @Override + protected void onResume() { + super.onResume(); + mView.onResume(); + } +} diff --git a/opengl/tests/testViewport/src/com/android/test/TestView.java b/opengl/tests/testViewport/src/com/android/test/TestView.java new file mode 100644 index 000000000000..23cc37d1f132 --- /dev/null +++ b/opengl/tests/testViewport/src/com/android/test/TestView.java @@ -0,0 +1,262 @@ +/* + * Copyright (C) 2009 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. + */ + +package com.android.test; +/* + * Copyright (C) 2008 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. + */ + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.CharBuffer; +import java.nio.FloatBuffer; + +import android.content.Context; +import android.opengl.GLSurfaceView; +import android.util.AttributeSet; +import android.util.Log; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import javax.microedition.khronos.egl.EGL10; +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL; +import javax.microedition.khronos.opengles.GL10; +import javax.microedition.khronos.opengles.GL11; +/** + * An implementation of SurfaceView that uses the dedicated surface for + * displaying an OpenGL animation. This allows the animation to run in a + * separate thread, without requiring that it be driven by the update mechanism + * of the view hierarchy. + * + * The application-specific rendering code is delegated to a GLView.Renderer + * instance. + */ +class TestView extends GLSurfaceView { + TestView(Context context) { + super(context); + init(); + } + + public TestView(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + private void init() { + setRenderer(new Renderer()); + setRenderMode(RENDERMODE_WHEN_DIRTY); + } + + /** A grid is a topologically rectangular array of vertices. + * + * The vertex and index data are held in VBO objects because on most + * GPUs VBO objects are the fastest way of rendering static vertex + * and index data. + * + */ + + private static class Grid { + // Size of vertex data elements in bytes: + final static int FLOAT_SIZE = 4; + final static int CHAR_SIZE = 2; + + // Vertex structure: + // float x, y, z; + + final static int VERTEX_SIZE = 3 * FLOAT_SIZE; + + private int mVertexBufferObjectId; + private int mElementBufferObjectId; + + // These buffers are used to hold the vertex and index data while + // constructing the grid. Once createBufferObjects() is called + // the buffers are nulled out to save memory. + + private ByteBuffer mVertexByteBuffer; + private FloatBuffer mVertexBuffer; + private CharBuffer mIndexBuffer; + + private int mW; + private int mH; + private int mIndexCount; + + public Grid(int w, int h) { + if (w < 0 || w >= 65536) { + throw new IllegalArgumentException("w"); + } + if (h < 0 || h >= 65536) { + throw new IllegalArgumentException("h"); + } + if (w * h >= 65536) { + throw new IllegalArgumentException("w * h >= 65536"); + } + + mW = w; + mH = h; + int size = w * h; + + mVertexByteBuffer = ByteBuffer.allocateDirect(VERTEX_SIZE * size) + .order(ByteOrder.nativeOrder()); + mVertexBuffer = mVertexByteBuffer.asFloatBuffer(); + + int quadW = mW - 1; + int quadH = mH - 1; + int quadCount = quadW * quadH; + int indexCount = quadCount * 6; + mIndexCount = indexCount; + mIndexBuffer = ByteBuffer.allocateDirect(CHAR_SIZE * indexCount) + .order(ByteOrder.nativeOrder()).asCharBuffer(); + + /* + * Initialize triangle list mesh. + * + * [0]-----[ 1] ... + * | / | + * | / | + * | / | + * [w]-----[w+1] ... + * | | + * + */ + + { + int i = 0; + for (int y = 0; y < quadH; y++) { + for (int x = 0; x < quadW; x++) { + char a = (char) (y * mW + x); + char b = (char) (y * mW + x + 1); + char c = (char) ((y + 1) * mW + x); + char d = (char) ((y + 1) * mW + x + 1); + + mIndexBuffer.put(i++, a); + mIndexBuffer.put(i++, c); + mIndexBuffer.put(i++, b); + + mIndexBuffer.put(i++, b); + mIndexBuffer.put(i++, c); + mIndexBuffer.put(i++, d); + } + } + } + + } + + public void set(int i, int j, float x, float y, float z) { + if (i < 0 || i >= mW) { + throw new IllegalArgumentException("i"); + } + if (j < 0 || j >= mH) { + throw new IllegalArgumentException("j"); + } + + int index = mW * j + i; + + mVertexBuffer.position(index * VERTEX_SIZE / FLOAT_SIZE); + mVertexBuffer.put(x); + mVertexBuffer.put(y); + mVertexBuffer.put(z); + } + + public void createBufferObjects(GL gl) { + // Generate a the vertex and element buffer IDs + int[] vboIds = new int[2]; + GL11 gl11 = (GL11) gl; + gl11.glGenBuffers(2, vboIds, 0); + mVertexBufferObjectId = vboIds[0]; + mElementBufferObjectId = vboIds[1]; + + // Upload the vertex data + gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId); + mVertexByteBuffer.position(0); + gl11.glBufferData(GL11.GL_ARRAY_BUFFER, mVertexByteBuffer.capacity(), mVertexByteBuffer, GL11.GL_STATIC_DRAW); + + gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId); + mIndexBuffer.position(0); + gl11.glBufferData(GL11.GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer.capacity() * CHAR_SIZE, mIndexBuffer, GL11.GL_STATIC_DRAW); + + // We don't need the in-memory data any more + mVertexBuffer = null; + mVertexByteBuffer = null; + mIndexBuffer = null; + } + + public void draw(GL10 gl) { + GL11 gl11 = (GL11) gl; + + gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); + + gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, mVertexBufferObjectId); + gl11.glVertexPointer(3, GL10.GL_FLOAT, VERTEX_SIZE, 0); + + gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, mElementBufferObjectId); + gl11.glDrawElements(GL10.GL_TRIANGLES, mIndexCount, GL10.GL_UNSIGNED_SHORT, 0); + gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); + gl11.glBindBuffer(GL11.GL_ARRAY_BUFFER, 0); + gl11.glBindBuffer(GL11.GL_ELEMENT_ARRAY_BUFFER, 0); + } + } + + + private class Renderer implements GLSurfaceView.Renderer { + private static final String TAG = "Renderer"; + private Grid mGrid; + + public void onDrawFrame(GL10 gl) { + gl.glClearColor(0,0,1,1); + gl.glClear(GL10.GL_COLOR_BUFFER_BIT); + mGrid.draw(gl); + } + + public void onSurfaceChanged(GL10 gl, int width, int height) { + gl.glViewport(0, 0, width, height); + gl.glMatrixMode(GL11.GL_PROJECTION); + gl.glLoadIdentity(); + gl.glOrthof(0, width, height, 0, -1, 1); + gl.glMatrixMode(GL11.GL_MODELVIEW); + createGrid(gl, width, height); + } + + public void onSurfaceCreated(GL10 gl, EGLConfig config) { + } + + private void createGrid(GL10 gl, float w, float h) { + mGrid = new Grid(2, 2); + for (int j = 0; j < 2; j++) { + for (int i = 0; i < 2; i++) { + float x = w * i; + float y = h * j; + float z = 0.0f; + mGrid.set(i,j, x, y, z); + } + } + mGrid.createBufferObjects(gl); + } + } +} + |