Bug 1675375 Part 3: Stub in polygon clipping in WebRender. r=gw

This defines a PolygonKey and includes it in ClipItemKind::ImageMask. The
actual process of clipping is just a stub.

Differential Revision: https://phabricator.services.mozilla.com/D105548
This commit is contained in:
Brad Werth 2021-04-14 17:17:15 +00:00
Родитель d2b048063e
Коммит ade4bd1b00
4 изменённых файлов: 62 добавлений и 14 удалений

Просмотреть файл

@ -93,7 +93,7 @@
//!
use api::{BorderRadius, ClipMode, ComplexClipRegion, ImageMask};
use api::{BoxShadowClipMode, ClipId, ImageKey, ImageRendering, PipelineId};
use api::{BoxShadowClipMode, ClipId, FillRule, ImageKey, ImageRendering, PipelineId};
use api::units::*;
use crate::image_tiling::{self, Repetition};
use crate::border::{ensure_no_corner_overlap, BorderRadiusAu};
@ -105,7 +105,7 @@ use crate::gpu_types::{BoxShadowStretchMode};
use crate::intern::{self, ItemUid};
use crate::internal_types::{FastHashMap, FastHashSet};
use crate::prim_store::{VisibleMaskImageTile};
use crate::prim_store::{PointKey, SizeKey, RectangleKey};
use crate::prim_store::{PointKey, SizeKey, RectangleKey, PolygonKey};
use crate::render_task_cache::to_cache_size;
use crate::resource_cache::{ImageRequest, ResourceCache};
use crate::space::SpaceMapper;
@ -398,11 +398,12 @@ impl From<ClipItemKey> for ClipNode {
mode,
}
}
ClipItemKeyKind::ImageMask(rect, image, repeat) => {
ClipItemKeyKind::ImageMask(rect, image, repeat, polygon) => {
ClipItemKind::Image {
image,
rect: rect.into(),
repeat,
polygon,
}
}
ClipItemKeyKind::BoxShadow(shadow_rect_fract_offset, shadow_rect_size, shadow_radius, prim_shadow_rect, blur_radius, clip_mode) => {
@ -609,7 +610,7 @@ impl ClipNodeInfo {
let mut visible_tiles = None;
if let ClipItemKind::Image { rect, image, repeat } = node.item.kind {
if let ClipItemKind::Image { rect, image, repeat, .. } = node.item.kind {
let request = ImageRequest {
key: image,
rendering: ImageRendering::Auto,
@ -1378,7 +1379,7 @@ impl ClipRegion<Option<ComplexClipRegion>> {
pub enum ClipItemKeyKind {
Rectangle(RectangleKey, ClipMode),
RoundedRectangle(RectangleKey, BorderRadiusAu, ClipMode),
ImageMask(RectangleKey, ImageKey, bool),
ImageMask(RectangleKey, ImageKey, bool, PolygonKey),
BoxShadow(PointKey, SizeKey, BorderRadiusAu, RectangleKey, Au, BoxShadowClipMode),
}
@ -1400,11 +1401,13 @@ impl ClipItemKeyKind {
}
}
pub fn image_mask(image_mask: &ImageMask, mask_rect: LayoutRect) -> Self {
pub fn image_mask(image_mask: &ImageMask, mask_rect: LayoutRect,
points: Vec<LayoutPoint>, fill_rule: FillRule) -> Self {
ClipItemKeyKind::ImageMask(
mask_rect.into(),
image_mask.image,
image_mask.repeat,
PolygonKey::new(&points, fill_rule)
)
}
@ -1486,6 +1489,7 @@ pub enum ClipItemKind {
image: ImageKey,
rect: LayoutRect,
repeat: bool,
polygon: PolygonKey,
},
BoxShadow {
source: BoxShadowClipSource,

Просмотреть файл

@ -86,8 +86,13 @@ impl HitTestClipNode {
ClipItemKind::RoundedRectangle { rect, radius, mode } => {
HitTestRegion::RoundedRectangle(rect, radius, mode)
}
ClipItemKind::Image { rect, .. } => {
HitTestRegion::Rectangle(rect, ClipMode::Clip)
ClipItemKind::Image { rect, polygon, .. } => {
if polygon.point_count > 0 {
// TODO(bradwerth): implement this.
HitTestRegion::Invalid
} else {
HitTestRegion::Rectangle(rect, ClipMode::Clip)
}
}
ClipItemKind::BoxShadow { .. } => HitTestRegion::Invalid,
};

Просмотреть файл

@ -5,7 +5,7 @@
use api::{BorderRadius, ClipMode, ColorF, ColorU, RasterSpace};
use api::{ImageRendering, RepeatMode, PrimitiveFlags};
use api::{PremultipliedColorF, PropertyBinding, Shadow};
use api::{PrimitiveKeyKind};
use api::{PrimitiveKeyKind, FillRule, POLYGON_CLIP_VERTEX_MAX};
use api::units::*;
use euclid::{SideOffsets2D, Size2D};
use malloc_size_of::MallocSizeOf;
@ -210,6 +210,46 @@ impl From<WorldRect> for RectangleKey {
}
}
/// To create a fixed-size representation of a polygon, we use a fixed
/// number of points. Our initialization method restricts us to values
/// <= 32. If our constant POLYGON_CLIP_VERTEX_MAX is > 32, the Rust
/// compiler will complain.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]
#[derive(Copy, Debug, Clone, Hash, MallocSizeOf, PartialEq)]
pub struct PolygonKey {
pub point_count: u8,
pub points: [PointKey; POLYGON_CLIP_VERTEX_MAX],
pub fill_rule: FillRule,
}
impl PolygonKey {
pub fn new(
points_layout: &Vec<LayoutPoint>,
fill_rule: FillRule,
) -> Self {
// We have to fill fixed-size arrays with data from a Vec.
// We'll do this by initializing the arrays to known-good
// values then overwriting those values as long as our
// iterator provides values.
let mut points: [PointKey; POLYGON_CLIP_VERTEX_MAX] = [PointKey { x: 0.0, y: 0.0}; POLYGON_CLIP_VERTEX_MAX];
let mut point_count: u8 = 0;
for (src, dest) in points_layout.iter().zip(points.iter_mut()) {
*dest = (*src as LayoutPoint).into();
point_count = point_count + 1;
}
PolygonKey {
point_count,
points,
fill_rule,
}
}
}
impl Eq for PolygonKey {}
/// A hashable SideOffset2D that can be used in primitive keys.
#[cfg_attr(feature = "capture", derive(Serialize))]
#[cfg_attr(feature = "replay", derive(Deserialize))]

Просмотреть файл

@ -2329,19 +2329,18 @@ impl<'a> SceneBuilder<'a> {
new_node_id: ClipId,
space_and_clip: &SpaceAndClipInfo,
image_mask: &ImageMask,
_fill_rule: FillRule,
_points_range: ItemRange<LayoutPoint>,
fill_rule: FillRule,
points_range: ItemRange<LayoutPoint>,
) {
// TODO(bradwerth): incorporate fill_rule and points_range into
// the ClipItemKey.
let spatial_node_index = self.id_to_index_mapper.get_spatial_node_index(space_and_clip.spatial_id);
let snapped_mask_rect = self.snap_rect(
&image_mask.rect,
spatial_node_index,
);
let points = points_range.iter().collect();
let item = ClipItemKey {
kind: ClipItemKeyKind::image_mask(image_mask, snapped_mask_rect),
kind: ClipItemKeyKind::image_mask(image_mask, snapped_mask_rect, points, fill_rule),
};
let handle = self