blob: a935e6f8054d5a36e593974fe080b366374ba2f5 [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
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700157 dc->gl.shaderCache->cleanupAll();
158 delete dc->gl.shaderCache;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700159 delete dc->gl.vertexArrayState;
160
Jason Sams4b3de472011-04-06 17:52:23 -0700161 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
Jason Sams2382aba2011-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 Sams4b3de472011-04-06 17:52:23 -0700165 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
Jason Sams2382aba2011-09-13 15:41:01 -0700166 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700167 }
Jason Sams2382aba2011-09-13 15:41:01 -0700168 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
Jason Sams4b3de472011-04-06 17:52:23 -0700169 checkEglError("eglDestroyContext");
170 }
171
172 gGLContextCount--;
173 if (!gGLContextCount) {
Jason Sams2382aba2011-09-13 15:41:01 -0700174 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
Jason Sams4b3de472011-04-06 17:52:23 -0700175 }
176}
177
Alex Sakhartchoukda7a1482012-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 Sams4b3de472011-04-06 17:52:23 -0700182
Jason Sams4b3de472011-04-06 17:52:23 -0700183 EGLint *configAttribsPtr = configAttribs;
Jason Sams4b3de472011-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 Agopian67605d72011-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 Sams4b3de472011-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 Sakhartchoukda7a1482012-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 Sams4b3de472011-04-06 17:52:23 -0700231 configAttribsPtr[0] = EGL_NONE;
Alex Sakhartchoukda7a1482012-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 Sams4b3de472011-04-06 17:52:23 -0700242
Steve Block65982012011-10-20 11:56:00 +0100243 ALOGV("%p initEGL start", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700244 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700245 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
246 checkEglError("eglGetDisplay");
247
Jason Sams2382aba2011-09-13 15:41:01 -0700248 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
249 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
Jason Sams4b3de472011-04-06 17:52:23 -0700250 checkEglError("eglInitialize");
251
Mathias Agopian67605d72011-07-06 16:35:30 -0700252 EGLBoolean ret;
253
254 EGLint numConfigs = -1, n = 0;
Jason Sams2382aba2011-09-13 15:41:01 -0700255 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Alex Sakhartchoukda7a1482012-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 Agopian67605d72011-07-06 16:35:30 -0700268
Jason Sams5f27d6f2012-02-07 15:32:08 -0800269 eglSwapInterval(dc->gl.egl.display, 0);
270
Mathias Agopian67605d72011-07-06 16:35:30 -0700271 if (numConfigs) {
272 EGLConfig* const configs = new EGLConfig[numConfigs];
273
Jason Sams2382aba2011-09-13 15:41:01 -0700274 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian67605d72011-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 Blockaf12ac62012-01-06 19:20:56 +0000279 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian67605d72011-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 Sams4b3de472011-04-06 17:52:23 -0700311 }
312
Jason Sams4b3de472011-04-06 17:52:23 -0700313 //if (props.mLogVisual) {
Stephen Hines9db7fe22011-04-20 17:08:14 -0700314 if (0) {
Jason Sams4b3de472011-04-06 17:52:23 -0700315 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9db7fe22011-04-20 17:08:14 -0700316 }
Jason Sams4b3de472011-04-06 17:52:23 -0700317 //}
318
Jason Sams2382aba2011-09-13 15:41:01 -0700319 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams4b3de472011-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 Blockaf12ac62012-01-06 19:20:56 +0000324 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700325 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700326 return false;
327 }
328 gGLContextCount++;
329
Daniel Lam8ce904d2012-03-23 19:44:11 -0700330 // Create a BufferQueue with a fake consumer
331 sp<BufferQueue> bq = new BufferQueue();
Daniel Lam0e8435a2012-03-28 23:52:49 -0700332 bq->consumerConnect(new DummyConsumer());
Daniel Lam8ce904d2012-03-23 19:44:11 -0700333 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(bq)));
334
Alex Sakhartchouk5575cf12012-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 Sams4b3de472011-04-06 17:52:23 -0700338
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -0800339 checkEglError("eglCreateWindowSurface");
Jason Sams4b3de472011-04-06 17:52:23 -0700340 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -0800341 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700342 rsdGLShutdown(rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700343 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700344 return false;
345 }
346
Jason Sams2382aba2011-09-13 15:41:01 -0700347 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian67605d72011-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 Sams4b3de472011-04-06 17:52:23 -0700350 if (ret == EGL_FALSE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000351 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams4b3de472011-04-06 17:52:23 -0700352 checkEglError("eglMakeCurrent", ret);
353 rsdGLShutdown(rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700354 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-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 Block65982012011-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 Sams4b3de472011-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 Blockaf12ac62012-01-06 19:20:56 +0000380 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams4b3de472011-04-06 17:52:23 -0700381 rsdGLShutdown(rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700382 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-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 Agopian91702752012-01-29 22:20:50 -0800400 dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700401 "GL_IMG_texture_npot");
Mathias Agopian91702752012-01-29 22:20:50 -0800402 dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-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 Hines9db7fe22011-04-20 17:08:14 -0700411 if (0) {
412 DumpDebug(dc);
413 }
Jason Sams4b3de472011-04-06 17:52:23 -0700414
Alex Sakhartchouka04e30d2011-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 Sakhartchouka9495242011-06-16 11:05:13 -0700418 dc->gl.currentFrameBuffer = NULL;
Jason Sams9719bd42012-01-12 14:22:21 -0800419 dc->mHasGraphics = true;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700420
Steve Block65982012011-10-20 11:56:00 +0100421 ALOGV("%p initGLThread end", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700422 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700423 return true;
424}
425
426
Jason Samsb3220332012-04-02 14:41:54 -0700427bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700428 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700429
430 EGLBoolean ret;
Jason Samsb3220332012-04-02 14:41:54 -0700431 if (dc->gl.egl.surface != NULL) {
Jason Sams2382aba2011-09-13 15:41:01 -0700432 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700433 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
434 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
435 checkEglError("eglMakeCurrent", ret);
436
Jason Sams2382aba2011-09-13 15:41:01 -0700437 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700438 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
439 checkEglError("eglDestroySurface", ret);
440
441 dc->gl.egl.surface = NULL;
Jason Sams4b3de472011-04-06 17:52:23 -0700442 }
443
Jason Samsb3220332012-04-02 14:41:54 -0700444 if (dc->gl.currentWndSurface != NULL) {
445 dc->gl.currentWndSurface->decStrong(NULL);
Jason Samsc33e6902011-06-20 16:58:04 -0700446 }
447
Jason Samsb3220332012-04-02 14:41:54 -0700448 dc->gl.currentWndSurface = (ANativeWindow *)sur;
449 if (dc->gl.currentWndSurface != NULL) {
450 dc->gl.currentWndSurface->incStrong(NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700451
Jason Sams2382aba2011-09-13 15:41:01 -0700452 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700453 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
Jason Samsb3220332012-04-02 14:41:54 -0700454 dc->gl.currentWndSurface, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700455 checkEglError("eglCreateWindowSurface");
456 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000457 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700458 }
459
Jason Sams2382aba2011-09-13 15:41:01 -0700460 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700461 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
462 dc->gl.egl.surface, dc->gl.egl.context);
463 checkEglError("eglMakeCurrent", ret);
464 }
Jason Sams2382aba2011-09-13 15:41:01 -0700465 rsc->setWatchdogGL(NULL, 0, NULL);
Jason Sams4b3de472011-04-06 17:52:23 -0700466 return true;
467}
468
Jason Samsb3220332012-04-02 14:41:54 -0700469bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
470 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
471
472 if (dc->gl.wndSurface != NULL) {
473 dc->gl.wndSurface->decStrong(NULL);
474 dc->gl.wndSurface = NULL;
475 }
476 if(w && h) {
477 // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
478 // pbuffer to avoid this pitfall.
479 dc->gl.wndSurface = (ANativeWindow *)sur;
480 if (dc->gl.wndSurface != NULL) {
481 dc->gl.wndSurface->incStrong(NULL);
482 }
483 }
484
485 return rsdGLSetInternalSurface(rsc, sur);
486}
487
Jason Sams4b3de472011-04-06 17:52:23 -0700488void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700489 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams2382aba2011-09-13 15:41:01 -0700490 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700491}
492
Jason Sams9719bd42012-01-12 14:22:21 -0800493void rsdGLSetPriority(const Context *rsc, int32_t priority) {
494 if (priority > 0) {
495 // Mark context as low priority.
496 ALOGV("low pri");
497 } else {
498 ALOGV("normal pri");
499 }
500}
501
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700502void rsdGLCheckError(const android::renderscript::Context *rsc,
503 const char *msg, bool isFatal) {
504 GLenum err = glGetError();
505 if (err != GL_NO_ERROR) {
506 char buf[1024];
507 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
508
509 if (isFatal) {
510 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
511 } else {
512 switch (err) {
513 case GL_OUT_OF_MEMORY:
514 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
515 break;
516 default:
517 rsc->setError(RS_ERROR_DRIVER, buf);
518 break;
519 }
520 }
521
Steve Blockaf12ac62012-01-06 19:20:56 +0000522 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700523 }
524
525}
Alex Sakhartchouk653b53e2012-02-24 14:22:34 -0800526
527void rsdGLClearColor(const android::renderscript::Context *rsc,
528 float r, float g, float b, float a) {
529 RSD_CALL_GL(glClearColor, r, g, b, a);
530 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
531}
532
533void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
534 RSD_CALL_GL(glClearDepthf, v);
535 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
536}
537
538void rsdGLFinish(const android::renderscript::Context *rsc) {
539 RSD_CALL_GL(glFinish);
540}
541
542void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
543 float x1, float y1, float z1, float u1, float v1,
544 float x2, float y2, float z2, float u2, float v2,
545 float x3, float y3, float z3, float u3, float v3,
546 float x4, float y4, float z4, float u4, float v4) {
547
548 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
549 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
550
551 RsdVertexArray::Attrib attribs[2];
552 attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
553 attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
554
555 RsdVertexArray va(attribs, 2);
556 va.setup(rsc);
557
558 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
559}