diff --git a/src/config/ConfigManager.cpp b/src/config/ConfigManager.cpp index 4cfd89b6..2283ba08 100644 --- a/src/config/ConfigManager.cpp +++ b/src/config/ConfigManager.cpp @@ -768,7 +768,7 @@ bool windowRuleValid(const std::string& RULE) { } bool layerRuleValid(const std::string& RULE) { - return !(RULE != "noanim"); + return !(RULE != "noanim" && RULE != "blur" && RULE != "ignorezero"); } void CConfigManager::handleWindowRule(const std::string& command, const std::string& value) { @@ -800,9 +800,8 @@ void CConfigManager::handleLayerRule(const std::string& command, const std::stri const auto VALUE = removeBeginEndSpacesTabs(value.substr(value.find_first_of(',') + 1)); // check rule and value - if (RULE == "" || VALUE == "") { + if (RULE == "" || VALUE == "") return; - } if (RULE == "unset") { std::erase_if(m_dLayerRules, [&](const SLayerRule& other) { return other.targetNamespace == VALUE; }); @@ -816,6 +815,11 @@ void CConfigManager::handleLayerRule(const std::string& command, const std::stri } m_dLayerRules.push_back({VALUE, RULE}); + + for (auto& m : g_pCompositor->m_vMonitors) + for (auto& lsl : m->m_aLayerSurfaceLayers) + for (auto& ls : lsl) + ls->applyRules(); } void CConfigManager::handleWindowRuleV2(const std::string& command, const std::string& value) { diff --git a/src/events/Layers.cpp b/src/events/Layers.cpp index 65f679d5..28c80e1d 100644 --- a/src/events/Layers.cpp +++ b/src/events/Layers.cpp @@ -121,10 +121,7 @@ void Events::listener_mapLayerSurface(void* owner, void* data) { if (!PMONITOR) return; - for (auto& rule : g_pConfigManager->getMatchingRules(layersurface)) { - if (rule.rule == "noanim") - layersurface->noAnimations = true; - } + layersurface->applyRules(); if ((uint64_t)layersurface->monitorID != PMONITOR->ID) { const auto POLDMON = g_pCompositor->getMonitorFromID(layersurface->monitorID); diff --git a/src/helpers/WLClasses.cpp b/src/helpers/WLClasses.cpp index 9b6926e2..29e10a54 100644 --- a/src/helpers/WLClasses.cpp +++ b/src/helpers/WLClasses.cpp @@ -5,4 +5,19 @@ SLayerSurface::SLayerSurface() { alpha.create(AVARTYPE_FLOAT, g_pConfigManager->getAnimationPropertyConfig("fadeIn"), nullptr, AVARDAMAGE_ENTIRE); alpha.m_pLayer = this; alpha.registerVar(); +} + +void SLayerSurface::applyRules() { + noAnimations = false; + forceBlur = false; + ignoreZero = false; + + for (auto& rule : g_pConfigManager->getMatchingRules(this)) { + if (rule.rule == "noanim") + noAnimations = true; + else if (rule.rule == "blur") + forceBlur = true; + else if (rule.rule == "ignorezero") + ignoreZero = true; + } } \ No newline at end of file diff --git a/src/helpers/WLClasses.hpp b/src/helpers/WLClasses.hpp index 55524ad1..7b87f3d1 100644 --- a/src/helpers/WLClasses.hpp +++ b/src/helpers/WLClasses.hpp @@ -15,6 +15,8 @@ struct SLayerRule { struct SLayerSurface { SLayerSurface(); + void applyRules(); + wlr_layer_surface_v1* layerSurface; wl_list link; @@ -40,7 +42,8 @@ struct SLayerSurface { bool noProcess = false; bool noAnimations = false; - bool forceBlur = false; + bool forceBlur = false; + bool ignoreZero = false; // For the list lookup bool operator==(const SLayerSurface& rhs) const { diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 5d26ff8f..3ae259b5 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -190,6 +190,7 @@ void CHyprOpenGLImpl::initShaders() { m_RenderData.pCurrentMonData->m_shRGBA.texAttrib = glGetAttribLocation(prog, "texcoord"); m_RenderData.pCurrentMonData->m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos"); m_RenderData.pCurrentMonData->m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); + m_RenderData.pCurrentMonData->m_shRGBA.discardAlphaZero = glGetUniformLocation(prog, "discardAlphaZero"); m_RenderData.pCurrentMonData->m_shRGBA.topLeft = glGetUniformLocation(prog, "topLeft"); m_RenderData.pCurrentMonData->m_shRGBA.fullSize = glGetUniformLocation(prog, "fullSize"); m_RenderData.pCurrentMonData->m_shRGBA.radius = glGetUniformLocation(prog, "radius"); @@ -466,15 +467,15 @@ void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha renderTexture(CTexture(tex), pBox, alpha, round, false, allowCustomUV); } -void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, 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()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowCustomUV, true); + renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardActive, false, allowCustomUV, true); scissor((wlr_box*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, +void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardActive, bool noAA, bool allowCustomUV, bool allowDim) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); @@ -542,7 +543,14 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b if (!usingFinalShader) { glUniform1f(shader->alpha, alpha); - glUniform1i(shader->discardOpaque, (int)discardOpaque); + + if (discardActive) { + glUniform1i(shader->discardOpaque, !!(m_RenderData.discardMode & DISCARD_OPAQUE)); + glUniform1i(shader->discardAlphaZero, !!(m_RenderData.discardMode & DISCARD_ALPHAZERO)); + } else { + glUniform1i(shader->discardOpaque, 0); + glUniform1i(shader->discardAlphaZero, 0); + } } wlr_box transformedBox; diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 171efb35..028be4df 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -23,6 +23,12 @@ inline const float fullVerts[] = { }; inline const float fanVertsFull[] = {-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f}; +enum eDiscardMode +{ + DISCARD_OPAQUE = 1, + DISCARD_ALPHAZERO = 1 << 1 +}; + struct SMonitorRenderData { CFramebuffer primaryFB; CFramebuffer mirrorFB; // these are used for some effects, @@ -64,6 +70,8 @@ struct SCurrentRenderData { Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); wlr_box clipBox = {}; + + uint32_t discardMode = DISCARD_OPAQUE; }; class CGradientValueData; @@ -78,7 +86,7 @@ class CHyprOpenGLImpl { void renderRect(wlr_box*, const CColor&, int round = 0); void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0); 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 discardOpaque = 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 renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0); void renderBorder(wlr_box*, const CGradientValueData&, int round, float a = 1.0); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b1c2cfe5..948d2e9a 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -376,7 +376,11 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, CMonitor* pMonitor, times renderdata.w = pLayer->geometry.width; renderdata.h = pLayer->geometry.height; renderdata.blockBlurOptimization = pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM || pLayer->layer == ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND; + + if (pLayer->ignoreZero) + g_pHyprOpenGL->m_RenderData.discardMode |= DISCARD_ALPHAZERO; wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); + g_pHyprOpenGL->m_RenderData.discardMode &= ~DISCARD_ALPHAZERO; renderdata.squishOversized = false; // don't squish popups renderdata.dontRound = true; diff --git a/src/render/Shader.hpp b/src/render/Shader.hpp index 6d3ca09b..33bcdca3 100644 --- a/src/render/Shader.hpp +++ b/src/render/Shader.hpp @@ -15,6 +15,7 @@ class CShader { GLint posAttrib; GLint texAttrib; GLint discardOpaque; + GLint discardAlphaZero; GLint topLeft; GLint bottomRight; diff --git a/src/render/shaders/Textures.hpp b/src/render/shaders/Textures.hpp index 0bf168a4..4360f5db 100644 --- a/src/render/shaders/Textures.hpp +++ b/src/render/shaders/Textures.hpp @@ -96,6 +96,7 @@ uniform vec2 fullSize; uniform float radius; uniform int discardOpaque; +uniform int discardAlphaZero; uniform int applyTint; uniform vec3 tint; @@ -107,13 +108,15 @@ void main() { vec4 pixColor = texture2D(tex, v_texcoord); if (discardOpaque == 1 && pixColor[3] * alpha == 1.0) - discard; - + discard; + + if (discardAlphaZero == 1 && pixColor[3] == 0.0) + discard; if (applyTint == 1) { - pixColor[0] = pixColor[0] * tint[0]; - pixColor[1] = pixColor[1] * tint[1]; - pixColor[2] = pixColor[2] * tint[2]; + pixColor[0] = pixColor[0] * tint[0]; + pixColor[1] = pixColor[1] * tint[1]; + pixColor[2] = pixColor[2] * tint[2]; } )#" +