diff --git a/src/opengl/egldisplay.cpp b/src/opengl/egldisplay.cpp index b9378e343b..6960ded844 100644 --- a/src/opengl/egldisplay.cpp +++ b/src/opengl/egldisplay.cpp @@ -79,8 +79,13 @@ EglDisplay::EglDisplay(::EGLDisplay display, const QList &extensions , m_owning(owning) , m_supportsBufferAge(extensions.contains(QByteArrayLiteral("EGL_EXT_buffer_age")) && qgetenv("KWIN_USE_BUFFER_AGE") != "0") , m_supportsNativeFence(extensions.contains(QByteArrayLiteral("EGL_ANDROID_native_fence_sync"))) - , m_importFormats(queryImportFormats()) { + m_functions.createImageKHR = reinterpret_cast(eglGetProcAddress("eglCreateImageKHR")); + m_functions.destroyImageKHR = reinterpret_cast(eglGetProcAddress("eglDestroyImageKHR")); + m_functions.queryDmaBufFormatsEXT = reinterpret_cast(eglGetProcAddress("eglQueryDmaBufFormatsEXT")); + m_functions.queryDmaBufModifiersEXT = reinterpret_cast(eglGetProcAddress("eglQueryDmaBufModifiersEXT")); + + m_importFormats = queryImportFormats(); } EglDisplay::~EglDisplay() @@ -212,7 +217,7 @@ EGLImageKHR EglDisplay::importDmaBufAsImage(const DmaBufAttributes &dmabuf) cons attribs << EGL_NONE; - return eglCreateImageKHR(m_handle, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data()); + return createImage(EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data()); } EGLImageKHR EglDisplay::importDmaBufAsImage(const DmaBufAttributes &dmabuf, int plane, int format, const QSize &size) const @@ -233,7 +238,7 @@ EGLImageKHR EglDisplay::importDmaBufAsImage(const DmaBufAttributes &dmabuf, int } attribs << EGL_NONE; - return eglCreateImageKHR(m_handle, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data()); + return createImage(EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, nullptr, attribs.data()); } QHash EglDisplay::allSupportedDrmFormats() const @@ -266,37 +271,31 @@ QHash EglDisplay::queryImportFormats() cons return {}; } - typedef EGLBoolean (*eglQueryDmaBufFormatsEXT_func)(EGLDisplay dpy, EGLint max_formats, EGLint *formats, EGLint *num_formats); - typedef EGLBoolean (*eglQueryDmaBufModifiersEXT_func)(EGLDisplay dpy, EGLint format, EGLint max_modifiers, EGLuint64KHR *modifiers, EGLBoolean *external_only, EGLint *num_modifiers); - eglQueryDmaBufFormatsEXT_func eglQueryDmaBufFormatsEXT = nullptr; - eglQueryDmaBufModifiersEXT_func eglQueryDmaBufModifiersEXT = nullptr; - eglQueryDmaBufFormatsEXT = (eglQueryDmaBufFormatsEXT_func)eglGetProcAddress("eglQueryDmaBufFormatsEXT"); - eglQueryDmaBufModifiersEXT = (eglQueryDmaBufModifiersEXT_func)eglGetProcAddress("eglQueryDmaBufModifiersEXT"); - if (eglQueryDmaBufFormatsEXT == nullptr) { + if (m_functions.queryDmaBufFormatsEXT == nullptr) { return {}; } EGLint count = 0; - EGLBoolean success = eglQueryDmaBufFormatsEXT(m_handle, 0, nullptr, &count); + EGLBoolean success = m_functions.queryDmaBufFormatsEXT(m_handle, 0, nullptr, &count); if (!success || count == 0) { qCCritical(KWIN_OPENGL) << "eglQueryDmaBufFormatsEXT failed!" << getEglErrorString(); return {}; } QList formats(count); - if (!eglQueryDmaBufFormatsEXT(m_handle, count, (EGLint *)formats.data(), &count)) { + if (!m_functions.queryDmaBufFormatsEXT(m_handle, count, (EGLint *)formats.data(), &count)) { qCCritical(KWIN_OPENGL) << "eglQueryDmaBufFormatsEXT with count" << count << "failed!" << getEglErrorString(); return {}; } QHash ret; for (const auto format : std::as_const(formats)) { - if (eglQueryDmaBufModifiersEXT != nullptr) { + if (m_functions.queryDmaBufModifiersEXT != nullptr) { EGLint count = 0; - const EGLBoolean success = eglQueryDmaBufModifiersEXT(m_handle, format, 0, nullptr, nullptr, &count); + const EGLBoolean success = m_functions.queryDmaBufModifiersEXT(m_handle, format, 0, nullptr, nullptr, &count); if (success && count > 0) { DrmFormatInfo drmFormatInfo; drmFormatInfo.allModifiers.resize(count); QList externalOnly(count); - if (eglQueryDmaBufModifiersEXT(m_handle, format, count, drmFormatInfo.allModifiers.data(), externalOnly.data(), &count)) { + if (m_functions.queryDmaBufModifiersEXT(m_handle, format, count, drmFormatInfo.allModifiers.data(), externalOnly.data(), &count)) { drmFormatInfo.externalOnlyModifiers = drmFormatInfo.allModifiers; drmFormatInfo.nonExternalOnlyModifiers = drmFormatInfo.allModifiers; for (int i = drmFormatInfo.allModifiers.size() - 1; i >= 0; i--) { @@ -325,4 +324,15 @@ QHash EglDisplay::queryImportFormats() cons return ret; } +EGLImageKHR EglDisplay::createImage(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) const +{ + Q_ASSERT(m_functions.createImageKHR); + return m_functions.createImageKHR(m_handle, ctx, target, buffer, attrib_list); +} + +void EglDisplay::destroyImage(EGLImageKHR image) const +{ + Q_ASSERT(m_functions.destroyImageKHR); + m_functions.destroyImageKHR(m_handle, image); +} } diff --git a/src/opengl/egldisplay.h b/src/opengl/egldisplay.h index c55fe9c942..1de350916f 100644 --- a/src/opengl/egldisplay.h +++ b/src/opengl/egldisplay.h @@ -48,6 +48,9 @@ public: QHash allSupportedDrmFormats() const; bool isExternalOnly(uint32_t format, uint64_t modifier) const; + EGLImageKHR createImage(EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) const; + void destroyImage(EGLImageKHR image) const; + EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &dmabuf) const; EGLImageKHR importDmaBufAsImage(const DmaBufAttributes &dmabuf, int plane, int format, const QSize &size) const; @@ -62,7 +65,16 @@ private: const bool m_supportsBufferAge; const bool m_supportsNativeFence; - const QHash m_importFormats; + QHash m_importFormats; + + struct + { + PFNEGLCREATEIMAGEKHRPROC createImageKHR = nullptr; + PFNEGLDESTROYIMAGEKHRPROC destroyImageKHR = nullptr; + + PFNEGLQUERYDMABUFFORMATSEXTPROC queryDmaBufFormatsEXT = nullptr; + PFNEGLQUERYDMABUFMODIFIERSEXTPROC queryDmaBufModifiersEXT = nullptr; + } m_functions; }; } diff --git a/src/opengl/eglimagetexture.cpp b/src/opengl/eglimagetexture.cpp index b2bed6197b..1701337325 100644 --- a/src/opengl/eglimagetexture.cpp +++ b/src/opengl/eglimagetexture.cpp @@ -26,7 +26,7 @@ EGLImageTexture::EGLImageTexture(EglDisplay *display, EGLImage image, uint textu EGLImageTexture::~EGLImageTexture() { - eglDestroyImageKHR(m_display->handle(), m_image); + m_display->destroyImage(m_image); } std::shared_ptr EGLImageTexture::create(EglDisplay *display, EGLImageKHR image, int internalFormat, const QSize &size, bool externalOnly) diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index 4b4ae68f5d..d955e2f559 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -82,7 +82,7 @@ void AbstractEglBackend::teardown() void AbstractEglBackend::cleanup() { for (const EGLImageKHR &image : m_importedBuffers) { - eglDestroyImageKHR(m_display->handle(), image); + m_display->destroyImage(image); } cleanupSurfaces(); @@ -302,7 +302,7 @@ EGLImageKHR AbstractEglBackend::importBufferAsImage(GraphicsBuffer *buffer, int if (image != EGL_NO_IMAGE_KHR) { m_importedBuffers[key] = image; connect(buffer, &QObject::destroyed, this, [this, key]() { - eglDestroyImageKHR(m_display->handle(), m_importedBuffers.take(key)); + m_display->destroyImage(m_importedBuffers.take(key)); }); } else { qCWarning(KWIN_OPENGL) << "failed to import dmabuf" << buffer; @@ -324,7 +324,7 @@ EGLImageKHR AbstractEglBackend::importBufferAsImage(GraphicsBuffer *buffer) if (image != EGL_NO_IMAGE_KHR) { m_importedBuffers[key] = image; connect(buffer, &QObject::destroyed, this, [this, key]() { - eglDestroyImageKHR(m_display->handle(), m_importedBuffers.take(key)); + m_display->destroyImage(m_importedBuffers.take(key)); }); } else { qCWarning(KWIN_OPENGL) << "failed to import dmabuf" << buffer;