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 <vndk/window.h>
18
19 #include <sys/types.h>
20 #include <sys/resource.h>
21 #include <sched.h>
22
23 #define EGL_EGLEXT_PROTOTYPES
24 #include <EGL/egl.h>
25 #include <EGL/eglext.h>
26 #include <GLES/gl.h>
27 #include <GLES/glext.h>
28 #include <GLES2/gl2.h>
29 #include <GLES2/gl2ext.h>
30
31 #include <string.h>
32
33 #include "rsdCore.h"
34 #include "rsdGL.h"
35
36 #include <malloc.h>
37 #include "rsContext.h"
38 #include "rsDevice.h"
39 #include "rsdShaderCache.h"
40 #include "rsdVertexArray.h"
41 #include "rsdFrameBufferObj.h"
42
43 using android::renderscript::Context;
44
45 static int32_t gGLContextCount = 0;
46
checkEglError(const char * op,EGLBoolean returnVal=EGL_TRUE)47 static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
48 struct EGLUtils {
49 static const char *strerror(EGLint err) {
50 switch (err){
51 case EGL_SUCCESS: return "EGL_SUCCESS";
52 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED";
53 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS";
54 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC";
55 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE";
56 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG";
57 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT";
58 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE";
59 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY";
60 case EGL_BAD_MATCH: return "EGL_BAD_MATCH";
61 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP";
62 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW";
63 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER";
64 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE";
65 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST";
66 default: return "UNKNOWN";
67 }
68 }
69 };
70
71 if (returnVal != EGL_TRUE) {
72 fprintf(stderr, "%s() returned %d\n", op, returnVal);
73 }
74
75 for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
76 = eglGetError()) {
77 fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, EGLUtils::strerror(error),
78 error);
79 }
80 }
81
printEGLConfiguration(EGLDisplay dpy,EGLConfig config)82 static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
83
84 #define X(VAL) {VAL, #VAL}
85 struct {EGLint attribute; const char* name;} names[] = {
86 X(EGL_BUFFER_SIZE),
87 X(EGL_ALPHA_SIZE),
88 X(EGL_BLUE_SIZE),
89 X(EGL_GREEN_SIZE),
90 X(EGL_RED_SIZE),
91 X(EGL_DEPTH_SIZE),
92 X(EGL_STENCIL_SIZE),
93 X(EGL_CONFIG_CAVEAT),
94 X(EGL_CONFIG_ID),
95 X(EGL_LEVEL),
96 X(EGL_MAX_PBUFFER_HEIGHT),
97 X(EGL_MAX_PBUFFER_PIXELS),
98 X(EGL_MAX_PBUFFER_WIDTH),
99 X(EGL_NATIVE_RENDERABLE),
100 X(EGL_NATIVE_VISUAL_ID),
101 X(EGL_NATIVE_VISUAL_TYPE),
102 X(EGL_SAMPLES),
103 X(EGL_SAMPLE_BUFFERS),
104 X(EGL_SURFACE_TYPE),
105 X(EGL_TRANSPARENT_TYPE),
106 X(EGL_TRANSPARENT_RED_VALUE),
107 X(EGL_TRANSPARENT_GREEN_VALUE),
108 X(EGL_TRANSPARENT_BLUE_VALUE),
109 X(EGL_BIND_TO_TEXTURE_RGB),
110 X(EGL_BIND_TO_TEXTURE_RGBA),
111 X(EGL_MIN_SWAP_INTERVAL),
112 X(EGL_MAX_SWAP_INTERVAL),
113 X(EGL_LUMINANCE_SIZE),
114 X(EGL_ALPHA_MASK_SIZE),
115 X(EGL_COLOR_BUFFER_TYPE),
116 X(EGL_RENDERABLE_TYPE),
117 X(EGL_CONFORMANT),
118 };
119 #undef X
120
121 for (size_t j = 0; j < sizeof(names) / sizeof(names[0]); j++) {
122 EGLint value = -1;
123 EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
124 if (returnVal) {
125 ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
126 }
127 }
128 }
129
DumpDebug(RsdHal * dc)130 static void DumpDebug(RsdHal *dc) {
131 ALOGE(" EGL ver %i %i", dc->gl.egl.majorVersion, dc->gl.egl.minorVersion);
132 ALOGE(" EGL context %p surface %p, Display=%p", dc->gl.egl.context, dc->gl.egl.surface,
133 dc->gl.egl.display);
134 ALOGE(" GL vendor: %s", dc->gl.gl.vendor);
135 ALOGE(" GL renderer: %s", dc->gl.gl.renderer);
136 ALOGE(" GL Version: %s", dc->gl.gl.version);
137 ALOGE(" GL Extensions: %s", dc->gl.gl.extensions);
138 ALOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
139
140 ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
141 dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
142 ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
143 ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
144 dc->gl.gl.maxFragmentUniformVectors);
145 ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
146 }
147
rsdGLShutdown(const Context * rsc)148 void rsdGLShutdown(const Context *rsc) {
149 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
150
151 rsdGLSetSurface(rsc, 0, 0, nullptr);
152 dc->gl.shaderCache->cleanupAll();
153 delete dc->gl.shaderCache;
154 delete dc->gl.vertexArrayState;
155
156 if (dc->gl.egl.context != EGL_NO_CONTEXT) {
157 RSD_CALL_GL(eglMakeCurrent, dc->gl.egl.display,
158 EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
159 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surfaceDefault);
160 if (dc->gl.egl.surface != EGL_NO_SURFACE) {
161 RSD_CALL_GL(eglDestroySurface, dc->gl.egl.display, dc->gl.egl.surface);
162 }
163 RSD_CALL_GL(eglDestroyContext, dc->gl.egl.display, dc->gl.egl.context);
164 checkEglError("eglDestroyContext");
165 }
166
167 gGLContextCount--;
168 if (!gGLContextCount) {
169 RSD_CALL_GL(eglTerminate, dc->gl.egl.display);
170 }
171 }
172
getConfigData(const Context * rsc,EGLint * configAttribs,size_t configAttribsLen,uint32_t numSamples)173 void getConfigData(const Context *rsc,
174 EGLint *configAttribs, size_t configAttribsLen,
175 uint32_t numSamples) {
176 memset(configAttribs, 0, configAttribsLen*sizeof(*configAttribs));
177
178 EGLint *configAttribsPtr = configAttribs;
179
180 configAttribsPtr[0] = EGL_SURFACE_TYPE;
181 configAttribsPtr[1] = EGL_PBUFFER_BIT;
182 configAttribsPtr += 2;
183
184 configAttribsPtr[0] = EGL_RENDERABLE_TYPE;
185 configAttribsPtr[1] = EGL_OPENGL_ES2_BIT;
186 configAttribsPtr += 2;
187
188 configAttribsPtr[0] = EGL_RED_SIZE;
189 configAttribsPtr[1] = 8;
190 configAttribsPtr += 2;
191
192 configAttribsPtr[0] = EGL_GREEN_SIZE;
193 configAttribsPtr[1] = 8;
194 configAttribsPtr += 2;
195
196 configAttribsPtr[0] = EGL_BLUE_SIZE;
197 configAttribsPtr[1] = 8;
198 configAttribsPtr += 2;
199
200 if (rsc->mUserSurfaceConfig.alphaMin > 0) {
201 configAttribsPtr[0] = EGL_ALPHA_SIZE;
202 configAttribsPtr[1] = rsc->mUserSurfaceConfig.alphaMin;
203 configAttribsPtr += 2;
204 }
205
206 if (rsc->mUserSurfaceConfig.depthMin > 0) {
207 configAttribsPtr[0] = EGL_DEPTH_SIZE;
208 configAttribsPtr[1] = rsc->mUserSurfaceConfig.depthMin;
209 configAttribsPtr += 2;
210 }
211
212 if (numSamples > 1) {
213 configAttribsPtr[0] = EGL_SAMPLE_BUFFERS;
214 configAttribsPtr[1] = 1;
215 configAttribsPtr[2] = EGL_SAMPLES;
216 configAttribsPtr[3] = numSamples;
217 configAttribsPtr += 4;
218 }
219
220 configAttribsPtr[0] = EGL_NONE;
221 rsAssert(configAttribsPtr < (configAttribs + configAttribsLen));
222 }
223
rsdGLInit(const Context * rsc)224 int32_t rsdGLInit(const Context *rsc) {
225 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
226
227 dc->gl.egl.numConfigs = -1;
228
229 EGLint configAttribs[128];
230 EGLint context_attribs2[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
231
232 ALOGV("%p initEGL start", rsc);
233 rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
234 dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
235 checkEglError("eglGetDisplay");
236
237 RSD_CALL_GL(eglInitialize, dc->gl.egl.display,
238 &dc->gl.egl.majorVersion, &dc->gl.egl.minorVersion);
239 checkEglError("eglInitialize");
240
241 EGLBoolean ret;
242
243 EGLint numConfigs = -1, n = 0;
244 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
245
246 // Try minding a multisample config that matches the user request
247 uint32_t minSample = rsc->mUserSurfaceConfig.samplesMin;
248 uint32_t prefSample = rsc->mUserSurfaceConfig.samplesPref;
249 for (uint32_t sampleCount = prefSample; sampleCount >= minSample; sampleCount--) {
250 getConfigData(rsc, configAttribs, (sizeof(configAttribs) / sizeof(EGLint)), sampleCount);
251 ret = eglChooseConfig(dc->gl.egl.display, configAttribs, 0, 0, &numConfigs);
252 checkEglError("eglGetConfigs", ret);
253 if (numConfigs > 0) {
254 break;
255 }
256 }
257
258 if (numConfigs) {
259 EGLConfig* const configs = new EGLConfig[numConfigs];
260
261 rsc->setWatchdogGL("eglChooseConfig", __LINE__, __FILE__);
262 ret = eglChooseConfig(dc->gl.egl.display,
263 configAttribs, configs, numConfigs, &n);
264 if (!ret || !n) {
265 checkEglError("eglChooseConfig", ret);
266 ALOGE("%p, couldn't find an EGLConfig matching the screen format\n", rsc);
267 }
268
269 // The first config is guaranteed to over-satisfy the constraints
270 dc->gl.egl.config = configs[0];
271
272 // go through the list and skip configs that over-satisfy our needs
273 for (int i=0 ; i<n ; i++) {
274 if (rsc->mUserSurfaceConfig.alphaMin <= 0) {
275 EGLint alphaSize;
276 eglGetConfigAttrib(dc->gl.egl.display,
277 configs[i], EGL_ALPHA_SIZE, &alphaSize);
278 if (alphaSize > 0) {
279 continue;
280 }
281 }
282
283 if (rsc->mUserSurfaceConfig.depthMin <= 0) {
284 EGLint depthSize;
285 eglGetConfigAttrib(dc->gl.egl.display,
286 configs[i], EGL_DEPTH_SIZE, &depthSize);
287 if (depthSize > 0) {
288 continue;
289 }
290 }
291
292 // Found one!
293 dc->gl.egl.config = configs[i];
294 break;
295 }
296
297 delete [] configs;
298 }
299
300 //if (props.mLogVisual) {
301 if (0) {
302 printEGLConfiguration(dc->gl.egl.display, dc->gl.egl.config);
303 }
304 //}
305
306 rsc->setWatchdogGL("eglCreateContext", __LINE__, __FILE__);
307 dc->gl.egl.context = eglCreateContext(dc->gl.egl.display, dc->gl.egl.config,
308 EGL_NO_CONTEXT, context_attribs2);
309 checkEglError("eglCreateContext");
310 if (dc->gl.egl.context == EGL_NO_CONTEXT) {
311 ALOGE("%p, eglCreateContext returned EGL_NO_CONTEXT", rsc);
312 rsc->setWatchdogGL(nullptr, 0, nullptr);
313 return -1;
314 }
315 gGLContextCount++;
316
317 EGLint pbuffer_attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE };
318 rsc->setWatchdogGL("eglCreatePbufferSurface", __LINE__, __FILE__);
319 dc->gl.egl.surfaceDefault = eglCreatePbufferSurface(dc->gl.egl.display, dc->gl.egl.config,
320 pbuffer_attribs);
321 checkEglError("eglCreatePbufferSurface");
322 if (dc->gl.egl.surfaceDefault == EGL_NO_SURFACE) {
323 ALOGE("eglCreatePbufferSurface returned EGL_NO_SURFACE");
324 rsdGLShutdown(rsc);
325 rsc->setWatchdogGL(nullptr, 0, nullptr);
326 return -1;
327 }
328
329 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
330 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
331 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
332 if (ret == EGL_FALSE) {
333 ALOGE("eglMakeCurrent returned EGL_FALSE");
334 checkEglError("eglMakeCurrent", ret);
335 rsdGLShutdown(rsc);
336 rsc->setWatchdogGL(nullptr, 0, nullptr);
337 return -1;
338 }
339
340 dc->gl.gl.version = glGetString(GL_VERSION);
341 dc->gl.gl.vendor = glGetString(GL_VENDOR);
342 dc->gl.gl.renderer = glGetString(GL_RENDERER);
343 dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
344
345 //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
346 //ALOGV("GL Version %s", mGL.mVersion);
347 //ALOGV("GL Vendor %s", mGL.mVendor);
348 //ALOGV("GL Renderer %s", mGL.mRenderer);
349 //ALOGV("GL Extensions %s", mGL.mExtensions);
350
351 const char *verptr = nullptr;
352 if (strlen((const char *)dc->gl.gl.version) > 9) {
353 if (!memcmp(dc->gl.gl.version, "OpenGL ES-CM", 12)) {
354 verptr = (const char *)dc->gl.gl.version + 12;
355 }
356 if (!memcmp(dc->gl.gl.version, "OpenGL ES ", 10)) {
357 verptr = (const char *)dc->gl.gl.version + 9;
358 }
359 }
360
361 if (!verptr) {
362 ALOGE("Error, OpenGL ES Lite not supported");
363 rsdGLShutdown(rsc);
364 rsc->setWatchdogGL(nullptr, 0, nullptr);
365 return -1;
366 } else {
367 sscanf(verptr, " %i.%i", &dc->gl.gl.majorVersion, &dc->gl.gl.minorVersion);
368 }
369
370 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &dc->gl.gl.maxVertexAttribs);
371 glGetIntegerv(GL_MAX_VERTEX_UNIFORM_VECTORS, &dc->gl.gl.maxVertexUniformVectors);
372 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxVertexTextureUnits);
373
374 glGetIntegerv(GL_MAX_VARYING_VECTORS, &dc->gl.gl.maxVaryingVectors);
375 glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxTextureImageUnits);
376
377 glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &dc->gl.gl.maxFragmentTextureImageUnits);
378 glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_VECTORS, &dc->gl.gl.maxFragmentUniformVectors);
379
380 dc->gl.gl.OES_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
381 "GL_OES_texture_npot");
382 dc->gl.gl.IMG_texture_npot = nullptr != strstr((const char *)dc->gl.gl.extensions,
383 "GL_IMG_texture_npot");
384 dc->gl.gl.NV_texture_npot_2D_mipmap = nullptr != strstr((const char *)dc->gl.gl.extensions,
385 "GL_NV_texture_npot_2D_mipmap");
386 dc->gl.gl.EXT_texture_max_aniso = 1.0f;
387 bool hasAniso = nullptr != strstr((const char *)dc->gl.gl.extensions,
388 "GL_EXT_texture_filter_anisotropic");
389 if (hasAniso) {
390 glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &dc->gl.gl.EXT_texture_max_aniso);
391 }
392
393 if (0) {
394 DumpDebug(dc);
395 }
396
397 dc->gl.shaderCache = new RsdShaderCache();
398 dc->gl.vertexArrayState = new RsdVertexArrayState();
399 dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
400 dc->gl.currentFrameBuffer = nullptr;
401 dc->mHasGraphics = true;
402
403 int syncFd = -1;
404 // Create a EGL sync object.
405 EGLSyncKHR sync = eglCreateSyncKHR(dc->gl.egl.display, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
406 if (sync != EGL_NO_SYNC_KHR) {
407 // native fence fd will not be populated until flush() is done.
408 glFlush();
409 // Convert the EGL sync object to a file descriptor.
410 syncFd = eglDupNativeFenceFDANDROID(dc->gl.egl.display, sync);
411 if (syncFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
412 ALOGW("Failed to dup sync khr object");
413 syncFd = -1;
414 }
415 // The sync object is no longer needed once we have the file descriptor.
416 eglDestroySyncKHR(dc->gl.egl.display, sync);
417 }
418
419 ALOGV("%p initGLThread end", rsc);
420 rsc->setWatchdogGL(nullptr, 0, nullptr);
421 return syncFd;
422 }
423
424
rsdGLSetInternalSurface(const Context * rsc,RsNativeWindow sur)425 bool rsdGLSetInternalSurface(const Context *rsc, RsNativeWindow sur) {
426 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
427
428 EGLBoolean ret;
429 if (dc->gl.egl.surface != nullptr) {
430 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
431 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surfaceDefault,
432 dc->gl.egl.surfaceDefault, dc->gl.egl.context);
433 checkEglError("eglMakeCurrent", ret);
434
435 rsc->setWatchdogGL("eglDestroySurface", __LINE__, __FILE__);
436 ret = eglDestroySurface(dc->gl.egl.display, dc->gl.egl.surface);
437 checkEglError("eglDestroySurface", ret);
438
439 dc->gl.egl.surface = nullptr;
440 }
441
442 if (dc->gl.currentWndSurface != nullptr) {
443 ANativeWindow_release(dc->gl.currentWndSurface);
444 }
445
446 dc->gl.currentWndSurface = (ANativeWindow *)sur;
447 if (dc->gl.currentWndSurface != nullptr) {
448 ANativeWindow_acquire(dc->gl.currentWndSurface);
449
450 rsc->setWatchdogGL("eglCreateWindowSurface", __LINE__, __FILE__);
451 dc->gl.egl.surface = eglCreateWindowSurface(dc->gl.egl.display, dc->gl.egl.config,
452 dc->gl.currentWndSurface, nullptr);
453 checkEglError("eglCreateWindowSurface");
454 if (dc->gl.egl.surface == EGL_NO_SURFACE) {
455 ALOGE("eglCreateWindowSurface returned EGL_NO_SURFACE");
456 }
457
458 rsc->setWatchdogGL("eglMakeCurrent", __LINE__, __FILE__);
459 ret = eglMakeCurrent(dc->gl.egl.display, dc->gl.egl.surface,
460 dc->gl.egl.surface, dc->gl.egl.context);
461 checkEglError("eglMakeCurrent", ret);
462 }
463 rsc->setWatchdogGL(nullptr, 0, nullptr);
464 return true;
465 }
466
rsdGLSetSurface(const Context * rsc,uint32_t w,uint32_t h,RsNativeWindow sur)467 bool rsdGLSetSurface(const Context *rsc, uint32_t w, uint32_t h, RsNativeWindow sur) {
468 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
469
470 if (dc->gl.wndSurface != nullptr) {
471 ANativeWindow_release(dc->gl.wndSurface);
472 dc->gl.wndSurface = nullptr;
473 }
474 if(w && h) {
475 // WAR: Some drivers fail to handle 0 size surfaces correctly. Use the
476 // pbuffer to avoid this pitfall.
477 dc->gl.wndSurface = (ANativeWindow *)sur;
478 if (dc->gl.wndSurface != nullptr) {
479 ANativeWindow_acquire(dc->gl.wndSurface);
480 }
481 }
482
483 return rsdGLSetInternalSurface(rsc, sur);
484 }
485
rsdGLSwap(const android::renderscript::Context * rsc)486 void rsdGLSwap(const android::renderscript::Context *rsc) {
487 RsdHal *dc = (RsdHal *)rsc->mHal.drv;
488 RSD_CALL_GL(eglSwapBuffers, dc->gl.egl.display, dc->gl.egl.surface);
489 }
490
rsdGLSetPriority(const Context * rsc,int32_t priority)491 void rsdGLSetPriority(const Context *rsc, int32_t priority) {
492 if (priority > 0) {
493 // Mark context as low priority.
494 ALOGV("low pri");
495 } else {
496 ALOGV("normal pri");
497 }
498 }
499
rsdGLCheckError(const android::renderscript::Context * rsc,const char * msg,bool isFatal)500 void rsdGLCheckError(const android::renderscript::Context *rsc,
501 const char *msg, bool isFatal) {
502 GLenum err = glGetError();
503 if (err != GL_NO_ERROR) {
504 char buf[1024];
505 snprintf(buf, sizeof(buf), "GL Error = 0x%08x, from: %s", err, msg);
506
507 if (isFatal) {
508 rsc->setError(RS_ERROR_FATAL_DRIVER, buf);
509 } else {
510 switch (err) {
511 case GL_OUT_OF_MEMORY:
512 rsc->setError(RS_ERROR_OUT_OF_MEMORY, buf);
513 break;
514 default:
515 rsc->setError(RS_ERROR_DRIVER, buf);
516 break;
517 }
518 }
519
520 ALOGE("%p, %s", rsc, buf);
521 }
522
523 }
524
rsdGLClearColor(const android::renderscript::Context * rsc,float r,float g,float b,float a)525 void rsdGLClearColor(const android::renderscript::Context *rsc,
526 float r, float g, float b, float a) {
527 RSD_CALL_GL(glClearColor, r, g, b, a);
528 RSD_CALL_GL(glClear, GL_COLOR_BUFFER_BIT);
529 }
530
rsdGLClearDepth(const android::renderscript::Context * rsc,float v)531 void rsdGLClearDepth(const android::renderscript::Context *rsc, float v) {
532 RSD_CALL_GL(glClearDepthf, v);
533 RSD_CALL_GL(glClear, GL_DEPTH_BUFFER_BIT);
534 }
535
rsdGLFinish(const android::renderscript::Context * rsc)536 void rsdGLFinish(const android::renderscript::Context *rsc) {
537 RSD_CALL_GL(glFinish);
538 }
539
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)540 void rsdGLDrawQuadTexCoords(const android::renderscript::Context *rsc,
541 float x1, float y1, float z1, float u1, float v1,
542 float x2, float y2, float z2, float u2, float v2,
543 float x3, float y3, float z3, float u3, float v3,
544 float x4, float y4, float z4, float u4, float v4) {
545
546 float vtx[] = {x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4};
547 const float tex[] = {u1,v1, u2,v2, u3,v3, u4,v4};
548
549 RsdVertexArray::Attrib attribs[2];
550
551 attribs[0].set(GL_FLOAT, 3, 12, false, (size_t)vtx, "ATTRIB_position");
552 attribs[1].set(GL_FLOAT, 2, 8, false, (size_t)tex, "ATTRIB_texture0");
553
554 RsdVertexArray va(attribs, 2);
555 va.setup(rsc);
556
557 RSD_CALL_GL(glDrawArrays, GL_TRIANGLE_FAN, 0, 4);
558 }
559