protocols: implement image-capture-source-v1 and image-copy-capture-v1 (#11709)

Implements the new screencopy protocols
This commit is contained in:
Ikalco 2026-02-22 06:30:11 -06:00 committed by GitHub
parent 93dbf88426
commit b4ee4674f9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
37 changed files with 2585 additions and 1078 deletions

View file

@ -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;
}
return fmt;
std::vector<uint64_t> CHyprOpenGLImpl::getDRMFormatModifiers(DRMFormat drmFormat) {
SDRMFormat format;
for (const auto& fmt : m_drmFormats) {
if (fmt.drmFormat == drmFormat) {
format = fmt;
break;
}
}
return format.modifiers;
}
bool CHyprOpenGLImpl::explicitSyncSupported() {