1 /* 2 * Copyright (C) 2013 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 <stdarg.h> 20 21 #include <EGL/egl.h> 22 #include <GLES2/gl2.h> 23 24 #include <system/graphics.h> 25 26 #include "util.h" 27 28 void matrix_init_ortho(GLfloat *m, float w, float h) { 29 m[0] = 2.0 / w; 30 m[1] = 0.0; 31 m[2] = 0.0; 32 m[3] = -1.0; 33 m[4] = 0.0; 34 m[5] = 2.0 / h; 35 m[6] = 0.0; 36 m[7] = -1.0; 37 m[8] = 0.0; 38 m[9] = 0.0; 39 m[10] -1.0; 40 m[11] = 0.0; 41 m[12] = 0.0; 42 m[13] = 0.0; 43 m[14] = 0.0; 44 m[15] = 1.0; 45 } 46 47 static GLuint load_shader(GLenum shaderType, const char *src) { 48 GLint status = 0, len = 0; 49 GLuint shader; 50 51 if (!(shader = glCreateShader(shaderType))) 52 return 0; 53 54 glShaderSource(shader, 1, &src, NULL); 55 glCompileShader(shader); 56 glGetShaderiv(shader, GL_COMPILE_STATUS, &status); 57 58 if (status) 59 return shader; 60 61 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len); 62 if (len) { 63 char *msg = malloc(len); 64 if (msg) { 65 glGetShaderInfoLog(shader, len, NULL, msg); 66 msg[len-1] = 0; 67 fprintf(stderr, "error compiling shader:\n%s\n", msg); 68 free(msg); 69 } 70 } 71 glDeleteShader(shader); 72 return 0; 73 } 74 75 GLuint load_program(const char *vert_src, const char *frag_src) { 76 GLuint vert, frag, prog; 77 GLint status = 0, len = 0; 78 79 if (!(vert = load_shader(GL_VERTEX_SHADER, vert_src))) 80 return 0; 81 if (!(frag = load_shader(GL_FRAGMENT_SHADER, frag_src))) 82 goto fail_frag; 83 if (!(prog = glCreateProgram())) 84 goto fail_prog; 85 86 glAttachShader(prog, vert); 87 glAttachShader(prog, frag); 88 glLinkProgram(prog); 89 90 glGetProgramiv(prog, GL_LINK_STATUS, &status); 91 if (status) 92 return prog; 93 94 glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &len); 95 if (len) { 96 char *buf = (char*) malloc(len); 97 if (buf) { 98 glGetProgramInfoLog(prog, len, NULL, buf); 99 buf[len-1] = 0; 100 fprintf(stderr, "error linking program:\n%s\n", buf); 101 free(buf); 102 } 103 } 104 glDeleteProgram(prog); 105 fail_prog: 106 glDeleteShader(frag); 107 fail_frag: 108 glDeleteShader(vert); 109 return 0; 110 } 111 112 int select_config_for_window(EGLDisplay dpy, EGLint *attr, 113 unsigned format, EGLConfig *config) { 114 EGLint R,G,B,A,r,g,b,a; 115 EGLint i, n, max; 116 EGLConfig *cfg; 117 118 switch (format) { 119 case HAL_PIXEL_FORMAT_RGBA_8888: 120 case HAL_PIXEL_FORMAT_BGRA_8888: 121 R = G = B = A = 8; 122 break; 123 case HAL_PIXEL_FORMAT_RGB_565: 124 R = 5; G = 6; B = 5; A = 0; 125 break; 126 default: 127 fprintf(stderr, "unknown fb pixel format %d\n", format); 128 return -1; 129 } 130 131 if (eglGetConfigs(dpy, NULL, 0, &max) == EGL_FALSE) { 132 fprintf(stderr, "no EGL configurations available?!\n"); 133 return -1; 134 } 135 136 cfg = (EGLConfig*) malloc(sizeof(EGLConfig) * max); 137 if (!cfg) 138 return -1; 139 140 if (eglChooseConfig(dpy, attr, cfg, max, &n) == EGL_FALSE) { 141 fprintf(stderr, "eglChooseConfig failed\n"); 142 return -1; 143 } 144 145 for (i = 0; i < n; i++) { 146 EGLint r,g,b,a; 147 eglGetConfigAttrib(dpy, cfg[i], EGL_RED_SIZE, &r); 148 eglGetConfigAttrib(dpy, cfg[i], EGL_GREEN_SIZE, &g); 149 eglGetConfigAttrib(dpy, cfg[i], EGL_BLUE_SIZE, &b); 150 eglGetConfigAttrib(dpy, cfg[i], EGL_ALPHA_SIZE, &a); 151 if (r == R && g == G && b == B && a == A) { 152 *config = cfg[i]; 153 free(cfg); 154 return 0; 155 } 156 } 157 158 fprintf(stderr, "cannot find matching config\n"); 159 free(cfg); 160 return -1; 161 } 162 163 static struct CNativeWindow *_cnw = 0; 164 165 int egl_create(EGLDisplay *_display, EGLSurface *_surface, int *_w, int *_h) { 166 EGLBoolean res; 167 EGLConfig config = { 0 }; 168 EGLint context_attrs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; 169 EGLint config_attrs[] = { 170 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 171 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 172 EGL_NONE }; 173 EGLint major, minor; 174 EGLContext context; 175 EGLSurface surface; 176 EGLint w, h; 177 EGLDisplay display; 178 EGLNativeWindowType window; 179 unsigned width, height, format; 180 struct CNativeWindow *cnw; 181 182 display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 183 if (display == EGL_NO_DISPLAY) 184 return -1; 185 186 if (!(res = eglInitialize(display, &major, &minor))) 187 return -1; 188 189 fprintf(stderr, "egl version: %d.%d\n", major, minor); 190 191 if ((cnw = cnw_create()) == 0) 192 return -1; 193 194 cnw_info(cnw, &width, &height, &format); 195 window = (EGLNativeWindowType) cnw; 196 197 if ((res = select_config_for_window(display, config_attrs, format, &config))) 198 goto fail; 199 200 surface = eglCreateWindowSurface(display, config, window, NULL); 201 if (surface == EGL_NO_SURFACE) 202 goto fail; 203 204 context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attrs); 205 if (context == EGL_NO_CONTEXT) 206 goto fail; 207 208 if (!(res = eglMakeCurrent(display, surface, surface, context))) 209 goto fail; 210 211 eglQuerySurface(display, surface, EGL_WIDTH, &w); 212 eglQuerySurface(display, surface, EGL_HEIGHT, &h); 213 214 fprintf(stderr, "window: %d x %d\n", w, h); 215 216 *_display = display; 217 *_surface = surface; 218 *_w = w; 219 *_h = h; 220 221 _cnw = cnw; 222 return 0; 223 224 fail: 225 cnw_destroy(cnw); 226 return -1; 227 } 228 229 void egl_destroy(EGLDisplay display, EGLSurface surface) { 230 if (_cnw) { 231 eglDestroySurface(display, surface); 232 eglTerminate(display); 233 cnw_destroy(_cnw); 234 _cnw = 0; 235 } 236 } 237