diff options
| author | Vaxry <vaxry@vaxry.net> | 2023-10-21 14:15:48 +0100 |
|---|---|---|
| committer | Vaxry <vaxry@vaxry.net> | 2023-10-21 14:15:56 +0100 |
| commit | 92311d260ab25c11adab05678663bdccaff11fa6 (patch) | |
| tree | d632d8998a979cb8582eede8dcb0d6f6002f19bd /src/render | |
| parent | af72404259f7a39069d1449bedbc49b3e6ae4fbc (diff) | |
renderer: add transformers
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/OpenGL.cpp | 21 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 7 | ||||
| -rw-r--r-- | src/render/Renderer.cpp | 17 | ||||
| -rw-r--r-- | src/render/Transformer.cpp | 1 | ||||
| -rw-r--r-- | src/render/Transformer.hpp | 13 |
5 files changed, 59 insertions, 0 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 29574887..705d92a8 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -128,10 +128,12 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) { m_RenderData.pCurrentMonData->primaryFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; m_RenderData.pCurrentMonData->mirrorFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; m_RenderData.pCurrentMonData->mirrorSwapFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; + m_RenderData.pCurrentMonData->offMainFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; m_RenderData.pCurrentMonData->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); m_RenderData.pCurrentMonData->mirrorFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); m_RenderData.pCurrentMonData->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); + m_RenderData.pCurrentMonData->offMainFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y); createBGTextureForMonitor(pMonitor); } @@ -149,6 +151,8 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) { m_bFakeFrame = fake; + m_RenderData.currentFB = &m_RenderData.pCurrentMonData->primaryFB; + if (m_bReloadScreenShader) { m_bReloadScreenShader = false; applyScreenShader(g_pConfigManager->getString("decoration:screen_shader")); @@ -1892,6 +1896,7 @@ void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) { g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorSwapFB.release(); g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].monitorMirrorFB.release(); g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].blurFB.release(); + g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].offMainFB.release(); g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].stencilTex.destroyTexture(); g_pHyprOpenGL->m_mMonitorBGTextures[pMonitor].destroyTexture(); g_pHyprOpenGL->m_mMonitorRenderResources.erase(pMonitor); @@ -1914,3 +1919,19 @@ void CHyprOpenGLImpl::setMatrixScaleTranslate(const Vector2D& translate, const f void CHyprOpenGLImpl::restoreMatrix() { memcpy(m_RenderData.projection, m_RenderData.savedProjection, 9 * sizeof(float)); } + +void CHyprOpenGLImpl::bindOffMain() { + m_RenderData.pCurrentMonData->offMainFB.bind(); + clear(CColor(0, 0, 0, 0)); + m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offMainFB; +} + +void CHyprOpenGLImpl::renderOffToMain(CFramebuffer* off) { + wlr_box monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; + renderTexturePrimitive(off->m_cTex, &monbox); +} + +void CHyprOpenGLImpl::bindBackOnMain() { + m_RenderData.pCurrentMonData->primaryFB.bind(); + m_RenderData.currentFB = &m_RenderData.pCurrentMonData->primaryFB; +} diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 61e8ffdb..0d4b7852 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -13,6 +13,7 @@ #include "Shader.hpp" #include "Texture.hpp" #include "Framebuffer.hpp" +#include "Transformer.hpp" #include "../debug/TracyDefines.hpp" @@ -41,6 +42,7 @@ struct SMonitorRenderData { CFramebuffer primaryFB; CFramebuffer mirrorFB; // these are used for some effects, CFramebuffer mirrorSwapFB; // etc + CFramebuffer offMainFB; CFramebuffer monitorMirrorFB; // used for mirroring outputs @@ -75,6 +77,7 @@ struct SCurrentRenderData { float savedProjection[9]; SMonitorRenderData* pCurrentMonData = nullptr; + CFramebuffer* currentFB = nullptr; CRegion damage; @@ -142,6 +145,10 @@ class CHyprOpenGLImpl { void applyScreenShader(const std::string& path); + void bindOffMain(); + void renderOffToMain(CFramebuffer* off); + void bindBackOnMain(); + SCurrentRenderData m_RenderData; GLint m_iCurrentOutputFb = 0; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index c153b855..255bdf33 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -406,6 +406,12 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* // render window decorations first, if not fullscreen full if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) { + + const bool TRANSFORMERSPRESENT = !pWindow->m_vTransformers.empty(); + + if (TRANSFORMERSPRESENT) + g_pHyprOpenGL->bindOffMain(); + if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations) wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, offset); @@ -443,6 +449,17 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec* g_pHyprOpenGL->renderBorder(&windowBox, g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColorPrevious, renderdata.rounding, borderSize, a2); } } + + if (TRANSFORMERSPRESENT) { + + CFramebuffer* last = g_pHyprOpenGL->m_RenderData.currentFB; + for (auto& t : pWindow->m_vTransformers) { + last = t->transform(last); + } + + g_pHyprOpenGL->bindBackOnMain(); + g_pHyprOpenGL->renderOffToMain(last); + } } if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) { diff --git a/src/render/Transformer.cpp b/src/render/Transformer.cpp new file mode 100644 index 00000000..f99e2d98 --- /dev/null +++ b/src/render/Transformer.cpp @@ -0,0 +1 @@ +#include "Transformer.hpp"
\ No newline at end of file diff --git a/src/render/Transformer.hpp b/src/render/Transformer.hpp new file mode 100644 index 00000000..62eb3362 --- /dev/null +++ b/src/render/Transformer.hpp @@ -0,0 +1,13 @@ +#pragma once + +#include "Framebuffer.hpp" + +// A window transformer can be attached to a window. +// If any is attached, Hyprland will render the window to a separate fb, then call the transform() func with it, +// and finally render it back to the main fb after all transformers pass. +class IWindowTransformer { + public: + // called by Hyprland. For more data about what is being rendered, inspect render data. + // returns the out fb. + virtual CFramebuffer* transform(CFramebuffer* in) = 0; +};
\ No newline at end of file |
