Bug 1860959 [wpt PR 42048] - [webaudio] Convert test to testharness, a=testonly
[gecko.git] / gfx / gl / GLLibraryEGL.h
blob28f84b27f445a549062aa5c76f41d14b20396818
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_
8 #if defined(MOZ_X11)
9 # include "mozilla/X11Util.h"
10 #endif
12 #include "base/platform_thread.h" // for PlatformThreadId
13 #include "gfxEnv.h"
14 #include "GLTypes.h"
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"
23 #include "prlink.h"
25 #include <bitset>
26 #include <memory>
27 #include <unordered_map>
29 #ifdef MOZ_WIDGET_ANDROID
30 # include "mozilla/ProfilerLabels.h"
31 #endif
33 #if defined(MOZ_X11)
34 # define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
35 #else
36 # define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
37 #endif
39 struct ID3D11Device;
41 extern "C" {
42 struct AHardwareBuffer;
45 namespace angle {
46 class Platform;
49 namespace mozilla {
51 namespace gfx {
52 class DataSourceSurface;
55 namespace gl {
57 class SymbolLoader;
59 PRLibrary* LoadApitraceLibrary();
61 void BeforeEGLCall(const char* funcName);
62 void AfterEGLCall(const char* funcName);
64 class EglDisplay;
65 /**
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,
76 ANGLE_platform_angle,
77 ANGLE_platform_angle_d3d,
78 EXT_device_enumeration,
79 EXT_device_query,
80 EXT_platform_device,
81 MESA_platform_surfaceless,
82 Max
85 /**
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 {
93 KHR_image_base,
94 KHR_image_pixmap,
95 KHR_gl_texture_2D_image,
96 ANGLE_surface_d3d_texture_2d_share_handle,
97 EXT_create_context_robustness,
98 KHR_image,
99 KHR_fence_sync,
100 KHR_wait_sync,
101 ANDROID_native_fence_sync,
102 EGL_ANDROID_image_crop,
103 ANGLE_d3d_share_handle_client_buffer,
104 KHR_create_context,
105 KHR_stream,
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,
114 EXT_buffer_age,
115 KHR_partial_update,
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,
124 // -
126 class GLLibraryEGL final {
127 friend class EglDisplay;
129 public:
130 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLLibraryEGL)
132 private:
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;
140 public:
141 static RefPtr<GLLibraryEGL> Get(nsACString* const out_failureId);
142 static void Shutdown();
144 private:
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);
157 public:
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; }
175 // -
176 // PFN wrappers
178 #ifdef MOZ_WIDGET_ANDROID
179 # define PROFILE_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
180 #else
181 # define PROFILE_CALL
182 #endif
184 #ifndef MOZ_FUNCTION_NAME
185 # ifdef __GNUC__
186 # define MOZ_FUNCTION_NAME __PRETTY_FUNCTION__
187 # elif defined(_MSC_VER)
188 # define MOZ_FUNCTION_NAME __FUNCTION__
189 # else
190 # define MOZ_FUNCTION_NAME \
191 __func__ // defined in C99, supported in various C++ compilers. Just raw
192 // function name.
193 # endif
194 #endif
196 #ifdef DEBUG
197 # define BEFORE_CALL BeforeEGLCall(MOZ_FUNCTION_NAME);
198 # define AFTER_CALL AfterEGLCall(MOZ_FUNCTION_NAME);
199 #else
200 # define BEFORE_CALL
201 # define AFTER_CALL
202 #endif
204 #define WRAP(X) \
205 PROFILE_CALL \
206 BEFORE_CALL \
207 const auto ret = mSymbols.X; \
208 AFTER_CALL \
209 return ret
211 public:
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));
253 private:
254 EGLBoolean fTerminate(EGLDisplay display) const { WRAP(fTerminate(display)); }
256 // -
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();
271 if (prevCtx) {
272 mOwningThreadByContext[prevCtx] = 0;
274 if (ctx) {
275 auto& ctxOwnerThread = mOwningThreadByContext[ctx];
276 if (ctxOwnerThread && ctxOwnerThread != tid) {
277 gfxCriticalError()
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");
284 return false;
286 ctxOwnerThread = tid;
290 WRAP(fMakeCurrent(dpy, draw, read, ctx));
293 // -
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));
314 public:
315 EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
316 EGLNativeWindowType win,
317 const EGLint* attrib_list) const {
318 WRAP(fCreateWindowSurface(dpy, config, win, attrib_list));
321 private:
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,
329 EGLConfig config,
330 const EGLint* attrib_list) const {
331 WRAP(fCreatePbufferFromClientBuffer(dpy, buftype, buffer, config,
332 attrib_list));
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));
370 public:
371 const GLubyte* fQueryString(EGLDisplay dpy, EGLint name) const {
372 WRAP(fQueryString(dpy, name));
375 private:
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));
442 // KHR_stream
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));
473 // EXT_device_query
474 EGLBoolean fQueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute,
475 EGLAttrib* value) const {
476 WRAP(fQueryDisplayAttribEXT(dpy, attribute, value));
479 public:
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));
489 private:
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,
503 void* texture,
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) {
523 WRAP(
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));
531 public:
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));
538 #undef WRAP
540 #undef WRAP
541 #undef PROFILE_CALL
542 #undef BEFORE_CALL
543 #undef AFTER_CALL
544 #undef MOZ_FUNCTION_NAME
546 ////
548 private:
549 struct {
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,
566 EGLConfig config,
567 EGLNativeWindowType win,
568 const EGLint* attrib_list);
569 EGLSurface(GLAPIENTRY* fCreatePbufferSurface)(EGLDisplay dpy,
570 EGLConfig config,
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,
576 EGLConfig config,
577 EGLNativePixmapType pixmap,
578 const EGLint* attrib_list);
579 EGLBoolean(GLAPIENTRY* fBindAPI)(EGLenum api);
580 EGLBoolean(GLAPIENTRY* fInitialize)(EGLDisplay dpy, EGLint* major,
581 EGLint* minor);
582 EGLBoolean(GLAPIENTRY* fChooseConfig)(EGLDisplay dpy,
583 const EGLint* attrib_list,
584 EGLConfig* configs,
585 EGLint config_size,
586 EGLint* num_config);
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,
600 EGLint buffer);
601 EGLBoolean(GLAPIENTRY* fReleaseTexImage)(EGLDisplay, EGLSurface surface,
602 EGLint buffer);
603 EGLBoolean(GLAPIENTRY* fSwapInterval)(EGLDisplay dpy, EGLint interval);
604 EGLImage(GLAPIENTRY* fCreateImageKHR)(EGLDisplay dpy, EGLContext ctx,
605 EGLenum target,
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,
612 EGLSurface surface,
613 EGLint attribute,
614 void** value);
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,
623 EGLint flags);
624 EGLint(GLAPIENTRY* fDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
625 // KHR_stream
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);
639 // EXT_device_query
640 EGLBoolean(GLAPIENTRY* fQueryDisplayAttribEXT)(EGLDisplay dpy,
641 EGLint attribute,
642 EGLAttrib* value);
643 EGLBoolean(GLAPIENTRY* fQueryDeviceAttribEXT)(EGLDeviceEXT device,
644 EGLint attribute,
645 EGLAttrib* value);
646 const char*(GLAPIENTRY* fQueryDeviceStringEXT)(EGLDeviceEXT device,
647 EGLint name);
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,
660 void* native_device,
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,
665 EGLSurface surface,
666 const EGLint* rects,
667 EGLint n_rects);
668 // EGL_KHR_partial_update
669 EGLBoolean(GLAPIENTRY* fSetDamageRegion)(EGLDisplay dpy, EGLSurface surface,
670 const EGLint* rects,
671 EGLint n_rects);
672 EGLClientBuffer(GLAPIENTRY* fGetNativeClientBufferANDROID)(
673 const struct AHardwareBuffer* buffer);
675 // EGL_MESA_image_dma_buf_export
676 EGLBoolean(GLAPIENTRY* fExportDMABUFImageQueryMESA)(EGLDisplay dpy,
677 EGLImage image,
678 int* fourcc,
679 int* num_planes,
680 uint64_t* modifiers);
681 EGLBoolean(GLAPIENTRY* fExportDMABUFImageMESA)(EGLDisplay dpy,
682 EGLImage image, int* fds,
683 EGLint* strides,
684 EGLint* offsets);
686 EGLBoolean(GLAPIENTRY* fQueryDevicesEXT)(EGLint max_devices,
687 EGLDeviceEXT* devices,
688 EGLint* num_devices);
690 } mSymbols = {};
693 class EglDisplay final {
694 public:
695 const RefPtr<GLLibraryEGL> mLib;
696 const EGLDisplay mDisplay;
697 const bool mIsWARP;
699 private:
700 std::bitset<UnderlyingValue(EGLExtension::Max)> mAvailableExtensions;
702 struct PrivateUseOnly final {};
704 public:
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);
712 public:
713 ~EglDisplay();
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;
726 void Shutdown();
728 // -
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);
740 // -
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,
774 EGLConfig config,
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,
783 num_config);
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);
866 // EXT_device_query
867 EGLBoolean fQueryDisplayAttribEXT(EGLint attribute, EGLAttrib* value) const {
868 MOZ_ASSERT(mLib->IsExtensionSupported(EGLLibExtension::EXT_device_query));
869 return mLib->fQueryDisplayAttribEXT(mDisplay, attribute, value);
872 // KHR_stream
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 {
891 MOZ_ASSERT(
892 IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture));
893 return mLib->fStreamConsumerGLTextureExternalKHR(mDisplay, stream);
896 EGLBoolean fStreamConsumerAcquireKHR(EGLStreamKHR stream) const {
897 MOZ_ASSERT(
898 IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture));
899 return mLib->fStreamConsumerAcquireKHR(mDisplay, stream);
902 EGLBoolean fStreamConsumerReleaseKHR(EGLStreamKHR stream) const {
903 MOZ_ASSERT(
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 {
911 MOZ_ASSERT(
912 IsExtensionSupported(EGLExtension::NV_stream_consumer_gltexture_yuv));
913 return mLib->fStreamConsumerGLTextureExternalAttribsNV(mDisplay, stream,
914 attrib_list);
917 // ANGLE_stream_producer_d3d_texture
918 EGLBoolean fCreateStreamProducerD3DTextureANGLE(
919 EGLStreamKHR stream, const EGLAttrib* attrib_list) const {
920 MOZ_ASSERT(
921 IsExtensionSupported(EGLExtension::ANGLE_stream_producer_d3d_texture));
922 return mLib->fCreateStreamProducerD3DTextureANGLE(mDisplay, stream,
923 attrib_list);
926 EGLBoolean fStreamPostD3DTextureANGLE(EGLStreamKHR stream, void* texture,
927 const EGLAttrib* attrib_list) const {
928 MOZ_ASSERT(
929 IsExtensionSupported(EGLExtension::ANGLE_stream_producer_d3d_texture));
930 return mLib->fStreamPostD3DTextureANGLE(mDisplay, stream, texture,
931 attrib_list);
934 // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
935 EGLBoolean fSwapBuffersWithDamage(EGLSurface surface, const EGLint* rects,
936 EGLint n_rects) {
937 MOZ_ASSERT(
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,
945 EGLint n_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,
951 int* num_planes,
952 uint64_t* modifiers) const {
953 MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export));
954 return mLib->fExportDMABUFImageQuery(mDisplay, image, fourcc, num_planes,
955 modifiers);
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);
964 } /* namespace gl */
965 } /* namespace mozilla */
967 #endif /* GLLIBRARYEGL_H_ */