blob: beb2cf0edd13b600d2bbb9421f8b77cad990ef18 [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
Jason Sams4b3de472011-04-06 17:52:23 -070017#include <ui/PixelFormat.h>
Mathias Agopianb8eba192012-02-24 18:25:41 -080018
19#include <system/window.h>
Jason Sams4b3de472011-04-06 17:52:23 -070020
21#include <sys/types.h>
22#include <sys/resource.h>
23#include <sched.h>
24
25#include <cutils/properties.h>
26
27#include <GLES/gl.h>
28#include <GLES/glext.h>
29#include <GLES2/gl2.h>
30#include <GLES2/gl2ext.h>
31
Jason Sams4b3de472011-04-06 17:52:23 -070032#include <string.h>
33
Jason Sams4b3de472011-04-06 17:52:23 -070034#include "rsdCore.h"
35#include "rsdGL.h"
36
37#include <malloc.h>
38#include "rsContext.h"
Alex Sakhartchouk4edf0302012-03-09 10:47:27 -080039#include "rsDevice.h"
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -070040#include "rsdShaderCache.h"
41#include "rsdVertexArray.h"
Alex Sakhartchouka9495242011-06-16 11:05:13 -070042#include "rsdFrameBufferObj.h"
Jason Sams4b3de472011-04-06 17:52:23 -070043
Mathias Agopian33c622e2013-02-14 17:34:06 -080044#include <gui/Surface.h>
Alex Sakhartchouk5575cf12012-02-28 10:16:06 -080045
Jason Sams4b3de472011-04-06 17:52:23 -070046using namespace android;
47using namespace android::renderscript;
48
49static int32_t gGLContextCount = 0;
50
51static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
Mathias Agopiane2559292012-02-24 16:42:46 -080052 struct EGLUtils {
53 static const char *strerror(EGLint err) {
54 switch (err){
55 case EGL_SUCCESS: return "EGL_SUCCESS";
56 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
57 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
58 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
59 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
60 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
61 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
62 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
63 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
64 case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
65 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
66 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
67 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
68 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
69 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
70 default: return "UNKNOWN";
71 }
72 }
73 };
74
Jason Sams4b3de472011-04-06 17:52:23 -070075 if (returnVal != EGL_TRUE) {
76 fprintf(stderr, "%s() returned %d\n", op, returnVal);
77 }
78
79 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
80 = eglGetError()) {
81 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
82 error);
83 }
84}
85
86static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
87
88#define X(VAL) {VAL, #VAL}
89 struct {EGLint attribute; const char* name;} names[] = {
90 X(EGL_BUFFER_SIZE),
91 X(EGL_ALPHA_SIZE),
92 X(EGL_BLUE_SIZE),
93 X(EGL_GREEN_SIZE),
94 X(EGL_RED_SIZE),
95 X(EGL_DEPTH_SIZE),
96 X(EGL_STENCIL_SIZE),
97 X(EGL_CONFIG_CAVEAT),
98 X(EGL_CONFIG_ID),
99 X(EGL_LEVEL),
100 X(EGL_MAX_PBUFFER_HEIGHT),
101 X(EGL_MAX_PBUFFER_PIXELS),
102 X(EGL_MAX_PBUFFER_WIDTH),
103 X(EGL_NATIVE_RENDERABLE),
104 X(EGL_NATIVE_VISUAL_ID),
105 X(EGL_NATIVE_VISUAL_TYPE),
106 X(EGL_SAMPLES),
107 X(EGL_SAMPLE_BUFFERS),
108 X(EGL_SURFACE_TYPE),
109 X(EGL_TRANSPARENT_TYPE),
110 X(EGL_TRANSPARENT_RED_VALUE),
111 X(EGL_TRANSPARENT_GREEN_VALUE),
112 X(EGL_TRANSPARENT_BLUE_VALUE),
113 X(EGL_BIND_TO_TEXTURE_RGB),
114 X(EGL_BIND_TO_TEXTURE_RGBA),
115 X(EGL_MIN_SWAP_INTERVAL),
116 X(EGL_MAX_SWAP_INTERVAL),
117 X(EGL_LUMINANCE_SIZE),
118 X(EGL_ALPHA_MASK_SIZE),
119 X(EGL_COLOR_BUFFER_TYPE),
120 X(EGL_RENDERABLE_TYPE),
121 X(EGL_CONFORMANT),
122 };
123#undef X
124
125 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
126 EGLint value = -1;
Mathias Agopian67605d72011-07-06 16:35:30 -0700127 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
128 if (returnVal) {
Steve Block65982012011-10-20 11:56:00 +0100129 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
Jason Sams4b3de472011-04-06 17:52:23 -0700130 }
131 }
132}
133
Jason Sams87fe59a2011-04-20 15:09:01 -0700134static void DumpDebug(RsdHal *dc) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000135 ALOGE(" EGL ver %i %i", dc->gl.egl.majorVersion, dc->gl.egl.minorVersion);
136 ALOGE(" EGL context %p surface %p, Display=%p", dc->gl.egl.context, dc->gl.egl.surface,
Jason Sams4b3de472011-04-06 17:52:23 -0700137 dc->gl.egl.display);
Steve Blockaf12ac62012-01-06 19:20:56 +0000138 ALOGE(" GL vendor: %s", dc->gl.gl.vendor);
139 ALOGE(" GL renderer: %s", dc->gl.gl.renderer);
140 ALOGE(" GL Version: %s", dc->gl.gl.version);
141 ALOGE(" GL Extensions: %s", dc->gl.gl.extensions);
142 ALOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
Jason Sams4b3de472011-04-06 17:52:23 -0700143
Steve Block65982012011-10-20 11:56:00 +0100144 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
Jason Sams4b3de472011-04-06 17:52:23 -0700145 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
Steve Block65982012011-10-20 11:56:00 +0100146 ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
147 ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
Jason Sams4b3de472011-04-06 17:52:23 -0700148 dc->gl.gl.maxFragmentUniformVectors);
Steve Block65982012011-10-20 11:56:00 +0100149 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
Jason Sams4b3de472011-04-06 17:52:23 -0700150}
151
152void rsdGLShutdown(const Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700153 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700154
Chris Wailes44bef6f2014-08-12 13:51:10 -0700155 rsdGLSetSurface(rsc, 0, 0, nullptr);
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700156 dc->gl.shaderCache->cleanupAll();
157 delete dc->gl.shaderCache;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700158 delete dc->gl.vertexArrayState;
159
Jason Sams4b3de472011-04-06 17:52:23 -0700160 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
Jason Sams2382aba2011-09-13 15:41:01 -0700161 RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
162 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
163 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
Jason Sams4b3de472011-04-06 17:52:23 -0700164 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
Jason Sams2382aba2011-09-13 15:41:01 -0700165 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700166 }
Jason Sams2382aba2011-09-13 15:41:01 -0700167 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
Jason Sams4b3de472011-04-06 17:52:23 -0700168 checkEglError("eglDestroyContext");
169 }
170
171 gGLContextCount--;
172 if (!gGLContextCount) {
Jason Sams2382aba2011-09-13 15:41:01 -0700173 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
Jason Sams4b3de472011-04-06 17:52:23 -0700174 }
175}
176
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800177void getConfigData(const Context *rsc,
178 EGLint *configAttribs, size_t configAttribsLen,
179 uint32_t numSamples) {
180 memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
Jason Sams4b3de472011-04-06 17:52:23 -0700181
Jason Sams4b3de472011-04-06 17:52:23 -0700182 EGLint *configAttribsPtr = configAttribs;
Jason Sams4b3de472011-04-06 17:52:23 -0700183
184 configAttribsPtr[0] = EGL_SURFACE_TYPE;
jon.parra06461b2014-05-08 15:09:15 +0100185 configAttribsPtr[1] = EGL_PBUFFER_BIT;
Jason Sams4b3de472011-04-06 17:52:23 -0700186 configAttribsPtr += 2;
187
188 configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
189 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
190 configAttribsPtr += 2;
191
Mathias Agopian67605d72011-07-06 16:35:30 -0700192 configAttribsPtr[0] = EGL_RED_SIZE;
193 configAttribsPtr[1] = 8;
194 configAttribsPtr += 2;
195
196 configAttribsPtr[0] = EGL_GREEN_SIZE;
197 configAttribsPtr[1] = 8;
198 configAttribsPtr += 2;
199
200 configAttribsPtr[0] = EGL_BLUE_SIZE;
201 configAttribsPtr[1] = 8;
202 configAttribsPtr += 2;
203
204 if (rsc->mUserSurfaceConfig.alphaMin > 0) {
205 configAttribsPtr[0] = EGL_ALPHA_SIZE;
206 configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
207 configAttribsPtr += 2;
208 }
209
Jason Sams4b3de472011-04-06 17:52:23 -0700210 if (rsc->mUserSurfaceConfig.depthMin > 0) {
211 configAttribsPtr[0] = EGL_DEPTH_SIZE;
212 configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
213 configAttribsPtr += 2;
214 }
215
216 if (rsc->mDev->mForceSW) {
217 configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
218 configAttribsPtr[1] = EGL_SLOW_CONFIG;
219 configAttribsPtr += 2;
220 }
221
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800222 if (numSamples > 1) {
223 configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
224 configAttribsPtr[1] = 1;
225 configAttribsPtr[2] = EGL_SAMPLES;
226 configAttribsPtr[3] = numSamples;
227 configAttribsPtr += 4;
228 }
229
Jason Sams4b3de472011-04-06 17:52:23 -0700230 configAttribsPtr[0] = EGL_NONE;
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800231 rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
232}
233
234bool rsdGLInit(const Context *rsc) {
235 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
236
237 dc->gl.egl.numConfigs = -1;
238
239 EGLint configAttribs[128];
240 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
Jason Sams4b3de472011-04-06 17:52:23 -0700241
Steve Block65982012011-10-20 11:56:00 +0100242 ALOGV("%p initEGL start", rsc);
Jason Sams2382aba2011-09-13 15:41:01 -0700243 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700244 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
245 checkEglError("eglGetDisplay");
246
Jason Sams2382aba2011-09-13 15:41:01 -0700247 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
248 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
Jason Sams4b3de472011-04-06 17:52:23 -0700249 checkEglError("eglInitialize");
250
Mathias Agopian67605d72011-07-06 16:35:30 -0700251 EGLBoolean ret;
252
253 EGLint numConfigs = -1, n = 0;
Jason Sams2382aba2011-09-13 15:41:01 -0700254 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Alex Sakhartchoukda7a1482012-02-28 14:35:31 -0800255
256 // Try minding a multisample config that matches the user request
257 uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
258 uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
259 for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
260 getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
261 ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
262 checkEglError("eglGetConfigs", ret);
263 if (numConfigs > 0) {
264 break;
265 }
266 }
Mathias Agopian67605d72011-07-06 16:35:30 -0700267
268 if (numConfigs) {
269 EGLConfig* const configs = new EGLConfig[numConfigs];
270
Jason Sams2382aba2011-09-13 15:41:01 -0700271 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
Mathias Agopian67605d72011-07-06 16:35:30 -0700272 ret = eglChooseConfig(dc->gl.egl.display,
273 configAttribs, configs, numConfigs, &n);
274 if (!ret || !n) {
275 checkEglError("eglChooseConfig", ret);
Steve Blockaf12ac62012-01-06 19:20:56 +0000276 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
Mathias Agopian67605d72011-07-06 16:35:30 -0700277 }
278
279 // The first config is guaranteed to over-satisfy the constraints
280 dc->gl.egl.config = configs[0];
281
282 // go through the list and skip configs that over-satisfy our needs
283 for (int i=0 ; i<n ; i++) {
284 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
285 EGLint alphaSize;
286 eglGetConfigAttrib(dc->gl.egl.display,
287 configs[i], EGL_ALPHA_SIZE, &alphaSize);
288 if (alphaSize > 0) {
289 continue;
290 }
291 }
292
293 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
294 EGLint depthSize;
295 eglGetConfigAttrib(dc->gl.egl.display,
296 configs[i], EGL_DEPTH_SIZE, &depthSize);
297 if (depthSize > 0) {
298 continue;
299 }
300 }
301
302 // Found one!
303 dc->gl.egl.config = configs[i];
304 break;
305 }
306
307 delete [] configs;
Jason Sams4b3de472011-04-06 17:52:23 -0700308 }
309
Jason Sams4b3de472011-04-06 17:52:23 -0700310 //if (props.mLogVisual) {
Stephen Hines9db7fe22011-04-20 17:08:14 -0700311 if (0) {
Jason Sams4b3de472011-04-06 17:52:23 -0700312 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
Stephen Hines9db7fe22011-04-20 17:08:14 -0700313 }
Jason Sams4b3de472011-04-06 17:52:23 -0700314 //}
315
Jason Sams2382aba2011-09-13 15:41:01 -0700316 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700317 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
318 EGL_NO_CONTEXT, context_attribs2);
319 checkEglError("eglCreateContext");
320 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000321 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700322 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700323 return false;
324 }
325 gGLContextCount++;
326
Mathias Agopian3318d182013-07-16 22:56:00 -0700327 EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
328 rsc->setWatchdogGL("eglCreatePbufferSurface", __LINE__, __FILE__);
329 dc->gl.egl.surfaceDefault = eglCreatePbufferSurface(dc->gl.egl.display, dc->gl.egl.config,
330 pbuffer_attribs);
331 checkEglError("eglCreatePbufferSurface");
Jason Sams4b3de472011-04-06 17:52:23 -0700332 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
Mathias Agopian3318d182013-07-16 22:56:00 -0700333 ALOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700334 rsdGLShutdown(rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700335 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700336 return false;
337 }
338
Jason Sams2382aba2011-09-13 15:41:01 -0700339 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Mathias Agopian67605d72011-07-06 16:35:30 -0700340 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
341 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
Jason Sams4b3de472011-04-06 17:52:23 -0700342 if (ret == EGL_FALSE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000343 ALOGE("eglMakeCurrent returned EGL_FALSE");
Jason Sams4b3de472011-04-06 17:52:23 -0700344 checkEglError("eglMakeCurrent", ret);
345 rsdGLShutdown(rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700346 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700347 return false;
348 }
349
350 dc->gl.gl.version = glGetString(GL_VERSION);
351 dc->gl.gl.vendor = glGetString(GL_VENDOR);
352 dc->gl.gl.renderer = glGetString(GL_RENDERER);
353 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
354
Steve Block65982012011-10-20 11:56:00 +0100355 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
356 //ALOGV("GL Version %s", mGL.mVersion);
357 //ALOGV("GL Vendor %s", mGL.mVendor);
358 //ALOGV("GL Renderer %s", mGL.mRenderer);
359 //ALOGV("GL Extensions %s", mGL.mExtensions);
Jason Sams4b3de472011-04-06 17:52:23 -0700360
Chris Wailes44bef6f2014-08-12 13:51:10 -0700361 const char *verptr = nullptr;
Jason Sams4b3de472011-04-06 17:52:23 -0700362 if (strlen((const char *)dc->gl.gl.version) > 9) {
363 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
364 verptr = (const char *)dc->gl.gl.version + 12;
365 }
366 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
367 verptr = (const char *)dc->gl.gl.version + 9;
368 }
369 }
370
371 if (!verptr) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000372 ALOGE("Error, OpenGL ES Lite not supported");
Jason Sams4b3de472011-04-06 17:52:23 -0700373 rsdGLShutdown(rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700374 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700375 return false;
376 } else {
377 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
378 }
379
380 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
381 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
382 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
383
384 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
385 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
386
387 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
388 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
389
Chris Wailes44bef6f2014-08-12 13:51:10 -0700390 dc->gl.gl.OES_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700391 "GL_OES_texture_npot");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700392 dc->gl.gl.IMG_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700393 "GL_IMG_texture_npot");
Chris Wailes44bef6f2014-08-12 13:51:10 -0700394 dc->gl.gl.NV_texture_npot_2D_mipmap = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700395 "GL_NV_texture_npot_2D_mipmap");
396 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700397 bool hasAniso = nullptr != strstr((const char *)dc->gl.gl.extensions,
Jason Sams4b3de472011-04-06 17:52:23 -0700398 "GL_EXT_texture_filter_anisotropic");
399 if (hasAniso) {
400 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
401 }
402
Stephen Hines9db7fe22011-04-20 17:08:14 -0700403 if (0) {
404 DumpDebug(dc);
405 }
Jason Sams4b3de472011-04-06 17:52:23 -0700406
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700407 dc->gl.shaderCache = new RsdShaderCache();
408 dc->gl.vertexArrayState = new RsdVertexArrayState();
409 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700410 dc->gl.currentFrameBuffer = nullptr;
Jason Sams9719bd42012-01-12 14:22:21 -0800411 dc->mHasGraphics = true;
Alex Sakhartchouka04e30d2011-04-29 16:49:08 -0700412
Steve Block65982012011-10-20 11:56:00 +0100413 ALOGV("%p initGLThread end", rsc);
Chris Wailes44bef6f2014-08-12 13:51:10 -0700414 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700415 return true;
416}
417
418
Jason Samsb3220332012-04-02 14:41:54 -0700419bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700420 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams4b3de472011-04-06 17:52:23 -0700421
422 EGLBoolean ret;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700423 if (dc->gl.egl.surface != nullptr) {
Jason Sams2382aba2011-09-13 15:41:01 -0700424 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700425 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
426 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
427 checkEglError("eglMakeCurrent", ret);
428
Jason Sams2382aba2011-09-13 15:41:01 -0700429 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700430 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
431 checkEglError("eglDestroySurface", ret);
432
Chris Wailes44bef6f2014-08-12 13:51:10 -0700433 dc->gl.egl.surface = nullptr;
Jason Sams4b3de472011-04-06 17:52:23 -0700434 }
435
Chris Wailes44bef6f2014-08-12 13:51:10 -0700436 if (dc->gl.currentWndSurface != nullptr) {
437 dc->gl.currentWndSurface->decStrong(nullptr);
Jason Samsc33e6902011-06-20 16:58:04 -0700438 }
439
Jason Samsb3220332012-04-02 14:41:54 -0700440 dc->gl.currentWndSurface = (ANativeWindow *)sur;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700441 if (dc->gl.currentWndSurface != nullptr) {
442 dc->gl.currentWndSurface->incStrong(nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700443
Jason Sams2382aba2011-09-13 15:41:01 -0700444 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700445 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
Chris Wailes44bef6f2014-08-12 13:51:10 -0700446 dc->gl.currentWndSurface, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700447 checkEglError("eglCreateWindowSurface");
448 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
Steve Blockaf12ac62012-01-06 19:20:56 +0000449 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
Jason Sams4b3de472011-04-06 17:52:23 -0700450 }
451
Jason Sams2382aba2011-09-13 15:41:01 -0700452 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
Jason Sams4b3de472011-04-06 17:52:23 -0700453 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
454 dc->gl.egl.surface, dc->gl.egl.context);
455 checkEglError("eglMakeCurrent", ret);
456 }
Chris Wailes44bef6f2014-08-12 13:51:10 -0700457 rsc->setWatchdogGL(nullptr, 0, nullptr);
Jason Sams4b3de472011-04-06 17:52:23 -0700458 return true;
459}
460
Jason Samsb3220332012-04-02 14:41:54 -0700461bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
462 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
463
Chris Wailes44bef6f2014-08-12 13:51:10 -0700464 if (dc->gl.wndSurface != nullptr) {
465 dc->gl.wndSurface->decStrong(nullptr);
466 dc->gl.wndSurface = nullptr;
Jason Samsb3220332012-04-02 14:41:54 -0700467 }
468 if(w && h) {
469 // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
470 // pbuffer to avoid this pitfall.
471 dc->gl.wndSurface = (ANativeWindow *)sur;
Chris Wailes44bef6f2014-08-12 13:51:10 -0700472 if (dc->gl.wndSurface != nullptr) {
473 dc->gl.wndSurface->incStrong(nullptr);
Jason Samsb3220332012-04-02 14:41:54 -0700474 }
475 }
476
477 return rsdGLSetInternalSurface(rsc, sur);
478}
479
Jason Sams4b3de472011-04-06 17:52:23 -0700480void rsdGLSwap(const android::renderscript::Context *rsc) {
Jason Sams87fe59a2011-04-20 15:09:01 -0700481 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
Jason Sams2382aba2011-09-13 15:41:01 -0700482 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
Jason Sams4b3de472011-04-06 17:52:23 -0700483}
484
Jason Sams9719bd42012-01-12 14:22:21 -0800485void rsdGLSetPriority(const Context *rsc, int32_t priority) {
486 if (priority > 0) {
487 // Mark context as low priority.
488 ALOGV("low pri");
489 } else {
490 ALOGV("normal pri");
491 }
492}
493
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700494void rsdGLCheckError(const android::renderscript::Context *rsc,
495 const char *msg, bool isFatal) {
496 GLenum err = glGetError();
497 if (err != GL_NO_ERROR) {
498 char buf[1024];
499 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
500
501 if (isFatal) {
502 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
503 } else {
504 switch (err) {
505 case GL_OUT_OF_MEMORY:
506 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
507 break;
508 default:
509 rsc->setError(RS_ERROR_DRIVER, buf);
510 break;
511 }
512 }
513
Steve Blockaf12ac62012-01-06 19:20:56 +0000514 ALOGE("%p, %s", rsc, buf);
Alex Sakhartchoukc19ff012011-05-06 14:59:45 -0700515 }
516
517}
Alex Sakhartchouk653b53e2012-02-24 14:22:34 -0800518
519void rsdGLClearColor(const android::renderscript::Context *rsc,
520 float r, float g, float b, float a) {
521 RSD_CALL_GL(glClearColor, r, g, b, a);
522 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
523}
524
525void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
526 RSD_CALL_GL(glClearDepthf, v);
527 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
528}
529
530void rsdGLFinish(const android::renderscript::Context *rsc) {
531 RSD_CALL_GL(glFinish);
532}
533
534void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
535 float x1, float y1, float z1, float u1, float v1,
536 float x2, float y2, float z2, float u2, float v2,
537 float x3, float y3, float z3, float u3, float v3,
538 float x4, float y4, float z4, float u4, float v4) {
539
540 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
541 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
542
543 RsdVertexArray::Attrib attribs[2];
Tim Murraye195a3f2014-03-13 15:04:58 -0700544
545 attribs[0].set(GL_FLOAT, 3, 12, false, (size_t)vtx, "ATTRIB_position");
546 attribs[1].set(GL_FLOAT, 2, 8, false, (size_t)tex, "ATTRIB_texture0");
Alex Sakhartchouk653b53e2012-02-24 14:22:34 -0800547
548 RsdVertexArray va(attribs, 2);
549 va.setup(rsc);
550
551 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
552}