From 9fe409800ba5466017be8dfa16a55ca9833a416e Mon Sep 17 00:00:00 2001 From: Virt <41426325+VirtCode@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:29:41 +0200 Subject: renderer: Fix mirrored displays when transformed and preserve aspect ratio (#5697) * renderer: transform mirror buffer and preserve mirror aspect ratio * renderer: render mirrors directly from offloadFB * renderer: fix formatting * renderer: use monitorMirrorFB again, but properly damage mirrors * renderer: clean mirrors after reload and support cursor zoom mirroring --- src/render/Renderer.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src/render/Renderer.cpp') diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index 4b1e7ace..36d4f9b6 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1246,9 +1246,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) { } // if we have no tracking or full tracking, invalidate the entire monitor - if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || pMonitor->forceFullFrames > 0 || damageBlinkCleanup > 0 || - pMonitor->isMirror() /* why??? */) { - + if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || pMonitor->forceFullFrames > 0 || damageBlinkCleanup > 0) { damage = {0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10}; finalDamage = damage; } else { @@ -1838,11 +1836,24 @@ void CHyprRenderer::damageRegion(const CRegion& rg) { void CHyprRenderer::damageMirrorsWith(CMonitor* pMonitor, const CRegion& pRegion) { for (auto& mirror : pMonitor->mirrors) { - Vector2D scale = {mirror->vecSize.x / pMonitor->vecSize.x, mirror->vecSize.y / pMonitor->vecSize.y}; - CRegion rg{pRegion}; - wlr_region_scale_xy(rg.pixman(), rg.pixman(), scale.x, scale.y); - pMonitor->addDamage(&rg); + // transform the damage here, so it won't get clipped by the monitor damage ring + auto monitor = mirror; + auto mirrored = pMonitor; + + CRegion transformed{pRegion}; + + // we want to transform to the same box as in CHyprOpenGLImpl::renderMirrored + double scale = std::min(monitor->vecTransformedSize.x / mirrored->vecTransformedSize.x, monitor->vecTransformedSize.y / mirrored->vecTransformedSize.y); + CBox monbox = {0, 0, mirrored->vecTransformedSize.x * scale, mirrored->vecTransformedSize.y * scale}; + monbox.x = (monitor->vecTransformedSize.x - monbox.w) / 2; + monbox.y = (monitor->vecTransformedSize.y - monbox.h) / 2; + + wlr_region_scale(transformed.pixman(), transformed.pixman(), scale); + transformed.transform(mirrored->transform, mirrored->vecPixelSize.x * scale, mirrored->vecPixelSize.y * scale); + transformed.translate(Vector2D(monbox.x, monbox.y)); + + mirror->addDamage(&transformed); g_pCompositor->scheduleFrameForMonitor(mirror); } -- cgit v1.2.3