From f4f090e4b2f9f0bba5408cbd135d2fff1990be1d Mon Sep 17 00:00:00 2001 From: Tom Englund Date: Wed, 25 Jun 2025 12:42:32 +0200 Subject: renderer: reduce a lot of glcalls and cache various states (#10757) * opengl: cache viewport state according to nvidia docs calling glViewPort unnecessarily on the same already set viewport is wasteful and can cause state changes when not needed. cache it in a struct and only call it when the viewport is actually changing. * opengl: cache glenable/gldisable state avoid making multiple glenable/gldisable calls on already set caps, can cause state changes and incur driver overhead. * opengl: cache glscissor box only call glscissor if the box actually has changed, try to avoid state changes. * opengl: cache gluniform calls cache the gluniform calls, the uniform values are cached in driver per program only the drawcalls setting the uniform yet again with the same value on same location is causing more overhead then caching it ourself and just no oping on it if no changes. * shader: rewrite handling of uniforms and state this is way faster as we don't need to mess with maps (hashing, etc) and instead can just use an array * opengl: stuff and 300 shaders * opengl: typo * opengl: get the uniform locations properly now that the legacy shaders are gone get the uniformlocations for SKIP_CM etc, so they can be properly set and used depending on if cm_enabled is set to false or true, before it was falling back to a legacy shader that didnt even have those uniforms. * opengl: check epsilon on float and remove extra glcall seems an extra unset glcall was added, remove it. and check the float epsilon on the glfloat. * opengl: remove instanced shader draw remove the instanced boolean from the vertex shader, might be neglible differences, needs more benchmark/work to see if its even worth it. * texture: cache texture paramaters parameters where occasionally set twice or more on same texture, short version wrap it and cache it. and move gpu churn to cpu churn. add a bind/unbind to texture aswell. * texture: use fast std::array caching cache the texparameter values in fast array lookups and incase we dont want it cached, apply it anyways. * shader: fix typo and hdr typo actually use Matrix4x2fv in the 4x2fv cache function, and send the proper float array for hdr. * texture: make caching not linear lookup make caching of texture params not linear. * minor style changes * opengl: revert drawarrays revert the mostly code style reduce loc change of drawarrays, and focus on the caching. its a if else case going wrong here breaking blur/contrast amongst others drawing. --------- Co-authored-by: Vaxry --- src/render/OpenGL.cpp | 781 ++++++++++++++++++++++++++------------------------ 1 file changed, 403 insertions(+), 378 deletions(-) (limited to 'src/render/OpenGL.cpp') 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::mapTEXVERTSRC = 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 tex, const CBox& box, static std::map, std::array> 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 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 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 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 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 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 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 tex, const CB glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindTexture(tex->m_target, 0); + tex->unbind(); } void CHyprOpenGLImpl::renderTexturePrimitive(SP tex, const CBox& box) { @@ -1704,12 +1707,12 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP 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 tex, const CBox& box) } scissor(nullptr); - glBindVertexArray(0); - glBindTexture(tex->m_target, 0); + tex->unbind(); } void CHyprOpenGLImpl::renderTextureMatte(SP tex, const CBox& box, CFramebuffer& matte) { @@ -1742,18 +1744,18 @@ void CHyprOpenGLImpl::renderTextureMatte(SP 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 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 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 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 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 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; } -- cgit v1.2.3