mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-05 06:31:57 -07:00
internal: Wrap regions (#2750)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
#include "Renderer.hpp"
|
||||
#include "../Compositor.hpp"
|
||||
#include "linux-dmabuf-unstable-v1-protocol.h"
|
||||
#include "../helpers/Region.hpp"
|
||||
|
||||
void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
|
||||
const auto TEXTURE = wlr_surface_get_texture(surface);
|
||||
@@ -455,8 +456,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
||||
g_pHyprOpenGL->m_RenderData.renderModif = RENDERMODIFDATA;
|
||||
|
||||
// for storing damage when we optimize for occlusion
|
||||
pixman_region32_t backupDamage;
|
||||
pixman_region32_init(&backupDamage);
|
||||
CRegion preOccludedDamage{g_pHyprOpenGL->m_RenderData.damage};
|
||||
|
||||
// Render layer surfaces below windows for monitor
|
||||
// if we have a fullscreen, opaque window that convers the screen, we can skip this.
|
||||
@@ -465,8 +465,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
||||
if (!pWorkspace->m_bHasFullscreenWindow || pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL || !PFULLWINDOW || PFULLWINDOW->m_vRealSize.isBeingAnimated() ||
|
||||
!PFULLWINDOW->opaque() || pWorkspace->m_vRenderOffset.vec() != Vector2D{}) {
|
||||
|
||||
pixman_region32_copy(&backupDamage, g_pHyprOpenGL->m_RenderData.pDamage);
|
||||
setOccludedForBackLayers(g_pHyprOpenGL->m_RenderData.pDamage, pWorkspace);
|
||||
setOccludedForBackLayers(g_pHyprOpenGL->m_RenderData.damage, pWorkspace);
|
||||
|
||||
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) {
|
||||
renderLayer(ls.get(), pMonitor, time);
|
||||
@@ -475,11 +474,9 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
|
||||
renderLayer(ls.get(), pMonitor, time);
|
||||
}
|
||||
|
||||
pixman_region32_copy(g_pHyprOpenGL->m_RenderData.pDamage, &backupDamage);
|
||||
g_pHyprOpenGL->m_RenderData.damage = preOccludedDamage;
|
||||
}
|
||||
|
||||
pixman_region32_fini(&backupDamage);
|
||||
|
||||
// pre window pass
|
||||
g_pHyprOpenGL->preWindowPass();
|
||||
|
||||
@@ -906,9 +903,9 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
|
||||
// check the damage
|
||||
pixman_region32_t damage;
|
||||
bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current);
|
||||
int bufferAge;
|
||||
CRegion damage;
|
||||
bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current);
|
||||
int bufferAge;
|
||||
|
||||
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0)
|
||||
return;
|
||||
@@ -933,8 +930,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||
return;
|
||||
}
|
||||
|
||||
pixman_region32_init(&damage);
|
||||
wlr_damage_ring_get_buffer_damage(&pMonitor->damage, bufferAge, &damage);
|
||||
wlr_damage_ring_get_buffer_damage(&pMonitor->damage, bufferAge, damage.pixman());
|
||||
|
||||
pMonitor->renderingActive = true;
|
||||
|
||||
@@ -944,9 +940,9 @@ 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??? */) {
|
||||
pixman_region32_union_rect(&damage, &damage, 0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10); // wot?
|
||||
|
||||
pixman_region32_copy(&pMonitor->lastFrameDamage, &damage);
|
||||
damage = {0, 0, (int)pMonitor->vecTransformedSize.x * 10, (int)pMonitor->vecTransformedSize.y * 10};
|
||||
pMonitor->lastFrameDamage = damage;
|
||||
} else {
|
||||
static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
|
||||
|
||||
@@ -958,14 +954,16 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||
const auto BLURRADIUS =
|
||||
*PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES); // is this 2^pass? I don't know but it works... I think.
|
||||
|
||||
auto extents = pixman_region32_extents(damage.pixman());
|
||||
|
||||
// now, prep the damage, get the extended damage region
|
||||
wlr_region_expand(&damage, &damage, BLURRADIUS); // expand for proper blurring
|
||||
wlr_region_expand(damage.pixman(), damage.pixman(), BLURRADIUS); // expand for proper blurring
|
||||
|
||||
pixman_region32_copy(&pMonitor->lastFrameDamage, &damage);
|
||||
pMonitor->lastFrameDamage = damage;
|
||||
|
||||
wlr_region_expand(&damage, &damage, BLURRADIUS); // expand for proper blurring 2
|
||||
wlr_region_expand(damage.pixman(), damage.pixman(), BLURRADIUS); // expand for proper blurring 2
|
||||
} else {
|
||||
pixman_region32_copy(&pMonitor->lastFrameDamage, &damage);
|
||||
pMonitor->lastFrameDamage = damage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1043,41 +1041,34 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
|
||||
g_pHyprOpenGL->end();
|
||||
|
||||
// calc frame damage
|
||||
pixman_region32_t frameDamage;
|
||||
pixman_region32_init(&frameDamage);
|
||||
CRegion frameDamage{};
|
||||
|
||||
const auto TRANSFORM = wlr_output_transform_invert(pMonitor->output->transform);
|
||||
wlr_region_transform(&frameDamage, &pMonitor->lastFrameDamage, TRANSFORM, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y);
|
||||
wlr_region_transform(frameDamage.pixman(), pMonitor->lastFrameDamage.pixman(), TRANSFORM, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y);
|
||||
|
||||
if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR)
|
||||
pixman_region32_union_rect(&frameDamage, &frameDamage, 0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y);
|
||||
frameDamage.add(0, 0, (int)pMonitor->vecTransformedSize.x, (int)pMonitor->vecTransformedSize.y);
|
||||
|
||||
if (*PDAMAGEBLINK)
|
||||
pixman_region32_union(&frameDamage, &frameDamage, &damage);
|
||||
frameDamage.add(damage);
|
||||
|
||||
wlr_output_set_damage(pMonitor->output, &frameDamage);
|
||||
//wlr_output_set_damage(pMonitor->output, frameDamage.pixman());
|
||||
|
||||
if (!pMonitor->mirrors.empty())
|
||||
g_pHyprRenderer->damageMirrorsWith(pMonitor, &frameDamage);
|
||||
|
||||
pixman_region32_fini(&frameDamage);
|
||||
g_pHyprRenderer->damageMirrorsWith(pMonitor, frameDamage);
|
||||
|
||||
pMonitor->renderingActive = false;
|
||||
|
||||
EMIT_HOOK_EVENT("render", RENDER_POST);
|
||||
|
||||
wlr_damage_ring_rotate(&pMonitor->damage);
|
||||
|
||||
if (!wlr_output_commit(pMonitor->output)) {
|
||||
pixman_region32_fini(&damage);
|
||||
|
||||
if (UNLOCK_SC)
|
||||
wlr_output_lock_software_cursors(pMonitor->output, false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damage);
|
||||
wlr_damage_ring_rotate(&pMonitor->damage);
|
||||
|
||||
if (UNLOCK_SC)
|
||||
wlr_output_lock_software_cursors(pMonitor->output, false);
|
||||
@@ -1391,24 +1382,20 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou
|
||||
if (g_pCompositor->m_bUnsafeState)
|
||||
return;
|
||||
|
||||
pixman_region32_t damageBox;
|
||||
pixman_region32_init(&damageBox);
|
||||
wlr_surface_get_effective_damage(pSurface, &damageBox);
|
||||
CRegion damageBox;
|
||||
wlr_surface_get_effective_damage(pSurface, damageBox.pixman());
|
||||
if (scale != 1.0)
|
||||
wlr_region_scale(&damageBox, &damageBox, scale);
|
||||
wlr_region_scale(damageBox.pixman(), damageBox.pixman(), scale);
|
||||
|
||||
// schedule frame events
|
||||
if (!wl_list_empty(&pSurface->current.frame_callback_list)) {
|
||||
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)));
|
||||
}
|
||||
|
||||
if (!pixman_region32_not_empty(&damageBox)) {
|
||||
pixman_region32_fini(&damageBox);
|
||||
if (damageBox.empty())
|
||||
return;
|
||||
}
|
||||
|
||||
pixman_region32_t damageBoxForEach;
|
||||
pixman_region32_init(&damageBoxForEach);
|
||||
CRegion damageBoxForEach;
|
||||
|
||||
for (auto& m : g_pCompositor->m_vMonitors) {
|
||||
if (!m->output)
|
||||
@@ -1417,23 +1404,19 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou
|
||||
double lx = 0, ly = 0;
|
||||
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly);
|
||||
|
||||
pixman_region32_copy(&damageBoxForEach, &damageBox);
|
||||
pixman_region32_translate(&damageBoxForEach, x - m->vecPosition.x, y - m->vecPosition.y);
|
||||
wlr_region_scale(&damageBoxForEach, &damageBoxForEach, m->scale);
|
||||
pixman_region32_translate(&damageBoxForEach, lx + m->vecPosition.x, ly + m->vecPosition.y);
|
||||
damageBoxForEach = damageBox;
|
||||
damageBoxForEach.translate({x - m->vecPosition.x, y - m->vecPosition.y});
|
||||
wlr_region_scale(damageBoxForEach.pixman(), damageBoxForEach.pixman(), m->scale);
|
||||
damageBoxForEach.translate({lx + m->vecPosition.x, ly + m->vecPosition.y});
|
||||
|
||||
m->addDamage(&damageBoxForEach);
|
||||
}
|
||||
|
||||
pixman_region32_fini(&damageBoxForEach);
|
||||
|
||||
static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
|
||||
|
||||
if (*PLOGDAMAGE)
|
||||
Debug::log(LOG, "Damage: Surface (extents): xy: %d, %d wh: %d, %d", damageBox.extents.x1, damageBox.extents.y1, damageBox.extents.x2 - damageBox.extents.x1,
|
||||
damageBox.extents.y2 - damageBox.extents.y1);
|
||||
|
||||
pixman_region32_fini(&damageBox);
|
||||
Debug::log(LOG, "Damage: Surface (extents): xy: %d, %d wh: %d, %d", damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y1,
|
||||
damageBox.pixman()->extents.x2 - damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y2 - damageBox.pixman()->extents.y1);
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageWindow(CWindow* pWindow) {
|
||||
@@ -1493,23 +1476,19 @@ void CHyprRenderer::damageBox(const int& x, const int& y, const int& w, const in
|
||||
damageBox(&box);
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageRegion(pixman_region32_t* rg) {
|
||||
PIXMAN_DAMAGE_FOREACH(rg) {
|
||||
const auto RECT = RECTSARR[i];
|
||||
void CHyprRenderer::damageRegion(const CRegion& rg) {
|
||||
for (auto& RECT : rg.getRects()) {
|
||||
damageBox(RECT.x1, RECT.y1, RECT.x2 - RECT.x1, RECT.y2 - RECT.y1);
|
||||
}
|
||||
}
|
||||
|
||||
void CHyprRenderer::damageMirrorsWith(CMonitor* pMonitor, pixman_region32_t* pRegion) {
|
||||
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};
|
||||
Vector2D scale = {mirror->vecSize.x / pMonitor->vecSize.x, mirror->vecSize.y / pMonitor->vecSize.y};
|
||||
|
||||
pixman_region32_t rg;
|
||||
pixman_region32_init(&rg);
|
||||
pixman_region32_copy(&rg, pRegion);
|
||||
wlr_region_scale_xy(&rg, &rg, scale.x, scale.y);
|
||||
CRegion rg{pRegion};
|
||||
wlr_region_scale_xy(rg.pixman(), rg.pixman(), scale.x, scale.y);
|
||||
pMonitor->addDamage(&rg);
|
||||
pixman_region32_fini(&rg);
|
||||
|
||||
g_pCompositor->scheduleFrameForMonitor(mirror);
|
||||
}
|
||||
@@ -1986,9 +1965,8 @@ void CHyprRenderer::initiateManualCrash() {
|
||||
g_pConfigManager->setInt("debug:damage_tracking", 0);
|
||||
}
|
||||
|
||||
void CHyprRenderer::setOccludedForBackLayers(pixman_region32_t* region, CWorkspace* pWorkspace) {
|
||||
pixman_region32_t rg;
|
||||
pixman_region32_init(&rg);
|
||||
void CHyprRenderer::setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace) {
|
||||
CRegion rg;
|
||||
|
||||
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID);
|
||||
|
||||
@@ -2003,10 +1981,8 @@ void CHyprRenderer::setOccludedForBackLayers(pixman_region32_t* region, CWorkspa
|
||||
const Vector2D POS = w->m_vRealPosition.vec() + Vector2D{ROUNDING, ROUNDING};
|
||||
const Vector2D SIZE = w->m_vRealSize.vec() - Vector2D{ROUNDING * 2, ROUNDING * 2};
|
||||
|
||||
pixman_region32_union_rect(&rg, &rg, POS.x, POS.y, SIZE.x, SIZE.y);
|
||||
rg.add(POS.x, POS.y, SIZE.x, SIZE.y);
|
||||
}
|
||||
|
||||
pixman_region32_subtract(region, region, &rg);
|
||||
|
||||
pixman_region32_fini(&rg);
|
||||
region.subtract(rg);
|
||||
}
|
||||
|
Reference in New Issue
Block a user