зеркало из 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(
|
||||
const wr::ImageMask& aMask) {
|
||||
const wr::ImageMask& aMask, const nsTArray<wr::LayoutPoint>& aPoints,
|
||||
wr::FillRule aFillRule) {
|
||||
CancelGroup();
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -460,7 +460,9 @@ class DisplayListBuilder final {
|
|||
const Maybe<wr::WrSpaceAndClip>& aParent, const wr::LayoutRect& aClipRect,
|
||||
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 DefineRectClip(wr::LayoutRect aClipRect);
|
||||
|
||||
|
|
|
@ -16,9 +16,11 @@ namespaces = ["mozilla", "wr"]
|
|||
|
||||
[export]
|
||||
item_types = ["globals", "enums", "structs", "unions", "typedefs", "opaque", "functions", "constants"]
|
||||
include = ["POLYGON_CLIP_VERTEX_MAX"]
|
||||
|
||||
[parse]
|
||||
parse_deps = true
|
||||
extra_bindings = ["webrender_api"]
|
||||
include = ["log", "euclid", "webrender", "webrender_api"]
|
||||
|
||||
[fn]
|
||||
|
|
|
@ -2554,7 +2554,7 @@ pub extern "C" fn wr_dp_push_stacking_context(
|
|||
let reference_frame_kind = match params.reference_frame_kind {
|
||||
WrReferenceFrameKind::Transform => ReferenceFrameKind::Transform {
|
||||
is_2d_scale_translation,
|
||||
should_snap
|
||||
should_snap,
|
||||
},
|
||||
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,
|
||||
parent: &WrSpaceAndClipChain,
|
||||
mask: ImageMask,
|
||||
points: *const LayoutPoint,
|
||||
point_count: usize,
|
||||
fill_rule: FillRule,
|
||||
) -> WrClipId {
|
||||
debug_assert!(unsafe { is_in_main_thread() });
|
||||
|
||||
let clip_id = state
|
||||
.frame_builder
|
||||
.dl_builder
|
||||
.define_clip_image_mask(&parent.to_webrender(state.pipeline_id), mask);
|
||||
let c_points = unsafe { make_slice(points, point_count) };
|
||||
let points: Vec<LayoutPoint> = c_points.iter().copied().collect();
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
@ -221,6 +221,8 @@ impl Example for App {
|
|||
let mask_clip_id = builder.define_clip_image_mask(
|
||||
&root_space_and_clip,
|
||||
mask,
|
||||
&vec![],
|
||||
FillRule::Nonzero,
|
||||
);
|
||||
let clip_id = builder.define_clip_rounded_rect(
|
||||
&SpaceAndClipInfo {
|
||||
|
|
|
@ -268,6 +268,9 @@ pub struct TileCoordinate;
|
|||
|
||||
// Geometry types for tile coordinates.
|
||||
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 TileRect = Rect<i32, TileCoordinate>;
|
||||
|
||||
|
@ -6185,7 +6188,7 @@ impl PicturePrimitive {
|
|||
}
|
||||
|
||||
// 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(
|
||||
cluster.spatial_node_index,
|
||||
frame_context.spatial_tree,
|
||||
|
|
|
@ -1491,6 +1491,8 @@ impl ComplexClipRegion {
|
|||
}
|
||||
}
|
||||
|
||||
pub const POLYGON_CLIP_VERTEX_MAX: usize = 16;
|
||||
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Deserialize, MallocSizeOf, PartialEq, Serialize, Eq, Hash, PeekPoke)]
|
||||
pub enum FillRule {
|
||||
|
|
|
@ -1800,11 +1800,9 @@ impl DisplayListBuilder {
|
|||
&mut self,
|
||||
parent_space_and_clip: &di::SpaceAndClipInfo,
|
||||
image_mask: di::ImageMask,
|
||||
points: &Vec<LayoutPoint>,
|
||||
fill_rule: di::FillRule,
|
||||
) -> 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 item = di::DisplayItem::ImageMaskClip(di::ImageMaskClipDisplayItem {
|
||||
id,
|
||||
|
|
|
@ -17,6 +17,7 @@ use std::usize;
|
|||
use webrender::api::*;
|
||||
use webrender::render_api::*;
|
||||
use webrender::api::units::*;
|
||||
use webrender::api::FillRule;
|
||||
use crate::wrench::{FontDescriptor, Wrench, WrenchThing};
|
||||
use crate::yaml_helper::{StringEnum, YamlHelper, make_perspective};
|
||||
use yaml_rust::{Yaml, YamlLoader};
|
||||
|
@ -1982,6 +1983,8 @@ impl YamlFrameReader {
|
|||
space_and_clip.clip_id = dl.define_clip_image_mask(
|
||||
&space_and_clip,
|
||||
image_mask,
|
||||
&vec![],
|
||||
FillRule::Nonzero,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -9514,6 +9514,43 @@ static Maybe<wr::WrClipId> CreateSimpleClipRegion(
|
|||
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(
|
||||
nsDisplayMasksAndClipPaths* aDisplayItem, const LayoutDeviceRect& aBounds,
|
||||
wr::IpcResourceUpdateQueue& aResources, wr::DisplayListBuilder& aBuilder,
|
||||
|
@ -9529,7 +9566,14 @@ static Maybe<wr::WrClipId> CreateWRClipPathAndMasks(
|
|||
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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче