1 /*
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/PixelFormat.h>
18 
19 #include <system/window.h>
20 
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 
32 #include <string.h>
33 
34 #include "rsdCore.h"
35 #include "rsdGL.h"
36 
37 #include <malloc.h>
38 #include "rsContext.h"
39 #include "rsDevice.h"
40 #include "rsdShaderCache.h"
41 #include "rsdVertexArray.h"
42 #include "rsdFrameBufferObj.h"
43 
44 #include <gui/Surface.h>
45 
46 using namespace android;
47 using namespace android::renderscript;
48 
49 static int32_t gGLContextCount = 0;
50 
checkEglError(const char * op,EGLBoolean returnVal=EGL_TRUE)51 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
52     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 
75     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 
printEGLConfiguration(EGLDisplay dpy,EGLConfig config)86 static 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;
127         EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
128         if (returnVal) {
129             ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
130         }
131     }
132 }
133 
DumpDebug(RsdHal * dc)134 static void DumpDebug(RsdHal *dc) {
135     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,
137          dc->gl.egl.display);
138     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);
143 
144     ALOGV("MAX Textures %i, %i  %i", dc->gl.gl.maxVertexTextureUnits,
145          dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
146     ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
147     ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
148          dc->gl.gl.maxFragmentUniformVectors);
149     ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
150 }
151 
rsdGLShutdown(const Context * rsc)152 void rsdGLShutdown(const Context *rsc) {
153     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
154 
155     rsdGLSetSurface(rsc, 0, 0, nullptr);
156     dc->gl.shaderCache->cleanupAll();
157     delete dc->gl.shaderCache;
158     delete dc->gl.vertexArrayState;
159 
160     if (dc->gl.egl.context != EGL_NO_CONTEXT) {
161         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);
164         if (dc->gl.egl.surface != EGL_NO_SURFACE) {
165             RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
166         }
167         RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
168         checkEglError("eglDestroyContext");
169     }
170 
171     gGLContextCount--;
172     if (!gGLContextCount) {
173         RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
174     }
175 }
176 
getConfigData(const Context * rsc,EGLint * configAttribs,size_t configAttribsLen,uint32_t numSamples)177 void getConfigData(const Context *rsc,
178                    EGLint *configAttribs, size_t configAttribsLen,
179                    uint32_t numSamples) {
180     memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
181 
182     EGLint *configAttribsPtr = configAttribs;
183 
184     configAttribsPtr[0] = EGL_SURFACE_TYPE;
185     configAttribsPtr[1] = EGL_PBUFFER_BIT;
186     configAttribsPtr += 2;
187 
188     configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
189     configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
190     configAttribsPtr += 2;
191 
192     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 
210     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 
222     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 
230     configAttribsPtr[0] = EGL_NONE;
231     rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
232 }
233 
rsdGLInit(const Context * rsc)234 bool 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 };
241 
242     ALOGV("%p initEGL start", rsc);
243     rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
244     dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
245     checkEglError("eglGetDisplay");
246 
247     RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
248                 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
249     checkEglError("eglInitialize");
250 
251     EGLBoolean ret;
252 
253     EGLint numConfigs = -1, n = 0;
254     rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
255 
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     }
267 
268     if (numConfigs) {
269         EGLConfig* const configs = new EGLConfig[numConfigs];
270 
271         rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
272         ret = eglChooseConfig(dc->gl.egl.display,
273                 configAttribs, configs, numConfigs, &n);
274         if (!ret || !n) {
275             checkEglError("eglChooseConfig", ret);
276             ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
277         }
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;
308     }
309 
310     //if (props.mLogVisual) {
311     if (0) {
312         printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
313     }
314     //}
315 
316     rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
317     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) {
321         ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
322         rsc->setWatchdogGL(nullptr, 0, nullptr);
323         return false;
324     }
325     gGLContextCount++;
326 
327     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");
332     if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
333         ALOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
334         rsdGLShutdown(rsc);
335         rsc->setWatchdogGL(nullptr, 0, nullptr);
336         return false;
337     }
338 
339     rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
340     ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
341                          dc->gl.egl.surfaceDefault, dc->gl.egl.context);
342     if (ret == EGL_FALSE) {
343         ALOGE("eglMakeCurrent returned EGL_FALSE");
344         checkEglError("eglMakeCurrent", ret);
345         rsdGLShutdown(rsc);
346         rsc->setWatchdogGL(nullptr, 0, nullptr);
347         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 
355     //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);
360 
361     const char *verptr = nullptr;
362     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) {
372         ALOGE("Error, OpenGL ES Lite not supported");
373         rsdGLShutdown(rsc);
374         rsc->setWatchdogGL(nullptr, 0, nullptr);
375         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 
390     dc->gl.gl.OES_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
391                                                 "GL_OES_texture_npot");
392     dc->gl.gl.IMG_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
393                                                    "GL_IMG_texture_npot");
394     dc->gl.gl.NV_texture_npot_2D_mipmap = nullptr != strstr((const char *)dc->gl.gl.extensions,
395                                                             "GL_NV_texture_npot_2D_mipmap");
396     dc->gl.gl.EXT_texture_max_aniso = 1.0f;
397     bool hasAniso = nullptr != strstr((const char *)dc->gl.gl.extensions,
398                                    "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 
403     if (0) {
404         DumpDebug(dc);
405     }
406 
407     dc->gl.shaderCache = new RsdShaderCache();
408     dc->gl.vertexArrayState = new RsdVertexArrayState();
409     dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
410     dc->gl.currentFrameBuffer = nullptr;
411     dc->mHasGraphics = true;
412 
413     ALOGV("%p initGLThread end", rsc);
414     rsc->setWatchdogGL(nullptr, 0, nullptr);
415     return true;
416 }
417 
418 
rsdGLSetInternalSurface(const Context * rsc,RsNativeWindow sur)419 bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
420     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
421 
422     EGLBoolean ret;
423     if (dc->gl.egl.surface != nullptr) {
424         rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
425         ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
426                              dc->gl.egl.surfaceDefault, dc->gl.egl.context);
427         checkEglError("eglMakeCurrent", ret);
428 
429         rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
430         ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
431         checkEglError("eglDestroySurface", ret);
432 
433         dc->gl.egl.surface = nullptr;
434     }
435 
436     if (dc->gl.currentWndSurface != nullptr) {
437         dc->gl.currentWndSurface->decStrong(nullptr);
438     }
439 
440     dc->gl.currentWndSurface = (ANativeWindow *)sur;
441     if (dc->gl.currentWndSurface != nullptr) {
442         dc->gl.currentWndSurface->incStrong(nullptr);
443 
444         rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
445         dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
446                                                     dc->gl.currentWndSurface, nullptr);
447         checkEglError("eglCreateWindowSurface");
448         if (dc->gl.egl.surface == EGL_NO_SURFACE) {
449             ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
450         }
451 
452         rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
453         ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
454                              dc->gl.egl.surface, dc->gl.egl.context);
455         checkEglError("eglMakeCurrent", ret);
456     }
457     rsc->setWatchdogGL(nullptr, 0, nullptr);
458     return true;
459 }
460 
rsdGLSetSurface(const Context * rsc,uint32_t w,uint32_t h,RsNativeWindow sur)461 bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
462     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
463 
464     if (dc->gl.wndSurface != nullptr) {
465         dc->gl.wndSurface->decStrong(nullptr);
466         dc->gl.wndSurface = nullptr;
467     }
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;
472         if (dc->gl.wndSurface != nullptr) {
473             dc->gl.wndSurface->incStrong(nullptr);
474         }
475     }
476 
477     return rsdGLSetInternalSurface(rsc, sur);
478 }
479 
rsdGLSwap(const android::renderscript::Context * rsc)480 void rsdGLSwap(const android::renderscript::Context *rsc) {
481     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
482     RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
483 }
484 
rsdGLSetPriority(const Context * rsc,int32_t priority)485 void 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 
rsdGLCheckError(const android::renderscript::Context * rsc,const char * msg,bool isFatal)494 void 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 
514         ALOGE("%p, %s", rsc, buf);
515     }
516 
517 }
518 
rsdGLClearColor(const android::renderscript::Context * rsc,float r,float g,float b,float a)519 void 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 
rsdGLClearDepth(const android::renderscript::Context * rsc,float v)525 void 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 
rsdGLFinish(const android::renderscript::Context * rsc)530 void rsdGLFinish(const android::renderscript::Context *rsc) {
531     RSD_CALL_GL(glFinish);
532 }
533 
rsdGLDrawQuadTexCoords(const android::renderscript::Context * rsc,float x1,float y1,float z1,float u1,float v1,float x2,float y2,float z2,float u2,float v2,float x3,float y3,float z3,float u3,float v3,float x4,float y4,float z4,float u4,float v4)534 void 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];
544 
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");
547 
548     RsdVertexArray va(attribs, 2);
549     va.setup(rsc);
550 
551     RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
552 }
553