blob: 80fa1371ad5cec4604ea1fe71544836b38bca1a4 [file] [log] [blame]
Jason Sams4b3de472011-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 Agopianb8eba192012-02-24 18:25:41 -080019
20#include <system/window.h>
Jason Sams4b3de472011-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 Sams4b3de472011-04-06 17:52:23 -070033#include <string.h>
34
Jason Sams4b3de472011-04-06 17:52:23 -070035#include "rsdCore.h"
36#include "rsdGL.h"
37
38#include <malloc.h>
39#include "rsContext.h"
Alex Sakhartchouk4edf0302012-03-09 10:47:27 -080040#include "rsDevice.h"
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070041#include "rsdShaderCache.h"
42#include "rsdVertexArray.h"
Alex Sakhartchouka9495242011-06-16 11:05:13 -070043#include "rsdFrameBufferObj.h"
Jason Sams4b3de472011-04-06 17:52:23 -070044
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -080045#include <gui/SurfaceTextureClient.h>
Daniel Lam8ce904d2012-03-23 19:44:11 -070046#include <gui/DummyConsumer.h>
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -080047
Jason Sams4b3de472011-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 Agopiane2559292012-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 Sams4b3de472011-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 Agopian67605d72011-07-06 16:35:30 -0700129 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
130 if (returnVal) {
Steve Block65982012011-10-20 11:56:00 +0100131 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
Jason Sams4b3de472011-04-06 17:52:23 -0700132 }
133 }
134}
135
Jason Sams87fe59a2011-04-20 15:09:01 -0700136static void DumpDebug(RsdHal *dc) {
Steve Blockaf12ac62012-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 Sams4b3de472011-04-06 17:52:23 -0700139 dc->gl.egl.display);
Steve Blockaf12ac62012-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 Sams4b3de472011-04-06 17:52:23 -0700145
Steve Block65982012011-10-20 11:56:00 +0100146 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
Jason Sams4b3de472011-04-06 17:52:23 -0700147 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
Steve Block65982012011-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 Sams4b3de472011-04-06 17:52:23 -0700150 dc->gl.gl.maxFragmentUniformVectors);
Steve Block65982012011-10-20 11:56:00 +0100151 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
Jason Sams4b3de472011-04-06 17:52:23 -0700152}
153
154void rsdGLShutdown(const Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700155 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700156
Jason Sams1d892432012-05-08 13:12:46 -0700157 rsdGLSetSurface(rsc, 0, 0, NULL);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700158 dc->gl.shaderCache->cleanupAll();
159 delete dc->gl.shaderCache;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700160 delete dc->gl.vertexArrayState;
161
Jason Sams4b3de472011-04-06 17:52:23 -0700162 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
Jason Sams2382aba2011-09-13 15:41:01 -0700163 RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
164 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
165 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
Jason Sams4b3de472011-04-06 17:52:23 -0700166 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
Jason Sams2382aba2011-09-13 15:41:01 -0700167 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700168 }
Jason Sams2382aba2011-09-13 15:41:01 -0700169 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
Jason Sams4b3de472011-04-06 17:52:23 -0700170 checkEglError("eglDestroyContext");
171 }
172
173 gGLContextCount--;
174 if (!gGLContextCount) {
Jason Sams2382aba2011-09-13 15:41:01 -0700175 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
Jason Sams4b3de472011-04-06 17:52:23 -0700176 }
177}
178
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800179void getConfigData(const Context *rsc,
180 EGLint *configAttribs, size_t configAttribsLen,
181 uint32_t numSamples) {
182 memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
Jason Sams4b3de472011-04-06 17:52:23 -0700183
Jason Sams4b3de472011-04-06 17:52:23 -0700184 EGLint *configAttribsPtr = configAttribs;
Jason Sams4b3de472011-04-06 17:52:23 -0700185
186 configAttribsPtr[0] = EGL_SURFACE_TYPE;
187 configAttribsPtr[1] = EGL_WINDOW_BIT;
188 configAttribsPtr += 2;
189
190 configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
191 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
192 configAttribsPtr += 2;
193
Mathias Agopian67605d72011-07-06 16:35:30 -0700194 configAttribsPtr[0] = EGL_RED_SIZE;
195 configAttribsPtr[1] = 8;
196 configAttribsPtr += 2;
197
198 configAttribsPtr[0] = EGL_GREEN_SIZE;
199 configAttribsPtr[1] = 8;
200 configAttribsPtr += 2;
201
202 configAttribsPtr[0] = EGL_BLUE_SIZE;
203 configAttribsPtr[1] = 8;
204 configAttribsPtr += 2;
205
206 if (rsc->mUserSurfaceConfig.alphaMin > 0) {
207 configAttribsPtr[0] = EGL_ALPHA_SIZE;
208 configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
209 configAttribsPtr += 2;
210 }
211
Jason Sams4b3de472011-04-06 17:52:23 -0700212 if (rsc->mUserSurfaceConfig.depthMin > 0) {
213 configAttribsPtr[0] = EGL_DEPTH_SIZE;
214 configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
215 configAttribsPtr += 2;
216 }
217
218 if (rsc->mDev->mForceSW) {
219 configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
220 configAttribsPtr[1] = EGL_SLOW_CONFIG;
221 configAttribsPtr += 2;
222 }
223
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800224 if (numSamples > 1) {
225 configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
226 configAttribsPtr[1] = 1;
227 configAttribsPtr[2] = EGL_SAMPLES;
228 configAttribsPtr[3] = numSamples;
229 configAttribsPtr += 4;
230 }
231
Jason Sams4b3de472011-04-06 17:52:23 -0700232 configAttribsPtr[0] = EGL_NONE;
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800233 rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
234}
235
236bool rsdGLInit(const Context *rsc) {
237 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
238
239 dc->gl.egl.numConfigs = -1;
240
241 EGLint configAttribs[128];
242 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
Jason Sams4b3de472011-04-06 17:52:23 -0700243
Steve Block65982012011-10-20 11:56:00 +0100244 ALOGV("%p initEGL start", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700245 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700246 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
247 checkEglError("eglGetDisplay");
248
Jason Sams2382aba2011-09-13 15:41:01 -0700249 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
250 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
Jason Sams4b3de472011-04-06 17:52:23 -0700251 checkEglError("eglInitialize");
252
Mathias Agopian67605d72011-07-06 16:35:30 -0700253 EGLBoolean ret;
254
255 EGLint numConfigs = -1, n = 0;
Jason Sams2382aba2011-09-13 15:41:01 -0700256 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800257
258 // Try minding a multisample config that matches the user request
259 uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
260 uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
261 for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
262 getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
263 ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
264 checkEglError("eglGetConfigs", ret);
265 if (numConfigs > 0) {
266 break;
267 }
268 }
Mathias Agopian67605d72011-07-06 16:35:30 -0700269
Jason Sams5f27d6f2012-02-07 15:32:08 -0800270 eglSwapInterval(dc->gl.egl.display, 0);
271
Mathias Agopian67605d72011-07-06 16:35:30 -0700272 if (numConfigs) {
273 EGLConfig* const configs = new EGLConfig[numConfigs];
274
Jason Sams2382aba2011-09-13 15:41:01 -0700275 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian67605d72011-07-06 16:35:30 -0700276 ret = eglChooseConfig(dc->gl.egl.display,
277 configAttribs, configs, numConfigs, &n);
278 if (!ret || !n) {
279 checkEglError("eglChooseConfig", ret);
Steve Blockaf12ac62012-01-06 19:20:56 +0000280 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian67605d72011-07-06 16:35:30 -0700281 }
282
283 // The first config is guaranteed to over-satisfy the constraints
284 dc->gl.egl.config = configs[0];
285
286 // go through the list and skip configs that over-satisfy our needs
287 for (int i=0 ; i<n ; i++) {
288 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
289 EGLint alphaSize;
290 eglGetConfigAttrib(dc->gl.egl.display,
291 configs[i], EGL_ALPHA_SIZE, &alphaSize);
292 if (alphaSize > 0) {
293 continue;
294 }
295 }
296
297 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
298 EGLint depthSize;
299 eglGetConfigAttrib(dc->gl.egl.display,
300 configs[i], EGL_DEPTH_SIZE, &depthSize);
301 if (depthSize > 0) {
302 continue;
303 }
304 }
305
306 // Found one!
307 dc->gl.egl.config = configs[i];
308 break;
309 }
310
311 delete [] configs;
Jason Sams4b3de472011-04-06 17:52:23 -0700312 }
313
Jason Sams4b3de472011-04-06 17:52:23 -0700314 //if (props.mLogVisual) {
Stephen Hines9db7fe22011-04-20 17:08:14 -0700315 if (0) {
Jason Sams4b3de472011-04-06 17:52:23 -0700316 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9db7fe22011-04-20 17:08:14 -0700317 }
Jason Sams4b3de472011-04-06 17:52:23 -0700318 //}
319
Jason Sams2382aba2011-09-13 15:41:01 -0700320 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700321 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
322 EGL_NO_CONTEXT, context_attribs2);
323 checkEglError("eglCreateContext");
324 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000325 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700326 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700327 return false;
328 }
329 gGLContextCount++;
330
Daniel Lam8ce904d2012-03-23 19:44:11 -0700331 // Create a BufferQueue with a fake consumer
332 sp<BufferQueue> bq = new BufferQueue();
Daniel Lam0e8435a2012-03-28 23:52:49 -0700333 bq->consumerConnect(new DummyConsumer());
Daniel Lam8ce904d2012-03-23 19:44:11 -0700334 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(bq)));
335
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -0800336 dc->gl.egl.surfaceDefault = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
337 static_cast<ANativeWindow*>(stc.get()),
338 NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700339
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -0800340 checkEglError("eglCreateWindowSurface");
Jason Sams4b3de472011-04-06 17:52:23 -0700341 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -0800342 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700343 rsdGLShutdown(rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700344 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700345 return false;
346 }
347
Jason Sams2382aba2011-09-13 15:41:01 -0700348 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian67605d72011-07-06 16:35:30 -0700349 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
350 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
Jason Sams4b3de472011-04-06 17:52:23 -0700351 if (ret == EGL_FALSE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000352 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams4b3de472011-04-06 17:52:23 -0700353 checkEglError("eglMakeCurrent", ret);
354 rsdGLShutdown(rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700355 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700356 return false;
357 }
358
359 dc->gl.gl.version = glGetString(GL_VERSION);
360 dc->gl.gl.vendor = glGetString(GL_VENDOR);
361 dc->gl.gl.renderer = glGetString(GL_RENDERER);
362 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
363
Steve Block65982012011-10-20 11:56:00 +0100364 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
365 //ALOGV("GL Version %s", mGL.mVersion);
366 //ALOGV("GL Vendor %s", mGL.mVendor);
367 //ALOGV("GL Renderer %s", mGL.mRenderer);
368 //ALOGV("GL Extensions %s", mGL.mExtensions);
Jason Sams4b3de472011-04-06 17:52:23 -0700369
370 const char *verptr = NULL;
371 if (strlen((const char *)dc->gl.gl.version) > 9) {
372 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
373 verptr = (const char *)dc->gl.gl.version + 12;
374 }
375 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
376 verptr = (const char *)dc->gl.gl.version + 9;
377 }
378 }
379
380 if (!verptr) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000381 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams4b3de472011-04-06 17:52:23 -0700382 rsdGLShutdown(rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700383 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700384 return false;
385 } else {
386 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
387 }
388
389 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
390 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
391 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
392
393 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
394 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
395
396 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
397 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
398
399 dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
400 "GL_OES_texture_npot");
Mathias Agopian91702752012-01-29 22:20:50 -0800401 dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700402 "GL_IMG_texture_npot");
Mathias Agopian91702752012-01-29 22:20:50 -0800403 dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700404 "GL_NV_texture_npot_2D_mipmap");
405 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
406 bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
407 "GL_EXT_texture_filter_anisotropic");
408 if (hasAniso) {
409 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
410 }
411
Stephen Hines9db7fe22011-04-20 17:08:14 -0700412 if (0) {
413 DumpDebug(dc);
414 }
Jason Sams4b3de472011-04-06 17:52:23 -0700415
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700416 dc->gl.shaderCache = new RsdShaderCache();
417 dc->gl.vertexArrayState = new RsdVertexArrayState();
418 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
Alex Sakhartchouka9495242011-06-16 11:05:13 -0700419 dc->gl.currentFrameBuffer = NULL;
Jason Sams9719bd42012-01-12 14:22:21 -0800420 dc->mHasGraphics = true;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700421
Steve Block65982012011-10-20 11:56:00 +0100422 ALOGV("%p initGLThread end", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700423 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700424 return true;
425}
426
427
Jason Samsb3220332012-04-02 14:41:54 -0700428bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700429 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700430
431 EGLBoolean ret;
Jason Samsb3220332012-04-02 14:41:54 -0700432 if (dc->gl.egl.surface != NULL) {
Jason Sams2382aba2011-09-13 15:41:01 -0700433 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700434 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
435 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
436 checkEglError("eglMakeCurrent", ret);
437
Jason Sams2382aba2011-09-13 15:41:01 -0700438 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700439 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
440 checkEglError("eglDestroySurface", ret);
441
442 dc->gl.egl.surface = NULL;
Jason Sams4b3de472011-04-06 17:52:23 -0700443 }
444
Jason Samsb3220332012-04-02 14:41:54 -0700445 if (dc->gl.currentWndSurface != NULL) {
446 dc->gl.currentWndSurface->decStrong(NULL);
Jason Samsc33e6902011-06-20 16:58:04 -0700447 }
448
Jason Samsb3220332012-04-02 14:41:54 -0700449 dc->gl.currentWndSurface = (ANativeWindow *)sur;
450 if (dc->gl.currentWndSurface != NULL) {
451 dc->gl.currentWndSurface->incStrong(NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700452
Jason Sams2382aba2011-09-13 15:41:01 -0700453 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700454 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
Jason Samsb3220332012-04-02 14:41:54 -0700455 dc->gl.currentWndSurface, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700456 checkEglError("eglCreateWindowSurface");
457 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000458 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700459 }
460
Jason Sams2382aba2011-09-13 15:41:01 -0700461 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-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 Sams2382aba2011-09-13 15:41:01 -0700466 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700467 return true;
468}
469
Jason Samsb3220332012-04-02 14:41:54 -0700470bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
471 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
472
473 if (dc->gl.wndSurface != NULL) {
474 dc->gl.wndSurface->decStrong(NULL);
475 dc->gl.wndSurface = NULL;
476 }
477 if(w && h) {
478 // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
479 // pbuffer to avoid this pitfall.
480 dc->gl.wndSurface = (ANativeWindow *)sur;
481 if (dc->gl.wndSurface != NULL) {
482 dc->gl.wndSurface->incStrong(NULL);
483 }
484 }
485
486 return rsdGLSetInternalSurface(rsc, sur);
487}
488
Jason Sams4b3de472011-04-06 17:52:23 -0700489void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700490 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams2382aba2011-09-13 15:41:01 -0700491 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700492}
493
Jason Sams9719bd42012-01-12 14:22:21 -0800494void rsdGLSetPriority(const Context *rsc, int32_t priority) {
495 if (priority > 0) {
496 // Mark context as low priority.
497 ALOGV("low pri");
498 } else {
499 ALOGV("normal pri");
500 }
501}
502
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700503void rsdGLCheckError(const android::renderscript::Context *rsc,
504 const char *msg, bool isFatal) {
505 GLenum err = glGetError();
506 if (err != GL_NO_ERROR) {
507 char buf[1024];
508 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
509
510 if (isFatal) {
511 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
512 } else {
513 switch (err) {
514 case GL_OUT_OF_MEMORY:
515 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
516 break;
517 default:
518 rsc->setError(RS_ERROR_DRIVER, buf);
519 break;
520 }
521 }
522
Steve Blockaf12ac62012-01-06 19:20:56 +0000523 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700524 }
525
526}
Alex Sakhartchouk653b53e2012-02-24 14:22:34 -0800527
528void rsdGLClearColor(const android::renderscript::Context *rsc,
529 float r, float g, float b, float a) {
530 RSD_CALL_GL(glClearColor, r, g, b, a);
531 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
532}
533
534void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
535 RSD_CALL_GL(glClearDepthf, v);
536 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
537}
538
539void rsdGLFinish(const android::renderscript::Context *rsc) {
540 RSD_CALL_GL(glFinish);
541}
542
543void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
544 float x1, float y1, float z1, float u1, float v1,
545 float x2, float y2, float z2, float u2, float v2,
546 float x3, float y3, float z3, float u3, float v3,
547 float x4, float y4, float z4, float u4, float v4) {
548
549 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
550 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
551
552 RsdVertexArray::Attrib attribs[2];
553 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
554 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
555
556 RsdVertexArray va(attribs, 2);
557 va.setup(rsc);
558
559 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
560}