mirror of
https://github.com/moonlight-stream/moonlight-qt.git
synced 2026-04-24 00:47:23 +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
|
// Dirty the modified portion of the plane
|
||||||
drmModeClip clip;
|
m_PropSetter.damagePlane(m_OverlayPlanes[0], overlayUnionRect);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Clear the pixels where this overlay was drawn before
|
// Clear the pixels where this overlay was drawn before
|
||||||
SDL_FillRect(m_OverlayCompositionSurface, &m_OverlayRects[type], 0);
|
SDL_FillRect(m_OverlayCompositionSurface, &m_OverlayRects[type], 0);
|
||||||
|
|
||||||
// Dirty the modified portion of the FB
|
// Dirty the modified portion of the plane
|
||||||
drmModeClip clip;
|
m_PropSetter.damagePlane(m_OverlayPlanes[0], m_OverlayRects[type]);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -213,6 +213,8 @@ class DrmRenderer : public IFFmpegRenderer {
|
|||||||
// Atomic only
|
// Atomic only
|
||||||
uint32_t pendingFbId;
|
uint32_t pendingFbId;
|
||||||
uint32_t pendingDumbBuffer;
|
uint32_t pendingDumbBuffer;
|
||||||
|
uint32_t fbDamageClipsPropId;
|
||||||
|
std::vector<drm_mode_rect> pendingFbDamageRects;
|
||||||
bool modified;
|
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;
|
int err;
|
||||||
|
|
||||||
if (m_Atomic) {
|
if (m_Atomic) {
|
||||||
@@ -281,7 +283,7 @@ class DrmRenderer : public IFFmpegRenderer {
|
|||||||
m_AtomicReq = drmModeAtomicAlloc();
|
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,
|
// This returns the new count of properties on success,
|
||||||
// so normalize it to 0 like drmModeObjectSetProperty()
|
// so normalize it to 0 like drmModeObjectSetProperty()
|
||||||
@@ -290,9 +292,14 @@ class DrmRenderer : public IFFmpegRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
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) {
|
if (verbose && err == 0) {
|
||||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Set property '%s': %" PRIu64,
|
"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,
|
bool testPlane(const DrmPropertyMap& plane,
|
||||||
uint32_t crtcId, uint32_t fbId,
|
uint32_t crtcId, uint32_t fbId,
|
||||||
int32_t crtcX, int32_t crtcY,
|
int32_t crtcX, int32_t crtcY,
|
||||||
@@ -500,11 +527,41 @@ class DrmRenderer : public IFFmpegRenderer {
|
|||||||
|
|
||||||
drmModeAtomicReqPtr req = nullptr;
|
drmModeAtomicReqPtr req = nullptr;
|
||||||
std::unordered_map<uint32_t, PlaneBuffer> pendingBuffers;
|
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
|
// Take ownership of the current atomic request to commit it and
|
||||||
// allow other threads to queue up changes for the next one.
|
// allow other threads to queue up changes for the next one.
|
||||||
std::lock_guard lg { m_Lock };
|
|
||||||
std::swap(req, m_AtomicReq);
|
std::swap(req, m_AtomicReq);
|
||||||
std::swap(pendingBuffers, m_PlaneBuffers);
|
std::swap(pendingBuffers, m_PlaneBuffers);
|
||||||
}
|
}
|
||||||
@@ -541,6 +598,11 @@ class DrmRenderer : public IFFmpegRenderer {
|
|||||||
err);
|
err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Free the damage clip blobs
|
||||||
|
for (auto blobId : damageBlobIds) {
|
||||||
|
drmModeDestroyPropertyBlob(m_Fd, blobId);
|
||||||
|
}
|
||||||
|
|
||||||
// Update the buffer state for any modified planes
|
// Update the buffer state for any modified planes
|
||||||
std::lock_guard lg { m_Lock };
|
std::lock_guard lg { m_Lock };
|
||||||
for (auto it = pendingBuffers.begin(); it != pendingBuffers.end(); it++) {
|
for (auto it = pendingBuffers.begin(); it != pendingBuffers.end(); it++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user