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/StaticPtr.h"
15 #include "mozilla/ThreadLocal.h"
16 #include "GeckoProfiler.h"
17 
18 #include <bitset>
19 #include <vector>
20 
21 #if defined(MOZ_X11)
22 #  define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
23 #else
24 #  define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
25 #endif
26 
27 class nsIGfxInfo;
28 
29 template <typename T>
30 class nsCOMPtr;
31 
32 namespace angle {
33 class Platform;
34 }
35 
36 namespace mozilla {
37 
38 namespace gfx {
39 class DataSourceSurface;
40 }
41 
42 namespace gl {
43 
44 class GLContext;
45 PRLibrary* LoadApitraceLibrary();
46 
47 void BeforeEGLCall(const char* funcName);
48 void AfterEGLCall(const char* funcName);
49 
50 class GLLibraryEGL final {
51  protected:
52   ~GLLibraryEGL() = default;
53 
54  public:
55   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLLibraryEGL)
56 
57   void InitClientExtensions();
58   void InitDisplayExtensions();
59 
60   /**
61    * Known GL extensions that can be queried by
62    * IsExtensionSupported.  The results of this are cached, and as
63    * such it's safe to use this even in performance critical code.
64    * If you add to this array, remember to add to the string names
65    * in GLLibraryEGL.cpp.
66    */
67   enum EGLExtensions {
68     KHR_image_base,
69     KHR_image_pixmap,
70     KHR_gl_texture_2D_image,
71     KHR_lock_surface,
72     ANGLE_surface_d3d_texture_2d_share_handle,
73     EXT_create_context_robustness,
74     KHR_image,
75     KHR_fence_sync,
76     ANDROID_native_fence_sync,
77     EGL_ANDROID_image_crop,
78     ANGLE_platform_angle,
79     ANGLE_platform_angle_d3d,
80     ANGLE_d3d_share_handle_client_buffer,
81     KHR_create_context,
82     KHR_stream,
83     KHR_stream_consumer_gltexture,
84     EXT_device_query,
85     NV_stream_consumer_gltexture_yuv,
86     ANGLE_stream_producer_d3d_texture,
87     ANGLE_device_creation,
88     ANGLE_device_creation_d3d11,
89     KHR_surfaceless_context,
90     KHR_create_context_no_error,
91     MOZ_create_context_provoking_vertex_dont_care,
92     EXT_swap_buffers_with_damage,
93     KHR_swap_buffers_with_damage,
94     EXT_buffer_age,
95     Extensions_Max
96   };
97 
IsExtensionSupported(EGLExtensions aKnownExtension)98   bool IsExtensionSupported(EGLExtensions aKnownExtension) const {
99     return mAvailableExtensions[aKnownExtension];
100   }
101 
MarkExtensionUnsupported(EGLExtensions aKnownExtension)102   void MarkExtensionUnsupported(EGLExtensions aKnownExtension) {
103     mAvailableExtensions[aKnownExtension] = false;
104   }
105 
106  protected:
107   std::bitset<Extensions_Max> mAvailableExtensions;
108 
109  public:
110   ////
111 
112 #ifdef MOZ_WIDGET_ANDROID
113 #  define PROFILE_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
114 #else
115 #  define PROFILE_CALL
116 #endif
117 
118 #ifndef MOZ_FUNCTION_NAME
119 #  ifdef __GNUC__
120 #    define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
121 #  elif defined(_MSC_VER)
122 #    define MOZ_FUNCTION_NAME __FUNCTION__
123 #  else
124 #    define MOZ_FUNCTION_NAME \
125       __func__  // defined in C99, supported in various C++ compilers. Just raw
126                 // function name.
127 #  endif
128 #endif
129 
130 #ifdef DEBUG
131 #  define BEFORE_CALL BeforeEGLCall(MOZ_FUNCTION_NAME);
132 #  define AFTER_CALL AfterEGLCall(MOZ_FUNCTION_NAME);
133 #else
134 #  define BEFORE_CALL
135 #  define AFTER_CALL
136 #endif
137 
138 #define WRAP(X)                  \
139   {                              \
140     PROFILE_CALL                 \
141     BEFORE_CALL                  \
142     const auto ret = mSymbols.X; \
143     AFTER_CALL                   \
144     return ret;                  \
145   }
146 
147 #define VOID_WRAP(X) \
148   {                  \
149     PROFILE_CALL     \
150     BEFORE_CALL      \
151     mSymbols.X;      \
152     AFTER_CALL       \
153   }
154 
fGetDisplay(void * display_id)155   EGLDisplay fGetDisplay(void* display_id) const WRAP(fGetDisplay(display_id))
156 
157       EGLDisplay fGetPlatformDisplayEXT(EGLenum platform, void* native_display,
158                                         const EGLint* attrib_list) const
159       WRAP(fGetPlatformDisplayEXT(platform, native_display, attrib_list))
160 
161           EGLBoolean fTerminate(EGLDisplay display) const
162       WRAP(fTerminate(display))
163 
164           EGLSurface fGetCurrentSurface(EGLint id) const
165       WRAP(fGetCurrentSurface(id))
166 
167           EGLContext fGetCurrentContext() const WRAP(fGetCurrentContext())
168 
169               EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw,
170                                       EGLSurface read, EGLContext ctx) const
171       WRAP(fMakeCurrent(dpy, draw, read, ctx))
172 
173           EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx) const
174       WRAP(fDestroyContext(dpy, ctx))
175 
176           EGLContext
177       fCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context,
178                      const EGLint* attrib_list) const
179       WRAP(fCreateContext(dpy, config, share_context, attrib_list))
180 
181           EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface) const
182       WRAP(fDestroySurface(dpy, surface))
183 
184           EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
185                                           EGLNativeWindowType win,
186                                           const EGLint* attrib_list) const
187       WRAP(fCreateWindowSurface(dpy, config, win, attrib_list))
188 
189           EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
190                                            const EGLint* attrib_list) const
191       WRAP(fCreatePbufferSurface(dpy, config, attrib_list))
192 
193           EGLSurface
194       fCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
195                                      EGLClientBuffer buffer, EGLConfig config,
196                                      const EGLint* attrib_list) const
197       WRAP(fCreatePbufferFromClientBuffer(dpy, buftype, buffer, config,
198                                           attrib_list))
199 
200           EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
201                                           EGLNativePixmapType pixmap,
202                                           const EGLint* attrib_list) const
203       WRAP(fCreatePixmapSurface(dpy, config, pixmap, attrib_list))
204 
205           EGLBoolean fBindAPI(EGLenum api) const WRAP(fBindAPI(api))
206 
207               EGLBoolean
208       fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) const
209       WRAP(fInitialize(dpy, major, minor))
210 
211           EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint* attrib_list,
212                                    EGLConfig* configs, EGLint config_size,
213                                    EGLint* num_config) const
214       WRAP(fChooseConfig(dpy, attrib_list, configs, config_size, num_config))
215 
216           EGLint fGetError() const WRAP(fGetError())
217 
218               EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
219                                           EGLint attribute, EGLint* value) const
220       WRAP(fGetConfigAttrib(dpy, config, attribute, value))
221 
222           EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig* configs,
223                                  EGLint config_size, EGLint* num_config) const
224       WRAP(fGetConfigs(dpy, configs, config_size, num_config))
225 
226           EGLBoolean fWaitNative(EGLint engine) const WRAP(fWaitNative(engine))
227 
228               EGLCastToRelevantPtr fGetProcAddress(const char* procname) const
229       WRAP(fGetProcAddress(procname))
230 
231           EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface) const
232       WRAP(fSwapBuffers(dpy, surface))
233 
234           EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface,
235                                   EGLNativePixmapType target) const
236       WRAP(fCopyBuffers(dpy, surface, target))
237 
238           const GLubyte* fQueryString(EGLDisplay dpy, EGLint name) const
239       WRAP(fQueryString(dpy, name))
240 
241           EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx,
242                                    EGLint attribute, EGLint* value) const
243       WRAP(fQueryContext(dpy, ctx, attribute, value))
244 
245           EGLBoolean
246       fBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) const
247       WRAP(fBindTexImage(dpy, surface, buffer))
248 
249           EGLBoolean
250       fReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) const
251       WRAP(fReleaseTexImage(dpy, surface, buffer))
252 
253           EGLBoolean fSwapInterval(EGLDisplay dpy, EGLint interval) const
254       WRAP(fSwapInterval(dpy, interval))
255 
256           EGLImage
257       fCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
258                    EGLClientBuffer buffer, const EGLint* attrib_list) const
259       WRAP(fCreateImageKHR(dpy, ctx, target, buffer, attrib_list))
260 
261           EGLBoolean fDestroyImage(EGLDisplay dpy, EGLImage image) const
262       WRAP(fDestroyImageKHR(dpy, image))
263 
264           EGLBoolean fLockSurface(EGLDisplay dpy, EGLSurface surface,
265                                   const EGLint* attrib_list) const
266       WRAP(fLockSurfaceKHR(dpy, surface, attrib_list))
267 
268           EGLBoolean fUnlockSurface(EGLDisplay dpy, EGLSurface surface) const
269       WRAP(fUnlockSurfaceKHR(dpy, surface))
270 
271           EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface,
272                                    EGLint attribute, EGLint* value) const
273       WRAP(fQuerySurface(dpy, surface, attribute, value))
274 
275           EGLBoolean
276       fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface,
277                                 EGLint attribute, void** value) const
278       WRAP(fQuerySurfacePointerANGLE(dpy, surface, attribute, value))
279 
280           EGLSync
281       fCreateSync(EGLDisplay dpy, EGLenum type, const EGLint* attrib_list) const
282       WRAP(fCreateSyncKHR(dpy, type, attrib_list))
283 
284           EGLBoolean fDestroySync(EGLDisplay dpy, EGLSync sync) const
285       WRAP(fDestroySyncKHR(dpy, sync))
286 
287           EGLint fClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags,
288                                  EGLTime timeout) const
289       WRAP(fClientWaitSyncKHR(dpy, sync, flags, timeout))
290 
291           EGLBoolean fGetSyncAttrib(EGLDisplay dpy, EGLSync sync,
292                                     EGLint attribute, EGLint* value) const
293       WRAP(fGetSyncAttribKHR(dpy, sync, attribute, value))
294 
295           EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) const
296       WRAP(fDupNativeFenceFDANDROID(dpy, sync))
297 
298       // KHR_stream
299       EGLStreamKHR
300       fCreateStreamKHR(EGLDisplay dpy, const EGLint* attrib_list) const
301       WRAP(fCreateStreamKHR(dpy, attrib_list))
302 
303           EGLBoolean
304       fDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) const
305       WRAP(fDestroyStreamKHR(dpy, stream))
306 
307           EGLBoolean fQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
308                                      EGLenum attribute, EGLint* value) const
309       WRAP(fQueryStreamKHR(dpy, stream, attribute, value))
310 
311       // KHR_stream_consumer_gltexture
312       EGLBoolean fStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
313                                                      EGLStreamKHR stream) const
314       WRAP(fStreamConsumerGLTextureExternalKHR(dpy, stream))
315 
316           EGLBoolean
317       fStreamConsumerAcquireKHR(EGLDisplay dpy, EGLStreamKHR stream) const
318       WRAP(fStreamConsumerAcquireKHR(dpy, stream))
319 
320           EGLBoolean
321       fStreamConsumerReleaseKHR(EGLDisplay dpy, EGLStreamKHR stream) const
322       WRAP(fStreamConsumerReleaseKHR(dpy, stream))
323 
324       // EXT_device_query
325       EGLBoolean fQueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute,
326                                         EGLAttrib* value) const
327       WRAP(fQueryDisplayAttribEXT(dpy, attribute, value))
328 
329           EGLBoolean
330       fQueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute,
331                             EGLAttrib* value) const
332       WRAP(fQueryDeviceAttribEXT(device, attribute, value))
333 
334       // NV_stream_consumer_gltexture_yuv
335       EGLBoolean fStreamConsumerGLTextureExternalAttribsNV(
336           EGLDisplay dpy, EGLStreamKHR stream,
337           const EGLAttrib* attrib_list) const
338       WRAP(fStreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list))
339 
340       // ANGLE_stream_producer_d3d_texture
341       EGLBoolean
342       fCreateStreamProducerD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream,
343                                            const EGLAttrib* attrib_list) const
344       WRAP(fCreateStreamProducerD3DTextureANGLE(dpy, stream, attrib_list))
345 
346           EGLBoolean
347       fStreamPostD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream,
348                                  void* texture,
349                                  const EGLAttrib* attrib_list) const
350       WRAP(fStreamPostD3DTextureANGLE(dpy, stream, texture, attrib_list))
351 
352       // ANGLE_device_creation
353       EGLDeviceEXT fCreateDeviceANGLE(EGLint device_type, void* native_device,
354                                       const EGLAttrib* attrib_list) const
355       WRAP(fCreateDeviceANGLE(device_type, native_device, attrib_list))
356 
357           EGLBoolean fReleaseDeviceANGLE(EGLDeviceEXT device)
358               WRAP(fReleaseDeviceANGLE(device))
359 
360       // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
361       EGLBoolean fSwapBuffersWithDamage(EGLDisplay dpy, EGLSurface surface,
362                                         const EGLint* rects, EGLint n_rects)
363           WRAP(fSwapBuffersWithDamage(dpy, surface, rects, n_rects))
364 #undef WRAP
365 #undef VOID_WRAP
366 #undef PROFILE_CALL
367 #undef BEFORE_CALL
368 #undef AFTER_CALL
369 #undef MOZ_FUNCTION_NAME
370 
371       ////
372 
373       EGLDisplay Display() const {
374     MOZ_ASSERT(mInitialized);
375     return mEGLDisplay;
376   }
377 
IsANGLE()378   bool IsANGLE() const {
379     MOZ_ASSERT(mInitialized);
380     return mIsANGLE;
381   }
382 
IsWARP()383   bool IsWARP() const {
384     MOZ_ASSERT(mInitialized);
385     return mIsWARP;
386   }
387 
HasKHRImageBase()388   bool HasKHRImageBase() {
389     return IsExtensionSupported(KHR_image) ||
390            IsExtensionSupported(KHR_image_base);
391   }
392 
HasKHRImagePixmap()393   bool HasKHRImagePixmap() {
394     return IsExtensionSupported(KHR_image) ||
395            IsExtensionSupported(KHR_image_pixmap);
396   }
397 
HasKHRImageTexture2D()398   bool HasKHRImageTexture2D() {
399     return IsExtensionSupported(KHR_gl_texture_2D_image);
400   }
401 
HasANGLESurfaceD3DTexture2DShareHandle()402   bool HasANGLESurfaceD3DTexture2DShareHandle() {
403     return IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle);
404   }
405 
406   bool ReadbackEGLImage(EGLImage image, gfx::DataSourceSurface* out_surface);
407 
Get()408   inline static GLLibraryEGL* Get() { return sEGLLibrary; }
409 
410   static bool EnsureInitialized(bool forceAccel,
411                                 nsACString* const out_failureId);
412 
413   void Shutdown();
414 
415   void DumpEGLConfig(EGLConfig cfg);
416   void DumpEGLConfigs();
417 
418   Maybe<SymbolLoader> GetSymbolLoader() const;
419 
420  private:
421   struct {
422     EGLCastToRelevantPtr(GLAPIENTRY* fGetProcAddress)(const char* procname);
423     EGLDisplay(GLAPIENTRY* fGetDisplay)(void* display_id);
424     EGLDisplay(GLAPIENTRY* fGetPlatformDisplayEXT)(EGLenum platform,
425                                                    void* native_display,
426                                                    const EGLint* attrib_list);
427     EGLBoolean(GLAPIENTRY* fTerminate)(EGLDisplay dpy);
428     EGLSurface(GLAPIENTRY* fGetCurrentSurface)(EGLint);
429     EGLContext(GLAPIENTRY* fGetCurrentContext)(void);
430     EGLBoolean(GLAPIENTRY* fMakeCurrent)(EGLDisplay dpy, EGLSurface draw,
431                                          EGLSurface read, EGLContext ctx);
432     EGLBoolean(GLAPIENTRY* fDestroyContext)(EGLDisplay dpy, EGLContext ctx);
433     EGLContext(GLAPIENTRY* fCreateContext)(EGLDisplay dpy, EGLConfig config,
434                                            EGLContext share_context,
435                                            const EGLint* attrib_list);
436     EGLBoolean(GLAPIENTRY* fDestroySurface)(EGLDisplay dpy, EGLSurface surface);
437     EGLSurface(GLAPIENTRY* fCreateWindowSurface)(EGLDisplay dpy,
438                                                  EGLConfig config,
439                                                  EGLNativeWindowType win,
440                                                  const EGLint* attrib_list);
441     EGLSurface(GLAPIENTRY* fCreatePbufferSurface)(EGLDisplay dpy,
442                                                   EGLConfig config,
443                                                   const EGLint* attrib_list);
444     EGLSurface(GLAPIENTRY* fCreatePbufferFromClientBuffer)(
445         EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
446         EGLConfig config, const EGLint* attrib_list);
447     EGLSurface(GLAPIENTRY* fCreatePixmapSurface)(EGLDisplay dpy,
448                                                  EGLConfig config,
449                                                  EGLNativePixmapType pixmap,
450                                                  const EGLint* attrib_list);
451     EGLBoolean(GLAPIENTRY* fBindAPI)(EGLenum api);
452     EGLBoolean(GLAPIENTRY* fInitialize)(EGLDisplay dpy, EGLint* major,
453                                         EGLint* minor);
454     EGLBoolean(GLAPIENTRY* fChooseConfig)(EGLDisplay dpy,
455                                           const EGLint* attrib_list,
456                                           EGLConfig* configs,
457                                           EGLint config_size,
458                                           EGLint* num_config);
459     EGLint(GLAPIENTRY* fGetError)(void);
460     EGLBoolean(GLAPIENTRY* fGetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
461                                              EGLint attribute, EGLint* value);
462     EGLBoolean(GLAPIENTRY* fGetConfigs)(EGLDisplay dpy, EGLConfig* configs,
463                                         EGLint config_size, EGLint* num_config);
464     EGLBoolean(GLAPIENTRY* fWaitNative)(EGLint engine);
465     EGLBoolean(GLAPIENTRY* fSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
466     EGLBoolean(GLAPIENTRY* fCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
467                                          EGLNativePixmapType target);
468     const GLubyte*(GLAPIENTRY* fQueryString)(EGLDisplay, EGLint name);
469     EGLBoolean(GLAPIENTRY* fQueryContext)(EGLDisplay dpy, EGLContext ctx,
470                                           EGLint attribute, EGLint* value);
471     EGLBoolean(GLAPIENTRY* fBindTexImage)(EGLDisplay, EGLSurface surface,
472                                           EGLint buffer);
473     EGLBoolean(GLAPIENTRY* fReleaseTexImage)(EGLDisplay, EGLSurface surface,
474                                              EGLint buffer);
475     EGLBoolean(GLAPIENTRY* fSwapInterval)(EGLDisplay dpy, EGLint interval);
476     EGLImage(GLAPIENTRY* fCreateImageKHR)(EGLDisplay dpy, EGLContext ctx,
477                                           EGLenum target,
478                                           EGLClientBuffer buffer,
479                                           const EGLint* attrib_list);
480     EGLBoolean(GLAPIENTRY* fDestroyImageKHR)(EGLDisplay dpy, EGLImage image);
481     // New extension which allow us to lock texture and get raw image pointer
482     EGLBoolean(GLAPIENTRY* fLockSurfaceKHR)(EGLDisplay dpy, EGLSurface surface,
483                                             const EGLint* attrib_list);
484     EGLBoolean(GLAPIENTRY* fUnlockSurfaceKHR)(EGLDisplay dpy,
485                                               EGLSurface surface);
486     EGLBoolean(GLAPIENTRY* fQuerySurface)(EGLDisplay dpy, EGLSurface surface,
487                                           EGLint attribute, EGLint* value);
488     EGLBoolean(GLAPIENTRY* fQuerySurfacePointerANGLE)(EGLDisplay dpy,
489                                                       EGLSurface surface,
490                                                       EGLint attribute,
491                                                       void** value);
492     EGLSync(GLAPIENTRY* fCreateSyncKHR)(EGLDisplay dpy, EGLenum type,
493                                         const EGLint* attrib_list);
494     EGLBoolean(GLAPIENTRY* fDestroySyncKHR)(EGLDisplay dpy, EGLSync sync);
495     EGLint(GLAPIENTRY* fClientWaitSyncKHR)(EGLDisplay dpy, EGLSync sync,
496                                            EGLint flags, EGLTime timeout);
497     EGLBoolean(GLAPIENTRY* fGetSyncAttribKHR)(EGLDisplay dpy, EGLSync sync,
498                                               EGLint attribute, EGLint* value);
499     EGLint(GLAPIENTRY* fDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
500     // KHR_stream
501     EGLStreamKHR(GLAPIENTRY* fCreateStreamKHR)(EGLDisplay dpy,
502                                                const EGLint* attrib_list);
503     EGLBoolean(GLAPIENTRY* fDestroyStreamKHR)(EGLDisplay dpy,
504                                               EGLStreamKHR stream);
505     EGLBoolean(GLAPIENTRY* fQueryStreamKHR)(EGLDisplay dpy, EGLStreamKHR stream,
506                                             EGLenum attribute, EGLint* value);
507     // KHR_stream_consumer_gltexture
508     EGLBoolean(GLAPIENTRY* fStreamConsumerGLTextureExternalKHR)(
509         EGLDisplay dpy, EGLStreamKHR stream);
510     EGLBoolean(GLAPIENTRY* fStreamConsumerAcquireKHR)(EGLDisplay dpy,
511                                                       EGLStreamKHR stream);
512     EGLBoolean(GLAPIENTRY* fStreamConsumerReleaseKHR)(EGLDisplay dpy,
513                                                       EGLStreamKHR stream);
514     // EXT_device_query
515     EGLBoolean(GLAPIENTRY* fQueryDisplayAttribEXT)(EGLDisplay dpy,
516                                                    EGLint attribute,
517                                                    EGLAttrib* value);
518     EGLBoolean(GLAPIENTRY* fQueryDeviceAttribEXT)(EGLDeviceEXT device,
519                                                   EGLint attribute,
520                                                   EGLAttrib* value);
521     // NV_stream_consumer_gltexture_yuv
522     EGLBoolean(GLAPIENTRY* fStreamConsumerGLTextureExternalAttribsNV)(
523         EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list);
524     // ANGLE_stream_producer_d3d_texture
525     EGLBoolean(GLAPIENTRY* fCreateStreamProducerD3DTextureANGLE)(
526         EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list);
527     EGLBoolean(GLAPIENTRY* fStreamPostD3DTextureANGLE)(
528         EGLDisplay dpy, EGLStreamKHR stream, void* texture,
529         const EGLAttrib* attrib_list);
530     // ANGLE_device_creation
531     EGLDeviceEXT(GLAPIENTRY* fCreateDeviceANGLE)(EGLint device_type,
532                                                  void* native_device,
533                                                  const EGLAttrib* attrib_list);
534     EGLBoolean(GLAPIENTRY* fReleaseDeviceANGLE)(EGLDeviceEXT device);
535     // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
536     EGLBoolean(GLAPIENTRY* fSwapBuffersWithDamage)(EGLDisplay dpy,
537                                                    EGLSurface surface,
538                                                    const EGLint* rects,
539                                                    EGLint n_rects);
540   } mSymbols = {};
541 
542  private:
543   bool DoEnsureInitialized();
544   bool DoEnsureInitialized(bool forceAccel, nsACString* const out_failureId);
545   EGLDisplay CreateDisplay(bool forceAccel, const nsCOMPtr<nsIGfxInfo>& gfxInfo,
546                            nsACString* const out_failureId);
547 
548   bool mInitialized = false;
549   PRLibrary* mEGLLibrary = nullptr;
550   mutable PRLibrary* mGLLibrary = nullptr;
551   EGLDisplay mEGLDisplay = EGL_NO_DISPLAY;
552   RefPtr<GLContext> mReadbackGL;
553 
554   bool mIsANGLE = false;
555   bool mIsWARP = false;
556   static StaticMutex sMutex;
557   static StaticRefPtr<GLLibraryEGL> sEGLLibrary;
558 };
559 
560 bool DoesEGLContextSupportSharingWithEGLImage(GLContext* gl);
561 
562 } /* namespace gl */
563 } /* namespace mozilla */
564 
565 #endif /* GLLIBRARYEGL_H_ */
566