Revert of [1] from [2] for [3][4] [1] https://github.com/qt/qtwebengine/commit/812bf186b15 [2] https://bugreports.qt.io/browse/QTBUG-136257 [3] https://bugreports.qt.io/browse/QTBUG-139424 [4] https://bugs.gentoo.org/962055 --- a/src/core/ozone/egl_helper.cpp +++ b/src/core/ozone/egl_helper.cpp @@ -60,2 +60,80 @@ +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() @@ -66,4 +144,2 @@ reinterpret_cast(context->getProcAddress("eglCreateImage")); - eglCreateDRMImageMESA = reinterpret_cast( - context->getProcAddress("eglCreateDRMImageMESA")); eglDestroyImage = @@ -124,3 +200,2 @@ && strstr(displayExtensions, "EGL_EXT_image_dma_buf_import_modifiers") - && strstr(displayExtensions, "EGL_MESA_drm_image") && strstr(displayExtensions, "EGL_MESA_image_dma_buf_export"); @@ -145,13 +220,15 @@ - // 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) { --- a/src/core/ozone/egl_helper.h +++ b/src/core/ozone/egl_helper.h @@ -13,3 +13,2 @@ #undef eglCreateImage -#undef eglCreateDRMImageMESA #undef eglDestroyImage @@ -36,3 +35,2 @@ PFNEGLCREATEIMAGEPROC eglCreateImage; - PFNEGLCREATEDRMIMAGEMESAPROC eglCreateDRMImageMESA; PFNEGLDESTROYIMAGEPROC eglDestroyImage;