1
0
Fork 0
forked from wry/wry

cmm: store render intent

This commit is contained in:
Julian Orth 2026-03-29 15:34:53 +02:00
parent a4928d8ed6
commit dca0df2555
16 changed files with 207 additions and 60 deletions

View file

@ -3,6 +3,7 @@ pub mod cmm_eotf;
pub mod cmm_luminance;
pub mod cmm_manager;
pub mod cmm_primaries;
pub mod cmm_render_intent;
#[cfg(test)]
mod cmm_tests;
pub mod cmm_transform;

View file

@ -5,6 +5,7 @@ use {
cmm_luminance::{Luminance, TargetLuminance, white_balance},
cmm_manager::Shared,
cmm_primaries::{NamedPrimaries, Primaries},
cmm_render_intent::RenderIntent,
cmm_transform::{ColorMatrix, Local, Xyz, bradford_adjustment},
},
utils::ordered_float::F64,
@ -39,12 +40,17 @@ pub struct ColorDescription {
}
impl LinearColorDescription {
pub fn color_transform(&self, target: &Self) -> ColorMatrix {
pub fn color_transform(&self, target: &Self, intent: RenderIntent) -> ColorMatrix {
let mut mat = target.local_from_xyz;
if self.luminance != target.luminance {
mat *= white_balance(&self.luminance, &target.luminance, target.primaries.wp);
mat *= white_balance(
&self.luminance,
&target.luminance,
target.primaries.wp,
intent,
);
}
if self.primaries.wp != target.primaries.wp {
if self.primaries.wp != target.primaries.wp && intent.bradford_adjustment() {
mat *= bradford_adjustment(self.primaries.wp, target.primaries.wp);
}
mat * self.xyz_from_local

View file

@ -1,5 +1,8 @@
use crate::{
cmm::cmm_transform::{ColorMatrix, Xyz},
cmm::{
cmm_render_intent::RenderIntent,
cmm_transform::{ColorMatrix, Xyz},
},
utils::ordered_float::F64,
};
@ -68,12 +71,19 @@ impl Default for Luminance {
}
#[expect(non_snake_case)]
pub fn white_balance(from: &Luminance, to: &Luminance, w_to: (F64, F64)) -> ColorMatrix<Xyz, Xyz> {
pub fn white_balance(
from: &Luminance,
to: &Luminance,
w_to: (F64, F64),
intent: RenderIntent,
) -> ColorMatrix<Xyz, Xyz> {
let a = ((from.max - from.min) / (to.max - to.min) * (to.white - to.min)
/ (from.white - from.min))
.0;
// let d = ((from.min - to.min) / (to.max - to.min)).0.max(0.0);
let d = 0.0;
let d = match intent.black_point_compensation() {
true => 0.0,
false => ((from.min - to.min) / (to.max - to.min)).0,
};
let s = a - d;
let (F64(x_to), F64(y_to)) = w_to;
let X_to = x_to / y_to;

View file

@ -0,0 +1,29 @@
use crate::{ifs::color_management::RENDER_INTENT_PERCEPTUAL, object::Version};
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Default)]
pub enum RenderIntent {
#[default]
Perceptual,
}
impl RenderIntent {
pub fn from_wayland(intent: u32, _version: Version) -> Option<Self> {
let res = match intent {
RENDER_INTENT_PERCEPTUAL => Self::Perceptual,
_ => return None,
};
Some(res)
}
pub fn black_point_compensation(self) -> bool {
match self {
RenderIntent::Perceptual => true,
}
}
pub fn bradford_adjustment(self) -> bool {
match self {
RenderIntent::Perceptual => true,
}
}
}

View file

@ -136,7 +136,7 @@ mod matrices {
mod transforms {
use crate::cmm::{
cmm_eotf::Eotf, cmm_luminance::Luminance, cmm_manager::ColorManager,
cmm_primaries::Primaries,
cmm_primaries::Primaries, cmm_render_intent::RenderIntent,
};
fn check(p1: Primaries, p2: Primaries, expected: [[f64; 4]; 3]) {
@ -155,7 +155,9 @@ mod transforms {
};
let d1 = d(p1);
let d2 = d(p2);
let m = d1.linear.color_transform(&d2.linear);
let m = d1
.linear
.color_transform(&d2.linear, RenderIntent::Perceptual);
println!("{:#?}", m);
assert!((m.0[0][0].0 - expected[0][0]).abs() < 0.001);
assert!((m.0[0][1].0 - expected[0][1]).abs() < 0.001);

View file

@ -1,6 +1,7 @@
use {
crate::{
async_engine::AsyncEngine,
cmm::cmm_render_intent::RenderIntent,
fixed::Fixed,
format::ARGB8888,
gfx_api::{AcquireSync, AlphaMode, GfxContext, GfxError, GfxTexture, ReleaseSync},
@ -398,6 +399,7 @@ fn render_img(image: &InstantiatedCursorImage, renderer: &mut Renderer, x: Fixed
ReleaseSync::None,
false,
renderer.state.color_manager.srgb_gamma22(),
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -424,6 +426,7 @@ impl Cursor for StaticCursor {
ReleaseSync::None,
false,
renderer.state.color_manager.srgb_gamma22(),
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -468,6 +471,7 @@ impl Cursor for AnimatedCursor {
ReleaseSync::None,
false,
renderer.state.color_manager.srgb_gamma22(),
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
}

View file

@ -1,7 +1,7 @@
use {
crate::{
async_engine::AsyncEngine,
cmm::cmm_manager::ColorManager,
cmm::{cmm_manager::ColorManager, cmm_render_intent::RenderIntent},
fixed::Fixed,
ifs::wl_output::WlOutputGlobal,
rect::{Rect, Region},
@ -169,7 +169,14 @@ impl DamageVisualizer {
if region.is_not_empty() {
let age = (now - entry.time).as_millis() as u64 as f32 / decay_millis;
let color = base_color * (1.0 - age);
renderer.fill_boxes2(region.rects(), &color, srgb, dx, dy);
renderer.fill_boxes2(
region.rects(),
&color,
srgb,
RenderIntent::Perceptual,
dx,
dy,
);
used = used.union_cow(&region).into_owned();
}
}

View file

@ -1,7 +1,10 @@
use {
crate::{
allocator::Allocator,
cmm::cmm_description::{ColorDescription, LinearColorDescription},
cmm::{
cmm_description::{ColorDescription, LinearColorDescription},
cmm_render_intent::RenderIntent,
},
cpu_worker::CpuWorker,
cursor::Cursor,
damage::DamageVisualizer,
@ -255,6 +258,7 @@ pub struct FillRect {
pub rect: FramebufferRect,
pub color: Color,
pub alpha: Option<f32>,
pub render_intent: RenderIntent,
pub cd: Rc<LinearColorDescription>,
}
@ -277,6 +281,7 @@ pub struct CopyTexture {
pub release_sync: ReleaseSync,
pub alpha: Option<f32>,
pub opaque: bool,
pub render_intent: RenderIntent,
pub cd: Rc<ColorDescription>,
pub alpha_mode: AlphaMode,
}
@ -512,6 +517,7 @@ impl dyn GfxFramebuffer {
release_sync,
false,
texture_cd,
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
let clear = self.format().has_alpha.then_some(&Color::TRANSPARENT);

View file

@ -4,6 +4,7 @@ use {
cmm::{
cmm_description::{ColorDescription, LinearColorDescription, LinearColorDescriptionId},
cmm_eotf::{Eotf, EotfPow, bt1886_eotf_args, bt1886_inv_eotf_args},
cmm_render_intent::RenderIntent,
cmm_transform::ColorMatrix,
},
cpu_worker::PendingJob,
@ -817,9 +818,12 @@ impl VulkanRenderer {
RenderPass::FrameBuffer => fb_cd,
};
let tf = target_cd.eotf;
let color = memory
.color_transforms
.apply_to_color(&fr.cd, target_cd, fr.color);
let color = memory.color_transforms.apply_to_color(
&fr.cd,
target_cd,
fr.render_intent,
fr.color,
);
let color = color.to_array2(tf, fr.alpha);
let source_type = match color[3] < 1.0 {
false => TexSourceType::Opaque,
@ -883,6 +887,7 @@ impl VulkanRenderer {
let color_management_data_address = memory.color_transforms.get_offset(
&ct.cd.linear,
target_cd,
ct.render_intent,
self.device.uniform_buffer_offset_mask,
&mut memory.uniform_buffer_writer,
);
@ -934,6 +939,7 @@ impl VulkanRenderer {
memory.blend_buffer_color_management_data_address = memory.color_transforms.get_offset(
&bb_cd.linear,
fb_cd,
RenderIntent::Perceptual,
self.device.uniform_buffer_offset_mask,
&mut memory.uniform_buffer_writer,
);
@ -1192,9 +1198,12 @@ impl VulkanRenderer {
if let Some(clear) = clear
&& clear_rects.is_not_empty()
{
let color = memory
.color_transforms
.apply_to_color(clear_cd, target_cd, *clear);
let color = memory.color_transforms.apply_to_color(
clear_cd,
target_cd,
RenderIntent::Perceptual,
*clear,
);
let clear_value = ClearValue {
color: ClearColorValue {
float32: color.to_array(target_cd.eotf),
@ -2312,7 +2321,7 @@ where
#[derive(Default)]
struct ColorTransforms {
map: AHashMap<[LinearColorDescriptionId; 2], ColorTransform>,
map: AHashMap<([LinearColorDescriptionId; 2], RenderIntent), ColorTransform>,
}
struct ColorTransform {
@ -2325,14 +2334,15 @@ impl ColorTransforms {
&mut self,
src: &LinearColorDescription,
dst: &ColorDescription,
intent: RenderIntent,
) -> Option<&mut ColorTransform> {
if src.embeds_into(&dst.linear) {
return None;
}
let ct = match self.map.entry([src.id, dst.linear.id]) {
let ct = match self.map.entry(([src.id, dst.linear.id], intent)) {
Entry::Occupied(o) => o.into_mut(),
Entry::Vacant(e) => {
let matrix = src.color_transform(&dst.linear);
let matrix = src.color_transform(&dst.linear, intent);
let ct = ColorTransform {
matrix,
offset: None,
@ -2347,9 +2357,10 @@ impl ColorTransforms {
&mut self,
src: &LinearColorDescription,
dst: &ColorDescription,
intent: RenderIntent,
mut color: Color,
) -> Color {
if let Some(ct) = self.get_or_create(src, dst) {
if let Some(ct) = self.get_or_create(src, dst, intent) {
color = ct.matrix * color;
};
color
@ -2359,10 +2370,11 @@ impl ColorTransforms {
&mut self,
src: &LinearColorDescription,
dst: &ColorDescription,
intent: RenderIntent,
uniform_buffer_offset_mask: DeviceSize,
writer: &mut GenericBufferWriter,
) -> Option<DeviceSize> {
let ct = self.get_or_create(src, dst)?;
let ct = self.get_or_create(src, dst, intent)?;
if ct.offset.is_none() {
let data = ColorManagementData {
matrix: ct.matrix.to_f32(),

View file

@ -27,6 +27,7 @@ mod consts {
pub const RENDER_INTENT_SATURATION: u32 = 2;
pub const RENDER_INTENT_ABSOLUTE: u32 = 3;
pub const RENDER_INTENT_RELATIVE_BPC: u32 = 4;
pub const RENDER_INTENT_ABSOLUTE_NO_ADAPTATION: u32 = 5;
pub const FEATURE_ICC_V2_V4: u32 = 0;
pub const FEATURE_PARAMETRIC: u32 = 1;

View file

@ -26,7 +26,7 @@ use {
crate::{
backend::{ButtonState, KeyState},
client::{Client, ClientError},
cmm::cmm_description::ColorDescription,
cmm::{cmm_description::ColorDescription, cmm_render_intent::RenderIntent},
cursor_user::{CursorUser, CursorUserId},
damage::DamageMatrix,
drm_feedback::DrmFeedback,
@ -337,6 +337,7 @@ pub struct WlSurface {
color_management_feedback:
CopyHashMap<WpColorManagementSurfaceFeedbackV1Id, Rc<WpColorManagementSurfaceFeedbackV1>>,
color_description: CloneCell<Option<Rc<ColorDescription>>>,
render_intent: Cell<RenderIntent>,
color_representation_surface: CloneCell<Option<Rc<WpColorRepresentationSurfaceV1>>>,
alpha_mode: Cell<AlphaMode>,
}
@ -476,7 +477,7 @@ struct PendingState {
fifo_barrier_wait: bool,
commit_time: Option<u64>,
tray_item_ack_serial: Option<u32>,
color_description: Option<Option<Rc<ColorDescription>>>,
color_description: Option<Option<(RenderIntent, Rc<ColorDescription>)>>,
serial: Option<u64>,
alpha_mode: Option<AlphaMode>,
surface_release: SmallVec<[SurfaceRelease; 1]>,
@ -689,6 +690,7 @@ impl WlSurface {
color_management_surface: Default::default(),
color_management_feedback: Default::default(),
color_description: Default::default(),
render_intent: Default::default(),
color_representation_surface: Default::default(),
alpha_mode: Default::default(),
}
@ -1210,7 +1212,9 @@ impl WlSurface {
let mut color_description_changed = false;
if let Some(desc) = pending.color_description.take() {
color_description_changed = true;
let (intent, desc) = desc.unzip();
self.color_description.set(desc);
self.render_intent.set(intent.unwrap_or_default());
}
let mut alpha_mode_changed = false;
if let Some(alpha_mode) = pending.alpha_mode.take()
@ -1756,6 +1760,10 @@ impl WlSurface {
}
}
pub fn render_intent(&self) -> RenderIntent {
self.render_intent.get()
}
pub fn add_color_management_feedback(&self, fb: &Rc<WpColorManagementSurfaceFeedbackV1>) {
self.color_management_feedback.set(fb.id, fb.clone());
}

View file

@ -1,7 +1,8 @@
use {
crate::{
client::{Client, ClientError},
ifs::{color_management, wl_surface::WlSurface},
cmm::cmm_render_intent::RenderIntent,
ifs::wl_surface::WlSurface,
leaks::Tracker,
object::{Object, Version},
wire::{
@ -51,16 +52,16 @@ impl WpColorManagementSurfaceV1RequestHandler for WpColorManagementSurfaceV1 {
req: SetImageDescription,
_slf: &Rc<Self>,
) -> Result<(), Self::Error> {
if req.render_intent != color_management::RENDER_INTENT_PERCEPTUAL {
let Some(intent) = RenderIntent::from_wayland(req.render_intent, self.version) else {
return Err(WpColorManagementSurfaceV1Error::UnsupportedRenderIntent(
req.render_intent,
));
}
};
let desc = self.client.lookup(req.image_description)?;
if desc.description.is_none() {
let Some(desc) = &desc.description else {
return Err(WpColorManagementSurfaceV1Error::NotReady);
}
self.surface.pending.borrow_mut().color_description = Some(desc.description.clone());
};
self.surface.pending.borrow_mut().color_description = Some(Some((intent, desc.clone())));
Ok(())
}

View file

@ -2,7 +2,7 @@ use {
crate::{
allocator::{BO_USE_RENDERING, BufferObject, BufferUsage},
async_engine::{Phase, SpawnedFuture},
cmm::cmm_manager::ColorManager,
cmm::{cmm_manager::ColorManager, cmm_render_intent::RenderIntent},
cursor::KnownCursor,
fixed::Fixed,
format::ARGB8888,
@ -207,7 +207,12 @@ impl GuiElement for Button {
(x1, y1 + border, x1 + border, y2 - border),
(x2 - border, y1 + border, x2, y2 - border),
];
r.fill_boxes_f(&rects, &self.border_color.get(), srgb);
r.fill_boxes_f(
&rects,
&self.border_color.get(),
srgb,
RenderIntent::Perceptual,
);
}
{
let rects = [(x1 + border, y1 + border, x2 - border, y2 - border)];
@ -215,7 +220,7 @@ impl GuiElement for Button {
true => self.bg_color.get(),
false => self.bg_hover_color.get(),
};
r.fill_boxes_f(&rects, &color, srgb);
r.fill_boxes_f(&rects, &color, srgb, RenderIntent::Perceptual);
}
if let Some(tex) = self.tex.get() {
let (tx, ty) = r.scale_point_f(x1 + self.tex_off_x.get(), y1 + self.tex_off_y.get());
@ -233,6 +238,7 @@ impl GuiElement for Button {
ReleaseSync::None,
false,
srgb_srgb,
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -336,6 +342,7 @@ impl GuiElement for Label {
ReleaseSync::None,
false,
color_manager.srgb_gamma22(),
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
}

View file

@ -1,5 +1,6 @@
use {
crate::{
cmm::cmm_render_intent::RenderIntent,
gfx_api::{AcquireSync, AlphaMode, GfxApiOpt, ReleaseSync, SampleRect},
icons::{IconState, SizedIcons},
ifs::wl_surface::{
@ -80,6 +81,7 @@ impl Renderer<'_> {
let theme = &self.state.theme;
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let srgb = &srgb_srgb.linear;
let perceptual = RenderIntent::Perceptual;
if let Some(fs) = &fullscreen {
fs.node_render(self, x, y, None);
} else {
@ -97,7 +99,7 @@ impl Renderer<'_> {
let bar_bg = self.base.scale_rect(bar_bg);
let c = theme.colors.bar_background.get();
self.base
.fill_scaled_boxes(slice::from_ref(&bar_bg), &c, None, srgb);
.fill_scaled_boxes(slice::from_ref(&bar_bg), &c, None, srgb, perceptual);
self.base.sync();
let rd = output.render_data.borrow_mut();
if let Some(aw) = &rd.active_workspace {
@ -106,7 +108,7 @@ impl Renderer<'_> {
false => theme.colors.focused_title_background.get(),
};
self.base
.fill_boxes2(slice::from_ref(&aw.rect), &c, srgb, x, y);
.fill_boxes2(slice::from_ref(&aw.rect), &c, srgb, perceptual, x, y);
}
let mut c = theme.colors.separator.get();
if let Some(ws) = &ws
@ -114,18 +116,30 @@ impl Renderer<'_> {
{
c = theme.colors.focused_title_background.get();
}
self.base
.fill_boxes2(slice::from_ref(&rd.bar_separator), &c, srgb, x, y);
self.base.fill_boxes2(
slice::from_ref(&rd.bar_separator),
&c,
srgb,
perceptual,
x,
y,
);
let c = theme.colors.unfocused_title_background.get();
self.base
.fill_boxes2(&rd.inactive_workspaces, &c, srgb, x, y);
.fill_boxes2(&rd.inactive_workspaces, &c, srgb, perceptual, x, y);
let c = theme.colors.captured_unfocused_title_background.get();
self.base
.fill_boxes2(&rd.captured_inactive_workspaces, &c, srgb, x, y);
.fill_boxes2(&rd.captured_inactive_workspaces, &c, srgb, perceptual, x, y);
self.base.sync();
let c = theme.colors.attention_requested_background.get();
self.base
.fill_boxes2(&rd.attention_requested_workspaces, &c, srgb, x, y);
self.base.fill_boxes2(
&rd.attention_requested_workspaces,
&c,
srgb,
perceptual,
x,
y,
);
let scale = output.global.persistent.scale.get();
for title in &rd.titles {
let (x, y) = self.base.scale_point(x + title.tex_x, y + title.tex_y);
@ -143,6 +157,7 @@ impl Renderer<'_> {
ReleaseSync::None,
false,
self.state.color_manager.srgb_gamma22(),
perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -166,6 +181,7 @@ impl Renderer<'_> {
ReleaseSync::None,
false,
srgb_srgb,
perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -210,7 +226,7 @@ impl Renderer<'_> {
let color = self.state.theme.colors.highlight.get();
let bounds = output.workspace_rect_rel.get().move_(x, y);
self.base.sync();
self.base.fill_boxes(&[bounds], &color, srgb);
self.base.fill_boxes(&[bounds], &color, srgb, perceptual);
}
}
@ -232,6 +248,7 @@ impl Renderer<'_> {
std::slice::from_ref(&pos.at_point(x, y)),
&Color::from_srgba_straight(20, 20, 20, 255),
&self.state.color_manager.srgb_gamma22().linear,
RenderIntent::Perceptual,
);
if let Some(tex) = placeholder.textures.borrow().get(&self.base.scale)
&& let Some(texture) = tex.texture()
@ -253,6 +270,7 @@ impl Renderer<'_> {
ReleaseSync::None,
false,
self.state.color_manager.srgb_gamma22(),
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -263,19 +281,23 @@ impl Renderer<'_> {
{
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let srgb = &srgb_srgb.linear;
let perceptual = RenderIntent::Perceptual;
let rd = container.render_data.borrow_mut();
let c = self.state.theme.colors.unfocused_title_background.get();
self.base.fill_boxes2(&rd.title_rects, &c, srgb, x, y);
self.base
.fill_boxes2(&rd.title_rects, &c, srgb, perceptual, x, y);
let c = self.state.theme.colors.focused_title_background.get();
self.base
.fill_boxes2(&rd.active_title_rects, &c, srgb, x, y);
.fill_boxes2(&rd.active_title_rects, &c, srgb, perceptual, x, y);
let c = self.state.theme.colors.attention_requested_background.get();
self.base
.fill_boxes2(&rd.attention_title_rects, &c, srgb, x, y);
.fill_boxes2(&rd.attention_title_rects, &c, srgb, perceptual, x, y);
let c = self.state.theme.colors.separator.get();
self.base.fill_boxes2(&rd.underline_rects, &c, srgb, x, y);
self.base
.fill_boxes2(&rd.underline_rects, &c, srgb, perceptual, x, y);
let c = self.state.theme.colors.border.get();
self.base.fill_boxes2(&rd.border_rects, &c, srgb, x, y);
self.base
.fill_boxes2(&rd.border_rects, &c, srgb, perceptual, x, y);
if let Some(lar) = &rd.last_active_rect {
let c = self
.state
@ -284,7 +306,7 @@ impl Renderer<'_> {
.focused_inactive_title_background
.get();
self.base
.fill_boxes2(std::slice::from_ref(lar), &c, srgb, x, y);
.fill_boxes2(std::slice::from_ref(lar), &c, srgb, perceptual, x, y);
}
if let Some(titles) = rd.titles.get(&self.base.scale) {
for title in titles {
@ -305,6 +327,7 @@ impl Renderer<'_> {
ReleaseSync::None,
false,
srgb_srgb,
perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -382,6 +405,7 @@ impl Renderer<'_> {
&color,
None,
&self.state.color_manager.srgb_gamma22().linear,
RenderIntent::Perceptual,
);
}
@ -392,6 +416,7 @@ impl Renderer<'_> {
slice::from_ref(rect),
&color,
&self.state.color_manager.srgb_gamma22().linear,
RenderIntent::Perceptual,
);
}
@ -469,6 +494,7 @@ impl Renderer<'_> {
let buf = &buffer.buffer.buf;
let alpha = surface.alpha();
let cd = surface.color_description();
let intent = surface.render_intent();
let alpha_mode = surface.alpha_mode();
if let Some(tex) = buf.get_texture(surface) {
let mut opaque = surface.opaque();
@ -489,6 +515,7 @@ impl Renderer<'_> {
buffer.release_sync,
opaque,
&cd,
intent,
alpha_mode,
);
} else if let Some(color) = &buf.color {
@ -503,7 +530,7 @@ impl Renderer<'_> {
);
self.base.sync();
self.base
.fill_scaled_boxes(&[rect], &color, alpha, &cd.linear);
.fill_scaled_boxes(&[rect], &color, alpha, &cd.linear, intent);
}
}
} else {
@ -539,21 +566,23 @@ impl Renderer<'_> {
];
let srgb_srgb = self.state.color_manager.srgb_gamma22();
let srgb = &srgb_srgb.linear;
self.base.fill_boxes(&borders, &bc, srgb);
let perceptual = RenderIntent::Perceptual;
self.base.fill_boxes(&borders, &bc, srgb, perceptual);
let title = [Rect::new_sized_saturating(
x + bw,
y + bw,
pos.width() - 2 * bw,
th,
)];
self.base.fill_boxes(&title, &tc, srgb);
self.base.fill_boxes(&title, &tc, srgb, perceptual);
let title_underline = [Rect::new_sized_saturating(
x + bw,
y + bw + th,
pos.width() - 2 * bw,
tuh,
)];
self.base.fill_boxes(&title_underline, &uc, srgb);
self.base
.fill_boxes(&title_underline, &uc, srgb, perceptual);
let rect = floating.title_rect.get().move_(x, y);
let bounds = self.base.scale_rect(rect);
let (mut x1, y1) = rect.position();
@ -586,6 +615,7 @@ impl Renderer<'_> {
ReleaseSync::None,
false,
srgb_srgb,
perceptual,
AlphaMode::PremultipliedElectrical,
);
}
@ -609,6 +639,7 @@ impl Renderer<'_> {
ReleaseSync::None,
false,
srgb_srgb,
perceptual,
AlphaMode::PremultipliedElectrical,
);
}

View file

@ -1,6 +1,9 @@
use {
crate::{
cmm::cmm_description::{ColorDescription, LinearColorDescription},
cmm::{
cmm_description::{ColorDescription, LinearColorDescription},
cmm_render_intent::RenderIntent,
},
gfx_api::{
AcquireSync, AlphaMode, BufferResv, CopyTexture, FillRect, FramebufferRect, GfxApiOpt,
GfxTexture, ReleaseSync, SampleRect,
@ -70,12 +73,19 @@ impl RendererBase<'_> {
color: &Color,
alpha: Option<f32>,
cd: &Rc<LinearColorDescription>,
render_intent: RenderIntent,
) {
self.fill_boxes3(boxes, color, alpha, cd, 0, 0, true);
self.fill_boxes3(boxes, color, alpha, cd, render_intent, 0, 0, true);
}
pub fn fill_boxes(&mut self, boxes: &[Rect], color: &Color, cd: &Rc<LinearColorDescription>) {
self.fill_boxes3(boxes, color, None, cd, 0, 0, false);
pub fn fill_boxes(
&mut self,
boxes: &[Rect],
color: &Color,
cd: &Rc<LinearColorDescription>,
render_intent: RenderIntent,
) {
self.fill_boxes3(boxes, color, None, cd, render_intent, 0, 0, false);
}
pub fn fill_boxes2(
@ -83,10 +93,11 @@ impl RendererBase<'_> {
boxes: &[Rect],
color: &Color,
cd: &Rc<LinearColorDescription>,
render_intent: RenderIntent,
dx: i32,
dy: i32,
) {
self.fill_boxes3(boxes, color, None, cd, dx, dy, false);
self.fill_boxes3(boxes, color, None, cd, render_intent, dx, dy, false);
}
fn fill_boxes3(
@ -95,6 +106,7 @@ impl RendererBase<'_> {
color: &Color,
alpha: Option<f32>,
cd: &Rc<LinearColorDescription>,
render_intent: RenderIntent,
dx: i32,
dy: i32,
scaled: bool,
@ -120,6 +132,7 @@ impl RendererBase<'_> {
),
color: *color,
alpha,
render_intent,
cd: cd.clone(),
}));
}
@ -130,8 +143,9 @@ impl RendererBase<'_> {
boxes: &[(f32, f32, f32, f32)],
color: &Color,
cd: &Rc<LinearColorDescription>,
render_intent: RenderIntent,
) {
self.fill_boxes2_f(boxes, color, cd, 0.0, 0.0);
self.fill_boxes2_f(boxes, color, cd, render_intent, 0.0, 0.0);
}
pub fn fill_boxes2_f(
@ -139,6 +153,7 @@ impl RendererBase<'_> {
boxes: &[(f32, f32, f32, f32)],
color: &Color,
cd: &Rc<LinearColorDescription>,
render_intent: RenderIntent,
dx: f32,
dy: f32,
) {
@ -160,6 +175,7 @@ impl RendererBase<'_> {
),
color: *color,
alpha: None,
render_intent,
cd: cd.clone(),
}));
}
@ -180,6 +196,7 @@ impl RendererBase<'_> {
release_sync: ReleaseSync,
opaque: bool,
cd: &Rc<ColorDescription>,
render_intent: RenderIntent,
alpha_mode: AlphaMode,
) {
// log::info!("rendering texture {:?}", std::ptr::from_ref(&**texture) as *const u8);
@ -227,6 +244,7 @@ impl RendererBase<'_> {
acquire_sync,
release_sync,
opaque,
render_intent,
cd: cd.clone(),
alpha_mode,
}));

View file

@ -13,7 +13,10 @@ use {
cli::RunArgs,
client::{Client, ClientCaps, ClientId, Clients, NUM_CACHED_SERIAL_RANGES, SerialRange},
clientmem::ClientMemOffset,
cmm::{cmm_description::ColorDescription, cmm_manager::ColorManager},
cmm::{
cmm_description::ColorDescription, cmm_manager::ColorManager,
cmm_render_intent::RenderIntent,
},
compositor::{LIBEI_SOCKET, LogLevel},
config::ConfigProxy,
control_center::{
@ -1332,6 +1335,7 @@ impl State {
release_sync,
false,
src_cd,
RenderIntent::Perceptual,
AlphaMode::PremultipliedElectrical,
);
if render_hardware_cursors