Skip to content

Commit ea5a4b0

Browse files
committed
[WPE] WPE Platform: use damage region in DRM platform
https://bugs.webkit.org/show_bug.cgi?id=276252 Reviewed by Alejandro G. Castro. * Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.cpp: (WPE::DRM::Plane::create): * Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.h: * Source/WebKit/WPEPlatform/wpe/drm/WPEViewDRM.cpp: (emptyPlaneProperties): (primaryPlaneProperties): (addPlaneProperties): (wpeViewDRMCommitAtomic): (buildDamageBlob): (destroyDamageBlob): (wpeViewDRMRequestUpdate): (wpeViewDRMRenderBuffer): Canonical link: https://commits.webkit.org/281337@main
1 parent b99bd62 commit ea5a4b0

File tree

3 files changed

+55
-9
lines changed

3 files changed

+55
-9
lines changed

Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,8 @@ std::unique_ptr<Plane> Plane::create(int fd, Type type, drmModePlane* plane, boo
168168
drmPropertyForName(fd, properties.get(), "SRC_X"),
169169
drmPropertyForName(fd, properties.get(), "SRC_Y"),
170170
drmPropertyForName(fd, properties.get(), "SRC_W"),
171-
drmPropertyForName(fd, properties.get(), "SRC_H")
171+
drmPropertyForName(fd, properties.get(), "SRC_H"),
172+
drmPropertyForName(fd, properties.get(), "FB_DAMAGE_CLIPS")
172173
};
173174
return makeUnique<Plane>(plane, WTFMove(formats), WTFMove(props));
174175
}

Source/WebKit/WPEPlatform/wpe/drm/WPEDRM.h

+1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class Plane {
121121
Property srcY { 0, 0 };
122122
Property srcW { 0, 0 };
123123
Property srcH { 0, 0 };
124+
Property fbDamageClips { 0, 0 };
124125
};
125126

126127
struct Format {

Source/WebKit/WPEPlatform/wpe/drm/WPEViewDRM.cpp

+52-8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <wtf/FastMalloc.h>
3838
#include <wtf/OptionSet.h>
3939
#include <wtf/RunLoop.h>
40+
#include <wtf/SafeStrerror.h>
4041
#include <wtf/Seconds.h>
4142
#include <wtf/glib/GRefPtr.h>
4243
#include <wtf/glib/WTFGType.h>
@@ -57,6 +58,7 @@ struct _WPEViewDRMPrivate {
5758
std::optional<uint32_t> modeBlob;
5859
GRefPtr<WPEBuffer> pendingBuffer;
5960
GRefPtr<WPEBuffer> committedBuffer;
61+
Vector<drm_mode_rect> damageRects;
6062
drmEventContext eventContext;
6163
GRefPtr<GSource> eventSource;
6264
OptionSet<UpdateFlags> updateFlags;
@@ -247,10 +249,11 @@ WPE::DRM::Plane::Properties emptyPlaneProperties(const WPE::DRM::Plane& plane)
247249
properties.srcY.second = 0;
248250
properties.srcW.second = 0;
249251
properties.srcH.second = 0;
252+
properties.fbDamageClips.second = 0;
250253
return properties;
251254
}
252255

253-
WPE::DRM::Plane::Properties primaryPlaneProperties(const WPE::DRM::Plane& plane, uint32_t crtcID, drmModeModeInfo* mode, const WPE::DRM::Buffer& buffer)
256+
WPE::DRM::Plane::Properties primaryPlaneProperties(const WPE::DRM::Plane& plane, uint32_t crtcID, drmModeModeInfo* mode, const WPE::DRM::Buffer& buffer, std::optional<uint32_t> damageID)
254257
{
255258
auto properties = plane.properties();
256259
properties.crtcID.second = crtcID;
@@ -263,6 +266,8 @@ WPE::DRM::Plane::Properties primaryPlaneProperties(const WPE::DRM::Plane& plane,
263266
properties.srcY.second = 0;
264267
properties.srcW.second = (static_cast<uint64_t>(gbm_bo_get_width(buffer.bufferObject())) << 16);
265268
properties.srcH.second = (static_cast<uint64_t>(gbm_bo_get_height(buffer.bufferObject())) << 16);
269+
if (properties.fbDamageClips.first && damageID)
270+
properties.fbDamageClips.second = damageID.value();
266271
return properties;
267272
}
268273

@@ -294,10 +299,12 @@ static bool addPlaneProperties(drmModeAtomicReq* request, const WPE::DRM::Plane&
294299
success &= drmAtomicAddProperty(request, plane.id(), properties.srcY);
295300
success &= drmAtomicAddProperty(request, plane.id(), properties.srcW);
296301
success &= drmAtomicAddProperty(request, plane.id(), properties.srcH);
302+
if (properties.fbDamageClips.first)
303+
success &= drmAtomicAddProperty(request, plane.id(), properties.fbDamageClips);
297304
return success;
298305
}
299306

300-
static bool wpeViewDRMCommitAtomic(WPEViewDRM* view, WPE::DRM::Buffer* buffer, GError** error)
307+
static bool wpeViewDRMCommitAtomic(WPEViewDRM* view, WPE::DRM::Buffer* buffer, std::optional<uint32_t> damageID, GError** error)
301308
{
302309
WPE::DRM::UniquePtr<drmModeAtomicReq> request(drmModeAtomicAlloc());
303310
uint32_t flags = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK;
@@ -312,8 +319,9 @@ static bool wpeViewDRMCommitAtomic(WPEViewDRM* view, WPE::DRM::Buffer* buffer, G
312319

313320
if (!view->priv->modeBlob) {
314321
uint32_t blobID;
315-
if (drmModeCreatePropertyBlob(fd, mode, sizeof(drmModeModeInfo), &blobID) == -1) {
316-
g_set_error_literal(error, WPE_VIEW_ERROR, WPE_VIEW_ERROR_RENDER_FAILED, "Failed to render buffer: failed to crate blob from DRM mode");
322+
auto result = drmModeCreatePropertyBlob(fd, mode, sizeof(drmModeModeInfo), &blobID);
323+
if (result < 0) {
324+
g_set_error(error, WPE_VIEW_ERROR, WPE_VIEW_ERROR_RENDER_FAILED, "Failed to render buffer: failed to crate blob from DRM mode: %s", safeStrerror(-result).data());
317325
return false;
318326
}
319327

@@ -330,7 +338,7 @@ static bool wpeViewDRMCommitAtomic(WPEViewDRM* view, WPE::DRM::Buffer* buffer, G
330338
}
331339

332340
auto& plane = wpeDisplayDRMGetPrimaryPlane(display);
333-
if (!addPlaneProperties(request.get(), plane, buffer ? primaryPlaneProperties(plane, crtc.id(), mode, *buffer) : emptyPlaneProperties(plane))) {
341+
if (!addPlaneProperties(request.get(), plane, buffer ? primaryPlaneProperties(plane, crtc.id(), mode, *buffer, damageID) : emptyPlaneProperties(plane))) {
334342
g_set_error_literal(error, WPE_VIEW_ERROR, WPE_VIEW_ERROR_RENDER_FAILED, "Failed to render buffer: failed to set plane properties");
335343
return false;
336344
}
@@ -382,18 +390,50 @@ static std::pair<uint32_t, uint64_t> wpeBufferFormat(WPEBuffer* buffer)
382390
return { DRM_FORMAT_INVALID, DRM_FORMAT_MOD_INVALID };
383391
}
384392

393+
static std::optional<uint32_t> buildDamageBlob(WPEDisplayDRM* display, const Vector<drm_mode_rect>& damageRects, GError** error)
394+
{
395+
if (damageRects.isEmpty())
396+
return std::nullopt;
397+
398+
uint32_t blobID;
399+
int fd = gbm_device_get_fd(wpe_display_drm_get_device(display));
400+
auto result = drmModeCreatePropertyBlob(fd, damageRects.data(), damageRects.sizeInBytes(), &blobID);
401+
if (result < 0) {
402+
g_set_error(error, WPE_VIEW_ERROR, WPE_VIEW_ERROR_RENDER_FAILED, "Failed to render buffer: failed to crate damage blob: %s", safeStrerror(-result).data());
403+
return 0;
404+
}
405+
406+
return blobID;
407+
}
408+
409+
static void destroyDamageBlob(WPEDisplayDRM* display, uint32_t blobID)
410+
{
411+
int fd = gbm_device_get_fd(wpe_display_drm_get_device(display));
412+
drmModeDestroyPropertyBlob(fd, blobID);
413+
}
414+
385415
static gboolean wpeViewDRMRequestUpdate(WPEViewDRM* view, GError** error)
386416
{
387417
auto* priv = view->priv;
388418
auto* buffer = priv->pendingBuffer ? priv->pendingBuffer.get() : priv->committedBuffer.get();
389419
auto* drmBuffer = buffer ? static_cast<WPE::DRM::Buffer*>(wpe_buffer_get_user_data(buffer)) : nullptr;
390-
if (wpe_display_drm_supports_atomic(WPE_DISPLAY_DRM(wpe_view_get_display(WPE_VIEW(view)))))
391-
return wpeViewDRMCommitAtomic(WPE_VIEW_DRM(view), drmBuffer, error);
420+
auto* display = WPE_DISPLAY_DRM(wpe_view_get_display(WPE_VIEW(view)));
421+
if (wpe_display_drm_supports_atomic(display)) {
422+
auto damageID = drmBuffer ? buildDamageBlob(display, priv->damageRects, error) : std::nullopt;
423+
if (damageID.has_value() && !damageID.value())
424+
return FALSE;
425+
426+
auto result = wpeViewDRMCommitAtomic(WPE_VIEW_DRM(view), drmBuffer, damageID, error);
427+
if (damageID)
428+
destroyDamageBlob(display, damageID.value());
429+
priv->damageRects.clear();
430+
return result;
431+
}
392432

393433
return wpeViewDRMCommitLegacy(WPE_VIEW_DRM(view), *drmBuffer, error);
394434
}
395435

396-
static gboolean wpeViewDRMRenderBuffer(WPEView* view, WPEBuffer* buffer, const WPERectangle*, guint, GError** error)
436+
static gboolean wpeViewDRMRenderBuffer(WPEView* view, WPEBuffer* buffer, const WPERectangle* damageRects, guint nDamageRects, GError** error)
397437
{
398438
auto* drmBuffer = static_cast<WPE::DRM::Buffer*>(wpe_buffer_get_user_data(buffer));
399439
if (!drmBuffer) {
@@ -411,6 +451,10 @@ static gboolean wpeViewDRMRenderBuffer(WPEView* view, WPEBuffer* buffer, const W
411451
}
412452
auto* priv = WPE_VIEW_DRM(view)->priv;
413453
priv->pendingBuffer = buffer;
454+
priv->damageRects.clear();
455+
priv->damageRects.reserveInitialCapacity(nDamageRects);
456+
for (unsigned i = 0; i < nDamageRects; ++i)
457+
priv->damageRects.append({ damageRects[i].x, damageRects[i].y, damageRects[i].x + damageRects[i].width, damageRects[i].y + damageRects[i].height });
414458

415459
if (priv->updateFlags.contains(UpdateFlags::CursorUpdateRequested)) {
416460
priv->updateFlags.add(UpdateFlags::BufferUpdatePending);

0 commit comments

Comments
 (0)