mirror of
https://github.com/hyprwm/Hyprland
synced 2025-12-20 08:30:02 +01:00
screencopy: un-hdr screencopy buffers for cm-unaware clients (#11294)
This commit is contained in:
parent
a907ecd4ff
commit
9607e3b5a8
6 changed files with 39 additions and 10 deletions
|
|
@ -204,6 +204,10 @@ bool CColorManager::good() {
|
||||||
return m_resource->resource();
|
return m_resource->resource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_client* CColorManager::client() {
|
||||||
|
return m_resource->client();
|
||||||
|
}
|
||||||
|
|
||||||
CColorManagementOutput::CColorManagementOutput(SP<CWpColorManagementOutputV1> resource, WP<CMonitor> monitor) : m_resource(resource), m_monitor(monitor) {
|
CColorManagementOutput::CColorManagementOutput(SP<CWpColorManagementOutputV1> resource, WP<CMonitor> monitor) : m_resource(resource), m_monitor(monitor) {
|
||||||
if UNLIKELY (!good())
|
if UNLIKELY (!good())
|
||||||
return;
|
return;
|
||||||
|
|
@ -818,6 +822,10 @@ void CColorManagementProtocol::onMonitorImageDescriptionChanged(WP<CMonitor> mon
|
||||||
feedback->onPreferredChanged();
|
feedback->onPreferredChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CColorManagementProtocol::isClientCMAware(wl_client* client) {
|
||||||
|
return std::ranges::any_of(m_managers, [client](const auto& m) { return m->client() == client; });
|
||||||
|
}
|
||||||
|
|
||||||
void CColorManagementProtocol::destroyResource(CColorManager* resource) {
|
void CColorManagementProtocol::destroyResource(CColorManager* resource) {
|
||||||
std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; });
|
std::erase_if(m_managers, [&](const auto& other) { return other.get() == resource; });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@ class CColorManager {
|
||||||
CColorManager(SP<CWpColorManagerV1> resource);
|
CColorManager(SP<CWpColorManagerV1> resource);
|
||||||
|
|
||||||
bool good();
|
bool good();
|
||||||
|
wl_client* client();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SP<CWpColorManagerV1> m_resource;
|
SP<CWpColorManagerV1> m_resource;
|
||||||
|
|
@ -187,6 +188,8 @@ class CColorManagementProtocol : public IWaylandProtocol {
|
||||||
void onImagePreferredChanged(uint32_t preferredId);
|
void onImagePreferredChanged(uint32_t preferredId);
|
||||||
void onMonitorImageDescriptionChanged(WP<CMonitor> monitor);
|
void onMonitorImageDescriptionChanged(WP<CMonitor> monitor);
|
||||||
|
|
||||||
|
bool isClientCMAware(wl_client* client);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void destroyResource(CColorManager* resource);
|
void destroyResource(CColorManager* resource);
|
||||||
void destroyResource(CColorManagementOutput* resource);
|
void destroyResource(CColorManagementOutput* resource);
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "core/Output.hpp"
|
#include "core/Output.hpp"
|
||||||
#include "types/WLBuffer.hpp"
|
#include "types/WLBuffer.hpp"
|
||||||
#include "types/Buffer.hpp"
|
#include "types/Buffer.hpp"
|
||||||
|
#include "ColorManagement.hpp"
|
||||||
#include "../helpers/Format.hpp"
|
#include "../helpers/Format.hpp"
|
||||||
#include "../helpers/time/Time.hpp"
|
#include "../helpers/time/Time.hpp"
|
||||||
#include "XDGShell.hpp"
|
#include "XDGShell.hpp"
|
||||||
|
|
@ -195,12 +196,18 @@ void CScreencopyFrame::renderMon() {
|
||||||
|
|
||||||
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
|
CRegion fakeDamage = {0, 0, INT16_MAX, INT16_MAX};
|
||||||
|
|
||||||
|
const bool IS_CM_AWARE = PROTO::colorManagement->isClientCMAware(m_client->client());
|
||||||
|
|
||||||
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
|
CBox monbox = CBox{0, 0, m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y}
|
||||||
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
|
.translate({-m_box.x, -m_box.y}) // vvvv kinda ass-backwards but that's how I designed the renderer... sigh.
|
||||||
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
|
.transform(wlTransformToHyprutils(invertTransform(m_monitor->m_transform)), m_monitor->m_pixelSize.x, m_monitor->m_pixelSize.y);
|
||||||
g_pHyprOpenGL->pushMonitorTransformEnabled(true);
|
g_pHyprOpenGL->pushMonitorTransformEnabled(true);
|
||||||
g_pHyprOpenGL->setRenderModifEnabled(false);
|
g_pHyprOpenGL->setRenderModifEnabled(false);
|
||||||
g_pHyprOpenGL->renderTexture(TEXTURE, monbox, {});
|
g_pHyprOpenGL->renderTexture(TEXTURE, monbox,
|
||||||
|
{
|
||||||
|
.cmBackToSRGB = !IS_CM_AWARE,
|
||||||
|
.cmBackToSRGBSource = !IS_CM_AWARE ? m_monitor.lock() : nullptr,
|
||||||
|
});
|
||||||
g_pHyprOpenGL->setRenderModifEnabled(true);
|
g_pHyprOpenGL->setRenderModifEnabled(true);
|
||||||
g_pHyprOpenGL->popMonitorTransformEnabled();
|
g_pHyprOpenGL->popMonitorTransformEnabled();
|
||||||
|
|
||||||
|
|
@ -453,6 +460,10 @@ bool CScreencopyClient::good() {
|
||||||
return m_resource->resource();
|
return m_resource->resource();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wl_client* CScreencopyClient::client() {
|
||||||
|
return m_resource ? m_resource->client() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
CScreencopyProtocol::CScreencopyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
CScreencopyProtocol::CScreencopyProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ class CScreencopyClient {
|
||||||
~CScreencopyClient();
|
~CScreencopyClient();
|
||||||
|
|
||||||
bool good();
|
bool good();
|
||||||
|
wl_client* client();
|
||||||
|
|
||||||
WP<CScreencopyClient> m_self;
|
WP<CScreencopyClient> m_self;
|
||||||
eClientOwners m_clientOwner = CLIENT_SCREENCOPY;
|
eClientOwners m_clientOwner = CLIENT_SCREENCOPY;
|
||||||
|
|
|
||||||
|
|
@ -1593,11 +1593,12 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
|
||||||
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
tex->setTexParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto imageDescription =
|
const auto imageDescription = m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ?
|
||||||
m_renderData.surface.valid() && m_renderData.surface->m_colorManagement.valid() ? m_renderData.surface->m_colorManagement->imageDescription() : SImageDescription{};
|
m_renderData.surface->m_colorManagement->imageDescription() :
|
||||||
|
(data.cmBackToSRGB ? data.cmBackToSRGBSource->m_imageDescription : SImageDescription{});
|
||||||
|
|
||||||
const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */
|
const bool skipCM = !*PENABLECM || !m_cmSupported /* CM unsupported or disabled */
|
||||||
|| (imageDescription == m_renderData.pMonitor->m_imageDescription) /* Source and target have the same image description */
|
|| (imageDescription == m_renderData.pMonitor->m_imageDescription && !data.cmBackToSRGB) /* Source and target have the same image description */
|
||||||
|| ((*PPASS == 1 || (*PPASS == 2 && imageDescription.transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ)) && m_renderData.pMonitor->m_activeWorkspace &&
|
|| ((*PPASS == 1 || (*PPASS == 2 && imageDescription.transferFunction == CM_TRANSFER_FUNCTION_ST2084_PQ)) && m_renderData.pMonitor->m_activeWorkspace &&
|
||||||
m_renderData.pMonitor->m_activeWorkspace->m_hasFullscreenWindow &&
|
m_renderData.pMonitor->m_activeWorkspace->m_hasFullscreenWindow &&
|
||||||
m_renderData.pMonitor->m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN) /* Fullscreen window with pass cm enabled */;
|
m_renderData.pMonitor->m_activeWorkspace->m_fullscreenMode == FSMODE_FULLSCREEN) /* Fullscreen window with pass cm enabled */;
|
||||||
|
|
@ -1609,6 +1610,9 @@ void CHyprOpenGLImpl::renderTextureInternal(SP<CTexture> tex, const CBox& box, c
|
||||||
|
|
||||||
if (shader == &m_shaders->m_shCM) {
|
if (shader == &m_shaders->m_shCM) {
|
||||||
shader->setUniformInt(SHADER_TEX_TYPE, texType);
|
shader->setUniformInt(SHADER_TEX_TYPE, texType);
|
||||||
|
if (data.cmBackToSRGB)
|
||||||
|
passCMUniforms(*shader, imageDescription, NColorManagement::SImageDescription{}, true, -1, -1);
|
||||||
|
else
|
||||||
passCMUniforms(*shader, imageDescription);
|
passCMUniforms(*shader, imageDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,8 @@ class CHyprOpenGLImpl {
|
||||||
bool noAA = false;
|
bool noAA = false;
|
||||||
bool blockBlurOptimization = false;
|
bool blockBlurOptimization = false;
|
||||||
GLenum wrapX = GL_CLAMP_TO_EDGE, wrapY = GL_CLAMP_TO_EDGE;
|
GLenum wrapX = GL_CLAMP_TO_EDGE, wrapY = GL_CLAMP_TO_EDGE;
|
||||||
|
bool cmBackToSRGB = false;
|
||||||
|
SP<CMonitor> cmBackToSRGBSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SBorderRenderData {
|
struct SBorderRenderData {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue