зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1675375 Part 2: Add a polygon clips to image masks. r=gw
This patch augments the pushing of an image mask to allow a polygon clip region to be attached to it. Differential Revision: https://phabricator.services.mozilla.com/D105397
This commit is contained in:
Родитель
4f7272a107
Коммит
8e27bc2b02
|
@ -1072,11 +1072,13 @@ wr::WrClipId DisplayListBuilder::DefineClip(
|
||||||
}
|
}
|
||||||
|
|
||||||
wr::WrClipId DisplayListBuilder::DefineImageMaskClip(
|
wr::WrClipId DisplayListBuilder::DefineImageMaskClip(
|
||||||
const wr::ImageMask& aMask) {
|
const wr::ImageMask& aMask, const nsTArray<wr::LayoutPoint>& aPoints,
|
||||||
|
wr::FillRule aFillRule) {
|
||||||
CancelGroup();
|
CancelGroup();
|
||||||
|
|
||||||
WrClipId clipId = wr_dp_define_image_mask_clip_with_parent_clip_chain(
|
WrClipId clipId = wr_dp_define_image_mask_clip_with_parent_clip_chain(
|
||||||
mWrState, &mCurrentSpaceAndClipChain, aMask);
|
mWrState, &mCurrentSpaceAndClipChain, aMask, aPoints.Elements(),
|
||||||
|
aPoints.Length(), aFillRule);
|
||||||
|
|
||||||
return clipId;
|
return clipId;
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,7 +460,9 @@ class DisplayListBuilder final {
|
||||||
const Maybe<wr::WrSpaceAndClip>& aParent, const wr::LayoutRect& aClipRect,
|
const Maybe<wr::WrSpaceAndClip>& aParent, const wr::LayoutRect& aClipRect,
|
||||||
const nsTArray<wr::ComplexClipRegion>* aComplex = nullptr);
|
const nsTArray<wr::ComplexClipRegion>* aComplex = nullptr);
|
||||||
|
|
||||||
wr::WrClipId DefineImageMaskClip(const wr::ImageMask& aMask);
|
wr::WrClipId DefineImageMaskClip(const wr::ImageMask& aMask,
|
||||||
|
const nsTArray<wr::LayoutPoint>&,
|
||||||
|
wr::FillRule);
|
||||||
wr::WrClipId DefineRoundedRectClip(const wr::ComplexClipRegion& aComplex);
|
wr::WrClipId DefineRoundedRectClip(const wr::ComplexClipRegion& aComplex);
|
||||||
wr::WrClipId DefineRectClip(wr::LayoutRect aClipRect);
|
wr::WrClipId DefineRectClip(wr::LayoutRect aClipRect);
|
||||||
|
|
||||||
|
|
|
@ -16,9 +16,11 @@ namespaces = ["mozilla", "wr"]
|
||||||
|
|
||||||
[export]
|
[export]
|
||||||
item_types = ["globals", "enums", "structs", "unions", "typedefs", "opaque", "functions", "constants"]
|
item_types = ["globals", "enums", "structs", "unions", "typedefs", "opaque", "functions", "constants"]
|
||||||
|
include = ["POLYGON_CLIP_VERTEX_MAX"]
|
||||||
|
|
||||||
[parse]
|
[parse]
|
||||||
parse_deps = true
|
parse_deps = true
|
||||||
|
extra_bindings = ["webrender_api"]
|
||||||
include = ["log", "euclid", "webrender", "webrender_api"]
|
include = ["log", "euclid", "webrender", "webrender_api"]
|
||||||
|
|
||||||
[fn]
|
[fn]
|
||||||
|
|
|
@ -2554,7 +2554,7 @@ pub extern "C" fn wr_dp_push_stacking_context(
|
||||||
let reference_frame_kind = match params.reference_frame_kind {
|
let reference_frame_kind = match params.reference_frame_kind {
|
||||||
WrReferenceFrameKind::Transform => ReferenceFrameKind::Transform {
|
WrReferenceFrameKind::Transform => ReferenceFrameKind::Transform {
|
||||||
is_2d_scale_translation,
|
is_2d_scale_translation,
|
||||||
should_snap
|
should_snap,
|
||||||
},
|
},
|
||||||
WrReferenceFrameKind::Perspective => ReferenceFrameKind::Perspective { scrolling_relative_to },
|
WrReferenceFrameKind::Perspective => ReferenceFrameKind::Perspective { scrolling_relative_to },
|
||||||
};
|
};
|
||||||
|
@ -2685,13 +2685,21 @@ pub extern "C" fn wr_dp_define_image_mask_clip_with_parent_clip_chain(
|
||||||
state: &mut WrState,
|
state: &mut WrState,
|
||||||
parent: &WrSpaceAndClipChain,
|
parent: &WrSpaceAndClipChain,
|
||||||
mask: ImageMask,
|
mask: ImageMask,
|
||||||
|
points: *const LayoutPoint,
|
||||||
|
point_count: usize,
|
||||||
|
fill_rule: FillRule,
|
||||||
) -> WrClipId {
|
) -> WrClipId {
|
||||||
debug_assert!(unsafe { is_in_main_thread() });
|
debug_assert!(unsafe { is_in_main_thread() });
|
||||||
|
|
||||||
let clip_id = state
|
let c_points = unsafe { make_slice(points, point_count) };
|
||||||
.frame_builder
|
let points: Vec<LayoutPoint> = c_points.iter().copied().collect();
|
||||||
.dl_builder
|
|
||||||
.define_clip_image_mask(&parent.to_webrender(state.pipeline_id), mask);
|
let clip_id = state.frame_builder.dl_builder.define_clip_image_mask(
|
||||||
|
&parent.to_webrender(state.pipeline_id),
|
||||||
|
mask,
|
||||||
|
&points,
|
||||||
|
fill_rule,
|
||||||
|
);
|
||||||
WrClipId::from_webrender(clip_id)
|
WrClipId::from_webrender(clip_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,8 @@ impl Example for App {
|
||||||
let mask_clip_id = builder.define_clip_image_mask(
|
let mask_clip_id = builder.define_clip_image_mask(
|
||||||
&root_space_and_clip,
|
&root_space_and_clip,
|
||||||
mask,
|
mask,
|
||||||
|
&vec![],
|
||||||
|
FillRule::Nonzero,
|
||||||
);
|
);
|
||||||
let clip_id = builder.define_clip_rounded_rect(
|
let clip_id = builder.define_clip_rounded_rect(
|
||||||
&SpaceAndClipInfo {
|
&SpaceAndClipInfo {
|
||||||
|
|
|
@ -268,6 +268,9 @@ pub struct TileCoordinate;
|
||||||
|
|
||||||
// Geometry types for tile coordinates.
|
// Geometry types for tile coordinates.
|
||||||
pub type TileOffset = Point2D<i32, TileCoordinate>;
|
pub type TileOffset = Point2D<i32, TileCoordinate>;
|
||||||
|
// TileSize type is also used in used in lib.rs and cbindgen picks the wrong one when
|
||||||
|
// generating headers.
|
||||||
|
/// cbindgen:ignore
|
||||||
pub type TileSize = Size2D<i32, TileCoordinate>;
|
pub type TileSize = Size2D<i32, TileCoordinate>;
|
||||||
pub type TileRect = Rect<i32, TileCoordinate>;
|
pub type TileRect = Rect<i32, TileCoordinate>;
|
||||||
|
|
||||||
|
@ -6185,7 +6188,7 @@ impl PicturePrimitive {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Map the cluster bounding rect into the space of the surface, and
|
// Map the cluster bounding rect into the space of the surface, and
|
||||||
// include it in the surface bounding rect.
|
// include it in the surface bounding rect.
|
||||||
surface.map_local_to_surface.set_target_spatial_node(
|
surface.map_local_to_surface.set_target_spatial_node(
|
||||||
cluster.spatial_node_index,
|
cluster.spatial_node_index,
|
||||||
frame_context.spatial_tree,
|
frame_context.spatial_tree,
|
||||||
|
|
|
@ -1491,6 +1491,8 @@ impl ComplexClipRegion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const POLYGON_CLIP_VERTEX_MAX: usize = 16;
|
||||||
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
|
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
|
||||||
pub enum FillRule {
|
pub enum FillRule {
|
||||||
|
|
|
@ -1800,11 +1800,9 @@ impl DisplayListBuilder {
|
||||||
&mut self,
|
&mut self,
|
||||||
parent_space_and_clip: &di::SpaceAndClipInfo,
|
parent_space_and_clip: &di::SpaceAndClipInfo,
|
||||||
image_mask: di::ImageMask,
|
image_mask: di::ImageMask,
|
||||||
|
points: &Vec<LayoutPoint>,
|
||||||
|
fill_rule: di::FillRule,
|
||||||
) -> di::ClipId {
|
) -> di::ClipId {
|
||||||
// TODO(bradwerth): get points and fill_rule as parameters.
|
|
||||||
let points = Vec::<LayoutPoint>::new();
|
|
||||||
let fill_rule = di::FillRule::Nonzero;
|
|
||||||
|
|
||||||
let id = self.generate_clip_index();
|
let id = self.generate_clip_index();
|
||||||
let item = di::DisplayItem::ImageMaskClip(di::ImageMaskClipDisplayItem {
|
let item = di::DisplayItem::ImageMaskClip(di::ImageMaskClipDisplayItem {
|
||||||
id,
|
id,
|
||||||
|
|
|
@ -17,6 +17,7 @@ use std::usize;
|
||||||
use webrender::api::*;
|
use webrender::api::*;
|
||||||
use webrender::render_api::*;
|
use webrender::render_api::*;
|
||||||
use webrender::api::units::*;
|
use webrender::api::units::*;
|
||||||
|
use webrender::api::FillRule;
|
||||||
use crate::wrench::{FontDescriptor, Wrench, WrenchThing};
|
use crate::wrench::{FontDescriptor, Wrench, WrenchThing};
|
||||||
use crate::yaml_helper::{StringEnum, YamlHelper, make_perspective};
|
use crate::yaml_helper::{StringEnum, YamlHelper, make_perspective};
|
||||||
use yaml_rust::{Yaml, YamlLoader};
|
use yaml_rust::{Yaml, YamlLoader};
|
||||||
|
@ -1982,6 +1983,8 @@ impl YamlFrameReader {
|
||||||
space_and_clip.clip_id = dl.define_clip_image_mask(
|
space_and_clip.clip_id = dl.define_clip_image_mask(
|
||||||
&space_and_clip,
|
&space_and_clip,
|
||||||
image_mask,
|
image_mask,
|
||||||
|
&vec![],
|
||||||
|
FillRule::Nonzero,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9514,6 +9514,43 @@ static Maybe<wr::WrClipId> CreateSimpleClipRegion(
|
||||||
return Some(clipId);
|
return Some(clipId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FillPolygonDataForDisplayItem(
|
||||||
|
const nsDisplayMasksAndClipPaths& aDisplayItem,
|
||||||
|
nsTArray<wr::LayoutPoint>& aPoints, wr::FillRule& aFillRule) {
|
||||||
|
nsIFrame* frame = aDisplayItem.Frame();
|
||||||
|
const auto* style = frame->StyleSVGReset();
|
||||||
|
bool isPolygon = style->HasClipPath() && style->mClipPath.IsShape() &&
|
||||||
|
style->mClipPath.AsShape()._0->IsPolygon();
|
||||||
|
if (!isPolygon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& clipPath = style->mClipPath;
|
||||||
|
const auto& shape = *clipPath.AsShape()._0;
|
||||||
|
const nsRect refBox =
|
||||||
|
nsLayoutUtils::ComputeGeometryBox(frame, clipPath.AsShape()._1);
|
||||||
|
|
||||||
|
// We only fill polygon data for polygons that are below a complexity
|
||||||
|
// limit.
|
||||||
|
nsTArray<nsPoint> vertices =
|
||||||
|
ShapeUtils::ComputePolygonVertices(shape, refBox);
|
||||||
|
if (vertices.Length() > wr::POLYGON_CLIP_VERTEX_MAX) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < vertices.Length(); ++i) {
|
||||||
|
wr::LayoutPoint point = wr::ToLayoutPoint(
|
||||||
|
LayoutDevicePoint::FromAppUnits(vertices[i], appUnitsPerDevPixel));
|
||||||
|
aPoints.AppendElement(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
aFillRule = (shape.AsPolygon().fill == StyleFillRule::Nonzero)
|
||||||
|
? wr::FillRule::Nonzero
|
||||||
|
: wr::FillRule::Evenodd;
|
||||||
|
}
|
||||||
|
|
||||||
static Maybe<wr::WrClipId> CreateWRClipPathAndMasks(
|
static Maybe<wr::WrClipId> CreateWRClipPathAndMasks(
|
||||||
nsDisplayMasksAndClipPaths* aDisplayItem, const LayoutDeviceRect& aBounds,
|
nsDisplayMasksAndClipPaths* aDisplayItem, const LayoutDeviceRect& aBounds,
|
||||||
wr::IpcResourceUpdateQueue& aResources, wr::DisplayListBuilder& aBuilder,
|
wr::IpcResourceUpdateQueue& aResources, wr::DisplayListBuilder& aBuilder,
|
||||||
|
@ -9529,7 +9566,14 @@ static Maybe<wr::WrClipId> CreateWRClipPathAndMasks(
|
||||||
return Nothing();
|
return Nothing();
|
||||||
}
|
}
|
||||||
|
|
||||||
wr::WrClipId clipId = aBuilder.DefineImageMaskClip(mask.ref());
|
// We couldn't create a simple clip region, but before we create an image
|
||||||
|
// mask clip, see if we can get a polygon clip to add to it.
|
||||||
|
nsTArray<wr::LayoutPoint> points;
|
||||||
|
wr::FillRule fillRule = wr::FillRule::Nonzero;
|
||||||
|
FillPolygonDataForDisplayItem(*aDisplayItem, points, fillRule);
|
||||||
|
|
||||||
|
wr::WrClipId clipId =
|
||||||
|
aBuilder.DefineImageMaskClip(mask.ref(), points, fillRule);
|
||||||
|
|
||||||
return Some(clipId);
|
return Some(clipId);
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче