More display list refactor.

This commit is contained in:
Samuel Guerra 2024-02-21 13:01:53 -03:00
parent 612ef11a44
commit 61bd8e1763
6 changed files with 87 additions and 78 deletions

View File

@ -1280,10 +1280,7 @@ impl FrameBuilder {
let image_id = image.renderer_id(r);
self.display_list.push_nine_patch_border(
bounds,
NinePatchSource::Image {
image_id,
rendering,
},
NinePatchSource::Image { image_id, rendering },
widths,
fill,
repeat_horizontal,
@ -1318,11 +1315,9 @@ impl FrameBuilder {
self.display_list.push_nine_patch_border(
bounds,
NinePatchSource::LinearGradient {
gradient: webrender_api::Gradient {
start_point: line.start.to_wr(),
end_point: line.end.to_wr(),
extend_mode,
},
start_point: line.start.cast(),
end_point: line.end.cast(),
extend_mode,
stops: stops.to_vec().into_boxed_slice(),
},
widths,
@ -1366,7 +1361,7 @@ impl FrameBuilder {
radius: radius.to_wr(),
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
extend_mode: extend_mode.into(),
},
stops: stops.to_vec().into_boxed_slice(),
},
@ -1411,7 +1406,7 @@ impl FrameBuilder {
angle: angle.0,
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
extend_mode: extend_mode.into(),
},
stops: stops.to_vec().into_boxed_slice(),
},
@ -1542,11 +1537,9 @@ impl FrameBuilder {
if !stops.is_empty() && self.visible {
self.display_list.push_linear_gradient(
clip_rect,
webrender_api::Gradient {
start_point: line.start.to_wr(),
end_point: line.end.to_wr(),
extend_mode,
},
line.start.cast(),
line.end.cast(),
extend_mode,
stops,
tile_origin,
tile_size,
@ -1599,7 +1592,7 @@ impl FrameBuilder {
radius: radius.to_wr(),
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
extend_mode: extend_mode.into(),
},
stops,
tile_origin,
@ -1650,7 +1643,7 @@ impl FrameBuilder {
angle: angle.0,
start_offset: 0.0,
end_offset: 1.0,
extend_mode,
extend_mode: extend_mode.into(),
},
stops,
tile_origin,
@ -1738,7 +1731,7 @@ impl FrameBuilder {
radius: radius.to_wr(),
start_offset: 0.0,
end_offset: 1.0,
extend_mode: RenderExtendMode::Clamp,
extend_mode: RenderExtendMode::Clamp.into(),
},
&[
RenderGradientStop { offset: 0.0, color },

View File

@ -47,7 +47,7 @@ impl From<ExtendMode> for RenderExtendMode {
///
/// Note that [`ExtendMode::Reflect`] is not supported
/// directly, you must duplicate and mirror the stops and use the `Repeat` render mode.
pub type RenderExtendMode = webrender_api::ExtendMode;
pub type RenderExtendMode = zero_ui_view_api::ExtendMode;
/// The radial gradient radius base length.
///

View File

@ -14,7 +14,6 @@ use zero_ui_var::{
animation::{easing::EasingStep, Transition, Transitionable},
context_var, impl_from_and_into_var, merge_var, IntoVar, Var, VarValue,
};
use zero_ui_view_api::webrender_api;
pub use zero_ui_view_api::config::ColorScheme;

View File

@ -7,6 +7,7 @@ use crate::{about_eq, about_eq_hash, Factor, FactorPercent};
/// # Equality
///
/// Equality is determined using [`about_eq`] with `0.00001` epsilon.
#[repr(C)]
#[derive(Default, Copy, Clone, serde::Serialize, serde::Deserialize)]
pub struct Rgba {
/// Red channel value, in the `[0.0..=1.0]` range.

View File

@ -11,7 +11,13 @@ use serde::{Deserialize, Serialize};
use webrender_api::{self as wr, PipelineId};
use crate::{
api_extension::{ApiExtensionId, ApiExtensionPayload}, font::{cast_glyphs_to_wr, FontId, GlyphInstance, GlyphOptions}, image::ImageTextureId, unit::PxToWr, window::FrameId, AlphaType, BorderSide, GradientStop, ImageRendering, MixBlendMode, ReferenceFrameId, RepeatMode, TransformStyle
api_extension::{ApiExtensionId, ApiExtensionPayload},
cast_gradient_stops_to_wr,
font::{cast_glyphs_to_wr, FontId, GlyphInstance, GlyphOptions},
image::ImageTextureId,
unit::PxToWr,
window::FrameId,
AlphaType, BorderSide, ExtendMode, GradientStop, ImageRendering, MixBlendMode, ReferenceFrameId, RepeatMode, TransformStyle,
};
use zero_ui_unit::*;
@ -327,10 +333,13 @@ impl DisplayListBuilder {
}
/// Push a linear gradient rectangle.
#[allow(clippy::too_many_arguments)]
pub fn push_linear_gradient(
&mut self,
clip_rect: PxRect,
gradient: wr::Gradient,
start_point: euclid::Point2D<f32, Px>,
end_point: euclid::Point2D<f32, Px>,
extend_mode: ExtendMode,
stops: &[GradientStop],
tile_origin: PxPoint,
tile_size: PxSize,
@ -338,7 +347,9 @@ impl DisplayListBuilder {
) {
self.list.push(DisplayItem::LinearGradient {
clip_rect,
gradient,
start_point,
end_point,
extend_mode,
stops: stops.to_vec().into_boxed_slice(),
tile_origin,
tile_size,
@ -1121,7 +1132,9 @@ enum DisplayItem {
LinearGradient {
clip_rect: PxRect,
gradient: wr::Gradient,
start_point: euclid::Point2D<f32, Px>,
end_point: euclid::Point2D<f32, Px>,
extend_mode: ExtendMode,
stops: Box<[GradientStop]>,
tile_origin: PxPoint,
tile_size: PxSize,
@ -1388,37 +1401,25 @@ impl DisplayItem {
NinePatchSource::Image { image_id, rendering } => {
wr::NinePatchBorderSource::Image(wr::ImageKey(cache.id_namespace(), image_id.get()), (*rendering).into())
}
NinePatchSource::LinearGradient { gradient, stops } => {
let stops: Vec<_> = stops
.iter()
.map(|s| wr::GradientStop {
offset: s.offset,
color: s.color.to_wr(),
})
.collect();
wr_list.push_stops(&stops);
wr::NinePatchBorderSource::Gradient(*gradient)
NinePatchSource::LinearGradient {
start_point,
end_point,
extend_mode,
stops,
} => {
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr::NinePatchBorderSource::Gradient(wr::Gradient {
start_point: start_point.cast_unit(),
end_point: end_point.cast_unit(),
extend_mode: (*extend_mode).into(),
})
}
NinePatchSource::RadialGradient { gradient, stops } => {
let stops: Vec<_> = stops
.iter()
.map(|s| wr::GradientStop {
offset: s.offset,
color: s.color.to_wr(),
})
.collect();
wr_list.push_stops(&stops);
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr::NinePatchBorderSource::RadialGradient(*gradient)
}
NinePatchSource::ConicGradient { gradient, stops } => {
let stops: Vec<_> = stops
.iter()
.map(|s| wr::GradientStop {
offset: s.offset,
color: s.color.to_wr(),
})
.collect();
wr_list.push_stops(&stops);
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr::NinePatchBorderSource::ConicGradient(*gradient)
}
};
@ -1487,7 +1488,9 @@ impl DisplayItem {
DisplayItem::LinearGradient {
clip_rect,
gradient,
start_point,
end_point,
extend_mode,
stops,
mut tile_origin,
tile_size,
@ -1504,14 +1507,7 @@ impl DisplayItem {
let clip = sc.clip_chain_id(wr_list);
// stops needs to be immediately followed by the gradient, if the clip-chain item
// is inserted in the between the stops are lost.
let stops: Vec<_> = stops
.iter()
.map(|s| wr::GradientStop {
offset: s.offset,
color: s.color.to_wr(),
})
.collect();
wr_list.push_stops(&stops);
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr_list.push_gradient(
&wr::CommonItemProperties {
clip_rect: clip_rect.to_wr(),
@ -1520,7 +1516,11 @@ impl DisplayItem {
flags: sc.primitive_flags(),
},
bounds,
*gradient,
wr::Gradient {
start_point: start_point.cast_unit(),
end_point: end_point.cast_unit(),
extend_mode: (*extend_mode).into(),
},
tile_size.to_wr(),
tile_spacing.to_wr(),
)
@ -1542,14 +1542,7 @@ impl DisplayItem {
.to_wr();
let clip = sc.clip_chain_id(wr_list);
let stops: Vec<_> = stops
.iter()
.map(|s| wr::GradientStop {
offset: s.offset,
color: s.color.to_wr(),
})
.collect();
wr_list.push_stops(&stops);
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr_list.push_radial_gradient(
&wr::CommonItemProperties {
clip_rect: clip_rect.to_wr(),
@ -1580,14 +1573,7 @@ impl DisplayItem {
.to_wr();
let clip = sc.clip_chain_id(wr_list);
let stops: Vec<_> = stops
.iter()
.map(|s| wr::GradientStop {
offset: s.offset,
color: s.color.to_wr(),
})
.collect();
wr_list.push_stops(&stops);
wr_list.push_stops(cast_gradient_stops_to_wr(stops));
wr_list.push_conic_gradient(
&wr::CommonItemProperties {
clip_rect: clip_rect.to_wr(),
@ -1741,7 +1727,9 @@ pub enum NinePatchSource {
rendering: ImageRendering,
},
LinearGradient {
gradient: wr::Gradient,
start_point: euclid::Point2D<f32, Px>,
end_point: euclid::Point2D<f32, Px>,
extend_mode: ExtendMode,
stops: Box<[GradientStop]>,
},
RadialGradient {

View File

@ -775,6 +775,7 @@ impl std::error::Error for ViewProcessOffline {}
pub(crate) type VpResult<T> = std::result::Result<T, ViewProcessOffline>;
/// Offset and color in a gradient.
#[repr(C)]
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
pub struct GradientStop {
/// Offset in pixels.
@ -782,6 +783,16 @@ pub struct GradientStop {
/// Color at the offset.
pub color: Rgba,
}
pub(crate) fn cast_gradient_stops_to_wr(stops: &[GradientStop]) -> &[webrender_api::GradientStop] {
debug_assert_eq!(
std::mem::size_of::<GradientStop>(),
std::mem::size_of::<webrender_api::GradientStop>()
);
debug_assert_eq!(std::mem::size_of::<Rgba>(), std::mem::size_of::<webrender_api::ColorF>());
// SAFETY: GradientStop has the same layout as webrender_api (f32, [f32; 4])
unsafe { std::mem::transmute(stops) }
}
/// Border side line style and color.
#[derive(Clone, Copy, Debug, Default, Deserialize, PartialEq, Serialize)]
@ -999,6 +1010,23 @@ impl From<AlphaType> for webrender_api::AlphaType {
}
}
/// Gradient extend mode.
#[allow(missing_docs)]
#[repr(u8)]
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize, Deserialize, Ord, PartialOrd)]
pub enum ExtendMode {
Clamp,
Repeat,
}
impl From<ExtendMode> for webrender_api::ExtendMode {
fn from(value: ExtendMode) -> Self {
match value {
ExtendMode::Clamp => webrender_api::ExtendMode::Clamp,
ExtendMode::Repeat => webrender_api::ExtendMode::Repeat,
}
}
}
#[cfg(test)]
mod tests {
use super::*;