diff options
| author | Ikalco <73481042+ikalco@users.noreply.github.com> | 2026-02-22 06:30:11 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-22 12:30:11 +0000 |
| commit | b4ee4674f9a74e3d602c7fb17bc09f79d221583c (patch) | |
| tree | 294bbb207c44e778dd78afda65cbd79181f04124 /src/render | |
| parent | 93dbf884261efcb387e920b1cd0e4ed5b288bc3a (diff) | |
protocols: implement image-capture-source-v1 and image-copy-capture-v1 (#11709)
Implements the new screencopy protocols
Diffstat (limited to 'src/render')
| -rw-r--r-- | src/render/OpenGL.cpp | 50 | ||||
| -rw-r--r-- | src/render/OpenGL.hpp | 5 | ||||
| -rw-r--r-- | src/render/Renderer.hpp | 11 | ||||
| -rw-r--r-- | src/render/pass/Pass.cpp | 2 | ||||
| -rw-r--r-- | src/render/pass/SurfacePassElement.cpp | 2 |
5 files changed, 45 insertions, 25 deletions
diff --git a/src/render/OpenGL.cpp b/src/render/OpenGL.cpp index 3e0c4f26..351df0c3 100644 --- a/src/render/OpenGL.cpp +++ b/src/render/OpenGL.cpp @@ -685,6 +685,7 @@ void CHyprOpenGLImpl::beginSimple(PHLMONITOR pMonitor, const CRegion& damage, SP if (!m_shadersInitialized) initShaders(); + m_renderData.transformDamage = true; m_renderData.damage.set(damage); m_renderData.finalDamage.set(damage); @@ -752,6 +753,7 @@ void CHyprOpenGLImpl::begin(PHLMONITOR pMonitor, const CRegion& damage_, CFrameb if (m_renderData.pCurrentMonData->monitorMirrorFB.isAllocated() && m_renderData.pMonitor->m_mirrors.empty()) m_renderData.pCurrentMonData->monitorMirrorFB.release(); + m_renderData.transformDamage = true; m_renderData.damage.set(damage_); m_renderData.finalDamage.set(finalDamage.value_or(damage_)); @@ -1059,7 +1061,7 @@ void CHyprOpenGLImpl::clear(const CHyprColor& color) { if (!m_renderData.damage.empty()) { m_renderData.damage.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glClear(GL_COLOR_BUFFER_BIT); }); } @@ -1194,13 +1196,13 @@ void CHyprOpenGLImpl::renderRectWithDamageInternal(const CBox& box, const CHyprC if (!damageClip.empty()) { damageClip.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } } else { data.damage->forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } @@ -1588,13 +1590,13 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c if (!damageClip.empty()) { damageClip.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } } else { data.damage->forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } @@ -1640,7 +1642,7 @@ void CHyprOpenGLImpl::renderTexturePrimitive(SP<CTexture> tex, const CBox& box) glBindVertexArray(shader->getUniformLocation(SHADER_SHADER_VAO)); m_renderData.damage.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); @@ -1681,7 +1683,7 @@ void CHyprOpenGLImpl::renderTextureMatte(SP<CTexture> tex, const CBox& box, CFra glBindVertexArray(shader->getUniformLocation(SHADER_SHADER_VAO)); m_renderData.damage.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); @@ -2275,7 +2277,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr if (!borderRegion.empty()) { borderRegion.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } @@ -2364,7 +2366,7 @@ void CHyprOpenGLImpl::renderBorder(const CBox& box, const CGradientValueData& gr if (!borderRegion.empty()) { borderRegion.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } @@ -2427,13 +2429,13 @@ void CHyprOpenGLImpl::renderRoundedShadow(const CBox& box, int round, float roun if (!damageClip.empty()) { damageClip.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } } else { m_renderData.damage.forEachRect([this](const auto& RECT) { - scissor(&RECT); + scissor(&RECT, m_renderData.transformDamage); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); }); } @@ -3063,18 +3065,30 @@ void CHyprOpenGLImpl::setCapStatus(int cap, bool status) { } } -uint32_t CHyprOpenGLImpl::getPreferredReadFormat(PHLMONITOR pMonitor) { +DRMFormat CHyprOpenGLImpl::getPreferredReadFormat(PHLMONITOR pMonitor) { static const auto PFORCE8BIT = CConfigValue<Hyprlang::INT>("misc:screencopy_force_8b"); - if (!*PFORCE8BIT) - return pMonitor->m_output->state->state().drmFormat; + auto monFmt = pMonitor->m_output->state->state().drmFormat; - auto fmt = pMonitor->m_output->state->state().drmFormat; + if (*PFORCE8BIT) + if (monFmt == DRM_FORMAT_BGRA1010102 || monFmt == DRM_FORMAT_ARGB2101010 || monFmt == DRM_FORMAT_XRGB2101010 || monFmt == DRM_FORMAT_BGRX1010102 || + monFmt == DRM_FORMAT_XBGR2101010) + monFmt = DRM_FORMAT_XRGB8888; - if (fmt == DRM_FORMAT_BGRA1010102 || fmt == DRM_FORMAT_ARGB2101010 || fmt == DRM_FORMAT_XRGB2101010 || fmt == DRM_FORMAT_BGRX1010102 || fmt == DRM_FORMAT_XBGR2101010) - return DRM_FORMAT_XRGB8888; + return monFmt; +} + +std::vector<uint64_t> CHyprOpenGLImpl::getDRMFormatModifiers(DRMFormat drmFormat) { + SDRMFormat format; + + for (const auto& fmt : m_drmFormats) { + if (fmt.drmFormat == drmFormat) { + format = fmt; + break; + } + } - return fmt; + return format.modifiers; } bool CHyprOpenGLImpl::explicitSyncSupported() { diff --git a/src/render/OpenGL.hpp b/src/render/OpenGL.hpp index 3df8322b..bc1f5f4d 100644 --- a/src/render/OpenGL.hpp +++ b/src/render/OpenGL.hpp @@ -172,6 +172,8 @@ struct SCurrentRenderData { bool useNearestNeighbor = false; bool blockScreenShader = false; bool simplePass = false; + bool transformDamage = true; + bool noSimplify = false; Vector2D primarySurfaceUVTopLeft = Vector2D(-1, -1); Vector2D primarySurfaceUVBottomRight = Vector2D(-1, -1); @@ -305,8 +307,9 @@ class CHyprOpenGLImpl { void setDamage(const CRegion& damage, std::optional<CRegion> finalDamage = {}); - uint32_t getPreferredReadFormat(PHLMONITOR pMonitor); + DRMFormat getPreferredReadFormat(PHLMONITOR pMonitor); std::vector<SDRMFormat> getDRMFormats(); + std::vector<uint64_t> getDRMFormatModifiers(DRMFormat format); EGLImageKHR createEGLImage(const Aquamarine::SDMABUFAttrs& attrs); bool initShaders(); diff --git a/src/render/Renderer.hpp b/src/render/Renderer.hpp index f2377b3b..24e0fb66 100644 --- a/src/render/Renderer.hpp +++ b/src/render/Renderer.hpp @@ -16,6 +16,12 @@ class CWorkspace; class CInputPopup; class IHLBuffer; class CEventLoopTimer; +class CToplevelExportProtocolManager; +class CInputManager; +struct SSessionLockSurface; +namespace Screenshare { + class CScreenshareFrame; +}; enum eDamageTrackingModes : int8_t { DAMAGE_TRACKING_INVALID = -1, @@ -37,10 +43,6 @@ enum eRenderMode : uint8_t { RENDER_MODE_TO_BUFFER_READ_ONLY = 3, }; -class CToplevelExportProtocolManager; -class CInputManager; -struct SSessionLockSurface; - struct SRenderWorkspaceUntilData { PHLLS ls; PHLWINDOW w; @@ -166,6 +168,7 @@ class CHyprRenderer { friend class CHyprOpenGLImpl; friend class CToplevelExportFrame; + friend class Screenshare::CScreenshareFrame; friend class CInputManager; friend class CPointerManager; friend class CMonitor; diff --git a/src/render/pass/Pass.cpp b/src/render/pass/Pass.cpp index b62a4734..3c82c84c 100644 --- a/src/render/pass/Pass.cpp +++ b/src/render/pass/Pass.cpp @@ -171,7 +171,7 @@ CRegion CRenderPass::render(const CRegion& damage_) { } else g_pHyprOpenGL->m_renderData.finalDamage = m_damage; - if (std::ranges::any_of(m_passElements, [](const auto& el) { return el->element->disableSimplification(); })) { + if (g_pHyprOpenGL->m_renderData.noSimplify || std::ranges::any_of(m_passElements, [](const auto& el) { return el->element->disableSimplification(); })) { for (auto& el : m_passElements) { el->elementDamage = m_damage; } diff --git a/src/render/pass/SurfacePassElement.cpp b/src/render/pass/SurfacePassElement.cpp index df410014..c5feb8f7 100644 --- a/src/render/pass/SurfacePassElement.cpp +++ b/src/render/pass/SurfacePassElement.cpp @@ -104,7 +104,7 @@ void CSurfacePassElement::draw(const CRegion& damage) { } const bool WINDOWOPAQUE = m_data.pWindow && m_data.pWindow->wlSurface()->resource() == m_data.surface ? m_data.pWindow->opaque() : false; - const bool CANDISABLEBLEND = ALPHA >= 1.f && OVERALL_ALPHA >= 1.f && rounding == 0 && WINDOWOPAQUE; + const bool CANDISABLEBLEND = ALPHA >= 1.f && OVERALL_ALPHA >= 1.f && rounding <= 0 && WINDOWOPAQUE; if (CANDISABLEBLEND) g_pHyprOpenGL->blend(false); |
