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