diff options
| author | Darksome <dev@darkso.me> | 2022-07-15 19:42:03 +0300 |
|---|---|---|
| committer | Darksome <dev@darkso.me> | 2022-07-15 19:42:03 +0300 |
| commit | 5388b54442614cb0d3d445f101e7cd86bf64c125 (patch) | |
| tree | 26057ff185e423e944e8b250ed7fe26654b69623 /src/render | |
| parent | cb8a6f881b11e9a269fd5f7aa64eafe2beda0b0d (diff) | |
| parent | 6306d4dae3fa221a6099e109c7faef60bac4fac5 (diff) | |
Merge upstream
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/Framebuffer.cpp | 18 | ||||
| -rw-r--r-- | src/render/Framebuffer.hpp | 2 | ||||
| -rw-r--r-- | src/render/OpenGL.cpp | 55 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 11 | ||||
| -rw-r--r-- | src/render/Renderer.cpp | 135 | ||||
| -rw-r--r-- | src/render/Renderer.hpp | 8 | ||||
| -rw-r--r-- | src/render/decorations/CHyprGroupBarDecoration.cpp | 16 |
7 files changed, 163 insertions, 82 deletions
diff --git a/src/render/Framebuffer.cpp b/src/render/Framebuffer.cpp index 4a5baf50..90b41a4b 100644 --- a/src/render/Framebuffer.cpp +++ b/src/render/Framebuffer.cpp @@ -2,15 +2,14 @@ #include "OpenGL.hpp" bool CFramebuffer::alloc(int w, int h) { - bool firstAlloc = false; - if (m_iFb == (uint32_t)-1) - { + bool firstAlloc = false; + + if (m_iFb == (uint32_t)-1) { firstAlloc = true; glGenFramebuffers(1, &m_iFb); } - if (m_cTex.m_iTexID == 0) - { + if (m_cTex.m_iTexID == 0) { firstAlloc = true; glGenTextures(1, &m_cTex.m_iTexID); glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID); @@ -20,13 +19,11 @@ bool CFramebuffer::alloc(int w, int h) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - if (firstAlloc || m_Size != Vector2D(w, h)) - { + if (firstAlloc || m_Size != Vector2D(w, h)) { glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glBindFramebuffer(GL_FRAMEBUFFER, m_iFb); - glBindTexture(GL_TEXTURE_2D, m_cTex.m_iTexID); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_cTex.m_iTexID, 0); @@ -37,7 +34,6 @@ bool CFramebuffer::alloc(int w, int h) { glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, 0); glBindFramebuffer(GL_FRAMEBUFFER, m_iFb); - glBindTexture(GL_TEXTURE_2D, m_pStencilTex->m_iTexID); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_pStencilTex->m_iTexID, 0); } @@ -78,3 +74,7 @@ void CFramebuffer::release() { m_cTex.m_iTexID = 0; m_iFb = -1; } + +CFramebuffer::~CFramebuffer() { + release(); +}
\ No newline at end of file diff --git a/src/render/Framebuffer.hpp b/src/render/Framebuffer.hpp index 3d15069d..6af59ca2 100644 --- a/src/render/Framebuffer.hpp +++ b/src/render/Framebuffer.hpp @@ -6,6 +6,8 @@ class CFramebuffer { public: + ~CFramebuffer(); + bool alloc(int w, int h); void bind(); void release(); diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 793901aa..d60e827e 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -311,21 +311,21 @@ void CHyprOpenGLImpl::renderRectWithDamage(wlr_box* box, const CColor& col, pixm glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } -void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round) { +void CHyprOpenGLImpl::renderTexture(wlr_texture* tex, wlr_box* pBox, float alpha, int round, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTexture(CTexture(tex), pBox, alpha, round); + renderTexture(CTexture(tex), pBox, alpha, round, false, allowCustomUV); } -void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowPrimary) { +void CHyprOpenGLImpl::renderTexture(const CTexture& tex, wlr_box* pBox, float alpha, int round, bool discardopaque, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); - renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowPrimary); + renderTextureInternalWithDamage(tex, pBox, alpha, m_RenderData.pDamage, round, discardopaque, false, allowCustomUV); scissor((wlr_box*)nullptr); } -void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowPrimary) { +void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_box* pBox, float alpha, pixman_region32_t* damage, int round, bool discardOpaque, bool noAA, bool allowCustomUV) { RASSERT(m_RenderData.pMonitor, "Tried to render texture without begin()!"); RASSERT((tex.m_iTexID > 0), "Attempted to draw NULL texture!"); @@ -388,7 +388,7 @@ void CHyprOpenGLImpl::renderTextureInternalWithDamage(const CTexture& tex, wlr_b glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts); - if (allowPrimary && m_RenderData.renderingPrimarySurface && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) { + if (allowCustomUV && m_RenderData.primarySurfaceUVTopLeft != Vector2D(-1, -1)) { const float verts[] = { m_RenderData.primarySurfaceUVBottomRight.x, m_RenderData.primarySurfaceUVTopLeft.y, // top right m_RenderData.primarySurfaceUVTopLeft.x, m_RenderData.primarySurfaceUVTopLeft.y, // top left @@ -702,8 +702,6 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { begin(PMONITOR, &fakeDamage, true); - pixman_region32_fini(&fakeDamage); - clear(CColor(0,0,0,0)); // JIC timespec now; @@ -717,7 +715,7 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { const auto BLURVAL = g_pConfigManager->getInt("decoration:blur"); g_pConfigManager->setInt("decoration:blur", 0); - g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders); + g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL); g_pConfigManager->setInt("decoration:blur", BLURVAL); @@ -742,9 +740,10 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { #else glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb); #endif - end(); + pixman_region32_fini(&fakeDamage); + wlr_output_rollback(PMONITOR->output); } @@ -762,8 +761,6 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) { begin(PMONITOR, &fakeDamage, true); - pixman_region32_fini(&fakeDamage); - const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer]; glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y); @@ -792,6 +789,8 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) { end(); + pixman_region32_fini(&fakeDamage); + wlr_output_rollback(PMONITOR->output); } @@ -915,9 +914,28 @@ void CHyprOpenGLImpl::renderRoundedShadow(wlr_box* box, int round, int range, fl glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); } +void CHyprOpenGLImpl::renderSplash(cairo_t *const CAIRO, cairo_surface_t *const CAIROSURFACE) { + cairo_select_font_face(CAIRO, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + + const auto FONTSIZE = (int)(m_RenderData.pMonitor->vecPixelSize.y / 76); + cairo_set_font_size(CAIRO, FONTSIZE); + + cairo_set_source_rgba(CAIRO, 1.f, 1.f, 1.f, 0.32f); + + cairo_text_extents_t textExtents; + cairo_text_extents(CAIRO, g_pCompositor->m_szCurrentSplash.c_str(), &textExtents); + + cairo_move_to(CAIRO, m_RenderData.pMonitor->vecPixelSize.x / 2.f - textExtents.width / 2.f, m_RenderData.pMonitor->vecPixelSize.y - textExtents.height - 1); + cairo_show_text(CAIRO, g_pCompositor->m_szCurrentSplash.c_str()); + + cairo_surface_flush(CAIROSURFACE); +} + void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) { RASSERT(m_RenderData.pMonitor, "Tried to createBGTex without begin()!"); + static auto *const PNOSPLASH = &g_pConfigManager->getConfigValuePtr("misc:disable_splash_rendering")->intValue; + // release the last tex if exists const auto PTEX = &m_mMonitorBGTextures[pMonitor]; PTEX->destroyTexture(); @@ -926,6 +944,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) { Debug::log(LOG, "Allocated texture for BGTex"); + // TODO: use relative paths to the installation + // or configure the paths at build time + // check if wallpapers exist if (!std::filesystem::exists("/usr/share/hyprland/wall_8K.png")) return; // the texture will be empty, oh well. We'll clear with a solid color anyways. @@ -949,6 +970,9 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) { const auto CAIRO = cairo_create(CAIROSURFACE); + if (!*PNOSPLASH) + renderSplash(CAIRO, CAIROSURFACE); + // copy the data to an OpenGL texture we have const auto DATA = cairo_image_surface_get_data(CAIROSURFACE); glBindTexture(GL_TEXTURE_2D, PTEX->m_iTexID); @@ -969,9 +993,12 @@ void CHyprOpenGLImpl::createBGTextureForMonitor(SMonitor* pMonitor) { void CHyprOpenGLImpl::clearWithTex() { RASSERT(m_RenderData.pMonitor, "Tried to render BGtex without begin()!"); - wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; + static auto *const PRENDERTEX = &g_pConfigManager->getConfigValuePtr("misc:disable_hyprland_logo")->intValue; - renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0); + if (!*PRENDERTEX) { + wlr_box box = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; + renderTexture(m_mMonitorBGTextures[m_RenderData.pMonitor], &box, 255, 0); + } } void CHyprOpenGLImpl::destroyMonitorResources(SMonitor* pMonitor) { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 292eba36..84cfcd39 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -6,6 +6,8 @@ #include <list> #include <unordered_map> +#include <cairo/cairo.h> + #include "Shaders.hpp" #include "Shader.hpp" #include "Texture.hpp" @@ -45,7 +47,6 @@ struct SCurrentRenderData { pixman_region32_t* pDamage = nullptr; - bool renderingPrimarySurface = false; Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1); Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); }; @@ -60,8 +61,8 @@ public: void renderRect(wlr_box*, const CColor&, int round = 0); void renderRectWithDamage(wlr_box*, const CColor&, pixman_region32_t* damage, int round = 0); - void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0); - void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowPrimary = false); + void renderTexture(wlr_texture*, wlr_box*, float a, int round = 0, bool allowCustomUV = false); + void renderTexture(const CTexture&, wlr_box*, float a, int round = 0, bool discardOpaque = false, bool allowCustomUV = false); void renderTextureWithBlur(const CTexture&, wlr_box*, float a, wlr_surface* pSurface, int round = 0); void renderRoundedShadow(wlr_box*, int round, int range, float a = 1.0); void renderBorder(wlr_box*, const CColor&, int round); @@ -121,7 +122,9 @@ private: // returns the out FB, can be either Mirror or MirrorSwap CFramebuffer* blurMainFramebufferWithDamage(float a, wlr_box* pBox, pixman_region32_t* damage); - void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowPrimary = false); + void renderTextureInternalWithDamage(const CTexture&, wlr_box* pBox, float a, pixman_region32_t* damage, int round = 0, bool discardOpaque = false, bool noAA = false, bool allowCustomUV = false); + + void renderSplash(cairo_t *const, cairo_surface_t *const); }; inline std::unique_ptr<CHyprOpenGLImpl> g_pHyprOpenGL;
\ No newline at end of file diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index eaa3cd90..d2b5efa9 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -12,22 +12,30 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { wlr_output_layout_output_coords(g_pCompositor->m_sWLROutputLayout, RDATA->output, &outputX, &outputY); wlr_box windowBox; - if (RDATA->surface && surface == RDATA->surface) { + if (RDATA->surface && surface == RDATA->surface) windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, RDATA->w, RDATA->h}; - } else { // here we clamp to 2, these might be some tiny specks + else // here we clamp to 2, these might be some tiny specks windowBox = {(int)outputX + RDATA->x + x, (int)outputY + RDATA->y + y, std::clamp(surface->current.width, 2, 1337420), std::clamp(surface->current.height, 2, 1337420)}; + + // squish all oversized + if (RDATA->squishOversized) { + if (x + windowBox.width > RDATA->w) + windowBox.width = RDATA->w - x; + if (y + windowBox.height > RDATA->h) + windowBox.height = RDATA->h - y; } + scaleBox(&windowBox, RDATA->output->scale); static auto *const PROUNDING = &g_pConfigManager->getConfigValuePtr("decoration:rounding")->intValue; float rounding = RDATA->dontRound ? 0 : RDATA->rounding == -1 ? *PROUNDING : RDATA->rounding; - g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = false; - if (RDATA->surface && surface == RDATA->surface) { - g_pHyprOpenGL->m_RenderData.renderingPrimarySurface = true; - g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding); + if (RDATA->blur) + g_pHyprOpenGL->renderTextureWithBlur(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, surface, rounding); + else + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, true); if (RDATA->decorate) { auto col = g_pHyprOpenGL->m_pCurrentWindow->m_cRealBorderColor.col(); @@ -35,8 +43,18 @@ void renderSurface(struct wlr_surface* surface, int x, int y, void* data) { g_pHyprOpenGL->renderBorder(&windowBox, col, rounding); } } - else - g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false, false); + else { + if (RDATA->surface && wlr_surface_is_xdg_surface(RDATA->surface)) { + wlr_box geo; + wlr_xdg_surface_get_geometry(wlr_xdg_surface_from_wlr_surface(RDATA->surface), &geo); + + windowBox.x -= geo.x; + windowBox.y -= geo.y; + } + + g_pHyprOpenGL->renderTexture(TEXTURE, &windowBox, RDATA->fadeAlpha * RDATA->alpha, rounding, false); + } + wlr_surface_send_frame_done(surface, RDATA->when); @@ -54,8 +72,8 @@ bool CHyprRenderer::shouldRenderWindow(CWindow* pWindow, SMonitor* pMonitor) { return true; const auto PWORKSPACE = g_pCompositor->getWorkspaceByID(pWindow->m_iWorkspaceID); - // if not, check if it maybe is active on a different monitor. vvv might be animation in progress - if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()))) + // if not, check if it maybe is active on a different monitor. vvv might be animation in progress + if (g_pCompositor->isWorkspaceVisible(pWindow->m_iWorkspaceID) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && PWORKSPACE->m_bForceRendering) || (PWORKSPACE && PWORKSPACE->m_iMonitorID == pMonitor->ID && (PWORKSPACE->m_vRenderOffset.isBeingAnimated() || PWORKSPACE->m_fAlpha.isBeingAnimated()))) return true; if (pMonitor->specialWorkspaceOpen && pWindow->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) @@ -93,7 +111,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor continue; // found it! - renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL); + renderWindow(w.get(), pMonitor, time, pWorkspace->m_efFullscreenMode != FULLSCREEN_FULL, RENDER_PASS_ALL); pWorkspaceWindow = w.get(); } @@ -103,7 +121,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor if (w->m_iWorkspaceID != pWorkspaceWindow->m_iWorkspaceID || !w->m_bCreatedOverFullscreen || !w->m_bIsMapped) continue; - renderWindow(w.get(), pMonitor, time, true); + renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL); } // and then special windows @@ -118,7 +136,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor continue; // render the bad boy - renderWindow(w.get(), pMonitor, time, true); + renderWindow(w.get(), pMonitor, time, true, RENDER_PASS_ALL); } // and the overlay layers @@ -140,7 +158,7 @@ void CHyprRenderer::renderWorkspaceWithFullscreenWindow(SMonitor* pMonitor, CWor g_pHyprError->draw(); } -void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate) { +void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* time, bool decorate, eRenderPassMode mode) { if (pWindow->m_bHidden) return; @@ -160,9 +178,11 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* renderdata.h = std::clamp(pWindow->m_vRealSize.vec().y, (double)5, (double)1337420); // otherwise we'll have issues later with invalid boxes renderdata.dontRound = pWindow->m_bIsFullscreen && PWORKSPACE->m_efFullscreenMode == FULLSCREEN_FULL; renderdata.fadeAlpha = pWindow->m_fAlpha.fl() * (PWORKSPACE->m_fAlpha.fl() / 255.f); - renderdata.alpha = pWindow->m_bIsFullscreen ? g_pConfigManager->getFloat("decoration:fullscreen_opacity") : pWindow == g_pCompositor->m_pLastWindow ? g_pConfigManager->getFloat("decoration:active_opacity") : g_pConfigManager->getFloat("decoration:inactive_opacity"); + renderdata.alpha = pWindow->m_fActiveInactiveAlpha.fl(); renderdata.decorate = decorate && !pWindow->m_bX11DoesntWantBorders && (pWindow->m_bIsFloating ? *PNOFLOATINGBORDERS == 0 : true) && (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL); renderdata.rounding = pWindow->m_sAdditionalConfigData.rounding; + renderdata.blur = true; // if it shouldn't, it will be ignored later + renderdata.squishOversized = pWindow->m_vRealPosition.isBeingAnimated(); // apply window special data if (pWindow->m_sSpecialRenderData.alphaInactive == -1) @@ -173,37 +193,40 @@ void CHyprRenderer::renderWindow(CWindow* pWindow, SMonitor* pMonitor, timespec* g_pHyprOpenGL->m_pCurrentWindow = pWindow; // render window decorations first, if not fullscreen full - if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations) - wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f); - - if (!pWindow->m_bIsX11) { - // To everyone who makes apps with improperly aligned surfaces, - // For example chromium, or GTK devs who allow shadows on windows, - // a sincere FUCK YOU. + if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_MAIN) { + if (!pWindow->m_bIsFullscreen || PWORKSPACE->m_efFullscreenMode != FULLSCREEN_FULL) for (auto& wd : pWindow->m_dWindowDecorations) + wd->draw(pMonitor, renderdata.alpha * renderdata.fadeAlpha / 255.f); - wlr_box geom; - wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom); + if (!pWindow->m_bIsX11) { + wlr_box geom; + wlr_xdg_surface_get_geometry(pWindow->m_uSurface.xdg, &geom); - g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height); - g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height); + g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D((double)geom.x / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)geom.y / (double)pWindow->m_uSurface.xdg->surface->current.height); + g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D((double)(geom.width + geom.x) / (double)pWindow->m_uSurface.xdg->surface->current.width, (double)(geom.y + geom.height) / (double)pWindow->m_uSurface.xdg->surface->current.height); - if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) { - // No special UV mods needed + if (g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft == Vector2D() && g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight == Vector2D(1, 1)) { + // No special UV mods needed + g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); + g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); + } + } else { g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); } - } - wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata); + wlr_surface_for_each_surface(g_pXWaylandManager->getWindowSurface(pWindow), renderSurface, &renderdata); - g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); - g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); + g_pHyprOpenGL->m_RenderData.primarySurfaceUVTopLeft = Vector2D(-1, -1); + g_pHyprOpenGL->m_RenderData.primarySurfaceUVBottomRight = Vector2D(-1, -1); + } - if (!pWindow->m_bIsX11) { - renderdata.dontRound = false; // restore dontround - renderdata.pMonitor = pMonitor; - wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata); + if (mode == RENDER_PASS_ALL || mode == RENDER_PASS_POPUP) { + if (!pWindow->m_bIsX11) { + renderdata.dontRound = false; // restore dontround + renderdata.pMonitor = pMonitor; + wlr_xdg_surface_for_each_popup_surface(pWindow->m_uSurface.xdg, renderSurface, &renderdata); + } } g_pHyprOpenGL->m_pCurrentWindow = nullptr; @@ -217,6 +240,11 @@ void CHyprRenderer::renderLayer(SLayerSurface* pLayer, SMonitor* pMonitor, times SRenderData renderdata = {pMonitor->output, time, pLayer->geometry.x, pLayer->geometry.y}; renderdata.fadeAlpha = pLayer->alpha.fl(); + renderdata.blur = pLayer->forceBlur; + renderdata.surface = pLayer->layerSurface->surface; + renderdata.decorate = false; + renderdata.w = pLayer->layerSurface->surface->current.width; + renderdata.h = pLayer->layerSurface->surface->current.height; wlr_surface_for_each_surface(pLayer->layerSurface->surface, renderSurface, &renderdata); } @@ -243,7 +271,25 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { return; } - // Non-floating + // Non-floating main + for (auto& w : g_pCompositor->m_vWindows) { + if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut) + continue; + + if (w->m_bIsFloating) + continue; // floating are in the second pass + + if (w->m_iWorkspaceID == SPECIAL_WORKSPACE_ID) + continue; // special are in the third pass + + if (!shouldRenderWindow(w.get(), PMONITOR)) + continue; + + // render the bad boy + renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_MAIN); + } + + // Non-floating popup for (auto& w : g_pCompositor->m_vWindows) { if (w->m_bHidden && !w->m_bIsMapped && !w->m_bFadingOut) continue; @@ -258,7 +304,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { continue; // render the bad boy - renderWindow(w.get(), PMONITOR, time, true); + renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_POPUP); } // floating on top @@ -276,7 +322,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { continue; // render the bad boy - renderWindow(w.get(), PMONITOR, time, true); + renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL); } // and then special @@ -291,7 +337,7 @@ void CHyprRenderer::renderAllClientsForMonitor(const int& ID, timespec* time) { continue; // render the bad boy - renderWindow(w.get(), PMONITOR, time, true); + renderWindow(w.get(), PMONITOR, time, true, RENDER_PASS_ALL); } // Render surfaces above windows for monitor @@ -428,7 +474,7 @@ 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) + if (ls->fadingOut || ls->readyToDelete || !ls->layerSurface) continue; const auto PLAYER = ls->layerSurface; @@ -551,6 +597,11 @@ void CHyprRenderer::damageSurface(wlr_surface* pSurface, double x, double y) { pixman_region32_init(&damageBox); wlr_surface_get_effective_damage(pSurface, &damageBox); + // schedule frame events + if (!wl_list_empty(&pSurface->current.frame_callback_list)) { + g_pCompositor->scheduleFrameForMonitor(g_pCompositor->getMonitorFromVector(Vector2D(x, y))); + } + if (!pixman_region32_not_empty(&damageBox)) { pixman_region32_fini(&damageBox); return; @@ -799,4 +850,4 @@ void CHyprRenderer::ensureCursorRenderingMode() { bool CHyprRenderer::shouldRenderCursor() { return m_bHasARenderedCursor; -}
\ No newline at end of file +} diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index ff9fd4ea..c03c7117 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -17,6 +17,12 @@ enum DAMAGETRACKINGMODES { DAMAGE_TRACKING_FULL }; +enum eRenderPassMode { + RENDER_PASS_ALL = 0, + RENDER_PASS_MAIN, + RENDER_PASS_POPUP +}; + class CHyprRenderer { public: @@ -41,7 +47,7 @@ public: private: void arrangeLayerArray(SMonitor*, const std::list<SLayerSurface*>&, bool, wlr_box*); void renderWorkspaceWithFullscreenWindow(SMonitor*, CWorkspace*, timespec*); - void renderWindow(CWindow*, SMonitor*, timespec*, bool); + void renderWindow(CWindow*, SMonitor*, timespec*, bool, eRenderPassMode); void renderLayer(SLayerSurface*, SMonitor*, timespec*); void renderDragIcon(SMonitor*, timespec*); diff --git a/src/render/decorations/CHyprGroupBarDecoration.cpp b/src/render/decorations/CHyprGroupBarDecoration.cpp index abb5d90c..2d46d7a0 100644 --- a/src/render/decorations/CHyprGroupBarDecoration.cpp +++ b/src/render/decorations/CHyprGroupBarDecoration.cpp @@ -40,12 +40,8 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) { if (g_pLayoutManager->getCurrentLayout()->getLayoutName() != "dwindle") { // ???? - for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) { - if (it->get() == this) { - pWindow->m_dWindowDecorations.erase(it); - return; - } - } + m_pWindow->m_vDecosToRemove.push_back(this); + return; } // get the group info @@ -58,12 +54,8 @@ void CHyprGroupBarDecoration::updateWindow(CWindow* pWindow) { if (m_dwGroupMembers.size() == 0) { // remove - for (auto it = pWindow->m_dWindowDecorations.begin(); it != pWindow->m_dWindowDecorations.end(); it++) { - if (it->get() == this) { - pWindow->m_dWindowDecorations.erase(it); - return; - } - } + m_pWindow->m_vDecosToRemove.push_back(this); + return; } } |
