blob: 63bf7cce4151153478ac01c1ac0caab0202ecd17 [file] [log] [blame]
Jason Sams803626f2011-04-06 17:52:23 -07001/*
2 * Copyright (C) 2011 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 <ui/FramebufferNativeWindow.h>
18#include <ui/PixelFormat.h>
Mathias Agopianaf01feaf2012-02-24 18:25:41 -080019
20#include <system/window.h>
Jason Sams803626f2011-04-06 17:52:23 -070021
22#include <sys/types.h>
23#include <sys/resource.h>
24#include <sched.h>
25
26#include <cutils/properties.h>
27
28#include <GLES/gl.h>
29#include <GLES/glext.h>
30#include <GLES2/gl2.h>
31#include <GLES2/gl2ext.h>
32
Jason Sams803626f2011-04-06 17:52:23 -070033#include <string.h>
34
Jason Sams803626f2011-04-06 17:52:23 -070035#include "rsdCore.h"
36#include "rsdGL.h"
37
38#include <malloc.h>
39#include "rsContext.h"
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070040#include "rsdShaderCache.h"
41#include "rsdVertexArray.h"
Alex Sakhartchouk8650c322011-06-16 11:05:13 -070042#include "rsdFrameBufferObj.h"
Jason Sams803626f2011-04-06 17:52:23 -070043
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -080044#include <gui/SurfaceTextureClient.h>
45
Jason Sams803626f2011-04-06 17:52:23 -070046using namespace android;
47using namespace android::renderscript;
48
49static int32_t gGLContextCount = 0;
50
51static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
Mathias Agopiancc0eaa62012-02-24 16:42:46 -080052 struct EGLUtils {
53 static const char *strerror(EGLint err) {
54 switch (err){
55 case EGL_SUCCESS: return "EGL_SUCCESS";
56 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
57 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
58 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
59 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
60 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
61 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
62 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
63 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
64 case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
65 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
66 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
67 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
68 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
69 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
70 default: return "UNKNOWN";
71 }
72 }
73 };
74
Jason Sams803626f2011-04-06 17:52:23 -070075 if (returnVal != EGL_TRUE) {
76 fprintf(stderr, "%s() returned %d\n", op, returnVal);
77 }
78
79 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
80 = eglGetError()) {
81 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
82 error);
83 }
84}
85
86static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
87
88#define X(VAL) {VAL, #VAL}
89 struct {EGLint attribute; const char* name;} names[] = {
90 X(EGL_BUFFER_SIZE),
91 X(EGL_ALPHA_SIZE),
92 X(EGL_BLUE_SIZE),
93 X(EGL_GREEN_SIZE),
94 X(EGL_RED_SIZE),
95 X(EGL_DEPTH_SIZE),
96 X(EGL_STENCIL_SIZE),
97 X(EGL_CONFIG_CAVEAT),
98 X(EGL_CONFIG_ID),
99 X(EGL_LEVEL),
100 X(EGL_MAX_PBUFFER_HEIGHT),
101 X(EGL_MAX_PBUFFER_PIXELS),
102 X(EGL_MAX_PBUFFER_WIDTH),
103 X(EGL_NATIVE_RENDERABLE),
104 X(EGL_NATIVE_VISUAL_ID),
105 X(EGL_NATIVE_VISUAL_TYPE),
106 X(EGL_SAMPLES),
107 X(EGL_SAMPLE_BUFFERS),
108 X(EGL_SURFACE_TYPE),
109 X(EGL_TRANSPARENT_TYPE),
110 X(EGL_TRANSPARENT_RED_VALUE),
111 X(EGL_TRANSPARENT_GREEN_VALUE),
112 X(EGL_TRANSPARENT_BLUE_VALUE),
113 X(EGL_BIND_TO_TEXTURE_RGB),
114 X(EGL_BIND_TO_TEXTURE_RGBA),
115 X(EGL_MIN_SWAP_INTERVAL),
116 X(EGL_MAX_SWAP_INTERVAL),
117 X(EGL_LUMINANCE_SIZE),
118 X(EGL_ALPHA_MASK_SIZE),
119 X(EGL_COLOR_BUFFER_TYPE),
120 X(EGL_RENDERABLE_TYPE),
121 X(EGL_CONFORMANT),
122 };
123#undef X
124
125 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
126 EGLint value = -1;
Mathias Agopian18617862011-07-06 16:35:30 -0700127 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
128 if (returnVal) {
Steve Block71f2cf12011-10-20 11:56:00 +0100129 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
Jason Sams803626f2011-04-06 17:52:23 -0700130 }
131 }
132}
133
Jason Samsfcf72312011-04-20 15:09:01 -0700134static void DumpDebug(RsdHal *dc) {
Steve Block3762c312012-01-06 19:20:56 +0000135 ALOGE(" EGL ver %i %i", dc->gl.egl.majorVersion, dc->gl.egl.minorVersion);
136 ALOGE(" EGL context %p surface %p, Display=%p", dc->gl.egl.context, dc->gl.egl.surface,
Jason Sams803626f2011-04-06 17:52:23 -0700137 dc->gl.egl.display);
Steve Block3762c312012-01-06 19:20:56 +0000138 ALOGE(" GL vendor: %s", dc->gl.gl.vendor);
139 ALOGE(" GL renderer: %s", dc->gl.gl.renderer);
140 ALOGE(" GL Version: %s", dc->gl.gl.version);
141 ALOGE(" GL Extensions: %s", dc->gl.gl.extensions);
142 ALOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
Jason Sams803626f2011-04-06 17:52:23 -0700143
Steve Block71f2cf12011-10-20 11:56:00 +0100144 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
Jason Sams803626f2011-04-06 17:52:23 -0700145 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
Steve Block71f2cf12011-10-20 11:56:00 +0100146 ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
147 ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
Jason Sams803626f2011-04-06 17:52:23 -0700148 dc->gl.gl.maxFragmentUniformVectors);
Steve Block71f2cf12011-10-20 11:56:00 +0100149 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
Jason Sams803626f2011-04-06 17:52:23 -0700150}
151
152void rsdGLShutdown(const Context *rsc) {
Jason Samsfcf72312011-04-20 15:09:01 -0700153 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams803626f2011-04-06 17:52:23 -0700154
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700155 dc->gl.shaderCache->cleanupAll();
156 delete dc->gl.shaderCache;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700157 delete dc->gl.vertexArrayState;
158
Jason Sams803626f2011-04-06 17:52:23 -0700159 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700160 RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
161 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
162 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
Jason Sams803626f2011-04-06 17:52:23 -0700163 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700164 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams803626f2011-04-06 17:52:23 -0700165 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700166 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
Jason Sams803626f2011-04-06 17:52:23 -0700167 checkEglError("eglDestroyContext");
168 }
169
170 gGLContextCount--;
171 if (!gGLContextCount) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700172 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
Jason Sams803626f2011-04-06 17:52:23 -0700173 }
174}
175
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800176void getConfigData(const Context *rsc,
177 EGLint *configAttribs, size_t configAttribsLen,
178 uint32_t numSamples) {
179 memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
Jason Sams803626f2011-04-06 17:52:23 -0700180
Jason Sams803626f2011-04-06 17:52:23 -0700181 EGLint *configAttribsPtr = configAttribs;
Jason Sams803626f2011-04-06 17:52:23 -0700182
183 configAttribsPtr[0] = EGL_SURFACE_TYPE;
184 configAttribsPtr[1] = EGL_WINDOW_BIT;
185 configAttribsPtr += 2;
186
187 configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
188 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
189 configAttribsPtr += 2;
190
Mathias Agopian18617862011-07-06 16:35:30 -0700191 configAttribsPtr[0] = EGL_RED_SIZE;
192 configAttribsPtr[1] = 8;
193 configAttribsPtr += 2;
194
195 configAttribsPtr[0] = EGL_GREEN_SIZE;
196 configAttribsPtr[1] = 8;
197 configAttribsPtr += 2;
198
199 configAttribsPtr[0] = EGL_BLUE_SIZE;
200 configAttribsPtr[1] = 8;
201 configAttribsPtr += 2;
202
203 if (rsc->mUserSurfaceConfig.alphaMin > 0) {
204 configAttribsPtr[0] = EGL_ALPHA_SIZE;
205 configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
206 configAttribsPtr += 2;
207 }
208
Jason Sams803626f2011-04-06 17:52:23 -0700209 if (rsc->mUserSurfaceConfig.depthMin > 0) {
210 configAttribsPtr[0] = EGL_DEPTH_SIZE;
211 configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
212 configAttribsPtr += 2;
213 }
214
215 if (rsc->mDev->mForceSW) {
216 configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
217 configAttribsPtr[1] = EGL_SLOW_CONFIG;
218 configAttribsPtr += 2;
219 }
220
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800221 if (numSamples > 1) {
222 configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
223 configAttribsPtr[1] = 1;
224 configAttribsPtr[2] = EGL_SAMPLES;
225 configAttribsPtr[3] = numSamples;
226 configAttribsPtr += 4;
227 }
228
Jason Sams803626f2011-04-06 17:52:23 -0700229 configAttribsPtr[0] = EGL_NONE;
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800230 rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
231}
232
233bool rsdGLInit(const Context *rsc) {
234 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
235
236 dc->gl.egl.numConfigs = -1;
237
238 EGLint configAttribs[128];
239 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
Jason Sams803626f2011-04-06 17:52:23 -0700240
Steve Block71f2cf12011-10-20 11:56:00 +0100241 ALOGV("%p initEGL start", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700242 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700243 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
244 checkEglError("eglGetDisplay");
245
Jason Sams5316b9e2011-09-13 15:41:01 -0700246 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
247 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
Jason Sams803626f2011-04-06 17:52:23 -0700248 checkEglError("eglInitialize");
249
Mathias Agopian18617862011-07-06 16:35:30 -0700250 EGLBoolean ret;
251
252 EGLint numConfigs = -1, n = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700253 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800254
255 // Try minding a multisample config that matches the user request
256 uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
257 uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
258 for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
259 getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
260 ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
261 checkEglError("eglGetConfigs", ret);
262 if (numConfigs > 0) {
263 break;
264 }
265 }
Mathias Agopian18617862011-07-06 16:35:30 -0700266
Jason Sams4c2e4c82012-02-07 15:32:08 -0800267 eglSwapInterval(dc->gl.egl.display, 0);
268
Mathias Agopian18617862011-07-06 16:35:30 -0700269 if (numConfigs) {
270 EGLConfig* const configs = new EGLConfig[numConfigs];
271
Jason Sams5316b9e2011-09-13 15:41:01 -0700272 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian18617862011-07-06 16:35:30 -0700273 ret = eglChooseConfig(dc->gl.egl.display,
274 configAttribs, configs, numConfigs, &n);
275 if (!ret || !n) {
276 checkEglError("eglChooseConfig", ret);
Steve Block3762c312012-01-06 19:20:56 +0000277 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian18617862011-07-06 16:35:30 -0700278 }
279
280 // The first config is guaranteed to over-satisfy the constraints
281 dc->gl.egl.config = configs[0];
282
283 // go through the list and skip configs that over-satisfy our needs
284 for (int i=0 ; i<n ; i++) {
285 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
286 EGLint alphaSize;
287 eglGetConfigAttrib(dc->gl.egl.display,
288 configs[i], EGL_ALPHA_SIZE, &alphaSize);
289 if (alphaSize > 0) {
290 continue;
291 }
292 }
293
294 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
295 EGLint depthSize;
296 eglGetConfigAttrib(dc->gl.egl.display,
297 configs[i], EGL_DEPTH_SIZE, &depthSize);
298 if (depthSize > 0) {
299 continue;
300 }
301 }
302
303 // Found one!
304 dc->gl.egl.config = configs[i];
305 break;
306 }
307
308 delete [] configs;
Jason Sams803626f2011-04-06 17:52:23 -0700309 }
310
Jason Sams803626f2011-04-06 17:52:23 -0700311 //if (props.mLogVisual) {
Stephen Hines9c35d792011-04-20 17:08:14 -0700312 if (0) {
Jason Sams803626f2011-04-06 17:52:23 -0700313 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9c35d792011-04-20 17:08:14 -0700314 }
Jason Sams803626f2011-04-06 17:52:23 -0700315 //}
316
Jason Sams5316b9e2011-09-13 15:41:01 -0700317 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700318 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
319 EGL_NO_CONTEXT, context_attribs2);
320 checkEglError("eglCreateContext");
321 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
Steve Block3762c312012-01-06 19:20:56 +0000322 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700323 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700324 return false;
325 }
326 gGLContextCount++;
327
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800328 sp<SurfaceTexture> st(new SurfaceTexture(123));
329 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st));
330 dc->gl.egl.surfaceDefault = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
331 static_cast<ANativeWindow*>(stc.get()),
332 NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700333
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800334 checkEglError("eglCreateWindowSurface");
Jason Sams803626f2011-04-06 17:52:23 -0700335 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800336 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams803626f2011-04-06 17:52:23 -0700337 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700338 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700339 return false;
340 }
341
Jason Sams5316b9e2011-09-13 15:41:01 -0700342 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian18617862011-07-06 16:35:30 -0700343 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
344 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
Jason Sams803626f2011-04-06 17:52:23 -0700345 if (ret == EGL_FALSE) {
Steve Block3762c312012-01-06 19:20:56 +0000346 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams803626f2011-04-06 17:52:23 -0700347 checkEglError("eglMakeCurrent", ret);
348 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700349 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700350 return false;
351 }
352
353 dc->gl.gl.version = glGetString(GL_VERSION);
354 dc->gl.gl.vendor = glGetString(GL_VENDOR);
355 dc->gl.gl.renderer = glGetString(GL_RENDERER);
356 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
357
Steve Block71f2cf12011-10-20 11:56:00 +0100358 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
359 //ALOGV("GL Version %s", mGL.mVersion);
360 //ALOGV("GL Vendor %s", mGL.mVendor);
361 //ALOGV("GL Renderer %s", mGL.mRenderer);
362 //ALOGV("GL Extensions %s", mGL.mExtensions);
Jason Sams803626f2011-04-06 17:52:23 -0700363
364 const char *verptr = NULL;
365 if (strlen((const char *)dc->gl.gl.version) > 9) {
366 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
367 verptr = (const char *)dc->gl.gl.version + 12;
368 }
369 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
370 verptr = (const char *)dc->gl.gl.version + 9;
371 }
372 }
373
374 if (!verptr) {
Steve Block3762c312012-01-06 19:20:56 +0000375 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams803626f2011-04-06 17:52:23 -0700376 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700377 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700378 return false;
379 } else {
380 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
381 }
382
383 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
384 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
385 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
386
387 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
388 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
389
390 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
391 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
392
393 dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
394 "GL_OES_texture_npot");
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800395 dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams803626f2011-04-06 17:52:23 -0700396 "GL_IMG_texture_npot");
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800397 dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams803626f2011-04-06 17:52:23 -0700398 "GL_NV_texture_npot_2D_mipmap");
399 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
400 bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
401 "GL_EXT_texture_filter_anisotropic");
402 if (hasAniso) {
403 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
404 }
405
Stephen Hines9c35d792011-04-20 17:08:14 -0700406 if (0) {
407 DumpDebug(dc);
408 }
Jason Sams803626f2011-04-06 17:52:23 -0700409
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700410 dc->gl.shaderCache = new RsdShaderCache();
411 dc->gl.vertexArrayState = new RsdVertexArrayState();
412 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700413 dc->gl.currentFrameBuffer = NULL;
Jason Sams17801f12012-01-12 14:22:21 -0800414 dc->mHasGraphics = true;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700415
Steve Block71f2cf12011-10-20 11:56:00 +0100416 ALOGV("%p initGLThread end", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700417 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700418 return true;
419}
420
421
Alex Sakhartchouk6c72eec2011-05-17 12:32:47 -0700422bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
Jason Samsfcf72312011-04-20 15:09:01 -0700423 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams803626f2011-04-06 17:52:23 -0700424
425 EGLBoolean ret;
426 // WAR: Some drivers fail to handle 0 size surfaces correcntly.
427 // Use the pbuffer to avoid this pitfall.
428 if ((dc->gl.egl.surface != NULL) || (w == 0) || (h == 0)) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700429 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700430 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
431 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
432 checkEglError("eglMakeCurrent", ret);
433
Jason Sams5316b9e2011-09-13 15:41:01 -0700434 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700435 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
436 checkEglError("eglDestroySurface", ret);
437
438 dc->gl.egl.surface = NULL;
439 dc->gl.width = 1;
440 dc->gl.height = 1;
441 }
442
Jason Samsfaa32b32011-06-20 16:58:04 -0700443 if (dc->gl.wndSurface != NULL) {
444 dc->gl.wndSurface->decStrong(NULL);
445 }
446
Alex Sakhartchouk6c72eec2011-05-17 12:32:47 -0700447 dc->gl.wndSurface = (ANativeWindow *)sur;
Jason Sams803626f2011-04-06 17:52:23 -0700448 if (dc->gl.wndSurface != NULL) {
Jason Samsfaa32b32011-06-20 16:58:04 -0700449 dc->gl.wndSurface->incStrong(NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700450 dc->gl.width = w;
451 dc->gl.height = h;
452
Jason Sams5316b9e2011-09-13 15:41:01 -0700453 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700454 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
455 dc->gl.wndSurface, NULL);
456 checkEglError("eglCreateWindowSurface");
457 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Block3762c312012-01-06 19:20:56 +0000458 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams803626f2011-04-06 17:52:23 -0700459 }
460
Jason Sams5316b9e2011-09-13 15:41:01 -0700461 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700462 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
463 dc->gl.egl.surface, dc->gl.egl.context);
464 checkEglError("eglMakeCurrent", ret);
465 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700466 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700467 return true;
468}
469
470void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Samsfcf72312011-04-20 15:09:01 -0700471 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams5316b9e2011-09-13 15:41:01 -0700472 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams803626f2011-04-06 17:52:23 -0700473}
474
Jason Sams17801f12012-01-12 14:22:21 -0800475void rsdGLSetPriority(const Context *rsc, int32_t priority) {
476 if (priority > 0) {
477 // Mark context as low priority.
478 ALOGV("low pri");
479 } else {
480 ALOGV("normal pri");
481 }
482}
483
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700484void rsdGLCheckError(const android::renderscript::Context *rsc,
485 const char *msg, bool isFatal) {
486 GLenum err = glGetError();
487 if (err != GL_NO_ERROR) {
488 char buf[1024];
489 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
490
491 if (isFatal) {
492 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
493 } else {
494 switch (err) {
495 case GL_OUT_OF_MEMORY:
496 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
497 break;
498 default:
499 rsc->setError(RS_ERROR_DRIVER, buf);
500 break;
501 }
502 }
503
Steve Block3762c312012-01-06 19:20:56 +0000504 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700505 }
506
507}
Alex Sakhartchouk20c9c922012-02-24 14:22:34 -0800508
509void rsdGLClearColor(const android::renderscript::Context *rsc,
510 float r, float g, float b, float a) {
511 RSD_CALL_GL(glClearColor, r, g, b, a);
512 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
513}
514
515void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
516 RSD_CALL_GL(glClearDepthf, v);
517 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
518}
519
520void rsdGLFinish(const android::renderscript::Context *rsc) {
521 RSD_CALL_GL(glFinish);
522}
523
524void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
525 float x1, float y1, float z1, float u1, float v1,
526 float x2, float y2, float z2, float u2, float v2,
527 float x3, float y3, float z3, float u3, float v3,
528 float x4, float y4, float z4, float u4, float v4) {
529
530 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
531 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
532
533 RsdVertexArray::Attrib attribs[2];
534 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
535 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
536
537 RsdVertexArray va(attribs, 2);
538 va.setup(rsc);
539
540 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
541}