diff options
Diffstat (limited to 'gfx/gl/GLLibraryEGL.h')
-rw-r--r-- | gfx/gl/GLLibraryEGL.h | 704 |
1 files changed, 704 insertions, 0 deletions
diff --git a/gfx/gl/GLLibraryEGL.h b/gfx/gl/GLLibraryEGL.h new file mode 100644 index 000000000..fa6ea748b --- /dev/null +++ b/gfx/gl/GLLibraryEGL.h @@ -0,0 +1,704 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef GLLIBRARYEGL_H_ +#define GLLIBRARYEGL_H_ + +#if defined(MOZ_X11) +#include "mozilla/X11Util.h" +#endif + +#include "GLLibraryLoader.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/ThreadLocal.h" +#include "nsIFile.h" +#include "GeckoProfiler.h" + +#include <bitset> +#include <vector> + +#ifdef XP_WIN + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN 1 + #endif + + #include <windows.h> + + typedef HDC EGLNativeDisplayType; + typedef HBITMAP EGLNativePixmapType; + typedef HWND EGLNativeWindowType; +#else + typedef void* EGLNativeDisplayType; + typedef void* EGLNativePixmapType; + typedef void* EGLNativeWindowType; + + #ifdef ANDROID + // We only need to explicitly dlopen egltrace + // on android as we can use LD_PRELOAD or other tricks + // on other platforms. We look for it in /data/local + // as that's writeable by all users + // + // This should really go in GLLibraryEGL.cpp but we currently reference + // APITRACE_LIB in GLContextProviderEGL.cpp. Further refactoring + // will come in subsequent patches on Bug 732865 + #define APITRACE_LIB "/data/local/tmp/egltrace.so" + #endif +#endif + +#if defined(MOZ_X11) +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay()) +#else +#define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0) +#endif + +namespace angle { +class Platform; +} + +namespace mozilla { + +namespace gfx { +class DataSourceSurface; +} + +namespace gl { + +#undef BEFORE_GL_CALL +#undef AFTER_GL_CALL + +#ifdef DEBUG + +#ifndef MOZ_FUNCTION_NAME +# ifdef __GNUC__ +# define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__ +# elif defined(_MSC_VER) +# define MOZ_FUNCTION_NAME __FUNCTION__ +# else +# define MOZ_FUNCTION_NAME __func__ // defined in C99, supported in various C++ compilers. Just raw function name. +# endif +#endif + +#ifdef MOZ_WIDGET_ANDROID +// Record the name of the GL call for better hang stacks on Android. +#define BEFORE_GL_CALL \ + PROFILER_LABEL_FUNC( \ + js::ProfileEntry::Category::GRAPHICS);\ + BeforeGLCall(MOZ_FUNCTION_NAME) +#else +#define BEFORE_GL_CALL do { \ + BeforeGLCall(MOZ_FUNCTION_NAME); \ +} while (0) +#endif + +#define AFTER_GL_CALL do { \ + AfterGLCall(MOZ_FUNCTION_NAME); \ +} while (0) +#else +#ifdef MOZ_WIDGET_ANDROID +// Record the name of the GL call for better hang stacks on Android. +#define BEFORE_GL_CALL PROFILER_LABEL_FUNC(js::ProfileEntry::Category::GRAPHICS) +#else +#define BEFORE_GL_CALL +#endif +#define AFTER_GL_CALL +#endif + +class GLContext; + +class GLLibraryEGL +{ +public: + GLLibraryEGL() + : mInitialized(false), + mEGLLibrary(nullptr), + mEGLDisplay(EGL_NO_DISPLAY), + mIsANGLE(false), + mIsWARP(false) + { + ClearSymbols(); + } + + void ClearSymbols() { + mSymbols.fANGLEPlatformInitialize = nullptr; + mSymbols.fANGLEPlatformShutdown = nullptr; + mSymbols.fGetDisplay = nullptr; + mSymbols.fGetPlatformDisplayEXT = nullptr; + mSymbols.fTerminate = nullptr; + mSymbols.fGetCurrentSurface = nullptr; + mSymbols.fGetCurrentContext = nullptr; + mSymbols.fMakeCurrent = nullptr; + mSymbols.fDestroyContext = nullptr; + mSymbols.fCreateContext = nullptr; + mSymbols.fDestroySurface = nullptr; + mSymbols.fCreateWindowSurface = nullptr; + mSymbols.fCreatePbufferSurface = nullptr; + mSymbols.fCreatePixmapSurface = nullptr; + mSymbols.fBindAPI = nullptr; + mSymbols.fInitialize = nullptr; + mSymbols.fChooseConfig = nullptr; + mSymbols.fGetError = nullptr; + mSymbols.fGetConfigAttrib = nullptr; + mSymbols.fGetConfigs = nullptr; + mSymbols.fWaitNative = nullptr; + mSymbols.fGetProcAddress = nullptr; + mSymbols.fSwapBuffers = nullptr; + mSymbols.fCopyBuffers = nullptr; + mSymbols.fQueryString = nullptr; + mSymbols.fQueryStringImplementationANDROID = nullptr; + mSymbols.fQueryContext = nullptr; + mSymbols.fBindTexImage = nullptr; + mSymbols.fReleaseTexImage = nullptr; + mSymbols.fCreateImage = nullptr; + mSymbols.fDestroyImage = nullptr; + mSymbols.fLockSurface = nullptr; + mSymbols.fUnlockSurface = nullptr; + mSymbols.fQuerySurface = nullptr; + mSymbols.fQuerySurfacePointerANGLE = nullptr; + mSymbols.fCreateSync = nullptr; + mSymbols.fDestroySync = nullptr; + mSymbols.fClientWaitSync = nullptr; + mSymbols.fGetSyncAttrib = nullptr; + mSymbols.fDupNativeFenceFDANDROID = nullptr; + } + + void InitClientExtensions(); + void InitDisplayExtensions(); + + /** + * Known GL extensions that can be queried by + * IsExtensionSupported. The results of this are cached, and as + * such it's safe to use this even in performance critical code. + * If you add to this array, remember to add to the string names + * in GLContext.cpp. + */ + enum EGLExtensions { + KHR_image_base, + KHR_image_pixmap, + KHR_gl_texture_2D_image, + KHR_lock_surface, + ANGLE_surface_d3d_texture_2d_share_handle, + EXT_create_context_robustness, + KHR_image, + KHR_fence_sync, + ANDROID_native_fence_sync, + EGL_ANDROID_image_crop, + ANGLE_platform_angle, + ANGLE_platform_angle_d3d, + Extensions_Max + }; + + bool IsExtensionSupported(EGLExtensions aKnownExtension) const { + return mAvailableExtensions[aKnownExtension]; + } + + void MarkExtensionUnsupported(EGLExtensions aKnownExtension) { + mAvailableExtensions[aKnownExtension] = false; + } + +protected: + std::bitset<Extensions_Max> mAvailableExtensions; + +public: + + EGLDisplay fGetDisplay(void* display_id) + { + BEFORE_GL_CALL; + EGLDisplay disp = mSymbols.fGetDisplay(display_id); + AFTER_GL_CALL; + return disp; + } + + EGLDisplay fGetPlatformDisplayEXT(EGLenum platform, void* native_display, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLDisplay disp = mSymbols.fGetPlatformDisplayEXT(platform, native_display, attrib_list); + AFTER_GL_CALL; + return disp; + } + + EGLBoolean fTerminate(EGLDisplay display) + { + BEFORE_GL_CALL; + EGLBoolean ret = mSymbols.fTerminate(display); + AFTER_GL_CALL; + return ret; + } + + EGLSurface fGetCurrentSurface(EGLint id) + { + BEFORE_GL_CALL; + EGLSurface surf = mSymbols.fGetCurrentSurface(id); + AFTER_GL_CALL; + return surf; + } + + EGLContext fGetCurrentContext() + { + BEFORE_GL_CALL; + EGLContext context = mSymbols.fGetCurrentContext(); + AFTER_GL_CALL; + return context; + } + + EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fMakeCurrent(dpy, draw, read, ctx); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fDestroyContext(dpy, ctx); + AFTER_GL_CALL; + return b; + } + + EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLContext ctx = mSymbols.fCreateContext(dpy, config, share_context, attrib_list); + AFTER_GL_CALL; + return ctx; + } + + EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fDestroySurface(dpy, surface); + AFTER_GL_CALL; + return b; + } + + EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLSurface surf = mSymbols.fCreateWindowSurface(dpy, config, win, attrib_list); + AFTER_GL_CALL; + return surf; + } + + EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLSurface surf = mSymbols.fCreatePbufferSurface(dpy, config, attrib_list); + AFTER_GL_CALL; + return surf; + } + + EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLSurface surf = mSymbols.fCreatePixmapSurface(dpy, config, pixmap, attrib_list); + AFTER_GL_CALL; + return surf; + } + + EGLBoolean fBindAPI(EGLenum api) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fBindAPI(api); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fInitialize(dpy, major, minor); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fChooseConfig(dpy, attrib_list, configs, config_size, num_config); + AFTER_GL_CALL; + return b; + } + + EGLint fGetError() + { + BEFORE_GL_CALL; + EGLint i = mSymbols.fGetError(); + AFTER_GL_CALL; + return i; + } + + EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fGetConfigAttrib(dpy, config, attribute, value); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fGetConfigs(dpy, configs, config_size, num_config); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fWaitNative(EGLint engine) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fWaitNative(engine); + AFTER_GL_CALL; + return b; + } + + EGLCastToRelevantPtr fGetProcAddress(const char* procname) + { + BEFORE_GL_CALL; + EGLCastToRelevantPtr p = mSymbols.fGetProcAddress(procname); + AFTER_GL_CALL; + return p; + } + + EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fSwapBuffers(dpy, surface); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fCopyBuffers(dpy, surface, target); + AFTER_GL_CALL; + return b; + } + + const GLubyte* fQueryString(EGLDisplay dpy, EGLint name) + { + BEFORE_GL_CALL; + const GLubyte* b; + if (mSymbols.fQueryStringImplementationANDROID) { + b = mSymbols.fQueryStringImplementationANDROID(dpy, name); + } else { + b = mSymbols.fQueryString(dpy, name); + } + AFTER_GL_CALL; + return b; + } + + EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint* value) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fQueryContext(dpy, ctx, attribute, value); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fBindTexImage(dpy, surface, buffer); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fReleaseTexImage(dpy, surface, buffer); + AFTER_GL_CALL; + return b; + } + + EGLImage fCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLImage i = mSymbols.fCreateImage(dpy, ctx, target, buffer, attrib_list); + AFTER_GL_CALL; + return i; + } + + EGLBoolean fDestroyImage(EGLDisplay dpy, EGLImage image) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fDestroyImage(dpy, image); + AFTER_GL_CALL; + return b; + } + + // New extension which allow us to lock texture and get raw image pointer + EGLBoolean fLockSurface(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fLockSurface(dpy, surface, attrib_list); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fUnlockSurface(EGLDisplay dpy, EGLSurface surface) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fUnlockSurface(dpy, surface); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fQuerySurface(dpy, surface, attribute, value); + AFTER_GL_CALL; + return b; + } + + EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fQuerySurfacePointerANGLE(dpy, surface, attribute, value); + AFTER_GL_CALL; + return b; + } + + EGLSync fCreateSync(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) + { + BEFORE_GL_CALL; + EGLSync ret = mSymbols.fCreateSync(dpy, type, attrib_list); + AFTER_GL_CALL; + return ret; + } + + EGLBoolean fDestroySync(EGLDisplay dpy, EGLSync sync) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fDestroySync(dpy, sync); + AFTER_GL_CALL; + return b; + } + + EGLint fClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout) + { + BEFORE_GL_CALL; + EGLint ret = mSymbols.fClientWaitSync(dpy, sync, flags, timeout); + AFTER_GL_CALL; + return ret; + } + + EGLBoolean fGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value) + { + BEFORE_GL_CALL; + EGLBoolean b = mSymbols.fGetSyncAttrib(dpy, sync, attribute, value); + AFTER_GL_CALL; + return b; + } + + EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) + { + MOZ_ASSERT(mSymbols.fDupNativeFenceFDANDROID); + BEFORE_GL_CALL; + EGLint ret = mSymbols.fDupNativeFenceFDANDROID(dpy, sync); + AFTER_GL_CALL; + return ret; + } + + void fANGLEPlatformInitialize(angle::Platform* platform) + { + MOZ_ASSERT(mSymbols.fANGLEPlatformInitialize); + BEFORE_GL_CALL; + mSymbols.fANGLEPlatformInitialize(platform); + AFTER_GL_CALL; + } + + void fANGLEPlatformShutdown() + { + MOZ_ASSERT(mSymbols.fANGLEPlatformShutdown); + BEFORE_GL_CALL; + mSymbols.fANGLEPlatformShutdown(); + AFTER_GL_CALL; + } + + EGLDisplay Display() { + MOZ_ASSERT(mInitialized); + return mEGLDisplay; + } + + bool IsANGLE() const { + MOZ_ASSERT(mInitialized); + return mIsANGLE; + } + + bool IsWARP() const { + MOZ_ASSERT(mInitialized); + return mIsWARP; + } + + bool HasKHRImageBase() { + return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base); + } + + bool HasKHRImagePixmap() { + return IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_pixmap); + } + + bool HasKHRImageTexture2D() { + return IsExtensionSupported(KHR_gl_texture_2D_image); + } + + bool HasANGLESurfaceD3DTexture2DShareHandle() { + return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle); + } + + bool HasRobustness() const { + return IsExtensionSupported(EXT_create_context_robustness); + } + + bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface); + + bool EnsureInitialized(bool forceAccel, nsACString* const out_failureId); + + void DumpEGLConfig(EGLConfig cfg); + void DumpEGLConfigs(); + + struct { + typedef EGLDisplay (GLAPIENTRY * pfnGetDisplay)(void* display_id); + pfnGetDisplay fGetDisplay; + typedef EGLDisplay(GLAPIENTRY * pfnGetPlatformDisplayEXT)(EGLenum platform, void* native_display, const EGLint* attrib_list); + pfnGetPlatformDisplayEXT fGetPlatformDisplayEXT; + typedef EGLBoolean (GLAPIENTRY * pfnTerminate)(EGLDisplay dpy); + pfnTerminate fTerminate; + typedef EGLSurface (GLAPIENTRY * pfnGetCurrentSurface)(EGLint); + pfnGetCurrentSurface fGetCurrentSurface; + typedef EGLContext (GLAPIENTRY * pfnGetCurrentContext)(void); + pfnGetCurrentContext fGetCurrentContext; + typedef EGLBoolean (GLAPIENTRY * pfnMakeCurrent)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); + pfnMakeCurrent fMakeCurrent; + typedef EGLBoolean (GLAPIENTRY * pfnDestroyContext)(EGLDisplay dpy, EGLContext ctx); + pfnDestroyContext fDestroyContext; + typedef EGLContext (GLAPIENTRY * pfnCreateContext)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint* attrib_list); + pfnCreateContext fCreateContext; + typedef EGLBoolean (GLAPIENTRY * pfnDestroySurface)(EGLDisplay dpy, EGLSurface surface); + pfnDestroySurface fDestroySurface; + typedef EGLSurface (GLAPIENTRY * pfnCreateWindowSurface)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint* attrib_list); + pfnCreateWindowSurface fCreateWindowSurface; + typedef EGLSurface (GLAPIENTRY * pfnCreatePbufferSurface)(EGLDisplay dpy, EGLConfig config, const EGLint* attrib_list); + pfnCreatePbufferSurface fCreatePbufferSurface; + typedef EGLSurface (GLAPIENTRY * pfnCreatePixmapSurface)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint* attrib_list); + pfnCreatePixmapSurface fCreatePixmapSurface; + typedef EGLBoolean (GLAPIENTRY * pfnBindAPI)(EGLenum api); + pfnBindAPI fBindAPI; + typedef EGLBoolean (GLAPIENTRY * pfnInitialize)(EGLDisplay dpy, EGLint* major, EGLint* minor); + pfnInitialize fInitialize; + typedef EGLBoolean (GLAPIENTRY * pfnChooseConfig)(EGLDisplay dpy, const EGLint* attrib_list, EGLConfig* configs, EGLint config_size, EGLint* num_config); + pfnChooseConfig fChooseConfig; + typedef EGLint (GLAPIENTRY * pfnGetError)(void); + pfnGetError fGetError; + typedef EGLBoolean (GLAPIENTRY * pfnGetConfigAttrib)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint* value); + pfnGetConfigAttrib fGetConfigAttrib; + typedef EGLBoolean (GLAPIENTRY * pfnGetConfigs)(EGLDisplay dpy, EGLConfig* configs, EGLint config_size, EGLint* num_config); + pfnGetConfigs fGetConfigs; + typedef EGLBoolean (GLAPIENTRY * pfnWaitNative)(EGLint engine); + pfnWaitNative fWaitNative; + typedef EGLCastToRelevantPtr (GLAPIENTRY * pfnGetProcAddress)(const char* procname); + pfnGetProcAddress fGetProcAddress; + typedef EGLBoolean (GLAPIENTRY * pfnSwapBuffers)(EGLDisplay dpy, EGLSurface surface); + pfnSwapBuffers fSwapBuffers; + typedef EGLBoolean (GLAPIENTRY * pfnCopyBuffers)(EGLDisplay dpy, EGLSurface surface, + EGLNativePixmapType target); + pfnCopyBuffers fCopyBuffers; + typedef const GLubyte* (GLAPIENTRY * pfnQueryString)(EGLDisplay, EGLint name); + pfnQueryString fQueryString; + pfnQueryString fQueryStringImplementationANDROID; + typedef EGLBoolean (GLAPIENTRY * pfnQueryContext)(EGLDisplay dpy, EGLContext ctx, + EGLint attribute, EGLint* value); + pfnQueryContext fQueryContext; + typedef EGLBoolean (GLAPIENTRY * pfnBindTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer); + pfnBindTexImage fBindTexImage; + typedef EGLBoolean (GLAPIENTRY * pfnReleaseTexImage)(EGLDisplay, EGLSurface surface, EGLint buffer); + pfnReleaseTexImage fReleaseTexImage; + typedef EGLImage (GLAPIENTRY * pfnCreateImage)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint* attrib_list); + pfnCreateImage fCreateImage; + typedef EGLBoolean (GLAPIENTRY * pfnDestroyImage)(EGLDisplay dpy, EGLImage image); + pfnDestroyImage fDestroyImage; + + // New extension which allow us to lock texture and get raw image pointer + typedef EGLBoolean (GLAPIENTRY * pfnLockSurface)(EGLDisplay dpy, EGLSurface surface, const EGLint* attrib_list); + pfnLockSurface fLockSurface; + typedef EGLBoolean (GLAPIENTRY * pfnUnlockSurface)(EGLDisplay dpy, EGLSurface surface); + pfnUnlockSurface fUnlockSurface; + typedef EGLBoolean (GLAPIENTRY * pfnQuerySurface)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint* value); + pfnQuerySurface fQuerySurface; + + typedef EGLBoolean (GLAPIENTRY * pfnQuerySurfacePointerANGLE)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void** value); + pfnQuerySurfacePointerANGLE fQuerySurfacePointerANGLE; + + typedef EGLSync (GLAPIENTRY * pfnCreateSync)(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list); + pfnCreateSync fCreateSync; + typedef EGLBoolean (GLAPIENTRY * pfnDestroySync)(EGLDisplay dpy, EGLSync sync); + pfnDestroySync fDestroySync; + typedef EGLint (GLAPIENTRY * pfnClientWaitSync)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); + pfnClientWaitSync fClientWaitSync; + typedef EGLBoolean (GLAPIENTRY * pfnGetSyncAttrib)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLint* value); + pfnGetSyncAttrib fGetSyncAttrib; + typedef EGLint (GLAPIENTRY * pfnDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync); + pfnDupNativeFenceFDANDROID fDupNativeFenceFDANDROID; + + typedef void (GLAPIENTRY * pfnANGLEPlatformInitialize)(angle::Platform* platform); + pfnANGLEPlatformInitialize fANGLEPlatformInitialize; + typedef void (GLAPIENTRY * pfnANGLEPlatformShutdown)(); + pfnANGLEPlatformShutdown fANGLEPlatformShutdown; + } mSymbols; + +#ifdef DEBUG + static void BeforeGLCall(const char* glFunction); + static void AfterGLCall(const char* glFunction); +#endif + +#ifdef MOZ_B2G + EGLContext CachedCurrentContext() { + return sCurrentContext.get(); + } + void UnsetCachedCurrentContext() { + sCurrentContext.set(nullptr); + } + void SetCachedCurrentContext(EGLContext aCtx) { + sCurrentContext.set(aCtx); + } + bool CachedCurrentContextMatches() { + return sCurrentContext.get() == fGetCurrentContext(); + } + +private: + static MOZ_THREAD_LOCAL(EGLContext) sCurrentContext; +public: + +#else + EGLContext CachedCurrentContext() { + return nullptr; + } + void UnsetCachedCurrentContext() {} + void SetCachedCurrentContext(EGLContext aCtx) { } + bool CachedCurrentContextMatches() { return true; } +#endif + +private: + bool mInitialized; + PRLibrary* mEGLLibrary; + EGLDisplay mEGLDisplay; + RefPtr<GLContext> mReadbackGL; + + bool mIsANGLE; + bool mIsWARP; + static StaticMutex sMutex; +}; + +extern GLLibraryEGL sEGLLibrary; +#define EGL_DISPLAY() sEGLLibrary.Display() + +} /* namespace gl */ +} /* namespace mozilla */ + +#endif /* GLLIBRARYEGL_H_ */ + |