Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/gfx/gl/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 36 kB image not shown  

Quelle  GLLibraryEGL.h   Sprache: C

 
/* 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 "base/platform_thread.h"  // for PlatformThreadId
#include "gfxEnv.h"
#include "GLContext.h"
#include "mozilla/EnumTypeTraits.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticMutex.h"
#include "mozilla/StaticPtr.h"
#include "nsISupports.h"
#include "prlink.h"

#include <bitset>
#include <memory>
#include <unordered_map>

#ifdef MOZ_WIDGET_ANDROID
#  include "mozilla/ProfilerLabels.h"
#  include "AndroidBuild.h"
#endif

#if defined(MOZ_X11)
#  define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)mozilla::DefaultXDisplay())
#else
#  define EGL_DEFAULT_DISPLAY ((EGLNativeDisplayType)0)
#endif

struct ID3D11Device;

extern "C" {
struct AHardwareBuffer;
}

namespace angle {
class Platform;
}

namespace mozilla {

namespace gfx {
class DataSourceSurface;
}

namespace gl {

class SymbolLoader;

PRLibrary* LoadApitraceLibrary();

void BeforeEGLCall(const char* funcName);
void AfterEGLCall(const char* funcName);

class EglDisplay;
/**
 * 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 GLLibraryEGL.cpp.
 */

enum class EGLLibExtension {
  ANDROID_get_native_client_buffer,
  ANGLE_device_creation,
  ANGLE_device_creation_d3d11,
  ANGLE_platform_angle,
  ANGLE_platform_angle_d3d,
  EXT_device_enumeration,
  EXT_device_query,
  EXT_platform_device,
  MESA_platform_surfaceless,
  Max
};

/**
 * 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 GLLibraryEGL.cpp.
 */

enum class EGLExtension {
  KHR_image_base,
  KHR_image_pixmap,
  KHR_gl_texture_2D_image,
  ANGLE_surface_d3d_texture_2d_share_handle,
  EXT_create_context_robustness,
  KHR_image,
  KHR_fence_sync,
  KHR_wait_sync,
  ANDROID_native_fence_sync,
  EGL_ANDROID_image_crop,
  ANGLE_d3d_share_handle_client_buffer,
  KHR_create_context,
  KHR_stream,
  KHR_stream_consumer_gltexture,
  NV_stream_consumer_gltexture_yuv,
  ANGLE_stream_producer_d3d_texture,
  KHR_surfaceless_context,
  KHR_create_context_no_error,
  MOZ_create_context_provoking_vertex_dont_care,
  EXT_swap_buffers_with_damage,
  KHR_swap_buffers_with_damage,
  EXT_buffer_age,
  KHR_partial_update,
  NV_robustness_video_memory_purge,
  EXT_image_dma_buf_import,
  EXT_image_dma_buf_import_modifiers,
  MESA_image_dma_buf_export,
  KHR_no_config_context,
  Max
};

// -

class GLLibraryEGL final {
  friend class EglDisplay;

 public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GLLibraryEGL)

 private:
  PRLibrary* mEGLLibrary = nullptr;
  PRLibrary* mGLLibrary = nullptr;
  bool mIsANGLE = false;
  std::bitset<UnderlyingValue(EGLLibExtension::Max)> mAvailableExtensions;
  std::weak_ptr<EglDisplay> mDefaultDisplay;
  std::unordered_map<EGLDisplay, std::weak_ptr<EglDisplay>> mActiveDisplays;

 public:
  static RefPtr<GLLibraryEGL> Get(nsACString* const out_failureId);
  static void Shutdown();

 private:
  ~GLLibraryEGL() = default;

  static StaticMutex sMutex;
  static StaticRefPtr<GLLibraryEGL> sInstance MOZ_GUARDED_BY(sMutex);

  bool Init(nsACString* const out_failureId);
  void InitLibExtensions();

  std::shared_ptr<EglDisplay> CreateDisplayLocked(
      bool forceAccel, bool forceSoftware, nsACString* const out_failureId,
      const StaticMutexAutoLock& aProofOfLock);

 public:
  Maybe<SymbolLoader> GetSymbolLoader() const;

  std::shared_ptr<EglDisplay> CreateDisplay(bool forceAccel, bool forceSoftware,
                                            nsACString* const out_failureId);
  std::shared_ptr<EglDisplay> CreateDisplay(ID3D11Device*);
  std::shared_ptr<EglDisplay> DefaultDisplay(nsACString* const out_failureId);

  bool IsExtensionSupported(EGLLibExtension aKnownExtension) const {
    return mAvailableExtensions[UnderlyingValue(aKnownExtension)];
  }

  void MarkExtensionUnsupported(EGLLibExtension aKnownExtension) {
    mAvailableExtensions[UnderlyingValue(aKnownExtension)] = false;
  }

  bool IsANGLE() const { return mIsANGLE; }

  // -
  // PFN wrappers

#ifdef MOZ_WIDGET_ANDROID
#  define PROFILE_CALL AUTO_PROFILER_LABEL(__func__, GRAPHICS);
#else
#  define PROFILE_CALL
#endif

#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 DEBUG
#  define BEFORE_CALL BeforeEGLCall(MOZ_FUNCTION_NAME);
#  define AFTER_CALL AfterEGLCall(MOZ_FUNCTION_NAME);
#else
#  define BEFORE_CALL
#  define AFTER_CALL
#endif

#define WRAP(X)                \
  PROFILE_CALL                 \
  BEFORE_CALL                  \
  const auto ret = mSymbols.X; \
  AFTER_CALL                   \
  return ret

 public:
  EGLDisplay fGetDisplay(void* display_id) const {
    WRAP(fGetDisplay(display_id));
  }

  EGLDisplay fGetPlatformDisplay(EGLenum platform, void* native_display,
                                 const EGLAttrib* attrib_list) const {
    WRAP(fGetPlatformDisplay(platform, native_display, attrib_list));
  }

  EGLSurface fGetCurrentSurface(EGLint id) const {
    WRAP(fGetCurrentSurface(id));
  }

  EGLContext fGetCurrentContext() const { WRAP(fGetCurrentContext()); }

  EGLBoolean fBindAPI(EGLenum api) const { WRAP(fBindAPI(api)); }

  EGLint fGetError() const { WRAP(fGetError()); }

  EGLBoolean fWaitNative(EGLint engine) const { WRAP(fWaitNative(engine)); }

  EGLCastToRelevantPtr fGetProcAddress(const char* procname) const {
    WRAP(fGetProcAddress(procname));
  }

  // ANGLE_device_creation
  EGLDeviceEXT fCreateDeviceANGLE(EGLint device_type, void* native_device,
                                  const EGLAttrib* attrib_list) const {
    WRAP(fCreateDeviceANGLE(device_type, native_device, attrib_list));
  }

  EGLBoolean fReleaseDeviceANGLE(EGLDeviceEXT device) {
    WRAP(fReleaseDeviceANGLE(device));
  }

  // ANDROID_get_native_client_buffer
  EGLClientBuffer fGetNativeClientBufferANDROID(
      const struct AHardwareBuffer* buffer) {
    WRAP(fGetNativeClientBufferANDROID(buffer));
  }

 private:
  EGLBoolean fTerminate(EGLDisplay display) const { WRAP(fTerminate(display)); }

  // -

  mutable Mutex mMutex = Mutex{"GLLibraryEGL::mMutex"};
  mutable std::unordered_map<EGLContext, PlatformThreadId>
      mOwningThreadByContext MOZ_GUARDED_BY(mMutex);

  EGLBoolean fMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
                          EGLContext ctx) const {
    const bool CHECK_CONTEXT_OWNERSHIP = true;
    if (CHECK_CONTEXT_OWNERSHIP) {
      const MutexAutoLock lock(mMutex);
      const auto tid = PlatformThread::CurrentId();
      const auto prevCtx = fGetCurrentContext();

      if (prevCtx) {
        mOwningThreadByContext[prevCtx] = 0;
      }
      if (ctx) {
        auto& ctxOwnerThread = mOwningThreadByContext[ctx];
        if (ctxOwnerThread && ctxOwnerThread != tid) {
          gfxCriticalError()
              << "EGLContext#" << ctx << " is owned by/Current on"
              << " thread#" << ctxOwnerThread << " but MakeCurrent requested on"
              << " thread#" << tid << "!";
          if (gfxEnv::MOZ_EGL_RELEASE_ASSERT_CONTEXT_OWNERSHIP()) {
            MOZ_CRASH("MOZ_EGL_RELEASE_ASSERT_CONTEXT_OWNERSHIP");
          }
          return false;
        }
        ctxOwnerThread = tid;
      }
    }

    // Always reset the TLS current context.
    // If we're called by TLS-caching MakeCurrent, after we return true,
    // the caller will set the TLS correctly anyway.
    GLContext::ResetTLSCurrentContext();

    WRAP(fMakeCurrent(dpy, draw, read, ctx));
  }

  // -

  EGLBoolean fDestroyContext(EGLDisplay dpy, EGLContext ctx) const {
    {
      const MutexAutoLock lock(mMutex);
      mOwningThreadByContext.erase(ctx);
    }

    WRAP(fDestroyContext(dpy, ctx));
  }

  EGLContext fCreateContext(EGLDisplay dpy, EGLConfig config,
                            EGLContext share_context,
                            const EGLint* attrib_list) const {
    WRAP(fCreateContext(dpy, config, share_context, attrib_list));
  }

  EGLBoolean fDestroySurface(EGLDisplay dpy, EGLSurface surface) const {
    WRAP(fDestroySurface(dpy, surface));
  }

 public:
  EGLSurface fCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
                                  EGLNativeWindowType win,
                                  const EGLint* attrib_list) const {
    WRAP(fCreateWindowSurface(dpy, config, win, attrib_list));
  }

 private:
  EGLSurface fCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
                                   const EGLint* attrib_list) const {
    WRAP(fCreatePbufferSurface(dpy, config, attrib_list));
  }

  EGLSurface fCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
                                            EGLClientBuffer buffer,
                                            EGLConfig config,
                                            const EGLint* attrib_list) const {
    WRAP(fCreatePbufferFromClientBuffer(dpy, buftype, buffer, config,
                                        attrib_list));
  }

  EGLSurface fCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
                                  EGLNativePixmapType pixmap,
                                  const EGLint* attrib_list) const {
    WRAP(fCreatePixmapSurface(dpy, config, pixmap, attrib_list));
  }

  EGLBoolean fInitialize(EGLDisplay dpy, EGLint* major, EGLint* minor) const {
    WRAP(fInitialize(dpy, major, minor));
  }

  EGLBoolean fChooseConfig(EGLDisplay dpy, const EGLint* attrib_list,
                           EGLConfig* configs, EGLint config_size,
                           EGLint* num_config) const {
    WRAP(fChooseConfig(dpy, attrib_list, configs, config_size, num_config));
  }

  EGLBoolean fGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
                              EGLint attribute, EGLint* value) const {
    WRAP(fGetConfigAttrib(dpy, config, attribute, value));
  }

  EGLBoolean fGetConfigs(EGLDisplay dpy, EGLConfig* configs, EGLint config_size,
                         EGLint* num_config) const {
    WRAP(fGetConfigs(dpy, configs, config_size, num_config));
  }

  EGLBoolean fSwapBuffers(EGLDisplay dpy, EGLSurface surface) const {
    WRAP(fSwapBuffers(dpy, surface));
  }

  EGLBoolean fCopyBuffers(EGLDisplay dpy, EGLSurface surface,
                          EGLNativePixmapType target) const {
    WRAP(fCopyBuffers(dpy, surface, target));
  }

 public:
  const GLubyte* fQueryString(EGLDisplay dpy, EGLint name) const {
    WRAP(fQueryString(dpy, name));
  }

 private:
  EGLBoolean fQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute,
                           EGLint* value) const {
    WRAP(fQueryContext(dpy, ctx, attribute, value));
  }

  EGLBoolean fBindTexImage(EGLDisplay dpy, EGLSurface surface,
                           EGLint buffer) const {
    WRAP(fBindTexImage(dpy, surface, buffer));
  }

  EGLBoolean fReleaseTexImage(EGLDisplay dpy, EGLSurface surface,
                              EGLint buffer) const {
    WRAP(fReleaseTexImage(dpy, surface, buffer));
  }

  EGLBoolean fSwapInterval(EGLDisplay dpy, EGLint interval) const {
    WRAP(fSwapInterval(dpy, interval));
  }

  EGLImage fCreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target,
                        EGLClientBuffer buffer,
                        const EGLint* attrib_list) const {
    WRAP(fCreateImageKHR(dpy, ctx, target, buffer, attrib_list));
  }

  EGLBoolean fDestroyImage(EGLDisplay dpy, EGLImage image) const {
    WRAP(fDestroyImageKHR(dpy, image));
  }

  EGLBoolean fQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute,
                           EGLint* value) const {
    WRAP(fQuerySurface(dpy, surface, attribute, value));
  }

  EGLBoolean fQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface,
                                       EGLint attribute, void** value) const {
    WRAP(fQuerySurfacePointerANGLE(dpy, surface, attribute, value));
  }

  EGLSync fCreateSync(EGLDisplay dpy, EGLenum type,
                      const EGLint* attrib_list) const {
    WRAP(fCreateSyncKHR(dpy, type, attrib_list));
  }

  EGLBoolean fDestroySync(EGLDisplay dpy, EGLSync sync) const {
    WRAP(fDestroySyncKHR(dpy, sync));
  }

  EGLint fClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags,
                         EGLTime timeout) const {
    WRAP(fClientWaitSyncKHR(dpy, sync, flags, timeout));
  }

  EGLBoolean fGetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute,
                            EGLint* value) const {
    WRAP(fGetSyncAttribKHR(dpy, sync, attribute, value));
  }

  EGLint fWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags) const {
    WRAP(fWaitSyncKHR(dpy, sync, flags));
  }

  EGLint fDupNativeFenceFDANDROID(EGLDisplay dpy, EGLSync sync) const {
    WRAP(fDupNativeFenceFDANDROID(dpy, sync));
  }

  // KHR_stream
  EGLStreamKHR fCreateStreamKHR(EGLDisplay dpy,
                                const EGLint* attrib_list) const {
    WRAP(fCreateStreamKHR(dpy, attrib_list));
  }

  EGLBoolean fDestroyStreamKHR(EGLDisplay dpy, EGLStreamKHR stream) const {
    WRAP(fDestroyStreamKHR(dpy, stream));
  }

  EGLBoolean fQueryStreamKHR(EGLDisplay dpy, EGLStreamKHR stream,
                             EGLenum attribute, EGLint* value) const {
    WRAP(fQueryStreamKHR(dpy, stream, attribute, value));
  }

  // KHR_stream_consumer_gltexture
  EGLBoolean fStreamConsumerGLTextureExternalKHR(EGLDisplay dpy,
                                                 EGLStreamKHR stream) const {
    WRAP(fStreamConsumerGLTextureExternalKHR(dpy, stream));
  }

  EGLBoolean fStreamConsumerAcquireKHR(EGLDisplay dpy,
                                       EGLStreamKHR stream) const {
    WRAP(fStreamConsumerAcquireKHR(dpy, stream));
  }

  EGLBoolean fStreamConsumerReleaseKHR(EGLDisplay dpy,
                                       EGLStreamKHR stream) const {
    WRAP(fStreamConsumerReleaseKHR(dpy, stream));
  }

  // EXT_device_query
  EGLBoolean fQueryDisplayAttribEXT(EGLDisplay dpy, EGLint attribute,
                                    EGLAttrib* value) const {
    WRAP(fQueryDisplayAttribEXT(dpy, attribute, value));
  }

 public:
  EGLBoolean fQueryDeviceAttribEXT(EGLDeviceEXT device, EGLint attribute,
                                   EGLAttrib* value) const {
    WRAP(fQueryDeviceAttribEXT(device, attribute, value));
  }

  const char* fQueryDeviceStringEXT(EGLDeviceEXT device, EGLint name) {
    WRAP(fQueryDeviceStringEXT(device, name));
  }

 private:
  // NV_stream_consumer_gltexture_yuv
  EGLBoolean fStreamConsumerGLTextureExternalAttribsNV(
      EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list) const {
    WRAP(fStreamConsumerGLTextureExternalAttribsNV(dpy, stream, attrib_list));
  }

  // ANGLE_stream_producer_d3d_texture
  EGLBoolean fCreateStreamProducerD3DTextureANGLE(
      EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list) const {
    WRAP(fCreateStreamProducerD3DTextureANGLE(dpy, stream, attrib_list));
  }

  EGLBoolean fStreamPostD3DTextureANGLE(EGLDisplay dpy, EGLStreamKHR stream,
                                        void* texture,
                                        const EGLAttrib* attrib_list) const {
    WRAP(fStreamPostD3DTextureANGLE(dpy, stream, texture, attrib_list));
  }

  // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
  EGLBoolean fSwapBuffersWithDamage(EGLDisplay dpy, EGLSurface surface,
                                    const EGLint* rects, EGLint n_rects) {
    WRAP(fSwapBuffersWithDamage(dpy, surface, rects, n_rects));
  }

  // EGL_KHR_partial_update
  EGLBoolean fSetDamageRegion(EGLDisplay dpy, EGLSurface surface,
                              const EGLint* rects, EGLint n_rects) {
    WRAP(fSetDamageRegion(dpy, surface, rects, n_rects));
  }
  // EGL_MESA_image_dma_buf_export
  EGLBoolean fExportDMABUFImageQuery(EGLDisplay dpy, EGLImage image,
                                     int* fourcc, int* num_planes,
                                     uint64_t* modifiers) {
    WRAP(
        fExportDMABUFImageQueryMESA(dpy, image, fourcc, num_planes, modifiers));
  }
  EGLBoolean fExportDMABUFImage(EGLDisplay dpy, EGLImage image, int* fds,
                                EGLint* strides, EGLint* offsets) {
    WRAP(fExportDMABUFImageMESA(dpy, image, fds, strides, offsets));
  }

 public:
  // EGL_EXT_device_enumeration
  EGLBoolean fQueryDevicesEXT(EGLint max_devices, EGLDeviceEXT* devices,
                              EGLint* num_devices) {
    WRAP(fQueryDevicesEXT(max_devices, devices, num_devices));
  }

#undef WRAP

#undef WRAP
#undef PROFILE_CALL
#undef BEFORE_CALL
#undef AFTER_CALL
#undef MOZ_FUNCTION_NAME

  ////

 private:
  struct {
    EGLCastToRelevantPtr(GLAPIENTRY* fGetProcAddress)(const char* procname);
    EGLDisplay(GLAPIENTRY* fGetDisplay)(void* display_id);
    EGLDisplay(GLAPIENTRY* fGetPlatformDisplay)(EGLenum platform,
                                                void* native_display,
                                                const EGLAttrib* attrib_list);
    EGLBoolean(GLAPIENTRY* fTerminate)(EGLDisplay dpy);
    EGLSurface(GLAPIENTRY* fGetCurrentSurface)(EGLint);
    EGLContext(GLAPIENTRY* fGetCurrentContext)(void);
    EGLBoolean(GLAPIENTRY* fMakeCurrent)(EGLDisplay dpy, EGLSurface draw,
                                         EGLSurface read, EGLContext ctx);
    EGLBoolean(GLAPIENTRY* fDestroyContext)(EGLDisplay dpy, EGLContext ctx);
    EGLContext(GLAPIENTRY* fCreateContext)(EGLDisplay dpy, EGLConfig config,
                                           EGLContext share_context,
                                           const EGLint* attrib_list);
    EGLBoolean(GLAPIENTRY* fDestroySurface)(EGLDisplay dpy, EGLSurface surface);
    EGLSurface(GLAPIENTRY* fCreateWindowSurface)(EGLDisplay dpy,
                                                 EGLConfig config,
                                                 EGLNativeWindowType win,
                                                 const EGLint* attrib_list);
    EGLSurface(GLAPIENTRY* fCreatePbufferSurface)(EGLDisplay dpy,
                                                  EGLConfig config,
                                                  const EGLint* attrib_list);
    EGLSurface(GLAPIENTRY* fCreatePbufferFromClientBuffer)(
        EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
        EGLConfig config, const EGLint* attrib_list);
    EGLSurface(GLAPIENTRY* fCreatePixmapSurface)(EGLDisplay dpy,
                                                 EGLConfig config,
                                                 EGLNativePixmapType pixmap,
                                                 const EGLint* attrib_list);
    EGLBoolean(GLAPIENTRY* fBindAPI)(EGLenum api);
    EGLBoolean(GLAPIENTRY* fInitialize)(EGLDisplay dpy, EGLint* major,
                                        EGLint* minor);
    EGLBoolean(GLAPIENTRY* fChooseConfig)(EGLDisplay dpy,
                                          const EGLint* attrib_list,
                                          EGLConfig* configs,
                                          EGLint config_size,
                                          EGLint* num_config);
    EGLint(GLAPIENTRY* fGetError)(void);
    EGLBoolean(GLAPIENTRY* fGetConfigAttrib)(EGLDisplay dpy, EGLConfig config,
                                             EGLint attribute, EGLint* value);
    EGLBoolean(GLAPIENTRY* fGetConfigs)(EGLDisplay dpy, EGLConfig* configs,
                                        EGLint config_size, EGLint* num_config);
    EGLBoolean(GLAPIENTRY* fWaitNative)(EGLint engine);
    EGLBoolean(GLAPIENTRY* fSwapBuffers)(EGLDisplay dpy, EGLSurface surface);
    EGLBoolean(GLAPIENTRY* fCopyBuffers)(EGLDisplay dpy, EGLSurface surface,
                                         EGLNativePixmapType target);
    const GLubyte*(GLAPIENTRY* fQueryString)(EGLDisplay, EGLint name);
    EGLBoolean(GLAPIENTRY* fQueryContext)(EGLDisplay dpy, EGLContext ctx,
                                          EGLint attribute, EGLint* value);
    EGLBoolean(GLAPIENTRY* fBindTexImage)(EGLDisplay, EGLSurface surface,
                                          EGLint buffer);
    EGLBoolean(GLAPIENTRY* fReleaseTexImage)(EGLDisplay, EGLSurface surface,
                                             EGLint buffer);
    EGLBoolean(GLAPIENTRY* fSwapInterval)(EGLDisplay dpy, EGLint interval);
    EGLImage(GLAPIENTRY* fCreateImageKHR)(EGLDisplay dpy, EGLContext ctx,
                                          EGLenum target,
                                          EGLClientBuffer buffer,
                                          const EGLint* attrib_list);
    EGLBoolean(GLAPIENTRY* fDestroyImageKHR)(EGLDisplay dpy, EGLImage image);
    EGLBoolean(GLAPIENTRY* fQuerySurface)(EGLDisplay dpy, EGLSurface surface,
                                          EGLint attribute, EGLint* value);
    EGLBoolean(GLAPIENTRY* fQuerySurfacePointerANGLE)(EGLDisplay dpy,
                                                      EGLSurface surface,
                                                      EGLint attribute,
                                                      void** value);
    EGLSync(GLAPIENTRY* fCreateSyncKHR)(EGLDisplay dpy, EGLenum type,
                                        const EGLint* attrib_list);
    EGLBoolean(GLAPIENTRY* fDestroySyncKHR)(EGLDisplay dpy, EGLSync sync);
    EGLint(GLAPIENTRY* fClientWaitSyncKHR)(EGLDisplay dpy, EGLSync sync,
                                           EGLint flags, EGLTime timeout);
    EGLBoolean(GLAPIENTRY* fGetSyncAttribKHR)(EGLDisplay dpy, EGLSync sync,
                                              EGLint attribute, EGLint* value);
    EGLint(GLAPIENTRY* fWaitSyncKHR)(EGLDisplay dpy, EGLSync sync,
                                     EGLint flags);
    EGLint(GLAPIENTRY* fDupNativeFenceFDANDROID)(EGLDisplay dpy, EGLSync sync);
    // KHR_stream
    EGLStreamKHR(GLAPIENTRY* fCreateStreamKHR)(EGLDisplay dpy,
                                               const EGLint* attrib_list);
    EGLBoolean(GLAPIENTRY* fDestroyStreamKHR)(EGLDisplay dpy,
                                              EGLStreamKHR stream);
    EGLBoolean(GLAPIENTRY* fQueryStreamKHR)(EGLDisplay dpy, EGLStreamKHR stream,
                                            EGLenum attribute, EGLint* value);
    // KHR_stream_consumer_gltexture
    EGLBoolean(GLAPIENTRY* fStreamConsumerGLTextureExternalKHR)(
        EGLDisplay dpy, EGLStreamKHR stream);
    EGLBoolean(GLAPIENTRY* fStreamConsumerAcquireKHR)(EGLDisplay dpy,
                                                      EGLStreamKHR stream);
    EGLBoolean(GLAPIENTRY* fStreamConsumerReleaseKHR)(EGLDisplay dpy,
                                                      EGLStreamKHR stream);
    // EXT_device_query
    EGLBoolean(GLAPIENTRY* fQueryDisplayAttribEXT)(EGLDisplay dpy,
                                                   EGLint attribute,
                                                   EGLAttrib* value);
    EGLBoolean(GLAPIENTRY* fQueryDeviceAttribEXT)(EGLDeviceEXT device,
                                                  EGLint attribute,
                                                  EGLAttrib* value);
    const char*(GLAPIENTRY* fQueryDeviceStringEXT)(EGLDeviceEXT device,
                                                   EGLint name);

    // NV_stream_consumer_gltexture_yuv
    EGLBoolean(GLAPIENTRY* fStreamConsumerGLTextureExternalAttribsNV)(
        EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list);
    // ANGLE_stream_producer_d3d_texture
    EGLBoolean(GLAPIENTRY* fCreateStreamProducerD3DTextureANGLE)(
        EGLDisplay dpy, EGLStreamKHR stream, const EGLAttrib* attrib_list);
    EGLBoolean(GLAPIENTRY* fStreamPostD3DTextureANGLE)(
        EGLDisplay dpy, EGLStreamKHR stream, void* texture,
        const EGLAttrib* attrib_list);
    // ANGLE_device_creation
    EGLDeviceEXT(GLAPIENTRY* fCreateDeviceANGLE)(EGLint device_type,
                                                 void* native_device,
                                                 const EGLAttrib* attrib_list);
    EGLBoolean(GLAPIENTRY* fReleaseDeviceANGLE)(EGLDeviceEXT device);
    // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
    EGLBoolean(GLAPIENTRY* fSwapBuffersWithDamage)(EGLDisplay dpy,
                                                   EGLSurface surface,
                                                   const EGLint* rects,
                                                   EGLint n_rects);
    // EGL_KHR_partial_update
    EGLBoolean(GLAPIENTRY* fSetDamageRegion)(EGLDisplay dpy, EGLSurface surface,
                                             const EGLint* rects,
                                             EGLint n_rects);
    EGLClientBuffer(GLAPIENTRY* fGetNativeClientBufferANDROID)(
        const struct AHardwareBuffer* buffer);

    // EGL_MESA_image_dma_buf_export
    EGLBoolean(GLAPIENTRY* fExportDMABUFImageQueryMESA)(EGLDisplay dpy,
                                                        EGLImage image,
                                                        int* fourcc,
                                                        int* num_planes,
                                                        uint64_t* modifiers);
    EGLBoolean(GLAPIENTRY* fExportDMABUFImageMESA)(EGLDisplay dpy,
                                                   EGLImage image, int* fds,
                                                   EGLint* strides,
                                                   EGLint* offsets);

    EGLBoolean(GLAPIENTRY* fQueryDevicesEXT)(EGLint max_devices,
                                             EGLDeviceEXT* devices,
                                             EGLint* num_devices);

  } mSymbols = {};
};

class EglDisplay final {
 public:
  const RefPtr<GLLibraryEGL> mLib;
  const EGLDisplay mDisplay;
  const bool mIsWARP;

 private:
  std::bitset<UnderlyingValue(EGLExtension::Max)> mAvailableExtensions;

  bool mShouldLeakEGLDisplay = false;

  struct PrivateUseOnly final {};

 public:
  static std::shared_ptr<EglDisplay> Create(
      GLLibraryEGL&, EGLDisplay, bool isWarp,
      const StaticMutexAutoLock& aProofOfLock);

  // Only `public` for make_shared.
  EglDisplay(const PrivateUseOnly&, GLLibraryEGL&, EGLDisplay, bool isWarp);

 public:
  ~EglDisplay();

  bool IsExtensionSupported(EGLExtension aKnownExtension) const {
    return mAvailableExtensions[UnderlyingValue(aKnownExtension)];
  }

  void MarkExtensionUnsupported(EGLExtension aKnownExtension) {
    mAvailableExtensions[UnderlyingValue(aKnownExtension)] = false;
  }

  void DumpEGLConfig(EGLConfig) const;
  void DumpEGLConfigs() const;

  // When called, ensure we deliberately leak the EGLDisplay rather than call
  // eglTerminate. Used as a workaround on buggy drivers.
  void SetShouldLeakEGLDisplay() { mShouldLeakEGLDisplay = true; }

  void Shutdown();

  // -

  bool HasKHRImageBase() const {
    return IsExtensionSupported(EGLExtension::KHR_image) ||
           IsExtensionSupported(EGLExtension::KHR_image_base);
  }

  bool HasKHRImagePixmap() const {
    return IsExtensionSupported(EGLExtension::KHR_image) ||
           IsExtensionSupported(EGLExtension::KHR_image_pixmap);
  }

  // -

  EGLBoolean fTerminate() {
    if (mShouldLeakEGLDisplay) {
      return LOCAL_EGL_TRUE;
    }
    return mLib->fTerminate(mDisplay);
  }

  EGLBoolean fMakeCurrent(EGLSurface draw, EGLSurface read,
                          EGLContext ctx) const {
    return mLib->fMakeCurrent(mDisplay, draw, read, ctx);
  }

  EGLBoolean fDestroyContext(EGLContext ctx) const {
    return mLib->fDestroyContext(mDisplay, ctx);
  }

  EGLContext fCreateContext(EGLConfig config, EGLContext share_context,
                            const EGLint* attrib_list) const {
    return mLib->fCreateContext(mDisplay, config, share_context, attrib_list);
  }

  EGLBoolean fDestroySurface(EGLSurface surface) const {
    return mLib->fDestroySurface(mDisplay, surface);
  }

  EGLSurface fCreateWindowSurface(EGLConfig config, EGLNativeWindowType win,
                                  const EGLint* attrib_list) const {
    return mLib->fCreateWindowSurface(mDisplay, config, win, attrib_list);
  }

  EGLSurface fCreatePbufferSurface(EGLConfig config,
                                   const EGLint* attrib_list) const {
    return mLib->fCreatePbufferSurface(mDisplay, config, attrib_list);
  }

  EGLSurface fCreatePbufferFromClientBuffer(EGLenum buftype,
                                            EGLClientBuffer buffer,
                                            EGLConfig config,
                                            const EGLint* attrib_list) const {
    return mLib->fCreatePbufferFromClientBuffer(mDisplay, buftype, buffer,
                                                config, attrib_list);
  }

  EGLBoolean fChooseConfig(const EGLint* attrib_list, EGLConfig* configs,
                           EGLint config_size, EGLint* num_config) const {
    return mLib->fChooseConfig(mDisplay, attrib_list, configs, config_size,
                               num_config);
  }

  EGLBoolean fGetConfigAttrib(EGLConfig config, EGLint attribute,
                              EGLint* value) const {
    return mLib->fGetConfigAttrib(mDisplay, config, attribute, value);
  }

  EGLBoolean fGetConfigs(EGLConfig* configs, EGLint config_size,
                         EGLint* num_config) const {
    return mLib->fGetConfigs(mDisplay, configs, config_size, num_config);
  }

  EGLBoolean fSwapBuffers(EGLSurface surface) const {
    return mLib->fSwapBuffers(mDisplay, surface);
  }

  EGLBoolean fBindTexImage(EGLSurface surface, EGLint buffer) const {
    return mLib->fBindTexImage(mDisplay, surface, buffer);
  }

  EGLBoolean fReleaseTexImage(EGLSurface surface, EGLint buffer) const {
    return mLib->fReleaseTexImage(mDisplay, surface, buffer);
  }

  EGLBoolean fSwapInterval(EGLint interval) const {
    return mLib->fSwapInterval(mDisplay, interval);
  }

  EGLImage fCreateImage(EGLContext ctx, EGLenum target, EGLClientBuffer buffer,
                        const EGLint* attribList) const {
    MOZ_ASSERT(HasKHRImageBase());
    return mLib->fCreateImage(mDisplay, ctx, target, buffer, attribList);
  }

  EGLBoolean fDestroyImage(EGLImage image) const {
    MOZ_ASSERT(HasKHRImageBase());
    return mLib->fDestroyImage(mDisplay, image);
  }

  EGLBoolean fQuerySurface(EGLSurface surface, EGLint attribute,
                           EGLint* value) const {
    return mLib->fQuerySurface(mDisplay, surface, attribute, value);
  }

  EGLBoolean fQuerySurfacePointerANGLE(EGLSurface surface, EGLint attribute,
                                       void** value) const {
    MOZ_ASSERT(IsExtensionSupported(
        EGLExtension::ANGLE_surface_d3d_texture_2d_share_handle));
    return mLib->fQuerySurfacePointerANGLE(mDisplay, surface, attribute, value);
  }

  EGLSync fCreateSync(EGLenum type, const EGLint* attrib_list) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync));
    return mLib->fCreateSync(mDisplay, type, attrib_list);
  }

  EGLBoolean fDestroySync(EGLSync sync) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync));
    return mLib->fDestroySync(mDisplay, sync);
  }

  EGLint fClientWaitSync(EGLSync sync, EGLint flags, EGLTime timeout) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync));
    return mLib->fClientWaitSync(mDisplay, sync, flags, timeout);
  }

  EGLBoolean fGetSyncAttrib(EGLSync sync, EGLint attribute,
                            EGLint* value) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_fence_sync));
    return mLib->fGetSyncAttrib(mDisplay, sync, attribute, value);
  }

  EGLint fWaitSync(EGLSync sync, EGLint flags) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_wait_sync));
    return mLib->fWaitSync(mDisplay, sync, flags);
  }

  EGLint fDupNativeFenceFDANDROID(EGLSync sync) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::ANDROID_native_fence_sync));
    return mLib->fDupNativeFenceFDANDROID(mDisplay, sync);
  }

  // EXT_device_query
  EGLBoolean fQueryDisplayAttribEXT(EGLint attribute, EGLAttrib* value) const {
    MOZ_ASSERT(mLib->IsExtensionSupported(EGLLibExtension::EXT_device_query));
    return mLib->fQueryDisplayAttribEXT(mDisplay, attribute, value);
  }

  // KHR_stream
  EGLStreamKHR fCreateStreamKHR(const EGLint* attrib_list) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_stream));
    return mLib->fCreateStreamKHR(mDisplay, attrib_list);
  }

  EGLBoolean fDestroyStreamKHR(EGLStreamKHR stream) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_stream));
    return mLib->fDestroyStreamKHR(mDisplay, stream);
  }

  EGLBoolean fQueryStreamKHR(EGLStreamKHR stream, EGLenum attribute,
                             EGLint* value) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_stream));
    return mLib->fQueryStreamKHR(mDisplay, stream, attribute, value);
  }

  // KHR_stream_consumer_gltexture
  EGLBoolean fStreamConsumerGLTextureExternalKHR(EGLStreamKHR stream) const {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture));
    return mLib->fStreamConsumerGLTextureExternalKHR(mDisplay, stream);
  }

  EGLBoolean fStreamConsumerAcquireKHR(EGLStreamKHR stream) const {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture));
    return mLib->fStreamConsumerAcquireKHR(mDisplay, stream);
  }

  EGLBoolean fStreamConsumerReleaseKHR(EGLStreamKHR stream) const {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::KHR_stream_consumer_gltexture));
    return mLib->fStreamConsumerReleaseKHR(mDisplay, stream);
  }

  // NV_stream_consumer_gltexture_yuv
  EGLBoolean fStreamConsumerGLTextureExternalAttribsNV(
      EGLStreamKHR stream, const EGLAttrib* attrib_list) const {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::NV_stream_consumer_gltexture_yuv));
    return mLib->fStreamConsumerGLTextureExternalAttribsNV(mDisplay, stream,
                                                           attrib_list);
  }

  // ANGLE_stream_producer_d3d_texture
  EGLBoolean fCreateStreamProducerD3DTextureANGLE(
      EGLStreamKHR stream, const EGLAttrib* attrib_list) const {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::ANGLE_stream_producer_d3d_texture));
    return mLib->fCreateStreamProducerD3DTextureANGLE(mDisplay, stream,
                                                      attrib_list);
  }

  EGLBoolean fStreamPostD3DTextureANGLE(EGLStreamKHR stream, void* texture,
                                        const EGLAttrib* attrib_list) const {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::ANGLE_stream_producer_d3d_texture));
    return mLib->fStreamPostD3DTextureANGLE(mDisplay, stream, texture,
                                            attrib_list);
  }

  // EGL_EXT_swap_buffers_with_damage / EGL_KHR_swap_buffers_with_damage
  EGLBoolean fSwapBuffersWithDamage(EGLSurface surface, const EGLint* rects,
                                    EGLint n_rects) {
    MOZ_ASSERT(
        IsExtensionSupported(EGLExtension::EXT_swap_buffers_with_damage) ||
        IsExtensionSupported(EGLExtension::KHR_swap_buffers_with_damage));
    return mLib->fSwapBuffersWithDamage(mDisplay, surface, rects, n_rects);
  }

  // EGL_KHR_partial_update
  EGLBoolean fSetDamageRegion(EGLSurface surface, const EGLint* rects,
                              EGLint n_rects) {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::KHR_partial_update));
    return mLib->fSetDamageRegion(mDisplay, surface, rects, n_rects);
  }

  EGLBoolean fExportDMABUFImageQuery(EGLImage image, int* fourcc,
                                     int* num_planes,
                                     uint64_t* modifiers) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export));
    return mLib->fExportDMABUFImageQuery(mDisplay, image, fourcc, num_planes,
                                         modifiers);
  }
  EGLBoolean fExportDMABUFImage(EGLImage image, int* fds, EGLint* strides,
                                EGLint* offsets) const {
    MOZ_ASSERT(IsExtensionSupported(EGLExtension::MESA_image_dma_buf_export));
    return mLib->fExportDMABUFImage(mDisplay, image, fds, strides, offsets);
  }
};

/* namespace gl */
/* namespace mozilla */

#endif /* GLLIBRARYEGL_H_ */

Messung V0.5
C=96 H=98 G=96

¤ Dauer der Verarbeitung: 0.18 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.