summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2023-10-21 14:15:48 +0100
committerVaxry <vaxry@vaxry.net>2023-10-21 14:15:56 +0100
commit92311d260ab25c11adab05678663bdccaff11fa6 (patch)
treed632d8998a979cb8582eede8dcb0d6f6002f19bd /src/render
parentaf72404259f7a39069d1449bedbc49b3e6ae4fbc (diff)
renderer: add transformers
Diffstat (limited to 'src/render')
-rw-r--r--src/render/OpenGL.cpp21
-rw-r--r--src/render/OpenGL.hpp7
-rw-r--r--src/render/Renderer.cpp17
-rw-r--r--src/render/Transformer.cpp1
-rw-r--r--src/render/Transformer.hpp13
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