diff options
| author | Vaxry <vaxry@vaxry.net> | 2023-11-30 10:14:35 +0000 |
|---|---|---|
| committer | Vaxry <vaxry@vaxry.net> | 2023-11-30 10:14:35 +0000 |
| commit | b9937484f4deefbc07c5fc3483d15885068e975d (patch) | |
| tree | 4705ee3b239c8ab56817c74a1df8ab04adbb9e04 /src/protocols/Screencopy.cpp | |
| parent | 776f944619168e1812e7f8bee0258757fed987a4 (diff) | |
screencopy: fix broken shm copying
fixes #4001
Diffstat (limited to 'src/protocols/Screencopy.cpp')
| -rw-r--r-- | src/protocols/Screencopy.cpp | 68 |
1 files changed, 48 insertions, 20 deletions
diff --git a/src/protocols/Screencopy.cpp b/src/protocols/Screencopy.cpp index fdd89d30..2e00a509 100644 --- a/src/protocols/Screencopy.cpp +++ b/src/protocols/Screencopy.cpp @@ -424,26 +424,54 @@ 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; - - // 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); - - // return success; - - return false; // TODO: maybe fix this with the new rendering pipeline? - // though who tf isnt using dmabuf? + wlr_texture* sourceTex = wlr_texture_from_buffer(g_pCompositor->m_sWLRRenderer, m_pLastMonitorBackBuffer); + if (!sourceTex) + 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)) { + wlr_texture_destroy(sourceTex); + return false; + } + + CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX}; + + g_pHyprRenderer->makeEGLCurrent(); + + CFramebuffer fb; + fb.alloc(frame->box.w, frame->box.h); // 8bit only + + if (!g_pHyprRenderer->beginRender(frame->pMonitor, fakeDamage, RENDER_MODE_FULL_FAKE, nullptr, &fb)) { + wlr_texture_destroy(sourceTex); + wlr_buffer_end_data_ptr_access(frame->buffer); + return false; + } + + CBox monbox = CBox{0, 0, frame->pMonitor->vecPixelSize.x, frame->pMonitor->vecPixelSize.y}.translate({-frame->box.x, -frame->box.y}); + g_pHyprOpenGL->setMonitorTransformEnabled(false); + g_pHyprOpenGL->renderTexture(sourceTex, &monbox, 1); + g_pHyprOpenGL->setMonitorTransformEnabled(true); + + glBindFramebuffer(GL_READ_FRAMEBUFFER, fb.m_iFb); + + const auto PFORMAT = gles2FromDRM(format); + if (!PFORMAT) { + Debug::log(ERR, "[sc] Cannot read pixels, unsupported format {:x}", (uintptr_t)PFORMAT); + wlr_texture_destroy(sourceTex); + wlr_buffer_end_data_ptr_access(frame->buffer); + return false; + } + + glReadPixels(0, 0, frame->box.w, frame->box.h, PFORMAT->gl_format, PFORMAT->gl_type, data); + + g_pHyprRenderer->endRender(); + + wlr_buffer_end_data_ptr_access(frame->buffer); + wlr_texture_destroy(sourceTex); + + return true; } bool CScreencopyProtocolManager::copyFrameDmabuf(SScreencopyFrame* frame) { |
