• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/FramebufferNativeWindow.h>
18 #include <ui/PixelFormat.h>
19 
20 #include <system/window.h>
21 
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 
33 #include <string.h>
34 
35 #include "rsdCore.h"
36 #include "rsdGL.h"
37 
38 #include <malloc.h>
39 #include "rsContext.h"
40 #include "rsDevice.h"
41 #include "rsdShaderCache.h"
42 #include "rsdVertexArray.h"
43 #include "rsdFrameBufferObj.h"
44 
45 #include <gui/SurfaceTextureClient.h>
46 #include <gui/DummyConsumer.h>
47 
48 using namespace android;
49 using namespace android::renderscript;
50 
51 static int32_t gGLContextCount = 0;
52 
checkEglError(const char * op,EGLBoolean returnVal=EGL_TRUE)53 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
54     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 
77     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 
printEGLConfiguration(EGLDisplay dpy,EGLConfig config)88 static 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;
129         EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
130         if (returnVal) {
131             ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
132         }
133     }
134 }
135 
DumpDebug(RsdHal * dc)136 static void DumpDebug(RsdHal *dc) {
137     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,
139          dc->gl.egl.display);
140     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);
145 
146     ALOGV("MAX Textures %i, %i  %i", dc->gl.gl.maxVertexTextureUnits,
147          dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
148     ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
149     ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
150          dc->gl.gl.maxFragmentUniformVectors);
151     ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
152 }
153 
rsdGLShutdown(const Context * rsc)154 void rsdGLShutdown(const Context *rsc) {
155     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
156 
157     rsdGLSetSurface(rsc, 0, 0, NULL);
158     dc->gl.shaderCache->cleanupAll();
159     delete dc->gl.shaderCache;
160     delete dc->gl.vertexArrayState;
161 
162     if (dc->gl.egl.context != EGL_NO_CONTEXT) {
163         RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
164                     EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
165         RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
166         if (dc->gl.egl.surface != EGL_NO_SURFACE) {
167             RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
168         }
169         RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
170         checkEglError("eglDestroyContext");
171     }
172 
173     gGLContextCount--;
174     if (!gGLContextCount) {
175         RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
176     }
177 }
178 
getConfigData(const Context * rsc,EGLint * configAttribs,size_t configAttribsLen,uint32_t numSamples)179 void getConfigData(const Context *rsc,
180                    EGLint *configAttribs, size_t configAttribsLen,
181                    uint32_t numSamples) {
182     memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
183 
184     EGLint *configAttribsPtr = configAttribs;
185 
186     configAttribsPtr[0] = EGL_SURFACE_TYPE;
187     configAttribsPtr[1] = EGL_WINDOW_BIT;
188     configAttribsPtr += 2;
189 
190     configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
191     configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
192     configAttribsPtr += 2;
193 
194     configAttribsPtr[0] = EGL_RED_SIZE;
195     configAttribsPtr[1] = 8;
196     configAttribsPtr += 2;
197 
198     configAttribsPtr[0] = EGL_GREEN_SIZE;
199     configAttribsPtr[1] = 8;
200     configAttribsPtr += 2;
201 
202     configAttribsPtr[0] = EGL_BLUE_SIZE;
203     configAttribsPtr[1] = 8;
204     configAttribsPtr += 2;
205 
206     if (rsc->mUserSurfaceConfig.alphaMin > 0) {
207         configAttribsPtr[0] = EGL_ALPHA_SIZE;
208         configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
209         configAttribsPtr += 2;
210     }
211 
212     if (rsc->mUserSurfaceConfig.depthMin > 0) {
213         configAttribsPtr[0] = EGL_DEPTH_SIZE;
214         configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
215         configAttribsPtr += 2;
216     }
217 
218     if (rsc->mDev->mForceSW) {
219         configAttribsPtr[0] = EGL_CONFIG_CAVEAT;
220         configAttribsPtr[1] = EGL_SLOW_CONFIG;
221         configAttribsPtr += 2;
222     }
223 
224     if (numSamples > 1) {
225         configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
226         configAttribsPtr[1] = 1;
227         configAttribsPtr[2] = EGL_SAMPLES;
228         configAttribsPtr[3] = numSamples;
229         configAttribsPtr += 4;
230     }
231 
232     configAttribsPtr[0] = EGL_NONE;
233     rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
234 }
235 
rsdGLInit(const Context * rsc)236 bool rsdGLInit(const Context *rsc) {
237     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
238 
239     dc->gl.egl.numConfigs = -1;
240 
241     EGLint configAttribs[128];
242     EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
243 
244     ALOGV("%p initEGL start", rsc);
245     rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
246     dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
247     checkEglError("eglGetDisplay");
248 
249     RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
250                 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
251     checkEglError("eglInitialize");
252 
253     EGLBoolean ret;
254 
255     EGLint numConfigs = -1, n = 0;
256     rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
257 
258     // Try minding a multisample config that matches the user request
259     uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
260     uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
261     for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
262         getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
263         ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
264         checkEglError("eglGetConfigs", ret);
265         if (numConfigs > 0) {
266             break;
267         }
268     }
269 
270     eglSwapInterval(dc->gl.egl.display, 0);
271 
272     if (numConfigs) {
273         EGLConfig* const configs = new EGLConfig[numConfigs];
274 
275         rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
276         ret = eglChooseConfig(dc->gl.egl.display,
277                 configAttribs, configs, numConfigs, &n);
278         if (!ret || !n) {
279             checkEglError("eglChooseConfig", ret);
280             ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
281         }
282 
283         // The first config is guaranteed to over-satisfy the constraints
284         dc->gl.egl.config = configs[0];
285 
286         // go through the list and skip configs that over-satisfy our needs
287         for (int i=0 ; i<n ; i++) {
288             if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
289                 EGLint alphaSize;
290                 eglGetConfigAttrib(dc->gl.egl.display,
291                         configs[i], EGL_ALPHA_SIZE, &alphaSize);
292                 if (alphaSize > 0) {
293                     continue;
294                 }
295             }
296 
297             if (rsc->mUserSurfaceConfig.depthMin <= 0) {
298                 EGLint depthSize;
299                 eglGetConfigAttrib(dc->gl.egl.display,
300                         configs[i], EGL_DEPTH_SIZE, &depthSize);
301                 if (depthSize > 0) {
302                     continue;
303                 }
304             }
305 
306             // Found one!
307             dc->gl.egl.config = configs[i];
308             break;
309         }
310 
311         delete [] configs;
312     }
313 
314     //if (props.mLogVisual) {
315     if (0) {
316         printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
317     }
318     //}
319 
320     rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
321     dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
322                                           EGL_NO_CONTEXT, context_attribs2);
323     checkEglError("eglCreateContext");
324     if (dc->gl.egl.context == EGL_NO_CONTEXT) {
325         ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
326         rsc->setWatchdogGL(NULL, 0, NULL);
327         return false;
328     }
329     gGLContextCount++;
330 
331     // Create a BufferQueue with a fake consumer
332     sp<BufferQueue> bq = new BufferQueue();
333     bq->consumerConnect(new DummyConsumer());
334     sp<SurfaceTextureClient> stc(new SurfaceTextureClient(static_cast<sp<ISurfaceTexture> >(bq)));
335 
336     dc->gl.egl.surfaceDefault = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
337                                                        static_cast<ANativeWindow*>(stc.get()),
338                                                        NULL);
339 
340     checkEglError("eglCreateWindowSurface");
341     if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
342         ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
343         rsdGLShutdown(rsc);
344         rsc->setWatchdogGL(NULL, 0, NULL);
345         return false;
346     }
347 
348     rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
349     ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
350                          dc->gl.egl.surfaceDefault, dc->gl.egl.context);
351     if (ret == EGL_FALSE) {
352         ALOGE("eglMakeCurrent returned EGL_FALSE");
353         checkEglError("eglMakeCurrent", ret);
354         rsdGLShutdown(rsc);
355         rsc->setWatchdogGL(NULL, 0, NULL);
356         return false;
357     }
358 
359     dc->gl.gl.version = glGetString(GL_VERSION);
360     dc->gl.gl.vendor = glGetString(GL_VENDOR);
361     dc->gl.gl.renderer = glGetString(GL_RENDERER);
362     dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
363 
364     //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
365     //ALOGV("GL Version %s", mGL.mVersion);
366     //ALOGV("GL Vendor %s", mGL.mVendor);
367     //ALOGV("GL Renderer %s", mGL.mRenderer);
368     //ALOGV("GL Extensions %s", mGL.mExtensions);
369 
370     const char *verptr = NULL;
371     if (strlen((const char *)dc->gl.gl.version) > 9) {
372         if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
373             verptr = (const char *)dc->gl.gl.version + 12;
374         }
375         if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
376             verptr = (const char *)dc->gl.gl.version + 9;
377         }
378     }
379 
380     if (!verptr) {
381         ALOGE("Error, OpenGL ES Lite not supported");
382         rsdGLShutdown(rsc);
383         rsc->setWatchdogGL(NULL, 0, NULL);
384         return false;
385     } else {
386         sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
387     }
388 
389     glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
390     glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
391     glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
392 
393     glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
394     glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
395 
396     glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
397     glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
398 
399     dc->gl.gl.OES_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
400                                                 "GL_OES_texture_npot");
401     dc->gl.gl.IMG_texture_npot = NULL != strstr((const char *)dc->gl.gl.extensions,
402                                                    "GL_IMG_texture_npot");
403     dc->gl.gl.NV_texture_npot_2D_mipmap = NULL != strstr((const char *)dc->gl.gl.extensions,
404                                                             "GL_NV_texture_npot_2D_mipmap");
405     dc->gl.gl.EXT_texture_max_aniso = 1.0f;
406     bool hasAniso = NULL != strstr((const char *)dc->gl.gl.extensions,
407                                    "GL_EXT_texture_filter_anisotropic");
408     if (hasAniso) {
409         glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
410     }
411 
412     if (0) {
413         DumpDebug(dc);
414     }
415 
416     dc->gl.shaderCache = new RsdShaderCache();
417     dc->gl.vertexArrayState = new RsdVertexArrayState();
418     dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
419     dc->gl.currentFrameBuffer = NULL;
420     dc->mHasGraphics = true;
421 
422     ALOGV("%p initGLThread end", rsc);
423     rsc->setWatchdogGL(NULL, 0, NULL);
424     return true;
425 }
426 
427 
rsdGLSetInternalSurface(const Context * rsc,RsNativeWindow sur)428 bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
429     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
430 
431     EGLBoolean ret;
432     if (dc->gl.egl.surface != NULL) {
433         rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
434         ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
435                              dc->gl.egl.surfaceDefault, dc->gl.egl.context);
436         checkEglError("eglMakeCurrent", ret);
437 
438         rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
439         ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
440         checkEglError("eglDestroySurface", ret);
441 
442         dc->gl.egl.surface = NULL;
443     }
444 
445     if (dc->gl.currentWndSurface != NULL) {
446         dc->gl.currentWndSurface->decStrong(NULL);
447     }
448 
449     dc->gl.currentWndSurface = (ANativeWindow *)sur;
450     if (dc->gl.currentWndSurface != NULL) {
451         dc->gl.currentWndSurface->incStrong(NULL);
452 
453         rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
454         dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
455                                                     dc->gl.currentWndSurface, NULL);
456         checkEglError("eglCreateWindowSurface");
457         if (dc->gl.egl.surface == EGL_NO_SURFACE) {
458             ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
459         }
460 
461         rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
462         ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
463                              dc->gl.egl.surface, dc->gl.egl.context);
464         checkEglError("eglMakeCurrent", ret);
465     }
466     rsc->setWatchdogGL(NULL, 0, NULL);
467     return true;
468 }
469 
rsdGLSetSurface(const Context * rsc,uint32_t w,uint32_t h,RsNativeWindow sur)470 bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
471     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
472 
473     if (dc->gl.wndSurface != NULL) {
474         dc->gl.wndSurface->decStrong(NULL);
475         dc->gl.wndSurface = NULL;
476     }
477     if(w && h) {
478         // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
479         // pbuffer to avoid this pitfall.
480         dc->gl.wndSurface = (ANativeWindow *)sur;
481         if (dc->gl.wndSurface != NULL) {
482             dc->gl.wndSurface->incStrong(NULL);
483         }
484     }
485 
486     return rsdGLSetInternalSurface(rsc, sur);
487 }
488 
rsdGLSwap(const android::renderscript::Context * rsc)489 void rsdGLSwap(const android::renderscript::Context *rsc) {
490     RsdHal *dc = (RsdHal *)rsc->mHal.drv;
491     RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
492 }
493 
rsdGLSetPriority(const Context * rsc,int32_t priority)494 void rsdGLSetPriority(const Context *rsc, int32_t priority) {
495     if (priority > 0) {
496         // Mark context as low priority.
497         ALOGV("low pri");
498     } else {
499         ALOGV("normal pri");
500     }
501 }
502 
rsdGLCheckError(const android::renderscript::Context * rsc,const char * msg,bool isFatal)503 void rsdGLCheckError(const android::renderscript::Context *rsc,
504                      const char *msg, bool isFatal) {
505     GLenum err = glGetError();
506     if (err != GL_NO_ERROR) {
507         char buf[1024];
508         snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
509 
510         if (isFatal) {
511             rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
512         } else {
513             switch (err) {
514             case GL_OUT_OF_MEMORY:
515                 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
516                 break;
517             default:
518                 rsc->setError(RS_ERROR_DRIVER, buf);
519                 break;
520             }
521         }
522 
523         ALOGE("%p, %s", rsc, buf);
524     }
525 
526 }
527 
rsdGLClearColor(const android::renderscript::Context * rsc,float r,float g,float b,float a)528 void rsdGLClearColor(const android::renderscript::Context *rsc,
529                      float r, float g, float b, float a) {
530     RSD_CALL_GL(glClearColor, r, g, b, a);
531     RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
532 }
533 
rsdGLClearDepth(const android::renderscript::Context * rsc,float v)534 void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
535     RSD_CALL_GL(glClearDepthf, v);
536     RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
537 }
538 
rsdGLFinish(const android::renderscript::Context * rsc)539 void rsdGLFinish(const android::renderscript::Context *rsc) {
540     RSD_CALL_GL(glFinish);
541 }
542 
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)543 void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
544                             float x1, float y1, float z1, float u1, float v1,
545                             float x2, float y2, float z2, float u2, float v2,
546                             float x3, float y3, float z3, float u3, float v3,
547                             float x4, float y4, float z4, float u4, float v4) {
548 
549     float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
550     const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
551 
552     RsdVertexArray::Attrib attribs[2];
553     attribs[0].set(GL_FLOAT, 3, 12, false, (uint32_t)vtx, "ATTRIB_position");
554     attribs[1].set(GL_FLOAT, 2, 8, false, (uint32_t)tex, "ATTRIB_texture0");
555 
556     RsdVertexArray va(attribs, 2);
557     va.setup(rsc);
558 
559     RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
560 }
561