rsdGL.cpp revision 33c622e98b57c5021c92133543ff00ffdbbcafe7
13ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato/* 23ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * Copyright (C) 2011 The Android Open Source Project 33ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * 43ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * Licensed under the Apache License, Version 2.0 (the "License"); 53ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * you may not use this file except in compliance with the License. 63ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * You may obtain a copy of the License at 73ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * 83ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * http://www.apache.org/licenses/LICENSE-2.0 93ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * 103ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * Unless required by applicable law or agreed to in writing, software 113ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * distributed under the License is distributed on an "AS IS" BASIS, 123ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * See the License for the specific language governing permissions and 143ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato * limitations under the License. 153ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato */ 16f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato 17f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include <ui/FramebufferNativeWindow.h> 18f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include <ui/PixelFormat.h> 193ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato 203ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <system/window.h> 213ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato 223ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/types.h> 233ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <sys/resource.h> 24d2110dbce071a236b6176de344ca797b737542ebJoe Onorato#include <sched.h> 253ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato 261bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate#include <cutils/properties.h> 273ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato 283ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <GLES/gl.h> 293ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <GLES/glext.h> 303ad977b41c6e4ef30c2f4f316b909b742ffc04aaJoe Onorato#include <GLES2/gl2.h> 31f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include <GLES2/gl2ext.h> 32f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato 33f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include <string.h> 34f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato 35d2110dbce071a236b6176de344ca797b737542ebJoe Onorato#include "rsdCore.h" 36f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include "rsdGL.h" 371bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate 381bb6906c7a903ee6427c8ff37bdc5896c386ff73Christopher Tate#include <malloc.h> 39f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include "rsContext.h" 40f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include "rsDevice.h" 41f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include "rsdShaderCache.h" 42f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include "rsdVertexArray.h" 43c882ddacc8b3085a51f8ae18d89d8fd1d055141fYing Wang#include "rsdFrameBufferObj.h" 44c882ddacc8b3085a51f8ae18d89d8fd1d055141fYing Wang 45f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include <gui/Surface.h> 46f9225f89aafa13dcbc3a69a721acf9b76c34485cJoe Onorato#include <gui/DummyConsumer.h> 47 48using namespace android; 49using namespace android::renderscript; 50 51static int32_t gGLContextCount = 0; 52 53static 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 88static 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 136static 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 154void 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 179void 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 236bool 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<Surface> stc(new Surface(static_cast<sp<IGraphicBufferProducer> >(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 428bool 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 470bool 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 489void 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 494void 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 503void 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 528void 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 534void 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 539void rsdGLFinish(const android::renderscript::Context *rsc) { 540 RSD_CALL_GL(glFinish); 541} 542 543void 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