mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-02-16 02:30:52 +00:00
Use FB_DAMAGE_CLIPS instead of drmModeDirtyFB()
This commit is contained in:
@@ -1480,25 +1480,15 @@ void DrmRenderer::blitOverlayToCompositionSurface(Overlay::OverlayType type, SDL
|
||||
}
|
||||
}
|
||||
|
||||
// Dirty the modified portion of the FB
|
||||
drmModeClip clip;
|
||||
clip.x1 = overlayUnionRect.x;
|
||||
clip.x2 = overlayUnionRect.x + overlayUnionRect.w;
|
||||
clip.y1 = overlayUnionRect.y;
|
||||
clip.y2 = overlayUnionRect.y + overlayUnionRect.h;
|
||||
drmModeDirtyFB(m_DrmFd, m_OverlayCompositionSurfaceFbId, &clip, 1);
|
||||
// Dirty the modified portion of the plane
|
||||
m_PropSetter.damagePlane(m_OverlayPlanes[0], overlayUnionRect);
|
||||
}
|
||||
else {
|
||||
// Clear the pixels where this overlay was drawn before
|
||||
SDL_FillRect(m_OverlayCompositionSurface, &m_OverlayRects[type], 0);
|
||||
|
||||
// Dirty the modified portion of the FB
|
||||
drmModeClip clip;
|
||||
clip.x1 = m_OverlayRects[type].x;
|
||||
clip.x2 = m_OverlayRects[type].x + m_OverlayRects[type].w;
|
||||
clip.y1 = m_OverlayRects[type].y;
|
||||
clip.y2 = m_OverlayRects[type].y + m_OverlayRects[type].h;
|
||||
drmModeDirtyFB(m_DrmFd, m_OverlayCompositionSurfaceFbId, &clip, 1);
|
||||
// Dirty the modified portion of the plane
|
||||
m_PropSetter.damagePlane(m_OverlayPlanes[0], m_OverlayRects[type]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,6 +213,8 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
// Atomic only
|
||||
uint32_t pendingFbId;
|
||||
uint32_t pendingDumbBuffer;
|
||||
uint32_t fbDamageClipsPropId;
|
||||
std::vector<drm_mode_rect> pendingFbDamageRects;
|
||||
bool modified;
|
||||
};
|
||||
|
||||
@@ -270,7 +272,7 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
bool set(const DrmProperty& prop, uint64_t value, bool verbose = true) {
|
||||
int set(uint32_t objectId, uint32_t objectType, uint32_t propId, uint64_t value) {
|
||||
int err;
|
||||
|
||||
if (m_Atomic) {
|
||||
@@ -281,7 +283,7 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
m_AtomicReq = drmModeAtomicAlloc();
|
||||
}
|
||||
|
||||
err = drmModeAtomicAddProperty(m_AtomicReq, prop.objectId(), prop.id(), value);
|
||||
err = drmModeAtomicAddProperty(m_AtomicReq, objectId, propId, value);
|
||||
|
||||
// This returns the new count of properties on success,
|
||||
// so normalize it to 0 like drmModeObjectSetProperty()
|
||||
@@ -290,9 +292,14 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = drmModeObjectSetProperty(m_Fd, prop.objectId(), prop.objectType(), prop.id(), value);
|
||||
err = drmModeObjectSetProperty(m_Fd, objectId, objectType, propId, value);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
bool set(const DrmProperty& prop, uint64_t value, bool verbose = true) {
|
||||
int err = set(prop.objectId(), prop.objectType(), prop.id(), value);
|
||||
if (verbose && err == 0) {
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Set property '%s': %" PRIu64,
|
||||
@@ -440,6 +447,26 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// The damage rect is relative to the FB
|
||||
void damagePlane(const DrmPropertyMap& plane, const SDL_Rect& rect) {
|
||||
SDL_assert(m_Atomic);
|
||||
|
||||
if (auto prop = plane.property("FB_DAMAGE_CLIPS")) {
|
||||
std::lock_guard lg { m_Lock };
|
||||
auto& pb = m_PlaneBuffers[plane.objectId()];
|
||||
|
||||
// Append this new damage rect to our existing list
|
||||
drm_mode_rect drmRect;
|
||||
drmRect.x1 = rect.x;
|
||||
drmRect.x2 = rect.x + rect.w;
|
||||
drmRect.y1 = rect.y;
|
||||
drmRect.y2 = rect.y + rect.h;
|
||||
pb.pendingFbDamageRects.emplace_back(std::move(drmRect));
|
||||
|
||||
pb.fbDamageClipsPropId = prop->id();
|
||||
}
|
||||
}
|
||||
|
||||
bool testPlane(const DrmPropertyMap& plane,
|
||||
uint32_t crtcId, uint32_t fbId,
|
||||
int32_t crtcX, int32_t crtcY,
|
||||
@@ -500,11 +527,41 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
|
||||
drmModeAtomicReqPtr req = nullptr;
|
||||
std::unordered_map<uint32_t, PlaneBuffer> pendingBuffers;
|
||||
std::vector<uint32_t> damageBlobIds;
|
||||
|
||||
{
|
||||
std::lock_guard lg { m_Lock };
|
||||
|
||||
// Create property blobs for any pending FB damage clip rects
|
||||
for (auto &[planeId, pb] : m_PlaneBuffers) {
|
||||
uint32_t damageBlob;
|
||||
|
||||
if (!pb.pendingFbDamageRects.empty()) {
|
||||
int err = drmModeCreatePropertyBlob(m_Fd,
|
||||
pb.pendingFbDamageRects.data(),
|
||||
pb.pendingFbDamageRects.size() * sizeof(drm_mode_rect),
|
||||
&damageBlob);
|
||||
if (err < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"drmModeCreatePropertyBlob(FB_DAMAGE_CLIPS) failed: %d",
|
||||
err);
|
||||
continue;
|
||||
}
|
||||
|
||||
err = set(planeId, DRM_MODE_OBJECT_PLANE, pb.fbDamageClipsPropId, damageBlob);
|
||||
if (err < 0) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Failed to set property 'FB_DAMAGE_CLIPS': %d",
|
||||
err);
|
||||
// Fall-through
|
||||
}
|
||||
|
||||
damageBlobIds.emplace_back(damageBlob);
|
||||
}
|
||||
}
|
||||
|
||||
// Take ownership of the current atomic request to commit it and
|
||||
// allow other threads to queue up changes for the next one.
|
||||
std::lock_guard lg { m_Lock };
|
||||
std::swap(req, m_AtomicReq);
|
||||
std::swap(pendingBuffers, m_PlaneBuffers);
|
||||
}
|
||||
@@ -541,6 +598,11 @@ class DrmRenderer : public IFFmpegRenderer {
|
||||
err);
|
||||
}
|
||||
|
||||
// Free the damage clip blobs
|
||||
for (auto blobId : damageBlobIds) {
|
||||
drmModeDestroyPropertyBlob(m_Fd, blobId);
|
||||
}
|
||||
|
||||
// Update the buffer state for any modified planes
|
||||
std::lock_guard lg { m_Lock };
|
||||
for (auto it = pendingBuffers.begin(); it != pendingBuffers.end(); it++) {
|
||||
|
||||
Reference in New Issue
Block a user