From 109136af97547f35f767dae2e7908ab218dfea11 Mon Sep 17 00:00:00 2001 From: vaxerski <43317083+vaxerski@users.noreply.github.com> Date: Sat, 14 May 2022 17:23:46 +0200 Subject: Fadein/out now applies to layersurfaces too --- src/render/OpenGL.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++- src/render/OpenGL.hpp | 3 ++ src/render/Renderer.cpp | 26 ++++++++++++------ src/render/Renderer.hpp | 1 + 4 files changed, 94 insertions(+), 9 deletions(-) (limited to 'src/render') 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 m_mWindowFramebuffers; + std::unordered_map m_mLayerFramebuffers; std::unordered_map m_mMonitorRenderResources; std::unordered_map 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::listvecPosition.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*); -- cgit v1.2.3