1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef GLLIBRARYEGL_H_ 6 #define GLLIBRARYEGL_H_ 7 8 #if defined(MOZ_X11) 9 #include "mozilla/X11Util.h" 10 #endif 11 12 #include "GLLibraryLoader.h" 13 #include "mozilla/StaticMutex.h" 14 #include "mozilla/ThreadLocal.h" 15 #include "nsIFile.h" 16 #include "GeckoProfiler.h" 17 18 #include <bitset> 19 #include <vector> 20 21 #ifdef XP_WIN 22 #ifndef WIN32_LEAN_AND_MEAN 23 #define WIN32_LEAN_AND_MEAN 1 24 #endif 25 26 #include <windows.h> 27 28 typedef HDC EGLNativeDisplayType; 29 typedef HBITMAP EGLNativePixmapType; 30 typedef HWND EGLNativeWindowType; 31 #else 32 typedef void* EGLNativeDisplayType; 33 typedef void* EGLNativePixmapType; 34 typedef void* EGLNativeWindowType; 35 36 #ifdef ANDROID 37 // We only need to explicitly dlopen egltrace 38 // on android as we can use LD_PRELOAD or other tricks 39 // on other platforms. We look for it in /data/local 40 // as that's writeable by all users 41 // 42 // This should really go in GLLibraryEGL.cpp but we currently reference 43 // APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring 44 // will come in subsequent patches on Bug 732865 45 #define APITRACE_LIB "/data/local/tmp/egltrace.so" 46 #endif 47 #endif 48 49 #if defined(MOZ_X11) 50 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay()) 51 #else 52 #define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) 53 #endif 54 55 namespace angle { 56 class Platform; 57 } 58 59 namespace mozilla { 60 61 namespace gfx { 62 class DataSourceSurface; 63 } 64 65 namespace gl { 66 67 #undef BEFORE_GL_CALL 68 #undef AFTER_GL_CALL 69 70 #ifdef DEBUG 71 72 #ifndef MOZ_FUNCTION_NAME 73 # ifdef __GNUC__ 74 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__ 75 # elif defined(_MSC_VER) 76 # define MOZ_FUNCTION_NAME __FUNCTION__ 77 # else 78 # define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name. 79 # endif 80 #endif 81 82 #ifdef MOZ_WIDGET_ANDROID 83 // Record the name of the GL call for better hang stacks on Android. 84 #define BEFORE_GL_CALL \ 85 PROFILER_LABEL_FUNC( \ 86 js::ProfileEntry::Category::GRAPHICS);\ 87 BeforeGLCall(MOZ_FUNCTION_NAME) 88 #else 89 #define BEFORE_GL_CALL do { \ 90 BeforeGLCall(MOZ_FUNCTION_NAME); \ 91 } while (0) 92 #endif 93 94 #define AFTER_GL_CALL do { \ 95 AfterGLCall(MOZ_FUNCTION_NAME); \ 96 } while (0) 97 #else 98 #ifdef MOZ_WIDGET_ANDROID 99 // Record the name of the GL call for better hang stacks on Android. 100 #define BEFORE_GL_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS) 101 #else 102 #define BEFORE_GL_CALL 103 #endif 104 #define AFTER_GL_CALL 105 #endif 106 107 class GLContext; 108 109 class GLLibraryEGL 110 { 111 public: GLLibraryEGL()112 GLLibraryEGL() 113 : mInitialized(false), 114 mEGLLibrary(nullptr), 115 mEGLDisplay(EGL_NO_DISPLAY), 116 mIsANGLE(false), 117 mIsWARP(false) 118 { 119 ClearSymbols(); 120 } 121 ClearSymbols()122 void ClearSymbols() { 123 mSymbols.fANGLEPlatformInitialize = nullptr; 124 mSymbols.fANGLEPlatformShutdown = nullptr; 125 mSymbols.fGetDisplay = nullptr; 126 mSymbols.fGetPlatformDisplayEXT = nullptr; 127 mSymbols.fTerminate = nullptr; 128 mSymbols.fGetCurrentSurface = nullptr; 129 mSymbols.fGetCurrentContext = nullptr; 130 mSymbols.fMakeCurrent = nullptr; 131 mSymbols.fDestroyContext = nullptr; 132 mSymbols.fCreateContext = nullptr; 133 mSymbols.fDestroySurface = nullptr; 134 mSymbols.fCreateWindowSurface = nullptr; 135 mSymbols.fCreatePbufferSurface = nullptr; 136 mSymbols.fCreatePixmapSurface = nullptr; 137 mSymbols.fBindAPI = nullptr; 138 mSymbols.fInitialize = nullptr; 139 mSymbols.fChooseConfig = nullptr; 140 mSymbols.fGetError = nullptr; 141 mSymbols.fGetConfigAttrib = nullptr; 142 mSymbols.fGetConfigs = nullptr; 143 mSymbols.fWaitNative = nullptr; 144 mSymbols.fGetProcAddress = nullptr; 145 mSymbols.fSwapBuffers = nullptr; 146 mSymbols.fCopyBuffers = nullptr; 147 mSymbols.fQueryString = nullptr; 148 mSymbols.fQueryStringImplementationANDROID = nullptr; 149 mSymbols.fQueryContext = nullptr; 150 mSymbols.fBindTexImage = nullptr; 151 mSymbols.fReleaseTexImage = nullptr; 152 mSymbols.fCreateImage = nullptr; 153 mSymbols.fDestroyImage = nullptr; 154 mSymbols.fLockSurface = nullptr; 155 mSymbols.fUnlockSurface = nullptr; 156 mSymbols.fQuerySurface = nullptr; 157 mSymbols.fQuerySurfacePointerANGLE = nullptr; 158 mSymbols.fCreateSync = nullptr; 159 mSymbols.fDestroySync = nullptr; 160 mSymbols.fClientWaitSync = nullptr; 161 mSymbols.fGetSyncAttrib = nullptr; 162 mSymbols.fDupNativeFenceFDANDROID = nullptr; 163 } 164 165 void InitClientExtensions(); 166 void InitDisplayExtensions(); 167 168 /** 169 * Known GL extensions that can be queried by 170 * IsExtensionSupported. The results of this are cached, and as 171 * such it's safe to use this even in performance critical code. 172 * If you add to this array, remember to add to the string names 173 * in GLContext.cpp. 174 */ 175 enum EGLExtensions { 176 KHR_image_base, 177 KHR_image_pixmap, 178 KHR_gl_texture_2D_image, 179 KHR_lock_surface, 180 ANGLE_surface_d3d_texture_2d_share_handle, 181 EXT_create_context_robustness, 182 KHR_image, 183 KHR_fence_sync, 184 ANDROID_native_fence_sync, 185 EGL_ANDROID_image_crop, 186 ANGLE_platform_angle, 187 ANGLE_platform_angle_d3d, 188 Extensions_Max 189 }; 190 IsExtensionSupported(EGLExtensions aKnownExtension)191 bool IsExtensionSupported(EGLExtensions aKnownExtension) const { 192 return mAvailableExtensions[aKnownExtension]; 193 } 194 MarkExtensionUnsupported(EGLExtensions aKnownExtension)195 void MarkExtensionUnsupported(EGLExtensions aKnownExtension) { 196 mAvailableExtensions[aKnownExtension] = false; 197 } 198 199 protected: 200 std::bitset<Extensions_Max> mAvailableExtensions; 201 202 public: 203 fGetDisplay(void * display_id)204 EGLDisplay fGetDisplay(void* display_id) 205 { 206 BEFORE_GL_CALL; 207 EGLDisplay disp = mSymbols.fGetDisplay(display_id); 208 AFTER_GL_CALL; 209 return disp; 210 } 211 fGetPlatformDisplayEXT(EGLenum platform,void * native_display,const EGLint * attrib_list)212 EGLDisplay fGetPlatformDisplayEXT(EGLenum platform, void* native_display, const EGLint* attrib_list) 213 { 214 BEFORE_GL_CALL; 215 EGLDisplay disp = mSymbols.fGetPlatformDisplayEXT(platform, native_display, attrib_list); 216 AFTER_GL_CALL; 217 return disp; 218 } 219 fTerminate(EGLDisplay display)220 EGLBoolean fTerminate(EGLDisplay display) 221 { 222 BEFORE_GL_CALL; 223 EGLBoolean ret = mSymbols.fTerminate(display); 224 AFTER_GL_CALL; 225 return ret; 226 } 227 fGetCurrentSurface(EGLint id)228 EGLSurface fGetCurrentSurface(EGLint id) 229 { 230 BEFORE_GL_CALL; 231 EGLSurface surf = mSymbols.fGetCurrentSurface(id); 232 AFTER_GL_CALL; 233 return surf; 234 } 235 fGetCurrentContext()236 EGLContext fGetCurrentContext() 237 { 238 BEFORE_GL_CALL; 239 EGLContext context = mSymbols.fGetCurrentContext(); 240 AFTER_GL_CALL; 241 return context; 242 } 243 fMakeCurrent(EGLDisplay dpy,EGLSurface draw,EGLSurface read,EGLContext ctx)244 EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) 245 { 246 BEFORE_GL_CALL; 247 EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx); 248 AFTER_GL_CALL; 249 return b; 250 } 251 fDestroyContext(EGLDisplay dpy,EGLContext ctx)252 EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx) 253 { 254 BEFORE_GL_CALL; 255 EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx); 256 AFTER_GL_CALL; 257 return b; 258 } 259 fCreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_context,const EGLint * attrib_list)260 EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list) 261 { 262 BEFORE_GL_CALL; 263 EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list); 264 AFTER_GL_CALL; 265 return ctx; 266 } 267 fDestroySurface(EGLDisplay dpy,EGLSurface surface)268 EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface) 269 { 270 BEFORE_GL_CALL; 271 EGLBoolean b = mSymbols.fDestroySurface(dpy, surface); 272 AFTER_GL_CALL; 273 return b; 274 } 275 fCreateWindowSurface(EGLDisplay dpy,EGLConfig config,EGLNativeWindowType win,const EGLint * attrib_list)276 EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list) 277 { 278 BEFORE_GL_CALL; 279 EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list); 280 AFTER_GL_CALL; 281 return surf; 282 } 283 fCreatePbufferSurface(EGLDisplay dpy,EGLConfig config,const EGLint * attrib_list)284 EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) 285 { 286 BEFORE_GL_CALL; 287 EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list); 288 AFTER_GL_CALL; 289 return surf; 290 } 291 fCreatePixmapSurface(EGLDisplay dpy,EGLConfig config,EGLNativePixmapType pixmap,const EGLint * attrib_list)292 EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list) 293 { 294 BEFORE_GL_CALL; 295 EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list); 296 AFTER_GL_CALL; 297 return surf; 298 } 299 fBindAPI(EGLenum api)300 EGLBoolean fBindAPI(EGLenum api) 301 { 302 BEFORE_GL_CALL; 303 EGLBoolean b = mSymbols.fBindAPI(api); 304 AFTER_GL_CALL; 305 return b; 306 } 307 fInitialize(EGLDisplay dpy,EGLint * major,EGLint * minor)308 EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) 309 { 310 BEFORE_GL_CALL; 311 EGLBoolean b = mSymbols.fInitialize(dpy, major, minor); 312 AFTER_GL_CALL; 313 return b; 314 } 315 fChooseConfig(EGLDisplay dpy,const EGLint * attrib_list,EGLConfig * configs,EGLint config_size,EGLint * num_config)316 EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) 317 { 318 BEFORE_GL_CALL; 319 EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config); 320 AFTER_GL_CALL; 321 return b; 322 } 323 fGetError()324 EGLint fGetError() 325 { 326 BEFORE_GL_CALL; 327 EGLint i = mSymbols.fGetError(); 328 AFTER_GL_CALL; 329 return i; 330 } 331 fGetConfigAttrib(EGLDisplay dpy,EGLConfig config,EGLint attribute,EGLint * value)332 EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) 333 { 334 BEFORE_GL_CALL; 335 EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value); 336 AFTER_GL_CALL; 337 return b; 338 } 339 fGetConfigs(EGLDisplay dpy,EGLConfig * configs,EGLint config_size,EGLint * num_config)340 EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) 341 { 342 BEFORE_GL_CALL; 343 EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config); 344 AFTER_GL_CALL; 345 return b; 346 } 347 fWaitNative(EGLint engine)348 EGLBoolean fWaitNative(EGLint engine) 349 { 350 BEFORE_GL_CALL; 351 EGLBoolean b = mSymbols.fWaitNative(engine); 352 AFTER_GL_CALL; 353 return b; 354 } 355 fGetProcAddress(const char * procname)356 EGLCastToRelevantPtr fGetProcAddress(const char* procname) 357 { 358 BEFORE_GL_CALL; 359 EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname); 360 AFTER_GL_CALL; 361 return p; 362 } 363 fSwapBuffers(EGLDisplay dpy,EGLSurface surface)364 EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface) 365 { 366 BEFORE_GL_CALL; 367 EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface); 368 AFTER_GL_CALL; 369 return b; 370 } 371 fCopyBuffers(EGLDisplay dpy,EGLSurface surface,EGLNativePixmapType target)372 EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) 373 { 374 BEFORE_GL_CALL; 375 EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target); 376 AFTER_GL_CALL; 377 return b; 378 } 379 fQueryString(EGLDisplay dpy,EGLint name)380 const GLubyte* fQueryString(EGLDisplay dpy, EGLint name) 381 { 382 BEFORE_GL_CALL; 383 const GLubyte* b; 384 if (mSymbols.fQueryStringImplementationANDROID) { 385 b = mSymbols.fQueryStringImplementationANDROID(dpy, name); 386 } else { 387 b = mSymbols.fQueryString(dpy, name); 388 } 389 AFTER_GL_CALL; 390 return b; 391 } 392 fQueryContext(EGLDisplay dpy,EGLContext ctx,EGLint attribute,EGLint * value)393 EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) 394 { 395 BEFORE_GL_CALL; 396 EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value); 397 AFTER_GL_CALL; 398 return b; 399 } 400 fBindTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)401 EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 402 { 403 BEFORE_GL_CALL; 404 EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer); 405 AFTER_GL_CALL; 406 return b; 407 } 408 fReleaseTexImage(EGLDisplay dpy,EGLSurface surface,EGLint buffer)409 EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) 410 { 411 BEFORE_GL_CALL; 412 EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer); 413 AFTER_GL_CALL; 414 return b; 415 } 416 fCreateImage(EGLDisplay dpy,EGLContext ctx,EGLenum target,EGLClientBuffer buffer,const EGLint * attrib_list)417 EGLImage fCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list) 418 { 419 BEFORE_GL_CALL; 420 EGLImage i = mSymbols.fCreateImage(dpy, ctx, target, buffer, attrib_list); 421 AFTER_GL_CALL; 422 return i; 423 } 424 fDestroyImage(EGLDisplay dpy,EGLImage image)425 EGLBoolean fDestroyImage(EGLDisplay dpy, EGLImage image) 426 { 427 BEFORE_GL_CALL; 428 EGLBoolean b = mSymbols.fDestroyImage(dpy, image); 429 AFTER_GL_CALL; 430 return b; 431 } 432 433 // New extension which allow us to lock texture and get raw image pointer fLockSurface(EGLDisplay dpy,EGLSurface surface,const EGLint * attrib_list)434 EGLBoolean fLockSurface(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list) 435 { 436 BEFORE_GL_CALL; 437 EGLBoolean b = mSymbols.fLockSurface(dpy, surface, attrib_list); 438 AFTER_GL_CALL; 439 return b; 440 } 441 fUnlockSurface(EGLDisplay dpy,EGLSurface surface)442 EGLBoolean fUnlockSurface(EGLDisplay dpy, EGLSurface surface) 443 { 444 BEFORE_GL_CALL; 445 EGLBoolean b = mSymbols.fUnlockSurface(dpy, surface); 446 AFTER_GL_CALL; 447 return b; 448 } 449 fQuerySurface(EGLDisplay dpy,EGLSurface surface,EGLint attribute,EGLint * value)450 EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) 451 { 452 BEFORE_GL_CALL; 453 EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value); 454 AFTER_GL_CALL; 455 return b; 456 } 457 fQuerySurfacePointerANGLE(EGLDisplay dpy,EGLSurface surface,EGLint attribute,void ** value)458 EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value) 459 { 460 BEFORE_GL_CALL; 461 EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value); 462 AFTER_GL_CALL; 463 return b; 464 } 465 fCreateSync(EGLDisplay dpy,EGLenum type,const EGLint * attrib_list)466 EGLSync fCreateSync(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) 467 { 468 BEFORE_GL_CALL; 469 EGLSync ret = mSymbols.fCreateSync(dpy, type, attrib_list); 470 AFTER_GL_CALL; 471 return ret; 472 } 473 fDestroySync(EGLDisplay dpy,EGLSync sync)474 EGLBoolean fDestroySync(EGLDisplay dpy, EGLSync sync) 475 { 476 BEFORE_GL_CALL; 477 EGLBoolean b = mSymbols.fDestroySync(dpy, sync); 478 AFTER_GL_CALL; 479 return b; 480 } 481 fClientWaitSync(EGLDisplay dpy,EGLSync sync,EGLint flags,EGLTime timeout)482 EGLint fClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) 483 { 484 BEFORE_GL_CALL; 485 EGLint ret = mSymbols.fClientWaitSync(dpy, sync, flags, timeout); 486 AFTER_GL_CALL; 487 return ret; 488 } 489 fGetSyncAttrib(EGLDisplay dpy,EGLSync sync,EGLint attribute,EGLint * value)490 EGLBoolean fGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value) 491 { 492 BEFORE_GL_CALL; 493 EGLBoolean b = mSymbols.fGetSyncAttrib(dpy, sync, attribute, value); 494 AFTER_GL_CALL; 495 return b; 496 } 497 fDupNativeFenceFDANDROID(EGLDisplay dpy,EGLSync sync)498 EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) 499 { 500 MOZ_ASSERT(mSymbols.fDupNativeFenceFDANDROID); 501 BEFORE_GL_CALL; 502 EGLint ret = mSymbols.fDupNativeFenceFDANDROID(dpy, sync); 503 AFTER_GL_CALL; 504 return ret; 505 } 506 fANGLEPlatformInitialize(angle::Platform * platform)507 void fANGLEPlatformInitialize(angle::Platform* platform) 508 { 509 MOZ_ASSERT(mSymbols.fANGLEPlatformInitialize); 510 BEFORE_GL_CALL; 511 mSymbols.fANGLEPlatformInitialize(platform); 512 AFTER_GL_CALL; 513 } 514 fANGLEPlatformShutdown()515 void fANGLEPlatformShutdown() 516 { 517 MOZ_ASSERT(mSymbols.fANGLEPlatformShutdown); 518 BEFORE_GL_CALL; 519 mSymbols.fANGLEPlatformShutdown(); 520 AFTER_GL_CALL; 521 } 522 Display()523 EGLDisplay Display() { 524 MOZ_ASSERT(mInitialized); 525 return mEGLDisplay; 526 } 527 IsANGLE()528 bool IsANGLE() const { 529 MOZ_ASSERT(mInitialized); 530 return mIsANGLE; 531 } 532 IsWARP()533 bool IsWARP() const { 534 MOZ_ASSERT(mInitialized); 535 return mIsWARP; 536 } 537 HasKHRImageBase()538 bool HasKHRImageBase() { 539 return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base); 540 } 541 HasKHRImagePixmap()542 bool HasKHRImagePixmap() { 543 return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_pixmap); 544 } 545 HasKHRImageTexture2D()546 bool HasKHRImageTexture2D() { 547 return IsExtensionSupported(KHR_gl_texture_2D_image); 548 } 549 HasANGLESurfaceD3DTexture2DShareHandle()550 bool HasANGLESurfaceD3DTexture2DShareHandle() { 551 return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle); 552 } 553 HasRobustness()554 bool HasRobustness() const { 555 return IsExtensionSupported(EXT_create_context_robustness); 556 } 557 558 bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface); 559 560 bool EnsureInitialized(bool forceAccel, nsACString* const out_failureId); 561 562 void DumpEGLConfig(EGLConfig cfg); 563 void DumpEGLConfigs(); 564 565 struct { 566 typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void* display_id); 567 pfnGetDisplay fGetDisplay; 568 typedef EGLDisplay(GLAPIENTRY * pfnGetPlatformDisplayEXT)(EGLenum platform, void* native_display, const EGLint* attrib_list); 569 pfnGetPlatformDisplayEXT fGetPlatformDisplayEXT; 570 typedef EGLBoolean (GLAPIENTRY * pfnTerminate)(EGLDisplay dpy); 571 pfnTerminate fTerminate; 572 typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint); 573 pfnGetCurrentSurface fGetCurrentSurface; 574 typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void); 575 pfnGetCurrentContext fGetCurrentContext; 576 typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); 577 pfnMakeCurrent fMakeCurrent; 578 typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx); 579 pfnDestroyContext fDestroyContext; 580 typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list); 581 pfnCreateContext fCreateContext; 582 typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface); 583 pfnDestroySurface fDestroySurface; 584 typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list); 585 pfnCreateWindowSurface fCreateWindowSurface; 586 typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list); 587 pfnCreatePbufferSurface fCreatePbufferSurface; 588 typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list); 589 pfnCreatePixmapSurface fCreatePixmapSurface; 590 typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api); 591 pfnBindAPI fBindAPI; 592 typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint* major, EGLint* minor); 593 pfnInitialize fInitialize; 594 typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config); 595 pfnChooseConfig fChooseConfig; 596 typedef EGLint (GLAPIENTRY * pfnGetError)(void); 597 pfnGetError fGetError; 598 typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value); 599 pfnGetConfigAttrib fGetConfigAttrib; 600 typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config); 601 pfnGetConfigs fGetConfigs; 602 typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine); 603 pfnWaitNative fWaitNative; 604 typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char* procname); 605 pfnGetProcAddress fGetProcAddress; 606 typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface); 607 pfnSwapBuffers fSwapBuffers; 608 typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface, 609 EGLNativePixmapType target); 610 pfnCopyBuffers fCopyBuffers; 611 typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name); 612 pfnQueryString fQueryString; 613 pfnQueryString fQueryStringImplementationANDROID; 614 typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx, 615 EGLint attribute, EGLint* value); 616 pfnQueryContext fQueryContext; 617 typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer); 618 pfnBindTexImage fBindTexImage; 619 typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer); 620 pfnReleaseTexImage fReleaseTexImage; 621 typedef EGLImage (GLAPIENTRY * pfnCreateImage)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list); 622 pfnCreateImage fCreateImage; 623 typedef EGLBoolean (GLAPIENTRY * pfnDestroyImage)(EGLDisplay dpy, EGLImage image); 624 pfnDestroyImage fDestroyImage; 625 626 // New extension which allow us to lock texture and get raw image pointer 627 typedef EGLBoolean (GLAPIENTRY * pfnLockSurface)(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list); 628 pfnLockSurface fLockSurface; 629 typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurface)(EGLDisplay dpy, EGLSurface surface); 630 pfnUnlockSurface fUnlockSurface; 631 typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value); 632 pfnQuerySurface fQuerySurface; 633 634 typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value); 635 pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE; 636 637 typedef EGLSync (GLAPIENTRY * pfnCreateSync)(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list); 638 pfnCreateSync fCreateSync; 639 typedef EGLBoolean (GLAPIENTRY * pfnDestroySync)(EGLDisplay dpy, EGLSync sync); 640 pfnDestroySync fDestroySync; 641 typedef EGLint (GLAPIENTRY * pfnClientWaitSync)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); 642 pfnClientWaitSync fClientWaitSync; 643 typedef EGLBoolean (GLAPIENTRY * pfnGetSyncAttrib)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value); 644 pfnGetSyncAttrib fGetSyncAttrib; 645 typedef EGLint (GLAPIENTRY * pfnDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync); 646 pfnDupNativeFenceFDANDROID fDupNativeFenceFDANDROID; 647 648 typedef void (GLAPIENTRY * pfnANGLEPlatformInitialize)(angle::Platform* platform); 649 pfnANGLEPlatformInitialize fANGLEPlatformInitialize; 650 typedef void (GLAPIENTRY * pfnANGLEPlatformShutdown)(); 651 pfnANGLEPlatformShutdown fANGLEPlatformShutdown; 652 } mSymbols; 653 654 #ifdef DEBUG 655 static void BeforeGLCall(const char* glFunction); 656 static void AfterGLCall(const char* glFunction); 657 #endif 658 659 #ifdef MOZ_B2G CachedCurrentContext()660 EGLContext CachedCurrentContext() { 661 return sCurrentContext.get(); 662 } UnsetCachedCurrentContext()663 void UnsetCachedCurrentContext() { 664 sCurrentContext.set(nullptr); 665 } SetCachedCurrentContext(EGLContext aCtx)666 void SetCachedCurrentContext(EGLContext aCtx) { 667 sCurrentContext.set(aCtx); 668 } CachedCurrentContextMatches()669 bool CachedCurrentContextMatches() { 670 return sCurrentContext.get() == fGetCurrentContext(); 671 } 672 673 private: 674 static MOZ_THREAD_LOCAL(EGLContext) sCurrentContext; 675 public: 676 677 #else 678 EGLContext CachedCurrentContext() { 679 return nullptr; 680 } 681 void UnsetCachedCurrentContext() {} 682 void SetCachedCurrentContext(EGLContext aCtx) { } 683 bool CachedCurrentContextMatches() { return true; } 684 #endif 685 686 private: 687 bool mInitialized; 688 PRLibrary* mEGLLibrary; 689 EGLDisplay mEGLDisplay; 690 RefPtr<GLContext> mReadbackGL; 691 692 bool mIsANGLE; 693 bool mIsWARP; 694 static StaticMutex sMutex; 695 }; 696 697 extern GLLibraryEGL sEGLLibrary; 698 #define EGL_DISPLAY() sEGLLibrary.Display() 699 700 } /* namespace gl */ 701 } /* namespace mozilla */ 702 703 #endif /* GLLIBRARYEGL_H_ */ 704 705