pandora: add tv layer selection helper
[libpicofe.git] / gl.c
CommitLineData
b9801854 1#include <stdio.h>
2#include <stdlib.h>
3
4#include <EGL/egl.h>
5#include <GLES/gl.h>
0d645bc5 6#include "gl_platform.h"
b9801854 7#include "gl.h"
8
9static EGLDisplay edpy;
10static EGLSurface esfc;
11static EGLContext ectxt;
12
6fd09356 13/* for external flips */
14void *gl_es_display;
15void *gl_es_surface;
16
b9801854 17static int gl_have_error(const char *name)
18{
19 GLenum e = glGetError();
20 if (e != GL_NO_ERROR) {
21 fprintf(stderr, "GL error: %s %x\n", name, e);
22 return 1;
23 }
24 return 0;
25}
26
27static int gles_have_error(const char *name)
28{
29 EGLint e = eglGetError();
30 if (e != EGL_SUCCESS) {
31 fprintf(stderr, "%s %x\n", name, e);
32 return 1;
33 }
34 return 0;
35}
36
0d645bc5 37int gl_init(void *display, void *window, int *quirks)
b9801854 38{
39 EGLConfig ecfg = NULL;
40 GLuint texture_name = 0;
41 void *tmp_texture_mem = NULL;
42 EGLint num_config;
43 int retval = -1;
44 int ret;
45 EGLint attr[] =
46 {
47 EGL_NONE
48 };
49
0d645bc5 50 ret = gl_platform_init(&display, &window, quirks);
51 if (ret != 0) {
52 fprintf(stderr, "gl_platform_init failed with %d\n", ret);
53 goto out;
54 }
55
b9801854 56 tmp_texture_mem = calloc(1, 1024 * 512 * 2);
57 if (tmp_texture_mem == NULL) {
58 fprintf(stderr, "OOM\n");
59 goto out;
60 }
61
62 edpy = eglGetDisplay((EGLNativeDisplayType)display);
63 if (edpy == EGL_NO_DISPLAY) {
64 fprintf(stderr, "Failed to get EGL display\n");
65 goto out;
66 }
67
68 if (!eglInitialize(edpy, NULL, NULL)) {
69 fprintf(stderr, "Failed to initialize EGL\n");
70 goto out;
71 }
72
73 if (!eglChooseConfig(edpy, attr, &ecfg, 1, &num_config)) {
74 fprintf(stderr, "Failed to choose config (%x)\n", eglGetError());
75 goto out;
76 }
77
78 if (ecfg == NULL || num_config == 0) {
79 fprintf(stderr, "No EGL configs available\n");
80 goto out;
81 }
82
83 esfc = eglCreateWindowSurface(edpy, ecfg,
84 (EGLNativeWindowType)window, NULL);
85 if (esfc == EGL_NO_SURFACE) {
86 fprintf(stderr, "Unable to create EGL surface (%x)\n",
87 eglGetError());
88 goto out;
89 }
90
91 ectxt = eglCreateContext(edpy, ecfg, EGL_NO_CONTEXT, NULL);
92 if (ectxt == EGL_NO_CONTEXT) {
93 fprintf(stderr, "Unable to create EGL context (%x)\n",
94 eglGetError());
95 goto out;
96 }
97
98 eglMakeCurrent(edpy, esfc, esfc, ectxt);
99
100 glEnable(GL_TEXTURE_2D);
101
102 glGenTextures(1, &texture_name);
103
104 glBindTexture(GL_TEXTURE_2D, texture_name);
105
106 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 512, 0, GL_RGB,
107 GL_UNSIGNED_SHORT_5_6_5, tmp_texture_mem);
108 if (gl_have_error("glTexImage2D"))
109 goto out;
110
111 // no mipmaps
112 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
113 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
114
115 //glViewport(0, 0, 512, 512);
116 glLoadIdentity();
117 glFrontFace(GL_CW);
118 glEnable(GL_CULL_FACE);
119
120 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
121 glEnableClientState(GL_VERTEX_ARRAY);
122
123 if (gl_have_error("init"))
124 goto out;
125
6fd09356 126 gl_es_display = (void *)edpy;
127 gl_es_surface = (void *)esfc;
b9801854 128 retval = 0;
129out:
130 free(tmp_texture_mem);
131 return retval;
132}
133
134static float vertices[] = {
135 -1.0f, 1.0f, 0.0f, // 0 0 1
136 1.0f, 1.0f, 0.0f, // 1 ^
137 -1.0f, -1.0f, 0.0f, // 2 | 2 3
138 1.0f, -1.0f, 0.0f, // 3 +-->
139};
140
141static float texture[] = {
142 0.0f, 0.0f, // we flip this:
143 1.0f, 0.0f, // v^
144 0.0f, 1.0f, // | u
145 1.0f, 1.0f, // +-->
146};
147
148int gl_flip(const void *fb, int w, int h)
149{
150 static int old_w, old_h;
151
e54719ef 152 if (fb != NULL) {
153 if (w != old_w || h != old_h) {
154 float f_w = (float)w / 1024.0f;
155 float f_h = (float)h / 512.0f;
156 texture[1*2 + 0] = f_w;
157 texture[2*2 + 1] = f_h;
158 texture[3*2 + 0] = f_w;
159 texture[3*2 + 1] = f_h;
160 old_w = w;
161 old_h = h;
162 }
163
164 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h,
165 GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);
166 if (gl_have_error("glTexSubImage2D"))
167 return -1;
b9801854 168 }
169
b9801854 170 glVertexPointer(3, GL_FLOAT, 0, vertices);
171 glTexCoordPointer(2, GL_FLOAT, 0, texture);
172 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
173
174 if (gl_have_error("glDrawArrays"))
175 return -1;
176
177 eglSwapBuffers(edpy, esfc);
178 if (gles_have_error("eglSwapBuffers"))
179 return -1;
180
181 return 0;
182}
183
184void gl_finish(void)
185{
186 eglMakeCurrent(edpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
187 eglDestroyContext(edpy, ectxt);
188 ectxt = EGL_NO_CONTEXT;
189 eglDestroySurface(edpy, esfc);
190 esfc = EGL_NO_SURFACE;
191 eglTerminate(edpy);
192 edpy = EGL_NO_DISPLAY;
0d645bc5 193
6fd09356 194 gl_es_display = (void *)edpy;
195 gl_es_surface = (void *)esfc;
196
0d645bc5 197 gl_platform_finish();
b9801854 198}