Flutter Engine
flutter::PhysicalShapeLayer Class Reference

#include <physical_shape_layer.h>

Inheritance diagram for flutter::PhysicalShapeLayer:
flutter::ContainerLayer flutter::Layer

Public Member Functions

 PhysicalShapeLayer (SkColor color, SkColor shadow_color, float elevation, const SkPath &path, Clip clip_behavior)
 
void Preroll (PrerollContext *context, const SkMatrix &matrix) override
 
void Paint (PaintContext &context) const override
 
bool UsesSaveLayer () const
 
float elevation () const
 
- Public Member Functions inherited from flutter::ContainerLayer
 ContainerLayer ()
 
virtual void Add (std::shared_ptr< Layer > layer)
 
const std::vector< std::shared_ptr< Layer > > & layers () const
 
- Public Member Functions inherited from flutter::Layer
 Layer ()
 
virtual ~Layer ()
 
bool needs_system_composite () const
 
void set_needs_system_composite (bool value)
 
const SkRect & paint_bounds () const
 
void set_paint_bounds (const SkRect &paint_bounds)
 
bool needs_painting () const
 
uint64_t unique_id () const
 

Static Public Member Functions

static SkRect ComputeShadowBounds (const SkRect &bounds, float elevation, float pixel_ratio)
 
static void DrawShadow (SkCanvas *canvas, const SkPath &path, SkColor color, float elevation, bool transparentOccluder, SkScalar dpr)
 

Additional Inherited Members

- Protected Member Functions inherited from flutter::ContainerLayer
void PrerollChildren (PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
 
void PaintChildren (PaintContext &context) const
 
- Static Protected Member Functions inherited from flutter::ContainerLayer
static void TryToPrepareRasterCache (PrerollContext *context, Layer *layer, const SkMatrix &matrix)
 

Detailed Description

Definition at line 12 of file physical_shape_layer.h.

Constructor & Destructor Documentation

◆ PhysicalShapeLayer()

flutter::PhysicalShapeLayer::PhysicalShapeLayer ( SkColor  color,
SkColor  shadow_color,
float  elevation,
const SkPath &  path,
Clip  clip_behavior 
)

Definition at line 15 of file physical_shape_layer.cc.

20  : color_(color),
21  shadow_color_(shadow_color),
22  elevation_(elevation),
23  path_(path),
24  clip_behavior_(clip_behavior) {}
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32

Member Function Documentation

◆ ComputeShadowBounds()

SkRect flutter::PhysicalShapeLayer::ComputeShadowBounds ( const SkRect &  bounds,
float  elevation,
float  pixel_ratio 
)
static

Definition at line 98 of file physical_shape_layer.cc.

References flutter::kLightHeight.

Referenced by Preroll(), and flutter::testing::TEST_F().

100  {
101  // The shadow offset is calculated as follows:
102  // .--- (kLightRadius)
103  // -------/ (light)
104  // | /
105  // | /
106  // |/
107  // |O
108  // /| (kLightHeight)
109  // / |
110  // / |
111  // / |
112  // / |
113  // ------------- (layer)
114  // /| |
115  // / | | (elevation)
116  // A / | |B
117  // ------------------------------------------------ (canvas)
118  // --- (extent of shadow)
119  //
120  // E = lt } t = (r + w/2)/h
121  // } =>
122  // r + w/2 = ht } E = (l/h)(r + w/2)
123  //
124  // Where: E = extent of shadow
125  // l = elevation of layer
126  // r = radius of the light source
127  // w = width of the layer
128  // h = light height
129  // t = tangent of AOB, i.e., multiplier for elevation to extent
130  // tangent for x
131  double tx =
132  (kLightRadius * pixel_ratio + bounds.width() * 0.5) / kLightHeight;
133  // tangent for y
134  double ty =
135  (kLightRadius * pixel_ratio + bounds.height() * 0.5) / kLightHeight;
136  SkRect shadow_bounds(bounds);
137  shadow_bounds.outset(elevation * tx, elevation * ty);
138 
139  return shadow_bounds;
140 }
const SkScalar kLightHeight
const SkScalar kLightRadius

◆ DrawShadow()

void flutter::PhysicalShapeLayer::DrawShadow ( SkCanvas *  canvas,
const SkPath &  path,
SkColor  color,
float  elevation,
bool  transparentOccluder,
SkScalar  dpr 
)
static

Definition at line 142 of file physical_shape_layer.cc.

References flutter::flags, and flutter::CanvasPath::getBounds().

Referenced by flutter::Canvas::drawShadow(), and Paint().

147  {
148  const SkScalar kAmbientAlpha = 0.039f;
149  const SkScalar kSpotAlpha = 0.25f;
150 
151  SkShadowFlags flags = transparentOccluder
152  ? SkShadowFlags::kTransparentOccluder_ShadowFlag
153  : SkShadowFlags::kNone_ShadowFlag;
154  const SkRect& bounds = path.getBounds();
155  SkScalar shadow_x = (bounds.left() + bounds.right()) / 2;
156  SkScalar shadow_y = bounds.top() - 600.0f;
157  SkColor inAmbient = SkColorSetA(color, kAmbientAlpha * SkColorGetA(color));
158  SkColor inSpot = SkColorSetA(color, kSpotAlpha * SkColorGetA(color));
159  SkColor ambientColor, spotColor;
160  SkShadowUtils::ComputeTonalColors(inAmbient, inSpot, &ambientColor,
161  &spotColor);
162  SkShadowUtils::DrawShadow(
163  canvas, path, SkPoint3::Make(0, 0, dpr * elevation),
164  SkPoint3::Make(shadow_x, shadow_y, dpr * kLightHeight),
165  dpr * kLightRadius, ambientColor, spotColor, flags);
166 }
DEF_SWITCHES_START snapshot asset path
Definition: switches.h:32
const SkScalar kLightHeight
const SkScalar kLightRadius
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart flags
Definition: switches.h:66

◆ elevation()

float flutter::PhysicalShapeLayer::elevation ( ) const
inline

Definition at line 38 of file physical_shape_layer.h.

38 { return elevation_; }

◆ Paint()

void flutter::PhysicalShapeLayer::Paint ( PaintContext context) const
overridevirtual

Reimplemented from flutter::ContainerLayer.

Definition at line 46 of file physical_shape_layer.cc.

References flutter::antiAlias, flutter::antiAliasWithSaveLayer, flutter::Layer::PaintContext::checkerboard_offscreen_layers, flutter::DrawCheckerboard(), DrawShadow(), FML_DCHECK, flutter::Layer::PaintContext::frame_device_pixel_ratio, flutter::hardEdge, flutter::Layer::PaintContext::internal_nodes_canvas, flutter::Layer::PaintContext::leaf_nodes_canvas, flutter::Layer::needs_painting(), flutter::none, flutter::Layer::paint_bounds(), flutter::ContainerLayer::PaintChildren(), TRACE_EVENT0, and UsesSaveLayer().

46  {
47  TRACE_EVENT0("flutter", "PhysicalShapeLayer::Paint");
49 
50  if (elevation_ != 0) {
51  DrawShadow(context.leaf_nodes_canvas, path_, shadow_color_, elevation_,
52  SkColorGetA(color_) != 0xff, context.frame_device_pixel_ratio);
53  }
54 
55  // Call drawPath without clip if possible for better performance.
56  SkPaint paint;
57  paint.setColor(color_);
58  paint.setAntiAlias(true);
59  if (clip_behavior_ != Clip::antiAliasWithSaveLayer) {
60  context.leaf_nodes_canvas->drawPath(path_, paint);
61  }
62 
63  int saveCount = context.internal_nodes_canvas->save();
64  switch (clip_behavior_) {
65  case Clip::hardEdge:
66  context.internal_nodes_canvas->clipPath(path_, false);
67  break;
68  case Clip::antiAlias:
69  context.internal_nodes_canvas->clipPath(path_, true);
70  break;
72  context.internal_nodes_canvas->clipPath(path_, true);
73  context.internal_nodes_canvas->saveLayer(paint_bounds(), nullptr);
74  break;
75  case Clip::none:
76  break;
77  }
78 
79  if (UsesSaveLayer()) {
80  // If we want to avoid the bleeding edge artifact
81  // (https://github.com/flutter/flutter/issues/18057#issue-328003931)
82  // using saveLayer, we have to call drawPaint instead of drawPath as
83  // anti-aliased drawPath will always have such artifacts.
84  context.leaf_nodes_canvas->drawPaint(paint);
85  }
86 
87  PaintChildren(context);
88 
89  context.internal_nodes_canvas->restoreToCount(saveCount);
90 
91  if (UsesSaveLayer()) {
92  if (context.checkerboard_offscreen_layers) {
93  DrawCheckerboard(context.internal_nodes_canvas, paint_bounds());
94  }
95  }
96 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
#define FML_DCHECK(condition)
Definition: logging.h:86
bool needs_painting() const
Definition: layer.h:174
const SkRect & paint_bounds() const
Definition: layer.h:166
static void DrawShadow(SkCanvas *canvas, const SkPath &path, SkColor color, float elevation, bool transparentOccluder, SkScalar dpr)
void DrawCheckerboard(SkCanvas *canvas, SkColor c1, SkColor c2, int size)
Definition: paint_utils.cc:28
void PaintChildren(PaintContext &context) const

◆ Preroll()

void flutter::PhysicalShapeLayer::Preroll ( PrerollContext context,
const SkMatrix &  matrix 
)
overridevirtual

Reimplemented from flutter::ContainerLayer.

Definition at line 26 of file physical_shape_layer.cc.

References ComputeShadowBounds(), flutter::Layer::AutoPrerollSaveLayerState::Create(), flutter::PrerollContext::frame_device_pixel_ratio, flutter::ContainerLayer::PrerollChildren(), flutter::Layer::set_paint_bounds(), TRACE_EVENT0, and UsesSaveLayer().

27  {
28  TRACE_EVENT0("flutter", "PhysicalShapeLayer::Preroll");
29  Layer::AutoPrerollSaveLayerState save =
31 
32  SkRect child_paint_bounds;
33  PrerollChildren(context, matrix, &child_paint_bounds);
34 
35  if (elevation_ == 0) {
36  set_paint_bounds(path_.getBounds());
37  } else {
38  // We will draw the shadow in Paint(), so add some margin to the paint
39  // bounds to leave space for the shadow. We fill this whole region and clip
40  // children to it so we don't need to join the child paint bounds.
41  set_paint_bounds(ComputeShadowBounds(path_.getBounds(), elevation_,
42  context->frame_device_pixel_ratio));
43  }
44 }
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
static SkRect ComputeShadowBounds(const SkRect &bounds, float elevation, float pixel_ratio)
void PrerollChildren(PrerollContext *context, const SkMatrix &child_matrix, SkRect *child_paint_bounds)
static AutoPrerollSaveLayerState Create(PrerollContext *preroll_context, bool save_layer_is_active=true, bool layer_itself_performs_readback=false)
Definition: layer.cc:43
void set_paint_bounds(const SkRect &paint_bounds)
Definition: layer.h:170

◆ UsesSaveLayer()

bool flutter::PhysicalShapeLayer::UsesSaveLayer ( ) const
inline

Definition at line 34 of file physical_shape_layer.h.

References flutter::antiAliasWithSaveLayer.

Referenced by Paint(), and Preroll().

34  {
35  return clip_behavior_ == Clip::antiAliasWithSaveLayer;
36  }

The documentation for this class was generated from the following files: