blob: e8034878d01db69f5e3bed1957a38607813fb40b [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
Mathias Agopian33c622e2013-02-14 17:34:06 -080045#include <gui/Surface.h>
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -080046
Jason Sams4b3de472011-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 Agopiane2559292012-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 Sams4b3de472011-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 Agopian67605d72011-07-06 16:35:30 -0700128 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
129 if (returnVal) {
Steve Block65982012011-10-20 11:56:00 +0100130 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
Jason Sams4b3de472011-04-06 17:52:23 -0700131 }
132 }
133}
134
Jason Sams87fe59a2011-04-20 15:09:01 -0700135static void DumpDebug(RsdHal *dc) {
Steve Blockaf12ac62012-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 Sams4b3de472011-04-06 17:52:23 -0700138 dc->gl.egl.display);
Steve Blockaf12ac62012-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 Sams4b3de472011-04-06 17:52:23 -0700144
Steve Block65982012011-10-20 11:56:00 +0100145 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
Jason Sams4b3de472011-04-06 17:52:23 -0700146 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
Steve Block65982012011-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 Sams4b3de472011-04-06 17:52:23 -0700149 dc->gl.gl.maxFragmentUniformVectors);
Steve Block65982012011-10-20 11:56:00 +0100150 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
Jason Sams4b3de472011-04-06 17:52:23 -0700151}
152
153void rsdGLShutdown(const Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700154 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700155
Chris Wailes44bef6f2014-08-12 13:51:10 -0700156 rsdGLSetSurface(rsc, 0, 0, nullptr);
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
269 if (numConfigs) {
270 EGLConfig* const configs = new EGLConfig[numConfigs];
271
Jason Sams2382aba2011-09-13 15:41:01 -0700272 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian67605d72011-07-06 16:35:30 -0700273 ret = eglChooseConfig(dc->gl.egl.display,
274 configAttribs, configs, numConfigs, &n);
275 if (!ret || !n) {
276 checkEglError("eglChooseConfig", ret);
Steve Blockaf12ac62012-01-06 19:20:56 +0000277 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian67605d72011-07-06 16:35:30 -0700278 }
279
280 // The first config is guaranteed to over-satisfy the constraints
281 dc->gl.egl.config = configs[0];
282
283 // go through the list and skip configs that over-satisfy our needs
284 for (int i=0 ; i<n ; i++) {
285 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
286 EGLint alphaSize;
287 eglGetConfigAttrib(dc->gl.egl.display,
288 configs[i], EGL_ALPHA_SIZE, &alphaSize);
289 if (alphaSize > 0) {
290 continue;
291 }
292 }
293
294 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
295 EGLint depthSize;
296 eglGetConfigAttrib(dc->gl.egl.display,
297 configs[i], EGL_DEPTH_SIZE, &depthSize);
298 if (depthSize > 0) {
299 continue;
300 }
301 }
302
303 // Found one!
304 dc->gl.egl.config = configs[i];
305 break;
306 }
307
308 delete [] configs;
Jason Sams4b3de472011-04-06 17:52:23 -0700309 }
310
Jason Sams4b3de472011-04-06 17:52:23 -0700311 //if (props.mLogVisual) {
Stephen Hines9db7fe22011-04-20 17:08:14 -0700312 if (0) {
Jason Sams4b3de472011-04-06 17:52:23 -0700313 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9db7fe22011-04-20 17:08:14 -0700314 }
Jason Sams4b3de472011-04-06 17:52:23 -0700315 //}
316
Jason Sams2382aba2011-09-13 15:41:01 -0700317 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700318 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
319 EGL_NO_CONTEXT, context_attribs2);
320 checkEglError("eglCreateContext");
321 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000322 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700323 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700324 return false;
325 }
326 gGLContextCount++;
327
Mathias Agopian3318d182013-07-16 22:56:00 -0700328 EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
329 rsc->setWatchdogGL("eglCreatePbufferSurface", __LINE__, __FILE__);
330 dc->gl.egl.surfaceDefault = eglCreatePbufferSurface(dc->gl.egl.display, dc->gl.egl.config,
331 pbuffer_attribs);
332 checkEglError("eglCreatePbufferSurface");
Jason Sams4b3de472011-04-06 17:52:23 -0700333 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Mathias Agopian3318d182013-07-16 22:56:00 -0700334 ALOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700335 rsdGLShutdown(rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700336 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700337 return false;
338 }
339
Jason Sams2382aba2011-09-13 15:41:01 -0700340 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian67605d72011-07-06 16:35:30 -0700341 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
342 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
Jason Sams4b3de472011-04-06 17:52:23 -0700343 if (ret == EGL_FALSE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000344 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams4b3de472011-04-06 17:52:23 -0700345 checkEglError("eglMakeCurrent", ret);
346 rsdGLShutdown(rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700347 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700348 return false;
349 }
350
351 dc->gl.gl.version = glGetString(GL_VERSION);
352 dc->gl.gl.vendor = glGetString(GL_VENDOR);
353 dc->gl.gl.renderer = glGetString(GL_RENDERER);
354 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
355
Steve Block65982012011-10-20 11:56:00 +0100356 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
357 //ALOGV("GL Version %s", mGL.mVersion);
358 //ALOGV("GL Vendor %s", mGL.mVendor);
359 //ALOGV("GL Renderer %s", mGL.mRenderer);
360 //ALOGV("GL Extensions %s", mGL.mExtensions);
Jason Sams4b3de472011-04-06 17:52:23 -0700361
Chris Wailes44bef6f2014-08-12 13:51:10 -0700362 const char *verptr = nullptr;
Jason Sams4b3de472011-04-06 17:52:23 -0700363 if (strlen((const char *)dc->gl.gl.version) > 9) {
364 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
365 verptr = (const char *)dc->gl.gl.version + 12;
366 }
367 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
368 verptr = (const char *)dc->gl.gl.version + 9;
369 }
370 }
371
372 if (!verptr) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000373 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams4b3de472011-04-06 17:52:23 -0700374 rsdGLShutdown(rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700375 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700376 return false;
377 } else {
378 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
379 }
380
381 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
382 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
383 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
384
385 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
386 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
387
388 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
389 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
390
Chris Wailes44bef6f2014-08-12 13:51:10 -0700391 dc->gl.gl.OES_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700392 "GL_OES_texture_npot");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700393 dc->gl.gl.IMG_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700394 "GL_IMG_texture_npot");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700395 dc->gl.gl.NV_texture_npot_2D_mipmap = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700396 "GL_NV_texture_npot_2D_mipmap");
397 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700398 bool hasAniso = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700399 "GL_EXT_texture_filter_anisotropic");
400 if (hasAniso) {
401 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
402 }
403
Stephen Hines9db7fe22011-04-20 17:08:14 -0700404 if (0) {
405 DumpDebug(dc);
406 }
Jason Sams4b3de472011-04-06 17:52:23 -0700407
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700408 dc->gl.shaderCache = new RsdShaderCache();
409 dc->gl.vertexArrayState = new RsdVertexArrayState();
410 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700411 dc->gl.currentFrameBuffer = nullptr;
Jason Sams9719bd42012-01-12 14:22:21 -0800412 dc->mHasGraphics = true;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700413
Steve Block65982012011-10-20 11:56:00 +0100414 ALOGV("%p initGLThread end", rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700415 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700416 return true;
417}
418
419
Jason Samsb3220332012-04-02 14:41:54 -0700420bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700421 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700422
423 EGLBoolean ret;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700424 if (dc->gl.egl.surface != nullptr) {
Jason Sams2382aba2011-09-13 15:41:01 -0700425 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700426 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
427 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
428 checkEglError("eglMakeCurrent", ret);
429
Jason Sams2382aba2011-09-13 15:41:01 -0700430 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700431 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
432 checkEglError("eglDestroySurface", ret);
433
Chris Wailes44bef6f2014-08-12 13:51:10 -0700434 dc->gl.egl.surface = nullptr;
Jason Sams4b3de472011-04-06 17:52:23 -0700435 }
436
Chris Wailes44bef6f2014-08-12 13:51:10 -0700437 if (dc->gl.currentWndSurface != nullptr) {
438 dc->gl.currentWndSurface->decStrong(nullptr);
Jason Samsc33e6902011-06-20 16:58:04 -0700439 }
440
Jason Samsb3220332012-04-02 14:41:54 -0700441 dc->gl.currentWndSurface = (ANativeWindow *)sur;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700442 if (dc->gl.currentWndSurface != nullptr) {
443 dc->gl.currentWndSurface->incStrong(nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700444
Jason Sams2382aba2011-09-13 15:41:01 -0700445 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700446 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
Chris Wailes44bef6f2014-08-12 13:51:10 -0700447 dc->gl.currentWndSurface, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700448 checkEglError("eglCreateWindowSurface");
449 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000450 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700451 }
452
Jason Sams2382aba2011-09-13 15:41:01 -0700453 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700454 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
455 dc->gl.egl.surface, dc->gl.egl.context);
456 checkEglError("eglMakeCurrent", ret);
457 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700458 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700459 return true;
460}
461
Jason Samsb3220332012-04-02 14:41:54 -0700462bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
463 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
464
Chris Wailes44bef6f2014-08-12 13:51:10 -0700465 if (dc->gl.wndSurface != nullptr) {
466 dc->gl.wndSurface->decStrong(nullptr);
467 dc->gl.wndSurface = nullptr;
Jason Samsb3220332012-04-02 14:41:54 -0700468 }
469 if(w && h) {
470 // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
471 // pbuffer to avoid this pitfall.
472 dc->gl.wndSurface = (ANativeWindow *)sur;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700473 if (dc->gl.wndSurface != nullptr) {
474 dc->gl.wndSurface->incStrong(nullptr);
Jason Samsb3220332012-04-02 14:41:54 -0700475 }
476 }
477
478 return rsdGLSetInternalSurface(rsc, sur);
479}
480
Jason Sams4b3de472011-04-06 17:52:23 -0700481void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700482 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams2382aba2011-09-13 15:41:01 -0700483 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700484}
485
Jason Sams9719bd42012-01-12 14:22:21 -0800486void rsdGLSetPriority(const Context *rsc, int32_t priority) {
487 if (priority > 0) {
488 // Mark context as low priority.
489 ALOGV("low pri");
490 } else {
491 ALOGV("normal pri");
492 }
493}
494
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700495void rsdGLCheckError(const android::renderscript::Context *rsc,
496 const char *msg, bool isFatal) {
497 GLenum err = glGetError();
498 if (err != GL_NO_ERROR) {
499 char buf[1024];
500 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
501
502 if (isFatal) {
503 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
504 } else {
505 switch (err) {
506 case GL_OUT_OF_MEMORY:
507 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
508 break;
509 default:
510 rsc->setError(RS_ERROR_DRIVER, buf);
511 break;
512 }
513 }
514
Steve Blockaf12ac62012-01-06 19:20:56 +0000515 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700516 }
517
518}
Alex Sakhartchouk653b53e2012-02-24 14:22:34 -0800519
520void rsdGLClearColor(const android::renderscript::Context *rsc,
521 float r, float g, float b, float a) {
522 RSD_CALL_GL(glClearColor, r, g, b, a);
523 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
524}
525
526void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
527 RSD_CALL_GL(glClearDepthf, v);
528 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
529}
530
531void rsdGLFinish(const android::renderscript::Context *rsc) {
532 RSD_CALL_GL(glFinish);
533}
534
535void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
536 float x1, float y1, float z1, float u1, float v1,
537 float x2, float y2, float z2, float u2, float v2,
538 float x3, float y3, float z3, float u3, float v3,
539 float x4, float y4, float z4, float u4, float v4) {
540
541 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
542 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
543
544 RsdVertexArray::Attrib attribs[2];
Tim Murraye195a3f2014-03-13 15:04:58 -0700545
546 attribs[0].set(GL_FLOAT, 3, 12, false, (size_t)vtx, "ATTRIB_position");
547 attribs[1].set(GL_FLOAT, 2, 8, false, (size_t)tex, "ATTRIB_texture0");
Alex Sakhartchouk653b53e2012-02-24 14:22:34 -0800548
549 RsdVertexArray va(attribs, 2);
550 va.setup(rsc);
551
552 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
553}