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