gl2_perf.cpp revision e448dd1a4f01da5d9d0ab813c2d5939bcba85ccb
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <time.h>
20#include <sched.h>
21#include <sys/resource.h>
22
23#include <EGL/egl.h>
24#include <GLES2/gl2.h>
25#include <GLES2/gl2ext.h>
26
27#include <utils/Timers.h>
28
29#include <ui/FramebufferNativeWindow.h>
30#include <ui/EGLUtils.h>
31
32using namespace android;
33
34static void printGLString(const char *name, GLenum s) {
35    // fprintf(stderr, "printGLString %s, %d\n", name, s);
36    const char *v = (const char *) glGetString(s);
37    // int error = glGetError();
38    // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
39    //        (unsigned int) v);
40    // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
41    //    fprintf(stderr, "GL %s = %s\n", name, v);
42    // else
43    //    fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
44    fprintf(stderr, "GL %s = %s\n", name, v);
45}
46
47static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
48    if (returnVal != EGL_TRUE) {
49        fprintf(stderr, "%s() returned %d\n", op, returnVal);
50    }
51
52    for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
53            = eglGetError()) {
54        fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
55                error);
56    }
57}
58
59static void checkGlError(const char* op) {
60    for (GLint error = glGetError(); error; error
61            = glGetError()) {
62        fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
63    }
64}
65
66void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
67
68#define X(VAL) {VAL, #VAL}
69    struct {EGLint attribute; const char* name;} names[] = {
70    X(EGL_BUFFER_SIZE),
71    X(EGL_ALPHA_SIZE),
72    X(EGL_BLUE_SIZE),
73    X(EGL_GREEN_SIZE),
74    X(EGL_RED_SIZE),
75    X(EGL_DEPTH_SIZE),
76    X(EGL_STENCIL_SIZE),
77    X(EGL_CONFIG_CAVEAT),
78    X(EGL_CONFIG_ID),
79    X(EGL_LEVEL),
80    X(EGL_MAX_PBUFFER_HEIGHT),
81    X(EGL_MAX_PBUFFER_PIXELS),
82    X(EGL_MAX_PBUFFER_WIDTH),
83    X(EGL_NATIVE_RENDERABLE),
84    X(EGL_NATIVE_VISUAL_ID),
85    X(EGL_NATIVE_VISUAL_TYPE),
86    X(EGL_SAMPLES),
87    X(EGL_SAMPLE_BUFFERS),
88    X(EGL_SURFACE_TYPE),
89    X(EGL_TRANSPARENT_TYPE),
90    X(EGL_TRANSPARENT_RED_VALUE),
91    X(EGL_TRANSPARENT_GREEN_VALUE),
92    X(EGL_TRANSPARENT_BLUE_VALUE),
93    X(EGL_BIND_TO_TEXTURE_RGB),
94    X(EGL_BIND_TO_TEXTURE_RGBA),
95    X(EGL_MIN_SWAP_INTERVAL),
96    X(EGL_MAX_SWAP_INTERVAL),
97    X(EGL_LUMINANCE_SIZE),
98    X(EGL_ALPHA_MASK_SIZE),
99    X(EGL_COLOR_BUFFER_TYPE),
100    X(EGL_RENDERABLE_TYPE),
101    X(EGL_CONFORMANT),
102   };
103#undef X
104
105    for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
106        EGLint value = -1;
107        EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
108        EGLint error = eglGetError();
109        if (returnVal && error == EGL_SUCCESS) {
110            printf(" %s: ", names[j].name);
111            printf("%d (0x%x)", value, value);
112        }
113    }
114    printf("\n");
115}
116
117int printEGLConfigurations(EGLDisplay dpy) {
118    EGLint numConfig = 0;
119    EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
120    checkEglError("eglGetConfigs", returnVal);
121    if (!returnVal) {
122        return false;
123    }
124
125    printf("Number of EGL configuration: %d\n", numConfig);
126
127    EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
128    if (! configs) {
129        printf("Could not allocate configs.\n");
130        return false;
131    }
132
133    returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
134    checkEglError("eglGetConfigs", returnVal);
135    if (!returnVal) {
136        free(configs);
137        return false;
138    }
139
140    for(int i = 0; i < numConfig; i++) {
141        printf("Configuration %d\n", i);
142        printEGLConfiguration(dpy, configs[i]);
143    }
144
145    free(configs);
146    return true;
147}
148
149bool doTest(uint32_t w, uint32_t h);
150
151static EGLDisplay dpy;
152static EGLSurface surface;
153
154int main(int argc, char** argv) {
155    EGLBoolean returnValue;
156    EGLConfig myConfig = {0};
157
158    EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
159    EGLint s_configAttribs[] = {
160            EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
161            EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
162            EGL_NONE };
163    EGLint majorVersion;
164    EGLint minorVersion;
165    EGLContext context;
166    EGLint w, h;
167
168
169    checkEglError("<init>");
170    dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
171    checkEglError("eglGetDisplay");
172    if (dpy == EGL_NO_DISPLAY) {
173        printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
174        return 0;
175    }
176
177    returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
178    checkEglError("eglInitialize", returnValue);
179    fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
180    if (returnValue != EGL_TRUE) {
181        printf("eglInitialize failed\n");
182        return 0;
183    }
184
185    EGLNativeWindowType window = android_createDisplaySurface();
186    returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
187    if (returnValue) {
188        printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
189        return 0;
190    }
191
192    checkEglError("EGLUtils::selectConfigForNativeWindow");
193
194    printf("Chose this configuration:\n");
195    printEGLConfiguration(dpy, myConfig);
196
197    surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
198    checkEglError("eglCreateWindowSurface");
199    if (surface == EGL_NO_SURFACE) {
200        printf("gelCreateWindowSurface failed.\n");
201        return 0;
202    }
203
204    context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
205    checkEglError("eglCreateContext");
206    if (context == EGL_NO_CONTEXT) {
207        printf("eglCreateContext failed\n");
208        return 0;
209    }
210    returnValue = eglMakeCurrent(dpy, surface, surface, context);
211    checkEglError("eglMakeCurrent", returnValue);
212    if (returnValue != EGL_TRUE) {
213        return 0;
214    }
215    eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
216    checkEglError("eglQuerySurface");
217    eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
218    checkEglError("eglQuerySurface");
219    GLint dim = w < h ? w : h;
220
221    fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
222
223    printGLString("Version", GL_VERSION);
224    printGLString("Vendor", GL_VENDOR);
225    printGLString("Renderer", GL_RENDERER);
226    printGLString("Extensions", GL_EXTENSIONS);
227
228    glViewport(0, 0, w, h);
229
230    for (;;) {
231        doTest(w, h);
232        eglSwapBuffers(dpy, surface);
233        checkEglError("eglSwapBuffers");
234    }
235
236    return 0;
237}
238
239void ptSwap() {
240    eglSwapBuffers(dpy, surface);
241}
242
243