Title: [264168] trunk/Source/WebKit
Revision
264168
Author
carlo...@webkit.org
Date
2020-07-09 07:10:06 -0700 (Thu, 09 Jul 2020)

Log Message

[GTK] Add support for shm buffers in AcceleratedBackingStoreWayland when using the WPE renderer
https://bugs.webkit.org/show_bug.cgi?id=214135

Reviewed by Žan Doberšek.

It's available since wpe-fdo 1.7.0. This makes accelerated compositing work in platforms where
EGL_WL_bind_wayland_display is not available. It can also be forced with the environment variable
LIBGL_ALWAYS_SOFTWARE.

* UIProcess/glib/WebProcessPoolGLib.cpp:
(WebKit::WebProcessPool::platformInitializeWebProcess): Use AcceleratedBackingStoreWayland::checkRequirements()
instead of calling wpe_fdo_initialize_for_egl_display() again.
* UIProcess/gtk/AcceleratedBackingStoreWayland.cpp:
(WebKit::tryInitializeEGL): Moved EGL specific initialization here.
(WebKit::tryInitializeSHM): Added SHM initialization.
(WebKit::AcceleratedBackingStoreWayland::checkRequirements): Try to initialize EGL first and then SHM if EGL failed.
(WebKit::AcceleratedBackingStoreWayland::AcceleratedBackingStoreWayland): Create a EGL exportable only when
using EGL implementation.
(WebKit::AcceleratedBackingStoreWayland::~AcceleratedBackingStoreWayland): Release EGL resources only when using
EGL implementation.
(WebKit::AcceleratedBackingStoreWayland::unrealize): Ditto.
(WebKit::AcceleratedBackingStoreWayland::tryEnsureGLContext): Return early when not using EGL implementation.
(WebKit::AcceleratedBackingStoreWayland::update): Add implementation for the SHM case.
(WebKit::AcceleratedBackingStoreWayland::displayImage): Renamed.
(WebKit::AcceleratedBackingStoreWayland::displayBuffer): SHM implementation, copy the shm buffer into a cairo
image surface.
(WebKit::AcceleratedBackingStoreWayland::tryEnsureTexture):
(WebKit::AcceleratedBackingStoreWayland::downloadTexture):
(WebKit::AcceleratedBackingStoreWayland::snapshot): Handle the SHM case.
(WebKit::AcceleratedBackingStoreWayland::paint): Ditto.
* UIProcess/gtk/AcceleratedBackingStoreWayland.h:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (264167 => 264168)


--- trunk/Source/WebKit/ChangeLog	2020-07-09 14:02:14 UTC (rev 264167)
+++ trunk/Source/WebKit/ChangeLog	2020-07-09 14:10:06 UTC (rev 264168)
@@ -1,3 +1,37 @@
+2020-07-09  Carlos Garcia Campos  <cgar...@igalia.com>
+
+        [GTK] Add support for shm buffers in AcceleratedBackingStoreWayland when using the WPE renderer
+        https://bugs.webkit.org/show_bug.cgi?id=214135
+
+        Reviewed by Žan Doberšek.
+
+        It's available since wpe-fdo 1.7.0. This makes accelerated compositing work in platforms where
+        EGL_WL_bind_wayland_display is not available. It can also be forced with the environment variable
+        LIBGL_ALWAYS_SOFTWARE.
+
+        * UIProcess/glib/WebProcessPoolGLib.cpp:
+        (WebKit::WebProcessPool::platformInitializeWebProcess): Use AcceleratedBackingStoreWayland::checkRequirements()
+        instead of calling wpe_fdo_initialize_for_egl_display() again.
+        * UIProcess/gtk/AcceleratedBackingStoreWayland.cpp:
+        (WebKit::tryInitializeEGL): Moved EGL specific initialization here.
+        (WebKit::tryInitializeSHM): Added SHM initialization.
+        (WebKit::AcceleratedBackingStoreWayland::checkRequirements): Try to initialize EGL first and then SHM if EGL failed.
+        (WebKit::AcceleratedBackingStoreWayland::AcceleratedBackingStoreWayland): Create a EGL exportable only when
+        using EGL implementation.
+        (WebKit::AcceleratedBackingStoreWayland::~AcceleratedBackingStoreWayland): Release EGL resources only when using
+        EGL implementation.
+        (WebKit::AcceleratedBackingStoreWayland::unrealize): Ditto.
+        (WebKit::AcceleratedBackingStoreWayland::tryEnsureGLContext): Return early when not using EGL implementation.
+        (WebKit::AcceleratedBackingStoreWayland::update): Add implementation for the SHM case.
+        (WebKit::AcceleratedBackingStoreWayland::displayImage): Renamed.
+        (WebKit::AcceleratedBackingStoreWayland::displayBuffer): SHM implementation, copy the shm buffer into a cairo
+        image surface.
+        (WebKit::AcceleratedBackingStoreWayland::tryEnsureTexture):
+        (WebKit::AcceleratedBackingStoreWayland::downloadTexture):
+        (WebKit::AcceleratedBackingStoreWayland::snapshot): Handle the SHM case.
+        (WebKit::AcceleratedBackingStoreWayland::paint): Ditto.
+        * UIProcess/gtk/AcceleratedBackingStoreWayland.h:
+
 2020-07-09  Commit Queue  <commit-qu...@webkit.org>
 
         Unreviewed, reverting r264148.

Modified: trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp (264167 => 264168)


--- trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp	2020-07-09 14:02:14 UTC (rev 264167)
+++ trunk/Source/WebKit/UIProcess/glib/WebProcessPoolGLib.cpp	2020-07-09 14:10:06 UTC (rev 264168)
@@ -42,7 +42,7 @@
 
 #if PLATFORM(WAYLAND)
 #if USE(WPE_RENDERER)
-#include <wpe/fdo-egl.h>
+#include "AcceleratedBackingStoreWayland.h"
 #else
 #include "WaylandCompositor.h"
 #endif
@@ -116,7 +116,7 @@
     if (WebCore::PlatformDisplay::sharedDisplay().type() == WebCore::PlatformDisplay::Type::Wayland) {
 #if USE(WPE_RENDERER)
         wpe_loader_init("libWPEBackend-fdo-1.0.so");
-        if (wpe_fdo_initialize_for_egl_display(WebCore::PlatformDisplay::sharedDisplay().eglDisplay())) {
+        if (AcceleratedBackingStoreWayland::checkRequirements()) {
             parameters.hostClientFileDescriptor = wpe_renderer_host_create_client();
             parameters.implementationLibraryName = FileSystem::fileSystemRepresentation(wpe_loader_get_loaded_implementation_library_name());
         }

Modified: trunk/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreWayland.cpp (264167 => 264168)


--- trunk/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreWayland.cpp	2020-07-09 14:02:14 UTC (rev 264167)
+++ trunk/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreWayland.cpp	2020-07-09 14:10:06 UTC (rev 264168)
@@ -51,6 +51,10 @@
 
 #if USE(WPE_RENDERER)
 #include <wpe/fdo-egl.h>
+#if WPE_FDO_CHECK_VERSION(1, 7, 0)
+#include <wayland-server.h>
+#include <wpe/unstable/fdo-shm.h>
+#endif
 #else
 #include "WaylandCompositor.h"
 #endif
@@ -66,7 +70,11 @@
 namespace WebKit {
 using namespace WebCore;
 
-bool isEGLImageAvailable(bool useIndexedGetString)
+enum class WaylandImpl { Unsupported, EGL, SHM };
+static Optional<WaylandImpl> s_waylandImpl;
+
+#if USE(WPE_RENDERER)
+static bool isEGLImageAvailable(bool useIndexedGetString)
 {
 #if USE(OPENGL_ES)
     UNUSED_PARAM(useIndexedGetString);
@@ -92,42 +100,71 @@
     return false;
 }
 
-bool AcceleratedBackingStoreWayland::checkRequirements()
+static bool tryInitializeEGL()
 {
-#if USE(WPE_RENDERER)
-    if (!glImageTargetTexture2D) {
-        auto* eglDisplay = PlatformDisplay::sharedDisplay().eglDisplay();
-        const char* extensions = eglQueryString(eglDisplay, EGL_EXTENSIONS);
-        if (!GLContext::isExtensionSupported(extensions, "EGL_WL_bind_wayland_display"))
-            return false;
+    auto* eglDisplay = PlatformDisplay::sharedDisplay().eglDisplay();
+    const char* extensions = eglQueryString(eglDisplay, EGL_EXTENSIONS);
+    if (!GLContext::isExtensionSupported(extensions, "EGL_WL_bind_wayland_display"))
+        return false;
 
-        if (!wpe_fdo_initialize_for_egl_display(eglDisplay))
-            return false;
+    if (!wpe_fdo_initialize_for_egl_display(eglDisplay))
+        return false;
 
-        std::unique_ptr<WebCore::GLContext> eglContext = GLContext::createOffscreenContext();
-        if (!eglContext)
-            return false;
+    std::unique_ptr<WebCore::GLContext> eglContext = GLContext::createOffscreenContext();
+    if (!eglContext)
+        return false;
 
-        if (!eglContext->makeContextCurrent())
-            return false;
+    if (!eglContext->makeContextCurrent())
+        return false;
 
 #if USE(OPENGL_ES)
-        if (isEGLImageAvailable(false))
+    if (isEGLImageAvailable(false))
 #else
-        if (isEGLImageAvailable(GLContext::current()->version() >= 320))
+    if (isEGLImageAvailable(GLContext::current()->version() >= 320))
 #endif
-            glImageTargetTexture2D = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
-    }
+        glImageTargetTexture2D = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
 
-    if (!glImageTargetTexture2D) {
-        WTFLogAlways("AcceleratedBackingStoreWPE requires glEGLImageTargetTexture2D.");
+    if (!glImageTargetTexture2D)
         return false;
-    }
 
+    s_waylandImpl = WaylandImpl::EGL;
     return true;
+}
+
+static bool tryInitializeSHM()
+{
+#if WPE_FDO_CHECK_VERSION(1, 7, 0)
+    if (!wpe_fdo_initialize_shm())
+        return false;
+#endif
+
+    s_waylandImpl = WaylandImpl::SHM;
+    return true;
+}
+#endif // USE(WPE_RENDERER)
+
+bool AcceleratedBackingStoreWayland::checkRequirements()
+{
+#if USE(WPE_RENDERER)
+    if (s_waylandImpl)
+        return s_waylandImpl.value() != WaylandImpl::Unsupported;
+
+    if (tryInitializeEGL())
+        return true;
+
+    if (tryInitializeSHM())
+        return true;
+
+    WTFLogAlways("AcceleratedBackingStoreWayland requires glEGLImageTargetTexture2D or shm interface");
 #else
-    return WaylandCompositor::singleton().isRunning();
+    if (WaylandCompositor::singleton().isRunning()) {
+        s_waylandImpl = WaylandImpl::EGL;
+        return true;
+    }
 #endif
+
+    s_waylandImpl = WaylandImpl::Unsupported;
+    return false;
 }
 
 std::unique_ptr<AcceleratedBackingStoreWayland> AcceleratedBackingStoreWayland::create(WebPageProxy& webPage)
@@ -140,20 +177,48 @@
     : AcceleratedBackingStore(webPage)
 {
 #if USE(WPE_RENDERER)
-    static struct wpe_view_backend_exportable_fdo_egl_client exportableClient = {
+    static struct wpe_view_backend_exportable_fdo_egl_client exportableEGLClient = {
         // export_egl_image
         nullptr,
         // export_fdo_egl_image
         [](void* data, struct wpe_fdo_egl_exported_image* image)
         {
-            static_cast<AcceleratedBackingStoreWayland*>(data)->displayBuffer(image);
+            static_cast<AcceleratedBackingStoreWayland*>(data)->displayImage(image);
         },
         // padding
         nullptr, nullptr, nullptr
     };
 
+#if WPE_FDO_CHECK_VERSION(1, 7, 0)
+    static struct wpe_view_backend_exportable_fdo_client exportableClient = {
+        nullptr,
+        nullptr,
+        // export_shm_buffer
+        [](void* data, struct wpe_fdo_shm_exported_buffer* buffer)
+        {
+            static_cast<AcceleratedBackingStoreWayland*>(data)->displayBuffer(buffer);
+        },
+        nullptr,
+        nullptr,
+    };
+#endif
+
     auto viewSize = webPage.viewSize();
-    m_exportable = wpe_view_backend_exportable_fdo_egl_create(&exportableClient, this, viewSize.width(), viewSize.height());
+    switch (s_waylandImpl.value()) {
+    case WaylandImpl::EGL:
+        m_exportable = wpe_view_backend_exportable_fdo_egl_create(&exportableEGLClient, this, viewSize.width(), viewSize.height());
+        break;
+    case WaylandImpl::SHM:
+#if WPE_FDO_CHECK_VERSION(1, 7, 0)
+        m_exportable = wpe_view_backend_exportable_fdo_create(&exportableClient, this, viewSize.width(), viewSize.height());
+        break;
+#else
+        FALLTHROUGH;
+#endif
+    case WaylandImpl::Unsupported:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+
     wpe_view_backend_initialize(wpe_view_backend_exportable_fdo_get_view_backend(m_exportable));
 #else
     WaylandCompositor::singleton().registerWebPage(m_webPage);
@@ -163,13 +228,15 @@
 AcceleratedBackingStoreWayland::~AcceleratedBackingStoreWayland()
 {
 #if USE(WPE_RENDERER)
-    if (m_pendingImage)
-        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_pendingImage);
-    if (m_committedImage)
-        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_committedImage);
-    if (m_viewTexture) {
-        if (makeContextCurrent())
-            glDeleteTextures(1, &m_viewTexture);
+    if (s_waylandImpl.value() == WaylandImpl::EGL) {
+        if (m_egl.pendingImage)
+            wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_egl.pendingImage);
+        if (m_egl.committedImage)
+            wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_egl.committedImage);
+        if (m_egl.viewTexture) {
+            if (makeContextCurrent())
+                glDeleteTextures(1, &m_egl.viewTexture);
+        }
     }
     wpe_view_backend_exportable_fdo_destroy(m_exportable);
 #else
@@ -193,10 +260,12 @@
         return;
 
 #if USE(WPE_RENDERER)
-    if (m_viewTexture) {
-        if (makeContextCurrent())
-            glDeleteTextures(1, &m_viewTexture);
-        m_viewTexture = 0;
+    if (s_waylandImpl.value() == WaylandImpl::EGL) {
+        if (m_egl.viewTexture) {
+            if (makeContextCurrent())
+                glDeleteTextures(1, &m_egl.viewTexture);
+            m_egl.viewTexture = 0;
+        }
     }
 #else
     WaylandCompositor::singleton().unbindWebPage(m_webPage);
@@ -214,6 +283,9 @@
         return;
 
     m_glContextInitialized = true;
+    if (s_waylandImpl.value() != WaylandImpl::EGL)
+        return;
+
     GUniqueOutPtr<GError> error;
 #if USE(GTK4)
     m_gdkGLContext = adoptGRef(gdk_surface_create_gl_context(gtk_native_get_surface(gtk_widget_get_native(m_webPage.viewWidget())), &error.outPtr()));
@@ -252,10 +324,26 @@
         return;
 
     m_surfaceID = context.contextID;
-    if (m_pendingImage) {
-        wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
-        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_pendingImage);
-        m_pendingImage = nullptr;
+    switch (s_waylandImpl.value()) {
+    case WaylandImpl::EGL:
+        if (m_egl.pendingImage) {
+            wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
+            wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_egl.pendingImage);
+            m_egl.pendingImage = nullptr;
+        }
+        break;
+    case WaylandImpl::SHM:
+#if WPE_FDO_CHECK_VERSION(1, 7, 0)
+        if (m_shm.pendingFrame) {
+            wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
+            m_shm.pendingFrame = false;
+        }
+        break;
+#else
+        FALLTHROUGH;
+#endif
+    case WaylandImpl::Unsupported:
+        RELEASE_ASSERT_NOT_REACHED();
     }
 }
 
@@ -264,54 +352,108 @@
     return wpe_view_backend_get_renderer_host_fd(wpe_view_backend_exportable_fdo_get_view_backend(m_exportable));
 }
 
-void AcceleratedBackingStoreWayland::displayBuffer(struct wpe_fdo_egl_exported_image* image)
+void AcceleratedBackingStoreWayland::displayImage(struct wpe_fdo_egl_exported_image* image)
 {
+    ASSERT(s_waylandImpl.value() == WaylandImpl::EGL);
     if (!m_surfaceID) {
         wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
-        if (image != m_committedImage)
+        if (image != m_egl.committedImage)
             wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, image);
         return;
     }
 
-    if (m_pendingImage)
-        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_pendingImage);
-    m_pendingImage = image;
+    if (m_egl.pendingImage)
+        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_egl.pendingImage);
+    m_egl.pendingImage = image;
 
     m_webPage.setViewNeedsDisplay(IntRect(IntPoint::zero(), m_webPage.viewSize()));
 }
+
+#if WPE_FDO_CHECK_VERSION(1, 7, 0)
+void AcceleratedBackingStoreWayland::displayBuffer(struct wpe_fdo_shm_exported_buffer* buffer)
+{
+    ASSERT(s_waylandImpl.value() == WaylandImpl::SHM);
+    if (!m_surfaceID) {
+        wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
+        wpe_view_backend_exportable_fdo_dispatch_release_shm_exported_buffer(m_exportable, buffer);
+        return;
+    }
+
+    m_shm.pendingFrame = true;
+
+    struct wl_shm_buffer* shmBuffer = wpe_fdo_shm_exported_buffer_get_shm_buffer(buffer);
+    auto format = wl_shm_buffer_get_format(shmBuffer);
+    if (format != WL_SHM_FORMAT_ARGB8888 && format != WL_SHM_FORMAT_XRGB8888) {
+        wpe_view_backend_exportable_fdo_dispatch_release_shm_exported_buffer(m_exportable, buffer);
+        return;
+    }
+
+    int32_t width = wl_shm_buffer_get_width(shmBuffer);
+    int32_t height = wl_shm_buffer_get_height(shmBuffer);
+    int32_t stride = wl_shm_buffer_get_stride(shmBuffer);
+    int32_t surfaceStride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width);
+    if (!m_surface || cairo_image_surface_get_width(m_surface.get()) != width || cairo_image_surface_get_height(m_surface.get()) != height) {
+        auto* surfaceData = fastZeroedMalloc(height * surfaceStride);
+        m_surface = adoptRef(cairo_image_surface_create_for_data(static_cast<unsigned char*>(surfaceData), CAIRO_FORMAT_ARGB32, width, height, surfaceStride));
+        static cairo_user_data_key_t s_surfaceDataKey;
+        cairo_surface_set_user_data(m_surface.get(), &s_surfaceDataKey, surfaceData, [](void* data) {
+            fastFree(data);
+        });
+        cairoSurfaceSetDeviceScale(m_surface.get(), m_webPage.deviceScaleFactor(), m_webPage.deviceScaleFactor());
+    }
+
+    unsigned char* surfaceData = cairo_image_surface_get_data(m_surface.get());
+    wl_shm_buffer_begin_access(shmBuffer);
+    auto* data = "" char*>(wl_shm_buffer_get_data(shmBuffer));
+    for (int32_t y = 0; y < height; ++y) {
+        for (int32_t x = 0; x < width; ++x) {
+            surfaceData[surfaceStride * y + 4 * x + 0] = data[stride * y + 4 * x + 0];
+            surfaceData[surfaceStride * y + 4 * x + 1] = data[stride * y + 4 * x + 1];
+            surfaceData[surfaceStride * y + 4 * x + 2] = data[stride * y + 4 * x + 2];
+            surfaceData[surfaceStride * y + 4 * x + 3] = data[stride * y + 4 * x + 3];
+        }
+    }
+    wl_shm_buffer_end_access(shmBuffer);
+    wpe_view_backend_exportable_fdo_dispatch_release_shm_exported_buffer(m_exportable, buffer);
+
+    cairo_surface_mark_dirty(m_surface.get());
+    m_webPage.setViewNeedsDisplay(IntRect(IntPoint::zero(), m_webPage.viewSize()));
+}
 #endif
+#endif
 
 bool AcceleratedBackingStoreWayland::tryEnsureTexture(unsigned& texture, IntSize& textureSize)
 {
+    ASSERT(s_waylandImpl.value() == WaylandImpl::EGL);
 #if USE(WPE_RENDERER)
     if (!makeContextCurrent())
         return false;
 
-    if (m_pendingImage) {
+    if (m_egl.pendingImage) {
         wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
 
-        if (m_committedImage)
-            wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_committedImage);
-        m_committedImage = m_pendingImage;
-        m_pendingImage = nullptr;
+        if (m_egl.committedImage)
+            wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_egl.committedImage);
+        m_egl.committedImage = m_egl.pendingImage;
+        m_egl.pendingImage = nullptr;
     }
 
-    if (!m_committedImage)
+    if (!m_egl.committedImage)
         return false;
 
-    if (!m_viewTexture) {
-        glGenTextures(1, &m_viewTexture);
-        glBindTexture(GL_TEXTURE_2D, m_viewTexture);
+    if (!m_egl.viewTexture) {
+        glGenTextures(1, &m_egl.viewTexture);
+        glBindTexture(GL_TEXTURE_2D, m_egl.viewTexture);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     }
-    glBindTexture(GL_TEXTURE_2D, m_viewTexture);
-    glImageTargetTexture2D(GL_TEXTURE_2D, wpe_fdo_egl_exported_image_get_egl_image(m_committedImage));
+    glBindTexture(GL_TEXTURE_2D, m_egl.viewTexture);
+    glImageTargetTexture2D(GL_TEXTURE_2D, wpe_fdo_egl_exported_image_get_egl_image(m_egl.committedImage));
 
-    texture = m_viewTexture;
-    textureSize = { static_cast<int>(wpe_fdo_egl_exported_image_get_width(m_committedImage)), static_cast<int>(wpe_fdo_egl_exported_image_get_height(m_committedImage)) };
+    texture = m_egl.viewTexture;
+    textureSize = { static_cast<int>(wpe_fdo_egl_exported_image_get_width(m_egl.committedImage)), static_cast<int>(wpe_fdo_egl_exported_image_get_height(m_egl.committedImage)) };
 #else
     if (!WaylandCompositor::singleton().getTexture(m_webPage, texture, textureSize))
         return false;
@@ -322,6 +464,7 @@
 
 void AcceleratedBackingStoreWayland::downloadTexture(unsigned texture, const IntSize& textureSize)
 {
+    ASSERT(s_waylandImpl.value() == WaylandImpl::EGL);
     ASSERT(m_glContext);
 
     if (!m_surface || cairo_image_surface_get_width(m_surface.get()) != textureSize.width() || cairo_image_surface_get_height(m_surface.get()) != textureSize.height())
@@ -367,25 +510,45 @@
 #if USE(GTK4)
 void AcceleratedBackingStoreWayland::snapshot(GtkSnapshot* gtkSnapshot)
 {
-    GLuint texture;
-    IntSize textureSize;
-    if (!tryEnsureTexture(texture, textureSize))
-        return;
+    switch (s_waylandImpl.value()) {
+    case WaylandImpl::EGL: {
+        GLuint texture;
+        IntSize textureSize;
+        if (!tryEnsureTexture(texture, textureSize))
+            return;
 
-    graphene_rect_t bounds = GRAPHENE_RECT_INIT(0, 0, static_cast<float>(textureSize.width()), static_cast<float>(textureSize.height()));
-    if (m_gdkGLContext) {
-        GRefPtr<GdkTexture> gdkTexture = adoptGRef(gdk_gl_texture_new(m_gdkGLContext.get(), texture, textureSize.width(), textureSize.height(), nullptr, nullptr));
-        gtk_snapshot_append_texture(gtkSnapshot, gdkTexture.get(), &bounds);
-        return;
+        graphene_rect_t bounds = GRAPHENE_RECT_INIT(0, 0, static_cast<float>(textureSize.width()), static_cast<float>(textureSize.height()));
+        if (m_gdkGLContext) {
+            GRefPtr<GdkTexture> gdkTexture = adoptGRef(gdk_gl_texture_new(m_gdkGLContext.get(), texture, textureSize.width(), textureSize.height(), nullptr, nullptr));
+            gtk_snapshot_append_texture(gtkSnapshot, gdkTexture.get(), &bounds);
+            return;
+        }
+
+        downloadTexture(texture, textureSize);
+        break;
     }
+    case WaylandImpl::SHM:
+#if USE(WPE_RENDERER) && WPE_FDO_CHECK_VERSION(1, 7, 0)
+        if (m_shm.pendingFrame) {
+            wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
+            m_shm.pendingFrame = false;
+        }
 
-    downloadTexture(texture, textureSize);
+        if (!m_surface)
+            return;
+        break;
+#else
+        FALLTHROUGH;
+#endif
+    case WaylandImpl::Unsupported:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
 
     RefPtr<cairo_t> cr = adoptRef(gtk_snapshot_append_cairo(gtkSnapshot, &bounds));
 
     // The compositor renders the texture flipped for gdk, fix that here.
     cairo_matrix_t transform;
-    cairo_matrix_init(&transform, 1, 0, 0, -1, 0, textureSize.height() / m_webPage.deviceScaleFactor());
+    cairo_matrix_init(&transform, 1, 0, 0, -1, 0, cairo_image_surface_get_height(m_surface.get()) / m_webPage.deviceScaleFactor());
     cairo_transform(cr.get(), &transform);
 
     cairo_set_source_surface(cr.get(), m_surface.get(), 0, 0);
@@ -395,24 +558,46 @@
 #else
 bool AcceleratedBackingStoreWayland::paint(cairo_t* cr, const IntRect& clipRect)
 {
-    GLuint texture;
-    IntSize textureSize;
-    if (!tryEnsureTexture(texture, textureSize))
-        return true;
+    switch (s_waylandImpl.value()) {
+    case WaylandImpl::EGL: {
+        GLuint texture;
+        IntSize textureSize;
+        if (!tryEnsureTexture(texture, textureSize))
+            return true;
 
-    cairo_save(cr);
+        cairo_save(cr);
 
-    if (m_gdkGLContext) {
-        gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(m_webPage.viewWidget()), texture, GL_TEXTURE, m_webPage.deviceScaleFactor(), 0, 0, textureSize.width(), textureSize.height());
-        cairo_restore(cr);
-        return true;
+        if (m_gdkGLContext) {
+            gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(m_webPage.viewWidget()), texture, GL_TEXTURE, m_webPage.deviceScaleFactor(), 0, 0, textureSize.width(), textureSize.height());
+            cairo_restore(cr);
+            return true;
+        }
+
+        downloadTexture(texture, textureSize);
+        break;
     }
+    case WaylandImpl::SHM:
+#if USE(WPE_RENDERER) && WPE_FDO_CHECK_VERSION(1, 7, 0)
+        if (m_shm.pendingFrame) {
+            wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
+            m_shm.pendingFrame = false;
+        }
 
-    downloadTexture(texture, textureSize);
+        if (!m_surface)
+            return true;
 
+        cairo_save(cr);
+        break;
+#else
+        FALLTHROUGH;
+#endif
+    case WaylandImpl::Unsupported:
+        RELEASE_ASSERT_NOT_REACHED();
+    }
+
     // The compositor renders the texture flipped for gdk_cairo_draw_from_gl, fix that here.
     cairo_matrix_t transform;
-    cairo_matrix_init(&transform, 1, 0, 0, -1, 0, textureSize.height() / m_webPage.deviceScaleFactor());
+    cairo_matrix_init(&transform, 1, 0, 0, -1, 0, cairo_image_surface_get_height(m_surface.get()) / m_webPage.deviceScaleFactor());
     cairo_transform(cr, &transform);
 
     cairo_rectangle(cr, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height());

Modified: trunk/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreWayland.h (264167 => 264168)


--- trunk/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreWayland.h	2020-07-09 14:02:14 UTC (rev 264167)
+++ trunk/Source/WebKit/UIProcess/gtk/AcceleratedBackingStoreWayland.h	2020-07-09 14:10:06 UTC (rev 264168)
@@ -40,6 +40,7 @@
 typedef void* EGLImageKHR;
 typedef struct _GdkGLContext GdkGLContext;
 struct wpe_fdo_egl_exported_image;
+struct wpe_fdo_shm_exported_buffer;
 
 namespace WebCore {
 class GLContext;
@@ -62,8 +63,11 @@
 
     void tryEnsureGLContext();
 #if USE(WPE_RENDERER)
-    void displayBuffer(struct wpe_fdo_egl_exported_image*);
+    void displayImage(struct wpe_fdo_egl_exported_image*);
+#if WPE_FDO_CHECK_VERSION(1,7,0)
+    void displayBuffer(struct wpe_fdo_shm_exported_buffer*);
 #endif
+#endif
     bool tryEnsureTexture(unsigned&, WebCore::IntSize&);
     void downloadTexture(unsigned, const WebCore::IntSize&);
 
@@ -88,10 +92,18 @@
 #if USE(WPE_RENDERER)
     struct wpe_view_backend_exportable_fdo* m_exportable { nullptr };
     uint64_t m_surfaceID { 0 };
-    unsigned m_viewTexture { 0 };
-    struct wpe_fdo_egl_exported_image* m_committedImage { nullptr };
-    struct wpe_fdo_egl_exported_image* m_pendingImage { nullptr };
+    struct {
+        unsigned viewTexture { 0 };
+        struct wpe_fdo_egl_exported_image* committedImage { nullptr };
+        struct wpe_fdo_egl_exported_image* pendingImage { nullptr };
+    } m_egl;
+
+#if WPE_FDO_CHECK_VERSION(1,7,0)
+    struct {
+        bool pendingFrame { false };
+    } m_shm;
 #endif
+#endif
 };
 
 } // namespace WebKit
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to