2 * Copyright (C) 2007 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <sys/resource.h>
24 #include <GLES2/gl2.h>
25 #include <GLES2/gl2ext.h>
27 #include <utils/Timers.h>
29 #include <WindowSurface.h>
32 using namespace android;
34 static 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,
40 // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
41 // fprintf(stderr, "GL %s = %s\n", name, v);
43 // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
44 fprintf(stderr, "GL %s = %s\n", name, v);
47 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
48 if (returnVal != EGL_TRUE) {
49 fprintf(stderr, "%s() returned %d\n", op, returnVal);
52 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
54 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
59 static void checkGlError(const char* op) {
60 for (GLint error = glGetError(); error; error
62 fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
66 static const char gVertexShader[] = "attribute vec4 vPosition;\n"
68 " gl_Position = vPosition;\n"
71 static const char gFragmentShader[] = "precision mediump float;\n"
73 " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
76 GLuint loadShader(GLenum shaderType, const char* pSource) {
77 GLuint shader = glCreateShader(shaderType);
79 glShaderSource(shader, 1, &pSource, NULL);
80 glCompileShader(shader);
82 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
85 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
87 char* buf = (char*) malloc(infoLen);
89 glGetShaderInfoLog(shader, infoLen, NULL, buf);
90 fprintf(stderr, "Could not compile shader %d:\n%s\n",
94 glDeleteShader(shader);
102 GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
103 GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
108 GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
113 GLuint program = glCreateProgram();
115 glAttachShader(program, vertexShader);
116 checkGlError("glAttachShader");
117 glAttachShader(program, pixelShader);
118 checkGlError("glAttachShader");
119 glLinkProgram(program);
120 GLint linkStatus = GL_FALSE;
121 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
122 if (linkStatus != GL_TRUE) {
124 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
126 char* buf = (char*) malloc(bufLength);
128 glGetProgramInfoLog(program, bufLength, NULL, buf);
129 fprintf(stderr, "Could not link program:\n%s\n", buf);
133 glDeleteProgram(program);
141 GLuint gvPositionHandle;
143 bool setupGraphics(int w, int h) {
144 gProgram = createProgram(gVertexShader, gFragmentShader);
148 gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
149 checkGlError("glGetAttribLocation");
150 fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
153 glViewport(0, 0, w, h);
154 checkGlError("glViewport");
158 const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
162 glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
163 checkGlError("glClearColor");
164 glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
165 checkGlError("glClear");
167 glUseProgram(gProgram);
168 checkGlError("glUseProgram");
170 glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
171 checkGlError("glVertexAttribPointer");
172 glEnableVertexAttribArray(gvPositionHandle);
173 checkGlError("glEnableVertexAttribArray");
174 glDrawArrays(GL_TRIANGLES, 0, 3);
175 checkGlError("glDrawArrays");
178 void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
180 #define X(VAL) {VAL, #VAL}
181 struct {EGLint attribute; const char* name;} names[] = {
189 X(EGL_CONFIG_CAVEAT),
192 X(EGL_MAX_PBUFFER_HEIGHT),
193 X(EGL_MAX_PBUFFER_PIXELS),
194 X(EGL_MAX_PBUFFER_WIDTH),
195 X(EGL_NATIVE_RENDERABLE),
196 X(EGL_NATIVE_VISUAL_ID),
197 X(EGL_NATIVE_VISUAL_TYPE),
199 X(EGL_SAMPLE_BUFFERS),
201 X(EGL_TRANSPARENT_TYPE),
202 X(EGL_TRANSPARENT_RED_VALUE),
203 X(EGL_TRANSPARENT_GREEN_VALUE),
204 X(EGL_TRANSPARENT_BLUE_VALUE),
205 X(EGL_BIND_TO_TEXTURE_RGB),
206 X(EGL_BIND_TO_TEXTURE_RGBA),
207 X(EGL_MIN_SWAP_INTERVAL),
208 X(EGL_MAX_SWAP_INTERVAL),
209 X(EGL_LUMINANCE_SIZE),
210 X(EGL_ALPHA_MASK_SIZE),
211 X(EGL_COLOR_BUFFER_TYPE),
212 X(EGL_RENDERABLE_TYPE),
217 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
219 EGLint returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
220 EGLint error = eglGetError();
221 if (returnVal && error == EGL_SUCCESS) {
222 printf(" %s: ", names[j].name);
223 printf("%d (0x%x)", value, value);
229 int printEGLConfigurations(EGLDisplay dpy) {
230 EGLint numConfig = 0;
231 EGLint returnVal = eglGetConfigs(dpy, NULL, 0, &numConfig);
232 checkEglError("eglGetConfigs", returnVal);
237 printf("Number of EGL configuration: %d\n", numConfig);
239 EGLConfig* configs = (EGLConfig*) malloc(sizeof(EGLConfig) * numConfig);
241 printf("Could not allocate configs.\n");
245 returnVal = eglGetConfigs(dpy, configs, numConfig, &numConfig);
246 checkEglError("eglGetConfigs", returnVal);
252 for(int i = 0; i < numConfig; i++) {
253 printf("Configuration %d\n", i);
254 printEGLConfiguration(dpy, configs[i]);
261 int main(int argc, char** argv) {
262 EGLBoolean returnValue;
263 EGLConfig myConfig = {0};
265 EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
266 EGLint s_configAttribs[] = {
267 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
268 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
278 checkEglError("<init>");
279 dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
280 checkEglError("eglGetDisplay");
281 if (dpy == EGL_NO_DISPLAY) {
282 printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
286 returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
287 checkEglError("eglInitialize", returnValue);
288 fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
289 if (returnValue != EGL_TRUE) {
290 printf("eglInitialize failed\n");
294 if (!printEGLConfigurations(dpy)) {
295 printf("printEGLConfigurations failed\n");
299 checkEglError("printEGLConfigurations");
301 WindowSurface windowSurface;
302 EGLNativeWindowType window = windowSurface.getSurface();
303 returnValue = EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &myConfig);
305 printf("EGLUtils::selectConfigForNativeWindow() returned %d", returnValue);
309 checkEglError("EGLUtils::selectConfigForNativeWindow");
311 printf("Chose this configuration:\n");
312 printEGLConfiguration(dpy, myConfig);
314 surface = eglCreateWindowSurface(dpy, myConfig, window, NULL);
315 checkEglError("eglCreateWindowSurface");
316 if (surface == EGL_NO_SURFACE) {
317 printf("gelCreateWindowSurface failed.\n");
321 context = eglCreateContext(dpy, myConfig, EGL_NO_CONTEXT, context_attribs);
322 checkEglError("eglCreateContext");
323 if (context == EGL_NO_CONTEXT) {
324 printf("eglCreateContext failed\n");
327 returnValue = eglMakeCurrent(dpy, surface, surface, context);
328 checkEglError("eglMakeCurrent", returnValue);
329 if (returnValue != EGL_TRUE) {
332 eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
333 checkEglError("eglQuerySurface");
334 eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
335 checkEglError("eglQuerySurface");
336 GLint dim = w < h ? w : h;
338 fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
340 printGLString("Version", GL_VERSION);
341 printGLString("Vendor", GL_VENDOR);
342 printGLString("Renderer", GL_RENDERER);
343 printGLString("Extensions", GL_EXTENSIONS);
345 if(!setupGraphics(w, h)) {
346 fprintf(stderr, "Could not set up graphics.\n");
352 eglSwapBuffers(dpy, surface);
353 checkEglError("eglSwapBuffers");