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 <assert.h> 18 #include "HostConnection.h" 19 #include "ThreadInfo.h" 20 #include "eglDisplay.h" 21 #include "eglSync.h" 22 #include "egl_ftable.h" 23 #include <cutils/log.h> 24 #include <cutils/properties.h> 25 #include "goldfish_sync.h" 26 #include "gralloc_cb.h" 27 #include "GLClientState.h" 28 #include "GLSharedGroup.h" 29 #include "eglContext.h" 30 #include "ClientAPIExts.h" 31 #include "EGLImage.h" 32 #include "ProcessPipe.h" 33 34 #include "GLEncoder.h" 35 #ifdef WITH_GLES2 36 #include "GL2Encoder.h" 37 #endif 38 39 #include <GLES3/gl31.h> 40 41 #if PLATFORM_SDK_VERSION < 18 42 #define override 43 #endif 44 45 #if PLATFORM_SDK_VERSION >= 16 46 #include <system/window.h> 47 #else // PLATFORM_SDK_VERSION >= 16 48 #include <private/ui/android_natives_priv.h> 49 #endif // PLATFORM_SDK_VERSION >= 16 50 51 #if PLATFORM_SDK_VERSION <= 16 52 #define queueBuffer_DEPRECATED queueBuffer 53 #define dequeueBuffer_DEPRECATED dequeueBuffer 54 #define cancelBuffer_DEPRECATED cancelBuffer 55 #endif // PLATFORM_SDK_VERSION <= 16 56 57 #define DEBUG_EGL 0 58 59 #if DEBUG_EGL 60 #define DPRINT(fmt,...) ALOGD("%s: " fmt, __FUNCTION__, ##__VA_ARGS__); 61 #else 62 #define DPRINT(...) 63 #endif 64 65 template<typename T> 66 static T setErrorFunc(GLint error, T returnValue) { 67 getEGLThreadInfo()->eglError = error; 68 return returnValue; 69 } 70 71 const char * eglStrError(EGLint err) 72 { 73 switch (err){ 74 case EGL_SUCCESS: return "EGL_SUCCESS"; 75 case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; 76 case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; 77 case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; 78 case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; 79 case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; 80 case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; 81 case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; 82 case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; 83 case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; 84 case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; 85 case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; 86 case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; 87 case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; 88 case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; 89 default: return "UNKNOWN"; 90 } 91 } 92 93 #define LOG_EGL_ERRORS 1 94 95 #ifdef LOG_EGL_ERRORS 96 97 #define setErrorReturn(error, retVal) \ 98 { \ 99 ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error)); \ 100 return setErrorFunc(error, retVal); \ 101 } 102 103 #define RETURN_ERROR(ret,err) \ 104 ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err)); \ 105 getEGLThreadInfo()->eglError = err; \ 106 return ret; 107 108 #else //!LOG_EGL_ERRORS 109 110 #define setErrorReturn(error, retVal) return setErrorFunc(error, retVal); 111 112 #define RETURN_ERROR(ret,err) \ 113 getEGLThreadInfo()->eglError = err; \ 114 return ret; 115 116 #endif //LOG_EGL_ERRORS 117 118 #define VALIDATE_CONFIG(cfg,ret) \ 119 if(((intptr_t)(cfg)<0)||((intptr_t)(cfg)>s_display.getNumConfigs())) { \ 120 RETURN_ERROR(ret,EGL_BAD_CONFIG); \ 121 } 122 123 #define VALIDATE_DISPLAY(dpy,ret) \ 124 if ((dpy) != (EGLDisplay)&s_display) { \ 125 RETURN_ERROR(ret, EGL_BAD_DISPLAY); \ 126 } 127 128 #define VALIDATE_DISPLAY_INIT(dpy,ret) \ 129 VALIDATE_DISPLAY(dpy, ret) \ 130 if (!s_display.initialized()) { \ 131 RETURN_ERROR(ret, EGL_NOT_INITIALIZED); \ 132 } 133 134 #define DEFINE_HOST_CONNECTION \ 135 HostConnection *hostCon = HostConnection::get(); \ 136 ExtendedRCEncoderContext *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL) 137 138 #define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ 139 HostConnection *hostCon = HostConnection::get(); \ 140 if (!hostCon) { \ 141 ALOGE("egl: Failed to get host connection\n"); \ 142 return ret; \ 143 } \ 144 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \ 145 if (!rcEnc) { \ 146 ALOGE("egl: Failed to get renderControl encoder context\n"); \ 147 return ret; \ 148 } 149 150 #define DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(ret, tls) \ 151 HostConnection *hostCon = HostConnection::getWithThreadInfo(tls); \ 152 if (!hostCon) { \ 153 ALOGE("egl: Failed to get host connection\n"); \ 154 return ret; \ 155 } \ 156 ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \ 157 if (!rcEnc) { \ 158 ALOGE("egl: Failed to get renderControl encoder context\n"); \ 159 return ret; \ 160 } 161 162 #define VALIDATE_CONTEXT_RETURN(context,ret) \ 163 if (!(context) || !s_display.isContext((context))) { \ 164 RETURN_ERROR(ret,EGL_BAD_CONTEXT); \ 165 } 166 167 #define VALIDATE_SURFACE_RETURN(surface, ret) \ 168 if ((surface) != EGL_NO_SURFACE) { \ 169 if (!s_display.isSurface((surface))) \ 170 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); \ 171 egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \ 172 if (s->dpy != (EGLDisplay)&s_display) \ 173 setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \ 174 } 175 176 // The one and only supported display object. 177 static eglDisplay s_display; 178 179 // Extra defines not in the official EGL spec yet, 180 // but required in Android CTS. 181 182 #define EGL_TIMESTAMPS_ANDROID 0x314D 183 184 EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx, int maj, int min) : 185 dpy(dpy), 186 config(config), 187 read(EGL_NO_SURFACE), 188 draw(EGL_NO_SURFACE), 189 shareCtx(shareCtx), 190 rcContext(0), 191 versionString(NULL), 192 majorVersion(maj), 193 minorVersion(min), 194 vendorString(NULL) , 195 rendererString(NULL), 196 shaderVersionString(NULL), 197 extensionString(NULL), 198 deletePending(0), 199 goldfishSyncFd(-1) 200 { 201 202 DEFINE_HOST_CONNECTION; 203 switch (rcEnc->getGLESMaxVersion()) { 204 case GLES_MAX_VERSION_3_0: 205 deviceMajorVersion = 3; 206 deviceMinorVersion = 0; 207 break; 208 case GLES_MAX_VERSION_3_1: 209 deviceMajorVersion = 3; 210 deviceMinorVersion = 1; 211 break; 212 case GLES_MAX_VERSION_3_2: 213 deviceMajorVersion = 3; 214 deviceMinorVersion = 2; 215 break; 216 default: 217 deviceMajorVersion = 2; 218 deviceMinorVersion = 0; 219 break; 220 } 221 222 flags = 0; 223 clientState = new GLClientState(majorVersion, minorVersion); 224 if (shareCtx) 225 sharedGroup = shareCtx->getSharedGroup(); 226 else 227 sharedGroup = GLSharedGroupPtr(new GLSharedGroup()); 228 assert(dpy == (EGLDisplay)&s_display); 229 s_display.onCreateContext((EGLContext)this); 230 }; 231 232 int EGLContext_t::getGoldfishSyncFd() { 233 if (goldfishSyncFd < 0) { 234 goldfishSyncFd = goldfish_sync_open(); 235 } 236 return goldfishSyncFd; 237 } 238 239 EGLContext_t::~EGLContext_t() 240 { 241 if (goldfishSyncFd > 0) { 242 goldfish_sync_close(goldfishSyncFd); 243 goldfishSyncFd = -1; 244 } 245 assert(dpy == (EGLDisplay)&s_display); 246 s_display.onDestroyContext((EGLContext)this); 247 delete clientState; 248 delete [] versionString; 249 delete [] vendorString; 250 delete [] rendererString; 251 delete [] shaderVersionString; 252 delete [] extensionString; 253 } 254 255 // ---------------------------------------------------------------------------- 256 //egl_surface_t 257 258 //we don't need to handle depth since it's handled when window created on the host 259 260 struct egl_surface_t { 261 262 EGLDisplay dpy; 263 EGLConfig config; 264 265 266 egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType); 267 virtual ~egl_surface_t(); 268 269 virtual void setSwapInterval(int interval) = 0; 270 virtual EGLBoolean swapBuffers() = 0; 271 272 EGLint getSwapBehavior() const; 273 uint32_t getRcSurface() { return rcSurface; } 274 EGLint getSurfaceType() { return surfaceType; } 275 276 EGLint getWidth(){ return width; } 277 EGLint getHeight(){ return height; } 278 EGLint getNativeWidth(){ return nativeWidth; } 279 EGLint getNativeHeight(){ return nativeHeight; } 280 void setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; } 281 EGLint getTextureFormat() { return texFormat; } 282 void setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; } 283 EGLint getTextureTarget() { return texTarget; } 284 285 virtual void setCollectingTimestamps(EGLint collect) { } 286 virtual EGLint isCollectingTimestamps() const { return EGL_FALSE; } 287 EGLint deletePending; 288 void setIsCurrent(bool isCurrent) { mIsCurrent = isCurrent; } 289 bool isCurrent() const { return mIsCurrent;} 290 private: 291 // 292 //Surface attributes 293 // 294 EGLint width; 295 EGLint height; 296 EGLint texFormat; 297 EGLint texTarget; 298 299 // Width of the actual window being presented (not the EGL texture) 300 // Give it some default values. 301 int nativeWidth; 302 int nativeHeight; 303 bool mIsCurrent; 304 protected: 305 void setWidth(EGLint w) { width = w; } 306 void setHeight(EGLint h) { height = h; } 307 void setNativeWidth(int w) { nativeWidth = w; } 308 void setNativeHeight(int h) { nativeHeight = h; } 309 310 EGLint surfaceType; 311 uint32_t rcSurface; //handle to surface created via remote control 312 }; 313 314 egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType) 315 : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0), 316 deletePending(0), mIsCurrent(false) 317 { 318 width = 0; 319 height = 0; 320 // prevent div by 0 in EGL_(HORIZONTAL|VERTICAL)_RESOLUTION queries. 321 nativeWidth = 1; 322 nativeHeight = 1; 323 texFormat = EGL_NO_TEXTURE; 324 texTarget = EGL_NO_TEXTURE; 325 assert(dpy == (EGLDisplay)&s_display); 326 s_display.onCreateSurface((EGLSurface)this); 327 } 328 329 EGLint egl_surface_t::getSwapBehavior() const { 330 return EGL_BUFFER_PRESERVED; 331 } 332 333 egl_surface_t::~egl_surface_t() 334 { 335 assert(dpy == (EGLDisplay)&s_display); 336 s_display.onDestroySurface((EGLSurface)this); 337 } 338 339 // ---------------------------------------------------------------------------- 340 // egl_window_surface_t 341 342 struct egl_window_surface_t : public egl_surface_t { 343 static egl_window_surface_t* create( 344 EGLDisplay dpy, EGLConfig config, EGLint surfType, 345 ANativeWindow* window); 346 347 virtual ~egl_window_surface_t(); 348 349 virtual void setSwapInterval(int interval); 350 virtual EGLBoolean swapBuffers(); 351 352 virtual void setCollectingTimestamps(EGLint collect) 353 override { collectingTimestamps = (collect == EGL_TRUE) ? true : false; } 354 virtual EGLint isCollectingTimestamps() const override { return collectingTimestamps ? EGL_TRUE : EGL_FALSE; } 355 356 357 private: 358 egl_window_surface_t( 359 EGLDisplay dpy, EGLConfig config, EGLint surfType, 360 ANativeWindow* window); 361 EGLBoolean init(); 362 363 ANativeWindow* nativeWindow; 364 android_native_buffer_t* buffer; 365 bool collectingTimestamps; 366 }; 367 368 egl_window_surface_t::egl_window_surface_t ( 369 EGLDisplay dpy, EGLConfig config, EGLint surfType, 370 ANativeWindow* window) 371 : egl_surface_t(dpy, config, surfType), 372 nativeWindow(window), 373 buffer(NULL), 374 collectingTimestamps(false) 375 { 376 // keep a reference on the window 377 nativeWindow->common.incRef(&nativeWindow->common); 378 } 379 380 381 EGLBoolean egl_window_surface_t::init() 382 { 383 if (nativeWindow->dequeueBuffer_DEPRECATED(nativeWindow, &buffer) != NO_ERROR) { 384 setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); 385 } 386 setWidth(buffer->width); 387 setHeight(buffer->height); 388 389 int nativeWidth, nativeHeight; 390 nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &nativeWidth); 391 nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &nativeHeight); 392 393 setNativeWidth(nativeWidth); 394 setNativeHeight(nativeHeight); 395 396 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 397 rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config, 398 getWidth(), getHeight()); 399 if (!rcSurface) { 400 ALOGE("rcCreateWindowSurface returned 0"); 401 return EGL_FALSE; 402 } 403 rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, 404 ((cb_handle_t*)(buffer->handle))->hostHandle); 405 406 return EGL_TRUE; 407 } 408 409 egl_window_surface_t* egl_window_surface_t::create( 410 EGLDisplay dpy, EGLConfig config, EGLint surfType, 411 ANativeWindow* window) 412 { 413 egl_window_surface_t* wnd = new egl_window_surface_t( 414 dpy, config, surfType, window); 415 if (wnd && !wnd->init()) { 416 delete wnd; 417 wnd = NULL; 418 } 419 return wnd; 420 } 421 422 egl_window_surface_t::~egl_window_surface_t() { 423 DEFINE_HOST_CONNECTION; 424 if (rcSurface && rcEnc) { 425 rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface); 426 } 427 if (buffer) { 428 nativeWindow->cancelBuffer_DEPRECATED(nativeWindow, buffer); 429 } 430 nativeWindow->common.decRef(&nativeWindow->common); 431 } 432 433 void egl_window_surface_t::setSwapInterval(int interval) 434 { 435 nativeWindow->setSwapInterval(nativeWindow, interval); 436 } 437 438 // createNativeSync() creates an OpenGL sync object on the host 439 // using rcCreateSyncKHR. If necessary, a native fence FD will 440 // also be created through the goldfish sync device. 441 // Returns a handle to the host-side FenceSync object. 442 static uint64_t createNativeSync(EGLenum type, 443 const EGLint* attrib_list, 444 int num_actual_attribs, 445 bool destroy_when_signaled, 446 int fd_in, 447 int* fd_out) { 448 DEFINE_HOST_CONNECTION; 449 450 uint64_t sync_handle; 451 uint64_t thread_handle; 452 453 EGLint* actual_attribs = 454 (EGLint*)(num_actual_attribs == 0 ? NULL : attrib_list); 455 456 rcEnc->rcCreateSyncKHR(rcEnc, type, 457 actual_attribs, 458 num_actual_attribs * sizeof(EGLint), 459 destroy_when_signaled, 460 &sync_handle, 461 &thread_handle); 462 463 if (type == EGL_SYNC_NATIVE_FENCE_ANDROID && fd_in < 0) { 464 int queue_work_err = 465 goldfish_sync_queue_work( 466 getEGLThreadInfo()->currentContext->getGoldfishSyncFd(), 467 sync_handle, 468 thread_handle, 469 fd_out); 470 471 DPRINT("got native fence fd=%d queue_work_err=%d", 472 *fd_out, queue_work_err); 473 } 474 475 return sync_handle; 476 } 477 478 // createGoldfishOpenGLNativeSync() is for creating host-only sync objects 479 // that are needed by only this goldfish opengl driver, 480 // such as in swapBuffers(). 481 // The guest will not see any of these, and these sync objects will be 482 // destroyed on the host when signaled. 483 // A native fence FD is possibly returned. 484 static void createGoldfishOpenGLNativeSync(int* fd_out) { 485 createNativeSync(EGL_SYNC_NATIVE_FENCE_ANDROID, 486 NULL /* empty attrib list */, 487 0 /* 0 attrib count */, 488 true /* destroy when signaled. this is host-only 489 and there will only be one waiter */, 490 -1 /* we want a new fd */, 491 fd_out); 492 } 493 494 EGLBoolean egl_window_surface_t::swapBuffers() 495 { 496 497 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 498 499 // Follow up flushWindowColorBuffer with a fence command. 500 // When the fence command finishes, 501 // we're sure that the buffer on the host 502 // has been blitted. 503 // 504 // |presentFenceFd| guards the presentation of the 505 // current frame with a goldfish sync fence fd. 506 // 507 // When |presentFenceFd| is signaled, the recipient 508 // of the buffer that was sent through queueBuffer 509 // can be sure that the buffer is current. 510 // 511 // If we don't take care of this synchronization, 512 // an old frame can be processed by surfaceflinger, 513 // resulting in out of order frames. 514 515 int presentFenceFd = -1; 516 517 if (buffer == NULL) { 518 ALOGE("egl_window_surface_t::swapBuffers called with NULL buffer"); 519 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 520 } 521 522 #if PLATFORM_SDK_VERSION <= 16 523 rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface); 524 // equivalent to glFinish if no native sync 525 eglWaitClient(); 526 nativeWindow->queueBuffer(nativeWindow, buffer); 527 #else 528 if (rcEnc->hasNativeSync()) { 529 rcEnc->rcFlushWindowColorBufferAsync(rcEnc, rcSurface); 530 createGoldfishOpenGLNativeSync(&presentFenceFd); 531 } else { 532 rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface); 533 // equivalent to glFinish if no native sync 534 eglWaitClient(); 535 } 536 537 DPRINT("queueBuffer with fence %d", presentFenceFd); 538 nativeWindow->queueBuffer(nativeWindow, buffer, presentFenceFd); 539 #endif 540 541 DPRINT("calling dequeueBuffer..."); 542 543 #if PLATFORM_SDK_VERSION <= 16 544 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) { 545 buffer = NULL; 546 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 547 } 548 #else 549 int acquireFenceFd = -1; 550 if (nativeWindow->dequeueBuffer(nativeWindow, &buffer, &acquireFenceFd)) { 551 buffer = NULL; 552 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 553 } 554 555 DPRINT("dequeueBuffer with fence %d", acquireFenceFd); 556 557 if (acquireFenceFd > 0) { 558 close(acquireFenceFd); 559 } 560 #endif 561 562 rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, 563 ((cb_handle_t *)(buffer->handle))->hostHandle); 564 565 setWidth(buffer->width); 566 setHeight(buffer->height); 567 568 return EGL_TRUE; 569 } 570 571 // ---------------------------------------------------------------------------- 572 //egl_pbuffer_surface_t 573 574 struct egl_pbuffer_surface_t : public egl_surface_t { 575 static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config, 576 EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat); 577 578 virtual ~egl_pbuffer_surface_t(); 579 580 virtual void setSwapInterval(int interval) { (void)interval; } 581 virtual EGLBoolean swapBuffers() { return EGL_TRUE; } 582 583 uint32_t getRcColorBuffer() { return rcColorBuffer; } 584 585 private: 586 egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType, 587 int32_t w, int32_t h); 588 EGLBoolean init(GLenum format); 589 590 uint32_t rcColorBuffer; 591 }; 592 593 egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, 594 EGLint surfType, int32_t w, int32_t h) 595 : egl_surface_t(dpy, config, surfType), 596 rcColorBuffer(0) 597 { 598 setWidth(w); 599 setHeight(h); 600 } 601 602 egl_pbuffer_surface_t::~egl_pbuffer_surface_t() 603 { 604 DEFINE_HOST_CONNECTION; 605 if (rcEnc) { 606 if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer); 607 if (rcSurface) rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface); 608 } 609 } 610 611 // Destroy a pending surface and set it to NULL. 612 613 static void s_destroyPendingSurfaceAndSetNull(EGLSurface* surface) { 614 if (!s_display.isSurface(surface)) { 615 *surface = NULL; 616 return; 617 } 618 619 egl_surface_t* surf = static_cast<egl_surface_t *>(*surface); 620 if (surf && surf->deletePending) { 621 delete surf; 622 *surface = NULL; 623 } 624 } 625 626 static void s_destroyPendingSurfacesInContext(EGLContext_t* context) { 627 if (context->read == context->draw) { 628 // If they are the same, delete it only once 629 s_destroyPendingSurfaceAndSetNull(&context->draw); 630 if (context->draw == NULL) { 631 context->read = NULL; 632 } 633 } else { 634 s_destroyPendingSurfaceAndSetNull(&context->draw); 635 s_destroyPendingSurfaceAndSetNull(&context->read); 636 } 637 } 638 639 EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat) 640 { 641 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 642 643 rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uintptr_t)config, 644 getWidth(), getHeight()); 645 if (!rcSurface) { 646 ALOGE("rcCreateWindowSurface returned 0"); 647 return EGL_FALSE; 648 } 649 650 rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), pixelFormat); 651 if (!rcColorBuffer) { 652 ALOGE("rcCreateColorBuffer returned 0"); 653 return EGL_FALSE; 654 } 655 656 rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer); 657 658 return EGL_TRUE; 659 } 660 661 egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy, 662 EGLConfig config, EGLint surfType, int32_t w, int32_t h, 663 GLenum pixelFormat) 664 { 665 egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType, 666 w, h); 667 if (pb && !pb->init(pixelFormat)) { 668 delete pb; 669 pb = NULL; 670 } 671 return pb; 672 } 673 674 // Required for Skia. 675 static const char kOESEGLImageExternalEssl3[] = "GL_OES_EGL_image_external_essl3"; 676 677 static bool sWantES30OrAbove(const char* exts) { 678 if (strstr(exts, kGLESMaxVersion_3_0) || 679 strstr(exts, kGLESMaxVersion_3_1) || 680 strstr(exts, kGLESMaxVersion_3_2)) { 681 return true; 682 } 683 return false; 684 } 685 686 static std::vector<std::string> getExtStringArray() { 687 std::vector<std::string> res; 688 689 EGLThreadInfo *tInfo = getEGLThreadInfo(); 690 if (!tInfo || !tInfo->currentContext) { 691 return res; 692 } 693 694 #define GL_EXTENSIONS 0x1F03 695 696 DEFINE_AND_VALIDATE_HOST_CONNECTION(res); 697 698 char *hostStr = NULL; 699 int n = rcEnc->rcGetGLString(rcEnc, GL_EXTENSIONS, NULL, 0); 700 if (n < 0) { 701 hostStr = new char[-n+1]; 702 n = rcEnc->rcGetGLString(rcEnc, GL_EXTENSIONS, hostStr, -n); 703 if (n <= 0) { 704 delete [] hostStr; 705 hostStr = NULL; 706 } 707 } 708 709 if (!hostStr || !strlen(hostStr)) { return res; } 710 711 // find the number of extensions 712 int extStart = 0; 713 int extEnd = 0; 714 int currentExtIndex = 0; 715 int numExts = 0; 716 717 if (sWantES30OrAbove(hostStr) && 718 !strstr(hostStr, kOESEGLImageExternalEssl3)) { 719 res.push_back(kOESEGLImageExternalEssl3); 720 } 721 722 while (extEnd < strlen(hostStr)) { 723 if (hostStr[extEnd] == ' ') { 724 int extSz = extEnd - extStart; 725 res.push_back(std::string(hostStr + extStart, extSz)); 726 currentExtIndex++; 727 extStart = extEnd + 1; 728 } 729 extEnd++; 730 } 731 732 delete [] hostStr; 733 return res; 734 } 735 736 static const char *getGLString(int glEnum) 737 { 738 EGLThreadInfo *tInfo = getEGLThreadInfo(); 739 if (!tInfo || !tInfo->currentContext) { 740 return NULL; 741 } 742 743 const char** strPtr = NULL; 744 745 #define GL_VENDOR 0x1F00 746 #define GL_RENDERER 0x1F01 747 #define GL_VERSION 0x1F02 748 #define GL_SHADING_LANGUAGE_VERSION 0x8B8C 749 #define GL_EXTENSIONS 0x1F03 750 751 switch(glEnum) { 752 case GL_VERSION: 753 strPtr = &tInfo->currentContext->versionString; 754 break; 755 case GL_VENDOR: 756 strPtr = &tInfo->currentContext->vendorString; 757 break; 758 case GL_RENDERER: 759 strPtr = &tInfo->currentContext->rendererString; 760 break; 761 case GL_SHADING_LANGUAGE_VERSION: 762 strPtr = &tInfo->currentContext->shaderVersionString; 763 break; 764 case GL_EXTENSIONS: 765 strPtr = &tInfo->currentContext->extensionString; 766 break; 767 } 768 769 if (!strPtr) { 770 return NULL; 771 } 772 773 char* hostStr = NULL; 774 775 if (glEnum == GL_EXTENSIONS) { 776 777 std::vector<std::string> exts = getExtStringArray(); 778 779 int totalSz = 1; // null terminator 780 for (int i = 0; i < exts.size(); i++) { 781 totalSz += exts[i].size() + 1; // for space 782 } 783 784 if (totalSz == 1) return NULL; 785 786 hostStr = new char[totalSz]; 787 memset(hostStr, 0, totalSz); 788 789 char* current = hostStr; 790 for (int i = 0; i < exts.size(); i++) { 791 memcpy(current, exts[i].c_str(), exts[i].size()); 792 current += exts[i].size(); 793 *current = ' '; 794 ++current; 795 } 796 } else { 797 // 798 // first query of that string - need to query host 799 // 800 DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL); 801 int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0); 802 if (n < 0) { 803 hostStr = new char[-n+1]; 804 n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n); 805 if (n <= 0) { 806 delete [] hostStr; 807 hostStr = NULL; 808 } 809 } 810 } 811 812 // 813 // keep the string in the context and return its value 814 // 815 *strPtr = hostStr; 816 return hostStr; 817 } 818 819 // ---------------------------------------------------------------------------- 820 821 static EGLClient_eglInterface s_eglIface = { 822 getThreadInfo: getEGLThreadInfo, 823 getGLString: getGLString, 824 }; 825 826 #define DBG_FUNC DBG("%s\n", __FUNCTION__) 827 EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) 828 { 829 // 830 // we support only EGL_DEFAULT_DISPLAY. 831 // 832 if (display_id != EGL_DEFAULT_DISPLAY) { 833 return EGL_NO_DISPLAY; 834 } 835 836 return (EGLDisplay)&s_display; 837 } 838 839 EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 840 { 841 VALIDATE_DISPLAY(dpy,EGL_FALSE); 842 843 if (!s_display.initialize(&s_eglIface)) { 844 return EGL_FALSE; 845 } 846 if (major!=NULL) 847 *major = s_display.getVersionMajor(); 848 if (minor!=NULL) 849 *minor = s_display.getVersionMinor(); 850 return EGL_TRUE; 851 } 852 853 EGLBoolean eglTerminate(EGLDisplay dpy) 854 { 855 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 856 857 s_display.terminate(); 858 return EGL_TRUE; 859 } 860 861 EGLint eglGetError() 862 { 863 EGLint error = getEGLThreadInfo()->eglError; 864 getEGLThreadInfo()->eglError = EGL_SUCCESS; 865 return error; 866 } 867 868 __eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) 869 { 870 // search in EGL function table 871 for (int i=0; i<egl_num_funcs; i++) { 872 if (!strcmp(egl_funcs_by_name[i].name, procname)) { 873 return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc; 874 } 875 } 876 877 // look in gles client api's extensions table 878 return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname); 879 880 // Fail - function not found. 881 return NULL; 882 } 883 884 const char* eglQueryString(EGLDisplay dpy, EGLint name) 885 { 886 VALIDATE_DISPLAY_INIT(dpy, NULL); 887 888 return s_display.queryString(name); 889 } 890 891 EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) 892 { 893 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 894 895 if(!num_config) { 896 RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER); 897 } 898 899 GLint numConfigs = s_display.getNumConfigs(); 900 if (!configs) { 901 *num_config = numConfigs; 902 return EGL_TRUE; 903 } 904 905 EGLint i; 906 for (i = 0 ; i < numConfigs && i < config_size ; i++) { 907 *configs++ = (EGLConfig)(uintptr_t)i; 908 } 909 *num_config = i; 910 return EGL_TRUE; 911 } 912 913 EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) 914 { 915 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 916 917 if (!num_config) { 918 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); 919 } 920 921 int attribs_size = 0; 922 if (attrib_list) { 923 const EGLint * attrib_p = attrib_list; 924 while (attrib_p[0] != EGL_NONE) { 925 attribs_size += 2; 926 attrib_p += 2; 927 } 928 attribs_size++; //for the terminating EGL_NONE 929 } 930 931 // API 19 passes EGL_SWAP_BEHAVIOR_PRESERVED_BIT to surface type, 932 // while the host never supports it. 933 // We remove the bit here. 934 EGLint* local_attrib_list = NULL; 935 if (PLATFORM_SDK_VERSION <= 19) { 936 local_attrib_list = new EGLint[attribs_size]; 937 memcpy(local_attrib_list, attrib_list, attribs_size * sizeof(EGLint)); 938 EGLint* local_attrib_p = local_attrib_list; 939 while (local_attrib_p[0] != EGL_NONE) { 940 if (local_attrib_p[0] == EGL_SURFACE_TYPE) { 941 local_attrib_p[1] &= ~(EGLint)EGL_SWAP_BEHAVIOR_PRESERVED_BIT; 942 } 943 local_attrib_p += 2; 944 } 945 } 946 947 uint32_t* tempConfigs[config_size]; 948 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 949 *num_config = rcEnc->rcChooseConfig(rcEnc, 950 local_attrib_list ? local_attrib_list:(EGLint*)attrib_list, 951 attribs_size * sizeof(EGLint), (uint32_t*)tempConfigs, config_size); 952 953 if (local_attrib_list) delete [] local_attrib_list; 954 if (*num_config <= 0) { 955 EGLint err = -(*num_config); 956 *num_config = 0; 957 switch (err) { 958 case EGL_BAD_ATTRIBUTE: 959 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); 960 default: 961 return EGL_FALSE; 962 } 963 } 964 965 if (configs!=NULL) { 966 EGLint i=0; 967 for (i=0;i<(*num_config);i++) { 968 *((uintptr_t*)configs+i) = *((uint32_t*)tempConfigs+i); 969 } 970 } 971 972 return EGL_TRUE; 973 } 974 975 EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) 976 { 977 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 978 VALIDATE_CONFIG(config, EGL_FALSE); 979 980 if (s_display.getConfigAttrib(config, attribute, value)) 981 { 982 return EGL_TRUE; 983 } 984 else 985 { 986 ALOGD("%s: bad attrib 0x%x", __FUNCTION__, attribute); 987 RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE); 988 } 989 } 990 991 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) 992 { 993 (void)attrib_list; 994 995 VALIDATE_DISPLAY_INIT(dpy, NULL); 996 VALIDATE_CONFIG(config, EGL_FALSE); 997 if (win == 0) { 998 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); 999 } 1000 1001 EGLint surfaceType; 1002 if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; 1003 1004 if (!(surfaceType & EGL_WINDOW_BIT)) { 1005 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); 1006 } 1007 1008 if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { 1009 setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); 1010 } 1011 1012 egl_surface_t* surface = egl_window_surface_t::create( 1013 &s_display, config, EGL_WINDOW_BIT, static_cast<ANativeWindow*>(win)); 1014 if (!surface) { 1015 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1016 } 1017 1018 return surface; 1019 } 1020 1021 EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) 1022 { 1023 VALIDATE_DISPLAY_INIT(dpy, NULL); 1024 VALIDATE_CONFIG(config, EGL_FALSE); 1025 1026 EGLint surfaceType; 1027 if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; 1028 1029 if (!(surfaceType & EGL_PBUFFER_BIT)) { 1030 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); 1031 } 1032 1033 int32_t w = 0; 1034 int32_t h = 0; 1035 EGLint texFormat = EGL_NO_TEXTURE; 1036 EGLint texTarget = EGL_NO_TEXTURE; 1037 while (attrib_list[0] != EGL_NONE) { 1038 switch (attrib_list[0]) { 1039 case EGL_WIDTH: 1040 w = attrib_list[1]; 1041 if (w < 0) setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE); 1042 break; 1043 case EGL_HEIGHT: 1044 h = attrib_list[1]; 1045 if (h < 0) setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE); 1046 break; 1047 case EGL_TEXTURE_FORMAT: 1048 texFormat = attrib_list[1]; 1049 break; 1050 case EGL_TEXTURE_TARGET: 1051 texTarget = attrib_list[1]; 1052 break; 1053 // the followings are not supported 1054 case EGL_LARGEST_PBUFFER: 1055 case EGL_MIPMAP_TEXTURE: 1056 case EGL_VG_ALPHA_FORMAT: 1057 case EGL_VG_COLORSPACE: 1058 break; 1059 default: 1060 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); 1061 }; 1062 attrib_list+=2; 1063 } 1064 if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) || 1065 ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) { 1066 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); 1067 } 1068 // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage 1069 1070 GLenum pixelFormat; 1071 if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE) 1072 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); 1073 1074 egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config, 1075 EGL_PBUFFER_BIT, w, h, pixelFormat); 1076 if (!surface) { 1077 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); 1078 } 1079 1080 //setup attributes 1081 surface->setTextureFormat(texFormat); 1082 surface->setTextureTarget(texTarget); 1083 1084 return surface; 1085 } 1086 1087 EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) 1088 { 1089 //XXX: Pixmap not supported. The host cannot render to a pixmap resource 1090 // located on host. In order to support Pixmaps we should either punt 1091 // to s/w rendering -or- let the host render to a buffer that will be 1092 // copied back to guest at some sync point. None of those methods not 1093 // implemented and pixmaps are not used with OpenGL anyway ... 1094 VALIDATE_CONFIG(config, EGL_FALSE); 1095 (void)dpy; 1096 (void)pixmap; 1097 (void)attrib_list; 1098 return EGL_NO_SURFACE; 1099 } 1100 1101 EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface) 1102 { 1103 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1104 VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); 1105 1106 EGLThreadInfo* tInfo = getEGLThreadInfo(); 1107 egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface)); 1108 if (surface->isCurrent()) { 1109 surface->deletePending = 1; 1110 } else { 1111 delete surface; 1112 } 1113 1114 return EGL_TRUE; 1115 } 1116 1117 static float s_getNativeDpi() { 1118 float nativeDPI = 560.0f; 1119 const char* dpiPropName = "qemu.sf.lcd_density"; 1120 char dpiProp[PROPERTY_VALUE_MAX]; 1121 if (property_get(dpiPropName, dpiProp, NULL) > 0) { 1122 nativeDPI = atof(dpiProp); 1123 } 1124 return nativeDPI; 1125 } 1126 1127 EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value) 1128 { 1129 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1130 VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); 1131 1132 egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); 1133 1134 // Parameters involved in queries of EGL_(HORIZONTAL|VERTICAL)_RESOLUTION 1135 float currWidth, currHeight, scaledResolution, effectiveSurfaceDPI; 1136 EGLBoolean ret = EGL_TRUE; 1137 switch (attribute) { 1138 case EGL_CONFIG_ID: 1139 ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value); 1140 break; 1141 case EGL_WIDTH: 1142 *value = surface->getWidth(); 1143 break; 1144 case EGL_HEIGHT: 1145 *value = surface->getHeight(); 1146 break; 1147 case EGL_TEXTURE_FORMAT: 1148 if (surface->getSurfaceType() & EGL_PBUFFER_BIT) { 1149 *value = surface->getTextureFormat(); 1150 } 1151 break; 1152 case EGL_TEXTURE_TARGET: 1153 if (surface->getSurfaceType() & EGL_PBUFFER_BIT) { 1154 *value = surface->getTextureTarget(); 1155 } 1156 break; 1157 case EGL_SWAP_BEHAVIOR: 1158 { 1159 EGLint surfaceType; 1160 ret = s_display.getConfigAttrib(surface->config, EGL_SURFACE_TYPE, 1161 &surfaceType); 1162 if (ret == EGL_TRUE) { 1163 if (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) { 1164 *value = EGL_BUFFER_PRESERVED; 1165 } else { 1166 *value = EGL_BUFFER_DESTROYED; 1167 } 1168 } 1169 break; 1170 } 1171 case EGL_LARGEST_PBUFFER: 1172 // not modified for a window or pixmap surface 1173 // and we ignore it when creating a PBuffer surface (default is EGL_FALSE) 1174 if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE; 1175 break; 1176 case EGL_MIPMAP_TEXTURE: 1177 // not modified for a window or pixmap surface 1178 // and we ignore it when creating a PBuffer surface (default is 0) 1179 if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = false; 1180 break; 1181 case EGL_MIPMAP_LEVEL: 1182 // not modified for a window or pixmap surface 1183 // and we ignore it when creating a PBuffer surface (default is 0) 1184 if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = 0; 1185 break; 1186 case EGL_MULTISAMPLE_RESOLVE: 1187 // ignored when creating the surface, return default 1188 *value = EGL_MULTISAMPLE_RESOLVE_DEFAULT; 1189 break; 1190 case EGL_HORIZONTAL_RESOLUTION: 1191 // pixel/mm * EGL_DISPLAY_SCALING 1192 // TODO: get the DPI from avd config 1193 currWidth = surface->getWidth(); 1194 scaledResolution = currWidth / surface->getNativeWidth(); 1195 effectiveSurfaceDPI = 1196 scaledResolution * s_getNativeDpi() * EGL_DISPLAY_SCALING; 1197 *value = (EGLint)(effectiveSurfaceDPI); 1198 break; 1199 case EGL_VERTICAL_RESOLUTION: 1200 // pixel/mm * EGL_DISPLAY_SCALING 1201 // TODO: get the real DPI from avd config 1202 currHeight = surface->getHeight(); 1203 scaledResolution = currHeight / surface->getNativeHeight(); 1204 effectiveSurfaceDPI = 1205 scaledResolution * s_getNativeDpi() * EGL_DISPLAY_SCALING; 1206 *value = (EGLint)(effectiveSurfaceDPI); 1207 break; 1208 case EGL_PIXEL_ASPECT_RATIO: 1209 // w / h * EGL_DISPLAY_SCALING 1210 // Please don't ask why * EGL_DISPLAY_SCALING, the document says it 1211 *value = 1 * EGL_DISPLAY_SCALING; 1212 break; 1213 case EGL_RENDER_BUFFER: 1214 switch (surface->getSurfaceType()) { 1215 case EGL_PBUFFER_BIT: 1216 *value = EGL_BACK_BUFFER; 1217 break; 1218 case EGL_PIXMAP_BIT: 1219 *value = EGL_SINGLE_BUFFER; 1220 break; 1221 case EGL_WINDOW_BIT: 1222 // ignored when creating the surface, return default 1223 *value = EGL_BACK_BUFFER; 1224 break; 1225 default: 1226 ALOGE("eglQuerySurface %x unknown surface type %x", 1227 attribute, surface->getSurfaceType()); 1228 ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1229 break; 1230 } 1231 break; 1232 case EGL_VG_COLORSPACE: 1233 // ignored when creating the surface, return default 1234 *value = EGL_VG_COLORSPACE_sRGB; 1235 break; 1236 case EGL_VG_ALPHA_FORMAT: 1237 // ignored when creating the surface, return default 1238 *value = EGL_VG_ALPHA_FORMAT_NONPRE; 1239 break; 1240 case EGL_TIMESTAMPS_ANDROID: 1241 *value = surface->isCollectingTimestamps(); 1242 break; 1243 //TODO: complete other attributes 1244 default: 1245 ALOGE("eglQuerySurface %x EGL_BAD_ATTRIBUTE", attribute); 1246 ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1247 break; 1248 } 1249 1250 return ret; 1251 } 1252 1253 EGLBoolean eglBindAPI(EGLenum api) 1254 { 1255 if (api != EGL_OPENGL_ES_API) 1256 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); 1257 return EGL_TRUE; 1258 } 1259 1260 EGLenum eglQueryAPI() 1261 { 1262 return EGL_OPENGL_ES_API; 1263 } 1264 1265 EGLBoolean eglWaitClient() 1266 { 1267 return eglWaitGL(); 1268 } 1269 1270 // We may need to trigger this directly from the TLS destructor. 1271 static EGLBoolean s_eglReleaseThreadImpl(EGLThreadInfo* tInfo) { 1272 if (!tInfo) return EGL_TRUE; 1273 1274 tInfo->eglError = EGL_SUCCESS; 1275 EGLContext_t* context = tInfo->currentContext; 1276 1277 if (!context || !s_display.isContext(context)) return EGL_TRUE; 1278 1279 // The following code is doing pretty much the same thing as 1280 // eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE) 1281 // with the only issue that we do not require a valid display here. 1282 DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(EGL_FALSE, tInfo); 1283 // We are going to call makeCurrent on the null context and surface 1284 // anyway once we are on the host, so skip rcMakeCurrent here. 1285 // rcEnc->rcMakeCurrent(rcEnc, 0, 0, 0); 1286 context->flags &= ~EGLContext_t::IS_CURRENT; 1287 1288 s_destroyPendingSurfacesInContext(context); 1289 1290 if (context->deletePending) { 1291 if (context->rcContext) { 1292 rcEnc->rcDestroyContext(rcEnc, context->rcContext); 1293 context->rcContext = 0; 1294 } 1295 delete context; 1296 } 1297 tInfo->currentContext = 0; 1298 1299 return EGL_TRUE; 1300 } 1301 1302 EGLBoolean eglReleaseThread() 1303 { 1304 return s_eglReleaseThreadImpl(getEGLThreadInfo()); 1305 } 1306 1307 EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) 1308 { 1309 //TODO 1310 (void)dpy; 1311 (void)buftype; 1312 (void)buffer; 1313 (void)config; 1314 (void)attrib_list; 1315 ALOGW("%s not implemented", __FUNCTION__); 1316 return 0; 1317 } 1318 1319 EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) 1320 { 1321 // Right now we don't do anything when using host GPU. 1322 // This is purely just to pass the data through 1323 // without issuing a warning. We may benefit from validating the 1324 // display and surface for debug purposes. 1325 // TODO: Find cases where we actually need to do something. 1326 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1327 VALIDATE_SURFACE_RETURN(surface, EGL_FALSE); 1328 if (surface == EGL_NO_SURFACE) { 1329 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 1330 } 1331 1332 (void)value; 1333 1334 egl_surface_t* p_surface( static_cast<egl_surface_t*>(surface) ); 1335 switch (attribute) { 1336 case EGL_MIPMAP_LEVEL: 1337 return true; 1338 case EGL_MULTISAMPLE_RESOLVE: 1339 { 1340 if (value == EGL_MULTISAMPLE_RESOLVE_BOX) { 1341 EGLint surface_type; 1342 s_display.getConfigAttrib(p_surface->config, EGL_SURFACE_TYPE, &surface_type); 1343 if (0 == (surface_type & EGL_MULTISAMPLE_RESOLVE_BOX_BIT)) { 1344 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); 1345 } 1346 } 1347 return true; 1348 } 1349 case EGL_SWAP_BEHAVIOR: 1350 if (value == EGL_BUFFER_PRESERVED) { 1351 EGLint surface_type; 1352 s_display.getConfigAttrib(p_surface->config, EGL_SURFACE_TYPE, &surface_type); 1353 if (0 == (surface_type & EGL_SWAP_BEHAVIOR_PRESERVED_BIT)) { 1354 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); 1355 } 1356 } 1357 return true; 1358 case EGL_TIMESTAMPS_ANDROID: 1359 ALOGD("%s: set frame timestamps collecting %d\n", __func__, value); 1360 p_surface->setCollectingTimestamps(value); 1361 return true; 1362 default: 1363 ALOGW("%s: attr=0x%x not implemented", __FUNCTION__, attribute); 1364 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1365 } 1366 return false; 1367 } 1368 1369 EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer) 1370 { 1371 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1372 VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); 1373 if (eglSurface == EGL_NO_SURFACE) { 1374 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 1375 } 1376 1377 if (buffer != EGL_BACK_BUFFER) { 1378 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); 1379 } 1380 1381 egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); 1382 1383 if (surface->getTextureFormat() == EGL_NO_TEXTURE) { 1384 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); 1385 } 1386 1387 if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) { 1388 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 1389 } 1390 1391 //It's now safe to cast to pbuffer surface 1392 egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface; 1393 1394 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 1395 rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer()); 1396 1397 return GL_TRUE; 1398 } 1399 1400 EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 1401 { 1402 //TODO 1403 (void)dpy; 1404 (void)surface; 1405 (void)buffer; 1406 ALOGW("%s not implemented", __FUNCTION__); 1407 return 0; 1408 } 1409 1410 EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) 1411 { 1412 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1413 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 1414 1415 EGLContext_t* ctx = getEGLThreadInfo()->currentContext; 1416 if (!ctx) { 1417 setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); 1418 } 1419 if (!ctx->draw) { 1420 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 1421 } 1422 egl_surface_t* draw(static_cast<egl_surface_t*>(ctx->draw)); 1423 draw->setSwapInterval(interval); 1424 1425 rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host 1426 1427 return EGL_TRUE; 1428 } 1429 1430 EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) 1431 { 1432 VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT); 1433 VALIDATE_CONFIG(config, EGL_NO_CONTEXT); 1434 1435 EGLint majorVersion = 1; //default 1436 EGLint minorVersion = 0; 1437 EGLint context_flags = 0; 1438 EGLint profile_mask = 0; 1439 EGLint reset_notification_strategy = 0; 1440 1441 bool wantedMajorVersion = false; 1442 bool wantedMinorVersion = false; 1443 1444 while (attrib_list && attrib_list[0] != EGL_NONE) { 1445 EGLint attrib_val = attrib_list[1]; 1446 switch(attrib_list[0]) { 1447 case EGL_CONTEXT_MAJOR_VERSION_KHR: 1448 majorVersion = attrib_val; 1449 wantedMajorVersion = true; 1450 break; 1451 case EGL_CONTEXT_MINOR_VERSION_KHR: 1452 minorVersion = attrib_val; 1453 wantedMinorVersion = true; 1454 break; 1455 case EGL_CONTEXT_FLAGS_KHR: 1456 if ((attrib_val | EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR) || 1457 (attrib_val | EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR) || 1458 (attrib_val | EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR)) { 1459 context_flags = attrib_val; 1460 } else { 1461 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE); 1462 } 1463 break; 1464 case EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR: 1465 if ((attrib_val | EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR) || 1466 (attrib_val | EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR)) { 1467 profile_mask = attrib_val; 1468 } else { 1469 RETURN_ERROR(EGL_NO_CONTEXT,EGL_BAD_ATTRIBUTE); 1470 } 1471 break; 1472 case EGL_CONTEXT_PRIORITY_LEVEL_IMG: 1473 // According to the spec, we are allowed not to honor this hint. 1474 // https://www.khronos.org/registry/EGL/extensions/IMG/EGL_IMG_context_priority.txt 1475 break; 1476 default: 1477 ALOGV("eglCreateContext unsupported attrib 0x%x", attrib_list[0]); 1478 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); 1479 } 1480 attrib_list+=2; 1481 } 1482 1483 // Support up to GLES 3.2 depending on advertised version from the host system. 1484 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT); 1485 if (rcEnc->getGLESMaxVersion() >= GLES_MAX_VERSION_3_0) { 1486 if (!wantedMajorVersion) { 1487 majorVersion = 1; 1488 wantedMinorVersion = false; 1489 } 1490 1491 if (wantedMajorVersion && 1492 majorVersion == 2) { 1493 majorVersion = 3; 1494 wantedMinorVersion = false; 1495 } 1496 1497 if (majorVersion == 3 && !wantedMinorVersion) { 1498 switch (rcEnc->getGLESMaxVersion()) { 1499 case GLES_MAX_VERSION_3_0: 1500 minorVersion = 0; 1501 break; 1502 case GLES_MAX_VERSION_3_1: 1503 minorVersion = 1; 1504 break; 1505 case GLES_MAX_VERSION_3_2: 1506 minorVersion = 2; 1507 break; 1508 default: 1509 minorVersion = 0; 1510 break; 1511 } 1512 } 1513 } else { 1514 if (!wantedMajorVersion) { 1515 majorVersion = 1; 1516 } 1517 } 1518 1519 switch (majorVersion) { 1520 case 1: 1521 case 2: 1522 break; 1523 case 3: 1524 if (rcEnc->getGLESMaxVersion() < GLES_MAX_VERSION_3_0) { 1525 ALOGE("%s: EGL_BAD_CONFIG: no ES 3 support", __FUNCTION__); 1526 setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT); 1527 } 1528 switch (minorVersion) { 1529 case 0: 1530 break; 1531 case 1: 1532 if (rcEnc->getGLESMaxVersion() < GLES_MAX_VERSION_3_1) { 1533 ALOGE("%s: EGL_BAD_CONFIG: no ES 3.1 support", __FUNCTION__); 1534 setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT); 1535 } 1536 break; 1537 case 2: 1538 if (rcEnc->getGLESMaxVersion() < GLES_MAX_VERSION_3_2) { 1539 ALOGE("%s: EGL_BAD_CONFIG: no ES 3.2 support", __FUNCTION__); 1540 setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT); 1541 } 1542 break; 1543 default: 1544 ALOGE("%s: EGL_BAD_CONFIG: Unknown ES version %d.%d", 1545 __FUNCTION__, majorVersion, minorVersion); 1546 setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT); 1547 } 1548 break; 1549 default: 1550 setErrorReturn(EGL_BAD_CONFIG, EGL_NO_CONTEXT); 1551 } 1552 1553 uint32_t rcShareCtx = 0; 1554 EGLContext_t * shareCtx = NULL; 1555 if (share_context) { 1556 shareCtx = static_cast<EGLContext_t*>(share_context); 1557 rcShareCtx = shareCtx->rcContext; 1558 if (shareCtx->dpy != dpy) 1559 setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT); 1560 } 1561 1562 // We've created EGL context. Disconnecting 1563 // would be dangerous at this point. 1564 hostCon->setGrallocOnly(false); 1565 1566 int rcMajorVersion = majorVersion; 1567 if (majorVersion == 3 && minorVersion == 1) { 1568 rcMajorVersion = 4; 1569 } 1570 if (majorVersion == 3 && minorVersion == 2) { 1571 rcMajorVersion = 4; 1572 } 1573 uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uintptr_t)config, rcShareCtx, rcMajorVersion); 1574 if (!rcContext) { 1575 ALOGE("rcCreateContext returned 0"); 1576 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); 1577 } 1578 1579 EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx, majorVersion, minorVersion); 1580 ALOGD("%s: %p: maj %d min %d rcv %d", __FUNCTION__, context, majorVersion, minorVersion, rcMajorVersion); 1581 if (!context) { 1582 ALOGE("could not alloc egl context!"); 1583 setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); 1584 } 1585 1586 context->rcContext = rcContext; 1587 return context; 1588 } 1589 1590 EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) 1591 { 1592 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1593 VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); 1594 1595 EGLContext_t * context = static_cast<EGLContext_t*>(ctx); 1596 1597 if (context->flags & EGLContext_t::IS_CURRENT) { 1598 context->deletePending = 1; 1599 return EGL_TRUE; 1600 } 1601 1602 if (context->rcContext) { 1603 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 1604 rcEnc->rcDestroyContext(rcEnc, context->rcContext); 1605 context->rcContext = 0; 1606 } 1607 1608 delete context; 1609 return EGL_TRUE; 1610 } 1611 1612 EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) 1613 { 1614 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1615 VALIDATE_SURFACE_RETURN(draw, EGL_FALSE); 1616 VALIDATE_SURFACE_RETURN(read, EGL_FALSE); 1617 1618 // Only place to initialize the TLS destructor; any 1619 // thread can suddenly jump in any eglMakeCurrent 1620 setTlsDestructor((tlsDtorCallback)s_eglReleaseThreadImpl); 1621 1622 if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) 1623 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); 1624 if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT)) 1625 setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); 1626 1627 EGLContext_t * context = static_cast<EGLContext_t*>(ctx); 1628 uint32_t ctxHandle = (context) ? context->rcContext : 0; 1629 egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw); 1630 uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0; 1631 egl_surface_t * readSurf = static_cast<egl_surface_t *>(read); 1632 uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0; 1633 1634 // 1635 // Nothing to do if no binding change has made 1636 // 1637 EGLThreadInfo *tInfo = getEGLThreadInfo(); 1638 1639 if (tInfo->currentContext == context && 1640 (context == NULL || 1641 (context && (context->draw == draw) && (context->read == read)))) { 1642 return EGL_TRUE; 1643 } 1644 1645 if (tInfo->currentContext) { 1646 EGLContext_t* prevCtx = tInfo->currentContext; 1647 1648 if (prevCtx->draw) { 1649 static_cast<egl_surface_t *>(prevCtx->draw)->setIsCurrent(false); 1650 } 1651 if (prevCtx->read) { 1652 static_cast<egl_surface_t *>(prevCtx->read)->setIsCurrent(false); 1653 } 1654 s_destroyPendingSurfacesInContext(tInfo->currentContext); 1655 1656 if (prevCtx->deletePending && prevCtx != context) { 1657 tInfo->currentContext = 0; 1658 eglDestroyContext(dpy, prevCtx); 1659 } 1660 } 1661 1662 if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { 1663 // context is current to another thread 1664 ALOGE("%s: error: EGL_BAD_ACCESS: context %p current to another thread!\n", __FUNCTION__, context); 1665 setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); 1666 } 1667 1668 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 1669 if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) { 1670 ALOGE("rcMakeCurrent returned EGL_FALSE"); 1671 setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); 1672 } 1673 1674 //Now make the local bind 1675 if (context) { 1676 1677 ALOGD("%s: %p: ver %d %d (tinfo %p)", __FUNCTION__, context, context->majorVersion, context->minorVersion, tInfo); 1678 // This is a nontrivial context. 1679 // The thread cannot be gralloc-only anymore. 1680 hostCon->setGrallocOnly(false); 1681 context->draw = draw; 1682 context->read = read; 1683 if (drawSurf) { 1684 drawSurf->setIsCurrent(true); 1685 } 1686 if (readSurf) { 1687 readSurf->setIsCurrent(true); 1688 } 1689 context->flags |= EGLContext_t::IS_CURRENT; 1690 GLClientState* contextState = 1691 context->getClientState(); 1692 1693 if (!hostCon->gl2Encoder()->isInitialized()) { 1694 s_display.gles2_iface()->init(); 1695 hostCon->gl2Encoder()->setInitialized(); 1696 ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1); 1697 } 1698 if (contextState->needsInitFromCaps()) { 1699 // Need to set the version first if 1700 // querying caps, or validation will trip incorrectly. 1701 hostCon->gl2Encoder()->setVersion( 1702 context->majorVersion, 1703 context->minorVersion, 1704 context->deviceMajorVersion, 1705 context->deviceMinorVersion); 1706 // Get caps for indexed buffers from host. 1707 // Some need a current context. 1708 int max_transform_feedback_separate_attribs = 0; 1709 int max_uniform_buffer_bindings = 0; 1710 int max_atomic_counter_buffer_bindings = 0; 1711 int max_shader_storage_buffer_bindings = 0; 1712 int max_vertex_attrib_bindings = 0; 1713 int max_color_attachments = 1; 1714 int max_draw_buffers = 1; 1715 if (context->majorVersion > 2) { 1716 s_display.gles2_iface()->getIntegerv( 1717 GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &max_transform_feedback_separate_attribs); 1718 s_display.gles2_iface()->getIntegerv( 1719 GL_MAX_UNIFORM_BUFFER_BINDINGS, &max_uniform_buffer_bindings); 1720 if (context->minorVersion > 0) { 1721 s_display.gles2_iface()->getIntegerv( 1722 GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS, &max_atomic_counter_buffer_bindings); 1723 s_display.gles2_iface()->getIntegerv( 1724 GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS, &max_shader_storage_buffer_bindings); 1725 s_display.gles2_iface()->getIntegerv( 1726 GL_MAX_VERTEX_ATTRIB_BINDINGS, &max_vertex_attrib_bindings); 1727 } 1728 s_display.gles2_iface()->getIntegerv( 1729 GL_MAX_COLOR_ATTACHMENTS, &max_color_attachments); 1730 s_display.gles2_iface()->getIntegerv( 1731 GL_MAX_DRAW_BUFFERS, &max_draw_buffers); 1732 } 1733 contextState->initFromCaps( 1734 max_transform_feedback_separate_attribs, 1735 max_uniform_buffer_bindings, 1736 max_atomic_counter_buffer_bindings, 1737 max_shader_storage_buffer_bindings, 1738 max_vertex_attrib_bindings, 1739 max_color_attachments, 1740 max_draw_buffers); 1741 } 1742 1743 // update the client state, share group, and version 1744 if (context->majorVersion > 1) { 1745 hostCon->gl2Encoder()->setClientStateMakeCurrent( 1746 contextState, 1747 context->majorVersion, 1748 context->minorVersion, 1749 context->deviceMajorVersion, 1750 context->deviceMinorVersion); 1751 hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup()); 1752 } 1753 else { 1754 hostCon->glEncoder()->setClientState(context->getClientState()); 1755 hostCon->glEncoder()->setSharedGroup(context->getSharedGroup()); 1756 } 1757 } 1758 else if (tInfo->currentContext) { 1759 //release ClientState & SharedGroup 1760 if (tInfo->currentContext->majorVersion > 1) { 1761 hostCon->gl2Encoder()->setClientState(NULL); 1762 hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL)); 1763 } 1764 else { 1765 hostCon->glEncoder()->setClientState(NULL); 1766 hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL)); 1767 } 1768 1769 } 1770 1771 if (tInfo->currentContext && (tInfo->currentContext != context)) { 1772 tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT; 1773 } 1774 1775 //Now make current 1776 tInfo->currentContext = context; 1777 1778 //Check maybe we need to init the encoder, if it's first eglMakeCurrent 1779 if (tInfo->currentContext) { 1780 if (tInfo->currentContext->majorVersion > 1) { 1781 if (!hostCon->gl2Encoder()->isInitialized()) { 1782 s_display.gles2_iface()->init(); 1783 hostCon->gl2Encoder()->setInitialized(); 1784 ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1); 1785 } 1786 const char* exts = getGLString(GL_EXTENSIONS); 1787 if (exts) { 1788 hostCon->gl2Encoder()->setExtensions(exts, getExtStringArray()); 1789 } 1790 } 1791 else { 1792 if (!hostCon->glEncoder()->isInitialized()) { 1793 s_display.gles_iface()->init(); 1794 hostCon->glEncoder()->setInitialized(); 1795 ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0); 1796 } 1797 } 1798 } 1799 1800 return EGL_TRUE; 1801 } 1802 1803 EGLContext eglGetCurrentContext() 1804 { 1805 return getEGLThreadInfo()->currentContext; 1806 } 1807 1808 EGLSurface eglGetCurrentSurface(EGLint readdraw) 1809 { 1810 EGLContext_t * context = getEGLThreadInfo()->currentContext; 1811 if (!context) 1812 return EGL_NO_SURFACE; //not an error 1813 1814 switch (readdraw) { 1815 case EGL_READ: 1816 return context->read; 1817 case EGL_DRAW: 1818 return context->draw; 1819 default: 1820 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE); 1821 } 1822 } 1823 1824 EGLDisplay eglGetCurrentDisplay() 1825 { 1826 EGLContext_t * context = getEGLThreadInfo()->currentContext; 1827 if (!context) 1828 return EGL_NO_DISPLAY; //not an error 1829 1830 return context->dpy; 1831 } 1832 1833 EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) 1834 { 1835 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1836 VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); 1837 1838 EGLContext_t * context = static_cast<EGLContext_t*>(ctx); 1839 1840 EGLBoolean ret = EGL_TRUE; 1841 switch (attribute) { 1842 case EGL_CONFIG_ID: 1843 ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value); 1844 break; 1845 case EGL_CONTEXT_CLIENT_TYPE: 1846 *value = EGL_OPENGL_ES_API; 1847 break; 1848 case EGL_CONTEXT_CLIENT_VERSION: 1849 *value = context->majorVersion; 1850 break; 1851 case EGL_RENDER_BUFFER: 1852 if (!context->draw) 1853 *value = EGL_NONE; 1854 else 1855 *value = EGL_BACK_BUFFER; //single buffer not supported 1856 break; 1857 default: 1858 ALOGE("eglQueryContext %x EGL_BAD_ATTRIBUTE", attribute); 1859 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); 1860 break; 1861 } 1862 1863 return ret; 1864 } 1865 1866 EGLBoolean eglWaitGL() 1867 { 1868 EGLThreadInfo *tInfo = getEGLThreadInfo(); 1869 if (!tInfo || !tInfo->currentContext) { 1870 return EGL_FALSE; 1871 } 1872 1873 if (tInfo->currentContext->majorVersion > 1) { 1874 s_display.gles2_iface()->finish(); 1875 } 1876 else { 1877 s_display.gles_iface()->finish(); 1878 } 1879 1880 return EGL_TRUE; 1881 } 1882 1883 EGLBoolean eglWaitNative(EGLint engine) 1884 { 1885 (void)engine; 1886 return EGL_TRUE; 1887 } 1888 1889 EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface) 1890 { 1891 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 1892 if (eglSurface == EGL_NO_SURFACE) 1893 setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); 1894 1895 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 1896 1897 egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface); 1898 if (d->dpy != dpy) 1899 setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); 1900 1901 // post the surface 1902 EGLBoolean ret = d->swapBuffers(); 1903 1904 hostCon->flush(); 1905 return ret; 1906 } 1907 1908 EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 1909 { 1910 //TODO :later 1911 (void)dpy; 1912 (void)surface; 1913 (void)target; 1914 return 0; 1915 } 1916 1917 EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) 1918 { 1919 //TODO later 1920 (void)display; 1921 (void)surface; 1922 (void)attrib_list; 1923 return 0; 1924 } 1925 1926 EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) 1927 { 1928 //TODO later 1929 (void)display; 1930 (void)surface; 1931 return 0; 1932 } 1933 1934 EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) 1935 { 1936 (void)attrib_list; 1937 1938 VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR); 1939 1940 if (target == EGL_NATIVE_BUFFER_ANDROID) { 1941 if (ctx != EGL_NO_CONTEXT) { 1942 setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); 1943 } 1944 1945 android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer; 1946 1947 if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) 1948 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 1949 1950 if (native_buffer->common.version != sizeof(android_native_buffer_t)) 1951 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 1952 1953 cb_handle_t *cb = (cb_handle_t *)(native_buffer->handle); 1954 1955 switch (cb->format) { 1956 case HAL_PIXEL_FORMAT_RGBA_8888: 1957 case HAL_PIXEL_FORMAT_RGBX_8888: 1958 case HAL_PIXEL_FORMAT_RGB_888: 1959 case HAL_PIXEL_FORMAT_RGB_565: 1960 case HAL_PIXEL_FORMAT_YV12: 1961 case HAL_PIXEL_FORMAT_BGRA_8888: 1962 case HAL_PIXEL_FORMAT_RGBA_FP16: 1963 case HAL_PIXEL_FORMAT_RGBA_1010102: 1964 break; 1965 default: 1966 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 1967 } 1968 1969 native_buffer->common.incRef(&native_buffer->common); 1970 1971 EGLImage_t *image = new EGLImage_t(); 1972 image->dpy = dpy; 1973 image->target = target; 1974 image->native_buffer = native_buffer; 1975 1976 return (EGLImageKHR)image; 1977 } 1978 else if (target == EGL_GL_TEXTURE_2D_KHR) { 1979 VALIDATE_CONTEXT_RETURN(ctx, EGL_NO_IMAGE_KHR); 1980 1981 EGLContext_t *context = static_cast<EGLContext_t*>(ctx); 1982 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_IMAGE_KHR); 1983 1984 uint32_t ctxHandle = (context) ? context->rcContext : 0; 1985 GLuint texture = (GLuint)reinterpret_cast<uintptr_t>(buffer); 1986 uint32_t img = rcEnc->rcCreateClientImage(rcEnc, ctxHandle, target, texture); 1987 EGLImage_t *image = new EGLImage_t(); 1988 image->dpy = dpy; 1989 image->target = target; 1990 image->host_egl_image = img; 1991 1992 return (EGLImageKHR)image; 1993 } 1994 1995 setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); 1996 } 1997 1998 EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) 1999 { 2000 VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); 2001 EGLImage_t *image = (EGLImage_t*)img; 2002 2003 if (!image || image->dpy != dpy) { 2004 RETURN_ERROR(EGL_FALSE, EGL_BAD_PARAMETER); 2005 } 2006 2007 if (image->target == EGL_NATIVE_BUFFER_ANDROID) { 2008 android_native_buffer_t* native_buffer = image->native_buffer; 2009 2010 if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) 2011 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); 2012 2013 if (native_buffer->common.version != sizeof(android_native_buffer_t)) 2014 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); 2015 2016 native_buffer->common.decRef(&native_buffer->common); 2017 delete image; 2018 2019 return EGL_TRUE; 2020 } 2021 else if (image->target == EGL_GL_TEXTURE_2D_KHR) { 2022 uint32_t host_egl_image = image->host_egl_image; 2023 delete image; 2024 DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); 2025 return rcEnc->rcDestroyClientImage(rcEnc, host_egl_image); 2026 } 2027 2028 setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); 2029 } 2030 2031 #define FENCE_SYNC_HANDLE (EGLSyncKHR)0xFE4CE 2032 #define MAX_EGL_SYNC_ATTRIBS 10 2033 2034 EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, 2035 const EGLint *attrib_list) 2036 { 2037 VALIDATE_DISPLAY(dpy, EGL_NO_SYNC_KHR); 2038 DPRINT("type for eglCreateSyncKHR: 0x%x", type); 2039 2040 DEFINE_HOST_CONNECTION; 2041 2042 if ((type != EGL_SYNC_FENCE_KHR && 2043 type != EGL_SYNC_NATIVE_FENCE_ANDROID) || 2044 (type != EGL_SYNC_FENCE_KHR && 2045 !rcEnc->hasNativeSync())) { 2046 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); 2047 } 2048 2049 EGLThreadInfo *tInfo = getEGLThreadInfo(); 2050 if (!tInfo || !tInfo->currentContext) { 2051 setErrorReturn(EGL_BAD_MATCH, EGL_NO_SYNC_KHR); 2052 } 2053 2054 int num_actual_attribs = 0; 2055 2056 // If attrib_list is not NULL, 2057 // ensure attrib_list contains (key, value) pairs 2058 // followed by a single EGL_NONE. 2059 // Also validate attribs. 2060 int inputFenceFd = -1; 2061 if (attrib_list) { 2062 for (int i = 0; i < MAX_EGL_SYNC_ATTRIBS; i += 2) { 2063 if (attrib_list[i] == EGL_NONE) { 2064 num_actual_attribs = i; 2065 break; 2066 } 2067 if (i + 1 == MAX_EGL_SYNC_ATTRIBS) { 2068 DPRINT("ERROR: attrib list without EGL_NONE"); 2069 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); 2070 } 2071 } 2072 2073 // Validate and input attribs 2074 for (int i = 0; i < num_actual_attribs; i += 2) { 2075 if (attrib_list[i] == EGL_SYNC_TYPE_KHR) { 2076 DPRINT("ERROR: attrib key = EGL_SYNC_TYPE_KHR"); 2077 } 2078 if (attrib_list[i] == EGL_SYNC_STATUS_KHR) { 2079 DPRINT("ERROR: attrib key = EGL_SYNC_STATUS_KHR"); 2080 } 2081 if (attrib_list[i] == EGL_SYNC_CONDITION_KHR) { 2082 DPRINT("ERROR: attrib key = EGL_SYNC_CONDITION_KHR"); 2083 } 2084 EGLint attrib_key = attrib_list[i]; 2085 EGLint attrib_val = attrib_list[i + 1]; 2086 if (attrib_key == EGL_SYNC_NATIVE_FENCE_FD_ANDROID) { 2087 if (attrib_val != EGL_NO_NATIVE_FENCE_FD_ANDROID) { 2088 inputFenceFd = attrib_val; 2089 } 2090 } 2091 DPRINT("attrib: 0x%x : 0x%x", attrib_key, attrib_val); 2092 } 2093 } 2094 2095 uint64_t sync_handle = 0; 2096 int newFenceFd = -1; 2097 2098 if (rcEnc->hasNativeSync()) { 2099 sync_handle = 2100 createNativeSync(type, attrib_list, num_actual_attribs, 2101 false /* don't destroy when signaled on the host; 2102 let the guest clean this up, 2103 because the guest called eglCreateSyncKHR. */, 2104 inputFenceFd, 2105 &newFenceFd); 2106 2107 } else { 2108 // Just trigger a glFinish if the native sync on host 2109 // is unavailable. 2110 eglWaitClient(); 2111 } 2112 2113 EGLSync_t* syncRes = new EGLSync_t(sync_handle); 2114 2115 if (type == EGL_SYNC_NATIVE_FENCE_ANDROID) { 2116 syncRes->type = EGL_SYNC_NATIVE_FENCE_ANDROID; 2117 2118 if (inputFenceFd < 0) { 2119 syncRes->android_native_fence_fd = newFenceFd; 2120 } else { 2121 DPRINT("has input fence fd %d", 2122 inputFenceFd); 2123 syncRes->android_native_fence_fd = inputFenceFd; 2124 } 2125 } else { 2126 syncRes->type = EGL_SYNC_FENCE_KHR; 2127 syncRes->android_native_fence_fd = -1; 2128 if (!rcEnc->hasNativeSync()) { 2129 syncRes->status = EGL_SIGNALED_KHR; 2130 } 2131 } 2132 2133 return (EGLSyncKHR)syncRes; 2134 } 2135 2136 EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync) 2137 { 2138 (void)dpy; 2139 2140 if (!eglsync) { 2141 DPRINT("WARNING: null sync object") 2142 return EGL_TRUE; 2143 } 2144 2145 EGLSync_t* sync = static_cast<EGLSync_t*>(eglsync); 2146 2147 if (sync && sync->android_native_fence_fd > 0) { 2148 close(sync->android_native_fence_fd); 2149 sync->android_native_fence_fd = -1; 2150 } 2151 2152 if (sync) { 2153 DEFINE_HOST_CONNECTION; 2154 if (rcEnc->hasNativeSync()) { 2155 rcEnc->rcDestroySyncKHR(rcEnc, sync->handle); 2156 } 2157 delete sync; 2158 } 2159 2160 return EGL_TRUE; 2161 } 2162 2163 EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync, EGLint flags, 2164 EGLTimeKHR timeout) 2165 { 2166 (void)dpy; 2167 2168 if (!eglsync) { 2169 DPRINT("WARNING: null sync object"); 2170 return EGL_CONDITION_SATISFIED_KHR; 2171 } 2172 2173 EGLSync_t* sync = (EGLSync_t*)eglsync; 2174 2175 DPRINT("sync=0x%lx (handle=0x%lx) flags=0x%x timeout=0x%llx", 2176 sync, sync->handle, flags, timeout); 2177 2178 DEFINE_HOST_CONNECTION; 2179 2180 EGLint retval; 2181 if (rcEnc->hasNativeSync()) { 2182 retval = rcEnc->rcClientWaitSyncKHR 2183 (rcEnc, sync->handle, flags, timeout); 2184 } else { 2185 retval = EGL_CONDITION_SATISFIED_KHR; 2186 } 2187 EGLint res_status; 2188 switch (sync->type) { 2189 case EGL_SYNC_FENCE_KHR: 2190 res_status = EGL_SIGNALED_KHR; 2191 break; 2192 case EGL_SYNC_NATIVE_FENCE_ANDROID: 2193 res_status = EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID; 2194 break; 2195 default: 2196 res_status = EGL_SIGNALED_KHR; 2197 } 2198 sync->status = res_status; 2199 return retval; 2200 } 2201 2202 EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR eglsync, 2203 EGLint attribute, EGLint *value) 2204 { 2205 (void)dpy; 2206 2207 EGLSync_t* sync = (EGLSync_t*)eglsync; 2208 2209 switch (attribute) { 2210 case EGL_SYNC_TYPE_KHR: 2211 *value = sync->type; 2212 return EGL_TRUE; 2213 case EGL_SYNC_STATUS_KHR: 2214 *value = sync->status; 2215 return EGL_TRUE; 2216 case EGL_SYNC_CONDITION_KHR: 2217 *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; 2218 return EGL_TRUE; 2219 default: 2220 setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); 2221 } 2222 } 2223 2224 int eglDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSyncKHR eglsync) { 2225 (void)dpy; 2226 2227 DPRINT("call"); 2228 2229 EGLSync_t* sync = (EGLSync_t*)eglsync; 2230 if (sync && sync->android_native_fence_fd > 0) { 2231 int res = dup(sync->android_native_fence_fd); 2232 return res; 2233 } else { 2234 return -1; 2235 } 2236 } 2237 2238 EGLint eglWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR eglsync, EGLint flags) { 2239 (void)dpy; 2240 2241 if (!eglsync) { 2242 ALOGE("%s: null sync object!", __FUNCTION__); 2243 return EGL_FALSE; 2244 } 2245 2246 if (flags) { 2247 ALOGE("%s: flags must be 0, got 0x%x", __FUNCTION__, flags); 2248 return EGL_FALSE; 2249 } 2250 2251 DEFINE_HOST_CONNECTION; 2252 if (rcEnc->hasNativeSyncV3()) { 2253 EGLSync_t* sync = (EGLSync_t*)eglsync; 2254 rcEnc->rcWaitSyncKHR(rcEnc, sync->handle, flags); 2255 } 2256 2257 return EGL_TRUE; 2258 } 2259