internal: Wrap regions (#2750)

This commit is contained in:
Vaxry 2023-07-19 20:09:49 +02:00 committed by GitHub
parent ce9896204a
commit 89b87158db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 297 additions and 250 deletions

View file

@ -27,13 +27,6 @@
#define DELTALESSTHAN(a, b, delta) (abs((a) - (b)) < (delta)) #define DELTALESSTHAN(a, b, delta) (abs((a) - (b)) < (delta))
#define PIXMAN_DAMAGE_FOREACH(region) \
int rectsNum = 0; \
const auto RECTSARR = pixman_region32_rectangles(region, &rectsNum); \
for (int i = 0; i < rectsNum; ++i)
#define PIXMAN_REGION_FOREACH(region) PIXMAN_DAMAGE_FOREACH(region)
#define interface class #define interface class
#define STICKS(a, b) abs((a) - (b)) < 2 #define STICKS(a, b) abs((a) - (b)) < 2

View file

@ -10,12 +10,10 @@ int ratHandler(void* data) {
CMonitor::CMonitor() { CMonitor::CMonitor() {
wlr_damage_ring_init(&damage); wlr_damage_ring_init(&damage);
pixman_region32_init(&lastFrameDamage);
} }
CMonitor::~CMonitor() { CMonitor::~CMonitor() {
wlr_damage_ring_finish(&damage); wlr_damage_ring_finish(&damage);
pixman_region32_fini(&lastFrameDamage);
hyprListener_monitorDestroy.removeCallback(); hyprListener_monitorDestroy.removeCallback();
hyprListener_monitorFrame.removeCallback(); hyprListener_monitorFrame.removeCallback();
@ -331,6 +329,10 @@ void CMonitor::addDamage(const pixman_region32_t* rg) {
g_pCompositor->scheduleFrameForMonitor(this); g_pCompositor->scheduleFrameForMonitor(this);
} }
void CMonitor::addDamage(const CRegion* rg) {
addDamage(const_cast<CRegion*>(rg)->pixman());
}
void CMonitor::addDamage(const wlr_box* box) { void CMonitor::addDamage(const wlr_box* box) {
static auto* const PZOOMFACTOR = &g_pConfigManager->getConfigValuePtr("misc:cursor_zoom_factor")->floatValue; static auto* const PZOOMFACTOR = &g_pConfigManager->getConfigValuePtr("misc:cursor_zoom_factor")->floatValue;
if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) { if (*PZOOMFACTOR != 1.f && g_pCompositor->getMonitorFromCursor() == this) {

View file

@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <xf86drmMode.h> #include <xf86drmMode.h>
#include "Timer.hpp" #include "Timer.hpp"
#include "Region.hpp"
struct SMonitorRule; struct SMonitorRule;
@ -61,7 +62,7 @@ class CMonitor {
CMonitor* pMirrorOf = nullptr; CMonitor* pMirrorOf = nullptr;
std::vector<CMonitor*> mirrors; std::vector<CMonitor*> mirrors;
pixman_region32_t lastFrameDamage; // stores last frame damage CRegion lastFrameDamage; // stores last frame damage
// for the special workspace. 0 means not open. // for the special workspace. 0 means not open.
int specialWorkspaceID = 0; int specialWorkspaceID = 0;
@ -84,6 +85,7 @@ class CMonitor {
void onConnect(bool noRule); void onConnect(bool noRule);
void onDisconnect(); void onDisconnect();
void addDamage(const pixman_region32_t* rg); void addDamage(const pixman_region32_t* rg);
void addDamage(const CRegion* rg);
void addDamage(const wlr_box* box); void addDamage(const wlr_box* box);
void setMirror(const std::string&); void setMirror(const std::string&);
bool isMirror(); bool isMirror();

93
src/helpers/Region.cpp Normal file
View file

@ -0,0 +1,93 @@
#include "Region.hpp"
#include <wlr/util/box.h>
CRegion::CRegion() {
pixman_region32_init(&m_rRegion);
}
CRegion::CRegion(pixman_region32_t* ref) {
pixman_region32_init(&m_rRegion);
pixman_region32_copy(&m_rRegion, ref);
}
CRegion::CRegion(double x, double y, double w, double h) {
pixman_region32_init_rect(&m_rRegion, x, y, w, h);
}
CRegion::CRegion(wlr_box* box) {
pixman_region32_init_rect(&m_rRegion, box->x, box->y, box->width, box->height);
}
CRegion::CRegion(const CRegion& other) {
pixman_region32_init(&m_rRegion);
pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman());
}
CRegion::CRegion(CRegion&& other) {
pixman_region32_init(&m_rRegion);
pixman_region32_copy(&m_rRegion, other.pixman());
}
CRegion::~CRegion() {
pixman_region32_fini(&m_rRegion);
}
CRegion& CRegion::clear() {
pixman_region32_clear(&m_rRegion);
return *this;
}
CRegion& CRegion::set(const CRegion& other) {
pixman_region32_copy(&m_rRegion, const_cast<CRegion*>(&other)->pixman());
return *this;
}
CRegion& CRegion::add(const CRegion& other) {
pixman_region32_union(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
return *this;
}
CRegion& CRegion::add(double x, double y, double w, double h) {
pixman_region32_union_rect(&m_rRegion, &m_rRegion, x, y, w, h);
return *this;
}
CRegion& CRegion::subtract(const CRegion& other) {
pixman_region32_subtract(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
return *this;
}
CRegion& CRegion::intersect(const CRegion& other) {
pixman_region32_intersect(&m_rRegion, &m_rRegion, const_cast<CRegion*>(&other)->pixman());
return *this;
}
CRegion& CRegion::intersect(double x, double y, double w, double h) {
pixman_region32_intersect_rect(&m_rRegion, &m_rRegion, x, y, w, h);
return *this;
}
CRegion& CRegion::invert(pixman_box32_t* box) {
pixman_region32_inverse(&m_rRegion, &m_rRegion, box);
return *this;
}
CRegion& CRegion::translate(const Vector2D& vec) {
pixman_region32_translate(&m_rRegion, vec.x, vec.y);
return *this;
}
std::vector<pixman_box32_t> CRegion::getRects() const {
std::vector<pixman_box32_t> result;
int rectsNum = 0;
const auto RECTSARR = pixman_region32_rectangles(&m_rRegion, &rectsNum);
result.assign(RECTSARR, RECTSARR + rectsNum);
return result;
}
bool CRegion::empty() {
return !pixman_region32_not_empty(&m_rRegion);
}

53
src/helpers/Region.hpp Normal file
View file

@ -0,0 +1,53 @@
#pragma once
#include <pixman.h>
#include <vector>
#include "Vector2D.hpp"
struct wlr_box;
class CRegion {
public:
/* Create an empty region */
CRegion();
/* Create from a reference. Copies, does not own. */
CRegion(pixman_region32_t* ref);
/* Create from a box */
CRegion(double x, double y, double w, double h);
/* Create from a wlr_box */
CRegion(wlr_box* box);
CRegion(const CRegion&);
CRegion(CRegion&&);
~CRegion();
CRegion& operator=(CRegion&& other) {
pixman_region32_copy(&m_rRegion, other.pixman());
return *this;
}
CRegion& operator=(CRegion& other) {
pixman_region32_copy(&m_rRegion, other.pixman());
return *this;
}
CRegion& clear();
CRegion& set(const CRegion& other);
CRegion& add(const CRegion& other);
CRegion& add(double x, double y, double w, double h);
CRegion& subtract(const CRegion& other);
CRegion& intersect(const CRegion& other);
CRegion& intersect(double x, double y, double w, double h);
CRegion& translate(const Vector2D& vec);
CRegion& invert(pixman_box32_t* box);
bool empty();
std::vector<pixman_box32_t> getRects() const;
pixman_region32_t* pixman() {
return &m_rRegion;
}
private:
pixman_region32_t m_rRegion;
};

View file

@ -7,6 +7,7 @@
#include "SubsurfaceTree.hpp" #include "SubsurfaceTree.hpp"
#include "AnimatedVariable.hpp" #include "AnimatedVariable.hpp"
#include "WLSurface.hpp" #include "WLSurface.hpp"
#include "Region.hpp"
struct SLayerRule { struct SLayerRule {
std::string targetNamespace = ""; std::string targetNamespace = "";
@ -144,7 +145,7 @@ struct SMouse {
wlr_pointer_constraint_v1* currentConstraint = nullptr; wlr_pointer_constraint_v1* currentConstraint = nullptr;
bool constraintActive = false; bool constraintActive = false;
pixman_region32_t confinedTo; CRegion confinedTo;
std::string name = ""; std::string name = "";

View file

@ -255,15 +255,12 @@ void CAnimationManager::tick() {
// easy, damage the entire box // easy, damage the entire box
g_pHyprRenderer->damageBox(&dmg); g_pHyprRenderer->damageBox(&dmg);
} else { } else {
pixman_region32_t rg; CRegion rg{dmg.x, dmg.y, dmg.width, dmg.height};
pixman_region32_init_rect(&rg, dmg.x, dmg.y, dmg.width, dmg.height); CRegion wb{PWINDOW->m_vRealPosition.vec().x, PWINDOW->m_vRealPosition.vec().y, PWINDOW->m_vRealSize.vec().x, PWINDOW->m_vRealSize.vec().y};
pixman_region32_t wb;
pixman_region32_init_rect(&wb, PWINDOW->m_vRealPosition.vec().x, PWINDOW->m_vRealPosition.vec().y, PWINDOW->m_vRealSize.vec().x, rg.subtract(wb);
PWINDOW->m_vRealSize.vec().y);
pixman_region32_subtract(&rg, &rg, &wb); g_pHyprRenderer->damageRegion(rg);
g_pHyprRenderer->damageRegion(&rg);
pixman_region32_fini(&rg);
pixman_region32_fini(&wb);
} }
} }

View file

@ -1151,9 +1151,9 @@ void CInputManager::recheckConstraint(SMouse* pMouse) {
const auto PREGION = &pMouse->currentConstraint->region; const auto PREGION = &pMouse->currentConstraint->region;
if (pMouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED) { if (pMouse->currentConstraint->type == WLR_POINTER_CONSTRAINT_V1_CONFINED) {
pixman_region32_copy(&pMouse->confinedTo, PREGION); pMouse->confinedTo.set(PREGION);
} else { } else {
pixman_region32_clear(&pMouse->confinedTo); pMouse->confinedTo.clear();
} }
} }

View file

@ -403,17 +403,15 @@ void CScreencopyProtocolManager::sendFrameDamage(SScreencopyFrame* frame) {
if (!frame->withDamage) if (!frame->withDamage)
return; return;
PIXMAN_DAMAGE_FOREACH(&frame->pMonitor->lastFrameDamage) { for (auto& RECT : frame->pMonitor->lastFrameDamage.getRects()) {
const auto RECT = &RECTSARR[i];
if (frame->buffer->width < 1 || frame->buffer->height < 1 || frame->buffer->width - RECT->x1 < 1 || frame->buffer->height - RECT->y1 < 1) { if (frame->buffer->width < 1 || frame->buffer->height < 1 || frame->buffer->width - RECT.x1 < 1 || frame->buffer->height - RECT.y1 < 1) {
Debug::log(ERR, "[sc] Failed to send damage"); Debug::log(ERR, "[sc] Failed to send damage");
break; break;
} }
zwlr_screencopy_frame_v1_send_damage(frame->resource, std::clamp(RECT->x1, 0, frame->buffer->width), std::clamp(RECT->y1, 0, frame->buffer->height), zwlr_screencopy_frame_v1_send_damage(frame->resource, std::clamp(RECT.x1, 0, frame->buffer->width), std::clamp(RECT.y1, 0, frame->buffer->height),
std::clamp(RECT->x2 - RECT->x1, 0, frame->buffer->width - RECT->x1), std::clamp(RECT.x2 - RECT.x1, 0, frame->buffer->width - RECT.x1), std::clamp(RECT.y2 - RECT.y1, 0, frame->buffer->height - RECT.y1));
std::clamp(RECT->y2 - RECT->y1, 0, frame->buffer->height - RECT->y1));
} }
} }

View file

@ -347,16 +347,14 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
return false; return false;
// render the client // render the client
const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(frame->pWindow->m_iMonitorID);
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, PMONITOR->vecPixelSize.x * 10, PMONITOR->vecPixelSize.y * 10};
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecPixelSize.x * 10, PMONITOR->vecPixelSize.y * 10);
if (frame->overlayCursor) if (frame->overlayCursor)
wlr_output_lock_software_cursors(PMONITOR->output, true); wlr_output_lock_software_cursors(PMONITOR->output, true);
if (!wlr_output_attach_render(PMONITOR->output, nullptr)) { if (!wlr_output_attach_render(PMONITOR->output, nullptr)) {
Debug::log(ERR, "[toplevel_export] Couldn't attach render"); Debug::log(ERR, "[toplevel_export] Couldn't attach render");
pixman_region32_fini(&fakeDamage);
wlr_buffer_end_data_ptr_access(frame->buffer); wlr_buffer_end_data_ptr_access(frame->buffer);
if (frame->overlayCursor) if (frame->overlayCursor)
wlr_output_lock_software_cursors(PMONITOR->output, false); wlr_output_lock_software_cursors(PMONITOR->output, false);
@ -398,7 +396,6 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
if (!PFORMAT) { if (!PFORMAT) {
Debug::log(ERR, "[toplevel_export] Cannot read pixels, unsupported format %lx", PFORMAT); Debug::log(ERR, "[toplevel_export] Cannot read pixels, unsupported format %lx", PFORMAT);
g_pHyprOpenGL->end(); g_pHyprOpenGL->end();
pixman_region32_fini(&fakeDamage);
wlr_buffer_end_data_ptr_access(frame->buffer); wlr_buffer_end_data_ptr_access(frame->buffer);
if (frame->overlayCursor) if (frame->overlayCursor)
wlr_output_lock_software_cursors(PMONITOR->output, false); wlr_output_lock_software_cursors(PMONITOR->output, false);
@ -415,8 +412,6 @@ bool CToplevelExportProtocolManager::copyFrameShm(SScreencopyFrame* frame, times
wlr_output_rollback(PMONITOR->output); wlr_output_rollback(PMONITOR->output);
pixman_region32_fini(&fakeDamage);
wlr_buffer_end_data_ptr_access(frame->buffer); wlr_buffer_end_data_ptr_access(frame->buffer);
if (frame->overlayCursor) if (frame->overlayCursor)

View file

@ -93,7 +93,7 @@ GLuint CHyprOpenGLImpl::compileShader(const GLuint& type, std::string src, bool
return shader; return shader;
} }
void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool fake) { void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) {
m_RenderData.pMonitor = pMonitor; m_RenderData.pMonitor = pMonitor;
if (eglGetCurrentContext() != wlr_egl_get_context(g_pCompositor->m_sWLREGL)) { if (eglGetCurrentContext() != wlr_egl_get_context(g_pCompositor->m_sWLREGL)) {
@ -133,7 +133,7 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, pixman_region32_t* pDamage, bool
// bind the primary Hypr Framebuffer // bind the primary Hypr Framebuffer
m_RenderData.pCurrentMonData->primaryFB.bind(); m_RenderData.pCurrentMonData->primaryFB.bind();
m_RenderData.pDamage = pDamage; m_RenderData.damage.set(*pDamage);
m_bFakeFrame = fake; m_bFakeFrame = fake;
@ -148,7 +148,7 @@ void CHyprOpenGLImpl::end() {
// end the render, copy the data to the WLR framebuffer // end the render, copy the data to the WLR framebuffer
if (!m_bFakeFrame) { if (!m_bFakeFrame) {
pixman_region32_copy(m_RenderData.pDamage, &m_RenderData.pMonitor->lastFrameDamage); m_RenderData.damage = m_RenderData.pMonitor->lastFrameDamage;
if (!m_RenderData.pMonitor->mirrors.empty()) if (!m_RenderData.pMonitor->mirrors.empty())
g_pHyprOpenGL->saveBufferForMirror(); // save with original damage region g_pHyprOpenGL->saveBufferForMirror(); // save with original damage region
@ -373,11 +373,9 @@ void CHyprOpenGLImpl::clear(const CColor& color) {
glClearColor(color.r, color.g, color.b, color.a); glClearColor(color.r, color.g, color.b, color.a);
if (pixman_region32_not_empty(m_RenderData.pDamage)) { if (!m_RenderData.damage.empty()) {
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) { for (auto& RECT : m_RenderData.damage.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
} }
} }
@ -426,11 +424,11 @@ void CHyprOpenGLImpl::scissor(const int x, const int y, const int w, const int h
} }
void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) { void CHyprOpenGLImpl::renderRect(wlr_box* box, const CColor& col, int round) {
if (pixman_region32_not_empty(m_RenderData.pDamage)) if (!m_RenderData.damage.empty())
renderRectWithDamage(box, col, m_RenderData.pDamage, round); renderRectWithDamage(box, col, &m_RenderData.damage, round);
} }
void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixman_region32_t* damage, int round) { void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, CRegion* damage, int round) {
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
@ -481,22 +479,17 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib); glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shQUAD.posAttrib);
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
pixman_region32_t damageClip; CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height};
pixman_region32_init(&damageClip); damageClip.intersect(*damage);
pixman_region32_intersect_rect(&damageClip, damage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
if (pixman_region32_not_empty(&damageClip)) { if (!damageClip.empty()) {
PIXMAN_DAMAGE_FOREACH(&damageClip) { for (auto& RECT : damageClip.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
} }
pixman_region32_fini(&damageClip);
} else { } else {
PIXMAN_DAMAGE_FOREACH(damage) { for (auto& RECT : damage->getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
@ -516,19 +509,19 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha
void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) { void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardActive, bool allowCustomUV) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardActive, false, allowCustomUV, true); renderTextureInternalWithDamage(tex, pBox, alpha, &m_RenderData.damage, round, discardActive, false, allowCustomUV, true);
scissor((wlr_box*)nullptr); scissor((wlr_box*)nullptr);
} }
void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardActive, bool noAA, void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, CRegion* damage, int round, bool discardActive, bool noAA,
bool allowCustomUV, bool allowDim) { bool allowCustomUV, bool allowDim) {
RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!");
RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!");
alpha = std::clamp(alpha, 0.f, 1.f); alpha = std::clamp(alpha, 0.f, 1.f);
if (!pixman_region32_not_empty(m_RenderData.pDamage)) if (m_RenderData.damage.empty())
return; return;
wlr_box newBox = *pBox; wlr_box newBox = *pBox;
@ -670,22 +663,17 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
glEnableVertexAttribArray(shader->texAttrib); glEnableVertexAttribArray(shader->texAttrib);
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
pixman_region32_t damageClip; CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height};
pixman_region32_init(&damageClip); damageClip.intersect(*damage);
pixman_region32_intersect_rect(&damageClip, damage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
if (pixman_region32_not_empty(&damageClip)) { if (!damageClip.empty()) {
PIXMAN_DAMAGE_FOREACH(&damageClip) { for (auto& RECT : damageClip.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
} }
pixman_region32_fini(&damageClip);
} else { } else {
PIXMAN_DAMAGE_FOREACH(damage) { for (auto& RECT : damage->getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
@ -701,7 +689,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b
// but it works... well, I guess? // but it works... well, I guess?
// //
// Dual (or more) kawase blur // Dual (or more) kawase blur
CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* originalDamage) { CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* pBox, CRegion* originalDamage) {
glDisable(GL_BLEND); glDisable(GL_BLEND);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
@ -720,12 +708,10 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue; static auto* const PBLURPASSES = &g_pConfigManager->getConfigValuePtr("decoration:blur_passes")->intValue;
// prep damage // prep damage
pixman_region32_t damage; CRegion damage{*originalDamage};
pixman_region32_init(&damage); wlr_region_transform(damage.pixman(), damage.pixman(), wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x,
pixman_region32_copy(&damage, originalDamage);
wlr_region_transform(&damage, &damage, wlr_output_transform_invert(m_RenderData.pMonitor->transform), m_RenderData.pMonitor->vecTransformedSize.x,
m_RenderData.pMonitor->vecTransformedSize.y); m_RenderData.pMonitor->vecTransformedSize.y);
wlr_region_expand(&damage, &damage, *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES)); wlr_region_expand(damage.pixman(), damage.pixman(), *PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES));
// helper // helper
const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB; const auto PMIRRORFB = &m_RenderData.pCurrentMonData->mirrorFB;
@ -734,7 +720,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
CFramebuffer* currentRenderToFB = &m_RenderData.pCurrentMonData->primaryFB; CFramebuffer* currentRenderToFB = &m_RenderData.pCurrentMonData->primaryFB;
// declare the draw func // declare the draw func
auto drawPass = [&](CShader* pShader, pixman_region32_t* pDamage) { auto drawPass = [&](CShader* pShader, CRegion* pDamage) {
if (currentRenderToFB == PMIRRORFB) if (currentRenderToFB == PMIRRORFB)
PMIRRORSWAPFB->bind(); PMIRRORSWAPFB->bind();
else else
@ -770,11 +756,9 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
glEnableVertexAttribArray(pShader->posAttrib); glEnableVertexAttribArray(pShader->posAttrib);
glEnableVertexAttribArray(pShader->texAttrib); glEnableVertexAttribArray(pShader->texAttrib);
if (pixman_region32_not_empty(pDamage)) { if (!pDamage->empty()) {
PIXMAN_DAMAGE_FOREACH(pDamage) { for (auto& RECT : pDamage->getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT, false /* this region is already transformed */); scissor(&RECT, false /* this region is already transformed */);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
} }
@ -794,27 +778,23 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p
glBindTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTarget, m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTexID); glBindTexture(m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTarget, m_RenderData.pCurrentMonData->primaryFB.m_cTex.m_iTexID);
// damage region will be scaled, make a temp // damage region will be scaled, make a temp
pixman_region32_t tempDamage; CRegion tempDamage{damage};
pixman_region32_init(&tempDamage); wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET
wlr_region_scale(&tempDamage, &damage, 1.f / 2.f); // when DOWNscaling, we make the region twice as small because it's the TARGET
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage);
// and draw // and draw
for (int i = 1; i < *PBLURPASSES; ++i) { for (int i = 1; i < *PBLURPASSES; ++i) {
wlr_region_scale(&tempDamage, &damage, 1.f / (1 << (i + 1))); wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << (i + 1)));
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down drawPass(&m_RenderData.pCurrentMonData->m_shBLUR1, &tempDamage); // down
} }
for (int i = *PBLURPASSES - 1; i >= 0; --i) { for (int i = *PBLURPASSES - 1; i >= 0; --i) {
wlr_region_scale(&tempDamage, &damage, 1.f / (1 << i)); // when upsampling we make the region twice as big wlr_region_scale(tempDamage.pixman(), damage.pixman(), 1.f / (1 << i)); // when upsampling we make the region twice as big
drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up drawPass(&m_RenderData.pCurrentMonData->m_shBLUR2, &tempDamage); // up
} }
// finish // finish
pixman_region32_fini(&tempDamage);
pixman_region32_fini(&damage);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
@ -862,20 +842,14 @@ void CHyprOpenGLImpl::preRender(CMonitor* pMonitor) {
if (PSURFACE->opaque) if (PSURFACE->opaque)
return false; return false;
pixman_region32_t inverseOpaque; CRegion inverseOpaque;
pixman_region32_init(&inverseOpaque);
pixman_box32_t surfbox = {0, 0, PSURFACE->current.width, PSURFACE->current.height}; pixman_box32_t surfbox = {0, 0, PSURFACE->current.width, PSURFACE->current.height};
pixman_region32_copy(&inverseOpaque, &PSURFACE->current.opaque); CRegion opaqueRegion{&PSURFACE->current.opaque};
pixman_region32_inverse(&inverseOpaque, &inverseOpaque, &surfbox); inverseOpaque.set(opaqueRegion).invert(&surfbox).intersect(0, 0, PSURFACE->current.width, PSURFACE->current.height);
pixman_region32_intersect_rect(&inverseOpaque, &inverseOpaque, 0, 0, PSURFACE->current.width, PSURFACE->current.height);
if (!pixman_region32_not_empty(&inverseOpaque)) { if (inverseOpaque.empty())
pixman_region32_fini(&inverseOpaque);
return false; return false;
}
pixman_region32_fini(&inverseOpaque);
} }
return true; return true;
@ -907,8 +881,7 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
m_RenderData.renderModif = {}; // fix shit m_RenderData.renderModif = {}; // fix shit
// make the fake dmg // make the fake dmg
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
pixman_region32_init_rect(&fakeDamage, 0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y);
wlr_box wholeMonitor = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; wlr_box wholeMonitor = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y};
const auto POUTFB = blurMainFramebufferWithDamage(1, &wholeMonitor, &fakeDamage); const auto POUTFB = blurMainFramebufferWithDamage(1, &wholeMonitor, &fakeDamage);
@ -922,8 +895,6 @@ void CHyprOpenGLImpl::preBlurForCurrentMonitor() {
renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 1, &fakeDamage, 0, false, true, false); renderTextureInternalWithDamage(POUTFB->m_cTex, &wholeMonitor, 1, &fakeDamage, 0, false, true, false);
m_bEndFrame = false; m_bEndFrame = false;
pixman_region32_fini(&fakeDamage);
m_RenderData.pCurrentMonData->primaryFB.bind(); m_RenderData.pCurrentMonData->primaryFB.bind();
m_RenderData.pCurrentMonData->blurFBDirty = false; m_RenderData.pCurrentMonData->blurFBDirty = false;
@ -951,11 +922,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur_xray")->intValue; static auto* const PBLURXRAY = &g_pConfigManager->getConfigValuePtr("decoration:blur_xray")->intValue;
// make a damage region for this window // make a damage region for this window
pixman_region32_t damage; CRegion texDamage{m_RenderData.damage};
pixman_region32_init(&damage); texDamage.intersect(pBox->x, pBox->y, pBox->width, pBox->height);
pixman_region32_intersect_rect(&damage, m_RenderData.pDamage, pBox->x, pBox->y, pBox->width, pBox->height); // clip it to the box
if (!pixman_region32_not_empty(&damage)) if (texDamage.empty())
return; return;
if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) || if (*PBLURENABLED == 0 || (*PNOBLUROVERSIZED && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) ||
@ -965,24 +935,21 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
} }
// amazing hack: the surface has an opaque region! // amazing hack: the surface has an opaque region!
pixman_region32_t inverseOpaque; CRegion inverseOpaque;
pixman_region32_init(&inverseOpaque);
if (a >= 1.f) { if (a >= 1.f) {
pixman_box32_t surfbox = {0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale}; pixman_box32_t surfbox = {0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale};
pixman_region32_copy(&inverseOpaque, &pSurface->current.opaque); inverseOpaque = &pSurface->current.opaque;
pixman_region32_inverse(&inverseOpaque, &inverseOpaque, &surfbox); inverseOpaque.invert(&surfbox).intersect(0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale);
pixman_region32_intersect_rect(&inverseOpaque, &inverseOpaque, 0, 0, pSurface->current.width * pSurface->current.scale, pSurface->current.height * pSurface->current.scale);
if (!pixman_region32_not_empty(&inverseOpaque)) { if (inverseOpaque.empty()) {
pixman_region32_fini(&inverseOpaque);
renderTexture(tex, pBox, a, round, false, true); renderTexture(tex, pBox, a, round, false, true);
return; return;
} }
} else { } else {
pixman_region32_init_rect(&inverseOpaque, 0, 0, pBox->width, pBox->height); inverseOpaque = {0, 0, pBox->width, pBox->height};
} }
wlr_region_scale(&inverseOpaque, &inverseOpaque, m_RenderData.pMonitor->scale); wlr_region_scale(inverseOpaque.pixman(), inverseOpaque.pixman(), m_RenderData.pMonitor->scale);
// vvv TODO: layered blur fbs? // vvv TODO: layered blur fbs?
const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && !blockBlurOptimization && const bool USENEWOPTIMIZE = (*PBLURNEWOPTIMIZE && !blockBlurOptimization &&
@ -991,17 +958,13 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
CFramebuffer* POUTFB = nullptr; CFramebuffer* POUTFB = nullptr;
if (!USENEWOPTIMIZE) { if (!USENEWOPTIMIZE) {
pixman_region32_translate(&inverseOpaque, pBox->x, pBox->y); inverseOpaque.translate({pBox->x, pBox->y}).intersect(texDamage);
pixman_region32_intersect(&inverseOpaque, &inverseOpaque, &damage);
POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque); POUTFB = blurMainFramebufferWithDamage(a, pBox, &inverseOpaque);
} else { } else {
POUTFB = &m_RenderData.pCurrentMonData->blurFB; POUTFB = &m_RenderData.pCurrentMonData->blurFB;
} }
pixman_region32_fini(&inverseOpaque);
// bind primary // bind primary
m_RenderData.pCurrentMonData->primaryFB.bind(); m_RenderData.pCurrentMonData->primaryFB.bind();
@ -1032,7 +995,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
m_bEndFrame = true; // fix transformed m_bEndFrame = true; // fix transformed
const auto SAVEDRENDERMODIF = m_RenderData.renderModif; const auto SAVEDRENDERMODIF = m_RenderData.renderModif;
m_RenderData.renderModif = {}; // fix shit m_RenderData.renderModif = {}; // fix shit
renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 1.f : a, &damage, 0, false, false, false); renderTextureInternalWithDamage(POUTFB->m_cTex, &MONITORBOX, *PBLURIGNOREOPACITY ? 1.f : a, &texDamage, 0, false, false, false);
m_bEndFrame = false; m_bEndFrame = false;
m_RenderData.renderModif = SAVEDRENDERMODIF; m_RenderData.renderModif = SAVEDRENDERMODIF;
@ -1042,11 +1005,10 @@ void CHyprOpenGLImpl::renderTextureWithBlur(const CTexture& tex, wlr_box* pBox,
// draw window // draw window
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
renderTextureInternalWithDamage(tex, pBox, a, &damage, round, false, false, true, true); renderTextureInternalWithDamage(tex, pBox, a, &texDamage, round, false, false, true, true);
glStencilMask(-1); glStencilMask(-1);
glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF);
pixman_region32_fini(&damage);
scissor((wlr_box*)nullptr); scissor((wlr_box*)nullptr);
} }
@ -1061,7 +1023,7 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CGradientValueData& grad,
RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!"); RASSERT((box->width > 0 && box->height > 0), "Tried to render rect with width/height < 0!");
RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!"); RASSERT(m_RenderData.pMonitor, "Tried to render rect without begin()!");
if (!pixman_region32_not_empty(m_RenderData.pDamage) || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBorder)) if (m_RenderData.damage.empty() || (m_pCurrentWindow && m_pCurrentWindow->m_sAdditionalConfigData.forceNoBorder))
return; return;
static auto* const PMULTISAMPLE = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue; static auto* const PMULTISAMPLE = &g_pConfigManager->getConfigValuePtr("decoration:multisample_edges")->intValue;
@ -1133,22 +1095,17 @@ void CHyprOpenGLImpl::renderBorder(wlr_box* box, const CGradientValueData& grad,
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBORDER1.texAttrib); glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shBORDER1.texAttrib);
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
pixman_region32_t damageClip; CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height};
pixman_region32_init(&damageClip); damageClip.intersect(m_RenderData.damage);
pixman_region32_intersect_rect(&damageClip, m_RenderData.pDamage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
if (pixman_region32_not_empty(&damageClip)) { if (!damageClip.empty()) {
PIXMAN_DAMAGE_FOREACH(&damageClip) { for (auto& RECT : damageClip.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
} }
pixman_region32_fini(&damageClip);
} else { } else {
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) { for (auto& RECT : m_RenderData.damage.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
@ -1172,9 +1129,7 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra
// we need to "damage" the entire monitor // we need to "damage" the entire monitor
// so that we render the entire window // so that we render the entire window
// this is temporary, doesnt mess with the actual wlr damage // this is temporary, doesnt mess with the actual wlr damage
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y};
pixman_region32_init(&fakeDamage);
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
begin(PMONITOR, &fakeDamage, true); begin(PMONITOR, &fakeDamage, true);
@ -1214,8 +1169,6 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra
#endif #endif
end(); end();
pixman_region32_fini(&fakeDamage);
wlr_output_rollback(PMONITOR->output); wlr_output_rollback(PMONITOR->output);
} }
@ -1231,9 +1184,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
// we need to "damage" the entire monitor // we need to "damage" the entire monitor
// so that we render the entire window // so that we render the entire window
// this is temporary, doesnt mess with the actual wlr damage // this is temporary, doesnt mess with the actual wlr damage
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y};
pixman_region32_init(&fakeDamage);
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
begin(PMONITOR, &fakeDamage, true); begin(PMONITOR, &fakeDamage, true);
@ -1276,8 +1227,6 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
#endif #endif
end(); end();
pixman_region32_fini(&fakeDamage);
g_pHyprRenderer->m_bRenderingSnapshot = false; g_pHyprRenderer->m_bRenderingSnapshot = false;
wlr_output_rollback(PMONITOR->output); wlr_output_rollback(PMONITOR->output);
@ -1295,9 +1244,7 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
// we need to "damage" the entire monitor // we need to "damage" the entire monitor
// so that we render the entire window // so that we render the entire window
// this is temporary, doesnt mess with the actual wlr damage // this is temporary, doesnt mess with the actual wlr damage
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y};
pixman_region32_init(&fakeDamage);
pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y);
begin(PMONITOR, &fakeDamage, true); begin(PMONITOR, &fakeDamage, true);
@ -1337,8 +1284,6 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
g_pHyprRenderer->m_bRenderingSnapshot = false; g_pHyprRenderer->m_bRenderingSnapshot = false;
pixman_region32_fini(&fakeDamage);
wlr_output_rollback(PMONITOR->output); wlr_output_rollback(PMONITOR->output);
} }
@ -1371,8 +1316,7 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
windowBox.x = ((PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x); windowBox.x = ((PWINDOW->m_vRealPosition.vec().x - PMONITOR->vecPosition.x) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.x * PMONITOR->scale) * scaleXY.x);
windowBox.y = ((PWINDOW->m_vRealPosition.vec().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y); windowBox.y = ((PWINDOW->m_vRealPosition.vec().y - PMONITOR->vecPosition.y) * PMONITOR->scale) - ((PWINDOW->m_vOriginalClosedPos.y * PMONITOR->scale) * scaleXY.y);
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y);
if (*PDIMAROUND && (*pWindow)->m_sAdditionalConfigData.dimAround) { if (*PDIMAROUND && (*pWindow)->m_sAdditionalConfigData.dimAround) {
wlr_box monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y}; wlr_box monbox = {0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y};
@ -1385,8 +1329,6 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), &fakeDamage, 0); renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PWINDOW->m_fAlpha.fl(), &fakeDamage, 0);
m_bEndFrame = false; m_bEndFrame = false;
pixman_region32_fini(&fakeDamage);
} }
void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) { void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
@ -1403,20 +1345,17 @@ void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
if (it == m_mLayerFramebuffers.end() || !it->second.m_cTex.m_iTexID) if (it == m_mLayerFramebuffers.end() || !it->second.m_cTex.m_iTexID)
return; return;
const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID); const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID);
wlr_box monbox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y}; wlr_box monbox = {0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
pixman_region32_t fakeDamage; CRegion fakeDamage{0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y};
pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecTransformedSize.x, PMONITOR->vecTransformedSize.y);
m_bEndFrame = true; m_bEndFrame = true;
renderTextureInternalWithDamage(it->second.m_cTex, &monbox, PLAYER->alpha.fl(), &fakeDamage, 0); renderTextureInternalWithDamage(it->second.m_cTex, &monbox, PLAYER->alpha.fl(), &fakeDamage, 0);
m_bEndFrame = false; m_bEndFrame = false;
pixman_region32_fini(&fakeDamage);
} }
void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, float a) { void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, float a) {
@ -1424,7 +1363,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!"); RASSERT((box->width > 0 && box->height > 0), "Tried to render shadow with width/height < 0!");
RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!"); RASSERT(m_pCurrentWindow, "Tried to render shadow without a window!");
if (!pixman_region32_not_empty(m_RenderData.pDamage)) if (m_RenderData.damage.empty())
return; return;
wlr_box newBox = *box; wlr_box newBox = *box;
@ -1479,22 +1418,17 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl
glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib); glEnableVertexAttribArray(m_RenderData.pCurrentMonData->m_shSHADOW.texAttrib);
if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) { if (m_RenderData.clipBox.width != 0 && m_RenderData.clipBox.height != 0) {
pixman_region32_t damageClip; CRegion damageClip{m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height};
pixman_region32_init(&damageClip); damageClip.intersect(m_RenderData.damage);
pixman_region32_intersect_rect(&damageClip, m_RenderData.pDamage, m_RenderData.clipBox.x, m_RenderData.clipBox.y, m_RenderData.clipBox.width, m_RenderData.clipBox.height);
if (pixman_region32_not_empty(&damageClip)) { if (!damageClip.empty()) {
PIXMAN_DAMAGE_FOREACH(&damageClip) { for (auto& RECT : damageClip.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }
} }
pixman_region32_fini(&damageClip);
} else { } else {
PIXMAN_DAMAGE_FOREACH(m_RenderData.pDamage) { for (auto& RECT : m_RenderData.damage.getRects()) {
const auto RECT = RECTSARR[i];
scissor(&RECT); scissor(&RECT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
} }

View file

@ -4,6 +4,7 @@
#include "../helpers/Monitor.hpp" #include "../helpers/Monitor.hpp"
#include "../helpers/Color.hpp" #include "../helpers/Color.hpp"
#include "../helpers/Timer.hpp" #include "../helpers/Timer.hpp"
#include "../helpers/Region.hpp"
#include <list> #include <list>
#include <unordered_map> #include <unordered_map>
@ -23,7 +24,8 @@ inline const float fullVerts[] = {
}; };
inline const float fanVertsFull[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f}; inline const float fanVertsFull[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f};
enum eDiscardMode { enum eDiscardMode
{
DISCARD_OPAQUE = 1, DISCARD_OPAQUE = 1,
DISCARD_ALPHA = 1 << 1 DISCARD_ALPHA = 1 << 1
}; };
@ -35,8 +37,8 @@ struct SRenderModifData {
struct SMonitorRenderData { struct SMonitorRenderData {
CFramebuffer primaryFB; CFramebuffer primaryFB;
CFramebuffer mirrorFB; // these are used for some effects, CFramebuffer mirrorFB; // these are used for some effects,
CFramebuffer mirrorSwapFB; // etc CFramebuffer mirrorSwapFB; // etc
CFramebuffer monitorMirrorFB; // used for mirroring outputs CFramebuffer monitorMirrorFB; // used for mirroring outputs
@ -71,7 +73,7 @@ struct SCurrentRenderData {
SMonitorRenderData* pCurrentMonData = nullptr; SMonitorRenderData* pCurrentMonData = nullptr;
pixman_region32_t* pDamage = nullptr; CRegion damage;
SRenderModifData renderModif; SRenderModifData renderModif;
float mouseZoomFactor = 1.f; float mouseZoomFactor = 1.f;
@ -93,11 +95,11 @@ class CHyprOpenGLImpl {
public: public:
CHyprOpenGLImpl(); CHyprOpenGLImpl();
void begin(CMonitor*, pixman_region32_t*, bool fake = false); void begin(CMonitor*, CRegion*, bool fake = false);
void end(); void end();
void renderRect(wlr_box*, const CColor&, int round = 0); void renderRect(wlr_box*, const CColor&, int round = 0);
void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0); void renderRectWithDamage(wlr_box*, const CColor&, CRegion* damage, int round = 0);
void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false); void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false);
void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false); void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardActive = false, bool allowCustomUV = false);
void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false); void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0, bool blockBlurOptimization = false);
@ -139,7 +141,7 @@ class CHyprOpenGLImpl {
bool m_bReloadScreenShader = true; // at launch it can be set bool m_bReloadScreenShader = true; // at launch it can be set
CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window CWindow* m_pCurrentWindow = nullptr; // hack to get the current rendered window
std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers; std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers; std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
@ -166,9 +168,9 @@ class CHyprOpenGLImpl {
void initShaders(); void initShaders();
// returns the out FB, can be either Mirror or MirrorSwap // returns the out FB, can be either Mirror or MirrorSwap
CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage); CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, CRegion* damage);
void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, CRegion* damage, int round = 0, bool discardOpaque = false, bool noAA = false,
bool allowCustomUV = false, bool allowDim = false); bool allowCustomUV = false, bool allowDim = false);
void renderSplash(cairo_t* const, cairo_surface_t* const, double); void renderSplash(cairo_t* const, cairo_surface_t* const, double);

View file

@ -1,6 +1,7 @@
#include "Renderer.hpp" #include "Renderer.hpp"
#include "../Compositor.hpp" #include "../Compositor.hpp"
#include "linux-dmabuf-unstable-v1-protocol.h" #include "linux-dmabuf-unstable-v1-protocol.h"
#include "../helpers/Region.hpp"
void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { void renderSurface(struct wlr_surface* surface, int x, int y, void* data) {
const auto TEXTURE = wlr_surface_get_texture(surface); const auto TEXTURE = wlr_surface_get_texture(surface);
@ -455,8 +456,7 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
g_pHyprOpenGL->m_RenderData.renderModif = RENDERMODIFDATA; g_pHyprOpenGL->m_RenderData.renderModif = RENDERMODIFDATA;
// for storing damage when we optimize for occlusion // for storing damage when we optimize for occlusion
pixman_region32_t backupDamage; CRegion preOccludedDamage{g_pHyprOpenGL->m_RenderData.damage};
pixman_region32_init(&backupDamage);
// Render layer surfaces below windows for monitor // Render layer surfaces below windows for monitor
// if we have a fullscreen, opaque window that convers the screen, we can skip this. // 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() || if (!pWorkspace->m_bHasFullscreenWindow || pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL || !PFULLWINDOW || PFULLWINDOW->m_vRealSize.isBeingAnimated() ||
!PFULLWINDOW->opaque() || pWorkspace->m_vRenderOffset.vec() != Vector2D{}) { !PFULLWINDOW->opaque() || pWorkspace->m_vRenderOffset.vec() != Vector2D{}) {
pixman_region32_copy(&backupDamage, g_pHyprOpenGL->m_RenderData.pDamage); setOccludedForBackLayers(g_pHyprOpenGL->m_RenderData.damage, pWorkspace);
setOccludedForBackLayers(g_pHyprOpenGL->m_RenderData.pDamage, pWorkspace);
for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) { for (auto& ls : pMonitor->m_aLayerSurfaceLayers[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) {
renderLayer(ls.get(), pMonitor, time); renderLayer(ls.get(), pMonitor, time);
@ -475,11 +474,9 @@ void CHyprRenderer::renderAllClientsForWorkspace(CMonitor* pMonitor, CWorkspace*
renderLayer(ls.get(), pMonitor, time); 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 // pre window pass
g_pHyprOpenGL->preWindowPass(); g_pHyprOpenGL->preWindowPass();
@ -906,9 +903,9 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
clock_gettime(CLOCK_MONOTONIC, &now); clock_gettime(CLOCK_MONOTONIC, &now);
// check the damage // check the damage
pixman_region32_t damage; CRegion damage;
bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current); bool hasChanged = pMonitor->output->needs_frame || pixman_region32_not_empty(&pMonitor->damage.current);
int bufferAge; int bufferAge;
if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0) if (!hasChanged && *PDAMAGETRACKINGMODE != DAMAGE_TRACKING_NONE && pMonitor->forceFullFrames == 0 && damageBlinkCleanup == 0)
return; return;
@ -933,8 +930,7 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
return; return;
} }
pixman_region32_init(&damage); wlr_damage_ring_get_buffer_damage(&pMonitor->damage, bufferAge, damage.pixman());
wlr_damage_ring_get_buffer_damage(&pMonitor->damage, bufferAge, &damage);
pMonitor->renderingActive = true; 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 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 || if (*PDAMAGETRACKINGMODE == DAMAGE_TRACKING_NONE || *PDAMAGETRACKINGMODE == DAMAGE_TRACKING_MONITOR || pMonitor->forceFullFrames > 0 || damageBlinkCleanup > 0 ||
pMonitor->isMirror() /* why??? */) { 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 { } else {
static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue; static auto* const PBLURENABLED = &g_pConfigManager->getConfigValuePtr("decoration:blur")->intValue;
@ -958,14 +954,16 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
const auto BLURRADIUS = 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. *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 // 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 { } else {
pixman_region32_copy(&pMonitor->lastFrameDamage, &damage); pMonitor->lastFrameDamage = damage;
} }
} }
@ -1043,41 +1041,34 @@ void CHyprRenderer::renderMonitor(CMonitor* pMonitor) {
g_pHyprOpenGL->end(); g_pHyprOpenGL->end();
// calc frame damage // calc frame damage
pixman_region32_t frameDamage; CRegion frameDamage{};
pixman_region32_init(&frameDamage);
const auto TRANSFORM = wlr_output_transform_invert(pMonitor->output->transform); 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) 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) 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()) if (!pMonitor->mirrors.empty())
g_pHyprRenderer->damageMirrorsWith(pMonitor, &frameDamage); g_pHyprRenderer->damageMirrorsWith(pMonitor, frameDamage);
pixman_region32_fini(&frameDamage);
pMonitor->renderingActive = false; pMonitor->renderingActive = false;
EMIT_HOOK_EVENT("render", RENDER_POST); EMIT_HOOK_EVENT("render", RENDER_POST);
wlr_damage_ring_rotate(&pMonitor->damage);
if (!wlr_output_commit(pMonitor->output)) { if (!wlr_output_commit(pMonitor->output)) {
pixman_region32_fini(&damage);
if (UNLOCK_SC) if (UNLOCK_SC)
wlr_output_lock_software_cursors(pMonitor->output, false); wlr_output_lock_software_cursors(pMonitor->output, false);
return; return;
} }
pixman_region32_fini(&damage); wlr_damage_ring_rotate(&pMonitor->damage);
if (UNLOCK_SC) if (UNLOCK_SC)
wlr_output_lock_software_cursors(pMonitor->output, false); 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) if (g_pCompositor->m_bUnsafeState)
return; return;
pixman_region32_t damageBox; CRegion damageBox;
pixman_region32_init(&damageBox); wlr_surface_get_effective_damage(pSurface, damageBox.pixman());
wlr_surface_get_effective_damage(pSurface, &damageBox);
if (scale != 1.0) if (scale != 1.0)
wlr_region_scale(&damageBox, &damageBox, scale); wlr_region_scale(damageBox.pixman(), damageBox.pixman(), scale);
// schedule frame events // schedule frame events
if (!wl_list_empty(&pSurface->current.frame_callback_list)) { if (!wl_list_empty(&pSurface->current.frame_callback_list)) {
g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y))); g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y)));
} }
if (!pixman_region32_not_empty(&damageBox)) { if (damageBox.empty())
pixman_region32_fini(&damageBox);
return; return;
}
pixman_region32_t damageBoxForEach; CRegion damageBoxForEach;
pixman_region32_init(&damageBoxForEach);
for (auto& m : g_pCompositor->m_vMonitors) { for (auto& m : g_pCompositor->m_vMonitors) {
if (!m->output) if (!m->output)
@ -1417,23 +1404,19 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y, dou
double lx = 0, ly = 0; double lx = 0, ly = 0;
wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly); wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, m->output, &lx, &ly);
pixman_region32_copy(&damageBoxForEach, &damageBox); damageBoxForEach = damageBox;
pixman_region32_translate(&damageBoxForEach, x - m->vecPosition.x, y - m->vecPosition.y); damageBoxForEach.translate({x - m->vecPosition.x, y - m->vecPosition.y});
wlr_region_scale(&damageBoxForEach, &damageBoxForEach, m->scale); wlr_region_scale(damageBoxForEach.pixman(), damageBoxForEach.pixman(), m->scale);
pixman_region32_translate(&damageBoxForEach, lx + m->vecPosition.x, ly + m->vecPosition.y); damageBoxForEach.translate({lx + m->vecPosition.x, ly + m->vecPosition.y});
m->addDamage(&damageBoxForEach); m->addDamage(&damageBoxForEach);
} }
pixman_region32_fini(&damageBoxForEach);
static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue; static auto* const PLOGDAMAGE = &g_pConfigManager->getConfigValuePtr("debug:log_damage")->intValue;
if (*PLOGDAMAGE) 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, Debug::log(LOG, "Damage: Surface (extents): xy: %d, %d wh: %d, %d", damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y1,
damageBox.extents.y2 - damageBox.extents.y1); damageBox.pixman()->extents.x2 - damageBox.pixman()->extents.x1, damageBox.pixman()->extents.y2 - damageBox.pixman()->extents.y1);
pixman_region32_fini(&damageBox);
} }
void CHyprRenderer::damageWindow(CWindow* pWindow) { 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); damageBox(&box);
} }
void CHyprRenderer::damageRegion(pixman_region32_t* rg) { void CHyprRenderer::damageRegion(const CRegion& rg) {
PIXMAN_DAMAGE_FOREACH(rg) { for (auto& RECT : rg.getRects()) {
const auto RECT = RECTSARR[i];
damageBox(RECT.x1, RECT.y1, RECT.x2 - RECT.x1, RECT.y2 - RECT.y1); 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) { 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; CRegion rg{pRegion};
pixman_region32_init(&rg); wlr_region_scale_xy(rg.pixman(), rg.pixman(), scale.x, scale.y);
pixman_region32_copy(&rg, pRegion);
wlr_region_scale_xy(&rg, &rg, scale.x, scale.y);
pMonitor->addDamage(&rg); pMonitor->addDamage(&rg);
pixman_region32_fini(&rg);
g_pCompositor->scheduleFrameForMonitor(mirror); g_pCompositor->scheduleFrameForMonitor(mirror);
} }
@ -1986,9 +1965,8 @@ void CHyprRenderer::initiateManualCrash() {
g_pConfigManager->setInt("debug:damage_tracking", 0); g_pConfigManager->setInt("debug:damage_tracking", 0);
} }
void CHyprRenderer::setOccludedForBackLayers(pixman_region32_t* region, CWorkspace* pWorkspace) { void CHyprRenderer::setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace) {
pixman_region32_t rg; CRegion rg;
pixman_region32_init(&rg);
const auto PMONITOR = g_pCompositor->getMonitorFromID(pWorkspace->m_iMonitorID); 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 POS = w->m_vRealPosition.vec() + Vector2D{ROUNDING, ROUNDING};
const Vector2D SIZE = w->m_vRealSize.vec() - Vector2D{ROUNDING * 2, ROUNDING * 2}; 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); region.subtract(rg);
pixman_region32_fini(&rg);
} }

View file

@ -7,6 +7,7 @@
#include "../Window.hpp" #include "../Window.hpp"
#include "OpenGL.hpp" #include "OpenGL.hpp"
#include "../helpers/Timer.hpp" #include "../helpers/Timer.hpp"
#include "../helpers/Region.hpp"
struct SMonitorRule; struct SMonitorRule;
@ -39,9 +40,9 @@ class CHyprRenderer {
void damageWindow(CWindow*); void damageWindow(CWindow*);
void damageBox(wlr_box*); void damageBox(wlr_box*);
void damageBox(const int& x, const int& y, const int& w, const int& h); void damageBox(const int& x, const int& y, const int& w, const int& h);
void damageRegion(pixman_region32_t*); void damageRegion(const CRegion&);
void damageMonitor(CMonitor*); void damageMonitor(CMonitor*);
void damageMirrorsWith(CMonitor*, pixman_region32_t*); void damageMirrorsWith(CMonitor*, const CRegion&);
bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false); bool applyMonitorRule(CMonitor*, SMonitorRule*, bool force = false);
bool shouldRenderWindow(CWindow*, CMonitor*, CWorkspace*); bool shouldRenderWindow(CWindow*, CMonitor*, CWorkspace*);
bool shouldRenderWindow(CWindow*); bool shouldRenderWindow(CWindow*);
@ -50,7 +51,7 @@ class CHyprRenderer {
void calculateUVForSurface(CWindow*, wlr_surface*, bool main = false); void calculateUVForSurface(CWindow*, wlr_surface*, bool main = false);
std::tuple<float, float, float> getRenderTimes(CMonitor* pMonitor); // avg max min std::tuple<float, float, float> getRenderTimes(CMonitor* pMonitor); // avg max min
void renderLockscreen(CMonitor* pMonitor, timespec* now); void renderLockscreen(CMonitor* pMonitor, timespec* now);
void setOccludedForBackLayers(pixman_region32_t* region, CWorkspace* pWorkspace); void setOccludedForBackLayers(CRegion& region, CWorkspace* pWorkspace);
bool m_bWindowRequestedCursorHide = false; bool m_bWindowRequestedCursorHide = false;
bool m_bBlockSurfaceFeedback = false; bool m_bBlockSurfaceFeedback = false;