blob: fae602ccdee5a773ef24158fd07fae639ac5aa10 [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 Sakhartchoukbedc0232012-03-09 10:47:27 -080040#include "rsDevice.h"
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -070041#include "rsdShaderCache.h"
42#include "rsdVertexArray.h"
Alex Sakhartchouk8650c322011-06-16 11:05:13 -070043#include "rsdFrameBufferObj.h"
Jason Sams803626f2011-04-06 17:52:23 -070044
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -080045#include <gui/SurfaceTextureClient.h>
46
Jason Sams803626f2011-04-06 17:52:23 -070047using namespace android;
48using namespace android::renderscript;
49
50static int32_t gGLContextCount = 0;
51
52static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
Mathias Agopiancc0eaa62012-02-24 16:42:46 -080053 struct EGLUtils {
54 static const char *strerror(EGLint err) {
55 switch (err){
56 case EGL_SUCCESS: return "EGL_SUCCESS";
57 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
58 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
59 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
60 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
61 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
62 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
63 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
64 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
65 case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
66 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
67 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
68 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
69 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
70 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
71 default: return "UNKNOWN";
72 }
73 }
74 };
75
Jason Sams803626f2011-04-06 17:52:23 -070076 if (returnVal != EGL_TRUE) {
77 fprintf(stderr, "%s() returned %d\n", op, returnVal);
78 }
79
80 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
81 = eglGetError()) {
82 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
83 error);
84 }
85}
86
87static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
88
89#define X(VAL) {VAL, #VAL}
90 struct {EGLint attribute; const char* name;} names[] = {
91 X(EGL_BUFFER_SIZE),
92 X(EGL_ALPHA_SIZE),
93 X(EGL_BLUE_SIZE),
94 X(EGL_GREEN_SIZE),
95 X(EGL_RED_SIZE),
96 X(EGL_DEPTH_SIZE),
97 X(EGL_STENCIL_SIZE),
98 X(EGL_CONFIG_CAVEAT),
99 X(EGL_CONFIG_ID),
100 X(EGL_LEVEL),
101 X(EGL_MAX_PBUFFER_HEIGHT),
102 X(EGL_MAX_PBUFFER_PIXELS),
103 X(EGL_MAX_PBUFFER_WIDTH),
104 X(EGL_NATIVE_RENDERABLE),
105 X(EGL_NATIVE_VISUAL_ID),
106 X(EGL_NATIVE_VISUAL_TYPE),
107 X(EGL_SAMPLES),
108 X(EGL_SAMPLE_BUFFERS),
109 X(EGL_SURFACE_TYPE),
110 X(EGL_TRANSPARENT_TYPE),
111 X(EGL_TRANSPARENT_RED_VALUE),
112 X(EGL_TRANSPARENT_GREEN_VALUE),
113 X(EGL_TRANSPARENT_BLUE_VALUE),
114 X(EGL_BIND_TO_TEXTURE_RGB),
115 X(EGL_BIND_TO_TEXTURE_RGBA),
116 X(EGL_MIN_SWAP_INTERVAL),
117 X(EGL_MAX_SWAP_INTERVAL),
118 X(EGL_LUMINANCE_SIZE),
119 X(EGL_ALPHA_MASK_SIZE),
120 X(EGL_COLOR_BUFFER_TYPE),
121 X(EGL_RENDERABLE_TYPE),
122 X(EGL_CONFORMANT),
123 };
124#undef X
125
126 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
127 EGLint value = -1;
Mathias Agopian18617862011-07-06 16:35:30 -0700128 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
129 if (returnVal) {
Steve Block71f2cf12011-10-20 11:56:00 +0100130 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
Jason Sams803626f2011-04-06 17:52:23 -0700131 }
132 }
133}
134
Jason Samsfcf72312011-04-20 15:09:01 -0700135static void DumpDebug(RsdHal *dc) {
Steve Block3762c312012-01-06 19:20:56 +0000136 ALOGE(" EGL ver %i %i", dc->gl.egl.majorVersion, dc->gl.egl.minorVersion);
137 ALOGE(" EGL context %p surface %p, Display=%p", dc->gl.egl.context, dc->gl.egl.surface,
Jason Sams803626f2011-04-06 17:52:23 -0700138 dc->gl.egl.display);
Steve Block3762c312012-01-06 19:20:56 +0000139 ALOGE(" GL vendor: %s", dc->gl.gl.vendor);
140 ALOGE(" GL renderer: %s", dc->gl.gl.renderer);
141 ALOGE(" GL Version: %s", dc->gl.gl.version);
142 ALOGE(" GL Extensions: %s", dc->gl.gl.extensions);
143 ALOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
Jason Sams803626f2011-04-06 17:52:23 -0700144
Steve Block71f2cf12011-10-20 11:56:00 +0100145 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
Jason Sams803626f2011-04-06 17:52:23 -0700146 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
Steve Block71f2cf12011-10-20 11:56:00 +0100147 ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
148 ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
Jason Sams803626f2011-04-06 17:52:23 -0700149 dc->gl.gl.maxFragmentUniformVectors);
Steve Block71f2cf12011-10-20 11:56:00 +0100150 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
Jason Sams803626f2011-04-06 17:52:23 -0700151}
152
153void rsdGLShutdown(const Context *rsc) {
Jason Samsfcf72312011-04-20 15:09:01 -0700154 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams803626f2011-04-06 17:52:23 -0700155
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700156 dc->gl.shaderCache->cleanupAll();
157 delete dc->gl.shaderCache;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700158 delete dc->gl.vertexArrayState;
159
Jason Sams803626f2011-04-06 17:52:23 -0700160 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700161 RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
162 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
163 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
Jason Sams803626f2011-04-06 17:52:23 -0700164 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700165 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams803626f2011-04-06 17:52:23 -0700166 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700167 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
Jason Sams803626f2011-04-06 17:52:23 -0700168 checkEglError("eglDestroyContext");
169 }
170
171 gGLContextCount--;
172 if (!gGLContextCount) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700173 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
Jason Sams803626f2011-04-06 17:52:23 -0700174 }
175}
176
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800177void getConfigData(const Context *rsc,
178 EGLint *configAttribs, size_t configAttribsLen,
179 uint32_t numSamples) {
180 memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
Jason Sams803626f2011-04-06 17:52:23 -0700181
Jason Sams803626f2011-04-06 17:52:23 -0700182 EGLint *configAttribsPtr = configAttribs;
Jason Sams803626f2011-04-06 17:52:23 -0700183
184 configAttribsPtr[0] = EGL_SURFACE_TYPE;
185 configAttribsPtr[1] = EGL_WINDOW_BIT;
186 configAttribsPtr += 2;
187
188 configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
189 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
190 configAttribsPtr += 2;
191
Mathias Agopian18617862011-07-06 16:35:30 -0700192 configAttribsPtr[0] = EGL_RED_SIZE;
193 configAttribsPtr[1] = 8;
194 configAttribsPtr += 2;
195
196 configAttribsPtr[0] = EGL_GREEN_SIZE;
197 configAttribsPtr[1] = 8;
198 configAttribsPtr += 2;
199
200 configAttribsPtr[0] = EGL_BLUE_SIZE;
201 configAttribsPtr[1] = 8;
202 configAttribsPtr += 2;
203
204 if (rsc->mUserSurfaceConfig.alphaMin > 0) {
205 configAttribsPtr[0] = EGL_ALPHA_SIZE;
206 configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
207 configAttribsPtr += 2;
208 }
209
Jason Sams803626f2011-04-06 17:52:23 -0700210 if (rsc->mUserSurfaceConfig.depthMin > 0) {
211 configAttribsPtr[0] = EGL_DEPTH_SIZE;
212 configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
213 configAttribsPtr += 2;
214 }
215
216 if (rsc->mDev->mForceSW) {
217 configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
218 configAttribsPtr[1] = EGL_SLOW_CONFIG;
219 configAttribsPtr += 2;
220 }
221
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800222 if (numSamples > 1) {
223 configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
224 configAttribsPtr[1] = 1;
225 configAttribsPtr[2] = EGL_SAMPLES;
226 configAttribsPtr[3] = numSamples;
227 configAttribsPtr += 4;
228 }
229
Jason Sams803626f2011-04-06 17:52:23 -0700230 configAttribsPtr[0] = EGL_NONE;
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800231 rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
232}
233
234bool rsdGLInit(const Context *rsc) {
235 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
236
237 dc->gl.egl.numConfigs = -1;
238
239 EGLint configAttribs[128];
240 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
Jason Sams803626f2011-04-06 17:52:23 -0700241
Steve Block71f2cf12011-10-20 11:56:00 +0100242 ALOGV("%p initEGL start", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700243 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700244 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
245 checkEglError("eglGetDisplay");
246
Jason Sams5316b9e2011-09-13 15:41:01 -0700247 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
248 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
Jason Sams803626f2011-04-06 17:52:23 -0700249 checkEglError("eglInitialize");
250
Mathias Agopian18617862011-07-06 16:35:30 -0700251 EGLBoolean ret;
252
253 EGLint numConfigs = -1, n = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700254 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800255
256 // Try minding a multisample config that matches the user request
257 uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
258 uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
259 for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
260 getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
261 ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
262 checkEglError("eglGetConfigs", ret);
263 if (numConfigs > 0) {
264 break;
265 }
266 }
Mathias Agopian18617862011-07-06 16:35:30 -0700267
Jason Sams4c2e4c82012-02-07 15:32:08 -0800268 eglSwapInterval(dc->gl.egl.display, 0);
269
Mathias Agopian18617862011-07-06 16:35:30 -0700270 if (numConfigs) {
271 EGLConfig* const configs = new EGLConfig[numConfigs];
272
Jason Sams5316b9e2011-09-13 15:41:01 -0700273 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian18617862011-07-06 16:35:30 -0700274 ret = eglChooseConfig(dc->gl.egl.display,
275 configAttribs, configs, numConfigs, &n);
276 if (!ret || !n) {
277 checkEglError("eglChooseConfig", ret);
Steve Block3762c312012-01-06 19:20:56 +0000278 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian18617862011-07-06 16:35:30 -0700279 }
280
281 // The first config is guaranteed to over-satisfy the constraints
282 dc->gl.egl.config = configs[0];
283
284 // go through the list and skip configs that over-satisfy our needs
285 for (int i=0 ; i<n ; i++) {
286 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
287 EGLint alphaSize;
288 eglGetConfigAttrib(dc->gl.egl.display,
289 configs[i], EGL_ALPHA_SIZE, &alphaSize);
290 if (alphaSize > 0) {
291 continue;
292 }
293 }
294
295 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
296 EGLint depthSize;
297 eglGetConfigAttrib(dc->gl.egl.display,
298 configs[i], EGL_DEPTH_SIZE, &depthSize);
299 if (depthSize > 0) {
300 continue;
301 }
302 }
303
304 // Found one!
305 dc->gl.egl.config = configs[i];
306 break;
307 }
308
309 delete [] configs;
Jason Sams803626f2011-04-06 17:52:23 -0700310 }
311
Jason Sams803626f2011-04-06 17:52:23 -0700312 //if (props.mLogVisual) {
Stephen Hines9c35d792011-04-20 17:08:14 -0700313 if (0) {
Jason Sams803626f2011-04-06 17:52:23 -0700314 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9c35d792011-04-20 17:08:14 -0700315 }
Jason Sams803626f2011-04-06 17:52:23 -0700316 //}
317
Jason Sams5316b9e2011-09-13 15:41:01 -0700318 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700319 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
320 EGL_NO_CONTEXT, context_attribs2);
321 checkEglError("eglCreateContext");
322 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
Steve Block3762c312012-01-06 19:20:56 +0000323 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700324 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700325 return false;
326 }
327 gGLContextCount++;
328
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800329 sp<SurfaceTexture> st(new SurfaceTexture(123));
330 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st));
331 dc->gl.egl.surfaceDefault = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
332 static_cast<ANativeWindow*>(stc.get()),
333 NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700334
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800335 checkEglError("eglCreateWindowSurface");
Jason Sams803626f2011-04-06 17:52:23 -0700336 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800337 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams803626f2011-04-06 17:52:23 -0700338 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700339 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700340 return false;
341 }
342
Jason Sams5316b9e2011-09-13 15:41:01 -0700343 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian18617862011-07-06 16:35:30 -0700344 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
345 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
Jason Sams803626f2011-04-06 17:52:23 -0700346 if (ret == EGL_FALSE) {
Steve Block3762c312012-01-06 19:20:56 +0000347 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams803626f2011-04-06 17:52:23 -0700348 checkEglError("eglMakeCurrent", ret);
349 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700350 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700351 return false;
352 }
353
354 dc->gl.gl.version = glGetString(GL_VERSION);
355 dc->gl.gl.vendor = glGetString(GL_VENDOR);
356 dc->gl.gl.renderer = glGetString(GL_RENDERER);
357 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
358
Steve Block71f2cf12011-10-20 11:56:00 +0100359 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
360 //ALOGV("GL Version %s", mGL.mVersion);
361 //ALOGV("GL Vendor %s", mGL.mVendor);
362 //ALOGV("GL Renderer %s", mGL.mRenderer);
363 //ALOGV("GL Extensions %s", mGL.mExtensions);
Jason Sams803626f2011-04-06 17:52:23 -0700364
365 const char *verptr = NULL;
366 if (strlen((const char *)dc->gl.gl.version) > 9) {
367 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
368 verptr = (const char *)dc->gl.gl.version + 12;
369 }
370 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
371 verptr = (const char *)dc->gl.gl.version + 9;
372 }
373 }
374
375 if (!verptr) {
Steve Block3762c312012-01-06 19:20:56 +0000376 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams803626f2011-04-06 17:52:23 -0700377 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700378 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700379 return false;
380 } else {
381 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
382 }
383
384 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
385 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
386 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
387
388 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
389 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
390
391 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
392 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
393
394 dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
395 "GL_OES_texture_npot");
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800396 dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams803626f2011-04-06 17:52:23 -0700397 "GL_IMG_texture_npot");
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800398 dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams803626f2011-04-06 17:52:23 -0700399 "GL_NV_texture_npot_2D_mipmap");
400 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
401 bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
402 "GL_EXT_texture_filter_anisotropic");
403 if (hasAniso) {
404 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
405 }
406
Stephen Hines9c35d792011-04-20 17:08:14 -0700407 if (0) {
408 DumpDebug(dc);
409 }
Jason Sams803626f2011-04-06 17:52:23 -0700410
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700411 dc->gl.shaderCache = new RsdShaderCache();
412 dc->gl.vertexArrayState = new RsdVertexArrayState();
413 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700414 dc->gl.currentFrameBuffer = NULL;
Jason Sams17801f12012-01-12 14:22:21 -0800415 dc->mHasGraphics = true;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700416
Steve Block71f2cf12011-10-20 11:56:00 +0100417 ALOGV("%p initGLThread end", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700418 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700419 return true;
420}
421
422
Alex Sakhartchouk6c72eec2011-05-17 12:32:47 -0700423bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
Jason Samsfcf72312011-04-20 15:09:01 -0700424 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams803626f2011-04-06 17:52:23 -0700425
426 EGLBoolean ret;
427 // WAR: Some drivers fail to handle 0 size surfaces correcntly.
428 // Use the pbuffer to avoid this pitfall.
429 if ((dc->gl.egl.surface != NULL) || (w == 0) || (h == 0)) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700430 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700431 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
432 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
433 checkEglError("eglMakeCurrent", ret);
434
Jason Sams5316b9e2011-09-13 15:41:01 -0700435 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700436 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
437 checkEglError("eglDestroySurface", ret);
438
439 dc->gl.egl.surface = NULL;
440 dc->gl.width = 1;
441 dc->gl.height = 1;
442 }
443
Jason Samsfaa32b32011-06-20 16:58:04 -0700444 if (dc->gl.wndSurface != NULL) {
445 dc->gl.wndSurface->decStrong(NULL);
446 }
447
Alex Sakhartchouk6c72eec2011-05-17 12:32:47 -0700448 dc->gl.wndSurface = (ANativeWindow *)sur;
Jason Sams803626f2011-04-06 17:52:23 -0700449 if (dc->gl.wndSurface != NULL) {
Jason Samsfaa32b32011-06-20 16:58:04 -0700450 dc->gl.wndSurface->incStrong(NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700451 dc->gl.width = w;
452 dc->gl.height = h;
453
Jason Sams5316b9e2011-09-13 15:41:01 -0700454 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700455 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
456 dc->gl.wndSurface, NULL);
457 checkEglError("eglCreateWindowSurface");
458 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Block3762c312012-01-06 19:20:56 +0000459 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams803626f2011-04-06 17:52:23 -0700460 }
461
Jason Sams5316b9e2011-09-13 15:41:01 -0700462 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700463 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
464 dc->gl.egl.surface, dc->gl.egl.context);
465 checkEglError("eglMakeCurrent", ret);
466 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700467 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700468 return true;
469}
470
471void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Samsfcf72312011-04-20 15:09:01 -0700472 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams5316b9e2011-09-13 15:41:01 -0700473 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams803626f2011-04-06 17:52:23 -0700474}
475
Jason Sams17801f12012-01-12 14:22:21 -0800476void rsdGLSetPriority(const Context *rsc, int32_t priority) {
477 if (priority > 0) {
478 // Mark context as low priority.
479 ALOGV("low pri");
480 } else {
481 ALOGV("normal pri");
482 }
483}
484
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700485void rsdGLCheckError(const android::renderscript::Context *rsc,
486 const char *msg, bool isFatal) {
487 GLenum err = glGetError();
488 if (err != GL_NO_ERROR) {
489 char buf[1024];
490 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
491
492 if (isFatal) {
493 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
494 } else {
495 switch (err) {
496 case GL_OUT_OF_MEMORY:
497 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
498 break;
499 default:
500 rsc->setError(RS_ERROR_DRIVER, buf);
501 break;
502 }
503 }
504
Steve Block3762c312012-01-06 19:20:56 +0000505 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700506 }
507
508}
Alex Sakhartchouk20c9c922012-02-24 14:22:34 -0800509
510void rsdGLClearColor(const android::renderscript::Context *rsc,
511 float r, float g, float b, float a) {
512 RSD_CALL_GL(glClearColor, r, g, b, a);
513 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
514}
515
516void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
517 RSD_CALL_GL(glClearDepthf, v);
518 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
519}
520
521void rsdGLFinish(const android::renderscript::Context *rsc) {
522 RSD_CALL_GL(glFinish);
523}
524
525void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
526 float x1, float y1, float z1, float u1, float v1,
527 float x2, float y2, float z2, float u2, float v2,
528 float x3, float y3, float z3, float u3, float v3,
529 float x4, float y4, float z4, float u4, float v4) {
530
531 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
532 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
533
534 RsdVertexArray::Attrib attribs[2];
535 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
536 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
537
538 RsdVertexArray va(attribs, 2);
539 va.setup(rsc);
540
541 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
542}