From 9235728166201964e3a9dd6635dafa768ab9916a Mon Sep 17 00:00:00 2001 From: Vaxry Date: Fri, 5 Jul 2024 21:06:23 +0200 Subject: [PATCH] fix nvidia crasherino lmao --- src/Compositor.hpp | 2 +- src/managers/CursorManager.cpp | 3 +-- src/managers/PointerManager.cpp | 5 ++++- src/render/OpenGL.cpp | 5 +++-- src/render/OpenGL.hpp | 2 +- src/render/Renderbuffer.cpp | 18 +++++++++++++---- src/render/Renderbuffer.hpp | 2 ++ src/render/Renderer.cpp | 14 +++++++++---- src/render/Renderer.hpp | 36 ++++++++++++++++----------------- src/render/Texture.hpp | 2 +- 10 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/Compositor.hpp b/src/Compositor.hpp index d3ac6a30685..3eaafb47ba4 100644 --- a/src/Compositor.hpp +++ b/src/Compositor.hpp @@ -86,7 +86,7 @@ class CCompositor { bool m_bReadyToProcess = false; bool m_bSessionActive = true; bool m_bDPMSStateON = true; - bool m_bUnsafeState = false; // unsafe state is when there is no monitors. + bool m_bUnsafeState = false; // unsafe state is when there is no monitors. bool m_bNextIsUnsafe = false; CMonitor* m_pUnsafeOutput = nullptr; // fallback output for the unsafe state bool m_bExitTriggered = false; // For exit dispatcher diff --git a/src/managers/CursorManager.cpp b/src/managers/CursorManager.cpp index 3dd4394036c..176caaa59ec 100644 --- a/src/managers/CursorManager.cpp +++ b/src/managers/CursorManager.cpp @@ -139,8 +139,7 @@ void CCursorManager::setXCursor(const std::string& name) { return; } - m_vCursorBuffers.emplace_back( - makeShared(xcursor.defaultCursor->pixels.data(), xcursor.defaultCursor->size, xcursor.defaultCursor->hotspot)); + m_vCursorBuffers.emplace_back(makeShared(xcursor.defaultCursor->pixels.data(), xcursor.defaultCursor->size, xcursor.defaultCursor->hotspot)); g_pPointerManager->setCursorBuffer(getCursorBuffer(), xcursor.defaultCursor->hotspot / scale, scale); if (m_vCursorBuffers.size() > 1) diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index 11259632faf..e7c5b42b441 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -395,6 +395,9 @@ SP CPointerManager::renderHWCursorBuffer(SPm_RenderData.pMonitor = state->monitor.get(); const auto RBO = g_pHyprRenderer->getOrCreateRenderbuffer(buf, state->monitor->cursorSwapchain->currentOptions().format); + if (!RBO) + return nullptr; + RBO->bind(); g_pHyprOpenGL->beginSimple(state->monitor.get(), damage, RBO); @@ -410,7 +413,7 @@ SP CPointerManager::renderHWCursorBuffer(SPm_RenderData.pMonitor = nullptr; - g_pHyprRenderer->onRenderbufferDestroy(RBO); + g_pHyprRenderer->onRenderbufferDestroy(RBO.get()); return buf; } diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 3789b7b637c..8c5adf4ecbf 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -617,7 +617,7 @@ bool CHyprOpenGLImpl::passRequiresIntrospection(CMonitor* pMonitor) { return false; } -void CHyprOpenGLImpl::beginSimple(CMonitor* pMonitor, const CRegion& damage, CRenderbuffer* rb, CFramebuffer* fb) { +void CHyprOpenGLImpl::beginSimple(CMonitor* pMonitor, const CRegion& damage, SP rb, CFramebuffer* fb) { m_RenderData.pMonitor = pMonitor; #ifndef GLES2 @@ -1558,7 +1558,8 @@ CFramebuffer* CHyprOpenGLImpl::blurMainFramebufferWithDamage(float a, CRegion* o // prep damage CRegion damage{*originalDamage}; - damage.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, m_RenderData.pMonitor->vecTransformedSize.y); + damage.transform(wlTransformToHyprutils(invertTransform(m_RenderData.pMonitor->transform)), m_RenderData.pMonitor->vecTransformedSize.x, + m_RenderData.pMonitor->vecTransformedSize.y); damage.expand(*PBLURPASSES > 10 ? pow(2, 15) : std::clamp(*PBLURSIZE, (int64_t)1, (int64_t)40) * pow(2, *PBLURPASSES)); // helper diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 4b525b163c4..9696c2ccb69 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -130,7 +130,7 @@ class CHyprOpenGLImpl { CHyprOpenGLImpl(); void begin(CMonitor*, const CRegion& damage, CFramebuffer* fb = nullptr, std::optional finalDamage = {}); - void beginSimple(CMonitor*, const CRegion& damage, CRenderbuffer* rb = nullptr, CFramebuffer* fb = nullptr); + void beginSimple(CMonitor*, const CRegion& damage, SP rb = nullptr, CFramebuffer* fb = nullptr); void end(); void renderRect(CBox*, const CColor&, int round = 0); diff --git a/src/render/Renderbuffer.cpp b/src/render/Renderbuffer.cpp index 65c64eb9287..57f4fbd21a3 100644 --- a/src/render/Renderbuffer.cpp +++ b/src/render/Renderbuffer.cpp @@ -22,8 +22,10 @@ CRenderbuffer::CRenderbuffer(SP buffer, uint32_t format) : auto dma = buffer->dmabuf(); m_iImage = g_pHyprOpenGL->createEGLImage(dma); - if (m_iImage == EGL_NO_IMAGE_KHR) - throw std::runtime_error("createEGLImage failed"); + if (m_iImage == EGL_NO_IMAGE_KHR) { + Debug::log(ERR, "rb: createEGLImage failed"); + return; + } glGenRenderbuffers(1, &m_iRBO); glBindRenderbuffer(GL_RENDERBUFFER, m_iRBO); @@ -35,12 +37,20 @@ CRenderbuffer::CRenderbuffer(SP buffer, uint32_t format) : m_sFramebuffer.bind(); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_iRBO); - if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) - throw std::runtime_error("rbo: glCheckFramebufferStatus failed"); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + Debug::log(ERR, "rbo: glCheckFramebufferStatus failed"); + return; + } glBindFramebuffer(GL_FRAMEBUFFER, 0); listeners.destroyBuffer = buffer->events.destroy.registerListener([this](std::any d) { g_pHyprRenderer->onRenderbufferDestroy(this); }); + + m_bGood = true; +} + +bool CRenderbuffer::good() { + return m_bGood; } void CRenderbuffer::bind() { diff --git a/src/render/Renderbuffer.hpp b/src/render/Renderbuffer.hpp index 518b34dae7a..f8155087178 100644 --- a/src/render/Renderbuffer.hpp +++ b/src/render/Renderbuffer.hpp @@ -10,6 +10,7 @@ class CRenderbuffer { CRenderbuffer(SP buffer, uint32_t format); ~CRenderbuffer(); + bool good(); void bind(); void bindFB(); void unbind(); @@ -23,6 +24,7 @@ class CRenderbuffer { GLuint m_iRBO = 0; CFramebuffer m_sFramebuffer; uint32_t m_uDrmFormat = 0; + bool m_bGood = false; struct { CHyprSignalListener destroyBuffer; diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp index b336a5f846b..f753a626123 100644 --- a/src/render/Renderer.cpp +++ b/src/render/Renderer.cpp @@ -2541,13 +2541,19 @@ void CHyprRenderer::recheckSolitaryForMonitor(CMonitor* pMonitor) { pMonitor->solitaryClient = PCANDIDATE; } -CRenderbuffer* CHyprRenderer::getOrCreateRenderbuffer(SP buffer, uint32_t fmt) { +SP CHyprRenderer::getOrCreateRenderbuffer(SP buffer, uint32_t fmt) { auto it = std::find_if(m_vRenderbuffers.begin(), m_vRenderbuffers.end(), [&](const auto& other) { return other->m_pHLBuffer == buffer; }); if (it != m_vRenderbuffers.end()) - return it->get(); + return *it; - return m_vRenderbuffers.emplace_back(std::make_unique(buffer, fmt)).get(); + auto buf = makeShared(buffer, fmt); + + if (!buf->good()) + return nullptr; + + m_vRenderbuffers.emplace_back(buf); + return buf; } void CHyprRenderer::makeEGLCurrent() { @@ -2650,7 +2656,7 @@ void CHyprRenderer::onRenderbufferDestroy(CRenderbuffer* rb) { std::erase_if(m_vRenderbuffers, [&](const auto& rbo) { return rbo.get() == rb; }); } -CRenderbuffer* CHyprRenderer::getCurrentRBO() { +SP CHyprRenderer::getCurrentRBO() { return m_pCurrentRenderbuffer; } diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index 81b9e55bd87..ce37f51b24f 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -69,7 +69,7 @@ class CHyprRenderer { void setCursorSurface(SP surf, int hotspotX, int hotspotY, bool force = false); void setCursorFromName(const std::string& name, bool force = false); void onRenderbufferDestroy(CRenderbuffer* rb); - CRenderbuffer* getCurrentRBO(); + SP getCurrentRBO(); bool isNvidia(); void makeEGLCurrent(); void unsetEGL(); @@ -107,21 +107,21 @@ class CHyprRenderer { } m_sLastCursorData; private: - void arrangeLayerArray(CMonitor*, const std::vector&, bool, CBox*); - void renderWorkspaceWindowsFullscreen(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) - void renderWorkspaceWindows(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) - void renderWindow(PHLWINDOW, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); - void renderLayer(PHLLS, CMonitor*, timespec*, bool popups = false); - void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); - void renderDragIcon(CMonitor*, timespec*); - void renderIMEPopup(CInputPopup*, CMonitor*, timespec*); - void renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry); - void sendFrameEventsToWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now); // sends frame displayed events but doesn't actually render anything - void renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); - - bool m_bCursorHidden = false; - bool m_bCursorHasSurface = false; - CRenderbuffer* m_pCurrentRenderbuffer = nullptr; + void arrangeLayerArray(CMonitor*, const std::vector&, bool, CBox*); + void renderWorkspaceWindowsFullscreen(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (fullscreen) (tiled, floating, pinned, but no special) + void renderWorkspaceWindows(CMonitor*, PHLWORKSPACE, timespec*); // renders workspace windows (no fullscreen) (tiled, floating, pinned, but no special) + void renderWindow(PHLWINDOW, CMonitor*, timespec*, bool, eRenderPassMode, bool ignorePosition = false, bool ignoreAllGeometry = false); + void renderLayer(PHLLS, CMonitor*, timespec*, bool popups = false); + void renderSessionLockSurface(SSessionLockSurface*, CMonitor*, timespec*); + void renderDragIcon(CMonitor*, timespec*); + void renderIMEPopup(CInputPopup*, CMonitor*, timespec*); + void renderWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const CBox& geometry); + void sendFrameEventsToWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now); // sends frame displayed events but doesn't actually render anything + void renderAllClientsForWorkspace(CMonitor* pMonitor, PHLWORKSPACE pWorkspace, timespec* now, const Vector2D& translate = {0, 0}, const float& scale = 1.f); + + bool m_bCursorHidden = false; + bool m_bCursorHasSurface = false; + SP m_pCurrentRenderbuffer = nullptr; SP m_pCurrentBuffer; eRenderMode m_eRenderMode = RENDER_MODE_NORMAL; @@ -133,8 +133,8 @@ class CHyprRenderer { bool hiddenOnKeyboard = false; } m_sCursorHiddenConditions; - CRenderbuffer* getOrCreateRenderbuffer(SP buffer, uint32_t fmt); - std::vector> m_vRenderbuffers; + SP getOrCreateRenderbuffer(SP buffer, uint32_t fmt); + std::vector> m_vRenderbuffers; friend class CHyprOpenGLImpl; friend class CToplevelExportProtocolManager; diff --git a/src/render/Texture.hpp b/src/render/Texture.hpp index 07156cc8157..0da95300cc4 100644 --- a/src/render/Texture.hpp +++ b/src/render/Texture.hpp @@ -37,7 +37,7 @@ class CTexture { GLenum m_iTarget = GL_TEXTURE_2D; GLuint m_iTexID = 0; Vector2D m_vSize; - void* m_pEglImage = nullptr; + void* m_pEglImage = nullptr; private: void createFromShm(uint32_t drmFormat, uint8_t* pixels, uint32_t stride, const Vector2D& size);