diff --git a/src/Compositor.cpp b/src/Compositor.cpp index b0e1fcb3..5adfea86 100644 --- a/src/Compositor.cpp +++ b/src/Compositor.cpp @@ -190,7 +190,7 @@ void CCompositor::initServer() { m_sWLRGammaCtrlMgr = wlr_gamma_control_manager_v1_create(m_sWLDisplay); - m_sWLROutputLayout = wlr_output_layout_create(); + m_sWLROutputLayout = wlr_output_layout_create(m_sWLDisplay); m_sWLROutputPowerMgr = wlr_output_power_manager_v1_create(m_sWLDisplay); @@ -282,7 +282,7 @@ void CCompositor::initServer() { void CCompositor::initAllSignals() { addWLSignal(&m_sWLRBackend->events.new_output, &Events::listen_newOutput, m_sWLRBackend, "Backend"); - addWLSignal(&m_sWLRXDGShell->events.new_surface, &Events::listen_newXDGToplevel, m_sWLRXDGShell, "XDG Shell"); + addWLSignal(&m_sWLRXDGShell->events.new_toplevel, &Events::listen_newXDGToplevel, m_sWLRXDGShell, "XDG Shell"); addWLSignal(&m_sWLRCursor->events.motion, &Events::listen_mouseMove, m_sWLRCursor, "WLRCursor"); addWLSignal(&m_sWLRCursor->events.motion_absolute, &Events::listen_mouseMoveAbsolute, m_sWLRCursor, "WLRCursor"); addWLSignal(&m_sWLRCursor->events.button, &Events::listen_mouseButton, m_sWLRCursor, "WLRCursor"); diff --git a/src/events/Windows.cpp b/src/events/Windows.cpp index 556ec1b5..2ee70264 100644 --- a/src/events/Windows.cpp +++ b/src/events/Windows.cpp @@ -1171,12 +1171,10 @@ void Events::listener_surfaceXWayland(wl_listener* listener, void* data) { void Events::listener_newXDGToplevel(wl_listener* listener, void* data) { // A window got opened - const auto XDGSURFACE = (wlr_xdg_surface*)data; + const auto XDGTOPLEVEL = (wlr_xdg_toplevel*)data; + const auto XDGSURFACE = XDGTOPLEVEL->base; - if (XDGSURFACE->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) - return; - - Debug::log(LOG, "New XDG Surface created. (class: {})", XDGSURFACE->toplevel->app_id ? XDGSURFACE->toplevel->app_id : "null"); + Debug::log(LOG, "New XDG Toplevel created. (class: {})", XDGSURFACE->toplevel->app_id ? XDGSURFACE->toplevel->app_id : "null"); const auto PNEWWINDOW = g_pCompositor->m_vWindows.emplace_back(std::make_unique()).get(); PNEWWINDOW->m_uSurface.xdg = XDGSURFACE; diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index f0f0f69e..fdd89d30 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -424,23 +424,26 @@ void CScreencopyProtocolManager::sendFrameDamage(SScreencopyFrame* frame) { } bool CScreencopyProtocolManager::copyFrameShm(SScreencopyFrame* frame, timespec* now) { - void* data; - uint32_t format; - size_t stride; - if (!wlr_buffer_begin_data_ptr_access(frame->buffer, WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &data, &format, &stride)) - return false; + // void* data; + // uint32_t format; + // size_t stride; + // if (!wlr_buffer_begin_data_ptr_access(frame->buffer, WLR_BUFFER_DATA_PTR_ACCESS_WRITE, &data, &format, &stride)) + // return false; - if (!wlr_renderer_begin_with_buffer(g_pCompositor->m_sWLRRenderer, m_pLastMonitorBackBuffer)) { - Debug::log(ERR, "[sc] shm: Client requested a copy to a buffer that failed to pass wlr_renderer_begin_with_buffer"); - wlr_buffer_end_data_ptr_access(frame->buffer); - return false; - } + // if (!wlr_renderer_begin_with_buffer(g_pCompositor->m_sWLRRenderer, m_pLastMonitorBackBuffer)) { + // Debug::log(ERR, "[sc] shm: Client requested a copy to a buffer that failed to pass wlr_renderer_begin_with_buffer"); + // wlr_buffer_end_data_ptr_access(frame->buffer); + // return false; + // } - bool success = wlr_renderer_read_pixels(g_pCompositor->m_sWLRRenderer, format, stride, frame->box.width, frame->box.height, frame->box.x, frame->box.y, 0, 0, data); - wlr_renderer_end(g_pCompositor->m_sWLRRenderer); - wlr_buffer_end_data_ptr_access(frame->buffer); + // bool success = wlr_renderer_read_pixels(g_pCompositor->m_sWLRRenderer, format, stride, frame->box.width, frame->box.height, frame->box.x, frame->box.y, 0, 0, data); + // wlr_renderer_end(g_pCompositor->m_sWLRRenderer); + // wlr_buffer_end_data_ptr_access(frame->buffer); - return success; + // return success; + + return false; // TODO: maybe fix this with the new rendering pipeline? + // though who tf isnt using dmabuf? } bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) { diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index abb4a7d2..59836524 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -123,6 +123,12 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { static auto* const POPTIM = &g_pConfigManager->getConfigValuePtr("decoration:blur:new_optimizations")->intValue; static auto* const PBLURSPECIAL = &g_pConfigManager->getConfigValuePtr("decoration:blur:special")->intValue; + if (m_RenderData.mouseZoomFactor != 1.0) + return true; + + if (!pMonitor->mirrors.empty()) + return true; + if (*PBLUR == 0) return false; @@ -178,7 +184,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { return false; } -void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) { +void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, CFramebuffer* fb) { m_RenderData.pMonitor = pMonitor; TRACY_GPU_ZONE("RenderBegin"); @@ -214,35 +220,36 @@ void CHyprOpenGLImpl::begin(CMonitor* pMonitor, CRegion* pDamage, bool fake) { m_RenderData.damage.set(*pDamage); - m_bFakeFrame = fake; + m_bFakeFrame = fb; if (m_bReloadScreenShader) { m_bReloadScreenShader = false; applyScreenShader(g_pConfigManager->getString("decoration:screen_shader")); } - const auto PRBO = g_pHyprRenderer->getCurrentRBO(); + const auto PRBO = g_pHyprRenderer->getCurrentRBO(); + const bool FBPROPERSIZE = fb && fb->m_vSize == pMonitor->vecPixelSize; - if (m_sFinalScreenShader.program > 0 || m_bFakeFrame || m_RenderData.mouseZoomFactor != 1.0 || pMonitor->vecPixelSize != PRBO->getFB()->m_vSize || !pMonitor->mirrors.empty() || - passRequiresIntrospection(pMonitor)) { + if (!FBPROPERSIZE || m_sFinalScreenShader.program > 0 || (PRBO && pMonitor->vecPixelSize != PRBO->getFB()->m_vSize) || passRequiresIntrospection(pMonitor)) { // we have to offload - // bind the primary Hypr Framebuffer + // bind the offload Hypr Framebuffer m_RenderData.pCurrentMonData->offloadFB.bind(); m_RenderData.currentFB = &m_RenderData.pCurrentMonData->offloadFB; m_bOffloadedFramebuffer = true; } else { - // we can render to the rbo directly - const auto PFBO = PRBO->getFB(); + // we can render to the rbo / fbo (fake) directly + const auto PFBO = fb ? fb : PRBO->getFB(); m_RenderData.currentFB = PFBO; if (PFBO->m_pStencilTex != &m_RenderData.pCurrentMonData->stencilTex) { PFBO->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; PFBO->addStencil(); } - PRBO->bindFB(); + PFBO->bind(); m_bOffloadedFramebuffer = false; } m_RenderData.mainFB = m_RenderData.currentFB; + m_RenderData.outFB = fb ? fb : PRBO->getFB(); } void CHyprOpenGLImpl::end() { @@ -254,10 +261,10 @@ void CHyprOpenGLImpl::end() { saveBufferForMirror(); // save with original damage region // end the render, copy the data to the WLR framebuffer - if (m_bOffloadedFramebuffer && !m_bFakeFrame) { + if (m_bOffloadedFramebuffer) { m_RenderData.damage = m_RenderData.pMonitor->lastFrameDamage; - g_pHyprRenderer->getCurrentRBO()->bindFB(); + m_RenderData.outFB->bind(); CBox monbox = {0, 0, m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y}; @@ -1559,14 +1566,18 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) return; - 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 CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; - begin(PMONITOR, &fakeDamage, true); + g_pHyprRenderer->makeEGLCurrent(); + + pFramebuffer->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; + + pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat); + + g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, pFramebuffer); clear(CColor(0, 0, 0, 0)); // JIC @@ -1584,12 +1595,6 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra // TODO: how can we make this the size of the window? setting it to window's size makes the entire screen render with the wrong res forever more. odd. glViewport(0, 0, PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y); - pFramebuffer->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; - - pFramebuffer->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat); - - pFramebuffer->bind(); - m_RenderData.currentFB = pFramebuffer; clear(CColor(0, 0, 0, 0)); // JIC @@ -1598,15 +1603,7 @@ void CHyprOpenGLImpl::makeRawWindowSnapshot(CWindow* pWindow, CFramebuffer* pFra g_pConfigManager->setInt("decoration:blur:enabled", BLURVAL); -// restore original fb -#ifndef GLES2 - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iCurrentOutputFb); -#else - glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb); -#endif - end(); - - wlr_output_rollback(PMONITOR->output); + g_pHyprRenderer->endRender(); } void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { @@ -1619,14 +1616,18 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { if (!g_pHyprRenderer->shouldRenderWindow(pWindow)) return; // ignore, window is not being rendered - 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 CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; - begin(PMONITOR, &fakeDamage, true); + g_pHyprRenderer->makeEGLCurrent(); + + const auto PFRAMEBUFFER = &m_mWindowFramebuffers[pWindow]; + + PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat); + + g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER); g_pHyprRenderer->m_bRenderingSnapshot = true; @@ -1643,35 +1644,15 @@ void CHyprOpenGLImpl::makeWindowSnapshot(CWindow* pWindow) { const auto BLURVAL = g_pConfigManager->getInt("decoration:blur:enabled"); g_pConfigManager->setInt("decoration:blur:enabled", 0); - glViewport(0, 0, m_RenderData.pMonitor->vecPixelSize.x, m_RenderData.pMonitor->vecPixelSize.y); - - const auto PFRAMEBUFFER = &m_mWindowFramebuffers[pWindow]; - - PFRAMEBUFFER->m_pStencilTex = &m_RenderData.pCurrentMonData->stencilTex; - - PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat); - - PFRAMEBUFFER->bind(); - - m_RenderData.currentFB = PFRAMEBUFFER; - clear(CColor(0, 0, 0, 0)); // JIC g_pHyprRenderer->renderWindow(pWindow, PMONITOR, &now, !pWindow->m_bX11DoesntWantBorders, RENDER_PASS_ALL); g_pConfigManager->setInt("decoration:blur:enabled", BLURVAL); -// restore original fb -#ifndef GLES2 - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iCurrentOutputFb); -#else - glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb); -#endif - end(); + g_pHyprRenderer->endRender(); g_pHyprRenderer->m_bRenderingSnapshot = false; - - wlr_output_rollback(PMONITOR->output); } void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) { @@ -1681,26 +1662,18 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) { if (!PMONITOR || !PMONITOR->output || PMONITOR->vecPixelSize.x <= 0 || PMONITOR->vecPixelSize.y <= 0) return; - 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 - CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; - - begin(PMONITOR, &fakeDamage, true); - - g_pHyprRenderer->m_bRenderingSnapshot = true; + CRegion fakeDamage{0, 0, (int)PMONITOR->vecTransformedSize.x, (int)PMONITOR->vecTransformedSize.y}; const auto PFRAMEBUFFER = &m_mLayerFramebuffers[pLayer]; - glViewport(0, 0, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecPixelSize.y); - PFRAMEBUFFER->alloc(PMONITOR->vecPixelSize.x, PMONITOR->vecPixelSize.y, PMONITOR->drmFormat); - PFRAMEBUFFER->bind(); + g_pHyprRenderer->beginRender(PMONITOR, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, PFRAMEBUFFER); - m_RenderData.currentFB = PFRAMEBUFFER; + g_pHyprRenderer->m_bRenderingSnapshot = true; clear(CColor(0, 0, 0, 0)); // JIC @@ -1715,20 +1688,9 @@ void CHyprOpenGLImpl::makeLayerSnapshot(SLayerSurface* pLayer) { pLayer->forceBlur = BLURLSSTATUS; - // TODO: WARN: - // revise if any stencil-requiring rendering is done to the layers. - -// restore original fb -#ifndef GLES2 - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_iCurrentOutputFb); -#else - glBindFramebuffer(GL_FRAMEBUFFER, m_iCurrentOutputFb); -#endif - end(); + g_pHyprRenderer->endRender(); g_pHyprRenderer->m_bRenderingSnapshot = false; - - wlr_output_rollback(PMONITOR->output); } void CHyprOpenGLImpl::renderSnapshot(CWindow** pWindow) { @@ -2052,7 +2014,7 @@ void CHyprOpenGLImpl::clearWithTex() { } void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) { - wlr_output_attach_render(pMonitor->output, nullptr); + g_pHyprRenderer->makeEGLCurrent(); g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].mirrorFB.release(); g_pHyprOpenGL->m_mMonitorRenderResources[pMonitor].offloadFB.release(); @@ -2066,8 +2028,6 @@ void CHyprOpenGLImpl::destroyMonitorResources(CMonitor* pMonitor) { g_pHyprOpenGL->m_mMonitorBGTextures.erase(pMonitor); Debug::log(LOG, "Monitor {} -> destroyed all render data", pMonitor->szName); - - wlr_output_rollback(pMonitor->output); } void CHyprOpenGLImpl::saveMatrix() { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index ea2fe07e..f4661e1a 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -82,8 +82,9 @@ struct SCurrentRenderData { float savedProjection[9]; SMonitorRenderData* pCurrentMonData = nullptr; - CFramebuffer* currentFB = nullptr; - CFramebuffer* mainFB = nullptr; + CFramebuffer* currentFB = nullptr; // current rendering to + CFramebuffer* mainFB = nullptr; // main to render to + CFramebuffer* outFB = nullptr; // out to render to (if offloaded, etc) CRegion damage; @@ -107,7 +108,7 @@ class CHyprOpenGLImpl { public: CHyprOpenGLImpl(); - void begin(CMonitor*, CRegion*, bool fake = false); + void begin(CMonitor*, CRegion*, CFramebuffer* fb = nullptr /* if provided, it's not a real frame */); void end(); void renderRect(CBox*, const CColor&, int round = 0); diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index e058f1c7..20bcdcd2 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -2280,22 +2280,31 @@ CRenderbuffer* CHyprRenderer::getOrCreateRenderbuffer(wlr_buffer* buffer, uint32 return m_vRenderbuffers.emplace_back(std::make_unique(buffer, fmt)).get(); } -bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode, wlr_buffer* withBuffer) { - +void CHyprRenderer::makeEGLCurrent() { if (eglGetCurrentContext() != wlr_egl_get_context(g_pCompositor->m_sWLREGL)) eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)); +} + +void CHyprRenderer::unsetEGL() { + eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); +} + +bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode, wlr_buffer* buffer, CFramebuffer* fb) { + + makeEGLCurrent(); m_eRenderMode = mode; g_pHyprOpenGL->m_RenderData.pMonitor = pMonitor; // has to be set cuz allocs if (mode == RENDER_MODE_FULL_FAKE) { - wlr_output_attach_render(pMonitor->output, nullptr); - g_pHyprOpenGL->begin(pMonitor, &damage, true); + RASSERT(fb, "Cannot render FULL_FAKE without a provided fb!"); + fb->bind(); + g_pHyprOpenGL->begin(pMonitor, &damage, fb); return true; } - if (!withBuffer) { + if (!buffer) { if (!wlr_output_configure_primary_swapchain(pMonitor->output, &pMonitor->output->pending, &pMonitor->output->swapchain)) return false; @@ -2303,7 +2312,7 @@ bool CHyprRenderer::beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode if (!m_pCurrentWlrBuffer) return false; } else { - m_pCurrentWlrBuffer = withBuffer; + m_pCurrentWlrBuffer = buffer; } try { @@ -2334,8 +2343,10 @@ void CHyprRenderer::endRender() { else glFlush(); - if (m_eRenderMode == RENDER_MODE_NORMAL) + if (m_eRenderMode == RENDER_MODE_NORMAL) { wlr_output_state_set_buffer(&PMONITOR->output->pending, m_pCurrentWlrBuffer); + unsetEGL(); // flush the context + } wlr_buffer_unlock(m_pCurrentWlrBuffer); diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 1107d993..3c21a84e 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -70,18 +70,20 @@ class CHyprRenderer { void onRenderbufferDestroy(CRenderbuffer* rb); CRenderbuffer* getCurrentRBO(); bool isNvidia(); + void makeEGLCurrent(); + void unsetEGL(); - bool beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode = RENDER_MODE_NORMAL, wlr_buffer* withBuffer = nullptr); - void endRender(); + bool beginRender(CMonitor* pMonitor, CRegion& damage, eRenderMode mode = RENDER_MODE_NORMAL, wlr_buffer* buffer = nullptr, CFramebuffer* fb = nullptr); + void endRender(); - bool m_bWindowRequestedCursorHide = false; - bool m_bBlockSurfaceFeedback = false; - bool m_bRenderingSnapshot = false; - CWindow* m_pLastScanout = nullptr; - CMonitor* m_pMostHzMonitor = nullptr; - bool m_bDirectScanoutBlocked = false; - bool m_bSoftwareCursorsLocked = false; - bool m_bTearingEnvSatisfied = false; + bool m_bWindowRequestedCursorHide = false; + bool m_bBlockSurfaceFeedback = false; + bool m_bRenderingSnapshot = false; + CWindow* m_pLastScanout = nullptr; + CMonitor* m_pMostHzMonitor = nullptr; + bool m_bDirectScanoutBlocked = false; + bool m_bSoftwareCursorsLocked = false; + bool m_bTearingEnvSatisfied = false; DAMAGETRACKINGMODES damageTrackingModeFromStr(const std::string&); diff --git a/subprojects/wlroots b/subprojects/wlroots index 2eb22523..d7ecdad4 160000 --- a/subprojects/wlroots +++ b/subprojects/wlroots @@ -1 +1 @@ -Subproject commit 2eb225236eb72f27beec921e9f37ddf58e874fba +Subproject commit d7ecdad4e082cb5817806348de198679a11b35df