Skip to content

Commit

Permalink
[WPE] WPE Platform: Implement monitors API in DRM platform
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=269062

Reviewed by Adrian Perez de Castro.

Add WPEMonitor implementation for DRM.

* Source/WebKit/UIProcess/glib/DisplayVBlankMonitorDRM.cpp:
(WebKit::DisplayVBlankMonitorDRM::create):
* Source/WebKit/WPEPlatform/wpe/drm/CMakeLists.txt:
* Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.cpp:
(WPE::DRM::Crtc::Crtc):
(WPE::DRM::Connector::Connector):
* Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.h:
(WPE::DRM::Crtc::x const):
(WPE::DRM::Crtc::y const):
(WPE::DRM::Crtc::width const):
(WPE::DRM::Crtc::height const):
(WPE::DRM::Connector::widthMM const):
(WPE::DRM::Connector::heightMM const):
* Source/WebKit/WPEPlatform/wpe/drm/WPEDisplayDRM.cpp:
(wpeDisplayDRMConnect):
(wpeDisplayDRMGetNMonitors):
(wpeDisplayDRMGetMonitor):
(wpe_display_drm_class_init):
(wpeDisplayDRMGetCrtc): Deleted.
* Source/WebKit/WPEPlatform/wpe/drm/WPEDisplayDRMPrivate.h:
* Source/WebKit/WPEPlatform/wpe/drm/WPEMonitorDRM.cpp: Added.
(wpeMonitorDRMInvalidate):
(wpeMonitorDRMDispose):
(wpe_monitor_drm_class_init):
(wpeMonitorDRMCreate):
(wpeMonitorDRMGetMode):
(wpeMonitorDRMGetCrtc):
(wpe_monitor_drm_get_crtc_index):
* Source/WebKit/WPEPlatform/wpe/drm/WPEMonitorDRM.h: Copied from Source/WebKit/WPEPlatform/wpe/drm/wpe-drm.h.
* Source/WebKit/WPEPlatform/wpe/drm/WPEMonitorDRMPrivate.h: Copied from Source/WebKit/WPEPlatform/wpe/drm/wpe-drm.h.
* Source/WebKit/WPEPlatform/wpe/drm/WPEViewDRM.cpp:
(wpeViewDRMConstructed):
(wpeViewDRMCommitAtomic):
(wpeViewDRMCommitLegacy):
(wpeViewDRMGetMonitor):
(wpeViewDRMScheduleCursorUpdate):
(wpe_view_drm_class_init):
* Source/WebKit/WPEPlatform/wpe/drm/wpe-drm.h:

Canonical link: https://commits.webkit.org/274619@main
  • Loading branch information
carlosgcampos committed Feb 14, 2024
1 parent 2d31dba commit b96094f
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 51 deletions.
14 changes: 13 additions & 1 deletion Source/WebKit/UIProcess/glib/DisplayVBlankMonitorDRM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@

#if PLATFORM(WPE) && ENABLE(WPE_PLATFORM)
#include <wpe/wpe-platform.h>
#ifdef WPE_PLATFORM_DRM
#include <wpe/drm/wpe-drm.h>
#endif
#endif

namespace WebKit {
Expand Down Expand Up @@ -237,7 +240,16 @@ std::unique_ptr<DisplayVBlankMonitor> DisplayVBlankMonitorDRM::create(PlatformDi
auto crtcInfo = findCrtc(fd.value(), monitor);
#elif PLATFORM(WPE)
#if ENABLE(WPE_PLATFORM)
auto crtcInfo = monitor ? findCrtc(fd.value(), monitor) : findCrtc(fd.value());
std::optional<std::pair<uint32_t, uint32_t>> crtcInfo;
if (usingWPEPlatformAPI) {
#ifdef WPE_PLATFORM_DRM
if (WPE_IS_MONITOR_DRM(monitor))
crtcInfo = { wpe_monitor_drm_get_crtc_index(WPE_MONITOR_DRM(monitor)), wpe_monitor_get_refresh_rate(monitor) };
else
#endif
crtcInfo = findCrtc(fd.value(), monitor);
} else
crtcInfo = findCrtc(fd.value());
#else
auto crtcInfo = findCrtc(fd.value());
#endif
Expand Down
2 changes: 2 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/drm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ set(WPEPlatformDRM_SOURCES
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEDRMSession.cpp
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEDRMSessionLogind.cpp
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEDisplayDRM.cpp
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEMonitorDRM.cpp
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEViewDRM.cpp
)

set(WPEPlatformDRM_INSTALLED_HEADERS
${WEBKIT_DIR}/WPEPlatform/wpe/drm/wpe-drm.h
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEDisplayDRM.h
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEMonitorDRM.h
${WEBKIT_DIR}/WPEPlatform/wpe/drm/WPEViewDRM.h
)

Expand Down
6 changes: 6 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ std::unique_ptr<Crtc> Crtc::create(int fd, drmModeCrtc* crtc, unsigned index)
Crtc::Crtc(drmModeCrtc* crtc, unsigned index, Properties&& properties)
: m_id(crtc->crtc_id)
, m_index(index)
, m_x(crtc->x)
, m_y(crtc->y)
, m_width(crtc->width)
, m_height(crtc->height)
, m_properties(WTFMove(properties))
{
if (crtc->mode_valid)
Expand Down Expand Up @@ -88,6 +92,8 @@ std::unique_ptr<Connector> Connector::create(int fd, drmModeConnector* connector
Connector::Connector(drmModeConnector* connector, Properties&& properties)
: m_id(connector->connector_id)
, m_encoderID(connector->encoder_id)
, m_widthMM(connector->mmWidth)
, m_heightMM(connector->mmHeight)
, m_properties(WTFMove(properties))
{
m_modes.reserveInitialCapacity(connector->count_modes);
Expand Down
12 changes: 12 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ class Crtc {

uint32_t id() const { return m_id; }
unsigned index() const { return m_index; }
uint32_t x() const { return m_x; }
uint32_t y() const { return m_y; }
uint32_t width() const { return m_width; }
uint32_t height() const { return m_height; }
const std::optional<drmModeModeInfo>& currentMode() const { return m_currentMode; }
const Properties& properties() const { return m_properties; }

Expand All @@ -59,6 +63,10 @@ class Crtc {
private:
uint32_t m_id { 0 };
unsigned m_index { 0 };
uint32_t m_x { 0 };
uint32_t m_y { 0 };
uint32_t m_width { 0 };
uint32_t m_height { 0 };
std::optional<drmModeModeInfo> m_currentMode;
Properties m_properties;
};
Expand All @@ -78,13 +86,17 @@ class Connector {

uint32_t id() const { return m_id; }
uint32_t encoderID() const { return m_encoderID; }
uint32_t widthMM() const { return m_widthMM; }
uint32_t heightMM() const { return m_heightMM; }
const Vector<drmModeModeInfo>& modes() const { return m_modes; }
const std::optional<unsigned> preferredModeIndex() const { return m_preferredModeIndex; }
const Properties& properties() const { return m_properties; }

private:
uint32_t m_id { 0 };
uint32_t m_encoderID { 0 };
uint32_t m_widthMM { 0 };
uint32_t m_heightMM { 0 };
Vector<drmModeModeInfo> m_modes;
std::optional<unsigned> m_preferredModeIndex;
Properties m_properties;
Expand Down
23 changes: 19 additions & 4 deletions Source/WebKit/WPEPlatform/wpe/drm/WPEDisplayDRM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "DRMUniquePtr.h"
#include "WPEDisplayDRMPrivate.h"
#include "WPEExtensions.h"
#include "WPEMonitorDRMPrivate.h"
#include "WPEViewDRM.h"
#include <fcntl.h>
#include <gio/gio.h>
Expand All @@ -47,7 +48,7 @@ struct _WPEDisplayDRMPrivate {
uint32_t cursorWidth;
uint32_t cursorHeight;
std::unique_ptr<WPE::DRM::Connector> connector;
std::unique_ptr<WPE::DRM::Crtc> crtc;
GRefPtr<WPEMonitor> monitor;
std::unique_ptr<WPE::DRM::Plane> primaryPlane;
std::unique_ptr<WPE::DRM::Cursor> cursor;
std::unique_ptr<WPE::DRM::Seat> seat;
Expand Down Expand Up @@ -248,7 +249,7 @@ static gboolean wpeDisplayDRMConnect(WPEDisplay* display, GError** error)
displayDRM->priv->fd = WTFMove(fd);
displayDRM->priv->device = device;
displayDRM->priv->connector = WTFMove(connector);
displayDRM->priv->crtc = WTFMove(crtc);
displayDRM->priv->monitor = wpeMonitorDRMCreate(WTFMove(crtc), *displayDRM->priv->connector);
displayDRM->priv->primaryPlane = WTFMove(primaryPlane);
displayDRM->priv->seat = WPE::DRM::Seat::create();
if (cursorPlane)
Expand Down Expand Up @@ -278,6 +279,18 @@ static GList* wpeDisplayDRMGetPreferredDMABufFormats(WPEDisplay* display)
return g_list_reverse(preferredFormats);
}

static guint wpeDisplayDRMGetNMonitors(WPEDisplay*)
{
return 1;
}

static WPEMonitor* wpeDisplayDRMGetMonitor(WPEDisplay* display, guint index)
{
if (index)
return nullptr;
return WPE_DISPLAY_DRM(display)->priv->monitor.get();
}

static void wpe_display_drm_class_init(WPEDisplayDRMClass* displayDRMClass)
{
GObjectClass* objectClass = G_OBJECT_CLASS(displayDRMClass);
Expand All @@ -287,16 +300,18 @@ static void wpe_display_drm_class_init(WPEDisplayDRMClass* displayDRMClass)
displayClass->connect = wpeDisplayDRMConnect;
displayClass->create_view = wpeDisplayDRMCreateView;
displayClass->get_preferred_dma_buf_formats = wpeDisplayDRMGetPreferredDMABufFormats;
displayClass->get_n_monitors = wpeDisplayDRMGetNMonitors;
displayClass->get_monitor = wpeDisplayDRMGetMonitor;
}

const WPE::DRM::Connector& wpeDisplayDRMGetConnector(WPEDisplayDRM* display)
{
return *display->priv->connector;
}

const WPE::DRM::Crtc& wpeDisplayDRMGetCrtc(WPEDisplayDRM* display)
WPEMonitor* wpeDisplayDRMGetMonitor(WPEDisplayDRM* display)
{
return *display->priv->crtc;
return display->priv->monitor.get();
}

const WPE::DRM::Plane& wpeDisplayDRMGetPrimaryPlane(WPEDisplayDRM* display)
Expand Down
3 changes: 2 additions & 1 deletion Source/WebKit/WPEPlatform/wpe/drm/WPEDisplayDRMPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@
#include "WPEDRM.h"
#include "WPEDRMCursor.h"
#include "WPEDRMSeat.h"
#include "WPEMonitor.h"

const WPE::DRM::Connector& wpeDisplayDRMGetConnector(WPEDisplayDRM*);
const WPE::DRM::Crtc& wpeDisplayDRMGetCrtc(WPEDisplayDRM*);
WPEMonitor* wpeDisplayDRMGetMonitor(WPEDisplayDRM*);
const WPE::DRM::Plane& wpeDisplayDRMGetPrimaryPlane(WPEDisplayDRM*);
WPE::DRM::Cursor* wpeDisplayDRMGetCursor(WPEDisplayDRM*);
const WPE::DRM::Seat& wpeDisplayDRMGetSeat(WPEDisplayDRM*);
134 changes: 134 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/drm/WPEMonitorDRM.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2024 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"
#include "WPEMonitorDRM.h"

#include "WPEMonitorDRMPrivate.h"
#include <wtf/glib/WTFGType.h>

/**
* WPEMonitorDRM:
*
*/
struct _WPEMonitorDRMPrivate {
std::unique_ptr<WPE::DRM::Crtc> crtc;
drmModeModeInfo mode;
};
WEBKIT_DEFINE_FINAL_TYPE(WPEMonitorDRM, wpe_monitor_drm, WPE_TYPE_MONITOR, WPEMonitor)

static void wpeMonitorDRMInvalidate(WPEMonitor* monitor)
{
auto* priv = WPE_MONITOR_DRM(monitor)->priv;
priv->crtc = nullptr;
}

static void wpeMonitorDRMDispose(GObject* object)
{
wpeMonitorDRMInvalidate(WPE_MONITOR(object));

G_OBJECT_CLASS(wpe_monitor_drm_parent_class)->dispose(object);
}

static void wpe_monitor_drm_class_init(WPEMonitorDRMClass* monitorDRMClass)
{
GObjectClass* objectClass = G_OBJECT_CLASS(monitorDRMClass);
objectClass->dispose = wpeMonitorDRMDispose;

WPEMonitorClass* monitorClass = WPE_MONITOR_CLASS(monitorDRMClass);
monitorClass->invalidate = wpeMonitorDRMInvalidate;
}

WPEMonitor* wpeMonitorDRMCreate(std::unique_ptr<WPE::DRM::Crtc>&& crtc, const WPE::DRM::Connector& connector)
{
auto* monitor = WPE_MONITOR(g_object_new(WPE_TYPE_MONITOR_DRM, "id", crtc->id(), nullptr));
auto* priv = WPE_MONITOR_DRM(monitor)->priv;
priv->crtc = WTFMove(crtc);

wpe_monitor_set_position(monitor, priv->crtc->x(), priv->crtc->y());
wpe_monitor_set_size(monitor, priv->crtc->width(), priv->crtc->height());
wpe_monitor_set_physical_size(monitor, connector.widthMM(), connector.heightMM());

if (const char* scaleString = getenv("WPE_DRM_SCALE"))
wpe_monitor_set_scale(monitor, g_ascii_strtod(scaleString, nullptr));

if (const auto& mode = priv->crtc->currentMode())
priv->mode = mode.value();
else {
if (const auto& preferredModeIndex = connector.preferredModeIndex())
priv->mode = connector.modes()[preferredModeIndex.value()];
else {
int area = 0;
for (const auto& mode : connector.modes()) {
int modeArea = mode.hdisplay * mode.vdisplay;
if (modeArea > area) {
priv->mode = mode;
area = modeArea;
}
}
}
}

uint32_t refresh = [](drmModeModeInfo* info) -> uint32_t {
uint64_t refresh = (info->clock * 1000000LL / info->htotal + info->vtotal / 2) / info->vtotal;
if (info->flags & DRM_MODE_FLAG_INTERLACE)
refresh *= 2;
if (info->flags & DRM_MODE_FLAG_DBLSCAN)
refresh /= 2;
if (info->vscan > 1)
refresh /= info->vscan;

return refresh;
}(&priv->mode);

wpe_monitor_set_refresh_rate(monitor, refresh);

return WPE_MONITOR(monitor);
}

drmModeModeInfo* wpeMonitorDRMGetMode(WPEMonitorDRM* monitor)
{
return &monitor->priv->mode;
}

const WPE::DRM::Crtc wpeMonitorDRMGetCrtc(WPEMonitorDRM* monitor)
{
return *monitor->priv->crtc;
}

/**
* wpe_monitor_drm_get_crtc_index: (skip)
* @monitor: a #WPEMonitorDRM
*
* Get the DRM CRTC index of @monitor
*
* Returns: the CRTC index
*/
guint wpe_monitor_drm_get_crtc_index(WPEMonitorDRM* monitor)
{
g_return_val_if_fail(WPE_IS_MONITOR_DRM(monitor), 0);

return monitor->priv->crtc->index();
}
45 changes: 45 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/drm/WPEMonitorDRM.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2024 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef WPEMonitorDRM_h
#define WPEMonitorDRM_h

#if !defined(__WPE_DRM_H_INSIDE__) && !defined(BUILDING_WEBKIT)
#error "Only <wpe/drm/wpe-drm.h> can be included directly."
#endif

#include <glib-object.h>
#include <wpe/wpe-platform.h>

G_BEGIN_DECLS

#define WPE_TYPE_MONITOR_DRM (wpe_monitor_drm_get_type())
WPE_API G_DECLARE_FINAL_TYPE (WPEMonitorDRM, wpe_monitor_drm, WPE, MONITOR_DRM, WPEMonitor)

WPE_API guint wpe_monitor_drm_get_crtc_index(WPEMonitorDRM *monitor);

G_END_DECLS

#endif /* WPEMonitorDRM_h */
33 changes: 33 additions & 0 deletions Source/WebKit/WPEPlatform/wpe/drm/WPEMonitorDRMPrivate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2024 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#include "WPEDRM.h"
#include "WPEMonitorDRM.h"

WPEMonitor* wpeMonitorDRMCreate(std::unique_ptr<WPE::DRM::Crtc>&&, const WPE::DRM::Connector&);
drmModeModeInfo* wpeMonitorDRMGetMode(WPEMonitorDRM*);
const WPE::DRM::Crtc wpeMonitorDRMGetCrtc(WPEMonitorDRM*);
Loading

0 comments on commit b96094f

Please sign in to comment.