diff options
| author | Narice <narice@tutanota.com> | 2022-05-16 11:53:28 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-16 11:53:28 +0100 |
| commit | 23c3534197f54e2f74b791ce2a8857b25bbba259 (patch) | |
| tree | c48e00553bb7027779b19e93a7f631a5f10eee98 /src/render | |
| parent | 4f10d8e07dd330bf1c4ce9eebecc0db919e522d9 (diff) | |
| parent | e991550abe8f4b13af586d635cdfec3b5c18fcd9 (diff) | |
Merge branch 'vaxerski:main' into main
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/OpenGL.cpp | 75 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 3 | ||||
| -rw-r--r-- | src/render/Renderer.cpp | 29 | ||||
| -rw-r--r-- | src/render/Renderer.hpp | 1 |
4 files changed, 96 insertions, 12 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 80478de0..59bea30d 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -377,7 +377,7 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, wlr_box* p pixman_region32_t damage; pixman_region32_init(&damage); pixman_region32_copy(&damage, originalDamage); - wlr_region_expand(&damage, &damage, BLURPASSES * BLURSIZE * 2); + wlr_region_expand(&damage, &damage, pow(2, BLURPASSES) * BLURSIZE); // helper const auto PMIRRORFB = &m_mMonitorRenderResources[m_RenderData.pMonitor].mirrorFB; @@ -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..22060e83 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -70,8 +70,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor // and the overlay layers 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); @@ -121,6 +120,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 +139,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 +186,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 +322,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 || ls->readyToDelete) + 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*); |
