color-management: add more capabilities
This commit is contained in:
parent
e92de36f7a
commit
8f992f7cef
13 changed files with 293 additions and 97 deletions
|
|
@ -560,6 +560,10 @@ impl MetalConnector {
|
|||
}
|
||||
return None;
|
||||
};
|
||||
if ct.cd.id != self.state.color_manager.srgb_srgb().id {
|
||||
// Direct scanout requires identical color descriptions.
|
||||
return None;
|
||||
}
|
||||
if ct.alpha.is_some() {
|
||||
// Direct scanout with alpha factor is not supported.
|
||||
return None;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,6 @@ impl Luminance {
|
|||
white: F64(80.0),
|
||||
};
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub const BT1886: Self = Self {
|
||||
min: F64(0.01),
|
||||
max: F64(100.0),
|
||||
|
|
|
|||
|
|
@ -100,12 +100,10 @@ impl ColorManager {
|
|||
&self.srgb_linear
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub fn windows_scrgb(&self) -> &Rc<ColorDescription> {
|
||||
&self.windows_scrgb
|
||||
}
|
||||
|
||||
#[expect(dead_code)]
|
||||
pub fn get_description(
|
||||
self: &Rc<Self>,
|
||||
named_primaries: Option<NamedPrimaries>,
|
||||
|
|
|
|||
|
|
@ -3,23 +3,14 @@ use {crate::utils::ordered_float::F64, std::hash::Hash};
|
|||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum NamedPrimaries {
|
||||
Srgb,
|
||||
#[expect(dead_code)]
|
||||
PalM,
|
||||
#[expect(dead_code)]
|
||||
Pal,
|
||||
#[expect(dead_code)]
|
||||
Ntsc,
|
||||
#[expect(dead_code)]
|
||||
GenericFilm,
|
||||
#[expect(dead_code)]
|
||||
Bt2020,
|
||||
#[expect(dead_code)]
|
||||
Cie1931Xyz,
|
||||
#[expect(dead_code)]
|
||||
DciP3,
|
||||
#[expect(dead_code)]
|
||||
DisplayP3,
|
||||
#[expect(dead_code)]
|
||||
AdobeRgb,
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +94,6 @@ impl Primaries {
|
|||
};
|
||||
}
|
||||
impl NamedPrimaries {
|
||||
#[expect(dead_code)]
|
||||
pub const fn primaries(self) -> Primaries {
|
||||
match self {
|
||||
NamedPrimaries::Srgb => Primaries::SRGB,
|
||||
|
|
|
|||
|
|
@ -1,56 +1,63 @@
|
|||
pub use consts::*;
|
||||
|
||||
pub mod wp_color_management_output_v1;
|
||||
pub mod wp_color_management_surface_feedback_v1;
|
||||
pub mod wp_color_management_surface_v1;
|
||||
pub mod wp_color_manager_v1;
|
||||
pub mod wp_image_description_creator_icc_v1;
|
||||
pub mod wp_image_description_creator_params_v1;
|
||||
pub mod wp_image_description_info_v1;
|
||||
pub mod wp_image_description_v1;
|
||||
|
||||
const PRIMARIES_MUL: f64 = 1_000_000.0;
|
||||
const PRIMARIES_MUL_INV: f64 = 1.0 / PRIMARIES_MUL;
|
||||
|
||||
const MIN_LUM_MUL: f64 = 10_000.0;
|
||||
const MIN_LUM_MUL_INV: f64 = 1.0 / MIN_LUM_MUL;
|
||||
|
||||
#[expect(dead_code)]
|
||||
mod consts {
|
||||
pub(super) const RENDER_INTENT_PERCEPTUAL: u32 = 0;
|
||||
pub(super) const RENDER_INTENT_RELATIVE: u32 = 1;
|
||||
pub(super) const RENDER_INTENT_SATURATION: u32 = 2;
|
||||
pub(super) const RENDER_INTENT_ABSOLUTE: u32 = 3;
|
||||
pub(super) const RENDER_INTENT_RELATIVE_BPC: u32 = 4;
|
||||
pub const RENDER_INTENT_PERCEPTUAL: u32 = 0;
|
||||
pub const RENDER_INTENT_RELATIVE: u32 = 1;
|
||||
pub const RENDER_INTENT_SATURATION: u32 = 2;
|
||||
pub const RENDER_INTENT_ABSOLUTE: u32 = 3;
|
||||
pub const RENDER_INTENT_RELATIVE_BPC: u32 = 4;
|
||||
|
||||
pub(super) const FEATURE_ICC_V2_V4: u32 = 0;
|
||||
pub(super) const FEATURE_PARAMETRIC: u32 = 1;
|
||||
pub(super) const FEATURE_SET_PRIMARIES: u32 = 2;
|
||||
pub(super) const FEATURE_SET_TF_POWER: u32 = 3;
|
||||
pub(super) const FEATURE_SET_LUMINANCES: u32 = 4;
|
||||
pub(super) const FEATURE_SET_MASTERING_DISPLAY_PRIMARIES: u32 = 5;
|
||||
pub(super) const FEATURE_EXTENDED_TARGET_VOLUME: u32 = 6;
|
||||
pub(super) const FEATURE_WINDOWS_SCRGB: u32 = 7;
|
||||
pub const FEATURE_ICC_V2_V4: u32 = 0;
|
||||
pub const FEATURE_PARAMETRIC: u32 = 1;
|
||||
pub const FEATURE_SET_PRIMARIES: u32 = 2;
|
||||
pub const FEATURE_SET_TF_POWER: u32 = 3;
|
||||
pub const FEATURE_SET_LUMINANCES: u32 = 4;
|
||||
pub const FEATURE_SET_MASTERING_DISPLAY_PRIMARIES: u32 = 5;
|
||||
pub const FEATURE_EXTENDED_TARGET_VOLUME: u32 = 6;
|
||||
pub const FEATURE_WINDOWS_SCRGB: u32 = 7;
|
||||
|
||||
pub(super) const PRIMARIES_SRGB: u32 = 1;
|
||||
pub(super) const PRIMARIES_PAL_M: u32 = 2;
|
||||
pub(super) const PRIMARIES_PAL: u32 = 3;
|
||||
pub(super) const PRIMARIES_NTSC: u32 = 4;
|
||||
pub(super) const PRIMARIES_GENERIC_FILM: u32 = 5;
|
||||
pub(super) const PRIMARIES_BT2020: u32 = 6;
|
||||
pub(super) const PRIMARIES_CIE1931_XYZ: u32 = 7;
|
||||
pub(super) const PRIMARIES_DCI_P3: u32 = 8;
|
||||
pub(super) const PRIMARIES_DISPLAY_P3: u32 = 9;
|
||||
pub(super) const PRIMARIES_ADOBE_RGB: u32 = 10;
|
||||
pub const PRIMARIES_SRGB: u32 = 1;
|
||||
pub const PRIMARIES_PAL_M: u32 = 2;
|
||||
pub const PRIMARIES_PAL: u32 = 3;
|
||||
pub const PRIMARIES_NTSC: u32 = 4;
|
||||
pub const PRIMARIES_GENERIC_FILM: u32 = 5;
|
||||
pub const PRIMARIES_BT2020: u32 = 6;
|
||||
pub const PRIMARIES_CIE1931_XYZ: u32 = 7;
|
||||
pub const PRIMARIES_DCI_P3: u32 = 8;
|
||||
pub const PRIMARIES_DISPLAY_P3: u32 = 9;
|
||||
pub const PRIMARIES_ADOBE_RGB: u32 = 10;
|
||||
|
||||
pub(super) const TRANSFER_FUNCTION_BT1886: u32 = 1;
|
||||
pub(super) const TRANSFER_FUNCTION_GAMMA22: u32 = 2;
|
||||
pub(super) const TRANSFER_FUNCTION_GAMMA28: u32 = 3;
|
||||
pub(super) const TRANSFER_FUNCTION_ST240: u32 = 4;
|
||||
pub(super) const TRANSFER_FUNCTION_EXT_LINEAR: u32 = 5;
|
||||
pub(super) const TRANSFER_FUNCTION_LOG_100: u32 = 6;
|
||||
pub(super) const TRANSFER_FUNCTION_LOG_316: u32 = 7;
|
||||
pub(super) const TRANSFER_FUNCTION_XVYCC: u32 = 8;
|
||||
pub(super) const TRANSFER_FUNCTION_SRGB: u32 = 9;
|
||||
pub(super) const TRANSFER_FUNCTION_EXT_SRGB: u32 = 10;
|
||||
pub(super) const TRANSFER_FUNCTION_ST2084_PQ: u32 = 11;
|
||||
pub(super) const TRANSFER_FUNCTION_ST428: u32 = 12;
|
||||
pub(super) const TRANSFER_FUNCTION_HLG: u32 = 13;
|
||||
pub const TRANSFER_FUNCTION_BT1886: u32 = 1;
|
||||
pub const TRANSFER_FUNCTION_GAMMA22: u32 = 2;
|
||||
pub const TRANSFER_FUNCTION_GAMMA28: u32 = 3;
|
||||
pub const TRANSFER_FUNCTION_ST240: u32 = 4;
|
||||
pub const TRANSFER_FUNCTION_EXT_LINEAR: u32 = 5;
|
||||
pub const TRANSFER_FUNCTION_LOG_100: u32 = 6;
|
||||
pub const TRANSFER_FUNCTION_LOG_316: u32 = 7;
|
||||
pub const TRANSFER_FUNCTION_XVYCC: u32 = 8;
|
||||
pub const TRANSFER_FUNCTION_SRGB: u32 = 9;
|
||||
pub const TRANSFER_FUNCTION_EXT_SRGB: u32 = 10;
|
||||
pub const TRANSFER_FUNCTION_ST2084_PQ: u32 = 11;
|
||||
pub const TRANSFER_FUNCTION_ST428: u32 = 12;
|
||||
pub const TRANSFER_FUNCTION_HLG: u32 = 13;
|
||||
|
||||
pub(super) const CAUSE_LOW_VERSION: u32 = 0;
|
||||
pub(super) const CAUSE_UNSUPPORTED: u32 = 1;
|
||||
pub(super) const CAUSE_OPERATING_SYSTEM: u32 = 2;
|
||||
pub(super) const CAUSE_NO_OUTPUT: u32 = 3;
|
||||
pub const CAUSE_LOW_VERSION: u32 = 0;
|
||||
pub const CAUSE_UNSUPPORTED: u32 = 1;
|
||||
pub const CAUSE_OPERATING_SYSTEM: u32 = 2;
|
||||
pub const CAUSE_NO_OUTPUT: u32 = 3;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,10 +43,11 @@ impl WpColorManagementOutputV1RequestHandler for WpColorManagementOutputV1 {
|
|||
client: self.client.clone(),
|
||||
version: self.version,
|
||||
tracker: Default::default(),
|
||||
description: self.client.state.color_manager.srgb_srgb().clone(),
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
obj.send_ready(0);
|
||||
obj.send_ready();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ impl WpColorManagementSurfaceFeedbackV1 {
|
|||
client: self.client.clone(),
|
||||
version: self.version,
|
||||
tracker: Default::default(),
|
||||
description: self.client.state.color_manager.srgb_srgb().clone(),
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
obj.send_ready(0);
|
||||
obj.send_ready();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,15 +2,27 @@ use {
|
|||
crate::{
|
||||
client::{Client, ClientError},
|
||||
globals::{Global, GlobalName},
|
||||
ifs::color_management::{
|
||||
consts::{
|
||||
FEATURE_PARAMETRIC, PRIMARIES_SRGB, RENDER_INTENT_PERCEPTUAL,
|
||||
TRANSFER_FUNCTION_SRGB,
|
||||
ifs::{
|
||||
color_management::{
|
||||
consts::{
|
||||
FEATURE_PARAMETRIC, FEATURE_SET_LUMINANCES, FEATURE_SET_PRIMARIES,
|
||||
FEATURE_WINDOWS_SCRGB, PRIMARIES_ADOBE_RGB, PRIMARIES_BT2020,
|
||||
PRIMARIES_CIE1931_XYZ, PRIMARIES_DCI_P3, PRIMARIES_DISPLAY_P3,
|
||||
PRIMARIES_GENERIC_FILM, PRIMARIES_NTSC, PRIMARIES_PAL, PRIMARIES_PAL_M,
|
||||
PRIMARIES_SRGB, RENDER_INTENT_PERCEPTUAL, TRANSFER_FUNCTION_BT1886,
|
||||
TRANSFER_FUNCTION_EXT_LINEAR, TRANSFER_FUNCTION_EXT_SRGB,
|
||||
TRANSFER_FUNCTION_GAMMA22, TRANSFER_FUNCTION_GAMMA28,
|
||||
TRANSFER_FUNCTION_LOG_100, TRANSFER_FUNCTION_LOG_316, TRANSFER_FUNCTION_SRGB,
|
||||
TRANSFER_FUNCTION_ST240, TRANSFER_FUNCTION_ST428, TRANSFER_FUNCTION_ST2084_PQ,
|
||||
},
|
||||
wp_color_management_output_v1::WpColorManagementOutputV1,
|
||||
wp_color_management_surface_feedback_v1::WpColorManagementSurfaceFeedbackV1,
|
||||
wp_image_description_creator_params_v1::WpImageDescriptionCreatorParamsV1,
|
||||
wp_image_description_v1::WpImageDescriptionV1,
|
||||
},
|
||||
wl_surface::wp_color_management_surface_v1::{
|
||||
WpColorManagementSurfaceV1, WpColorManagementSurfaceV1Error,
|
||||
},
|
||||
wp_color_management_output_v1::WpColorManagementOutputV1,
|
||||
wp_color_management_surface_feedback_v1::WpColorManagementSurfaceFeedbackV1,
|
||||
wp_color_management_surface_v1::WpColorManagementSurfaceV1,
|
||||
wp_image_description_creator_params_v1::WpImageDescriptionCreatorParamsV1,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
|
|
@ -63,8 +75,30 @@ impl WpColorManagerV1 {
|
|||
fn send_capabilities(&self) {
|
||||
self.send_supported_intent(RENDER_INTENT_PERCEPTUAL);
|
||||
self.send_supported_feature(FEATURE_PARAMETRIC);
|
||||
self.send_supported_feature(FEATURE_SET_PRIMARIES);
|
||||
self.send_supported_feature(FEATURE_SET_LUMINANCES);
|
||||
self.send_supported_feature(FEATURE_WINDOWS_SCRGB);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_BT1886);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_GAMMA22);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_GAMMA28);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_ST240);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_EXT_LINEAR);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_LOG_100);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_LOG_316);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_SRGB);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_EXT_SRGB);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_ST2084_PQ);
|
||||
self.send_supported_tf_named(TRANSFER_FUNCTION_ST428);
|
||||
self.send_supported_primaries_named(PRIMARIES_SRGB);
|
||||
self.send_supported_primaries_named(PRIMARIES_PAL_M);
|
||||
self.send_supported_primaries_named(PRIMARIES_PAL);
|
||||
self.send_supported_primaries_named(PRIMARIES_NTSC);
|
||||
self.send_supported_primaries_named(PRIMARIES_GENERIC_FILM);
|
||||
self.send_supported_primaries_named(PRIMARIES_BT2020);
|
||||
self.send_supported_primaries_named(PRIMARIES_CIE1931_XYZ);
|
||||
self.send_supported_primaries_named(PRIMARIES_DCI_P3);
|
||||
self.send_supported_primaries_named(PRIMARIES_DISPLAY_P3);
|
||||
self.send_supported_primaries_named(PRIMARIES_ADOBE_RGB);
|
||||
self.send_done();
|
||||
}
|
||||
|
||||
|
|
@ -123,15 +157,17 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
|
|||
}
|
||||
|
||||
fn get_surface(&self, req: GetSurface, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let _ = self.client.lookup(req.surface)?;
|
||||
let surface = self.client.lookup(req.surface)?;
|
||||
let obj = Rc::new(WpColorManagementSurfaceV1 {
|
||||
id: req.id,
|
||||
client: self.client.clone(),
|
||||
version: self.version,
|
||||
tracker: Default::default(),
|
||||
surface: surface.clone(),
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
obj.install()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +206,9 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
|
|||
client: self.client.clone(),
|
||||
version: self.version,
|
||||
tracker: Default::default(),
|
||||
tf: Default::default(),
|
||||
primaries: Default::default(),
|
||||
luminance: Default::default(),
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
|
|
@ -178,10 +217,20 @@ impl WpColorManagerV1RequestHandler for WpColorManagerV1 {
|
|||
|
||||
fn create_windows_scrgb(
|
||||
&self,
|
||||
_req: CreateWindowsScrgb,
|
||||
req: CreateWindowsScrgb,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
Err(WpColorManagerV1Error::CreateWindowsScrgbNotSupported)
|
||||
let obj = Rc::new(WpImageDescriptionV1 {
|
||||
id: req.image_description,
|
||||
client: self.client.clone(),
|
||||
version: self.version,
|
||||
tracker: Default::default(),
|
||||
description: self.client.state.color_manager.windows_scrgb().clone(),
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
obj.send_ready();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +271,7 @@ pub enum WpColorManagerV1Error {
|
|||
ClientError(Box<ClientError>),
|
||||
#[error("create_icc_creator is not supported")]
|
||||
CreateIccCreatorNotSupported,
|
||||
#[error("create_windows_scrgb is not supported")]
|
||||
CreateWindowsScrgbNotSupported,
|
||||
#[error(transparent)]
|
||||
Surface(#[from] WpColorManagementSurfaceV1Error),
|
||||
}
|
||||
efrom!(WpColorManagerV1Error, ClientError);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,27 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
cmm::{
|
||||
cmm_luminance::Luminance,
|
||||
cmm_primaries::{NamedPrimaries, Primaries},
|
||||
cmm_transfer_function::TransferFunction,
|
||||
},
|
||||
ifs::color_management::{
|
||||
consts::{PRIMARIES_SRGB, TRANSFER_FUNCTION_SRGB},
|
||||
MIN_LUM_MUL_INV, PRIMARIES_MUL_INV,
|
||||
consts::{
|
||||
PRIMARIES_ADOBE_RGB, PRIMARIES_BT2020, PRIMARIES_CIE1931_XYZ, PRIMARIES_DCI_P3,
|
||||
PRIMARIES_DISPLAY_P3, PRIMARIES_GENERIC_FILM, PRIMARIES_NTSC, PRIMARIES_PAL,
|
||||
PRIMARIES_PAL_M, PRIMARIES_SRGB, TRANSFER_FUNCTION_BT1886,
|
||||
TRANSFER_FUNCTION_EXT_LINEAR, TRANSFER_FUNCTION_EXT_SRGB,
|
||||
TRANSFER_FUNCTION_GAMMA22, TRANSFER_FUNCTION_GAMMA28, TRANSFER_FUNCTION_LOG_100,
|
||||
TRANSFER_FUNCTION_LOG_316, TRANSFER_FUNCTION_SRGB, TRANSFER_FUNCTION_ST240,
|
||||
TRANSFER_FUNCTION_ST428, TRANSFER_FUNCTION_ST2084_PQ,
|
||||
},
|
||||
wp_image_description_v1::WpImageDescriptionV1,
|
||||
},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
utils::ordered_float::F64,
|
||||
wire::{
|
||||
WpImageDescriptionCreatorParamsV1Id,
|
||||
wp_image_description_creator_params_v1::{
|
||||
|
|
@ -16,7 +31,7 @@ use {
|
|||
},
|
||||
},
|
||||
},
|
||||
std::rc::Rc,
|
||||
std::{cell::Cell, rc::Rc},
|
||||
thiserror::Error,
|
||||
};
|
||||
|
||||
|
|
@ -25,30 +40,74 @@ pub struct WpImageDescriptionCreatorParamsV1 {
|
|||
pub client: Rc<Client>,
|
||||
pub version: Version,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub tf: Cell<Option<TransferFunction>>,
|
||||
pub primaries: Cell<Option<(Option<NamedPrimaries>, Primaries)>>,
|
||||
pub luminance: Cell<Option<Luminance>>,
|
||||
}
|
||||
|
||||
impl WpImageDescriptionCreatorParamsV1RequestHandler for WpImageDescriptionCreatorParamsV1 {
|
||||
type Error = WpImageDescriptionCreatorParamsV1Error;
|
||||
|
||||
fn create(&self, req: Create, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let Some(transfer_function) = self.tf.get() else {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::TfNotSet);
|
||||
};
|
||||
let Some((named_primaries, primaries)) = self.primaries.get() else {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::PrimariesNotSet);
|
||||
};
|
||||
let default_luminance = match transfer_function {
|
||||
TransferFunction::Bt1886 => Luminance::BT1886,
|
||||
TransferFunction::St2084Pq => Luminance::ST2084_PQ,
|
||||
_ => Luminance::SRGB,
|
||||
};
|
||||
let mut luminance = self.luminance.get().unwrap_or(default_luminance);
|
||||
if transfer_function == TransferFunction::St2084Pq {
|
||||
luminance.max.0 = luminance.min.0 + 10_000.0;
|
||||
}
|
||||
if luminance.max.0 <= luminance.min.0 || luminance.white.0 <= luminance.min.0 {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::MinLuminanceTooLow);
|
||||
}
|
||||
let description = self.client.state.color_manager.get_description(
|
||||
named_primaries,
|
||||
primaries,
|
||||
luminance,
|
||||
transfer_function,
|
||||
);
|
||||
let obj = Rc::new(WpImageDescriptionV1 {
|
||||
id: req.image_description,
|
||||
client: self.client.clone(),
|
||||
version: self.version,
|
||||
tracker: Default::default(),
|
||||
description,
|
||||
});
|
||||
track!(self.client, obj);
|
||||
self.client.add_client_obj(&obj)?;
|
||||
obj.send_ready(0);
|
||||
obj.send_ready();
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_tf_named(&self, req: SetTfNamed, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
if req.tf != TRANSFER_FUNCTION_SRGB {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::UnsupportedTf(
|
||||
req.tf,
|
||||
));
|
||||
let tf = match req.tf {
|
||||
TRANSFER_FUNCTION_BT1886 => TransferFunction::Bt1886,
|
||||
TRANSFER_FUNCTION_GAMMA22 => TransferFunction::Gamma22,
|
||||
TRANSFER_FUNCTION_GAMMA28 => TransferFunction::Gamma28,
|
||||
TRANSFER_FUNCTION_ST240 => TransferFunction::St240,
|
||||
TRANSFER_FUNCTION_EXT_LINEAR => TransferFunction::Linear,
|
||||
TRANSFER_FUNCTION_LOG_100 => TransferFunction::Log100,
|
||||
TRANSFER_FUNCTION_LOG_316 => TransferFunction::Log316,
|
||||
TRANSFER_FUNCTION_SRGB => TransferFunction::Srgb,
|
||||
TRANSFER_FUNCTION_EXT_SRGB => TransferFunction::ExtSrgb,
|
||||
TRANSFER_FUNCTION_ST2084_PQ => TransferFunction::St2084Pq,
|
||||
TRANSFER_FUNCTION_ST428 => TransferFunction::St428,
|
||||
_ => {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::UnsupportedTf(
|
||||
req.tf,
|
||||
));
|
||||
}
|
||||
};
|
||||
if self.tf.replace(Some(tf)).is_some() {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::TfAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -62,20 +121,55 @@ impl WpImageDescriptionCreatorParamsV1RequestHandler for WpImageDescriptionCreat
|
|||
req: SetPrimariesNamed,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
if req.primaries != PRIMARIES_SRGB {
|
||||
return Err(
|
||||
WpImageDescriptionCreatorParamsV1Error::UnsupportedPrimaries(req.primaries),
|
||||
);
|
||||
let primaries = match req.primaries {
|
||||
PRIMARIES_SRGB => NamedPrimaries::Srgb,
|
||||
PRIMARIES_PAL_M => NamedPrimaries::PalM,
|
||||
PRIMARIES_PAL => NamedPrimaries::Pal,
|
||||
PRIMARIES_NTSC => NamedPrimaries::Ntsc,
|
||||
PRIMARIES_GENERIC_FILM => NamedPrimaries::GenericFilm,
|
||||
PRIMARIES_BT2020 => NamedPrimaries::Bt2020,
|
||||
PRIMARIES_CIE1931_XYZ => NamedPrimaries::Cie1931Xyz,
|
||||
PRIMARIES_DCI_P3 => NamedPrimaries::DciP3,
|
||||
PRIMARIES_DISPLAY_P3 => NamedPrimaries::DisplayP3,
|
||||
PRIMARIES_ADOBE_RGB => NamedPrimaries::AdobeRgb,
|
||||
_ => {
|
||||
return Err(
|
||||
WpImageDescriptionCreatorParamsV1Error::UnsupportedPrimaries(req.primaries),
|
||||
);
|
||||
}
|
||||
};
|
||||
let primaries = (Some(primaries), primaries.primaries());
|
||||
if self.primaries.replace(Some(primaries)).is_some() {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::PrimariesAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_primaries(&self, _req: SetPrimaries, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
Err(WpImageDescriptionCreatorParamsV1Error::SetPrimariesNotSupported)
|
||||
fn set_primaries(&self, req: SetPrimaries, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let map = |n: i32| F64(n as f64 * PRIMARIES_MUL_INV);
|
||||
let primaries = Primaries {
|
||||
r: (map(req.r_x), map(req.r_y)),
|
||||
g: (map(req.g_x), map(req.g_y)),
|
||||
b: (map(req.b_x), map(req.b_y)),
|
||||
wp: (map(req.w_x), map(req.w_y)),
|
||||
};
|
||||
let primaries = (None, primaries);
|
||||
if self.primaries.replace(Some(primaries)).is_some() {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::PrimariesAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_luminances(&self, _req: SetLuminances, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
Err(WpImageDescriptionCreatorParamsV1Error::SetLuminancesNotSupported)
|
||||
fn set_luminances(&self, req: SetLuminances, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
let luminance = Luminance {
|
||||
min: F64(req.min_lum as f64 * MIN_LUM_MUL_INV),
|
||||
max: F64(req.max_lum as f64),
|
||||
white: F64(req.reference_lum as f64),
|
||||
};
|
||||
if self.luminance.replace(Some(luminance)).is_some() {
|
||||
return Err(WpImageDescriptionCreatorParamsV1Error::LuminancesAlreadySet);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_mastering_display_primaries(
|
||||
|
|
@ -120,15 +214,23 @@ pub enum WpImageDescriptionCreatorParamsV1Error {
|
|||
SetMasteringLuminanceNotSupported,
|
||||
#[error("set_mastering_display_primaries is not supported")]
|
||||
SetMasteringDisplayPrimariesNotSupported,
|
||||
#[error("set_luminances is not supported")]
|
||||
SetLuminancesNotSupported,
|
||||
#[error("set_primaries is not supported")]
|
||||
SetPrimariesNotSupported,
|
||||
#[error("{} is not a supported named primary", .0)]
|
||||
UnsupportedPrimaries(u32),
|
||||
#[error("set_tf_power is not supported")]
|
||||
SetTfPowerNotSupported,
|
||||
#[error("{} is not a supported named transfer function", .0)]
|
||||
UnsupportedTf(u32),
|
||||
#[error("The transfer function has already been set")]
|
||||
TfAlreadySet,
|
||||
#[error("The primaries have already been set")]
|
||||
PrimariesAlreadySet,
|
||||
#[error("The luminances have already been set")]
|
||||
LuminancesAlreadySet,
|
||||
#[error("The minimum luminance is too low")]
|
||||
MinLuminanceTooLow,
|
||||
#[error("The transfer function was not set")]
|
||||
TfNotSet,
|
||||
#[error("The primaries were not set")]
|
||||
PrimariesNotSet,
|
||||
}
|
||||
efrom!(WpImageDescriptionCreatorParamsV1Error, ClientError);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
cmm::cmm_description::ColorDescription,
|
||||
ifs::color_management::wp_image_description_info_v1::WpImageDescriptionInfoV1,
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
|
|
@ -15,6 +16,7 @@ pub struct WpImageDescriptionV1 {
|
|||
pub client: Rc<Client>,
|
||||
pub version: Version,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub description: Rc<ColorDescription>,
|
||||
}
|
||||
|
||||
impl WpImageDescriptionV1 {
|
||||
|
|
@ -27,10 +29,10 @@ impl WpImageDescriptionV1 {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn send_ready(&self, identity: u32) {
|
||||
pub fn send_ready(&self) {
|
||||
self.client.event(Ready {
|
||||
self_id: self.id,
|
||||
identity,
|
||||
identity: self.description.id.into(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ pub mod ext_session_lock_surface_v1;
|
|||
pub mod tray;
|
||||
pub mod wl_subsurface;
|
||||
pub mod wp_alpha_modifier_surface_v1;
|
||||
pub mod wp_color_management_surface_v1;
|
||||
pub mod wp_commit_timer_v1;
|
||||
pub mod wp_fifo_v1;
|
||||
pub mod wp_fractional_scale_v1;
|
||||
|
|
@ -22,6 +23,7 @@ use {
|
|||
crate::{
|
||||
backend::KeyState,
|
||||
client::{Client, ClientError},
|
||||
cmm::cmm_description::ColorDescription,
|
||||
cursor_user::{CursorUser, CursorUserId},
|
||||
damage::DamageMatrix,
|
||||
drm_feedback::DrmFeedback,
|
||||
|
|
@ -104,6 +106,7 @@ use {
|
|||
rc::{Rc, Weak},
|
||||
},
|
||||
thiserror::Error,
|
||||
wp_color_management_surface_v1::WpColorManagementSurfaceV1,
|
||||
zwp_idle_inhibitor_v1::ZwpIdleInhibitorV1,
|
||||
};
|
||||
|
||||
|
|
@ -332,6 +335,8 @@ pub struct WlSurface {
|
|||
commit_timer: CloneCell<Option<Rc<WpCommitTimerV1>>>,
|
||||
before_latch_listener: EventListener<dyn BeforeLatchListener>,
|
||||
is_opaque: Cell<bool>,
|
||||
color_management_surface: CloneCell<Option<Rc<WpColorManagementSurfaceV1>>>,
|
||||
color_description: CloneCell<Option<Rc<ColorDescription>>>,
|
||||
}
|
||||
|
||||
impl Debug for WlSurface {
|
||||
|
|
@ -461,6 +466,7 @@ struct PendingState {
|
|||
fifo_barrier_wait: bool,
|
||||
commit_time: Option<u64>,
|
||||
tray_item_ack_serial: Option<u32>,
|
||||
color_description: Option<Option<Rc<ColorDescription>>>,
|
||||
}
|
||||
|
||||
struct AttachedSubsurfaceState {
|
||||
|
|
@ -513,6 +519,7 @@ impl PendingState {
|
|||
opt!(alpha_multiplier);
|
||||
opt!(commit_time);
|
||||
opt!(tray_item_ack_serial);
|
||||
opt!(color_description);
|
||||
{
|
||||
let (dx1, dy1) = self.offset;
|
||||
let (dx2, dy2) = mem::take(&mut next.offset);
|
||||
|
|
@ -670,6 +677,8 @@ impl WlSurface {
|
|||
commit_timer: Default::default(),
|
||||
before_latch_listener: EventListener::new(slf.clone()),
|
||||
is_opaque: Cell::new(false),
|
||||
color_management_surface: Default::default(),
|
||||
color_description: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1137,6 +1146,11 @@ impl WlSurface {
|
|||
}
|
||||
}
|
||||
}
|
||||
let mut color_description_changed = false;
|
||||
if let Some(desc) = pending.color_description.take() {
|
||||
color_description_changed = true;
|
||||
self.color_description.set(desc);
|
||||
}
|
||||
let mut alpha_changed = false;
|
||||
if let Some(alpha) = pending.alpha_multiplier.take() {
|
||||
alpha_changed = true;
|
||||
|
|
@ -1144,8 +1158,11 @@ impl WlSurface {
|
|||
}
|
||||
let buffer_abs_pos = self.buffer_abs_pos.get();
|
||||
let mut max_surface_size = buffer_abs_pos.size();
|
||||
let mut damage_full =
|
||||
scale_changed || buffer_transform_changed || viewport_changed || alpha_changed;
|
||||
let mut damage_full = scale_changed
|
||||
|| buffer_transform_changed
|
||||
|| viewport_changed
|
||||
|| alpha_changed
|
||||
|| color_description_changed;
|
||||
let mut buffer_changed = false;
|
||||
let mut old_raw_size = None;
|
||||
let (mut dx, mut dy) = mem::take(&mut pending.offset);
|
||||
|
|
@ -1658,6 +1675,13 @@ impl WlSurface {
|
|||
pub fn opaque_region(&self) -> Option<Rc<Region>> {
|
||||
self.opaque_region.get()
|
||||
}
|
||||
|
||||
pub fn color_description(&self) -> Rc<ColorDescription> {
|
||||
match self.color_description.get() {
|
||||
Some(cd) => cd,
|
||||
None => self.client.state.color_manager.srgb_srgb().clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
|
|
@ -1689,6 +1713,7 @@ impl Object for WlSurface {
|
|||
self.text_input_connections.clear();
|
||||
self.fifo.take();
|
||||
self.commit_timer.take();
|
||||
self.color_management_surface.take();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
crate::{
|
||||
client::{Client, ClientError},
|
||||
ifs::color_management::consts::RENDER_INTENT_PERCEPTUAL,
|
||||
ifs::{color_management, wl_surface::WlSurface},
|
||||
leaks::Tracker,
|
||||
object::{Object, Version},
|
||||
wire::{
|
||||
|
|
@ -21,12 +21,26 @@ pub struct WpColorManagementSurfaceV1 {
|
|||
pub client: Rc<Client>,
|
||||
pub version: Version,
|
||||
pub tracker: Tracker<Self>,
|
||||
pub surface: Rc<WlSurface>,
|
||||
}
|
||||
|
||||
impl WpColorManagementSurfaceV1 {
|
||||
pub fn install(self: &Rc<Self>) -> Result<(), WpColorManagementSurfaceV1Error> {
|
||||
if self.surface.color_management_surface.is_some() {
|
||||
return Err(WpColorManagementSurfaceV1Error::HasSurface);
|
||||
}
|
||||
self.surface
|
||||
.color_management_surface
|
||||
.set(Some(self.clone()));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl WpColorManagementSurfaceV1RequestHandler for WpColorManagementSurfaceV1 {
|
||||
type Error = WpColorManagementSurfaceV1Error;
|
||||
|
||||
fn destroy(&self, _req: Destroy, _slf: &Rc<Self>) -> Result<(), Self::Error> {
|
||||
self.surface.color_management_surface.take();
|
||||
self.client.remove_obj(self)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -36,12 +50,13 @@ impl WpColorManagementSurfaceV1RequestHandler for WpColorManagementSurfaceV1 {
|
|||
req: SetImageDescription,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let _ = self.client.lookup(req.image_description)?;
|
||||
if req.render_intent != RENDER_INTENT_PERCEPTUAL {
|
||||
if req.render_intent != color_management::RENDER_INTENT_PERCEPTUAL {
|
||||
return Err(WpColorManagementSurfaceV1Error::UnsupportedRenderIntent(
|
||||
req.render_intent,
|
||||
));
|
||||
}
|
||||
let desc = self.client.lookup(req.image_description)?;
|
||||
self.surface.pending.borrow_mut().color_description = Some(Some(desc.description.clone()));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +65,7 @@ impl WpColorManagementSurfaceV1RequestHandler for WpColorManagementSurfaceV1 {
|
|||
_req: UnsetImageDescription,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
self.surface.pending.borrow_mut().color_description = Some(None);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -69,5 +85,7 @@ pub enum WpColorManagementSurfaceV1Error {
|
|||
ClientError(Box<ClientError>),
|
||||
#[error("{} is not a supported render intent", .0)]
|
||||
UnsupportedRenderIntent(u32),
|
||||
#[error("wl_surface already has a color-management extension")]
|
||||
HasSurface,
|
||||
}
|
||||
efrom!(WpColorManagementSurfaceV1Error, ClientError);
|
||||
|
|
@ -444,7 +444,7 @@ impl Renderer<'_> {
|
|||
bounds: Option<&Rect>,
|
||||
) {
|
||||
let alpha = surface.alpha();
|
||||
let cd = self.state.color_manager.srgb_srgb();
|
||||
let cd = surface.color_description();
|
||||
if let Some(tex) = buffer.buffer.get_texture(surface) {
|
||||
let mut opaque = surface.opaque();
|
||||
if !opaque && tex.format().has_alpha {
|
||||
|
|
@ -463,7 +463,7 @@ impl Renderer<'_> {
|
|||
AcquireSync::Unnecessary,
|
||||
buffer.release_sync,
|
||||
opaque,
|
||||
cd,
|
||||
&cd,
|
||||
);
|
||||
} else if let Some(color) = &buffer.buffer.color {
|
||||
if let Some(rect) = Rect::new_sized(x, y, tsize.0, tsize.1) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue