Revert of [1]+[2] from [3] for [4][5] [1] https://github.com/qt/qtwebengine/commit/ddcd30454a [2] https://github.com/qt/qtwebengine/commit/9168bc6f53 [3] https://bugreports.qt.io/browse/QTBUG-136257 [4] https://bugreports.qt.io/browse/QTBUG-139424 [5] https://bugs.gentoo.org/962055 --- a/src/core/ozone/egl_helper.cpp +++ b/src/core/ozone/egl_helper.cpp @@ -7,5 +7,7 @@ #include "web_engine_context.h" +#include #include +#include #include #include @@ -58,4 +60,82 @@ QT_BEGIN_NAMESPACE +class ScopedGLContext +{ +public: + ScopedGLContext(QOffscreenSurface *surface, EGLHelper::EGLFunctions *eglFun) + : m_context(new QOpenGLContext()), m_eglFun(eglFun) + { + if ((m_previousEGLContext = m_eglFun->eglGetCurrentContext())) { + m_previousEGLDrawSurface = m_eglFun->eglGetCurrentSurface(EGL_DRAW); + m_previousEGLReadSurface = m_eglFun->eglGetCurrentSurface(EGL_READ); + m_previousEGLDisplay = m_eglFun->eglGetCurrentDisplay(); + } + + if (!m_context->create()) { + qWarning("Failed to create OpenGL context."); + return; + } + + Q_ASSERT(surface->isValid()); + if (!m_context->makeCurrent(surface)) { + qWarning("Failed to make OpenGL context current."); + return; + } + } + + ~ScopedGLContext() + { + if (!m_textures.empty()) { + auto *glFun = m_context->functions(); + glFun->glDeleteTextures(m_textures.size(), m_textures.data()); + } + + if (m_previousEGLContext) { + // Make sure the scoped context is not current when restoring the previous + // EGL context otherwise the QOpenGLContext destructor resets the restored + // current context. + m_context->doneCurrent(); + + m_eglFun->eglMakeCurrent(m_previousEGLDisplay, m_previousEGLDrawSurface, + m_previousEGLReadSurface, m_previousEGLContext); + if (m_eglFun->eglGetError() != EGL_SUCCESS) + qWarning("Failed to restore EGL context."); + } + } + + bool isValid() const { return m_context->isValid() && (m_context->surface() != nullptr); } + + EGLContext eglContext() const + { + QNativeInterface::QEGLContext *nativeInterface = + m_context->nativeInterface(); + return nativeInterface->nativeContext(); + } + + uint createTexture(int width, int height) + { + auto *glFun = m_context->functions(); + + uint glTexture; + glFun->glGenTextures(1, &glTexture); + glFun->glBindTexture(GL_TEXTURE_2D, glTexture); + glFun->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + NULL); + glFun->glBindTexture(GL_TEXTURE_2D, 0); + + m_textures.push_back(glTexture); + return glTexture; + } + +private: + QScopedPointer m_context; + EGLHelper::EGLFunctions *m_eglFun; + EGLContext m_previousEGLContext = nullptr; + EGLSurface m_previousEGLDrawSurface = nullptr; + EGLSurface m_previousEGLReadSurface = nullptr; + EGLDisplay m_previousEGLDisplay = nullptr; + std::vector m_textures; +}; + EGLHelper::EGLFunctions::EGLFunctions() { @@ -64,6 +144,4 @@ eglCreateImage = reinterpret_cast(context->getProcAddress("eglCreateImage")); - eglCreateDRMImageMESA = reinterpret_cast( - context->getProcAddress("eglCreateDRMImageMESA")); eglDestroyImage = reinterpret_cast(context->getProcAddress("eglDestroyImage")); @@ -94,4 +172,5 @@ : m_eglDisplay(qApp->platformNativeInterface()->nativeResourceForIntegration("egldisplay")) , m_functions(new EGLHelper::EGLFunctions()) + , m_offscreenSurface(new QOffscreenSurface()) { const char *extensions = m_functions->eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS); @@ -111,4 +190,7 @@ } + Q_ASSERT(QThread::currentThread() == qApp->thread()); + m_offscreenSurface->create(); + m_isDmaBufSupported = QtWebEngineCore::WebEngineContext::isGbmSupported(); @@ -118,5 +200,4 @@ m_isDmaBufSupported = strstr(displayExtensions, "EGL_EXT_image_dma_buf_import") && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers") - && strstr(displayExtensions, "EGL_MESA_drm_image") && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export"); } @@ -139,15 +220,17 @@ return; - // clang-format off - EGLint attribs[] = { - EGL_WIDTH, width, - EGL_HEIGHT, height, - EGL_DRM_BUFFER_FORMAT_MESA, EGL_DRM_BUFFER_FORMAT_ARGB32_MESA, - EGL_DRM_BUFFER_USE_MESA, EGL_DRM_BUFFER_USE_SHARE_MESA, - EGL_NONE - }; - // clang-format on + ScopedGLContext context(m_offscreenSurface.get(), m_functions.get()); + if (!context.isValid()) + return; + + EGLContext eglContext = context.eglContext(); + if (!eglContext) { + qWarning("EGL: No EGLContext."); + return; + } - EGLImage eglImage = m_functions->eglCreateDRMImageMESA(m_eglDisplay, attribs); + uint64_t textureId = context.createTexture(width, height); + EGLImage eglImage = m_functions->eglCreateImage(m_eglDisplay, eglContext, EGL_GL_TEXTURE_2D, + (EGLClientBuffer)textureId, NULL); if (eglImage == EGL_NO_IMAGE) { qWarning("EGL: Failed to create EGLImage: %s", getLastEGLErrorString()); --- a/src/core/ozone/egl_helper.h +++ b/src/core/ozone/egl_helper.h @@ -13,5 +13,4 @@ #undef eglCreateImage -#undef eglCreateDRMImageMESA #undef eglDestroyImage #undef eglExportDMABUFImageMESA @@ -26,4 +25,6 @@ QT_BEGIN_NAMESPACE +class QOffscreenSurface; + class EGLHelper { @@ -34,5 +35,4 @@ PFNEGLCREATEIMAGEPROC eglCreateImage; - PFNEGLCREATEDRMIMAGEMESAPROC eglCreateDRMImageMESA; PFNEGLDESTROYIMAGEPROC eglDestroyImage; PFNEGLEXPORTDMABUFIMAGEMESAPROC eglExportDMABUFImageMESA; @@ -60,4 +60,5 @@ EGLDisplay m_eglDisplay = EGL_NO_DISPLAY; QScopedPointer m_functions; + QScopedPointer m_offscreenSurface; bool m_isDmaBufSupported = false; };