summaryrefslogtreecommitdiff
path: root/src/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/render')
-rw-r--r--src/render/OpenGL.cpp73
-rw-r--r--src/render/OpenGL.hpp3
-rw-r--r--src/render/Renderer.cpp26
-rw-r--r--src/render/Renderer.hpp1
4 files changed, 94 insertions, 9 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp
index 80478de0..1711d08e 100644
--- a/src/render/OpenGL.cpp
+++ b/src/render/OpenGL.cpp
@@ -698,12 +698,57 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) {
wlr_output_rollback(PMONITOR->output);
}
+void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) {
+ // we trust the window is valid.
+ const auto PMONITOR = g_pCompositor->getMonitorFromID(pLayer->monitorID);
+ wlr_output_attach_render(PMONITOR->output, nullptr);
+
+ // we need to "damage" the entire monitor
+ // so that we render the entire window
+ // this is temporary, doesnt mess with the actual wlr damage
+ pixman_region32_t fakeDamage;
+ pixman_region32_init(&fakeDamage);
+ pixman_region32_union_rect(&fakeDamage, &fakeDamage, 0, 0, (int)PMONITOR->vecSize.x, (int)PMONITOR->vecSize.y);
+
+ begin(PMONITOR, &fakeDamage);
+
+ pixman_region32_fini(&fakeDamage);
+
+ const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer];
+
+ PFRAMEBUFFER->m_tTransform = pLayer->layerSurface->surface->current.transform;
+
+ PFRAMEBUFFER->alloc(PMONITOR->vecSize.x, PMONITOR->vecSize.y);
+
+ PFRAMEBUFFER->bind();
+
+ clear(CColor(0, 0, 0, 0)); // JIC
+
+ timespec now;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+
+ // draw the layer
+ g_pHyprRenderer->renderLayer(pLayer, PMONITOR, &now);
+
+// restore original fb
+#ifndef GLES2
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iCurrentOutputFb);
+#else
+ glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb);
+#endif
+ glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecSize.y);
+
+ end();
+
+ wlr_output_rollback(PMONITOR->output);
+}
+
void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!");
const auto PWINDOW = *pWindow;
auto it = m_mWindowFramebuffers.begin();
- for (;it != m_mWindowFramebuffers.end(); it++) {
+ for (; it != m_mWindowFramebuffers.end(); it++) {
if (it->first == PWINDOW) {
break;
}
@@ -724,6 +769,32 @@ void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) {
pixman_region32_fini(&fakeDamage);
}
+void CHyprOpenGLImpl::renderSnapshot(SLayerSurface** pLayer) {
+ RASSERT(m_RenderData.pMonitor, "Tried to render snapshot rect without begin()!");
+ const auto PLAYER = *pLayer;
+
+ auto it = m_mLayerFramebuffers.begin();
+ for (; it != m_mLayerFramebuffers.end(); it++) {
+ if (it->first == PLAYER) {
+ break;
+ }
+ }
+
+ if (it == m_mLayerFramebuffers.end() || !it->second.m_cTex.m_iTexID)
+ return;
+
+ const auto PMONITOR = g_pCompositor->getMonitorFromID(PLAYER->monitorID);
+
+ wlr_box windowBox = {0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y};
+
+ pixman_region32_t fakeDamage;
+ pixman_region32_init_rect(&fakeDamage, 0, 0, PMONITOR->vecSize.x, PMONITOR->vecSize.y);
+
+ renderTextureInternalWithDamage(it->second.m_cTex, &windowBox, PLAYER->alpha.fl(), &fakeDamage, 0);
+
+ pixman_region32_fini(&fakeDamage);
+}
+
void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) {
RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!");
diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp
index 99de2a29..34b1a871 100644
--- a/src/render/OpenGL.hpp
+++ b/src/render/OpenGL.hpp
@@ -60,7 +60,9 @@ public:
void renderBorder(wlr_box*, const CColor&, int thick = 1, int round = 0);
void makeWindowSnapshot(CWindow*);
+ void makeLayerSnapshot(SLayerSurface*);
void renderSnapshot(CWindow**);
+ void renderSnapshot(SLayerSurface**);
void clear(const CColor&);
void clearWithTex();
@@ -78,6 +80,7 @@ public:
pixman_region32_t m_rOriginalDamageRegion; // used for storing the pre-expanded region
std::unordered_map<CWindow*, CFramebuffer> m_mWindowFramebuffers;
+ std::unordered_map<SLayerSurface*, CFramebuffer> m_mLayerFramebuffers;
std::unordered_map<SMonitor*, SMonitorRenderData> m_mMonitorRenderResources;
std::unordered_map<SMonitor*, CTexture> m_mMonitorBGTextures;
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index be51336c..9509b30d 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -121,6 +121,17 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec*
}
}
+void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, timespec* time) {
+ if (pLayer->fadingOut) {
+ g_pHyprOpenGL->renderSnapshot(&pLayer);
+ return;
+ }
+
+ SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y};
+ renderdata.fadeAlpha = pLayer->alpha.fl();
+ wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata);
+}
+
void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
const auto PMONITOR = g_pCompositor->getMonitorFromID(ID);
@@ -129,12 +140,10 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
// Render layer surfaces below windows for monitor
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND]) {
- SRenderData renderdata = {PMONITOR->output, time, ls->geometry.x, ls->geometry.y};
- wlr_surface_for_each_surface(ls->layerSurface->surface, renderSurface, &renderdata);
+ renderLayer(ls, PMONITOR, time);
}
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM]) {
- SRenderData renderdata = {PMONITOR->output, time, ls->geometry.x, ls->geometry.y};
- wlr_surface_for_each_surface(ls->layerSurface->surface, renderSurface, &renderdata);
+ renderLayer(ls, PMONITOR, time);
}
// if there is a fullscreen window, render it and then do not render anymore.
@@ -178,12 +187,10 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) {
// Render surfaces above windows for monitor
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_TOP]) {
- SRenderData renderdata = {PMONITOR->output, time, ls->geometry.x, ls->geometry.y};
- wlr_surface_for_each_surface(ls->layerSurface->surface, renderSurface, &renderdata);
+ renderLayer(ls, PMONITOR, time);
}
for (auto& ls : PMONITOR->m_aLayerSurfaceLists[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY]) {
- SRenderData renderdata = {PMONITOR->output, time, ls->geometry.x, ls->geometry.y};
- wlr_surface_for_each_surface(ls->layerSurface->surface, renderSurface, &renderdata);
+ renderLayer(ls, PMONITOR, time);
}
renderDragIcon(PMONITOR, time);
@@ -316,6 +323,9 @@ void CHyprRenderer::arrangeLayerArray(SMonitor* pMonitor, const std::list<SLayer
wlr_box full_area = {pMonitor->vecPosition.x, pMonitor->vecPosition.y, pMonitor->vecSize.x, pMonitor->vecSize.y};
for (auto& ls : layerSurfaces) {
+ if (ls->fadingOut)
+ continue;
+
const auto PLAYER = ls->layerSurface;
const auto PSTATE = &PLAYER->current;
if (exclusiveZone != (PSTATE->exclusive_zone > 0)) {
diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp
index b445c176..f879702b 100644
--- a/src/render/Renderer.hpp
+++ b/src/render/Renderer.hpp
@@ -37,6 +37,7 @@ private:
void drawBorderForWindow(CWindow*, SMonitor*, float a = 255.f, const Vector2D& offset = Vector2D(0,0));
void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*);
void renderWindow(CWindow*, SMonitor*, timespec*, bool);
+ void renderLayer(SLayerSurface*, SMonitor*, timespec*);
void renderDragIcon(SMonitor*, timespec*);