renderer: add transformers

This commit is contained in:
Vaxry 2023-10-21 14:15:48 +01:00
parent af72404259
commit 92311d260a
6 changed files with 64 additions and 0 deletions

View file

@ -32,6 +32,8 @@ enum eGroupRules
GROUP_OVERRIDE = 1 << 6, // Override other rules GROUP_OVERRIDE = 1 << 6, // Override other rules
}; };
class IWindowTransformer;
template <typename T> template <typename T>
class CWindowOverridableVar { class CWindowOverridableVar {
public: public:
@ -290,6 +292,9 @@ class CWindow {
SWindowSpecialRenderData m_sSpecialRenderData; SWindowSpecialRenderData m_sSpecialRenderData;
SWindowAdditionalConfigData m_sAdditionalConfigData; SWindowAdditionalConfigData m_sAdditionalConfigData;
// Transformers
std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers;
// for alpha // for alpha
CAnimatedVariable m_fActiveInactiveAlpha; CAnimatedVariable m_fActiveInactiveAlpha;

View file

@ -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->primaryFB.m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex;
m_RenderData.pCurrentMonData->mirrorFB.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->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->primaryFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
m_RenderData.pCurrentMonData->mirrorFB.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->mirrorSwapFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
m_RenderData.pCurrentMonData->offMainFB.alloc(pMonitor->vecPixelSize.x, pMonitor->vecPixelSize.y);
createBGTextureForMonitor(pMonitor); createBGTextureForMonitor(pMonitor);
} }
@ -149,6 +151,8 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) {
m_bFakeFrame = fake; m_bFakeFrame = fake;
m_RenderData.currentFB = &m_RenderData.pCurrentMonData->primaryFB;
if (m_bReloadScreenShader) { if (m_bReloadScreenShader) {
m_bReloadScreenShader = false; m_bReloadScreenShader = false;
applyScreenShader(g_pConfigManager->getString("decoration:screen_shader")); 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].mirrorSwapFB.release();
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].monitorMirrorFB.release(); g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].monitorMirrorFB.release();
g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].blurFB.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_mMonitorRenderResources[pMonitor].stencilTex.destroyTexture();
g_pHyprOpenGL->m_mMonitorBGTextures[pMonitor].destroyTexture(); g_pHyprOpenGL->m_mMonitorBGTextures[pMonitor].destroyTexture();
g_pHyprOpenGL->m_mMonitorRenderResources.erase(pMonitor); g_pHyprOpenGL->m_mMonitorRenderResources.erase(pMonitor);
@ -1914,3 +1919,19 @@ void CHyprOpenGLImpl::setMatrixScaleTranslate(const Vector2D& translate, const f
void CHyprOpenGLImpl::restoreMatrix() { void CHyprOpenGLImpl::restoreMatrix() {
memcpy(m_RenderData.projection, m_RenderData.savedProjection, 9 * sizeof(float)); 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;
}

View file

@ -13,6 +13,7 @@
#include "Shader.hpp" #include "Shader.hpp"
#include "Texture.hpp" #include "Texture.hpp"
#include "Framebuffer.hpp" #include "Framebuffer.hpp"
#include "Transformer.hpp"
#include "../debug/TracyDefines.hpp" #include "../debug/TracyDefines.hpp"
@ -41,6 +42,7 @@ struct SMonitorRenderData {
CFramebuffer primaryFB; CFramebuffer primaryFB;
CFramebuffer mirrorFB; // these are used for some effects, CFramebuffer mirrorFB; // these are used for some effects,
CFramebuffer mirrorSwapFB; // etc CFramebuffer mirrorSwapFB; // etc
CFramebuffer offMainFB;
CFramebuffer monitorMirrorFB; // used for mirroring outputs CFramebuffer monitorMirrorFB; // used for mirroring outputs
@ -75,6 +77,7 @@ struct SCurrentRenderData {
float savedProjection[9]; float savedProjection[9];
SMonitorRenderData* pCurrentMonData = nullptr; SMonitorRenderData* pCurrentMonData = nullptr;
CFramebuffer* currentFB = nullptr;
CRegion damage; CRegion damage;
@ -142,6 +145,10 @@ class CHyprOpenGLImpl {
void applyScreenShader(const std::string& path); void applyScreenShader(const std::string& path);
void bindOffMain();
void renderOffToMain(CFramebuffer* off);
void bindBackOnMain();
SCurrentRenderData m_RenderData; SCurrentRenderData m_RenderData;
GLint m_iCurrentOutputFb = 0; GLint m_iCurrentOutputFb = 0;

View file

@ -406,6 +406,12 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, CMonitor* pMonitor, timespec*
// render window decorations first, if not fullscreen full // render window decorations first, if not fullscreen full
if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) { 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) if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL)
for (auto& wd : pWindow->m_dWindowDecorations) for (auto& wd : pWindow->m_dWindowDecorations)
wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha, offset); 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); 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) { if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) {

View file

@ -0,0 +1 @@
#include "Transformer.hpp"

View file

@ -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;
};