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/. */
5 #ifndef GLLIBRARYEGL_H_
6 #define GLLIBRARYEGL_H_
9 # include "mozilla/X11Util.h"
12 #include "base/platform_thread.h" // for PlatformThreadId
15 #include "mozilla/EnumTypeTraits.h"
16 #include "mozilla/gfx/Logging.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/Mutex.h"
19 #include "mozilla/RefPtr.h"
20 #include "mozilla/StaticMutex.h"
21 #include "mozilla/StaticPtr.h"
22 #include "nsISupports.h"
27 #include <unordered_map>
29 #ifdef MOZ_WIDGET_ANDROID
30 # include "mozilla/ProfilerLabels.h"
34 # define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
36 # define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
42 struct AHardwareBuffer
;
52 class DataSourceSurface
;
59 PRLibrary
* LoadApitraceLibrary();
61 void BeforeEGLCall(const char* funcName
);
62 void AfterEGLCall(const char* funcName
);
66 * Known GL extensions that can be queried by
67 * IsExtensionSupported. The results of this are cached, and as
68 * such it's safe to use this even in performance critical code.
69 * If you add to this array, remember to add to the string names
70 * in GLLibraryEGL.cpp.
72 enum class EGLLibExtension
{
73 ANDROID_get_native_client_buffer
,
74 ANGLE_device_creation
,
75 ANGLE_device_creation_d3d11
,
77 ANGLE_platform_angle_d3d
,
78 EXT_device_enumeration
,
81 MESA_platform_surfaceless
,
86 * Known GL extensions that can be queried by
87 * IsExtensionSupported. The results of this are cached, and as
88 * such it's safe to use this even in performance critical code.
89 * If you add to this array, remember to add to the string names
90 * in GLLibraryEGL.cpp.
92 enum class EGLExtension
{
95 KHR_gl_texture_2D_image
,
96 ANGLE_surface_d3d_texture_2d_share_handle
,
97 EXT_create_context_robustness
,
101 ANDROID_native_fence_sync
,
102 EGL_ANDROID_image_crop
,
103 ANGLE_d3d_share_handle_client_buffer
,
106 KHR_stream_consumer_gltexture
,
107 NV_stream_consumer_gltexture_yuv
,
108 ANGLE_stream_producer_d3d_texture
,
109 KHR_surfaceless_context
,
110 KHR_create_context_no_error
,
111 MOZ_create_context_provoking_vertex_dont_care
,
112 EXT_swap_buffers_with_damage
,
113 KHR_swap_buffers_with_damage
,
116 NV_robustness_video_memory_purge
,
117 EXT_image_dma_buf_import
,
118 EXT_image_dma_buf_import_modifiers
,
119 MESA_image_dma_buf_export
,
120 KHR_no_config_context
,
126 class GLLibraryEGL final
{
127 friend class EglDisplay
;
130 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLLibraryEGL
)
133 PRLibrary
* mEGLLibrary
= nullptr;
134 PRLibrary
* mGLLibrary
= nullptr;
135 bool mIsANGLE
= false;
136 std::bitset
<UnderlyingValue(EGLLibExtension::Max
)> mAvailableExtensions
;
137 std::weak_ptr
<EglDisplay
> mDefaultDisplay
;
138 std::unordered_map
<EGLDisplay
, std::weak_ptr
<EglDisplay
>> mActiveDisplays
;
141 static RefPtr
<GLLibraryEGL
> Get(nsACString
* const out_failureId
);
142 static void Shutdown();
145 ~GLLibraryEGL() = default;
147 static StaticMutex sMutex
;
148 static StaticRefPtr
<GLLibraryEGL
> sInstance
MOZ_GUARDED_BY(sMutex
);
150 bool Init(nsACString
* const out_failureId
);
151 void InitLibExtensions();
153 std::shared_ptr
<EglDisplay
> CreateDisplayLocked(
154 bool forceAccel
, nsACString
* const out_failureId
,
155 const StaticMutexAutoLock
& aProofOfLock
);
158 Maybe
<SymbolLoader
> GetSymbolLoader() const;
160 std::shared_ptr
<EglDisplay
> CreateDisplay(bool forceAccel
,
161 nsACString
* const out_failureId
);
162 std::shared_ptr
<EglDisplay
> CreateDisplay(ID3D11Device
*);
163 std::shared_ptr
<EglDisplay
> DefaultDisplay(nsACString
* const out_failureId
);
165 bool IsExtensionSupported(EGLLibExtension aKnownExtension
) const {
166 return mAvailableExtensions
[UnderlyingValue(aKnownExtension
)];
169 void MarkExtensionUnsupported(EGLLibExtension aKnownExtension
) {
170 mAvailableExtensions
[UnderlyingValue(aKnownExtension
)] = false;
173 bool IsANGLE() const { return mIsANGLE
; }
178 #ifdef MOZ_WIDGET_ANDROID
179 # define PROFILE_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
181 # define PROFILE_CALL
184 #ifndef MOZ_FUNCTION_NAME
186 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
187 # elif defined(_MSC_VER)
188 # define MOZ_FUNCTION_NAME __FUNCTION__
190 # define MOZ_FUNCTION_NAME \
191 __func__ // defined in C99, supported in various C++ compilers. Just raw
197 # define BEFORE_CALL BeforeEGLCall(MOZ_FUNCTION_NAME);
198 # define AFTER_CALL AfterEGLCall(MOZ_FUNCTION_NAME);
207 const auto ret = mSymbols.X; \
212 EGLDisplay
fGetDisplay(void* display_id
) const {
213 WRAP(fGetDisplay(display_id
));
216 EGLDisplay
fGetPlatformDisplay(EGLenum platform
, void* native_display
,
217 const EGLAttrib
* attrib_list
) const {
218 WRAP(fGetPlatformDisplay(platform
, native_display
, attrib_list
));
221 EGLSurface
fGetCurrentSurface(EGLint id
) const {
222 WRAP(fGetCurrentSurface(id
));
225 EGLContext
fGetCurrentContext() const { WRAP(fGetCurrentContext()); }
227 EGLBoolean
fBindAPI(EGLenum api
) const { WRAP(fBindAPI(api
)); }
229 EGLint
fGetError() const { WRAP(fGetError()); }
231 EGLBoolean
fWaitNative(EGLint engine
) const { WRAP(fWaitNative(engine
)); }
233 EGLCastToRelevantPtr
fGetProcAddress(const char* procname
) const {
234 WRAP(fGetProcAddress(procname
));
237 // ANGLE_device_creation
238 EGLDeviceEXT
fCreateDeviceANGLE(EGLint device_type
, void* native_device
,
239 const EGLAttrib
* attrib_list
) const {
240 WRAP(fCreateDeviceANGLE(device_type
, native_device
, attrib_list
));
243 EGLBoolean
fReleaseDeviceANGLE(EGLDeviceEXT device
) {
244 WRAP(fReleaseDeviceANGLE(device
));
247 // ANDROID_get_native_client_buffer
248 EGLClientBuffer
fGetNativeClientBufferANDROID(
249 const struct AHardwareBuffer
* buffer
) {
250 WRAP(fGetNativeClientBufferANDROID(buffer
));
254 EGLBoolean
fTerminate(EGLDisplay display
) const { WRAP(fTerminate(display
)); }
258 mutable Mutex mMutex
= Mutex
{"GLLibraryEGL::mMutex"};
259 mutable std::unordered_map
<EGLContext
, PlatformThreadId
>
260 mOwningThreadByContext
MOZ_GUARDED_BY(mMutex
);
262 EGLBoolean
fMakeCurrent(EGLDisplay dpy
, EGLSurface draw
, EGLSurface read
,
263 EGLContext ctx
) const {
264 const bool CHECK_CONTEXT_OWNERSHIP
= true;
265 if (CHECK_CONTEXT_OWNERSHIP
) {
266 const MutexAutoLock
lock(mMutex
);
268 const auto tid
= PlatformThread::CurrentId();
269 const auto prevCtx
= fGetCurrentContext();
272 mOwningThreadByContext
[prevCtx
] = 0;
275 auto& ctxOwnerThread
= mOwningThreadByContext
[ctx
];
276 if (ctxOwnerThread
&& ctxOwnerThread
!= tid
) {
278 << "EGLContext#" << ctx
<< " is owned by/Current on"
279 << " thread#" << ctxOwnerThread
<< " but MakeCurrent requested on"
280 << " thread#" << tid
<< "!";
281 if (gfxEnv::MOZ_EGL_RELEASE_ASSERT_CONTEXT_OWNERSHIP()) {
282 MOZ_CRASH("MOZ_EGL_RELEASE_ASSERT_CONTEXT_OWNERSHIP");
286 ctxOwnerThread
= tid
;
290 WRAP(fMakeCurrent(dpy
, draw
, read
, ctx
));
295 EGLBoolean
fDestroyContext(EGLDisplay dpy
, EGLContext ctx
) const {
297 const MutexAutoLock
lock(mMutex
);
298 mOwningThreadByContext
.erase(ctx
);
301 WRAP(fDestroyContext(dpy
, ctx
));
304 EGLContext
fCreateContext(EGLDisplay dpy
, EGLConfig config
,
305 EGLContext share_context
,
306 const EGLint
* attrib_list
) const {
307 WRAP(fCreateContext(dpy
, config
, share_context
, attrib_list
));
310 EGLBoolean
fDestroySurface(EGLDisplay dpy
, EGLSurface surface
) const {
311 WRAP(fDestroySurface(dpy
, surface
));
315 EGLSurface
fCreateWindowSurface(EGLDisplay dpy
, EGLConfig config
,
316 EGLNativeWindowType win
,
317 const EGLint
* attrib_list
) const {
318 WRAP(fCreateWindowSurface(dpy
, config
, win
, attrib_list
));
322 EGLSurface
fCreatePbufferSurface(EGLDisplay dpy
, EGLConfig config
,
323 const EGLint
* attrib_list
) const {
324 WRAP(fCreatePbufferSurface(dpy
, config
, attrib_list
));
327 EGLSurface
fCreatePbufferFromClientBuffer(EGLDisplay dpy
, EGLenum buftype
,
328 EGLClientBuffer buffer
,
330 const EGLint
* attrib_list
) const {
331 WRAP(fCreatePbufferFromClientBuffer(dpy
, buftype
, buffer
, config
,
335 EGLSurface
fCreatePixmapSurface(EGLDisplay dpy
, EGLConfig config
,
336 EGLNativePixmapType pixmap
,
337 const EGLint
* attrib_list
) const {
338 WRAP(fCreatePixmapSurface(dpy
, config
, pixmap
, attrib_list
));
341 EGLBoolean
fInitialize(EGLDisplay dpy
, EGLint
* major
, EGLint
* minor
) const {
342 WRAP(fInitialize(dpy
, major
, minor
));
345 EGLBoolean
fChooseConfig(EGLDisplay dpy
, const EGLint
* attrib_list
,
346 EGLConfig
* configs
, EGLint config_size
,
347 EGLint
* num_config
) const {
348 WRAP(fChooseConfig(dpy
, attrib_list
, configs
, config_size
, num_config
));
351 EGLBoolean
fGetConfigAttrib(EGLDisplay dpy
, EGLConfig config
,
352 EGLint attribute
, EGLint
* value
) const {
353 WRAP(fGetConfigAttrib(dpy
, config
, attribute
, value
));
356 EGLBoolean
fGetConfigs(EGLDisplay dpy
, EGLConfig
* configs
, EGLint config_size
,
357 EGLint
* num_config
) const {
358 WRAP(fGetConfigs(dpy
, configs
, config_size
, num_config
));
361 EGLBoolean
fSwapBuffers(EGLDisplay dpy
, EGLSurface surface
) const {
362 WRAP(fSwapBuffers(dpy
, surface
));
365 EGLBoolean
fCopyBuffers(EGLDisplay dpy
, EGLSurface surface
,
366 EGLNativePixmapType target
) const {
367 WRAP(fCopyBuffers(dpy
, surface
, target
));
371 const GLubyte
* fQueryString(EGLDisplay dpy
, EGLint name
) const {
372 WRAP(fQueryString(dpy
, name
));
376 EGLBoolean
fQueryContext(EGLDisplay dpy
, EGLContext ctx
, EGLint attribute
,
377 EGLint
* value
) const {
378 WRAP(fQueryContext(dpy
, ctx
, attribute
, value
));
381 EGLBoolean
fBindTexImage(EGLDisplay dpy
, EGLSurface surface
,
382 EGLint buffer
) const {
383 WRAP(fBindTexImage(dpy
, surface
, buffer
));
386 EGLBoolean
fReleaseTexImage(EGLDisplay dpy
, EGLSurface surface
,
387 EGLint buffer
) const {
388 WRAP(fReleaseTexImage(dpy
, surface
, buffer
));
391 EGLBoolean
fSwapInterval(EGLDisplay dpy
, EGLint interval
) const {
392 WRAP(fSwapInterval(dpy
, interval
));
395 EGLImage
fCreateImage(EGLDisplay dpy
, EGLContext ctx
, EGLenum target
,
396 EGLClientBuffer buffer
,
397 const EGLint
* attrib_list
) const {
398 WRAP(fCreateImageKHR(dpy
, ctx
, target
, buffer
, attrib_list
));
401 EGLBoolean
fDestroyImage(EGLDisplay dpy
, EGLImage image
) const {
402 WRAP(fDestroyImageKHR(dpy
, image
));
405 EGLBoolean
fQuerySurface(EGLDisplay dpy
, EGLSurface surface
, EGLint attribute
,
406 EGLint
* value
) const {
407 WRAP(fQuerySurface(dpy
, surface
, attribute
, value
));
410 EGLBoolean
fQuerySurfacePointerANGLE(EGLDisplay dpy
, EGLSurface surface
,
411 EGLint attribute
, void** value
) const {
412 WRAP(fQuerySurfacePointerANGLE(dpy
, surface
, attribute
, value
));
415 EGLSync
fCreateSync(EGLDisplay dpy
, EGLenum type
,
416 const EGLint
* attrib_list
) const {
417 WRAP(fCreateSyncKHR(dpy
, type
, attrib_list
));
420 EGLBoolean
fDestroySync(EGLDisplay dpy
, EGLSync sync
) const {
421 WRAP(fDestroySyncKHR(dpy
, sync
));
424 EGLint
fClientWaitSync(EGLDisplay dpy
, EGLSync sync
, EGLint flags
,
425 EGLTime timeout
) const {
426 WRAP(fClientWaitSyncKHR(dpy
, sync
, flags
, timeout
));
429 EGLBoolean
fGetSyncAttrib(EGLDisplay dpy
, EGLSync sync
, EGLint attribute
,
430 EGLint
* value
) const {
431 WRAP(fGetSyncAttribKHR(dpy
, sync
, attribute
, value
));
434 EGLint
fWaitSync(EGLDisplay dpy
, EGLSync sync
, EGLint flags
) const {
435 WRAP(fWaitSyncKHR(dpy
, sync
, flags
));
438 EGLint
fDupNativeFenceFDANDROID(EGLDisplay dpy
, EGLSync sync
) const {
439 WRAP(fDupNativeFenceFDANDROID(dpy
, sync
));
443 EGLStreamKHR
fCreateStreamKHR(EGLDisplay dpy
,
444 const EGLint
* attrib_list
) const {
445 WRAP(fCreateStreamKHR(dpy
, attrib_list
));
448 EGLBoolean
fDestroyStreamKHR(EGLDisplay dpy
, EGLStreamKHR stream
) const {
449 WRAP(fDestroyStreamKHR(dpy
, stream
));
452 EGLBoolean
fQueryStreamKHR(EGLDisplay dpy
, EGLStreamKHR stream
,
453 EGLenum attribute
, EGLint
* value
) const {
454 WRAP(fQueryStreamKHR(dpy
, stream
, attribute
, value
));
457 // KHR_stream_consumer_gltexture
458 EGLBoolean
fStreamConsumerGLTextureExternalKHR(EGLDisplay dpy
,
459 EGLStreamKHR stream
) const {
460 WRAP(fStreamConsumerGLTextureExternalKHR(dpy
, stream
));
463 EGLBoolean
fStreamConsumerAcquireKHR(EGLDisplay dpy
,
464 EGLStreamKHR stream
) const {
465 WRAP(fStreamConsumerAcquireKHR(dpy
, stream
));
468 EGLBoolean
fStreamConsumerReleaseKHR(EGLDisplay dpy
,
469 EGLStreamKHR stream
) const {
470 WRAP(fStreamConsumerReleaseKHR(dpy
, stream
));
474 EGLBoolean
fQueryDisplayAttribEXT(EGLDisplay dpy
, EGLint attribute
,
475 EGLAttrib
* value
) const {
476 WRAP(fQueryDisplayAttribEXT(dpy
, attribute
, value
));
480 EGLBoolean
fQueryDeviceAttribEXT(EGLDeviceEXT device
, EGLint attribute
,
481 EGLAttrib
* value
) const {
482 WRAP(fQueryDeviceAttribEXT(device
, attribute
, value
));
485 const char* fQueryDeviceStringEXT(EGLDeviceEXT device
, EGLint name
) {
486 WRAP(fQueryDeviceStringEXT(device
, name
));
490 // NV_stream_consumer_gltexture_yuv
491 EGLBoolean
fStreamConsumerGLTextureExternalAttribsNV(
492 EGLDisplay dpy
, EGLStreamKHR stream
, const EGLAttrib
* attrib_list
) const {
493 WRAP(fStreamConsumerGLTextureExternalAttribsNV(dpy
, stream
, attrib_list
));
496 // ANGLE_stream_producer_d3d_texture
497 EGLBoolean
fCreateStreamProducerD3DTextureANGLE(
498 EGLDisplay dpy
, EGLStreamKHR stream
, const EGLAttrib
* attrib_list
) const {
499 WRAP(fCreateStreamProducerD3DTextureANGLE(dpy
, stream
, attrib_list
));
502 EGLBoolean
fStreamPostD3DTextureANGLE(EGLDisplay dpy
, EGLStreamKHR stream
,
504 const EGLAttrib
* attrib_list
) const {
505 WRAP(fStreamPostD3DTextureANGLE(dpy
, stream
, texture
, attrib_list
));
508 // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
509 EGLBoolean
fSwapBuffersWithDamage(EGLDisplay dpy
, EGLSurface surface
,
510 const EGLint
* rects
, EGLint n_rects
) {
511 WRAP(fSwapBuffersWithDamage(dpy
, surface
, rects
, n_rects
));
514 // EGL_KHR_partial_update
515 EGLBoolean
fSetDamageRegion(EGLDisplay dpy
, EGLSurface surface
,
516 const EGLint
* rects
, EGLint n_rects
) {
517 WRAP(fSetDamageRegion(dpy
, surface
, rects
, n_rects
));
519 // EGL_MESA_image_dma_buf_export
520 EGLBoolean
fExportDMABUFImageQuery(EGLDisplay dpy
, EGLImage image
,
521 int* fourcc
, int* num_planes
,
522 uint64_t* modifiers
) {
524 fExportDMABUFImageQueryMESA(dpy
, image
, fourcc
, num_planes
, modifiers
));
526 EGLBoolean
fExportDMABUFImage(EGLDisplay dpy
, EGLImage image
, int* fds
,
527 EGLint
* strides
, EGLint
* offsets
) {
528 WRAP(fExportDMABUFImageMESA(dpy
, image
, fds
, strides
, offsets
));
532 // EGL_EXT_device_enumeration
533 EGLBoolean
fQueryDevicesEXT(EGLint max_devices
, EGLDeviceEXT
* devices
,
534 EGLint
* num_devices
) {
535 WRAP(fQueryDevicesEXT(max_devices
, devices
, num_devices
));
544 #undef MOZ_FUNCTION_NAME
550 EGLCastToRelevantPtr(GLAPIENTRY
* fGetProcAddress
)(const char* procname
);
551 EGLDisplay(GLAPIENTRY
* fGetDisplay
)(void* display_id
);
552 EGLDisplay(GLAPIENTRY
* fGetPlatformDisplay
)(EGLenum platform
,
553 void* native_display
,
554 const EGLAttrib
* attrib_list
);
555 EGLBoolean(GLAPIENTRY
* fTerminate
)(EGLDisplay dpy
);
556 EGLSurface(GLAPIENTRY
* fGetCurrentSurface
)(EGLint
);
557 EGLContext(GLAPIENTRY
* fGetCurrentContext
)(void);
558 EGLBoolean(GLAPIENTRY
* fMakeCurrent
)(EGLDisplay dpy
, EGLSurface draw
,
559 EGLSurface read
, EGLContext ctx
);
560 EGLBoolean(GLAPIENTRY
* fDestroyContext
)(EGLDisplay dpy
, EGLContext ctx
);
561 EGLContext(GLAPIENTRY
* fCreateContext
)(EGLDisplay dpy
, EGLConfig config
,
562 EGLContext share_context
,
563 const EGLint
* attrib_list
);
564 EGLBoolean(GLAPIENTRY
* fDestroySurface
)(EGLDisplay dpy
, EGLSurface surface
);
565 EGLSurface(GLAPIENTRY
* fCreateWindowSurface
)(EGLDisplay dpy
,
567 EGLNativeWindowType win
,
568 const EGLint
* attrib_list
);
569 EGLSurface(GLAPIENTRY
* fCreatePbufferSurface
)(EGLDisplay dpy
,
571 const EGLint
* attrib_list
);
572 EGLSurface(GLAPIENTRY
* fCreatePbufferFromClientBuffer
)(
573 EGLDisplay dpy
, EGLenum buftype
, EGLClientBuffer buffer
,
574 EGLConfig config
, const EGLint
* attrib_list
);
575 EGLSurface(GLAPIENTRY
* fCreatePixmapSurface
)(EGLDisplay dpy
,
577 EGLNativePixmapType pixmap
,
578 const EGLint
* attrib_list
);
579 EGLBoolean(GLAPIENTRY
* fBindAPI
)(EGLenum api
);
580 EGLBoolean(GLAPIENTRY
* fInitialize
)(EGLDisplay dpy
, EGLint
* major
,
582 EGLBoolean(GLAPIENTRY
* fChooseConfig
)(EGLDisplay dpy
,
583 const EGLint
* attrib_list
,
587 EGLint(GLAPIENTRY
* fGetError
)(void);
588 EGLBoolean(GLAPIENTRY
* fGetConfigAttrib
)(EGLDisplay dpy
, EGLConfig config
,
589 EGLint attribute
, EGLint
* value
);
590 EGLBoolean(GLAPIENTRY
* fGetConfigs
)(EGLDisplay dpy
, EGLConfig
* configs
,
591 EGLint config_size
, EGLint
* num_config
);
592 EGLBoolean(GLAPIENTRY
* fWaitNative
)(EGLint engine
);
593 EGLBoolean(GLAPIENTRY
* fSwapBuffers
)(EGLDisplay dpy
, EGLSurface surface
);
594 EGLBoolean(GLAPIENTRY
* fCopyBuffers
)(EGLDisplay dpy
, EGLSurface surface
,
595 EGLNativePixmapType target
);
596 const GLubyte
*(GLAPIENTRY
* fQueryString
)(EGLDisplay
, EGLint name
);
597 EGLBoolean(GLAPIENTRY
* fQueryContext
)(EGLDisplay dpy
, EGLContext ctx
,
598 EGLint attribute
, EGLint
* value
);
599 EGLBoolean(GLAPIENTRY
* fBindTexImage
)(EGLDisplay
, EGLSurface surface
,
601 EGLBoolean(GLAPIENTRY
* fReleaseTexImage
)(EGLDisplay
, EGLSurface surface
,
603 EGLBoolean(GLAPIENTRY
* fSwapInterval
)(EGLDisplay dpy
, EGLint interval
);
604 EGLImage(GLAPIENTRY
* fCreateImageKHR
)(EGLDisplay dpy
, EGLContext ctx
,
606 EGLClientBuffer buffer
,
607 const EGLint
* attrib_list
);
608 EGLBoolean(GLAPIENTRY
* fDestroyImageKHR
)(EGLDisplay dpy
, EGLImage image
);
609 EGLBoolean(GLAPIENTRY
* fQuerySurface
)(EGLDisplay dpy
, EGLSurface surface
,
610 EGLint attribute
, EGLint
* value
);
611 EGLBoolean(GLAPIENTRY
* fQuerySurfacePointerANGLE
)(EGLDisplay dpy
,
615 EGLSync(GLAPIENTRY
* fCreateSyncKHR
)(EGLDisplay dpy
, EGLenum type
,
616 const EGLint
* attrib_list
);
617 EGLBoolean(GLAPIENTRY
* fDestroySyncKHR
)(EGLDisplay dpy
, EGLSync sync
);
618 EGLint(GLAPIENTRY
* fClientWaitSyncKHR
)(EGLDisplay dpy
, EGLSync sync
,
619 EGLint flags
, EGLTime timeout
);
620 EGLBoolean(GLAPIENTRY
* fGetSyncAttribKHR
)(EGLDisplay dpy
, EGLSync sync
,
621 EGLint attribute
, EGLint
* value
);
622 EGLint(GLAPIENTRY
* fWaitSyncKHR
)(EGLDisplay dpy
, EGLSync sync
,
624 EGLint(GLAPIENTRY
* fDupNativeFenceFDANDROID
)(EGLDisplay dpy
, EGLSync sync
);
626 EGLStreamKHR(GLAPIENTRY
* fCreateStreamKHR
)(EGLDisplay dpy
,
627 const EGLint
* attrib_list
);
628 EGLBoolean(GLAPIENTRY
* fDestroyStreamKHR
)(EGLDisplay dpy
,
629 EGLStreamKHR stream
);
630 EGLBoolean(GLAPIENTRY
* fQueryStreamKHR
)(EGLDisplay dpy
, EGLStreamKHR stream
,
631 EGLenum attribute
, EGLint
* value
);
632 // KHR_stream_consumer_gltexture
633 EGLBoolean(GLAPIENTRY
* fStreamConsumerGLTextureExternalKHR
)(
634 EGLDisplay dpy
, EGLStreamKHR stream
);
635 EGLBoolean(GLAPIENTRY
* fStreamConsumerAcquireKHR
)(EGLDisplay dpy
,
636 EGLStreamKHR stream
);
637 EGLBoolean(GLAPIENTRY
* fStreamConsumerReleaseKHR
)(EGLDisplay dpy
,
638 EGLStreamKHR stream
);
640 EGLBoolean(GLAPIENTRY
* fQueryDisplayAttribEXT
)(EGLDisplay dpy
,
643 EGLBoolean(GLAPIENTRY
* fQueryDeviceAttribEXT
)(EGLDeviceEXT device
,
646 const char*(GLAPIENTRY
* fQueryDeviceStringEXT
)(EGLDeviceEXT device
,
649 // NV_stream_consumer_gltexture_yuv
650 EGLBoolean(GLAPIENTRY
* fStreamConsumerGLTextureExternalAttribsNV
)(
651 EGLDisplay dpy
, EGLStreamKHR stream
, const EGLAttrib
* attrib_list
);
652 // ANGLE_stream_producer_d3d_texture
653 EGLBoolean(GLAPIENTRY
* fCreateStreamProducerD3DTextureANGLE
)(
654 EGLDisplay dpy
, EGLStreamKHR stream
, const EGLAttrib
* attrib_list
);
655 EGLBoolean(GLAPIENTRY
* fStreamPostD3DTextureANGLE
)(
656 EGLDisplay dpy
, EGLStreamKHR stream
, void* texture
,
657 const EGLAttrib
* attrib_list
);
658 // ANGLE_device_creation
659 EGLDeviceEXT(GLAPIENTRY
* fCreateDeviceANGLE
)(EGLint device_type
,
661 const EGLAttrib
* attrib_list
);
662 EGLBoolean(GLAPIENTRY
* fReleaseDeviceANGLE
)(EGLDeviceEXT device
);
663 // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
664 EGLBoolean(GLAPIENTRY
* fSwapBuffersWithDamage
)(EGLDisplay dpy
,
668 // EGL_KHR_partial_update
669 EGLBoolean(GLAPIENTRY
* fSetDamageRegion
)(EGLDisplay dpy
, EGLSurface surface
,
672 EGLClientBuffer(GLAPIENTRY
* fGetNativeClientBufferANDROID
)(
673 const struct AHardwareBuffer
* buffer
);
675 // EGL_MESA_image_dma_buf_export
676 EGLBoolean(GLAPIENTRY
* fExportDMABUFImageQueryMESA
)(EGLDisplay dpy
,
680 uint64_t* modifiers
);
681 EGLBoolean(GLAPIENTRY
* fExportDMABUFImageMESA
)(EGLDisplay dpy
,
682 EGLImage image
, int* fds
,
686 EGLBoolean(GLAPIENTRY
* fQueryDevicesEXT
)(EGLint max_devices
,
687 EGLDeviceEXT
* devices
,
688 EGLint
* num_devices
);
693 class EglDisplay final
{
695 const RefPtr
<GLLibraryEGL
> mLib
;
696 const EGLDisplay mDisplay
;
700 std::bitset
<UnderlyingValue(EGLExtension::Max
)> mAvailableExtensions
;
702 struct PrivateUseOnly final
{};
705 static std::shared_ptr
<EglDisplay
> Create(
706 GLLibraryEGL
&, EGLDisplay
, bool isWarp
,
707 const StaticMutexAutoLock
& aProofOfLock
);
709 // Only `public` for make_shared.
710 EglDisplay(const PrivateUseOnly
&, GLLibraryEGL
&, EGLDisplay
, bool isWarp
);
715 bool IsExtensionSupported(EGLExtension aKnownExtension
) const {
716 return mAvailableExtensions
[UnderlyingValue(aKnownExtension
)];
719 void MarkExtensionUnsupported(EGLExtension aKnownExtension
) {
720 mAvailableExtensions
[UnderlyingValue(aKnownExtension
)] = false;
723 void DumpEGLConfig(EGLConfig
) const;
724 void DumpEGLConfigs() const;
730 bool HasKHRImageBase() const {
731 return IsExtensionSupported(EGLExtension::KHR_image
) ||
732 IsExtensionSupported(EGLExtension::KHR_image_base
);
735 bool HasKHRImagePixmap() const {
736 return IsExtensionSupported(EGLExtension::KHR_image
) ||
737 IsExtensionSupported(EGLExtension::KHR_image_pixmap
);
742 EGLBoolean
fTerminate() { return mLib
->fTerminate(mDisplay
); }
744 EGLBoolean
fMakeCurrent(EGLSurface draw
, EGLSurface read
,
745 EGLContext ctx
) const {
746 return mLib
->fMakeCurrent(mDisplay
, draw
, read
, ctx
);
749 EGLBoolean
fDestroyContext(EGLContext ctx
) const {
750 return mLib
->fDestroyContext(mDisplay
, ctx
);
753 EGLContext
fCreateContext(EGLConfig config
, EGLContext share_context
,
754 const EGLint
* attrib_list
) const {
755 return mLib
->fCreateContext(mDisplay
, config
, share_context
, attrib_list
);
758 EGLBoolean
fDestroySurface(EGLSurface surface
) const {
759 return mLib
->fDestroySurface(mDisplay
, surface
);
762 EGLSurface
fCreateWindowSurface(EGLConfig config
, EGLNativeWindowType win
,
763 const EGLint
* attrib_list
) const {
764 return mLib
->fCreateWindowSurface(mDisplay
, config
, win
, attrib_list
);
767 EGLSurface
fCreatePbufferSurface(EGLConfig config
,
768 const EGLint
* attrib_list
) const {
769 return mLib
->fCreatePbufferSurface(mDisplay
, config
, attrib_list
);
772 EGLSurface
fCreatePbufferFromClientBuffer(EGLenum buftype
,
773 EGLClientBuffer buffer
,
775 const EGLint
* attrib_list
) const {
776 return mLib
->fCreatePbufferFromClientBuffer(mDisplay
, buftype
, buffer
,
777 config
, attrib_list
);
780 EGLBoolean
fChooseConfig(const EGLint
* attrib_list
, EGLConfig
* configs
,
781 EGLint config_size
, EGLint
* num_config
) const {
782 return mLib
->fChooseConfig(mDisplay
, attrib_list
, configs
, config_size
,
786 EGLBoolean
fGetConfigAttrib(EGLConfig config
, EGLint attribute
,
787 EGLint
* value
) const {
788 return mLib
->fGetConfigAttrib(mDisplay
, config
, attribute
, value
);
791 EGLBoolean
fGetConfigs(EGLConfig
* configs
, EGLint config_size
,
792 EGLint
* num_config
) const {
793 return mLib
->fGetConfigs(mDisplay
, configs
, config_size
, num_config
);
796 EGLBoolean
fSwapBuffers(EGLSurface surface
) const {
797 return mLib
->fSwapBuffers(mDisplay
, surface
);
800 EGLBoolean
fBindTexImage(EGLSurface surface
, EGLint buffer
) const {
801 return mLib
->fBindTexImage(mDisplay
, surface
, buffer
);
804 EGLBoolean
fReleaseTexImage(EGLSurface surface
, EGLint buffer
) const {
805 return mLib
->fReleaseTexImage(mDisplay
, surface
, buffer
);
808 EGLBoolean
fSwapInterval(EGLint interval
) const {
809 return mLib
->fSwapInterval(mDisplay
, interval
);
812 EGLImage
fCreateImage(EGLContext ctx
, EGLenum target
, EGLClientBuffer buffer
,
813 const EGLint
* attribList
) const {
814 MOZ_ASSERT(HasKHRImageBase());
815 return mLib
->fCreateImage(mDisplay
, ctx
, target
, buffer
, attribList
);
818 EGLBoolean
fDestroyImage(EGLImage image
) const {
819 MOZ_ASSERT(HasKHRImageBase());
820 return mLib
->fDestroyImage(mDisplay
, image
);
823 EGLBoolean
fQuerySurface(EGLSurface surface
, EGLint attribute
,
824 EGLint
* value
) const {
825 return mLib
->fQuerySurface(mDisplay
, surface
, attribute
, value
);
828 EGLBoolean
fQuerySurfacePointerANGLE(EGLSurface surface
, EGLint attribute
,
829 void** value
) const {
830 MOZ_ASSERT(IsExtensionSupported(
831 EGLExtension::ANGLE_surface_d3d_texture_2d_share_handle
));
832 return mLib
->fQuerySurfacePointerANGLE(mDisplay
, surface
, attribute
, value
);
835 EGLSync
fCreateSync(EGLenum type
, const EGLint
* attrib_list
) const {
836 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync
));
837 return mLib
->fCreateSync(mDisplay
, type
, attrib_list
);
840 EGLBoolean
fDestroySync(EGLSync sync
) const {
841 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync
));
842 return mLib
->fDestroySync(mDisplay
, sync
);
845 EGLint
fClientWaitSync(EGLSync sync
, EGLint flags
, EGLTime timeout
) const {
846 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync
));
847 return mLib
->fClientWaitSync(mDisplay
, sync
, flags
, timeout
);
850 EGLBoolean
fGetSyncAttrib(EGLSync sync
, EGLint attribute
,
851 EGLint
* value
) const {
852 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync
));
853 return mLib
->fGetSyncAttrib(mDisplay
, sync
, attribute
, value
);
856 EGLint
fWaitSync(EGLSync sync
, EGLint flags
) const {
857 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_wait_sync
));
858 return mLib
->fWaitSync(mDisplay
, sync
, flags
);
861 EGLint
fDupNativeFenceFDANDROID(EGLSync sync
) const {
862 MOZ_ASSERT(IsExtensionSupported(EGLExtension::ANDROID_native_fence_sync
));
863 return mLib
->fDupNativeFenceFDANDROID(mDisplay
, sync
);
867 EGLBoolean
fQueryDisplayAttribEXT(EGLint attribute
, EGLAttrib
* value
) const {
868 MOZ_ASSERT(mLib
->IsExtensionSupported(EGLLibExtension::EXT_device_query
));
869 return mLib
->fQueryDisplayAttribEXT(mDisplay
, attribute
, value
);
873 EGLStreamKHR
fCreateStreamKHR(const EGLint
* attrib_list
) const {
874 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_stream
));
875 return mLib
->fCreateStreamKHR(mDisplay
, attrib_list
);
878 EGLBoolean
fDestroyStreamKHR(EGLStreamKHR stream
) const {
879 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_stream
));
880 return mLib
->fDestroyStreamKHR(mDisplay
, stream
);
883 EGLBoolean
fQueryStreamKHR(EGLStreamKHR stream
, EGLenum attribute
,
884 EGLint
* value
) const {
885 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_stream
));
886 return mLib
->fQueryStreamKHR(mDisplay
, stream
, attribute
, value
);
889 // KHR_stream_consumer_gltexture
890 EGLBoolean
fStreamConsumerGLTextureExternalKHR(EGLStreamKHR stream
) const {
892 IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture
));
893 return mLib
->fStreamConsumerGLTextureExternalKHR(mDisplay
, stream
);
896 EGLBoolean
fStreamConsumerAcquireKHR(EGLStreamKHR stream
) const {
898 IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture
));
899 return mLib
->fStreamConsumerAcquireKHR(mDisplay
, stream
);
902 EGLBoolean
fStreamConsumerReleaseKHR(EGLStreamKHR stream
) const {
904 IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture
));
905 return mLib
->fStreamConsumerReleaseKHR(mDisplay
, stream
);
908 // NV_stream_consumer_gltexture_yuv
909 EGLBoolean
fStreamConsumerGLTextureExternalAttribsNV(
910 EGLStreamKHR stream
, const EGLAttrib
* attrib_list
) const {
912 IsExtensionSupported(EGLExtension::NV_stream_consumer_gltexture_yuv
));
913 return mLib
->fStreamConsumerGLTextureExternalAttribsNV(mDisplay
, stream
,
917 // ANGLE_stream_producer_d3d_texture
918 EGLBoolean
fCreateStreamProducerD3DTextureANGLE(
919 EGLStreamKHR stream
, const EGLAttrib
* attrib_list
) const {
921 IsExtensionSupported(EGLExtension::ANGLE_stream_producer_d3d_texture
));
922 return mLib
->fCreateStreamProducerD3DTextureANGLE(mDisplay
, stream
,
926 EGLBoolean
fStreamPostD3DTextureANGLE(EGLStreamKHR stream
, void* texture
,
927 const EGLAttrib
* attrib_list
) const {
929 IsExtensionSupported(EGLExtension::ANGLE_stream_producer_d3d_texture
));
930 return mLib
->fStreamPostD3DTextureANGLE(mDisplay
, stream
, texture
,
934 // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
935 EGLBoolean
fSwapBuffersWithDamage(EGLSurface surface
, const EGLint
* rects
,
938 IsExtensionSupported(EGLExtension::EXT_swap_buffers_with_damage
) ||
939 IsExtensionSupported(EGLExtension::KHR_swap_buffers_with_damage
));
940 return mLib
->fSwapBuffersWithDamage(mDisplay
, surface
, rects
, n_rects
);
943 // EGL_KHR_partial_update
944 EGLBoolean
fSetDamageRegion(EGLSurface surface
, const EGLint
* rects
,
946 MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_partial_update
));
947 return mLib
->fSetDamageRegion(mDisplay
, surface
, rects
, n_rects
);
950 EGLBoolean
fExportDMABUFImageQuery(EGLImage image
, int* fourcc
,
952 uint64_t* modifiers
) const {
953 MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export
));
954 return mLib
->fExportDMABUFImageQuery(mDisplay
, image
, fourcc
, num_planes
,
957 EGLBoolean
fExportDMABUFImage(EGLImage image
, int* fds
, EGLint
* strides
,
958 EGLint
* offsets
) const {
959 MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export
));
960 return mLib
->fExportDMABUFImage(mDisplay
, image
, fds
, strides
, offsets
);
965 } /* namespace mozilla */
967 #endif /* GLLIBRARYEGL_H_ */