blob: 0860417a13bc10c2854a7ca6d3d2f8284e4e84f7 [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>
Daniel Lamae540b92012-03-23 19:44:11 -070046#include <gui/DummyConsumer.h>
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -080047
Jason Sams803626f2011-04-06 17:52:23 -070048using namespace android;
49using namespace android::renderscript;
50
51static int32_t gGLContextCount = 0;
52
53static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
Mathias Agopiancc0eaa62012-02-24 16:42:46 -080054 struct EGLUtils {
55 static const char *strerror(EGLint err) {
56 switch (err){
57 case EGL_SUCCESS: return "EGL_SUCCESS";
58 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
59 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
60 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
61 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
62 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
63 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
64 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
65 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
66 case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
67 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
68 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
69 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
70 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
71 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
72 default: return "UNKNOWN";
73 }
74 }
75 };
76
Jason Sams803626f2011-04-06 17:52:23 -070077 if (returnVal != EGL_TRUE) {
78 fprintf(stderr, "%s() returned %d\n", op, returnVal);
79 }
80
81 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
82 = eglGetError()) {
83 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
84 error);
85 }
86}
87
88static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
89
90#define X(VAL) {VAL, #VAL}
91 struct {EGLint attribute; const char* name;} names[] = {
92 X(EGL_BUFFER_SIZE),
93 X(EGL_ALPHA_SIZE),
94 X(EGL_BLUE_SIZE),
95 X(EGL_GREEN_SIZE),
96 X(EGL_RED_SIZE),
97 X(EGL_DEPTH_SIZE),
98 X(EGL_STENCIL_SIZE),
99 X(EGL_CONFIG_CAVEAT),
100 X(EGL_CONFIG_ID),
101 X(EGL_LEVEL),
102 X(EGL_MAX_PBUFFER_HEIGHT),
103 X(EGL_MAX_PBUFFER_PIXELS),
104 X(EGL_MAX_PBUFFER_WIDTH),
105 X(EGL_NATIVE_RENDERABLE),
106 X(EGL_NATIVE_VISUAL_ID),
107 X(EGL_NATIVE_VISUAL_TYPE),
108 X(EGL_SAMPLES),
109 X(EGL_SAMPLE_BUFFERS),
110 X(EGL_SURFACE_TYPE),
111 X(EGL_TRANSPARENT_TYPE),
112 X(EGL_TRANSPARENT_RED_VALUE),
113 X(EGL_TRANSPARENT_GREEN_VALUE),
114 X(EGL_TRANSPARENT_BLUE_VALUE),
115 X(EGL_BIND_TO_TEXTURE_RGB),
116 X(EGL_BIND_TO_TEXTURE_RGBA),
117 X(EGL_MIN_SWAP_INTERVAL),
118 X(EGL_MAX_SWAP_INTERVAL),
119 X(EGL_LUMINANCE_SIZE),
120 X(EGL_ALPHA_MASK_SIZE),
121 X(EGL_COLOR_BUFFER_TYPE),
122 X(EGL_RENDERABLE_TYPE),
123 X(EGL_CONFORMANT),
124 };
125#undef X
126
127 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
128 EGLint value = -1;
Mathias Agopian18617862011-07-06 16:35:30 -0700129 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
130 if (returnVal) {
Steve Block71f2cf12011-10-20 11:56:00 +0100131 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
Jason Sams803626f2011-04-06 17:52:23 -0700132 }
133 }
134}
135
Jason Samsfcf72312011-04-20 15:09:01 -0700136static void DumpDebug(RsdHal *dc) {
Steve Block3762c312012-01-06 19:20:56 +0000137 ALOGE(" EGL ver %i %i", dc->gl.egl.majorVersion, dc->gl.egl.minorVersion);
138 ALOGE(" EGL context %p surface %p, Display=%p", dc->gl.egl.context, dc->gl.egl.surface,
Jason Sams803626f2011-04-06 17:52:23 -0700139 dc->gl.egl.display);
Steve Block3762c312012-01-06 19:20:56 +0000140 ALOGE(" GL vendor: %s", dc->gl.gl.vendor);
141 ALOGE(" GL renderer: %s", dc->gl.gl.renderer);
142 ALOGE(" GL Version: %s", dc->gl.gl.version);
143 ALOGE(" GL Extensions: %s", dc->gl.gl.extensions);
144 ALOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
Jason Sams803626f2011-04-06 17:52:23 -0700145
Steve Block71f2cf12011-10-20 11:56:00 +0100146 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
Jason Sams803626f2011-04-06 17:52:23 -0700147 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
Steve Block71f2cf12011-10-20 11:56:00 +0100148 ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
149 ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
Jason Sams803626f2011-04-06 17:52:23 -0700150 dc->gl.gl.maxFragmentUniformVectors);
Steve Block71f2cf12011-10-20 11:56:00 +0100151 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
Jason Sams803626f2011-04-06 17:52:23 -0700152}
153
154void rsdGLShutdown(const Context *rsc) {
Jason Samsfcf72312011-04-20 15:09:01 -0700155 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams803626f2011-04-06 17:52:23 -0700156
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700157 dc->gl.shaderCache->cleanupAll();
158 delete dc->gl.shaderCache;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700159 delete dc->gl.vertexArrayState;
160
Jason Sams803626f2011-04-06 17:52:23 -0700161 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700162 RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
163 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
164 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
Jason Sams803626f2011-04-06 17:52:23 -0700165 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700166 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams803626f2011-04-06 17:52:23 -0700167 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700168 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
Jason Sams803626f2011-04-06 17:52:23 -0700169 checkEglError("eglDestroyContext");
170 }
171
172 gGLContextCount--;
173 if (!gGLContextCount) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700174 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
Jason Sams803626f2011-04-06 17:52:23 -0700175 }
176}
177
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800178void getConfigData(const Context *rsc,
179 EGLint *configAttribs, size_t configAttribsLen,
180 uint32_t numSamples) {
181 memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
Jason Sams803626f2011-04-06 17:52:23 -0700182
Jason Sams803626f2011-04-06 17:52:23 -0700183 EGLint *configAttribsPtr = configAttribs;
Jason Sams803626f2011-04-06 17:52:23 -0700184
185 configAttribsPtr[0] = EGL_SURFACE_TYPE;
186 configAttribsPtr[1] = EGL_WINDOW_BIT;
187 configAttribsPtr += 2;
188
189 configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
190 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
191 configAttribsPtr += 2;
192
Mathias Agopian18617862011-07-06 16:35:30 -0700193 configAttribsPtr[0] = EGL_RED_SIZE;
194 configAttribsPtr[1] = 8;
195 configAttribsPtr += 2;
196
197 configAttribsPtr[0] = EGL_GREEN_SIZE;
198 configAttribsPtr[1] = 8;
199 configAttribsPtr += 2;
200
201 configAttribsPtr[0] = EGL_BLUE_SIZE;
202 configAttribsPtr[1] = 8;
203 configAttribsPtr += 2;
204
205 if (rsc->mUserSurfaceConfig.alphaMin > 0) {
206 configAttribsPtr[0] = EGL_ALPHA_SIZE;
207 configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
208 configAttribsPtr += 2;
209 }
210
Jason Sams803626f2011-04-06 17:52:23 -0700211 if (rsc->mUserSurfaceConfig.depthMin > 0) {
212 configAttribsPtr[0] = EGL_DEPTH_SIZE;
213 configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
214 configAttribsPtr += 2;
215 }
216
217 if (rsc->mDev->mForceSW) {
218 configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
219 configAttribsPtr[1] = EGL_SLOW_CONFIG;
220 configAttribsPtr += 2;
221 }
222
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800223 if (numSamples > 1) {
224 configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
225 configAttribsPtr[1] = 1;
226 configAttribsPtr[2] = EGL_SAMPLES;
227 configAttribsPtr[3] = numSamples;
228 configAttribsPtr += 4;
229 }
230
Jason Sams803626f2011-04-06 17:52:23 -0700231 configAttribsPtr[0] = EGL_NONE;
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800232 rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
233}
234
235bool rsdGLInit(const Context *rsc) {
236 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
237
238 dc->gl.egl.numConfigs = -1;
239
240 EGLint configAttribs[128];
241 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
Jason Sams803626f2011-04-06 17:52:23 -0700242
Steve Block71f2cf12011-10-20 11:56:00 +0100243 ALOGV("%p initEGL start", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700244 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700245 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
246 checkEglError("eglGetDisplay");
247
Jason Sams5316b9e2011-09-13 15:41:01 -0700248 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
249 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
Jason Sams803626f2011-04-06 17:52:23 -0700250 checkEglError("eglInitialize");
251
Mathias Agopian18617862011-07-06 16:35:30 -0700252 EGLBoolean ret;
253
254 EGLint numConfigs = -1, n = 0;
Jason Sams5316b9e2011-09-13 15:41:01 -0700255 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Alex Sakhartchoukf203b832012-02-28 14:35:31 -0800256
257 // Try minding a multisample config that matches the user request
258 uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
259 uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
260 for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
261 getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
262 ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
263 checkEglError("eglGetConfigs", ret);
264 if (numConfigs > 0) {
265 break;
266 }
267 }
Mathias Agopian18617862011-07-06 16:35:30 -0700268
Jason Sams4c2e4c82012-02-07 15:32:08 -0800269 eglSwapInterval(dc->gl.egl.display, 0);
270
Mathias Agopian18617862011-07-06 16:35:30 -0700271 if (numConfigs) {
272 EGLConfig* const configs = new EGLConfig[numConfigs];
273
Jason Sams5316b9e2011-09-13 15:41:01 -0700274 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian18617862011-07-06 16:35:30 -0700275 ret = eglChooseConfig(dc->gl.egl.display,
276 configAttribs, configs, numConfigs, &n);
277 if (!ret || !n) {
278 checkEglError("eglChooseConfig", ret);
Steve Block3762c312012-01-06 19:20:56 +0000279 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian18617862011-07-06 16:35:30 -0700280 }
281
282 // The first config is guaranteed to over-satisfy the constraints
283 dc->gl.egl.config = configs[0];
284
285 // go through the list and skip configs that over-satisfy our needs
286 for (int i=0 ; i<n ; i++) {
287 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
288 EGLint alphaSize;
289 eglGetConfigAttrib(dc->gl.egl.display,
290 configs[i], EGL_ALPHA_SIZE, &alphaSize);
291 if (alphaSize > 0) {
292 continue;
293 }
294 }
295
296 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
297 EGLint depthSize;
298 eglGetConfigAttrib(dc->gl.egl.display,
299 configs[i], EGL_DEPTH_SIZE, &depthSize);
300 if (depthSize > 0) {
301 continue;
302 }
303 }
304
305 // Found one!
306 dc->gl.egl.config = configs[i];
307 break;
308 }
309
310 delete [] configs;
Jason Sams803626f2011-04-06 17:52:23 -0700311 }
312
Jason Sams803626f2011-04-06 17:52:23 -0700313 //if (props.mLogVisual) {
Stephen Hines9c35d792011-04-20 17:08:14 -0700314 if (0) {
Jason Sams803626f2011-04-06 17:52:23 -0700315 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9c35d792011-04-20 17:08:14 -0700316 }
Jason Sams803626f2011-04-06 17:52:23 -0700317 //}
318
Jason Sams5316b9e2011-09-13 15:41:01 -0700319 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700320 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
321 EGL_NO_CONTEXT, context_attribs2);
322 checkEglError("eglCreateContext");
323 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
Steve Block3762c312012-01-06 19:20:56 +0000324 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700325 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700326 return false;
327 }
328 gGLContextCount++;
329
Daniel Lamae540b92012-03-23 19:44:11 -0700330 // Create a BufferQueue with a fake consumer
331 sp<BufferQueue> bq = new BufferQueue();
332 sp<DummyConsumer> dummy = new DummyConsumer(bq);
333 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(bq)));
334
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800335 dc->gl.egl.surfaceDefault = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
336 static_cast<ANativeWindow*>(stc.get()),
337 NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700338
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800339 checkEglError("eglCreateWindowSurface");
Jason Sams803626f2011-04-06 17:52:23 -0700340 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Alex Sakhartchoukeb8b1fe2012-02-28 10:16:06 -0800341 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams803626f2011-04-06 17:52:23 -0700342 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700343 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700344 return false;
345 }
346
Jason Sams5316b9e2011-09-13 15:41:01 -0700347 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian18617862011-07-06 16:35:30 -0700348 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
349 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
Jason Sams803626f2011-04-06 17:52:23 -0700350 if (ret == EGL_FALSE) {
Steve Block3762c312012-01-06 19:20:56 +0000351 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams803626f2011-04-06 17:52:23 -0700352 checkEglError("eglMakeCurrent", ret);
353 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700354 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700355 return false;
356 }
357
358 dc->gl.gl.version = glGetString(GL_VERSION);
359 dc->gl.gl.vendor = glGetString(GL_VENDOR);
360 dc->gl.gl.renderer = glGetString(GL_RENDERER);
361 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
362
Steve Block71f2cf12011-10-20 11:56:00 +0100363 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
364 //ALOGV("GL Version %s", mGL.mVersion);
365 //ALOGV("GL Vendor %s", mGL.mVendor);
366 //ALOGV("GL Renderer %s", mGL.mRenderer);
367 //ALOGV("GL Extensions %s", mGL.mExtensions);
Jason Sams803626f2011-04-06 17:52:23 -0700368
369 const char *verptr = NULL;
370 if (strlen((const char *)dc->gl.gl.version) > 9) {
371 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
372 verptr = (const char *)dc->gl.gl.version + 12;
373 }
374 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
375 verptr = (const char *)dc->gl.gl.version + 9;
376 }
377 }
378
379 if (!verptr) {
Steve Block3762c312012-01-06 19:20:56 +0000380 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams803626f2011-04-06 17:52:23 -0700381 rsdGLShutdown(rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700382 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700383 return false;
384 } else {
385 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
386 }
387
388 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
389 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
390 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
391
392 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
393 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
394
395 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
396 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
397
398 dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
399 "GL_OES_texture_npot");
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800400 dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams803626f2011-04-06 17:52:23 -0700401 "GL_IMG_texture_npot");
Mathias Agopiandfbcee62012-01-29 22:20:50 -0800402 dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams803626f2011-04-06 17:52:23 -0700403 "GL_NV_texture_npot_2D_mipmap");
404 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
405 bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
406 "GL_EXT_texture_filter_anisotropic");
407 if (hasAniso) {
408 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
409 }
410
Stephen Hines9c35d792011-04-20 17:08:14 -0700411 if (0) {
412 DumpDebug(dc);
413 }
Jason Sams803626f2011-04-06 17:52:23 -0700414
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700415 dc->gl.shaderCache = new RsdShaderCache();
416 dc->gl.vertexArrayState = new RsdVertexArrayState();
417 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
Alex Sakhartchouk8650c322011-06-16 11:05:13 -0700418 dc->gl.currentFrameBuffer = NULL;
Jason Sams17801f12012-01-12 14:22:21 -0800419 dc->mHasGraphics = true;
Alex Sakhartchouk4a36b452011-04-29 16:49:08 -0700420
Steve Block71f2cf12011-10-20 11:56:00 +0100421 ALOGV("%p initGLThread end", rsc);
Jason Sams5316b9e2011-09-13 15:41:01 -0700422 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700423 return true;
424}
425
426
Alex Sakhartchouk6c72eec2011-05-17 12:32:47 -0700427bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
Jason Samsfcf72312011-04-20 15:09:01 -0700428 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams803626f2011-04-06 17:52:23 -0700429
430 EGLBoolean ret;
431 // WAR: Some drivers fail to handle 0 size surfaces correcntly.
432 // Use the pbuffer to avoid this pitfall.
433 if ((dc->gl.egl.surface != NULL) || (w == 0) || (h == 0)) {
Jason Sams5316b9e2011-09-13 15:41:01 -0700434 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700435 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
436 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
437 checkEglError("eglMakeCurrent", ret);
438
Jason Sams5316b9e2011-09-13 15:41:01 -0700439 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700440 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
441 checkEglError("eglDestroySurface", ret);
442
443 dc->gl.egl.surface = NULL;
444 dc->gl.width = 1;
445 dc->gl.height = 1;
446 }
447
Jason Samsfaa32b32011-06-20 16:58:04 -0700448 if (dc->gl.wndSurface != NULL) {
449 dc->gl.wndSurface->decStrong(NULL);
450 }
451
Alex Sakhartchouk6c72eec2011-05-17 12:32:47 -0700452 dc->gl.wndSurface = (ANativeWindow *)sur;
Jason Sams803626f2011-04-06 17:52:23 -0700453 if (dc->gl.wndSurface != NULL) {
Jason Samsfaa32b32011-06-20 16:58:04 -0700454 dc->gl.wndSurface->incStrong(NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700455 dc->gl.width = w;
456 dc->gl.height = h;
457
Jason Sams5316b9e2011-09-13 15:41:01 -0700458 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700459 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
460 dc->gl.wndSurface, NULL);
461 checkEglError("eglCreateWindowSurface");
462 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Block3762c312012-01-06 19:20:56 +0000463 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams803626f2011-04-06 17:52:23 -0700464 }
465
Jason Sams5316b9e2011-09-13 15:41:01 -0700466 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams803626f2011-04-06 17:52:23 -0700467 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
468 dc->gl.egl.surface, dc->gl.egl.context);
469 checkEglError("eglMakeCurrent", ret);
470 }
Jason Sams5316b9e2011-09-13 15:41:01 -0700471 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams803626f2011-04-06 17:52:23 -0700472 return true;
473}
474
475void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Samsfcf72312011-04-20 15:09:01 -0700476 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams5316b9e2011-09-13 15:41:01 -0700477 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams803626f2011-04-06 17:52:23 -0700478}
479
Jason Sams17801f12012-01-12 14:22:21 -0800480void rsdGLSetPriority(const Context *rsc, int32_t priority) {
481 if (priority > 0) {
482 // Mark context as low priority.
483 ALOGV("low pri");
484 } else {
485 ALOGV("normal pri");
486 }
487}
488
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700489void rsdGLCheckError(const android::renderscript::Context *rsc,
490 const char *msg, bool isFatal) {
491 GLenum err = glGetError();
492 if (err != GL_NO_ERROR) {
493 char buf[1024];
494 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
495
496 if (isFatal) {
497 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
498 } else {
499 switch (err) {
500 case GL_OUT_OF_MEMORY:
501 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
502 break;
503 default:
504 rsc->setError(RS_ERROR_DRIVER, buf);
505 break;
506 }
507 }
508
Steve Block3762c312012-01-06 19:20:56 +0000509 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchouk407cae92011-05-06 14:59:45 -0700510 }
511
512}
Alex Sakhartchouk20c9c922012-02-24 14:22:34 -0800513
514void rsdGLClearColor(const android::renderscript::Context *rsc,
515 float r, float g, float b, float a) {
516 RSD_CALL_GL(glClearColor, r, g, b, a);
517 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
518}
519
520void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
521 RSD_CALL_GL(glClearDepthf, v);
522 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
523}
524
525void rsdGLFinish(const android::renderscript::Context *rsc) {
526 RSD_CALL_GL(glFinish);
527}
528
529void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
530 float x1, float y1, float z1, float u1, float v1,
531 float x2, float y2, float z2, float u2, float v2,
532 float x3, float y3, float z3, float u3, float v3,
533 float x4, float y4, float z4, float u4, float v4) {
534
535 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
536 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
537
538 RsdVertexArray::Attrib attribs[2];
539 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
540 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
541
542 RsdVertexArray va(attribs, 2);
543 va.setup(rsc);
544
545 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
546}