Skip to content

Instantly share code, notes, and snippets.

@gulafaran
Created July 22, 2025 07:39
Show Gist options
  • Save gulafaran/c7ef557399d0795a8fcc67cd207ae3ea to your computer and use it in GitHub Desktop.
Save gulafaran/c7ef557399d0795a8fcc67cd207ae3ea to your computer and use it in GitHub Desktop.
diff --git a/src/render/pass/BorderPassElement.hpp b/src/render/pass/BorderPassElement.hpp
index 238b9ed5..5929c3e6 100644
--- a/src/render/pass/BorderPassElement.hpp
+++ b/src/render/pass/BorderPassElement.hpp
@@ -18,7 +18,10 @@ class CBorderPassElement : public IPassElement {
CBorderPassElement(const SBorderData& data_);
virtual ~CBorderPassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_BORDER;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
diff --git a/src/render/pass/ClearPassElement.hpp b/src/render/pass/ClearPassElement.hpp
index 067b7094..b86137fb 100644
--- a/src/render/pass/ClearPassElement.hpp
+++ b/src/render/pass/ClearPassElement.hpp
@@ -10,7 +10,10 @@ class CClearPassElement : public IPassElement {
CClearPassElement(const SClearData& data);
virtual ~CClearPassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_CLEAR;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual std::optional<CBox> boundingBox();
diff --git a/src/render/pass/FramebufferElement.hpp b/src/render/pass/FramebufferElement.hpp
index 515c3380..b4152228 100644
--- a/src/render/pass/FramebufferElement.hpp
+++ b/src/render/pass/FramebufferElement.hpp
@@ -11,7 +11,10 @@ class CFramebufferElement : public IPassElement {
CFramebufferElement(const SFramebufferElementData& data_);
virtual ~CFramebufferElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_FRAMEBUFFER;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual bool undiscardable();
@@ -22,4 +25,4 @@ class CFramebufferElement : public IPassElement {
private:
SFramebufferElementData m_data;
-};
\ No newline at end of file
+};
diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp
index 4ad1d444..6bb6b798 100644
--- a/src/render/pass/Pass.cpp
+++ b/src/render/pass/Pass.cpp
@@ -19,7 +19,8 @@ bool CRenderPass::single() const {
}
void CRenderPass::add(UP<IPassElement>&& el) {
- m_passElements.emplace_back(makeUnique<SPassElementData>(CRegion{}, std::move(el)));
+ auto& e = m_passElements.emplace_back(makeUnique<SPassElementData>(CRegion{}, std::move(el)));
+ m_sortedPassElements[e->element->getType()].emplace_back(e);
}
void CRenderPass::simplify() {
@@ -104,6 +105,10 @@ void CRenderPass::simplify() {
}
void CRenderPass::clear() {
+ for (auto& p : m_sortedPassElements) {
+ p.clear();
+ }
+
m_passElements.clear();
}
@@ -173,14 +178,19 @@ CRegion CRenderPass::render(const CRegion& damage_) {
if (m_passElements.empty())
return {};
- for (auto& el : m_passElements) {
- if (el->discard) {
- el->element->discard();
- continue;
- }
+ for (auto& p : m_sortedPassElements) {
+ for (auto& el : p) {
+ if (!el)
+ continue;
- g_pHyprOpenGL->m_renderData.damage = el->elementDamage;
- el->element->draw(el->elementDamage);
+ if (el->discard) {
+ el->element->discard();
+ continue;
+ }
+
+ g_pHyprOpenGL->m_renderData.damage = el->elementDamage;
+ el->element->draw(el->elementDamage);
+ }
}
if (*PDEBUGPASS) {
@@ -272,9 +282,14 @@ void CRenderPass::renderDebugData() {
std::string passStructure;
auto yn = [](const bool val) -> const char* { return val ? "yes" : "no"; };
auto tick = [](const bool val) -> const char* { return val ? "✔" : "✖"; };
- for (const auto& el : m_passElements | std::views::reverse) {
- passStructure += std::format("{} {} (bb: {} op: {}, pb: {}, lb: {})\n", tick(!el->discard), el->element->passName(), yn(el->element->boundingBox().has_value()),
- yn(!el->element->opaqueRegion().empty()), yn(el->element->needsPrecomputeBlur()), yn(el->element->needsLiveBlur()));
+ for (const auto& p : m_sortedPassElements) {
+ for (const auto& el : p) {
+ if (!el)
+ continue;
+
+ passStructure += std::format("{} {} (bb: {} op: {}, pb: {}, lb: {})\n", tick(!el->discard), el->element->passName(), yn(el->element->boundingBox().has_value()),
+ yn(!el->element->opaqueRegion().empty()), yn(el->element->needsPrecomputeBlur()), yn(el->element->needsLiveBlur()));
+ }
}
if (!passStructure.empty())
@@ -297,4 +312,7 @@ float CRenderPass::oneBlurRadius() {
void CRenderPass::removeAllOfType(const std::string& type) {
std::erase_if(m_passElements, [&type](const auto& e) { return e->element->passName() == type; });
+ for (auto& p : m_sortedPassElements) {
+ std::erase_if(p, [](const auto& e) { return !e; });
+ }
}
diff --git a/src/render/pass/Pass.hpp b/src/render/pass/Pass.hpp
index 435b5301..4867a70f 100644
--- a/src/render/pass/Pass.hpp
+++ b/src/render/pass/Pass.hpp
@@ -28,11 +28,12 @@ class CRenderPass {
bool discard = false;
};
- std::vector<UP<SPassElementData>> m_passElements;
+ std::vector<UP<SPassElementData>> m_passElements;
+ std::array<std::vector<WP<SPassElementData>>, SPassElementType::PASS_ELEMENT_LAST> m_sortedPassElements;
- void simplify();
- float oneBlurRadius();
- void renderDebugData();
+ void simplify();
+ float oneBlurRadius();
+ void renderDebugData();
struct {
bool present = false;
diff --git a/src/render/pass/PassElement.hpp b/src/render/pass/PassElement.hpp
index a006ce9e..c63097d5 100644
--- a/src/render/pass/PassElement.hpp
+++ b/src/render/pass/PassElement.hpp
@@ -3,11 +3,26 @@
#include "../../defines.hpp"
#include <optional>
+enum SPassElementType : size_t {
+ PASS_ELEMENT_TEX = 0,
+ PASS_ELEMENT_PREBLUR,
+ PASS_ELEMENT_RECT,
+ PASS_ELEMENT_BORDER,
+ PASS_ELEMENT_SURFACE,
+ PASS_ELEMENT_SHADOW,
+ PASS_ELEMENT_FRAMEBUFFER,
+ PASS_ELEMENT_RENDER_HINT,
+ PASS_ELEMENT_TEX_MATTE,
+ PASS_ELEMENT_CLEAR,
+ PASS_ELEMENT_LAST,
+};
+
class IPassElement {
public:
virtual ~IPassElement() = default;
virtual void draw(const CRegion& damage) = 0;
+ virtual SPassElementType getType() = 0;
virtual bool needsLiveBlur() = 0;
virtual bool needsPrecomputeBlur() = 0;
virtual const char* passName() = 0;
diff --git a/src/render/pass/PreBlurElement.hpp b/src/render/pass/PreBlurElement.hpp
index 80474a29..87406102 100644
--- a/src/render/pass/PreBlurElement.hpp
+++ b/src/render/pass/PreBlurElement.hpp
@@ -6,7 +6,10 @@ class CPreBlurElement : public IPassElement {
CPreBlurElement();
virtual ~CPreBlurElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_PREBLUR;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual bool disableSimplification();
@@ -15,4 +18,4 @@ class CPreBlurElement : public IPassElement {
virtual const char* passName() {
return "CPreBlurElement";
}
-};
\ No newline at end of file
+};
diff --git a/src/render/pass/RectPassElement.hpp b/src/render/pass/RectPassElement.hpp
index c83d52ec..4ec59a43 100644
--- a/src/render/pass/RectPassElement.hpp
+++ b/src/render/pass/RectPassElement.hpp
@@ -16,7 +16,10 @@ class CRectPassElement : public IPassElement {
CRectPassElement(const SRectData& data);
virtual ~CRectPassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_RECT;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual std::optional<CBox> boundingBox();
diff --git a/src/render/pass/RendererHintsPassElement.hpp b/src/render/pass/RendererHintsPassElement.hpp
index d56a0cd6..d319945e 100644
--- a/src/render/pass/RendererHintsPassElement.hpp
+++ b/src/render/pass/RendererHintsPassElement.hpp
@@ -12,7 +12,10 @@ class CRendererHintsPassElement : public IPassElement {
CRendererHintsPassElement(const SData& data);
virtual ~CRendererHintsPassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_RENDER_HINT;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual bool undiscardable();
@@ -23,4 +26,4 @@ class CRendererHintsPassElement : public IPassElement {
private:
SData m_data;
-};
\ No newline at end of file
+};
diff --git a/src/render/pass/ShadowPassElement.hpp b/src/render/pass/ShadowPassElement.hpp
index 028ac88c..e2b76179 100644
--- a/src/render/pass/ShadowPassElement.hpp
+++ b/src/render/pass/ShadowPassElement.hpp
@@ -13,7 +13,10 @@ class CShadowPassElement : public IPassElement {
CShadowPassElement(const SShadowData& data_);
virtual ~CShadowPassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_SHADOW;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
diff --git a/src/render/pass/SurfacePassElement.hpp b/src/render/pass/SurfacePassElement.hpp
index f4dbb45a..0fca4d11 100644
--- a/src/render/pass/SurfacePassElement.hpp
+++ b/src/render/pass/SurfacePassElement.hpp
@@ -52,7 +52,10 @@ class CSurfacePassElement : public IPassElement {
CSurfacePassElement(const SRenderData& data);
virtual ~CSurfacePassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_SURFACE;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual std::optional<CBox> boundingBox();
diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp
index 4257357e..f5fa4da1 100644
--- a/src/render/pass/TexPassElement.hpp
+++ b/src/render/pass/TexPassElement.hpp
@@ -27,7 +27,10 @@ class CTexPassElement : public IPassElement {
CTexPassElement(SRenderData&& data);
virtual ~CTexPassElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_TEX;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
virtual std::optional<CBox> boundingBox();
diff --git a/src/render/pass/TextureMatteElement.hpp b/src/render/pass/TextureMatteElement.hpp
index 57d0e1e3..afff9832 100644
--- a/src/render/pass/TextureMatteElement.hpp
+++ b/src/render/pass/TextureMatteElement.hpp
@@ -16,7 +16,10 @@ class CTextureMatteElement : public IPassElement {
CTextureMatteElement(const STextureMatteData& data_);
virtual ~CTextureMatteElement() = default;
- virtual void draw(const CRegion& damage);
+ virtual void draw(const CRegion& damage);
+ virtual SPassElementType getType() {
+ return PASS_ELEMENT_TEX_MATTE;
+ }
virtual bool needsLiveBlur();
virtual bool needsPrecomputeBlur();
@@ -26,4 +29,4 @@ class CTextureMatteElement : public IPassElement {
private:
STextureMatteData m_data;
-};
\ No newline at end of file
+};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment