Skip to content

Add API on stacking contexts to configure glyph raster mode. #2673

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions webrender/examples/alpha_perf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

for _ in 0 .. self.rect_count {
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
filters,
GlyphRasterSpace::Screen,
);

let complex_clip = ComplexClipRegion {
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

let image_mask_key = api.generate_image_key();
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/blob.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ impl Example for App {
None,
api::MixBlendMode::Normal,
Vec::new(),
api::GlyphRasterSpace::Screen,
);

let info = api::LayoutPrimitiveInfo::new((30, 30).by(500, 500));
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
builder.push_rect(
&LayoutPrimitiveInfo::new(local_rect),
Expand Down
2 changes: 2 additions & 0 deletions webrender/examples/frame_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ impl App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

builder.push_rect(&info, ColorF::new(1.0, 1.0, 0.0, 1.0));
Expand Down Expand Up @@ -155,6 +156,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

builder.push_image(
Expand Down
2 changes: 2 additions & 0 deletions webrender/examples/iframe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

// green rect visible == success
Expand All @@ -71,6 +72,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
// red rect under the iframe: if this is visible, things have gone wrong
builder.push_rect(&info, ColorF::new(1.0, 0.0, 0.0, 1.0));
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/image_resize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

let image_size = LayoutSize::new(100.0, 100.0);
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/multiwindow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ impl Window {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

let info = LayoutPrimitiveInfo::new(LayoutRect::new(
Expand Down
2 changes: 2 additions & 0 deletions webrender/examples/scrolling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

if true {
Expand All @@ -55,6 +56,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);
// set the scrolling clip
let clip_id = builder.define_scroll_frame(
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/texture_cache_stress.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

let x0 = 50.0;
Expand Down
1 change: 1 addition & 0 deletions webrender/examples/yuv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ impl Example for App {
None,
MixBlendMode::Normal,
Vec::new(),
GlyphRasterSpace::Screen,
);

let yuv_chanel1 = api.generate_image_key();
Expand Down
28 changes: 21 additions & 7 deletions webrender/src/display_list_flattener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use api::{AlphaType, BorderDetails, BorderDisplayItem, BuiltDisplayListIter, ClipAndScrollInfo};
use api::{ClipId, ColorF, ComplexClipRegion, DeviceIntPoint, DeviceIntRect, DeviceIntSize};
use api::{DevicePixelScale, DeviceUintRect, DisplayItemRef, Epoch, ExtendMode, ExternalScrollId};
use api::{FilterOp, FontInstanceKey, FontRenderMode, GlyphInstance, GlyphOptions, GradientStop};
use api::{FilterOp, FontInstanceKey, FontRenderMode, GlyphInstance, GlyphOptions, GlyphRasterSpace, GradientStop};
use api::{IframeDisplayItem, ImageKey, ImageRendering, ItemRange, LayerPoint, LayerPrimitiveInfo};
use api::{LayerRect, LayerSize, LayerVector2D, LayoutRect, LayoutSize, LayoutTransform};
use api::{LayoutVector2D, LineOrientation, LineStyle, LocalClip, PipelineId, PropertyBinding};
Expand Down Expand Up @@ -334,6 +334,7 @@ impl<'a> DisplayListFlattener<'a> {
true,
root_scroll_node,
None,
GlyphRasterSpace::Screen,
);

// For the root pipeline, there's no need to add a full screen rectangle
Expand Down Expand Up @@ -539,6 +540,7 @@ impl<'a> DisplayListFlattener<'a> {
false,
final_scroll_node,
stacking_context.clip_node_id,
stacking_context.glyph_raster_space,
);

self.flatten_items(
Expand Down Expand Up @@ -974,6 +976,7 @@ impl<'a> DisplayListFlattener<'a> {
is_pipeline_root: bool,
positioning_node: ClipId,
clipping_node: Option<ClipId>,
glyph_raster_space: GlyphRasterSpace,
) {
let clip_chain_id = match clipping_node {
Some(ref clipping_node) => self.id_to_index_mapper.get_clip_chain_index(clipping_node),
Expand Down Expand Up @@ -1237,6 +1240,7 @@ impl<'a> DisplayListFlattener<'a> {
allow_subpixel_aa,
transform_style,
rendering_context_3d_pic_index,
glyph_raster_space,
};

self.sc_stack.push(sc);
Expand Down Expand Up @@ -2065,19 +2069,24 @@ impl<'a> DisplayListFlattener<'a> {
flags |= options.flags;
}

let (allow_subpixel_aa, glyph_raster_space) = match self.sc_stack.last() {
Some(stacking_context) => {
(stacking_context.allow_subpixel_aa, stacking_context.glyph_raster_space)
}
None => {
(true, GlyphRasterSpace::Screen)
}
};

// There are some conditions under which we can't use
// subpixel text rendering, even if enabled.
if render_mode == FontRenderMode::Subpixel {
if !allow_subpixel_aa {
// text on a picture that has filters
// (e.g. opacity) can't use sub-pixel.
// TODO(gw): It's possible we can relax this in
// the future, if we modify the way
// we handle subpixel blending.
if let Some(stacking_context) = self.sc_stack.last() {
if !stacking_context.allow_subpixel_aa {
render_mode = FontRenderMode::Alpha;
}
}
render_mode = render_mode.limit_by(FontRenderMode::Alpha);
}

let prim_font = FontInstance::new(
Expand All @@ -2098,6 +2107,7 @@ impl<'a> DisplayListFlattener<'a> {
glyph_keys: Vec::new(),
offset: run_offset,
shadow: false,
glyph_raster_space,
}
};

Expand Down Expand Up @@ -2337,6 +2347,10 @@ struct FlattenedStackingContext {
/// on transparent stacking contexts.
allow_subpixel_aa: bool,

/// The rasterization mode for any text runs that are part
/// of this stacking context.
glyph_raster_space: GlyphRasterSpace,

/// CSS transform-style property.
transform_style: TransformStyle,

Expand Down
8 changes: 6 additions & 2 deletions webrender/src/prim_store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use api::{AlphaType, BorderRadius, BoxShadowClipMode, BuiltDisplayList, ClipMode, ColorF, ComplexClipRegion};
use api::{DeviceIntRect, DeviceIntSize, DevicePixelScale, Epoch, ExtendMode, FontRenderMode};
use api::{FilterOp, GlyphInstance, GlyphKey, GradientStop, ImageKey, ImageRendering, ItemRange, ItemTag};
use api::{LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D};
use api::{GlyphRasterSpace, LayerPoint, LayerRect, LayerSize, LayerToWorldTransform, LayerVector2D};
use api::{PipelineId, PremultipliedColorF, Shadow, YuvColorSpace, YuvFormat};
use border::{BorderCornerInstance, BorderEdgeKind};
use box_shadow::BLUR_SAMPLE_SCALE;
Expand Down Expand Up @@ -634,6 +634,7 @@ pub struct TextRunPrimitiveCpu {
pub glyph_keys: Vec<GlyphKey>,
pub glyph_gpu_blocks: Vec<GpuBlockData>,
pub shadow: bool,
pub glyph_raster_space: GlyphRasterSpace,
}

impl TextRunPrimitiveCpu {
Expand All @@ -645,7 +646,9 @@ impl TextRunPrimitiveCpu {
let mut font = self.font.clone();
font.size = font.size.scale_by(device_pixel_scale.0);
if let Some(transform) = transform {
if transform.has_perspective_component() || !transform.has_2d_inverse() {
if transform.has_perspective_component() ||
!transform.has_2d_inverse() ||
self.glyph_raster_space != GlyphRasterSpace::Screen {
font.render_mode = font.render_mode.limit_by(FontRenderMode::Alpha);
} else {
font.transform = FontTransform::from(&transform).quantize();
Expand Down Expand Up @@ -972,6 +975,7 @@ impl PrimitiveContainer {
glyph_keys: info.glyph_keys.clone(),
glyph_gpu_blocks: Vec::new(),
shadow: true,
glyph_raster_space: info.glyph_raster_space,
})
}
PrimitiveContainer::Brush(ref brush) => {
Expand Down
18 changes: 18 additions & 0 deletions webrender_api/src/display_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ pub struct StackingContext {
pub mix_blend_mode: MixBlendMode,
pub reference_frame_id: Option<ClipId>,
pub clip_node_id: Option<ClipId>,
pub glyph_raster_space: GlyphRasterSpace,
} // IMPLICIT: filters: Vec<FilterOp>

#[repr(u32)]
Expand All @@ -468,6 +469,23 @@ pub enum TransformStyle {
Preserve3D = 1,
}

// TODO(gw): In the future, we may modify this to apply to all elements
// within a stacking context, rather than just the glyphs. If
// this change occurs, we'll update the naming of this.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
#[repr(C, u8)]
pub enum GlyphRasterSpace {
// Rasterize glyphs in local-space, applying supplied scale to glyph sizes.
// Best performance, but lower quality.
Local(f32),

// Rasterize the glyphs in screen-space, including rotation / skew etc in
// the rasterized glyph. Best quality, but slower performance. Note that
// any stacking context with a perspective transform will be rasterized
// in local-space, even if this is set.
Screen,
}

#[repr(u32)]
#[derive(Clone, Copy, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
pub enum MixBlendMode {
Expand Down
4 changes: 3 additions & 1 deletion webrender_api/src/display_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use time::precise_time_ns;
use {AlphaType, BorderDetails, BorderDisplayItem, BorderRadius, BorderWidths, BoxShadowClipMode};
use {BoxShadowDisplayItem, ClipAndScrollInfo, ClipChainId, ClipChainItem, ClipDisplayItem, ClipId};
use {ColorF, ComplexClipRegion, DisplayItem, ExtendMode, ExternalScrollId, FilterOp};
use {FontInstanceKey, GlyphInstance, GlyphOptions, Gradient, GradientDisplayItem, GradientStop};
use {FontInstanceKey, GlyphInstance, GlyphOptions, GlyphRasterSpace, Gradient, GradientDisplayItem, GradientStop};
use {IframeDisplayItem, ImageDisplayItem, ImageKey, ImageMask, ImageRendering, LayerPrimitiveInfo};
use {LayoutPoint, LayoutPrimitiveInfo, LayoutRect, LayoutSize, LayoutTransform, LayoutVector2D};
use {LineDisplayItem, LineOrientation, LineStyle, MixBlendMode, PipelineId, PropertyBinding};
Expand Down Expand Up @@ -1276,6 +1276,7 @@ impl DisplayListBuilder {
perspective: Option<LayoutTransform>,
mix_blend_mode: MixBlendMode,
filters: Vec<FilterOp>,
glyph_raster_space: GlyphRasterSpace,
) {
let reference_frame_id = if transform.is_some() || perspective.is_some() {
Some(self.generate_clip_id())
Expand All @@ -1292,6 +1293,7 @@ impl DisplayListBuilder {
mix_blend_mode,
reference_frame_id,
clip_node_id,
glyph_raster_space,
},
});

Expand Down
Binary file added wrench/reftests/text/raster-space.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions wrench/reftests/text/raster-space.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
root:
items:
- type: stacking-context
transform: scale(5.0) rotate(45)
transform-origin: 300 300
glyph-raster-space: local(1.0)
items:
- text: "Local"
origin: 20 50
size: 20
font: "FreeSans.ttf"
- type: stacking-context
transform: scale(5.0) rotate(45)
transform-origin: 0 400
items:
- text: "Screen"
origin: 20 50
size: 20
font: "FreeSans.ttf"
1 change: 1 addition & 0 deletions wrench/reftests/text/reftest.list
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,4 @@ platform(linux) == two-shadows.yaml two-shadows.png
== shadow-fast-clip.yaml shadow-fast-clip-ref.yaml
== shadow-partial-glyph.yaml shadow-partial-glyph-ref.yaml
fuzzy(1,68) platform(linux) == shadow-transforms.yaml shadow-transforms.png
fuzzy(1,71) platform(linux) == raster-space.yaml raster-space.png
4 changes: 4 additions & 0 deletions wrench/src/yaml_frame_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1534,6 +1534,9 @@ impl YamlFrameReader {
let scroll_policy = yaml["scroll-policy"]
.as_scroll_policy()
.unwrap_or(ScrollPolicy::Scrollable);
let glyph_raster_space = yaml["glyph-raster-space"]
.as_glyph_raster_space()
.unwrap_or(GlyphRasterSpace::Screen);

if is_root {
if let Some(size) = yaml["scroll-offset"].as_point() {
Expand All @@ -1555,6 +1558,7 @@ impl YamlFrameReader {
perspective,
mix_blend_mode,
filters,
glyph_raster_space,
);

if !yaml["items"].is_badvalue() {
Expand Down
10 changes: 10 additions & 0 deletions wrench/src/yaml_frame_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ fn write_stacking_context(

enum_node(parent, "transform-style", sc.transform_style);

let glyph_raster_space = match sc.glyph_raster_space {
GlyphRasterSpace::Local(scale) => {
format!("local({})", scale)
}
GlyphRasterSpace::Screen => {
"screen".to_owned()
}
};
str_node(parent, "glyph-raster-space", &glyph_raster_space);

if let Some(clip_node_id) = sc.clip_node_id {
yaml_node(parent, "clip-node", Yaml::Integer(clip_id_mapper.map_id(&clip_node_id) as i64));
}
Expand Down
17 changes: 17 additions & 0 deletions wrench/src/yaml_helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub trait YamlHelper {
fn as_border_radius_component(&self) -> LayoutSize;
fn as_border_radius(&self) -> Option<BorderRadius>;
fn as_transform_style(&self) -> Option<TransformStyle>;
fn as_glyph_raster_space(&self) -> Option<GlyphRasterSpace>;
fn as_clip_mode(&self) -> Option<ClipMode>;
fn as_mix_blend_mode(&self) -> Option<MixBlendMode>;
fn as_scroll_policy(&self) -> Option<ScrollPolicy>;
Expand Down Expand Up @@ -519,6 +520,22 @@ impl YamlHelper for Yaml {
self.as_str().and_then(|x| StringEnum::from_str(x))
}

fn as_glyph_raster_space(&self) -> Option<GlyphRasterSpace> {
self.as_str().and_then(|s| {
match parse_function(s) {
("screen", _, _) => {
Some(GlyphRasterSpace::Screen)
}
("local", ref args, _) if args.len() == 1 => {
Some(GlyphRasterSpace::Local(args[0].parse().unwrap()))
}
f => {
panic!("error parsing glyph raster space {:?}", f);
}
}
})
}

fn as_mix_blend_mode(&self) -> Option<MixBlendMode> {
self.as_str().and_then(|x| StringEnum::from_str(x))
}
Expand Down