From 19fe56bb12fdb7a776ebc462e7c5a3ddf29756ef Mon Sep 17 00:00:00 2001 From: UjinT34 Date: Thu, 25 Jul 2024 11:04:02 +0300 Subject: [PATCH] copy from rendered texture --- src/helpers/Monitor.cpp | 6 +-- src/managers/PointerManager.cpp | 73 +++++++++++---------------------- 2 files changed, 26 insertions(+), 53 deletions(-) diff --git a/src/helpers/Monitor.cpp b/src/helpers/Monitor.cpp index 812662e9..b9f3bf37 100644 --- a/src/helpers/Monitor.cpp +++ b/src/helpers/Monitor.cpp @@ -399,10 +399,8 @@ int CMonitor::findAvailableDefaultWS() { SP CMonitor::resizeSwapchain(SP swapchain, Vector2D size, bool isCursor) { if (!swapchain || size != swapchain->currentOptions().size) { - if (!swapchain) { - Debug::log(TRACE, "creating new cursor {} swapchain", isCursor); + if (!swapchain) swapchain = Aquamarine::CSwapchain::create(output->getBackend()->preferredAllocator(), output->getBackend()); - } auto options = swapchain->currentOptions(); options.size = size; @@ -864,7 +862,6 @@ bool CMonitor::attemptDirectScanout() { } bool CMonitor::resizeCursorSwapchain(Vector2D size) { - Debug::log(TRACE, "resizeCursorSwapchain"); auto swapchain = resizeSwapchain(cursorSwapchain, size, true); if (!cursorSwapchain) cursorSwapchain = swapchain; @@ -873,7 +870,6 @@ bool CMonitor::resizeCursorSwapchain(Vector2D size) { } bool CMonitor::resizeCursorFallbackSwapchain(Vector2D size) { - Debug::log(TRACE, "resizeCursorFallbackSwapchain"); auto swapchain = resizeSwapchain(cursorFallbackSwapchain, size, false); if (!cursorFallbackSwapchain) cursorFallbackSwapchain = swapchain; diff --git a/src/managers/PointerManager.cpp b/src/managers/PointerManager.cpp index f5903eb3..9f1e4678 100644 --- a/src/managers/PointerManager.cpp +++ b/src/managers/PointerManager.cpp @@ -7,6 +7,7 @@ #include "eventLoop/EventLoopManager.hpp" #include "SeatManager.hpp" #include "render/OpenGL.hpp" +#include "render/Texture.hpp" #include #include #include @@ -420,14 +421,13 @@ SP CPointerManager::renderHWCursorBuffer(SPgetOrCreateRenderbuffer(fallback, state->monitor->cursorFallbackSwapchain->currentOptions().format); if (!RBO) { Debug::log(TRACE, "Failed to create cursor RB with format {}, mod {}", fallback->dmabuf().format, fallback->dmabuf().modifier); return nullptr; - } else - Debug::log(TRACE, "Created cursor RB with format {}, mod {}", fallback->dmabuf().format, fallback->dmabuf().modifier); - } else - Debug::log(TRACE, "Created cursor RB with format {}, mod {}", buf->dmabuf().format, buf->dmabuf().modifier); + } + } RBO->bind(); @@ -441,66 +441,43 @@ SP CPointerManager::renderHWCursorBuffer(SPrenderTexture(texture, &xbox, 1.F); g_pHyprOpenGL->end(); - if (needsFallback) - glFinish(); - else + if (!needsFallback) glFlush(); - g_pHyprOpenGL->m_RenderData.pMonitor = nullptr; + else { + glFinish(); - g_pHyprRenderer->onRenderbufferDestroy(RBO.get()); - - if (needsFallback) { // wlroots tries to blit here but it'll fail the same way we've got here in the first place auto bufAttrs = buf->dmabuf(); - Debug::log(TRACE, "mapping cursor buffer for writing"); + auto texAttrs = fallback->dmabuf(); + auto bufData = buf->beginDataPtr(GBM_BO_TRANSFER_WRITE); auto bufPtr = std::get<0>(bufData); - auto textAttrs = fallback->dmabuf(); - Debug::log(TRACE, "mapping cursor fallback buffer for reading"); - auto texData = fallback->beginDataPtr(GBM_BO_TRANSFER_WRITE); - auto texPtr = std::get<0>(texData); - Debug::log(TRACE, "cursor buffer {}x{} {} format={}({}) stride={}({})", bufAttrs.size.x, bufAttrs.size.y, (void*)bufPtr, bufAttrs.format, std::get<1>(bufData), - bufAttrs.strides[0], std::get<2>(bufData)); - Debug::log(TRACE, "cursor fallback buffer {}x{} {} format={}({}) stride={}({})", textAttrs.size.x, textAttrs.size.y, (void*)texPtr, textAttrs.format, std::get<1>(texData), - textAttrs.strides[0], std::get<2>(texData)); - - const auto dma = fallback->dmabuf(); - - auto image = g_pHyprOpenGL->createEGLImage(dma); - if (image == EGL_NO_IMAGE_KHR) { - Debug::log(TRACE, "texture fallback failed"); - return nullptr; - } + Debug::log(TRACE, "cursor buffer {}x{} {} format={} stride={}", bufAttrs.size.x, bufAttrs.size.y, (void*)bufPtr, bufAttrs.format, bufAttrs.strides[0]); + Debug::log(TRACE, "fallback buffer {}x{} format={} stride={}", texAttrs.size.x, texAttrs.size.y, texAttrs.format, texAttrs.strides[0]); + g_pHyprRenderer->makeEGLCurrent(); + auto fallbackTexture = new CTexture(fallback); GLuint id; + glGenFramebuffers(1, &id); + glBindFramebuffer(GL_FRAMEBUFFER, id); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, fallbackTexture->m_iTarget, fallbackTexture->m_iTexID, 0); - GLCALL(glGenTextures(1, &id)); + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + Debug::log(ERR, "cursor dumb copy: glCheckFramebufferStatus failed"); + else { + const auto PFORMAT = FormatUtils::getPixelFormatFromDRM(bufAttrs.format); + glPixelStorei(GL_PACK_ALIGNMENT, 1); - GLCALL(glBindTexture(GL_TEXTURE_2D, id)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); - GLCALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); - GLCALL(g_pHyprOpenGL->m_sProc.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image)); - GLCALL(glBindTexture(GL_TEXTURE_2D, 0)); - - Debug::log(TRACE, "texture fallback got {}", image); - if (!texPtr) - texPtr = (uint8_t*)image; - - if (!bufPtr || !texPtr) - return nullptr; - - // copy rendered cursor - for (int i = 0; i < textAttrs.size.y; i++) { - Debug::log(TRACE, "copying {}/{} dst start={}, src start={}, length={}", i + 1, textAttrs.size.y, (void*)(bufPtr + i * bufAttrs.strides[0]), - (void*)(texPtr + i * textAttrs.strides[0]), textAttrs.strides[0]); - memcpy(bufPtr + i * bufAttrs.strides[0], texPtr + i * textAttrs.strides[0], textAttrs.strides[0]); + glReadPixels(0, 0, bufAttrs.size.x, bufAttrs.size.y, GL_RGBA, PFORMAT->glType, bufPtr); } buf->endDataPtr(); - fallback->endDataPtr(); } + g_pHyprOpenGL->m_RenderData.pMonitor = nullptr; + g_pHyprRenderer->onRenderbufferDestroy(RBO.get()); + return buf; }