mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-29 23:25:58 +01:00
renderer: add transformers
This commit is contained in:
parent
af72404259
commit
92311d260a
6 changed files with 64 additions and 0 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
1
src/render/Transformer.cpp
Normal file
1
src/render/Transformer.cpp
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include "Transformer.hpp"
|
13
src/render/Transformer.hpp
Normal file
13
src/render/Transformer.hpp
Normal 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;
|
||||||
|
};
|
Loading…
Reference in a new issue