mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-26 04:45: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
|
||||
};
|
||||
|
||||
class IWindowTransformer;
|
||||
|
||||
template <typename T>
|
||||
class CWindowOverridableVar {
|
||||
public:
|
||||
|
@ -290,6 +292,9 @@ class CWindow {
|
|||
SWindowSpecialRenderData m_sSpecialRenderData;
|
||||
SWindowAdditionalConfigData m_sAdditionalConfigData;
|
||||
|
||||
// Transformers
|
||||
std::vector<std::unique_ptr<IWindowTransformer>> m_vTransformers;
|
||||
|
||||
// for alpha
|
||||
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->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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
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