Changeset 249424 in webkit


Ignore:
Timestamp:
Sep 3, 2019 3:45:45 AM (5 years ago)
Author:
zandobersek@gmail.com
Message:

[WPE] Make view backends multi-view-friendly
https://bugs.webkit.org/show_bug.cgi?id=201415

Reviewed by Carlos Garcia Campos.

Have the Wayland EGL connection for WindowViewBackend instances managed
through a per-process singleton, allowing multiple backend objects
use it for different views. HeadlessViewBackend already does this, but
the code there is refurbished into a singleton structure.

The ViewBackend classes are adjusted to work with the backend-specific
EGLDisplay objects (as constructed through the backend-specific EGL
connection approach).

  • wpe/backends/HeadlessViewBackend.cpp:

(WPEToolingBackends::HeadlessEGLConnection::singleton):
(WPEToolingBackends::HeadlessViewBackend::HeadlessViewBackend):
(WPEToolingBackends::HeadlessViewBackend::~HeadlessViewBackend):
(WPEToolingBackends::HeadlessViewBackend::createSnapshot):
(WPEToolingBackends::getEGLDisplay): Deleted.

  • wpe/backends/ViewBackend.cpp:

(WPEToolingBackends::ViewBackend::initialize):
(WPEToolingBackends::ViewBackend::deinitialize):
(WPEToolingBackends::ViewBackend::~ViewBackend): Deleted.

  • wpe/backends/ViewBackend.h:
  • wpe/backends/WindowViewBackend.cpp:

(WPEToolingBackends::WaylandEGLConnection::singleton):
(WPEToolingBackends::WindowViewBackend::WindowViewBackend):
(WPEToolingBackends::WindowViewBackend::~WindowViewBackend):
(WPEToolingBackends::WindowViewBackend::displayBuffer):

Location:
trunk/Tools
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r249419 r249424  
     12019-09-03  Zan Dobersek  <zdobersek@igalia.com>
     2
     3        [WPE] Make view backends multi-view-friendly
     4        https://bugs.webkit.org/show_bug.cgi?id=201415
     5
     6        Reviewed by Carlos Garcia Campos.
     7
     8        Have the Wayland EGL connection for WindowViewBackend instances managed
     9        through a per-process singleton, allowing multiple backend objects
     10        use it for different views. HeadlessViewBackend already does this, but
     11        the code there is refurbished into a singleton structure.
     12
     13        The ViewBackend classes are adjusted to work with the backend-specific
     14        EGLDisplay objects (as constructed through the backend-specific EGL
     15        connection approach).
     16
     17        * wpe/backends/HeadlessViewBackend.cpp:
     18        (WPEToolingBackends::HeadlessEGLConnection::singleton):
     19        (WPEToolingBackends::HeadlessViewBackend::HeadlessViewBackend):
     20        (WPEToolingBackends::HeadlessViewBackend::~HeadlessViewBackend):
     21        (WPEToolingBackends::HeadlessViewBackend::createSnapshot):
     22        (WPEToolingBackends::getEGLDisplay): Deleted.
     23        * wpe/backends/ViewBackend.cpp:
     24        (WPEToolingBackends::ViewBackend::initialize):
     25        (WPEToolingBackends::ViewBackend::deinitialize):
     26        (WPEToolingBackends::ViewBackend::~ViewBackend): Deleted.
     27        * wpe/backends/ViewBackend.h:
     28        * wpe/backends/WindowViewBackend.cpp:
     29        (WPEToolingBackends::WaylandEGLConnection::singleton):
     30        (WPEToolingBackends::WindowViewBackend::WindowViewBackend):
     31        (WPEToolingBackends::WindowViewBackend::~WindowViewBackend):
     32        (WPEToolingBackends::WindowViewBackend::displayBuffer):
     33
    1342019-09-03  Carlos Garcia Campos  <cgarcia@igalia.com>
    235
  • trunk/Tools/wpe/backends/HeadlessViewBackend.cpp

    r246304 r249424  
    2828#include <cassert>
    2929#include <fcntl.h>
     30#include <mutex>
    3031#include <unistd.h>
    3132
     
    4546namespace WPEToolingBackends {
    4647
     48struct HeadlessEGLConnection {
     49    EGLDisplay eglDisplay { EGL_NO_DISPLAY };
     50
     51    static const HeadlessEGLConnection& singleton()
     52    {
     53        static std::once_flag s_onceFlag;
     54        static HeadlessEGLConnection s_connection;
     55        std::call_once(s_onceFlag,
     56            [] {
     57                EGLDisplay eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
     58                if (eglDisplay == EGL_NO_DISPLAY)
     59                    return;
     60
     61                if (!eglInitialize(eglDisplay, nullptr, nullptr) || !eglBindAPI(EGL_OPENGL_ES_API))
     62                    return;
     63
     64                s_connection.eglDisplay = eglDisplay;
     65                wpe_fdo_initialize_for_egl_display(s_connection.eglDisplay);
     66            });
     67
     68        return s_connection;
     69    }
     70};
     71
    4772static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC imageTargetTexture2DOES;
    4873
     
    5075static int kRunLoopSourcePriorityDispatcher = -70;
    5176
    52 static EGLDisplay getEGLDisplay()
    53 {
    54     static EGLDisplay s_display = EGL_NO_DISPLAY;
    55     if (s_display == EGL_NO_DISPLAY) {
    56         EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    57         if (display == EGL_NO_DISPLAY)
    58             return EGL_NO_DISPLAY;
    59 
    60         s_display = display;
    61     }
    62 
    63     return s_display;
    64 }
    65 
    6677HeadlessViewBackend::HeadlessViewBackend(uint32_t width, uint32_t height)
    6778    : ViewBackend(width, height)
    6879{
    69     m_eglDisplay = getEGLDisplay();
    70     if (!initialize())
     80    auto& connection = HeadlessEGLConnection::singleton();
     81    if (connection.eglDisplay == EGL_NO_DISPLAY || !initialize(connection.eglDisplay))
    7182        return;
    7283
    7384    addActivityState(wpe_view_activity_state_visible | wpe_view_activity_state_focused | wpe_view_activity_state_in_window);
    7485
    75     if (!eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext))
     86    if (!eglMakeCurrent(connection.eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext))
    7687        return;
    7788
     
    93104        g_source_unref(m_updateSource);
    94105    }
     106
     107    if (m_lockedImage)
     108        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_lockedImage);
     109    if (m_pendingImage)
     110        wpe_view_backend_exportable_fdo_egl_dispatch_release_exported_image(m_exportable, m_pendingImage);
     111
     112    deinitialize(HeadlessEGLConnection::singleton().eglDisplay);
    95113}
    96114
     
    108126    bool successfulSnapshot = false;
    109127
    110     if (!eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext))
     128    if (!eglMakeCurrent(HeadlessEGLConnection::singleton().eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, m_eglContext))
    111129        return nullptr;
    112130
  • trunk/Tools/wpe/backends/ViewBackend.cpp

    r246304 r249424  
    137137}
    138138
    139 ViewBackend::~ViewBackend()
    140 {
    141     if (m_exportable)
    142         wpe_view_backend_exportable_fdo_destroy(m_exportable);
    143 
    144     if (m_eglContext)
    145         eglDestroyContext(m_eglDisplay, m_eglContext);
    146 }
    147 
    148 bool ViewBackend::initialize()
    149 {
    150     if (m_eglDisplay == EGL_NO_DISPLAY)
    151         return false;
    152 
    153     eglInitialize(m_eglDisplay, nullptr, nullptr);
    154 
    155     if (!eglBindAPI(EGL_OPENGL_ES_API))
    156         return false;
    157 
    158     wpe_fdo_initialize_for_egl_display(m_eglDisplay);
    159 
     139ViewBackend::~ViewBackend() = default;
     140
     141bool ViewBackend::initialize(EGLDisplay eglDisplay)
     142{
    160143    static const EGLint configAttributes[13] = {
    161144        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
     
    170153    {
    171154        EGLint count = 0;
    172         if (!eglGetConfigs(m_eglDisplay, nullptr, 0, &count) || count < 1)
     155        if (!eglGetConfigs(eglDisplay, nullptr, 0, &count) || count < 1)
    173156            return false;
    174157
    175158        EGLConfig* configs = g_new0(EGLConfig, count);
    176159        EGLint matched = 0;
    177         if (eglChooseConfig(m_eglDisplay, configAttributes, configs, count, &matched) && !!matched)
     160        if (eglChooseConfig(eglDisplay, configAttributes, configs, count, &matched) && !!matched)
    178161            m_eglConfig = configs[0];
    179162        g_free(configs);
     
    185168    };
    186169
    187     m_eglContext = eglCreateContext(m_eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttributes);
     170    m_eglContext = eglCreateContext(eglDisplay, m_eglConfig, EGL_NO_CONTEXT, contextAttributes);
    188171    if (!m_eglContext)
    189172        return false;
     
    205188
    206189    return true;
     190}
     191
     192void ViewBackend::deinitialize(EGLDisplay eglDisplay)
     193{
     194    m_inputClient = nullptr;
     195
     196    if (m_eglContext)
     197        eglDestroyContext(eglDisplay, m_eglContext);
     198
     199    if (m_exportable)
     200        wpe_view_backend_exportable_fdo_destroy(m_exportable);
    207201}
    208202
  • trunk/Tools/wpe/backends/ViewBackend.h

    r246304 r249424  
    6565    ViewBackend(uint32_t width, uint32_t height);
    6666
    67     bool initialize();
     67    bool initialize(EGLDisplay);
     68    void deinitialize(EGLDisplay);
     69
    6870    void initializeAccessibility();
    6971    void updateAccessibilityState(uint32_t);
     
    8183    uint32_t m_width { 0 };
    8284    uint32_t m_height { 0 };
    83     EGLDisplay m_eglDisplay { nullptr };
    8485    EGLContext m_eglContext { nullptr };
    8586    EGLConfig m_eglConfig;
  • trunk/Tools/wpe/backends/WindowViewBackend.cpp

    r249377 r249424  
    3030#include <linux/input.h>
    3131#include <memory>
     32#include <mutex>
    3233#include <sys/mman.h>
    3334#include <unistd.h>
     
    4748
    4849namespace WPEToolingBackends {
     50
     51struct WaylandEGLConnection {
     52    struct wl_display* display { nullptr };
     53    EGLDisplay eglDisplay { EGL_NO_DISPLAY };
     54
     55    static const WaylandEGLConnection& singleton()
     56    {
     57        static std::once_flag s_onceFlag;
     58        static WaylandEGLConnection s_connection;
     59        std::call_once(s_onceFlag,
     60            [] {
     61                s_connection.display = wl_display_connect(nullptr);
     62                if (!s_connection.display)
     63                    return;
     64
     65                EGLDisplay eglDisplay = eglGetDisplay(s_connection.display);
     66                if (eglDisplay == EGL_NO_DISPLAY)
     67                    return;
     68
     69                if (!eglInitialize(eglDisplay, nullptr, nullptr) || !eglBindAPI(EGL_OPENGL_ES_API))
     70                    return;
     71
     72                s_connection.eglDisplay = eglDisplay;
     73                wpe_fdo_initialize_for_egl_display(s_connection.eglDisplay);
     74            });
     75
     76        return s_connection;
     77    }
     78};
    4979
    5080static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC imageTargetTexture2DOES;
     
    482512    m_initialSize.height = height;
    483513
    484     m_display = wl_display_connect(nullptr);
    485     if (!m_display)
     514    auto& connection = WaylandEGLConnection::singleton();
     515    if (!connection.display)
    486516        return;
    487517
    488     m_eglDisplay = eglGetDisplay(m_display);
    489     if (!initialize())
     518    if (connection.eglDisplay == EGL_NO_DISPLAY || !initialize(connection.eglDisplay))
    490519        return;
    491520
    492521    {
    493         auto* registry = wl_display_get_registry(m_display);
     522        auto* registry = wl_display_get_registry(connection.display);
    494523        wl_registry_add_listener(registry, &s_registryListener, this);
    495         wl_display_roundtrip(m_display);
     524        wl_display_roundtrip(connection.display);
    496525
    497526        if (m_xdg)
     
    505534    {
    506535        auto& source = *reinterpret_cast<EventSource*>(m_eventSource);
    507         source.display = m_display;
    508 
    509         source.pfd.fd = wl_display_get_fd(m_display);
     536        source.display = connection.display;
     537
     538        source.pfd.fd = wl_display_get_fd(connection.display);
    510539        source.pfd.events = G_IO_IN | G_IO_ERR | G_IO_HUP;
    511540        source.pfd.revents = 0;
     
    534563    auto createPlatformWindowSurface =
    535564        reinterpret_cast<PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC>(eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT"));
    536     m_eglSurface = createPlatformWindowSurface(m_eglDisplay, m_eglConfig, m_eglWindow, nullptr);
     565    m_eglSurface = createPlatformWindowSurface(connection.eglDisplay, m_eglConfig, m_eglWindow, nullptr);
    537566    if (!m_eglSurface)
    538567        return;
    539568
    540     if (!eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
     569    if (!eglMakeCurrent(connection.eglDisplay, m_eglSurface, m_eglSurface, m_eglContext))
    541570        return;
    542571
     
    583612WindowViewBackend::~WindowViewBackend()
    584613{
     614    auto& connection = WaylandEGLConnection::singleton();
     615
    585616    if (m_eventSource) {
    586617        g_source_destroy(m_eventSource);
     
    610641
    611642    if (m_eglSurface)
    612         eglDestroySurface(m_eglDisplay, m_eglSurface);
     643        eglDestroySurface(connection.eglDisplay, m_eglSurface);
    613644
    614645    if (m_display)
    615646        wl_display_disconnect(m_display);
     647
     648    deinitialize(connection.eglDisplay);
    616649}
    617650
     
    670703        return;
    671704
    672     eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
     705    auto& connection = WaylandEGLConnection::singleton();
     706    eglMakeCurrent(connection.eglDisplay, m_eglSurface, m_eglSurface, m_eglContext);
    673707
    674708    glViewport(0, 0, m_width, m_height);
     
    713747    wl_callback_add_listener(callback, &s_frameListener, this);
    714748
    715     eglSwapBuffers(m_eglDisplay, m_eglSurface);
     749    eglSwapBuffers(connection.eglDisplay, m_eglSurface);
    716750}
    717751
Note: See TracChangeset for help on using the changeset viewer.