diff options
Diffstat (limited to 'src/render/OpenGL.cpp')
| -rw-r--r-- | src/render/OpenGL.cpp | 781 |
1 files changed, 403 insertions, 378 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 30680497..5568e5b9 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -675,7 +675,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP const auto FBO = rb ? rb->getFB() : fb; - glViewport(0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y); + setViewport(0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y); m_renderData.projection = Mat3x3::outputProjection(pMonitor->m_pixelSize, HYPRUTILS_TRANSFORM_NORMAL); @@ -725,7 +725,7 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb TRACY_GPU_ZONE("RenderBegin"); - glViewport(0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y); + setViewport(0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y); m_renderData.projection = Mat3x3::outputProjection(pMonitor->m_pixelSize, HYPRUTILS_TRANSFORM_NORMAL); @@ -895,26 +895,26 @@ static std::string processShader(const std::string& filename, const std::map<std // shader has #include "CM.glsl" static void getCMShaderUniforms(SShader& shader) { - shader.skipCM = glGetUniformLocation(shader.program, "skipCM"); - shader.sourceTF = glGetUniformLocation(shader.program, "sourceTF"); - shader.targetTF = glGetUniformLocation(shader.program, "targetTF"); - shader.srcTFRange = glGetUniformLocation(shader.program, "srcTFRange"); - shader.dstTFRange = glGetUniformLocation(shader.program, "dstTFRange"); - shader.targetPrimaries = glGetUniformLocation(shader.program, "targetPrimaries"); - shader.maxLuminance = glGetUniformLocation(shader.program, "maxLuminance"); - shader.dstMaxLuminance = glGetUniformLocation(shader.program, "dstMaxLuminance"); - shader.dstRefLuminance = glGetUniformLocation(shader.program, "dstRefLuminance"); - shader.sdrSaturation = glGetUniformLocation(shader.program, "sdrSaturation"); - shader.sdrBrightness = glGetUniformLocation(shader.program, "sdrBrightnessMultiplier"); - shader.convertMatrix = glGetUniformLocation(shader.program, "convertMatrix"); + shader.uniformLocations[SHADER_SKIP_CM] = glGetUniformLocation(shader.program, "skipCM"); + shader.uniformLocations[SHADER_SOURCE_TF] = glGetUniformLocation(shader.program, "sourceTF"); + shader.uniformLocations[SHADER_TARGET_TF] = glGetUniformLocation(shader.program, "targetTF"); + shader.uniformLocations[SHADER_SRC_TF_RANGE] = glGetUniformLocation(shader.program, "srcTFRange"); + shader.uniformLocations[SHADER_DST_TF_RANGE] = glGetUniformLocation(shader.program, "dstTFRange"); + shader.uniformLocations[SHADER_TARGET_PRIMARIES] = glGetUniformLocation(shader.program, "targetPrimaries"); + shader.uniformLocations[SHADER_MAX_LUMINANCE] = glGetUniformLocation(shader.program, "maxLuminance"); + shader.uniformLocations[SHADER_DST_MAX_LUMINANCE] = glGetUniformLocation(shader.program, "dstMaxLuminance"); + shader.uniformLocations[SHADER_DST_REF_LUMINANCE] = glGetUniformLocation(shader.program, "dstRefLuminance"); + shader.uniformLocations[SHADER_SDR_SATURATION] = glGetUniformLocation(shader.program, "sdrSaturation"); + shader.uniformLocations[SHADER_SDR_BRIGHTNESS] = glGetUniformLocation(shader.program, "sdrBrightnessMultiplier"); + shader.uniformLocations[SHADER_CONVERT_MATRIX] = glGetUniformLocation(shader.program, "convertMatrix"); } // shader has #include "rounding.glsl" static void getRoundingShaderUniforms(SShader& shader) { - shader.topLeft = glGetUniformLocation(shader.program, "topLeft"); - shader.fullSize = glGetUniformLocation(shader.program, "fullSize"); - shader.radius = glGetUniformLocation(shader.program, "radius"); - shader.roundingPower = glGetUniformLocation(shader.program, "roundingPower"); + shader.uniformLocations[SHADER_TOP_LEFT] = glGetUniformLocation(shader.program, "topLeft"); + shader.uniformLocations[SHADER_FULL_SIZE] = glGetUniformLocation(shader.program, "fullSize"); + shader.uniformLocations[SHADER_RADIUS] = glGetUniformLocation(shader.program, "radius"); + shader.uniformLocations[SHADER_ROUNDING_POWER] = glGetUniformLocation(shader.program, "roundingPower"); } bool CHyprOpenGLImpl::initShaders() { @@ -927,8 +927,7 @@ bool CHyprOpenGLImpl::initShaders() { loadShaderInclude("rounding.glsl", includes); loadShaderInclude("CM.glsl", includes); - shaders->TEXVERTSRC = processShader("tex.vert", includes); - shaders->TEXVERTSRC300 = processShader("tex300.vert", includes); + shaders->TEXVERTSRC = processShader("tex300.vert", includes); shaders->TEXVERTSRC320 = processShader("tex320.vert", includes); GLuint prog; @@ -938,7 +937,7 @@ bool CHyprOpenGLImpl::initShaders() { else { const auto TEXFRAGSRCCM = processShader("CM.frag", includes); - prog = createProgram(shaders->TEXVERTSRC300, TEXFRAGSRCCM, true, true); + prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCCM, true, true); if (m_shadersInitialized && m_cmSupported && prog == 0) g_pHyprNotificationOverlay->addNotification("CM shader reload failed, falling back to rgba/rgbx", CHyprColor{}, 15000, ICON_WARNING); @@ -947,20 +946,20 @@ bool CHyprOpenGLImpl::initShaders() { shaders->m_shCM.program = prog; getCMShaderUniforms(shaders->m_shCM); getRoundingShaderUniforms(shaders->m_shCM); - shaders->m_shCM.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shCM.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shCM.texType = glGetUniformLocation(prog, "texType"); - shaders->m_shCM.alphaMatte = glGetUniformLocation(prog, "texMatte"); - shaders->m_shCM.alpha = glGetUniformLocation(prog, "alpha"); - shaders->m_shCM.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shCM.matteTexAttrib = glGetAttribLocation(prog, "texcoordMatte"); - shaders->m_shCM.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shCM.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - shaders->m_shCM.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); - shaders->m_shCM.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); - shaders->m_shCM.applyTint = glGetUniformLocation(prog, "applyTint"); - shaders->m_shCM.tint = glGetUniformLocation(prog, "tint"); - shaders->m_shCM.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte"); + shaders->m_shCM.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shCM.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shCM.uniformLocations[SHADER_TEX_TYPE] = glGetUniformLocation(prog, "texType"); + shaders->m_shCM.uniformLocations[SHADER_ALPHA_MATTE] = glGetUniformLocation(prog, "texMatte"); + shaders->m_shCM.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); + shaders->m_shCM.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shCM.uniformLocations[SHADER_MATTE_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoordMatte"); + shaders->m_shCM.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shCM.uniformLocations[SHADER_DISCARD_OPAQUE] = glGetUniformLocation(prog, "discardOpaque"); + shaders->m_shCM.uniformLocations[SHADER_DISCARD_ALPHA] = glGetUniformLocation(prog, "discardAlpha"); + shaders->m_shCM.uniformLocations[SHADER_DISCARD_ALPHA_VALUE] = glGetUniformLocation(prog, "discardAlphaValue"); + shaders->m_shCM.uniformLocations[SHADER_APPLY_TINT] = glGetUniformLocation(prog, "applyTint"); + shaders->m_shCM.uniformLocations[SHADER_TINT] = glGetUniformLocation(prog, "tint"); + shaders->m_shCM.uniformLocations[SHADER_USE_ALPHA_MATTE] = glGetUniformLocation(prog, "useAlphaMatte"); shaders->m_shCM.createVao(); } else Debug::log(ERR, @@ -968,10 +967,10 @@ bool CHyprOpenGLImpl::initShaders() { "about this!"); } - const auto FRAGSHADOW = processShader(m_cmSupported ? "shadow.frag" : "shadow_legacy.frag", includes); - const auto FRAGBORDER1 = processShader(m_cmSupported ? "border.frag" : "border_legacy.frag", includes); - const auto FRAGBLURPREPARE = processShader(m_cmSupported ? "blurprepare.frag" : "blurprepare_legacy.frag", includes); - const auto FRAGBLURFINISH = processShader(m_cmSupported ? "blurfinish.frag" : "blurfinish_legacy.frag", includes); + const auto FRAGSHADOW = processShader("shadow.frag", includes); + const auto FRAGBORDER1 = processShader("border.frag", includes); + const auto FRAGBLURPREPARE = processShader("blurprepare.frag", includes); + const auto FRAGBLURFINISH = processShader("blurfinish.frag", includes); const auto QUADFRAGSRC = processShader("quad.frag", includes); const auto TEXFRAGSRCRGBA = processShader("rgba.frag", includes); const auto TEXFRAGSRCRGBAPASSTHRU = processShader("passthru.frag", includes); @@ -987,9 +986,9 @@ bool CHyprOpenGLImpl::initShaders() { return false; shaders->m_shQUAD.program = prog; getRoundingShaderUniforms(shaders->m_shQUAD); - shaders->m_shQUAD.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shQUAD.color = glGetUniformLocation(prog, "color"); - shaders->m_shQUAD.posAttrib = glGetAttribLocation(prog, "pos"); + shaders->m_shQUAD.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shQUAD.uniformLocations[SHADER_COLOR] = glGetUniformLocation(prog, "color"); + shaders->m_shQUAD.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); shaders->m_shQUAD.createVao(); prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBA, isDynamic); @@ -997,53 +996,53 @@ bool CHyprOpenGLImpl::initShaders() { return false; shaders->m_shRGBA.program = prog; getRoundingShaderUniforms(shaders->m_shRGBA); - shaders->m_shRGBA.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shRGBA.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shRGBA.alphaMatte = glGetUniformLocation(prog, "texMatte"); - shaders->m_shRGBA.alpha = glGetUniformLocation(prog, "alpha"); - shaders->m_shRGBA.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shRGBA.matteTexAttrib = glGetAttribLocation(prog, "texcoordMatte"); - shaders->m_shRGBA.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shRGBA.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - shaders->m_shRGBA.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); - shaders->m_shRGBA.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); - shaders->m_shRGBA.applyTint = glGetUniformLocation(prog, "applyTint"); - shaders->m_shRGBA.tint = glGetUniformLocation(prog, "tint"); - shaders->m_shRGBA.useAlphaMatte = glGetUniformLocation(prog, "useAlphaMatte"); + shaders->m_shRGBA.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shRGBA.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shRGBA.uniformLocations[SHADER_ALPHA_MATTE] = glGetUniformLocation(prog, "texMatte"); + shaders->m_shRGBA.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); + shaders->m_shRGBA.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shRGBA.uniformLocations[SHADER_MATTE_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoordMatte"); + shaders->m_shRGBA.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shRGBA.uniformLocations[SHADER_DISCARD_OPAQUE] = glGetUniformLocation(prog, "discardOpaque"); + shaders->m_shRGBA.uniformLocations[SHADER_DISCARD_ALPHA] = glGetUniformLocation(prog, "discardAlpha"); + shaders->m_shRGBA.uniformLocations[SHADER_DISCARD_ALPHA_VALUE] = glGetUniformLocation(prog, "discardAlphaValue"); + shaders->m_shRGBA.uniformLocations[SHADER_APPLY_TINT] = glGetUniformLocation(prog, "applyTint"); + shaders->m_shRGBA.uniformLocations[SHADER_TINT] = glGetUniformLocation(prog, "tint"); + shaders->m_shRGBA.uniformLocations[SHADER_USE_ALPHA_MATTE] = glGetUniformLocation(prog, "useAlphaMatte"); shaders->m_shRGBA.createVao(); prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBAPASSTHRU, isDynamic); if (!prog) return false; - shaders->m_shPASSTHRURGBA.program = prog; - shaders->m_shPASSTHRURGBA.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shPASSTHRURGBA.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shPASSTHRURGBA.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shPASSTHRURGBA.posAttrib = glGetAttribLocation(prog, "pos"); + shaders->m_shPASSTHRURGBA.program = prog; + shaders->m_shPASSTHRURGBA.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shPASSTHRURGBA.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shPASSTHRURGBA.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shPASSTHRURGBA.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); shaders->m_shPASSTHRURGBA.createVao(); prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBAMATTE, isDynamic); if (!prog) return false; - shaders->m_shMATTE.program = prog; - shaders->m_shMATTE.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shMATTE.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shMATTE.alphaMatte = glGetUniformLocation(prog, "texMatte"); - shaders->m_shMATTE.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shMATTE.posAttrib = glGetAttribLocation(prog, "pos"); + shaders->m_shMATTE.program = prog; + shaders->m_shMATTE.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shMATTE.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shMATTE.uniformLocations[SHADER_ALPHA_MATTE] = glGetUniformLocation(prog, "texMatte"); + shaders->m_shMATTE.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shMATTE.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); shaders->m_shMATTE.createVao(); prog = createProgram(shaders->TEXVERTSRC, FRAGGLITCH, isDynamic); if (!prog) return false; - shaders->m_shGLITCH.program = prog; - shaders->m_shGLITCH.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shGLITCH.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shGLITCH.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shGLITCH.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shGLITCH.distort = glGetUniformLocation(prog, "distort"); - shaders->m_shGLITCH.time = glGetUniformLocation(prog, "time"); - shaders->m_shGLITCH.fullSize = glGetUniformLocation(prog, "screenSize"); + shaders->m_shGLITCH.program = prog; + shaders->m_shGLITCH.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shGLITCH.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shGLITCH.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shGLITCH.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shGLITCH.uniformLocations[SHADER_DISTORT] = glGetUniformLocation(prog, "distort"); + shaders->m_shGLITCH.uniformLocations[SHADER_TIME] = glGetUniformLocation(prog, "time"); + shaders->m_shGLITCH.uniformLocations[SHADER_FULL_SIZE] = glGetUniformLocation(prog, "screenSize"); shaders->m_shGLITCH.createVao(); prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCRGBX, isDynamic); @@ -1051,16 +1050,16 @@ bool CHyprOpenGLImpl::initShaders() { return false; shaders->m_shRGBX.program = prog; getRoundingShaderUniforms(shaders->m_shRGBX); - shaders->m_shRGBX.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shRGBX.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shRGBX.alpha = glGetUniformLocation(prog, "alpha"); - shaders->m_shRGBX.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shRGBX.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shRGBX.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - shaders->m_shRGBX.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); - shaders->m_shRGBX.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); - shaders->m_shRGBX.applyTint = glGetUniformLocation(prog, "applyTint"); - shaders->m_shRGBX.tint = glGetUniformLocation(prog, "tint"); + shaders->m_shRGBX.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shRGBX.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shRGBX.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); + shaders->m_shRGBX.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shRGBX.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shRGBX.uniformLocations[SHADER_DISCARD_OPAQUE] = glGetUniformLocation(prog, "discardOpaque"); + shaders->m_shRGBX.uniformLocations[SHADER_DISCARD_ALPHA] = glGetUniformLocation(prog, "discardAlpha"); + shaders->m_shRGBX.uniformLocations[SHADER_DISCARD_ALPHA_VALUE] = glGetUniformLocation(prog, "discardAlphaValue"); + shaders->m_shRGBX.uniformLocations[SHADER_APPLY_TINT] = glGetUniformLocation(prog, "applyTint"); + shaders->m_shRGBX.uniformLocations[SHADER_TINT] = glGetUniformLocation(prog, "tint"); shaders->m_shRGBX.createVao(); prog = createProgram(shaders->TEXVERTSRC, TEXFRAGSRCEXT, isDynamic); @@ -1068,115 +1067,113 @@ bool CHyprOpenGLImpl::initShaders() { return false; shaders->m_shEXT.program = prog; getRoundingShaderUniforms(shaders->m_shEXT); - shaders->m_shEXT.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shEXT.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shEXT.alpha = glGetUniformLocation(prog, "alpha"); - shaders->m_shEXT.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shEXT.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shEXT.discardOpaque = glGetUniformLocation(prog, "discardOpaque"); - shaders->m_shEXT.discardAlpha = glGetUniformLocation(prog, "discardAlpha"); - shaders->m_shEXT.discardAlphaValue = glGetUniformLocation(prog, "discardAlphaValue"); - shaders->m_shEXT.applyTint = glGetUniformLocation(prog, "applyTint"); - shaders->m_shEXT.tint = glGetUniformLocation(prog, "tint"); + shaders->m_shEXT.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shEXT.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shEXT.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); + shaders->m_shEXT.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shEXT.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shEXT.uniformLocations[SHADER_DISCARD_OPAQUE] = glGetUniformLocation(prog, "discardOpaque"); + shaders->m_shEXT.uniformLocations[SHADER_DISCARD_ALPHA] = glGetUniformLocation(prog, "discardAlpha"); + shaders->m_shEXT.uniformLocations[SHADER_DISCARD_ALPHA_VALUE] = glGetUniformLocation(prog, "discardAlphaValue"); + shaders->m_shEXT.uniformLocations[SHADER_APPLY_TINT] = glGetUniformLocation(prog, "applyTint"); + shaders->m_shEXT.uniformLocations[SHADER_TINT] = glGetUniformLocation(prog, "tint"); shaders->m_shEXT.createVao(); prog = createProgram(shaders->TEXVERTSRC, FRAGBLUR1, isDynamic); if (!prog) return false; - shaders->m_shBLUR1.program = prog; - shaders->m_shBLUR1.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shBLUR1.alpha = glGetUniformLocation(prog, "alpha"); - shaders->m_shBLUR1.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shBLUR1.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shBLUR1.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shBLUR1.radius = glGetUniformLocation(prog, "radius"); - shaders->m_shBLUR1.halfpixel = glGetUniformLocation(prog, "halfpixel"); - shaders->m_shBLUR1.passes = glGetUniformLocation(prog, "passes"); - shaders->m_shBLUR1.vibrancy = glGetUniformLocation(prog, "vibrancy"); - shaders->m_shBLUR1.vibrancy_darkness = glGetUniformLocation(prog, "vibrancy_darkness"); + shaders->m_shBLUR1.program = prog; + shaders->m_shBLUR1.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shBLUR1.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); + shaders->m_shBLUR1.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shBLUR1.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shBLUR1.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shBLUR1.uniformLocations[SHADER_RADIUS] = glGetUniformLocation(prog, "radius"); + shaders->m_shBLUR1.uniformLocations[SHADER_HALFPIXEL] = glGetUniformLocation(prog, "halfpixel"); + shaders->m_shBLUR1.uniformLocations[SHADER_PASSES] = glGetUniformLocation(prog, "passes"); + shaders->m_shBLUR1.uniformLocations[SHADER_VIBRANCY] = glGetUniformLocation(prog, "vibrancy"); + shaders->m_shBLUR1.uniformLocations[SHADER_VIBRANCY_DARKNESS] = glGetUniformLocation(prog, "vibrancy_darkness"); shaders->m_shBLUR1.createVao(); prog = createProgram(shaders->TEXVERTSRC, FRAGBLUR2, isDynamic); if (!prog) return false; - shaders->m_shBLUR2.program = prog; - shaders->m_shBLUR2.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shBLUR2.alpha = glGetUniformLocation(prog, "alpha"); - shaders->m_shBLUR2.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shBLUR2.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shBLUR2.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shBLUR2.radius = glGetUniformLocation(prog, "radius"); - shaders->m_shBLUR2.halfpixel = glGetUniformLocation(prog, "halfpixel"); + shaders->m_shBLUR2.program = prog; + shaders->m_shBLUR2.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shBLUR2.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); + shaders->m_shBLUR2.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shBLUR2.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shBLUR2.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shBLUR2.uniformLocations[SHADER_RADIUS] = glGetUniformLocation(prog, "radius"); + shaders->m_shBLUR2.uniformLocations[SHADER_HALFPIXEL] = glGetUniformLocation(prog, "halfpixel"); shaders->m_shBLUR2.createVao(); - prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGBLURPREPARE, isDynamic); + prog = createProgram(shaders->TEXVERTSRC, FRAGBLURPREPARE, isDynamic); if (!prog) return false; shaders->m_shBLURPREPARE.program = prog; - if (m_cmSupported) - getCMShaderUniforms(shaders->m_shBLURPREPARE); - - shaders->m_shBLURPREPARE.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shBLURPREPARE.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shBLURPREPARE.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shBLURPREPARE.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shBLURPREPARE.contrast = glGetUniformLocation(prog, "contrast"); - shaders->m_shBLURPREPARE.brightness = glGetUniformLocation(prog, "brightness"); + getCMShaderUniforms(shaders->m_shBLURPREPARE); + + shaders->m_shBLURPREPARE.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shBLURPREPARE.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shBLURPREPARE.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shBLURPREPARE.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shBLURPREPARE.uniformLocations[SHADER_CONTRAST] = glGetUniformLocation(prog, "contrast"); + shaders->m_shBLURPREPARE.uniformLocations[SHADER_BRIGHTNESS] = glGetUniformLocation(prog, "brightness"); shaders->m_shBLURPREPARE.createVao(); - prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGBLURFINISH, isDynamic); + prog = createProgram(shaders->TEXVERTSRC, FRAGBLURFINISH, isDynamic); if (!prog) return false; shaders->m_shBLURFINISH.program = prog; // getCMShaderUniforms(shaders->m_shBLURFINISH); - shaders->m_shBLURFINISH.tex = glGetUniformLocation(prog, "tex"); - shaders->m_shBLURFINISH.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shBLURFINISH.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shBLURFINISH.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shBLURFINISH.brightness = glGetUniformLocation(prog, "brightness"); - shaders->m_shBLURFINISH.noise = glGetUniformLocation(prog, "noise"); + shaders->m_shBLURFINISH.uniformLocations[SHADER_TEX] = glGetUniformLocation(prog, "tex"); + shaders->m_shBLURFINISH.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shBLURFINISH.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shBLURFINISH.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shBLURFINISH.uniformLocations[SHADER_BRIGHTNESS] = glGetUniformLocation(prog, "brightness"); + shaders->m_shBLURFINISH.uniformLocations[SHADER_NOISE] = glGetUniformLocation(prog, "noise"); shaders->m_shBLURFINISH.createVao(); - prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGSHADOW, isDynamic); + prog = createProgram(shaders->TEXVERTSRC, FRAGSHADOW, isDynamic); if (!prog) return false; - if (m_cmSupported) - shaders->m_shSHADOW.program = prog; + + shaders->m_shSHADOW.program = prog; getCMShaderUniforms(shaders->m_shSHADOW); getRoundingShaderUniforms(shaders->m_shSHADOW); - shaders->m_shSHADOW.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shSHADOW.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shSHADOW.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shSHADOW.bottomRight = glGetUniformLocation(prog, "bottomRight"); - shaders->m_shSHADOW.range = glGetUniformLocation(prog, "range"); - shaders->m_shSHADOW.shadowPower = glGetUniformLocation(prog, "shadowPower"); - shaders->m_shSHADOW.color = glGetUniformLocation(prog, "color"); + shaders->m_shSHADOW.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shSHADOW.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shSHADOW.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shSHADOW.uniformLocations[SHADER_BOTTOM_RIGHT] = glGetUniformLocation(prog, "bottomRight"); + shaders->m_shSHADOW.uniformLocations[SHADER_RANGE] = glGetUniformLocation(prog, "range"); + shaders->m_shSHADOW.uniformLocations[SHADER_SHADOW_POWER] = glGetUniformLocation(prog, "shadowPower"); + shaders->m_shSHADOW.uniformLocations[SHADER_COLOR] = glGetUniformLocation(prog, "color"); shaders->m_shSHADOW.createVao(); - prog = createProgram(m_cmSupported ? shaders->TEXVERTSRC300 : shaders->TEXVERTSRC, FRAGBORDER1, isDynamic); + prog = createProgram(shaders->TEXVERTSRC, FRAGBORDER1, isDynamic); if (!prog) return false; - shaders->m_shBORDER1.program = prog; - if (m_cmSupported) - getCMShaderUniforms(shaders->m_shBORDER1); + shaders->m_shBORDER1.program = prog; + getCMShaderUniforms(shaders->m_shBORDER1); getRoundingShaderUniforms(shaders->m_shBORDER1); - shaders->m_shBORDER1.proj = glGetUniformLocation(prog, "proj"); - shaders->m_shBORDER1.thick = glGetUniformLocation(prog, "thick"); - shaders->m_shBORDER1.posAttrib = glGetAttribLocation(prog, "pos"); - shaders->m_shBORDER1.texAttrib = glGetAttribLocation(prog, "texcoord"); - shaders->m_shBORDER1.bottomRight = glGetUniformLocation(prog, "bottomRight"); - shaders->m_shBORDER1.fullSizeUntransformed = glGetUniformLocation(prog, "fullSizeUntransformed"); - shaders->m_shBORDER1.radiusOuter = glGetUniformLocation(prog, "radiusOuter"); - shaders->m_shBORDER1.gradient = glGetUniformLocation(prog, "gradient"); - shaders->m_shBORDER1.gradient2 = glGetUniformLocation(prog, "gradient2"); - shaders->m_shBORDER1.gradientLength = glGetUniformLocation(prog, "gradientLength"); - shaders->m_shBORDER1.gradient2Length = glGetUniformLocation(prog, "gradient2Length"); - shaders->m_shBORDER1.angle = glGetUniformLocation(prog, "angle"); - shaders->m_shBORDER1.angle2 = glGetUniformLocation(prog, "angle2"); - shaders->m_shBORDER1.gradientLerp = glGetUniformLocation(prog, "gradientLerp"); - shaders->m_shBORDER1.alpha = glGetUniformLocation(prog, "alpha"); + shaders->m_shBORDER1.uniformLocations[SHADER_PROJ] = glGetUniformLocation(prog, "proj"); + shaders->m_shBORDER1.uniformLocations[SHADER_THICK] = glGetUniformLocation(prog, "thick"); + shaders->m_shBORDER1.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(prog, "pos"); + shaders->m_shBORDER1.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(prog, "texcoord"); + shaders->m_shBORDER1.uniformLocations[SHADER_BOTTOM_RIGHT] = glGetUniformLocation(prog, "bottomRight"); + shaders->m_shBORDER1.uniformLocations[SHADER_FULL_SIZE_UNTRANSFORMED] = glGetUniformLocation(prog, "fullSizeUntransformed"); + shaders->m_shBORDER1.uniformLocations[SHADER_RADIUS_OUTER] = glGetUniformLocation(prog, "radiusOuter"); + shaders->m_shBORDER1.uniformLocations[SHADER_GRADIENT] = glGetUniformLocation(prog, "gradient"); + shaders->m_shBORDER1.uniformLocations[SHADER_GRADIENT2] = glGetUniformLocation(prog, "gradient2"); + shaders->m_shBORDER1.uniformLocations[SHADER_GRADIENT_LENGTH] = glGetUniformLocation(prog, "gradientLength"); + shaders->m_shBORDER1.uniformLocations[SHADER_GRADIENT2_LENGTH] = glGetUniformLocation(prog, "gradient2Length"); + shaders->m_shBORDER1.uniformLocations[SHADER_ANGLE] = glGetUniformLocation(prog, "angle"); + shaders->m_shBORDER1.uniformLocations[SHADER_ANGLE2] = glGetUniformLocation(prog, "angle2"); + shaders->m_shBORDER1.uniformLocations[SHADER_GRADIENT_LERP] = glGetUniformLocation(prog, "gradientLerp"); + shaders->m_shBORDER1.uniformLocations[SHADER_ALPHA] = glGetUniformLocation(prog, "alpha"); shaders->m_shBORDER1.createVao(); } catch (const std::exception& e) { @@ -1216,10 +1213,7 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { fragmentShader.starts_with("#version 320 es") // do not break existing custom shaders ? m_shaders->TEXVERTSRC320 : - (fragmentShader.starts_with("#version 300 es") // support lower es versions - ? - m_shaders->TEXVERTSRC300 : - m_shaders->TEXVERTSRC), + m_shaders->TEXVERTSRC, fragmentShader, true); if (!m_finalScreenShader.program) { @@ -1227,23 +1221,23 @@ void CHyprOpenGLImpl::applyScreenShader(const std::string& path) { return; } - m_finalScreenShader.proj = glGetUniformLocation(m_finalScreenShader.program, "proj"); - m_finalScreenShader.tex = glGetUniformLocation(m_finalScreenShader.program, "tex"); - m_finalScreenShader.time = glGetUniformLocation(m_finalScreenShader.program, "time"); - if (m_finalScreenShader.time != -1) + m_finalScreenShader.uniformLocations[SHADER_PROJ] = glGetUniformLocation(m_finalScreenShader.program, "proj"); + m_finalScreenShader.uniformLocations[SHADER_TEX] = glGetUniformLocation(m_finalScreenShader.program, "tex"); + m_finalScreenShader.uniformLocations[SHADER_TIME] = glGetUniformLocation(m_finalScreenShader.program, "time"); + if (m_finalScreenShader.uniformLocations[SHADER_TIME] != -1) m_finalScreenShader.initialTime = m_globalTimer.getSeconds(); - m_finalScreenShader.wl_output = glGetUniformLocation(m_finalScreenShader.program, "wl_output"); - m_finalScreenShader.fullSize = glGetUniformLocation(m_finalScreenShader.program, "screen_size"); - if (m_finalScreenShader.fullSize == -1) - m_finalScreenShader.fullSize = glGetUniformLocation(m_finalScreenShader.program, "screenSize"); - if (m_finalScreenShader.time != -1 && *PDT != 0 && !g_pHyprRenderer->m_crashingInProgress) { + m_finalScreenShader.uniformLocations[SHADER_WL_OUTPUT] = glGetUniformLocation(m_finalScreenShader.program, "wl_output"); + m_finalScreenShader.uniformLocations[SHADER_FULL_SIZE] = glGetUniformLocation(m_finalScreenShader.program, "screen_size"); + if (m_finalScreenShader.uniformLocations[SHADER_FULL_SIZE] == -1) + m_finalScreenShader.uniformLocations[SHADER_FULL_SIZE] = glGetUniformLocation(m_finalScreenShader.program, "screenSize"); + if (m_finalScreenShader.uniformLocations[SHADER_TIME] != -1 && *PDT != 0 && !g_pHyprRenderer->m_crashingInProgress) { // The screen shader uses the "time" uniform // Since the screen shader could change every frame, damage tracking *needs* to be disabled g_pConfigManager->addParseError("Screen shader: Screen shader uses uniform 'time', which requires debug:damage_tracking to be switched off.\n" "WARNING: Disabling damage tracking will *massively* increase GPU utilization!"); } - m_finalScreenShader.texAttrib = glGetAttribLocation(m_finalScreenShader.program, "texcoord"); - m_finalScreenShader.posAttrib = glGetAttribLocation(m_finalScreenShader.program, "pos"); + m_finalScreenShader.uniformLocations[SHADER_TEX_ATTRIB] = glGetAttribLocation(m_finalScreenShader.program, "texcoord"); + m_finalScreenShader.uniformLocations[SHADER_POS_ATTRIB] = glGetAttribLocation(m_finalScreenShader.program, "pos"); m_finalScreenShader.createVao(); } @@ -1266,10 +1260,10 @@ void CHyprOpenGLImpl::clear(const CHyprColor& color) { void CHyprOpenGLImpl::blend(bool enabled) { if (enabled) { - glEnable(GL_BLEND); + setCapStatus(GL_BLEND, true); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); // everything is premultiplied } else - glDisable(GL_BLEND); + setCapStatus(GL_BLEND, false); m_blend = enabled; } @@ -1277,24 +1271,36 @@ void CHyprOpenGLImpl::blend(bool enabled) { void CHyprOpenGLImpl::scissor(const CBox& originalBox, bool transform) { RASSERT(m_renderData.pMonitor, "Tried to scissor without begin()!"); + // only call glScissor if the box has changed + static CBox m_lastScissorBox = {}; + if (transform) { CBox box = originalBox; const auto TR = wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)); box.transform(TR, m_renderData.pMonitor->m_transformedSize.x, m_renderData.pMonitor->m_transformedSize.y); - glScissor(box.x, box.y, box.width, box.height); - glEnable(GL_SCISSOR_TEST); + + if (box != m_lastScissorBox) { + glScissor(box.x, box.y, box.width, box.height); + m_lastScissorBox = box; + } + + setCapStatus(GL_SCISSOR_TEST, true); return; } - glScissor(originalBox.x, originalBox.y, originalBox.width, originalBox.height); - glEnable(GL_SCISSOR_TEST); + if (originalBox != m_lastScissorBox) { + glScissor(originalBox.x, originalBox.y, originalBox.width, originalBox.height); + m_lastScissorBox = originalBox; + } + + setCapStatus(GL_SCISSOR_TEST, true); } void CHyprOpenGLImpl::scissor(const pixman_box32* pBox, bool transform) { RASSERT(m_renderData.pMonitor, "Tried to scissor without begin()!"); if (!pBox) { - glDisable(GL_SCISSOR_TEST); + setCapStatus(GL_SCISSOR_TEST, false); return; } @@ -1329,7 +1335,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col, glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_STENCIL_TEST); + setCapStatus(GL_STENCIL_TEST, true); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -1352,7 +1358,7 @@ void CHyprOpenGLImpl::renderRectWithBlur(const CBox& box, const CHyprColor& col, glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); - glDisable(GL_STENCIL_TEST); + setCapStatus(GL_STENCIL_TEST, false); glStencilMask(0xFF); glStencilFunc(GL_ALWAYS, 1, 0xFF); scissor(nullptr); @@ -1374,10 +1380,10 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co Mat3x3 glMatrix = m_renderData.projection.copy().multiply(matrix); useProgram(m_shaders->m_shQUAD.program); - glUniformMatrix3fv(m_shaders->m_shQUAD.proj, 1, GL_TRUE, glMatrix.getMatrix().data()); + m_shaders->m_shQUAD.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); // premultiply the color as well as we don't work with straight alpha - glUniform4f(m_shaders->m_shQUAD.color, col.r * col.a, col.g * col.a, col.b * col.a, col.a); + m_shaders->m_shQUAD.setUniformFloat4(SHADER_COLOR, col.r * col.a, col.g * col.a, col.b * col.a, col.a); CBox transformedBox = box; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x, @@ -1387,12 +1393,12 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co const auto FULLSIZE = Vector2D(transformedBox.width, transformedBox.height); // Rounded corners - glUniform2f(m_shaders->m_shQUAD.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); - glUniform2f(m_shaders->m_shQUAD.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform1f(m_shaders->m_shQUAD.radius, round); - glUniform1f(m_shaders->m_shQUAD.roundingPower, roundingPower); + m_shaders->m_shQUAD.setUniformFloat2(SHADER_TOP_LEFT, (float)TOPLEFT.x, (float)TOPLEFT.y); + m_shaders->m_shQUAD.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y); + m_shaders->m_shQUAD.setUniformFloat(SHADER_RADIUS, round); + m_shaders->m_shQUAD.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower); - glBindVertexArray(m_shaders->m_shQUAD.shaderVao); + glBindVertexArray(m_shaders->m_shQUAD.uniformLocations[SHADER_SHADER_VAO]); if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) { CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height}; @@ -1412,7 +1418,6 @@ void CHyprOpenGLImpl::renderRectWithDamage(const CBox& box, const CHyprColor& co } glBindVertexArray(0); - scissor(nullptr); } @@ -1436,40 +1441,40 @@ void CHyprOpenGLImpl::renderTextureWithDamage(SP<CTexture> tex, const CBox& box, static std::map<std::pair<uint32_t, uint32_t>, std::array<GLfloat, 9>> primariesConversionCache; -void CHyprOpenGLImpl::passCMUniforms(const SShader& shader, const NColorManagement::SImageDescription& imageDescription, - const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) { - glUniform1i(shader.sourceTF, imageDescription.transferFunction); - glUniform1i(shader.targetTF, targetImageDescription.transferFunction); +void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const NColorManagement::SImageDescription& imageDescription, + const NColorManagement::SImageDescription& targetImageDescription, bool modifySDR, float sdrMinLuminance, int sdrMaxLuminance) { + shader.setUniformInt(SHADER_SOURCE_TF, imageDescription.transferFunction); + shader.setUniformInt(SHADER_TARGET_TF, targetImageDescription.transferFunction); - const auto targetPrimaries = targetImageDescription.primariesNameSet || targetImageDescription.primaries == SPCPRimaries{} ? - getPrimaries(targetImageDescription.primariesNamed) : - targetImageDescription.primaries; + const auto targetPrimaries = targetImageDescription.primariesNameSet || targetImageDescription.primaries == SPCPRimaries{} ? + getPrimaries(targetImageDescription.primariesNamed) : + targetImageDescription.primaries; - const GLfloat glTargetPrimaries[8] = { + const std::array<GLfloat, 8> glTargetPrimaries = { targetPrimaries.red.x, targetPrimaries.red.y, targetPrimaries.green.x, targetPrimaries.green.y, targetPrimaries.blue.x, targetPrimaries.blue.y, targetPrimaries.white.x, targetPrimaries.white.y, }; - glUniformMatrix4x2fv(shader.targetPrimaries, 1, false, glTargetPrimaries); + shader.setUniformMatrix4x2fv(SHADER_TARGET_PRIMARIES, 1, false, glTargetPrimaries); - glUniform2f(shader.srcTFRange, imageDescription.getTFMinLuminance(sdrMinLuminance), imageDescription.getTFMaxLuminance(sdrMaxLuminance)); - glUniform2f(shader.dstTFRange, targetImageDescription.getTFMinLuminance(sdrMinLuminance), targetImageDescription.getTFMaxLuminance(sdrMaxLuminance)); + shader.setUniformFloat2(SHADER_SRC_TF_RANGE, imageDescription.getTFMinLuminance(sdrMinLuminance), imageDescription.getTFMaxLuminance(sdrMaxLuminance)); + shader.setUniformFloat2(SHADER_DST_TF_RANGE, targetImageDescription.getTFMinLuminance(sdrMinLuminance), targetImageDescription.getTFMaxLuminance(sdrMaxLuminance)); const float maxLuminance = imageDescription.luminances.max > 0 ? imageDescription.luminances.max : imageDescription.luminances.reference; - glUniform1f(shader.maxLuminance, maxLuminance * targetImageDescription.luminances.reference / imageDescription.luminances.reference); - glUniform1f(shader.dstMaxLuminance, targetImageDescription.luminances.max > 0 ? targetImageDescription.luminances.max : 10000); - glUniform1f(shader.dstRefLuminance, targetImageDescription.luminances.reference); - glUniform1f(shader.sdrSaturation, - modifySDR && m_renderData.pMonitor->m_sdrSaturation > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? - m_renderData.pMonitor->m_sdrSaturation : - 1.0f); - glUniform1f(shader.sdrBrightness, - modifySDR && m_renderData.pMonitor->m_sdrBrightness > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? - m_renderData.pMonitor->m_sdrBrightness : - - 1.0f); + shader.setUniformFloat(SHADER_MAX_LUMINANCE, maxLuminance * targetImageDescription.luminances.reference / imageDescription.luminances.reference); + shader.setUniformFloat(SHADER_DST_MAX_LUMINANCE, targetImageDescription.luminances.max > 0 ? targetImageDescription.luminances.max : 10000); + shader.setUniformFloat(SHADER_DST_REF_LUMINANCE, targetImageDescription.luminances.reference); + shader.setUniformFloat(SHADER_SDR_SATURATION, + modifySDR && m_renderData.pMonitor->m_sdrSaturation > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? + m_renderData.pMonitor->m_sdrSaturation : + 1.0f); + shader.setUniformFloat(SHADER_SDR_BRIGHTNESS, + modifySDR && m_renderData.pMonitor->m_sdrBrightness > 0 && targetImageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? + m_renderData.pMonitor->m_sdrBrightness : + + 1.0f); const auto cacheKey = std::make_pair(imageDescription.getId(), targetImageDescription.getId()); if (!primariesConversionCache.contains(cacheKey)) { - const auto mat = imageDescription.getPrimaries().convertMatrix(targetImageDescription.getPrimaries()).mat(); + const auto mat = imageDescription.getPrimaries().convertMatrix(targetImageDescription.getPrimaries()).mat(); const std::array<GLfloat, 9> glConvertMatrix = { mat[0][0], mat[1][0], mat[2][0], // mat[0][1], mat[1][1], mat[2][1], // @@ -1477,10 +1482,10 @@ void CHyprOpenGLImpl::passCMUniforms(const SShader& shader, const NColorManageme }; primariesConversionCache.insert(std::make_pair(cacheKey, glConvertMatrix)); } - glUniformMatrix3fv(shader.convertMatrix, 1, false, &primariesConversionCache[cacheKey][0]); + shader.setUniformMatrix3fv(SHADER_CONVERT_MATRIX, 1, false, primariesConversionCache[cacheKey]); } -void CHyprOpenGLImpl::passCMUniforms(const SShader& shader, const SImageDescription& imageDescription) { +void CHyprOpenGLImpl::passCMUniforms(SShader& shader, const SImageDescription& imageDescription) { passCMUniforms(shader, imageDescription, m_renderData.pMonitor->m_imageDescription, true, m_renderData.pMonitor->m_sdrMinLuminance, m_renderData.pMonitor->m_sdrMaxLuminance); } @@ -1547,17 +1552,17 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB } glActiveTexture(GL_TEXTURE0); - glBindTexture(tex->m_target, tex->m_texID); + tex->bind(); - glTexParameteri(tex->m_target, GL_TEXTURE_WRAP_S, wrapX); - glTexParameteri(tex->m_target, GL_TEXTURE_WRAP_T, wrapY); + tex->setTexParameter(GL_TEXTURE_WRAP_S, wrapX); + tex->setTexParameter(GL_TEXTURE_WRAP_T, wrapY); if (m_renderData.useNearestNeighbor) { - glTexParameteri(tex->m_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(tex->m_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_NEAREST); + tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_NEAREST); } else { - glTexParameteri(tex->m_target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(tex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); } const auto imageDescription = @@ -1575,40 +1580,38 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB useProgram(shader->program); if (shader == &m_shaders->m_shCM) { - glUniform1i(shader->texType, texType); + shader->setUniformInt(SHADER_TEX_TYPE, texType); passCMUniforms(*shader, imageDescription); } - glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform1i(shader->tex, 0); + shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + shader->setUniformInt(SHADER_TEX, 0); - if ((usingFinalShader && *PDT == 0) || CRASHING) { - glUniform1f(shader->time, m_globalTimer.getSeconds() - shader->initialTime); - } else if (usingFinalShader && shader->time != -1) { - // Don't let time be unitialised - glUniform1f(shader->time, 0.f); - } + if ((usingFinalShader && *PDT == 0) || CRASHING) + shader->setUniformFloat(SHADER_TIME, m_globalTimer.getSeconds() - shader->initialTime); + else if (usingFinalShader) + shader->setUniformFloat(SHADER_TIME, 0.f); - if (usingFinalShader && shader->wl_output != -1) - glUniform1i(shader->wl_output, m_renderData.pMonitor->m_id); - if (usingFinalShader && shader->fullSize != -1) - glUniform2f(shader->fullSize, m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y); + if (usingFinalShader) { + shader->setUniformInt(SHADER_WL_OUTPUT, m_renderData.pMonitor->m_id); + shader->setUniformFloat2(SHADER_FULL_SIZE, m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y); + } if (CRASHING) { - glUniform1f(shader->distort, g_pHyprRenderer->m_crashingDistort); - glUniform2f(shader->fullSize, m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y); + shader->setUniformFloat(SHADER_DISTORT, g_pHyprRenderer->m_crashingDistort); + shader->setUniformFloat2(SHADER_FULL_SIZE, m_renderData.pMonitor->m_pixelSize.x, m_renderData.pMonitor->m_pixelSize.y); } if (!usingFinalShader) { - glUniform1f(shader->alpha, alpha); + shader->setUniformFloat(SHADER_ALPHA, alpha); if (discardActive) { - glUniform1i(shader->discardOpaque, !!(m_renderData.discardMode & DISCARD_OPAQUE)); - glUniform1i(shader->discardAlpha, !!(m_renderData.discardMode & DISCARD_ALPHA)); - glUniform1f(shader->discardAlphaValue, m_renderData.discardOpacity); + shader->setUniformInt(SHADER_DISCARD_OPAQUE, !!(m_renderData.discardMode & DISCARD_OPAQUE)); + shader->setUniformInt(SHADER_DISCARD_ALPHA, !!(m_renderData.discardMode & DISCARD_ALPHA)); + shader->setUniformFloat(SHADER_DISCARD_ALPHA_VALUE, m_renderData.discardOpacity); } else { - glUniform1i(shader->discardOpaque, 0); - glUniform1i(shader->discardAlpha, 0); + shader->setUniformInt(SHADER_DISCARD_OPAQUE, 0); + shader->setUniformInt(SHADER_DISCARD_ALPHA, 0); } } @@ -1621,27 +1624,27 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB if (!usingFinalShader) { // Rounded corners - glUniform2f(shader->topLeft, TOPLEFT.x, TOPLEFT.y); - glUniform2f(shader->fullSize, FULLSIZE.x, FULLSIZE.y); - glUniform1f(shader->radius, round); - glUniform1f(shader->roundingPower, roundingPower); + shader->setUniformFloat2(SHADER_TOP_LEFT, TOPLEFT.x, TOPLEFT.y); + shader->setUniformFloat2(SHADER_FULL_SIZE, FULLSIZE.x, FULLSIZE.y); + shader->setUniformFloat(SHADER_RADIUS, round); + shader->setUniformFloat(SHADER_ROUNDING_POWER, roundingPower); if (allowDim && m_renderData.currentWindow) { if (m_renderData.currentWindow->m_notRespondingTint->value() > 0) { const auto DIM = m_renderData.currentWindow->m_notRespondingTint->value(); - glUniform1i(shader->applyTint, 1); - glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); + shader->setUniformInt(SHADER_APPLY_TINT, 1); + shader->setUniformFloat3(SHADER_TINT, 1.f - DIM, 1.f - DIM, 1.f - DIM); } else if (m_renderData.currentWindow->m_dimPercent->value() > 0) { - glUniform1i(shader->applyTint, 1); + shader->setUniformInt(SHADER_APPLY_TINT, 1); const auto DIM = m_renderData.currentWindow->m_dimPercent->value(); - glUniform3f(shader->tint, 1.f - DIM, 1.f - DIM, 1.f - DIM); + shader->setUniformFloat3(SHADER_TINT, 1.f - DIM, 1.f - DIM, 1.f - DIM); } else - glUniform1i(shader->applyTint, 0); + shader->setUniformInt(SHADER_APPLY_TINT, 0); } else - glUniform1i(shader->applyTint, 0); + shader->setUniformInt(SHADER_APPLY_TINT, 0); } - glBindVertexArray(shader->shaderVao); + glBindVertexArray(shader->uniformLocations[SHADER_SHADER_VAO]); if (allowCustomUV && m_renderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) { const float customUVs[] = { m_renderData.primarySurfaceUVBottomRight.x, m_renderData.primarySurfaceUVTopLeft.y, m_renderData.primarySurfaceUVTopLeft.x, @@ -1649,10 +1652,10 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB m_renderData.primarySurfaceUVTopLeft.x, m_renderData.primarySurfaceUVBottomRight.y, }; - glBindBuffer(GL_ARRAY_BUFFER, shader->shaderVboUv); + glBindBuffer(GL_ARRAY_BUFFER, shader->uniformLocations[SHADER_SHADER_VBO_UV]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(customUVs), customUVs); } else { - glBindBuffer(GL_ARRAY_BUFFER, shader->shaderVboUv); + glBindBuffer(GL_ARRAY_BUFFER, shader->uniformLocations[SHADER_SHADER_VBO_UV]); glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(fullVerts), fullVerts); } @@ -1681,7 +1684,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(SP<CTexture> tex, const CB glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(tex->m_target, 0); + tex->unbind(); } void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box) { @@ -1704,12 +1707,12 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box) SShader* shader = &m_shaders->m_shPASSTHRURGBA; glActiveTexture(GL_TEXTURE0); - glBindTexture(tex->m_target, tex->m_texID); + tex->bind(); useProgram(shader->program); - glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform1i(shader->tex, 0); - glBindVertexArray(shader->shaderVao); + shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + shader->setUniformInt(SHADER_TEX, 0); + glBindVertexArray(shader->uniformLocations[SHADER_SHADER_VAO]); for (auto const& RECT : m_renderData.damage.getRects()) { scissor(&RECT); @@ -1717,9 +1720,8 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box) } scissor(nullptr); - glBindVertexArray(0); - glBindTexture(tex->m_target, 0); + tex->unbind(); } void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFramebuffer& matte) { @@ -1742,18 +1744,18 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra SShader* shader = &m_shaders->m_shMATTE; useProgram(shader->program); - glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform1i(shader->tex, 0); - glUniform1i(shader->alphaMatte, 1); + shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + shader->setUniformInt(SHADER_TEX, 0); + shader->setUniformInt(SHADER_ALPHA_MATTE, 1); glActiveTexture(GL_TEXTURE0); - glBindTexture(tex->m_target, tex->m_texID); + tex->bind(); glActiveTexture(GL_TEXTURE0 + 1); auto matteTex = matte.getTexture(); - glBindTexture(matteTex->m_target, matteTex->m_texID); + matteTex->bind(); - glBindVertexArray(shader->shaderVao); + glBindVertexArray(shader->uniformLocations[SHADER_SHADER_VAO]); for (auto const& RECT : m_renderData.damage.getRects()) { scissor(&RECT); @@ -1761,9 +1763,8 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra } scissor(nullptr); - glBindVertexArray(0); - glBindTexture(tex->m_target, 0); + tex->unbind(); } // This probably isn't the fastest @@ -1784,7 +1785,7 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi const auto BLENDBEFORE = m_blend; blend(false); - glDisable(GL_STENCIL_TEST); + setCapStatus(GL_STENCIL_TEST, false); // get transforms for the full monitor const auto TRANSFORM = wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)); @@ -1822,35 +1823,34 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi auto currentTex = source.getTexture(); - glBindTexture(currentTex->m_target, currentTex->m_texID); - - glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + currentTex->bind(); + currentTex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); useProgram(m_shaders->m_shBLURPREPARE.program); // From FB to sRGB const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{}; - glUniform1i(m_shaders->m_shBLURPREPARE.skipCM, skipCM); + m_shaders->m_shBLURPREPARE.setUniformInt(SHADER_SKIP_CM, skipCM); if (!skipCM) { passCMUniforms(m_shaders->m_shBLURPREPARE, m_renderData.pMonitor->m_imageDescription, SImageDescription{}); - glUniform1f(m_shaders->m_shBLURPREPARE.sdrSaturation, - m_renderData.pMonitor->m_sdrSaturation > 0 && - m_renderData.pMonitor->m_imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? - m_renderData.pMonitor->m_sdrSaturation : - 1.0f); - glUniform1f(m_shaders->m_shBLURPREPARE.sdrBrightness, - m_renderData.pMonitor->m_sdrBrightness > 0 && - m_renderData.pMonitor->m_imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? - m_renderData.pMonitor->m_sdrBrightness : - 1.0f); + m_shaders->m_shBLURPREPARE.setUniformFloat(SHADER_SDR_SATURATION, + m_renderData.pMonitor->m_sdrSaturation > 0 && + m_renderData.pMonitor->m_imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? + m_renderData.pMonitor->m_sdrSaturation : + 1.0f); + m_shaders->m_shBLURPREPARE.setUniformFloat(SHADER_SDR_BRIGHTNESS, + m_renderData.pMonitor->m_sdrBrightness > 0 && + m_renderData.pMonitor->m_imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_ST2084_PQ ? + m_renderData.pMonitor->m_sdrBrightness : + 1.0f); } - glUniformMatrix3fv(m_shaders->m_shBLURPREPARE.proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform1f(m_shaders->m_shBLURPREPARE.contrast, *PBLURCONTRAST); - glUniform1f(m_shaders->m_shBLURPREPARE.brightness, *PBLURBRIGHTNESS); - glUniform1i(m_shaders->m_shBLURPREPARE.tex, 0); + m_shaders->m_shBLURPREPARE.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + m_shaders->m_shBLURPREPARE.setUniformFloat(SHADER_CONTRAST, *PBLURCONTRAST); + m_shaders->m_shBLURPREPARE.setUniformFloat(SHADER_BRIGHTNESS, *PBLURBRIGHTNESS); + m_shaders->m_shBLURPREPARE.setUniformInt(SHADER_TEX, 0); - glBindVertexArray(m_shaders->m_shBLURPREPARE.shaderVao); + glBindVertexArray(m_shaders->m_shBLURPREPARE.uniformLocations[SHADER_SHADER_VAO]); if (!damage.empty()) { for (auto const& RECT : damage.getRects()) { @@ -1874,25 +1874,26 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi auto currentTex = currentRenderToFB->getTexture(); - glBindTexture(currentTex->m_target, currentTex->m_texID); + currentTex->bind(); - glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + currentTex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); useProgram(pShader->program); // prep two shaders - glUniformMatrix3fv(pShader->proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform1f(pShader->radius, *PBLURSIZE * a); // this makes the blursize change with a + pShader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + pShader->setUniformFloat(SHADER_RADIUS, *PBLURSIZE * a); // this makes the blursize change with a if (pShader == &m_shaders->m_shBLUR1) { - glUniform2f(m_shaders->m_shBLUR1.halfpixel, 0.5f / (m_renderData.pMonitor->m_pixelSize.x / 2.f), 0.5f / (m_renderData.pMonitor->m_pixelSize.y / 2.f)); - glUniform1i(m_shaders->m_shBLUR1.passes, *PBLURPASSES); - glUniform1f(m_shaders->m_shBLUR1.vibrancy, *PBLURVIBRANCY); - glUniform1f(m_shaders->m_shBLUR1.vibrancy_darkness, *PBLURVIBRANCYDARKNESS); + m_shaders->m_shBLUR1.setUniformFloat2(SHADER_HALFPIXEL, 0.5f / (m_renderData.pMonitor->m_pixelSize.x / 2.f), 0.5f / (m_renderData.pMonitor->m_pixelSize.y / 2.f)); + m_shaders->m_shBLUR1.setUniformInt(SHADER_PASSES, *PBLURPASSES); + m_shaders->m_shBLUR1.setUniformFloat(SHADER_VIBRANCY, *PBLURVIBRANCY); + m_shaders->m_shBLUR1.setUniformFloat(SHADER_VIBRANCY_DARKNESS, *PBLURVIBRANCYDARKNESS); } else - glUniform2f(m_shaders->m_shBLUR2.halfpixel, 0.5f / (m_renderData.pMonitor->m_pixelSize.x * 2.f), 0.5f / (m_renderData.pMonitor->m_pixelSize.y * 2.f)); - glUniform1i(pShader->tex, 0); + m_shaders->m_shBLUR2.setUniformFloat2(SHADER_HALFPIXEL, 0.5f / (m_renderData.pMonitor->m_pixelSize.x * 2.f), 0.5f / (m_renderData.pMonitor->m_pixelSize.y * 2.f)); + pShader->setUniformInt(SHADER_TEX, 0); + + glBindVertexArray(pShader->uniformLocations[SHADER_SHADER_VAO]); - glBindVertexArray(pShader->shaderVao); if (!pDamage->empty()) { for (auto const& RECT : pDamage->getRects()) { scissor(&RECT, false /* this region is already transformed */); @@ -1911,7 +1912,7 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi // draw the things. // first draw is swap -> mirr PMIRRORFB->bind(); - glBindTexture(PMIRRORSWAPFB->getTexture()->m_target, PMIRRORSWAPFB->getTexture()->m_texID); + PMIRRORSWAPFB->getTexture()->bind(); // damage region will be scaled, make a temp CRegion tempDamage{damage}; @@ -1941,18 +1942,18 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi auto currentTex = currentRenderToFB->getTexture(); - glBindTexture(currentTex->m_target, currentTex->m_texID); + currentTex->bind(); - glTexParameteri(currentTex->m_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + currentTex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); useProgram(m_shaders->m_shBLURFINISH.program); - glUniformMatrix3fv(m_shaders->m_shBLURFINISH.proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform1f(m_shaders->m_shBLURFINISH.noise, *PBLURNOISE); - glUniform1f(m_shaders->m_shBLURFINISH.brightness, *PBLURBRIGHTNESS); + m_shaders->m_shBLURFINISH.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + m_shaders->m_shBLURFINISH.setUniformFloat(SHADER_NOISE, *PBLURNOISE); + m_shaders->m_shBLURFINISH.setUniformFloat(SHADER_BRIGHTNESS, *PBLURBRIGHTNESS); - glUniform1i(m_shaders->m_shBLURFINISH.tex, 0); + m_shaders->m_shBLURFINISH.setUniformInt(SHADER_TEX, 0); - glBindVertexArray(m_shaders->m_shBLURFINISH.shaderVao); + glBindVertexArray(m_shaders->m_shBLURFINISH.uniformLocations[SHADER_SHADER_VAO]); if (!damage.empty()) { for (auto const& RECT : damage.getRects()) { @@ -1970,7 +1971,7 @@ CFramebuffer* CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* origi } // finish - glBindTexture(PMIRRORFB->getTexture()->m_target, 0); + PMIRRORFB->getTexture()->unbind(); blend(BLENDBEFORE); @@ -2188,7 +2189,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_STENCIL_TEST); + setCapStatus(GL_STENCIL_TEST, true); glStencilFunc(GL_ALWAYS, 1, 0xFF); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); @@ -2237,7 +2238,7 @@ void CHyprOpenGLImpl::renderTextureWithBlur(SP<CTexture> tex, const CBox& box, f glClear(GL_STENCIL_BUFFER_BIT); // draw window - glDisable(GL_STENCIL_TEST); + setCapStatus(GL_STENCIL_TEST, false); renderTextureInternalWithDamage(tex, box, a * overallA, texDamage, round, roundingPower, false, false, true, true, wrapX, wrapY); glStencilMask(0xFF); @@ -2281,16 +2282,16 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr useProgram(m_shaders->m_shBORDER1.program); const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{}; - glUniform1i(m_shaders->m_shBORDER1.skipCM, skipCM); + m_shaders->m_shBORDER1.setUniformInt(SHADER_SKIP_CM, skipCM); if (!skipCM) passCMUniforms(m_shaders->m_shBORDER1, SImageDescription{}); - glUniformMatrix3fv(m_shaders->m_shBORDER1.proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform4fv(m_shaders->m_shBORDER1.gradient, grad.m_colorsOkLabA.size() / 4, (float*)grad.m_colorsOkLabA.data()); - glUniform1i(m_shaders->m_shBORDER1.gradientLength, grad.m_colorsOkLabA.size() / 4); - glUniform1f(m_shaders->m_shBORDER1.angle, (int)(grad.m_angle / (PI / 180.0)) % 360 * (PI / 180.0)); - glUniform1f(m_shaders->m_shBORDER1.alpha, a); - glUniform1i(m_shaders->m_shBORDER1.gradient2Length, 0); + m_shaders->m_shBORDER1.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + m_shaders->m_shBORDER1.setUniform4fv(SHADER_GRADIENT, grad.m_colorsOkLabA.size() / 4, grad.m_colorsOkLabA); + m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT_LENGTH, grad.m_colorsOkLabA.size() / 4); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE, (int)(grad.m_angle / (PI / 180.0)) % 360 * (PI / 180.0)); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ALPHA, a); + m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT2_LENGTH, 0); CBox transformedBox = newBox; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x, @@ -2299,15 +2300,15 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y); const auto FULLSIZE = Vector2D(transformedBox.width, transformedBox.height); - glUniform2f(m_shaders->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); - glUniform2f(m_shaders->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform2f(m_shaders->m_shBORDER1.fullSizeUntransformed, (float)newBox.width, (float)newBox.height); - glUniform1f(m_shaders->m_shBORDER1.radius, round); - glUniform1f(m_shaders->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); - glUniform1f(m_shaders->m_shBORDER1.roundingPower, roundingPower); - glUniform1f(m_shaders->m_shBORDER1.thick, scaledBorderSize); + m_shaders->m_shBORDER1.setUniformFloat2(SHADER_TOP_LEFT, (float)TOPLEFT.x, (float)TOPLEFT.y); + m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y); + m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE_UNTRANSFORMED, (float)newBox.width, (float)newBox.height); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS, round); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS_OUTER, outerRound == -1 ? round : outerRound); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_THICK, scaledBorderSize); - glBindVertexArray(m_shaders->m_shBORDER1.shaderVao); + glBindVertexArray(m_shaders->m_shBORDER1.uniformLocations[SHADER_SHADER_VAO]); if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) { CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height}; @@ -2366,16 +2367,16 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr blend(true); useProgram(m_shaders->m_shBORDER1.program); - glUniformMatrix3fv(m_shaders->m_shBORDER1.proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform4fv(m_shaders->m_shBORDER1.gradient, grad1.m_colorsOkLabA.size() / 4, (float*)grad1.m_colorsOkLabA.data()); - glUniform1i(m_shaders->m_shBORDER1.gradientLength, grad1.m_colorsOkLabA.size() / 4); - glUniform1f(m_shaders->m_shBORDER1.angle, (int)(grad1.m_angle / (PI / 180.0)) % 360 * (PI / 180.0)); + m_shaders->m_shBORDER1.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + m_shaders->m_shBORDER1.setUniform4fv(SHADER_GRADIENT, grad1.m_colorsOkLabA.size() / 4, grad1.m_colorsOkLabA); + m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT_LENGTH, grad1.m_colorsOkLabA.size() / 4); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE, (int)(grad1.m_angle / (PI / 180.0)) % 360 * (PI / 180.0)); if (!grad2.m_colorsOkLabA.empty()) - glUniform4fv(m_shaders->m_shBORDER1.gradient2, grad2.m_colorsOkLabA.size() / 4, (float*)grad2.m_colorsOkLabA.data()); - glUniform1i(m_shaders->m_shBORDER1.gradient2Length, grad2.m_colorsOkLabA.size() / 4); - glUniform1f(m_shaders->m_shBORDER1.angle2, (int)(grad2.m_angle / (PI / 180.0)) % 360 * (PI / 180.0)); - glUniform1f(m_shaders->m_shBORDER1.alpha, a); - glUniform1f(m_shaders->m_shBORDER1.gradientLerp, lerp); + m_shaders->m_shBORDER1.setUniform4fv(SHADER_GRADIENT2, grad2.m_colorsOkLabA.size() / 4, grad2.m_colorsOkLabA); + m_shaders->m_shBORDER1.setUniformInt(SHADER_GRADIENT2_LENGTH, grad2.m_colorsOkLabA.size() / 4); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ANGLE2, (int)(grad2.m_angle / (PI / 180.0)) % 360 * (PI / 180.0)); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ALPHA, a); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_GRADIENT_LERP, lerp); CBox transformedBox = newBox; transformedBox.transform(wlTransformToHyprutils(invertTransform(m_renderData.pMonitor->m_transform)), m_renderData.pMonitor->m_transformedSize.x, @@ -2384,15 +2385,15 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr const auto TOPLEFT = Vector2D(transformedBox.x, transformedBox.y); const auto FULLSIZE = Vector2D(transformedBox.width, transformedBox.height); - glUniform2f(m_shaders->m_shBORDER1.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); - glUniform2f(m_shaders->m_shBORDER1.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform2f(m_shaders->m_shBORDER1.fullSizeUntransformed, (float)newBox.width, (float)newBox.height); - glUniform1f(m_shaders->m_shBORDER1.radius, round); - glUniform1f(m_shaders->m_shBORDER1.radiusOuter, outerRound == -1 ? round : outerRound); - glUniform1f(m_shaders->m_shBORDER1.roundingPower, roundingPower); - glUniform1f(m_shaders->m_shBORDER1.thick, scaledBorderSize); + m_shaders->m_shBORDER1.setUniformFloat2(SHADER_TOP_LEFT, (float)TOPLEFT.x, (float)TOPLEFT.y); + m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y); + m_shaders->m_shBORDER1.setUniformFloat2(SHADER_FULL_SIZE_UNTRANSFORMED, (float)newBox.width, (float)newBox.height); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS, round); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_RADIUS_OUTER, outerRound == -1 ? round : outerRound); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower); + m_shaders->m_shBORDER1.setUniformFloat(SHADER_THICK, scaledBorderSize); - glBindVertexArray(m_shaders->m_shBORDER1.shaderVao); + glBindVertexArray(m_shaders->m_shBORDER1.uniformLocations[SHADER_SHADER_VAO]); if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) { CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height}; @@ -2442,27 +2443,27 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun useProgram(m_shaders->m_shSHADOW.program); const bool skipCM = !m_cmSupported || m_renderData.pMonitor->m_imageDescription == SImageDescription{}; - glUniform1i(m_shaders->m_shSHADOW.skipCM, skipCM); + m_shaders->m_shSHADOW.setUniformInt(SHADER_SKIP_CM, skipCM); if (!skipCM) passCMUniforms(m_shaders->m_shSHADOW, SImageDescription{}); - glUniformMatrix3fv(m_shaders->m_shSHADOW.proj, 1, GL_TRUE, glMatrix.getMatrix().data()); - glUniform4f(m_shaders->m_shSHADOW.color, col.r, col.g, col.b, col.a * a); + m_shaders->m_shSHADOW.setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); + m_shaders->m_shSHADOW.setUniformFloat4(SHADER_COLOR, col.r, col.g, col.b, col.a * a); const auto TOPLEFT = Vector2D(range + round, range + round); const auto BOTTOMRIGHT = Vector2D(newBox.width - (range + round), newBox.height - (range + round)); const auto FULLSIZE = Vector2D(newBox.width, newBox.height); // Rounded corners - glUniform2f(m_shaders->m_shSHADOW.topLeft, (float)TOPLEFT.x, (float)TOPLEFT.y); - glUniform2f(m_shaders->m_shSHADOW.bottomRight, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y); - glUniform2f(m_shaders->m_shSHADOW.fullSize, (float)FULLSIZE.x, (float)FULLSIZE.y); - glUniform1f(m_shaders->m_shSHADOW.radius, range + round); - glUniform1f(m_shaders->m_shSHADOW.roundingPower, roundingPower); - glUniform1f(m_shaders->m_shSHADOW.range, range); - glUniform1f(m_shaders->m_shSHADOW.shadowPower, SHADOWPOWER); + m_shaders->m_shSHADOW.setUniformFloat2(SHADER_TOP_LEFT, (float)TOPLEFT.x, (float)TOPLEFT.y); + m_shaders->m_shSHADOW.setUniformFloat2(SHADER_BOTTOM_RIGHT, (float)BOTTOMRIGHT.x, (float)BOTTOMRIGHT.y); + m_shaders->m_shSHADOW.setUniformFloat2(SHADER_FULL_SIZE, (float)FULLSIZE.x, (float)FULLSIZE.y); + m_shaders->m_shSHADOW.setUniformFloat(SHADER_RADIUS, range + round); + m_shaders->m_shSHADOW.setUniformFloat(SHADER_ROUNDING_POWER, roundingPower); + m_shaders->m_shSHADOW.setUniformFloat(SHADER_RANGE, range); + m_shaders->m_shSHADOW.setUniformFloat(SHADER_SHADOW_POWER, SHADOWPOWER); - glBindVertexArray(m_shaders->m_shSHADOW.shaderVao); + glBindVertexArray(m_shaders->m_shSHADOW.uniformLocations[SHADER_SHADER_VAO]); if (m_renderData.clipBox.width != 0 && m_renderData.clipBox.height != 0) { CRegion damageClip{m_renderData.clipBox.x, m_renderData.clipBox.y, m_renderData.clipBox.width, m_renderData.clipBox.height}; @@ -2606,13 +2607,13 @@ SP<CTexture> CHyprOpenGLImpl::loadAsset(const std::string& filename) { const GLint glType = CAIROFORMAT == CAIRO_FORMAT_RGB96F ? GL_FLOAT : GL_UNSIGNED_BYTE; const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - glBindTexture(GL_TEXTURE_2D, tex->m_texID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + tex->bind(); + tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (CAIROFORMAT != CAIRO_FORMAT_RGB96F) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED); } glTexImage2D(GL_TEXTURE_2D, 0, glIFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA); @@ -2689,11 +2690,11 @@ SP<CTexture> CHyprOpenGLImpl::renderText(const std::string& text, CHyprColor col tex->m_size = {cairo_image_surface_get_width(CAIROSURFACE), cairo_image_surface_get_height(CAIROSURFACE)}; const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - glBindTexture(GL_TEXTURE_2D, tex->m_texID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + tex->bind(); + tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex->m_size.x, tex->m_size.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, DATA); cairo_destroy(CAIRO); @@ -2730,11 +2731,11 @@ void CHyprOpenGLImpl::initMissingAssetTexture() { const GLint glType = GL_UNSIGNED_BYTE; const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - glBindTexture(GL_TEXTURE_2D, tex->m_texID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + tex->bind(); + tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED); glTexImage2D(GL_TEXTURE_2D, 0, glFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA); cairo_surface_destroy(CAIROSURFACE); @@ -2858,11 +2859,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) { const GLint glType = GL_UNSIGNED_BYTE; const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); - glBindTexture(GL_TEXTURE_2D, tex->m_texID); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_R, GL_BLUE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_B, GL_RED); + tex->bind(); + tex->setTexParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_R, GL_BLUE); + tex->setTexParameter(GL_TEXTURE_SWIZZLE_B, GL_RED); + glTexImage2D(GL_TEXTURE_2D, 0, glFormat, tex->m_size.x, tex->m_size.y, 0, glFormat, glType, DATA); cairo_surface_destroy(CAIROSURFACE); @@ -3000,6 +3002,29 @@ void CHyprOpenGLImpl::setRenderModifEnabled(bool enabled) { m_renderData.renderModif.enabled = enabled; } +void CHyprOpenGLImpl::setViewport(GLint x, GLint y, GLsizei width, GLsizei height) { + if (m_lastViewport.x == x && m_lastViewport.y == y && m_lastViewport.width == width && m_lastViewport.height == height) + return; + + glViewport(x, y, width, height); + m_lastViewport = {.x = x, .y = y, .width = width, .height = height}; +} + +void CHyprOpenGLImpl::setCapStatus(int cap, bool status) { + // check if the capability status is already set to the desired status + auto it = m_capStatus.find(cap); + bool currentStatus = (it != m_capStatus.end()) ? it->second : false; // default to 'false' if not found + + if (currentStatus == status) + return; + + m_capStatus[cap] = status; + + // Enable or disable the capability based on status + auto func = status ? [](int c) { glEnable(c); } : [](int c) { glDisable(c); }; + func(cap); +} + uint32_t CHyprOpenGLImpl::getPreferredReadFormat(PHLMONITOR pMonitor) { return pMonitor->m_output->state->state().drmFormat; } |
