[WPE] Switch ViewBackend to using wpe_view_backend_exportable_fdo_egl APIs
authorzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jul 2018 13:26:05 +0000 (13:26 +0000)
committerzandobersek@gmail.com <zandobersek@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 25 Jul 2018 13:26:05 +0000 (13:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=187997

Reviewed by Carlos Garcia Campos.

Instead of the raw wpe_view_backend_exportable_fdo API, switch to using
the EGL-oriented API that simply serves EGLImageKHR objects instead of
raw buffer resources. This allows us not to wrangle with creating and
managing lifetime of the same EGLImageKHR by ourselves.

ViewBackend now defines a wpe_view_backend_exportable_fdo_egl_client
struct and uses wpe_view_backend_exportable_fdo_egl_create() to create
the exportable object. This means that for each frame we're served an
EGLImageKHR object that is passed on to the displayBuffer()
implementation.

HeadlessViewBackend now just manages the pending and committed image
objects. Width and height values used during pixel data retrieval are
gathered from the ViewBackend's size that was specified when
constructed.

WindowViewBackend similarly only manages the committed image object,
not having to create an equivalent EGLImageKHR object from the raw
buffer resource anymore.

Unused EGL entrypoints in both HeadlessViewBackend and WindowViewBackend
classes are removed, and destructors for both classes are made virtual.

The WPEBackend-fdo version is bumped in order to have the EGL-specific
export API available.

* flatpak/org.webkit.WPE.yaml:
* wpe/backends/HeadlessViewBackend.cpp:
(WPEToolingBackends::HeadlessViewBackend::HeadlessViewBackend):
(WPEToolingBackends::HeadlessViewBackend::~HeadlessViewBackend):
(WPEToolingBackends::HeadlessViewBackend::createSnapshot):
(WPEToolingBackends::HeadlessViewBackend::performUpdate):
(WPEToolingBackends::HeadlessViewBackend::displayBuffer):
* wpe/backends/HeadlessViewBackend.h:
* wpe/backends/ViewBackend.cpp:
(WPEToolingBackends::ViewBackend::initialize):
* wpe/backends/ViewBackend.h:
* wpe/backends/WindowViewBackend.cpp:
(WPEToolingBackends::WindowViewBackend::WindowViewBackend):
(WPEToolingBackends::WindowViewBackend::~WindowViewBackend):
(WPEToolingBackends::WindowViewBackend::displayBuffer):
* wpe/backends/WindowViewBackend.h:
* wpe/jhbuild.modules:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@234193 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/flatpak/org.webkit.WPE.yaml
Tools/wpe/backends/HeadlessViewBackend.cpp
Tools/wpe/backends/HeadlessViewBackend.h
Tools/wpe/backends/ViewBackend.cpp
Tools/wpe/backends/ViewBackend.h
Tools/wpe/backends/WindowViewBackend.cpp
Tools/wpe/backends/WindowViewBackend.h
Tools/wpe/jhbuild.modules

index d0ecc2a..1a26b5a 100644 (file)
@@ -1,3 +1,54 @@
+2018-07-25  Zan Dobersek  <zdobersek@igalia.com>
+
+        [WPE] Switch ViewBackend to using wpe_view_backend_exportable_fdo_egl APIs
+        https://bugs.webkit.org/show_bug.cgi?id=187997
+
+        Reviewed by Carlos Garcia Campos.
+
+        Instead of the raw wpe_view_backend_exportable_fdo API, switch to using
+        the EGL-oriented API that simply serves EGLImageKHR objects instead of
+        raw buffer resources. This allows us not to wrangle with creating and
+        managing lifetime of the same EGLImageKHR by ourselves.
+
+        ViewBackend now defines a wpe_view_backend_exportable_fdo_egl_client
+        struct and uses wpe_view_backend_exportable_fdo_egl_create() to create
+        the exportable object. This means that for each frame we're served an
+        EGLImageKHR object that is passed on to the displayBuffer()
+        implementation.
+
+        HeadlessViewBackend now just manages the pending and committed image
+        objects. Width and height values used during pixel data retrieval are
+        gathered from the ViewBackend's size that was specified when
+        constructed.
+
+        WindowViewBackend similarly only manages the committed image object,
+        not having to create an equivalent EGLImageKHR object from the raw
+        buffer resource anymore.
+
+        Unused EGL entrypoints in both HeadlessViewBackend and WindowViewBackend
+        classes are removed, and destructors for both classes are made virtual.
+
+        The WPEBackend-fdo version is bumped in order to have the EGL-specific
+        export API available.
+
+        * flatpak/org.webkit.WPE.yaml:
+        * wpe/backends/HeadlessViewBackend.cpp:
+        (WPEToolingBackends::HeadlessViewBackend::HeadlessViewBackend):
+        (WPEToolingBackends::HeadlessViewBackend::~HeadlessViewBackend):
+        (WPEToolingBackends::HeadlessViewBackend::createSnapshot):
+        (WPEToolingBackends::HeadlessViewBackend::performUpdate):
+        (WPEToolingBackends::HeadlessViewBackend::displayBuffer):
+        * wpe/backends/HeadlessViewBackend.h:
+        * wpe/backends/ViewBackend.cpp:
+        (WPEToolingBackends::ViewBackend::initialize):
+        * wpe/backends/ViewBackend.h:
+        * wpe/backends/WindowViewBackend.cpp:
+        (WPEToolingBackends::WindowViewBackend::WindowViewBackend):
+        (WPEToolingBackends::WindowViewBackend::~WindowViewBackend):
+        (WPEToolingBackends::WindowViewBackend::displayBuffer):
+        * wpe/backends/WindowViewBackend.h:
+        * wpe/jhbuild.modules:
+
 2018-07-24  Thomas Denney  <tdenney@apple.com>
 
         Remove support for the double type from WHLSL
index cb1cf9f..c73cd8d 100644 (file)
@@ -9,7 +9,7 @@
   sources:
     - type: git
       url: https://github.com/Igalia/WPEBackend-fdo.git
-      branch: bdd46870b1dc3c92005343e3161bdd24f620b11d
+      branch: da746af2dff6b972c5c4903a132edcafdb768926
 - name: lua
   buildsystem: simple
   build-commands:
index 79953a4..ed1ada4 100644 (file)
@@ -44,9 +44,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, st
 
 namespace WPEToolingBackends {
 
-static PFNEGLCREATEIMAGEKHRPROC createImage;
-static PFNEGLDESTROYIMAGEKHRPROC destroyImage;
-static PFNEGLQUERYWAYLANDBUFFERWL queryBuffer;
 static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC imageTargetTexture2DOES;
 
 // Keep this in sync with wtf/glib/RunLoopSourcePriority.h.
@@ -68,6 +65,8 @@ static EGLDisplay getEGLDisplay()
 
 HeadlessViewBackend::HeadlessViewBackend(uint32_t width, uint32_t height)
     : ViewBackend(width, height)
+    , m_pendingImage(EGL_NO_IMAGE_KHR)
+    , m_lockedImage(EGL_NO_IMAGE_KHR)
 {
     m_eglDisplay = getEGLDisplay();
     if (!initialize())
@@ -76,9 +75,6 @@ HeadlessViewBackend::HeadlessViewBackend(uint32_t width, uint32_t height)
     if (!eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext))
         return;
 
-    createImage = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
-    destroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
-    queryBuffer = reinterpret_cast<PFNEGLQUERYWAYLANDBUFFERWL>(eglGetProcAddress("eglQueryWaylandBufferWL"));
     imageTargetTexture2DOES = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
 
     m_updateSource = g_timeout_source_new(m_frameRate / 1000);
@@ -96,11 +92,6 @@ HeadlessViewBackend::~HeadlessViewBackend()
         g_source_destroy(m_updateSource);
         g_source_unref(m_updateSource);
     }
-
-    if (auto image = std::get<0>(m_pendingImage.second))
-        destroyImage(m_eglDisplay, image);
-    if (auto image = std::get<0>(m_lockedImage.second))
-        destroyImage(m_eglDisplay, image);
 }
 
 cairo_surface_t* HeadlessViewBackend::createSnapshot()
@@ -110,14 +101,10 @@ cairo_surface_t* HeadlessViewBackend::createSnapshot()
 
     performUpdate();
 
-    EGLImageKHR image = std::get<0>(m_lockedImage.second);
-    if (!image)
+    if (!m_lockedImage)
         return nullptr;
 
-    uint32_t width = std::get<1>(m_lockedImage.second);
-    uint32_t height = std::get<2>(m_lockedImage.second);
-
-    uint8_t* buffer = new uint8_t[4 * width * height];
+    uint8_t* buffer = new uint8_t[4 * m_width * m_height];
     bool successfulSnapshot = false;
 
     if (!eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext))
@@ -130,9 +117,9 @@ cairo_surface_t* HeadlessViewBackend::createSnapshot()
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-    glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, width, height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, nullptr);
+    glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT, m_width, m_height, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE, nullptr);
 
-    imageTargetTexture2DOES(GL_TEXTURE_2D, image);
+    imageTargetTexture2DOES(GL_TEXTURE_2D, m_lockedImage);
     glBindTexture(GL_TEXTURE_2D, 0);
 
     GLuint imageFramebuffer;
@@ -142,7 +129,7 @@ cairo_surface_t* HeadlessViewBackend::createSnapshot()
 
     glFlush();
     if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
-        glReadPixels(0, 0, width, height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer);
+        glReadPixels(0, 0, m_width, m_height, GL_BGRA_EXT, GL_UNSIGNED_BYTE, buffer);
         successfulSnapshot = true;
     }
 
@@ -156,7 +143,7 @@ cairo_surface_t* HeadlessViewBackend::createSnapshot()
     }
 
     cairo_surface_t* imageSurface = cairo_image_surface_create_for_data(buffer,
-        CAIRO_FORMAT_ARGB32, width, height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width));
+        CAIRO_FORMAT_ARGB32, m_width, m_height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, m_width));
     cairo_surface_mark_dirty(imageSurface);
 
     static cairo_user_data_key_t bufferKey;
@@ -171,36 +158,23 @@ cairo_surface_t* HeadlessViewBackend::createSnapshot()
 
 void HeadlessViewBackend::performUpdate()
 {
-    if (!m_pendingImage.first)
+    if (!m_pendingImage)
         return;
 
     wpe_view_backend_exportable_fdo_dispatch_frame_complete(m_exportable);
-    if (m_lockedImage.first) {
-        wpe_view_backend_exportable_fdo_dispatch_release_buffer(m_exportable, m_lockedImage.first);
-        destroyImage(m_eglDisplay, std::get<0>(m_lockedImage.second));
-    }
+    if (m_lockedImage)
+        wpe_view_backend_exportable_fdo_egl_dispatch_release_image(m_exportable, m_lockedImage);
 
     m_lockedImage = m_pendingImage;
-    m_pendingImage = std::pair<struct wl_resource*, std::tuple<EGLImageKHR, uint32_t, uint32_t>> { };
+    m_pendingImage = EGL_NO_IMAGE_KHR;
 }
 
-void HeadlessViewBackend::displayBuffer(struct wl_resource* bufferResource)
+void HeadlessViewBackend::displayBuffer(EGLImageKHR image)
 {
-    if (m_pendingImage.first)
+    if (m_pendingImage)
         std::abort();
 
-    EGLint format = 0;
-    if (!queryBuffer(m_eglDisplay, bufferResource, EGL_TEXTURE_FORMAT, &format) || format != EGL_TEXTURE_RGBA)
-        return;
-
-    EGLint width, height;
-    if (!queryBuffer(m_eglDisplay, bufferResource, EGL_WIDTH, &width)
-        || !queryBuffer(m_eglDisplay, bufferResource, EGL_HEIGHT, &height))
-        return;
-
-    EGLint attributes[] = { EGL_WAYLAND_PLANE_WL, 0, EGL_NONE };
-    EGLImageKHR image = createImage(m_eglDisplay, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, bufferResource, attributes);
-    m_pendingImage = { bufferResource, std::make_tuple(image, width, height) };
+    m_pendingImage = image;
 }
 
 } // namespace WPEToolingBackends
index 178424e..b0d66e3 100644 (file)
@@ -37,17 +37,17 @@ namespace WPEToolingBackends {
 class HeadlessViewBackend final : public ViewBackend {
 public:
     HeadlessViewBackend(uint32_t width, uint32_t height);
-    ~HeadlessViewBackend();
+    virtual ~HeadlessViewBackend();
 
     cairo_surface_t* createSnapshot();
 
 private:
-    void displayBuffer(struct wl_resource*) override;
+    void displayBuffer(EGLImageKHR) override;
 
     void performUpdate();
 
-    std::pair<struct wl_resource*, std::tuple<EGLImageKHR, uint32_t, uint32_t>> m_pendingImage { };
-    std::pair<struct wl_resource*, std::tuple<EGLImageKHR, uint32_t, uint32_t>> m_lockedImage { };
+    EGLImageKHR m_pendingImage;
+    EGLImageKHR m_lockedImage;
 
     GSource* m_updateSource { nullptr };
     gint64 m_frameRate { G_USEC_PER_SEC / 60 };
index 048faf0..8dab0aa 100644 (file)
@@ -92,16 +92,16 @@ bool ViewBackend::initialize()
     if (!m_eglContext)
         return false;
 
-    static struct wpe_view_backend_exportable_fdo_client exportableClient = {
+    static struct wpe_view_backend_exportable_fdo_egl_client exportableClient = {
         // export_buffer_resource
-        [](void* data, struct wl_resource* bufferResource)
+        [](void* data, EGLImageKHR image)
         {
-            static_cast<ViewBackend*>(data)->displayBuffer(bufferResource);
+            static_cast<ViewBackend*>(data)->displayBuffer(image);
         },
         // padding
         nullptr, nullptr, nullptr, nullptr
     };
-    m_exportable = wpe_view_backend_exportable_fdo_create(&exportableClient, this, m_width, m_height);
+    m_exportable = wpe_view_backend_exportable_fdo_egl_create(&exportableClient, this, m_width, m_height);
 
     return true;
 }
index e99a188..63e9f8b 100644 (file)
@@ -31,6 +31,7 @@
 typedef void* EGLConfig;
 typedef void* EGLContext;
 typedef void* EGLDisplay;
+typedef void* EGLImageKHR;
 
 // Manually provide the EGL_CAST C++ definition in case eglplatform.h doesn't provide it.
 #ifndef EGL_CAST
@@ -66,7 +67,7 @@ protected:
     void dispatchInputKeyboardEvent(struct wpe_input_keyboard_event*);
     void dispatchInputTouchEvent(struct wpe_input_touch_event*);
 
-    virtual void displayBuffer(struct wl_resource*) = 0;
+    virtual void displayBuffer(EGLImageKHR) = 0;
 
     uint32_t m_width { 0 };
     uint32_t m_height { 0 };
index f1e6bd5..b29971a 100644 (file)
@@ -35,6 +35,7 @@
 // This include order is necessary to enforce the Wayland EGL platform.
 #include <wayland-egl.h>
 #include <epoxy/egl.h>
+#include <wpe/fdo-egl.h>
 
 #ifndef EGL_WL_bind_wayland_display
 #define EGL_WL_bind_wayland_display 1
@@ -46,8 +47,6 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLQUERYWAYLANDBUFFERWL) (EGLDisplay dpy, st
 
 namespace WPEToolingBackends {
 
-static PFNEGLCREATEIMAGEKHRPROC createImage;
-static PFNEGLDESTROYIMAGEKHRPROC destroyImage;
 static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC imageTargetTexture2DOES;
 
 struct EventSource {
@@ -499,8 +498,6 @@ WindowViewBackend::WindowViewBackend(uint32_t width, uint32_t height)
     if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
         return;
 
-    createImage = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
-    destroyImage = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
     imageTargetTexture2DOES = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
 
     {
@@ -577,9 +574,6 @@ WindowViewBackend::~WindowViewBackend()
     if (m_compositor)
         wl_compositor_destroy(m_compositor);
 
-    if (m_committed.image)
-        destroyImage(m_eglDisplay, m_committed.image);
-
     if (m_eglSurface)
         eglDestroySurface(m_eglDisplay, m_eglSurface);
 
@@ -597,15 +591,13 @@ const struct wl_callback_listener WindowViewBackend::s_frameListener = {
         auto& window = *static_cast<WindowViewBackend*>(data);
         wpe_view_backend_exportable_fdo_dispatch_frame_complete(window.m_exportable);
 
-        if (window.m_committed.image)
-            destroyImage(window.m_eglDisplay, window.m_committed.image);
-        if (window.m_committed.bufferResource)
-            wpe_view_backend_exportable_fdo_dispatch_release_buffer(window.m_exportable, window.m_committed.bufferResource);
-        window.m_committed = { nullptr, nullptr };
+        if (window.m_committedImage)
+            wpe_view_backend_exportable_fdo_egl_dispatch_release_image(window.m_exportable, window.m_committedImage);
+        window.m_committedImage = EGL_NO_IMAGE_KHR;
     }
 };
 
-void WindowViewBackend::displayBuffer(struct wl_resource* bufferResource)
+void WindowViewBackend::displayBuffer(EGLImageKHR image)
 {
     if (!m_eglContext)
         return;
@@ -617,20 +609,12 @@ void WindowViewBackend::displayBuffer(struct wl_resource* bufferResource)
 
     glUseProgram(m_program);
 
-    {
-        static EGLint imageAttributes[] = {
-            EGL_WAYLAND_PLANE_WL, 0,
-            EGL_NONE
-        };
-        EGLImageKHR image = createImage(m_eglDisplay, EGL_NO_CONTEXT, EGL_WAYLAND_BUFFER_WL, bufferResource, imageAttributes);
+    glActiveTexture(GL_TEXTURE0);
+    glBindTexture(GL_TEXTURE_2D, m_viewTexture);
+    imageTargetTexture2DOES(GL_TEXTURE_2D, image);
+    glUniform1i(m_textureUniform, 0);
 
-        glActiveTexture(GL_TEXTURE0);
-        glBindTexture(GL_TEXTURE_2D, m_viewTexture);
-        imageTargetTexture2DOES(GL_TEXTURE_2D, image);
-        glUniform1i(m_textureUniform, 0);
-
-        m_committed = { bufferResource, image };
-    }
+    m_committedImage = image;
 
     static const GLfloat vertices[4][2] = {
         { -1.0, 1.0 },
index 3f134a9..134fe7c 100644 (file)
@@ -41,10 +41,10 @@ namespace WPEToolingBackends {
 class WindowViewBackend final : public ViewBackend {
 public:
     WindowViewBackend(uint32_t width, uint32_t height);
-    ~WindowViewBackend();
+    virtual ~WindowViewBackend();
 
 private:
-    void displayBuffer(struct wl_resource*) override;
+    void displayBuffer(EGLImageKHR) override;
 
     static const struct wl_registry_listener s_registryListener;
     static const struct zxdg_shell_v6_listener s_xdgWmBaseListener;
@@ -119,10 +119,7 @@ private:
     unsigned m_program { 0 };
     unsigned m_textureUniform { 0 };
     unsigned m_viewTexture { 0 };
-    struct {
-        struct wl_resource* bufferResource { nullptr };
-        EGLImageKHR image;
-    } m_committed;
+    EGLImageKHR m_committedImage;
 };
 
 } // WPEToolingBackends
index 44910c1..b1ab468 100644 (file)
       <dep package="glib"/>
     </dependencies>
     <branch repo="github.com" module="Igalia/WPEBackend-fdo.git"
-            tag="bdd46870b1dc3c92005343e3161bdd24f620b11d"/>
+            tag="da746af2dff6b972c5c4903a132edcafdb768926"/>
   </cmake>
 
   <autotools id="libgpg-error" autogen-sh="configure">