Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
uber_sdf_geometry.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
6
8
9namespace impeller {
10
13
15
17 const ContentContext& renderer,
18 const Entity& entity,
19 RenderPass& pass) const {
20 // Return a quad (FillRectGeometry) that covers the base shape expanded by
21 // padding for stroke width and AA.
22 //
23 // For future performance enhancements (if the fill rate is a limiting factor)
24 // this can be optimized to use a tighter geometry for specific shapes. E.g.
25 // Using a tighter polygon, or cutting out the interior for stroked shapes.
26 FillRectGeometry frg(GetExpandedBounds(entity.GetTransform()));
27 return frg.GetPositionBuffer(renderer, entity, pass);
28}
29
30std::optional<Rect> UberSDFGeometry::GetCoverage(
31 const Matrix& transform) const {
32 return GetExpandedBounds(transform).TransformAndClipBounds(transform);
33}
34
36 const IRect& rect) const {
37 if (params_.type == UberSDFParameters::Type::kRect && !params_.stroke &&
38 transform.IsTranslationScaleOnly()) {
39 // The SDF is a filled axis-aligned rectangle. It "covers" the input rect if
40 // the SDF shader fully replaces the pixels contained in the rect parameter.
41 // The SDF shader is computed by the GPU at the center of the pixels it
42 // intersects and it computes a coverage for the pixels that reaches full
43 // coverage (1.0) at (aa_pixels / 2.0) inside the geometry. That coverage
44 // value will be applied for every MSAA sample intersected by the geometry.
45 //
46 // Since the input rect is an integer rect we already know that it encloses
47 // at least half a pixel on each side of the pixel centers inside it and
48 // that it encloses every MSAA sample location within those pixels. This
49 // means that the integer rect already meets all of the above criteria (as
50 // long as kAntialiasPixels is <= 1.0), so if the transformed geometry
51 // contains the integer input rect, all pixels will be fully rendered.
52 static_assert(UberSDFParameters::kAntialiasPixels <= 1.0);
53 return Rect::MakeEllipseBounds(params_.center, params_.size)
55 .Contains(rect);
56 }
57
58 // Conservatively return false. We can optimize to handle more cases in the
59 // future if needed for performance reasons.
60 return false;
61}
62
64 return (params_.type == UberSDFParameters::Type::kRect && !params_.stroke);
65}
66
67Rect UberSDFGeometry::GetExpandedBounds(const Matrix& transform) const {
68 // Get the scaling factor of the transform in the X and Y directions.
69 Vector2 transform_scaling = transform.GetBasisScaleXY();
70
71 // Get the device pixel size in local space units. This is the inverse of the
72 // transform scaling. E.g. if the transform performs a scale of 4 in the X
73 // direction and 0.5 in the Y direction, then 1 device pixel is size
74 // {0.25, 2.0} in local space units.
75 Size device_pixel_size = {
76 transform_scaling.x != 0 ? 1.0f / transform_scaling.x : 0,
77 transform_scaling.y != 0 ? 1.0f / transform_scaling.y : 0};
78
79 // The stroke padding is half the stroke width, if the shape is stroked.
80 Size stroke_padding;
81 if (params_.stroke) {
82 // For the purposes of stroke padding, clamp stroke width to a minimum of 1
83 // device pixel. Note that this means the stroke width padding in the X
84 // direction may differ from the stroke width padding in the Y direction.
85 Size effective_stroke_width =
86 Size(params_.stroke->width).Max(device_pixel_size);
87 stroke_padding = effective_stroke_width * 0.5f;
88 }
89
90 // Padding for antialiasing.
91 Size aa_padding = UberSDFParameters::kAntialiasPixels * device_pixel_size;
92
93 return Rect::MakeEllipseBounds(params_.center, params_.size)
94 .Expand(stroke_padding + aa_padding);
95}
96
97} // namespace impeller
const Matrix & GetTransform() const
Get the global transform matrix for this Entity.
Definition entity.cc:46
GeometryResult GetPositionBuffer(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
Render passes encode render commands directed as one specific render target into an underlying comman...
Definition render_pass.h:30
GeometryResult GetPositionBuffer(const ContentContext &renderer, const Entity &entity, RenderPass &pass) const override
bool IsAxisAlignedRect() const override
bool CoversArea(const Matrix &transform, const IRect &rect) const override
Determines if this geometry, transformed by the given transform, will completely cover all of the pix...
UberSDFGeometry(const UberSDFParameters &params)
std::optional< Rect > GetCoverage(const Matrix &transform) const override
The coverage rectangle of this geometry, transformed by the transform argument.
const EmbeddedViewParams * params
TSize< Scalar > Size
Definition size.h:159
A 4x4 matrix using column-major storage.
Definition matrix.h:37
constexpr TRect TransformBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle.
Definition rect.h:506
static constexpr TRect MakeEllipseBounds(const TPoint< Type > &center, const TSize< Type > &radii)
Definition rect.h:164
constexpr bool Contains(const TPoint< Type > &p) const
Returns true iff the provided point |p| is inside the half-open interior of this rectangle.
Definition rect.h:255
constexpr TRect TransformAndClipBounds(const Matrix &transform) const
Creates a new bounding box that contains this transformed rectangle, clipped against the near clippin...
Definition rect.h:472
constexpr TRect< T > Expand(T left, T top, T right, T bottom) const
Returns a rectangle with expanded edges. Negative expansion results in shrinking.
Definition rect.h:652
constexpr TSize Max(const TSize &o) const
Definition size.h:97
Parameters for rendering shapes using the UberSDF shader.
Type type
The type of shape to render.
Point center
The center point of the shape in local coordinates.
static constexpr Scalar kAntialiasPixels
std::optional< StrokeParameters > stroke
The stroke parameters. If std::nullopt, the shape is filled.