diff options
| author | UjinT34 <41110182+UjinT34@users.noreply.github.com> | 2026-03-07 18:23:54 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-03-07 15:23:54 +0000 |
| commit | b227efc8492468cc925014a6c8446a3d044b01e8 (patch) | |
| tree | bc0ec5c133a0742ee92f2d4f5bde24b5ebd33a43 /src/render | |
| parent | 73fca55e7c9dd19222c8c0cc331ddebf4c4bfddf (diff) | |
renderer: refactor projection setting (#13485)
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/OpenGL.cpp | 103 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 4 | ||||
| -rw-r--r-- | src/render/Renderer.cpp | 49 | ||||
| -rw-r--r-- | src/render/Renderer.hpp | 43 | ||||
| -rw-r--r-- | src/render/pass/TexPassElement.hpp | 26 |
5 files changed, 109 insertions, 116 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index f9cb83ac..97cefb48 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -662,13 +662,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP setViewport(0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y); - g_pHyprRenderer->m_renderData.projection = Mat3x3::outputProjection(pMonitor->m_pixelSize, HYPRUTILS_TRANSFORM_NORMAL); - - g_pHyprRenderer->m_renderData.monitorProjection = Mat3x3::identity(); - if (pMonitor->m_transform != WL_OUTPUT_TRANSFORM_NORMAL) { - const Vector2D tfmd = pMonitor->m_transform % 2 == 1 ? Vector2D{FBO->m_size.y, FBO->m_size.x} : FBO->m_size; - g_pHyprRenderer->m_renderData.monitorProjection.translate(FBO->m_size / 2.0).transform(Math::wlTransformToHyprutils(pMonitor->m_transform)).translate(-tfmd / 2.0); - } + g_pHyprRenderer->setProjectionType(FBO->m_size); if (!m_shadersInitialized) initShaders(); @@ -716,10 +710,7 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, SP<IFra TRACY_GPU_ZONE("RenderBegin"); setViewport(0, 0, pMonitor->m_pixelSize.x, pMonitor->m_pixelSize.y); - - g_pHyprRenderer->m_renderData.projection = Mat3x3::outputProjection(pMonitor->m_pixelSize, HYPRUTILS_TRANSFORM_NORMAL); - - g_pHyprRenderer->m_renderData.monitorProjection = pMonitor->m_projMatrix; + g_pHyprRenderer->setProjectionType(RPT_MONITOR); if (pMonitor && (!pMonitor->m_offloadFB || pMonitor->m_offloadFB->m_size != pMonitor->m_pixelSize)) destroyMonitorResources(pMonitor); @@ -1101,14 +1092,9 @@ void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprC CBox newBox = box; g_pHyprRenderer->m_renderData.renderModif.applyToBox(newBox); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox( - newBox, - Math::wlTransformToHyprutils( - Math::invertTransform(!g_pHyprRenderer->m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprRenderer->m_renderData.pMonitor->m_transform)), - newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox); - auto shader = useShader(getShaderVariant(SH_FRAG_QUAD, data.round > 0 ? SH_FEAT_ROUNDING : 0)); + auto shader = useShader(getShaderVariant(SH_FRAG_QUAD, data.round > 0 ? SH_FEAT_ROUNDING : 0)); shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); // premultiply the color as well as we don't work with straight alpha @@ -1502,10 +1488,9 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<ITexture> tex, const CBox& box, c if (g_pHyprRenderer->monitorTransformEnabled()) TRANSFORM = Math::composeTransform(MONITOR_INVERTED, TRANSFORM); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox, TRANSFORM); - const bool renderToOutput = m_applyFinalShader && g_pHyprRenderer->workBufferImageDescription()->id() == g_pHyprRenderer->m_renderData.pMonitor->m_imageDescription->id(); + const bool renderToOutput = m_applyFinalShader && g_pHyprRenderer->workBufferImageDescription()->id() == g_pHyprRenderer->m_renderData.pMonitor->m_imageDescription->id(); glActiveTexture(GL_TEXTURE0); tex->bind(); @@ -1594,10 +1579,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<ITexture> tex, const CBox& box) g_pHyprRenderer->m_renderData.renderModif.applyToBox(newBox); // get transform - const auto TRANSFORM = Math::wlTransformToHyprutils( - Math::invertTransform(!g_pHyprRenderer->m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprRenderer->m_renderData.pMonitor->m_transform)); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox); glActiveTexture(GL_TEXTURE0); tex->bind(); @@ -1640,12 +1622,9 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<ITexture> tex, const CBox& box, SP<I g_pHyprRenderer->m_renderData.renderModif.applyToBox(newBox); // get transform - const auto TRANSFORM = Math::wlTransformToHyprutils( - Math::invertTransform(!g_pHyprRenderer->m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprRenderer->m_renderData.pMonitor->m_transform)); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox(newBox, TRANSFORM, newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox); - auto shader = useShader(getShaderVariant(SH_FRAG_MATTE)); + auto shader = useShader(getShaderVariant(SH_FRAG_MATTE)); shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); shader->setUniformInt(SHADER_TEX, 0); shader->setUniformInt(SHADER_ALPHA_MATTE, 1); @@ -1690,10 +1669,10 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or setCapStatus(GL_STENCIL_TEST, false); // get transforms for the full monitor - const auto TRANSFORM = Math::wlTransformToHyprutils(Math::invertTransform(g_pHyprRenderer->m_renderData.pMonitor->m_transform)); - CBox MONITORBOX = {0, 0, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.x, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.y}; - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox(MONITORBOX, TRANSFORM); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto TRANSFORM = Math::wlTransformToHyprutils(Math::invertTransform(g_pHyprRenderer->m_renderData.pMonitor->m_transform)); + CBox MONITORBOX = {0, 0, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.x, g_pHyprRenderer->m_renderData.pMonitor->m_transformedSize.y}; + + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(MONITORBOX, TRANSFORM); // get the config settings static auto PBLURSIZE = CConfigValue<Hyprlang::INT>("decoration:blur:size"); @@ -1753,8 +1732,7 @@ SP<IFramebuffer> CHyprOpenGLImpl::blurFramebufferWithDamage(float a, CRegion* or } else shader = useShader(getShaderVariant(SH_FRAG_BLURPREPARE)); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox(MONITORBOX, *PBLEND ? HYPRUTILS_TRANSFORM_NORMAL : TRANSFORM); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(MONITORBOX, *PBLEND ? HYPRUTILS_TRANSFORM_NORMAL : TRANSFORM); shader->setUniformMatrix3fv(SHADER_PROJ, 1, GL_TRUE, glMatrix.getMatrix()); shader->setUniformFloat(SHADER_CONTRAST, *PBLURCONTRAST); shader->setUniformFloat(SHADER_BRIGHTNESS, *PBLURBRIGHTNESS); @@ -2198,16 +2176,11 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr newBox.width += 2 * scaledBorderSize; newBox.height += 2 * scaledBorderSize; - float round = data.round + (data.round == 0 ? 0 : scaledBorderSize); + float round = data.round + (data.round == 0 ? 0 : scaledBorderSize); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox( - newBox, - Math::wlTransformToHyprutils( - Math::invertTransform(!g_pHyprRenderer->m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprRenderer->m_renderData.pMonitor->m_transform)), - newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox); - const auto BLEND = m_blend; + const auto BLEND = m_blend; blend(true); WP<CShader> shader; @@ -2288,16 +2261,11 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr newBox.width += 2 * scaledBorderSize; newBox.height += 2 * scaledBorderSize; - float round = data.round + (data.round == 0 ? 0 : scaledBorderSize); + float round = data.round + (data.round == 0 ? 0 : scaledBorderSize); - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox( - newBox, - Math::wlTransformToHyprutils( - Math::invertTransform(!g_pHyprRenderer->m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprRenderer->m_renderData.pMonitor->m_transform)), - newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox); - const auto BLEND = m_blend; + const auto BLEND = m_blend; blend(true); WP<CShader> shader; @@ -2374,12 +2342,7 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun const auto col = color; - Mat3x3 matrix = g_pHyprRenderer->m_renderData.monitorProjection.projectBox( - newBox, - Math::wlTransformToHyprutils( - Math::invertTransform(!g_pHyprRenderer->m_monitorTransformEnabled ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprRenderer->m_renderData.pMonitor->m_transform)), - newBox.rot); - Mat3x3 glMatrix = g_pHyprRenderer->m_renderData.projection.copy().multiply(matrix); + const auto& glMatrix = g_pHyprRenderer->projectBoxToTarget(newBox); blend(true); @@ -2477,13 +2440,9 @@ void CHyprOpenGLImpl::renderMirrored() { g_pHyprRenderer->m_renderPass.add(makeUnique<CClearPassElement>(CClearPassElement::SClearData{CHyprColor(0, 0, 0, 0)})); CTexPassElement::SRenderData data; - data.tex = PFB->getTexture(); - data.box = monbox; - data.replaceProjection = Mat3x3::identity() - .translate(monitor->m_pixelSize / 2.0) - .transform(Math::wlTransformToHyprutils(monitor->m_transform)) - .transform(Math::wlTransformToHyprutils(Math::invertTransform(mirrored->m_transform))) - .translate(-monitor->m_transformedSize / 2.0); + data.tex = PFB->getTexture(); + data.box = monbox; + data.useMirrorProjection = true; g_pHyprRenderer->m_renderPass.add(makeUnique<CTexPassElement>(std::move(data))); } @@ -2663,7 +2622,7 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(PHLMONITOR pMonitor) { Log::logger->log(Log::DEBUG, "Background created for monitor {}", pMonitor->m_name); // clear the resource after we're done using it - g_pEventLoopManager->doLater([this] { g_pHyprRenderer->m_backgroundResource.reset(); }); + g_pEventLoopManager->doLater([] { g_pHyprRenderer->m_backgroundResource.reset(); }); // set the animation to start for fading this background in nicely pMonitor->m_backgroundOpacity->setValueAndWarp(0.F); @@ -2708,18 +2667,6 @@ void CHyprOpenGLImpl::destroyMonitorResources(PHLMONITORREF pMonitor) { Log::logger->log(Log::DEBUG, "Monitor {} -> destroyed all render data", pMonitor->m_name); } -void CHyprOpenGLImpl::saveMatrix() { - g_pHyprRenderer->m_renderData.savedProjection = g_pHyprRenderer->m_renderData.projection; -} - -void CHyprOpenGLImpl::setMatrixScaleTranslate(const Vector2D& translate, const float& scale) { - g_pHyprRenderer->m_renderData.projection.scale(scale).translate(translate); -} - -void CHyprOpenGLImpl::restoreMatrix() { - g_pHyprRenderer->m_renderData.projection = g_pHyprRenderer->m_renderData.savedProjection; -} - void CHyprOpenGLImpl::bindOffMain() { if (!g_pHyprRenderer->m_renderData.pMonitor->m_offMainFB) g_pHyprRenderer->m_renderData.pMonitor->m_offMainFB = g_pHyprRenderer->createFB(); diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 77d715a9..b11c1efb 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -231,10 +231,6 @@ class CHyprOpenGLImpl { void setViewport(GLint x, GLint y, GLsizei width, GLsizei height); void setCapStatus(int cap, bool status); - void saveMatrix(); - void setMatrixScaleTranslate(const Vector2D& translate, const float& scale); - void restoreMatrix(); - void blend(bool enabled); void clear(const CHyprColor&); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index f8cf6c6d..8dc2d82c 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -1014,8 +1014,8 @@ void CHyprRenderer::draw(CTexPassElement* element, const CRegion& damage) { // g_pHyprRenderer->popMonitorTransformEnabled(); m_renderData.clipBox = {}; - if (m_data.replaceProjection) - m_renderData.monitorProjection = m_renderData.pMonitor->m_projMatrix; + if (m_data.useMirrorProjection) + setProjectionType(RPT_MONITOR); if (m_data.ignoreAlpha.has_value()) m_renderData.discardMode = 0; }}; @@ -1023,8 +1023,8 @@ void CHyprRenderer::draw(CTexPassElement* element, const CRegion& damage) { if (!m_data.clipBox.empty()) m_renderData.clipBox = m_data.clipBox; - if (m_data.replaceProjection) - m_renderData.monitorProjection = *m_data.replaceProjection; + if (m_data.useMirrorProjection) + setProjectionType(RPT_MIRROR); if (m_data.ignoreAlpha.has_value()) { m_renderData.discardMode = DISCARD_ALPHA; @@ -1875,6 +1875,47 @@ void CHyprRenderer::calculateUVForSurface(PHLWINDOW pWindow, SP<CWLSurfaceResour } } +static Mat3x3 getMirrorProjection(PHLMONITORREF monitor) { + return Mat3x3::identity() + .translate(monitor->m_pixelSize / 2.0) + .transform(Math::wlTransformToHyprutils(monitor->m_transform)) + .transform(Math::wlTransformToHyprutils(Math::invertTransform(monitor->m_mirrorOf->m_transform))) + .translate(-monitor->m_transformedSize / 2.0); +} + +static Mat3x3 getFBProjection(PHLMONITORREF pMonitor, const Vector2D& size) { + if (pMonitor->m_transform == WL_OUTPUT_TRANSFORM_NORMAL) + return Mat3x3::identity(); + + const Vector2D tfmd = pMonitor->m_transform % 2 == 1 ? Vector2D{size.y, size.x} : size; + return Mat3x3::identity().translate(size / 2.0).transform(Math::wlTransformToHyprutils(pMonitor->m_transform)).translate(-tfmd / 2.0); +} + +void CHyprRenderer::setProjectionType(const Vector2D& fbSize) { + m_renderData.fbSize = fbSize; + setProjectionType(RPT_FB); +} + +void CHyprRenderer::setProjectionType(eRenderProjectionType projectionType) { + m_renderData.projectionType = projectionType; + switch (projectionType) { + case RPT_MONITOR: m_renderData.targetProjection = m_renderData.pMonitor->getTransformMatrix(); break; + case RPT_MIRROR: m_renderData.targetProjection = getMirrorProjection(m_renderData.pMonitor); break; + case RPT_FB: m_renderData.targetProjection = getFBProjection(m_renderData.pMonitor, m_renderData.fbSize); break; + default: UNREACHABLE(); + } +} + +Mat3x3 CHyprRenderer::getBoxProjection(const CBox& box, std::optional<eTransform> transform) { + return m_renderData.targetProjection.projectBox( + box, transform.value_or(Math::wlTransformToHyprutils(Math::invertTransform(!monitorTransformEnabled() ? WL_OUTPUT_TRANSFORM_NORMAL : m_renderData.pMonitor->m_transform))), + box.rot); +} + +Mat3x3 CHyprRenderer::projectBoxToTarget(const CBox& box, std::optional<eTransform> transform) { + return m_renderData.pMonitor->getScaleMatrix().copy().multiply(getBoxProjection(box, transform)); +} + static bool isSDR2HDR(const NColorManagement::SImageDescription& imageDescription, const NColorManagement::SImageDescription& targetImageDescription) { // might be too strict return (imageDescription.transferFunction == NColorManagement::CM_TRANSFER_FUNCTION_SRGB || diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 70aaca91..441a603c 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -73,6 +73,12 @@ struct SRenderWorkspaceUntilData { PHLWINDOW w; }; +enum eRenderProjectionType : uint8_t { + RPT_MONITOR, + RPT_MIRROR, + RPT_FB, +}; + struct SRenderData { // can be private Mat3x3 targetProjection; @@ -80,28 +86,26 @@ struct SRenderData { // ---------------------- // used by public - Vector2D fbSize = {-1, -1}; - PHLMONITORREF pMonitor; + Vector2D fbSize = {-1, -1}; + PHLMONITORREF pMonitor; - Mat3x3 projection; - Mat3x3 savedProjection; - Mat3x3 monitorProjection; + eRenderProjectionType projectionType = RPT_MONITOR; - SP<IFramebuffer> currentFB = nullptr; // current rendering to - SP<IFramebuffer> mainFB = nullptr; // main to render to - SP<IFramebuffer> outFB = nullptr; // out to render to (if offloaded, etc) + SP<IFramebuffer> currentFB = nullptr; // current rendering to + SP<IFramebuffer> mainFB = nullptr; // main to render to + SP<IFramebuffer> outFB = nullptr; // out to render to (if offloaded, etc) - CRegion damage; - CRegion finalDamage; // damage used for funal off -> main + CRegion damage; + CRegion finalDamage; // damage used for funal off -> main - SRenderModifData renderModif; - float mouseZoomFactor = 1.f; - bool mouseZoomUseMouse = true; // true by default - bool useNearestNeighbor = false; - bool blockScreenShader = false; + SRenderModifData renderModif; + float mouseZoomFactor = 1.f; + bool mouseZoomUseMouse = true; // true by default + bool useNearestNeighbor = false; + bool blockScreenShader = false; - Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1); - Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); + Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1); + Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); // TODO remove and pass directly CBox clipBox = {}; // scaled coordinates @@ -246,6 +250,11 @@ class CHyprRenderer { void popMonitorTransformEnabled(); bool monitorTransformEnabled(); + void setProjectionType(const Vector2D& fbSize); + void setProjectionType(eRenderProjectionType projectionType); + Mat3x3 getBoxProjection(const CBox& box, std::optional<eTransform> transform = std::nullopt); + Mat3x3 projectBoxToTarget(const CBox& box, std::optional<eTransform> transform = std::nullopt); + SCMSettings getCMSettings(const NColorManagement::PImageDescription imageDescription, const NColorManagement::PImageDescription targetImageDescription, SP<CWLSurfaceResource> surface = nullptr, bool modifySDR = false, float sdrMinLuminance = -1.0f, int sdrMaxLuminance = -1); bool reloadShaders(const std::string& path = ""); diff --git a/src/render/pass/TexPassElement.hpp b/src/render/pass/TexPassElement.hpp index 90f5f40e..1ac3db0c 100644 --- a/src/render/pass/TexPassElement.hpp +++ b/src/render/pass/TexPassElement.hpp @@ -9,19 +9,19 @@ class CSyncTimeline; class CTexPassElement : public IPassElement { public: struct SRenderData { - SP<ITexture> tex; - CBox box; - float a = 1.F; - float blurA = 1.F; - CRegion damage; - int round = 0; - float roundingPower = 2.0f; - bool flipEndFrame = false; - std::optional<Mat3x3> replaceProjection; - CBox clipBox; - bool blur = false; - std::optional<float> ignoreAlpha; - std::optional<bool> blockBlurOptimization; + SP<ITexture> tex; + CBox box; + float a = 1.F; + float blurA = 1.F; + CRegion damage; + int round = 0; + float roundingPower = 2.0f; + bool flipEndFrame = false; + bool useMirrorProjection = false; + CBox clipBox; + bool blur = false; + std::optional<float> ignoreAlpha; + std::optional<bool> blockBlurOptimization; }; CTexPassElement(const SRenderData& data); |
