mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-08-15 20:13:49 -07:00
protocols/cm: Fix preferred image description (#11026)
This commit is contained in:
@@ -3090,7 +3090,7 @@ SImageDescription CCompositor::getPreferredImageDescription() {
|
|||||||
}
|
}
|
||||||
Debug::log(WARN, "FIXME: color management protocol is enabled, determine correct preferred image description");
|
Debug::log(WARN, "FIXME: color management protocol is enabled, determine correct preferred image description");
|
||||||
// should determine some common settings to avoid unnecessary transformations while keeping maximum displayable precision
|
// should determine some common settings to avoid unnecessary transformations while keeping maximum displayable precision
|
||||||
return SImageDescription{.primaries = NColorPrimaries::BT709};
|
return m_monitors.size() == 1 ? m_monitors[0]->m_imageDescription : SImageDescription{.primaries = NColorPrimaries::BT709};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CCompositor::shouldChangePreferredImageDescription() {
|
bool CCompositor::shouldChangePreferredImageDescription() {
|
||||||
|
@@ -412,6 +412,7 @@ void CMonitor::onDisconnect(bool destroy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CMonitor::applyCMType(eCMType cmType) {
|
void CMonitor::applyCMType(eCMType cmType) {
|
||||||
|
auto oldImageDescription = m_imageDescription;
|
||||||
switch (cmType) {
|
switch (cmType) {
|
||||||
case CM_SRGB: m_imageDescription = {}; break; // assumes SImageDescirption defaults to sRGB
|
case CM_SRGB: m_imageDescription = {}; break; // assumes SImageDescirption defaults to sRGB
|
||||||
case CM_WIDE:
|
case CM_WIDE:
|
||||||
@@ -461,6 +462,11 @@ void CMonitor::applyCMType(eCMType cmType) {
|
|||||||
m_imageDescription.luminances.max = m_maxLuminance;
|
m_imageDescription.luminances.max = m_maxLuminance;
|
||||||
if (m_maxAvgLuminance >= 0)
|
if (m_maxAvgLuminance >= 0)
|
||||||
m_imageDescription.luminances.reference = m_maxAvgLuminance;
|
m_imageDescription.luminances.reference = m_maxAvgLuminance;
|
||||||
|
|
||||||
|
if (oldImageDescription != m_imageDescription) {
|
||||||
|
m_imageDescription.updateId();
|
||||||
|
PROTO::colorManagement->onMonitorImageDescriptionChanged(m_self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
||||||
@@ -783,7 +789,6 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
|||||||
m_supportsWideColor = RULE->supportsHDR;
|
m_supportsWideColor = RULE->supportsHDR;
|
||||||
m_supportsHDR = RULE->supportsHDR;
|
m_supportsHDR = RULE->supportsHDR;
|
||||||
|
|
||||||
auto oldImageDescription = m_imageDescription;
|
|
||||||
m_cmType = RULE->cmType;
|
m_cmType = RULE->cmType;
|
||||||
switch (m_cmType) {
|
switch (m_cmType) {
|
||||||
case CM_AUTO: m_cmType = m_enabled10bit && supportsWideColor() ? CM_WIDE : CM_SRGB; break;
|
case CM_AUTO: m_cmType = m_enabled10bit && supportsWideColor() ? CM_WIDE : CM_SRGB; break;
|
||||||
@@ -801,8 +806,6 @@ bool CMonitor::applyMonitorRule(SMonitorRule* pMonitorRule, bool force) {
|
|||||||
m_maxAvgLuminance = RULE->maxAvgLuminance;
|
m_maxAvgLuminance = RULE->maxAvgLuminance;
|
||||||
|
|
||||||
applyCMType(m_cmType);
|
applyCMType(m_cmType);
|
||||||
if (oldImageDescription != m_imageDescription)
|
|
||||||
PROTO::colorManagement->onMonitorImageDescriptionChanged(m_self);
|
|
||||||
|
|
||||||
m_sdrSaturation = RULE->sdrSaturation;
|
m_sdrSaturation = RULE->sdrSaturation;
|
||||||
m_sdrBrightness = RULE->sdrBrightness;
|
m_sdrBrightness = RULE->sdrBrightness;
|
||||||
|
@@ -410,14 +410,27 @@ CColorManagementFeedbackSurface::CColorManagementFeedbackSurface(SP<CWpColorMana
|
|||||||
m_currentPreferred = RESOURCE;
|
m_currentPreferred = RESOURCE;
|
||||||
|
|
||||||
m_currentPreferred->m_settings = m_surface->getPreferredImageDescription();
|
m_currentPreferred->m_settings = m_surface->getPreferredImageDescription();
|
||||||
if (!PROTO::colorManagement->m_debug && m_currentPreferred->m_settings.icc.fd) {
|
m_currentPreferredId = m_currentPreferred->m_settings.updateId();
|
||||||
|
|
||||||
|
if (!PROTO::colorManagement->m_debug && m_currentPreferred->m_settings.icc.fd >= 0) {
|
||||||
LOGM(ERR, "FIXME: parse icc profile");
|
LOGM(ERR, "FIXME: parse icc profile");
|
||||||
r->error(WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE, "ICC profiles are not supported");
|
r->error(WP_COLOR_MANAGER_V1_ERROR_UNSUPPORTED_FEATURE, "ICC profiles are not supported");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RESOURCE->resource()->sendReady(m_currentPreferred->m_settings.updateId());
|
RESOURCE->resource()->sendReady(m_currentPreferredId);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
m_listeners.enter = m_surface->m_events.enter.listen([this](const auto& monitor) { onPreferredChanged(); });
|
||||||
|
m_listeners.leave = m_surface->m_events.leave.listen([this](const auto& monitor) { onPreferredChanged(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void CColorManagementFeedbackSurface::onPreferredChanged() {
|
||||||
|
if (m_surface->m_enteredOutputs.size() == 1) {
|
||||||
|
const auto newId = m_surface->getPreferredImageDescription().updateId();
|
||||||
|
if (m_currentPreferredId != newId)
|
||||||
|
m_resource->sendPreferredChanged(newId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CColorManagementFeedbackSurface::good() {
|
bool CColorManagementFeedbackSurface::good() {
|
||||||
@@ -796,6 +809,9 @@ void CColorManagementProtocol::onMonitorImageDescriptionChanged(WP<CMonitor> mon
|
|||||||
if (output->m_monitor == monitor)
|
if (output->m_monitor == monitor)
|
||||||
output->m_resource->sendImageDescriptionChanged();
|
output->m_resource->sendImageDescriptionChanged();
|
||||||
}
|
}
|
||||||
|
// recheck feedbacks
|
||||||
|
for (auto const& feedback : m_feedbackSurfaces)
|
||||||
|
feedback->onPreferredChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CColorManagementProtocol::destroyResource(CColorManager* resource) {
|
void CColorManagementProtocol::destroyResource(CColorManager* resource) {
|
||||||
|
@@ -89,6 +89,14 @@ class CColorManagementFeedbackSurface {
|
|||||||
wl_client* m_client = nullptr;
|
wl_client* m_client = nullptr;
|
||||||
|
|
||||||
WP<CColorManagementImageDescription> m_currentPreferred;
|
WP<CColorManagementImageDescription> m_currentPreferred;
|
||||||
|
uint32_t m_currentPreferredId = 0;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
CHyprSignalListener enter;
|
||||||
|
CHyprSignalListener leave;
|
||||||
|
} m_listeners;
|
||||||
|
|
||||||
|
void onPreferredChanged();
|
||||||
|
|
||||||
friend class CColorManagementProtocol;
|
friend class CColorManagementProtocol;
|
||||||
};
|
};
|
||||||
|
@@ -307,6 +307,7 @@ void CWLSurfaceResource::enter(PHLMONITOR monitor) {
|
|||||||
m_enteredOutputs.emplace_back(monitor);
|
m_enteredOutputs.emplace_back(monitor);
|
||||||
|
|
||||||
m_resource->sendEnter(output->getResource().get());
|
m_resource->sendEnter(output->getResource().get());
|
||||||
|
m_events.enter.emit(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLSurfaceResource::leave(PHLMONITOR monitor) {
|
void CWLSurfaceResource::leave(PHLMONITOR monitor) {
|
||||||
@@ -323,6 +324,7 @@ void CWLSurfaceResource::leave(PHLMONITOR monitor) {
|
|||||||
std::erase(m_enteredOutputs, monitor);
|
std::erase(m_enteredOutputs, monitor);
|
||||||
|
|
||||||
m_resource->sendLeave(output->getResource().get());
|
m_resource->sendLeave(output->getResource().get());
|
||||||
|
m_events.leave.emit(monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLSurfaceResource::sendPreferredTransform(wl_output_transform t) {
|
void CWLSurfaceResource::sendPreferredTransform(wl_output_transform t) {
|
||||||
@@ -539,7 +541,18 @@ void CWLSurfaceResource::commitState(SSurfaceState& state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SImageDescription CWLSurfaceResource::getPreferredImageDescription() {
|
SImageDescription CWLSurfaceResource::getPreferredImageDescription() {
|
||||||
return m_enteredOutputs.size() == 1 ? m_enteredOutputs[0]->m_imageDescription : g_pCompositor->getPreferredImageDescription();
|
auto parent = m_self;
|
||||||
|
if (parent->m_role->role() == SURFACE_ROLE_SUBSURFACE) {
|
||||||
|
auto subsurface = ((CSubsurfaceRole*)parent->m_role.get())->m_subsurface.lock();
|
||||||
|
parent = subsurface->t1Parent();
|
||||||
|
}
|
||||||
|
WP<CMonitor> monitor;
|
||||||
|
if (parent->m_enteredOutputs.size() == 1)
|
||||||
|
monitor = parent->m_enteredOutputs[0];
|
||||||
|
else if (m_hlSurface.valid() && m_hlSurface->getWindow())
|
||||||
|
monitor = m_hlSurface->getWindow()->m_monitor;
|
||||||
|
|
||||||
|
return monitor ? monitor->m_imageDescription : g_pCompositor->getPreferredImageDescription();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CWLSurfaceResource::updateCursorShm(CRegion damage) {
|
void CWLSurfaceResource::updateCursorShm(CRegion damage) {
|
||||||
|
@@ -87,6 +87,8 @@ class CWLSurfaceResource {
|
|||||||
CSignalT<> unmap;
|
CSignalT<> unmap;
|
||||||
CSignalT<SP<CWLSubsurfaceResource>> newSubsurface;
|
CSignalT<SP<CWLSubsurfaceResource>> newSubsurface;
|
||||||
CSignalT<> destroy;
|
CSignalT<> destroy;
|
||||||
|
CSignalT<SP<CMonitor>> enter;
|
||||||
|
CSignalT<SP<CMonitor>> leave;
|
||||||
} m_events;
|
} m_events;
|
||||||
|
|
||||||
SSurfaceState m_current;
|
SSurfaceState m_current;
|
||||||
|
Reference in New Issue
Block a user