Flutter Engine
The Flutter Engine
dl_sk_dispatcher.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
5#include "flutter/display_list/skia/dl_sk_dispatcher.h"
6
7#include "flutter/display_list/dl_blend_mode.h"
8#include "flutter/display_list/skia/dl_sk_conversions.h"
9#include "flutter/display_list/skia/dl_sk_types.h"
10#include "flutter/fml/trace_event.h"
11
14
15namespace flutter {
16
17const SkPaint* DlSkCanvasDispatcher::safe_paint(bool use_attributes) {
18 if (use_attributes) {
19 // The accumulated SkPaint object will already have incorporated
20 // any attribute overrides.
21 // Any rendering operation that uses an optional paint will ignore
22 // the shader in the paint so we inform that |paint()| method so
23 // that it can set the dither flag appropriately.
24 return &paint(false);
25 } else if (has_opacity()) {
26 temp_paint_.setAlphaf(opacity());
27 return &temp_paint_;
28 } else {
29 return nullptr;
30 }
31}
32
34 canvas_->save();
35 // save has no impact on attributes, but it needs to register a record
36 // on the restore stack so that the eventual call to restore() will
37 // know what to do at that time. We could annotate the restore record
38 // with a flag that the record came from a save call, but it is simpler
39 // to just pass in the current opacity value as the value to be used by
40 // the children and let the utility calls notice that it didn't change.
42}
44 canvas_->restore();
46}
49 const DlImageFilter* backdrop) {
50 if (!options.content_is_clipped() && options.can_distribute_opacity() &&
51 backdrop == nullptr) {
52 // We know that:
53 // - no bounds is needed for clipping here
54 // - no backdrop filter is used to initialize the layer
55 // - the current attributes only have an alpha
56 // - the children are compatible with individually rendering with
57 // an inherited opacity
58 // Therefore we can just use a save instead of a saveLayer and pass the
59 // intended opacity to the children.
60 canvas_->save();
61 // If the saveLayer does not use attributes, the children should continue
62 // to render with the inherited opacity unmodified. If attributes are to
63 // be applied, the children should render with the combination of the
64 // inherited opacity combined with the alpha from the current color.
65 save_opacity(options.renders_with_attributes() ? combined_opacity()
66 : opacity());
67 } else {
68 TRACE_EVENT0("flutter", "Canvas::saveLayer");
69 const SkPaint* paint = safe_paint(options.renders_with_attributes());
70 const sk_sp<SkImageFilter> sk_backdrop = ToSk(backdrop);
71 const SkRect* sl_bounds = options.bounds_from_caller() ? &bounds : nullptr;
72 canvas_->saveLayer(
73 SkCanvas::SaveLayerRec(sl_bounds, paint, sk_backdrop.get(), 0));
74 // saveLayer will apply the current opacity on behalf of the children
75 // so they will inherit an opaque opacity.
77 }
78}
79
81 canvas_->translate(tx, ty);
82}
84 canvas_->scale(sx, sy);
85}
87 canvas_->rotate(degrees);
88}
90 canvas_->skew(sx, sy);
91}
92// clang-format off
93// 2x3 2D affine subset of a 4x4 transform in row major order
95 SkScalar mxx, SkScalar mxy, SkScalar mxt,
96 SkScalar myx, SkScalar myy, SkScalar myt) {
97 // Internally concat(SkMatrix) gets redirected to concat(SkM44)
98 // so we just jump directly to the SkM44 version
99 canvas_->concat(SkM44(mxx, mxy, 0, mxt,
100 myx, myy, 0, myt,
101 0, 0, 1, 0,
102 0, 0, 0, 1));
103}
104// full 4x4 transform in row major order
106 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
107 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
108 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
109 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
110 canvas_->concat(SkM44(mxx, mxy, mxz, mxt,
111 myx, myy, myz, myt,
112 mzx, mzy, mzz, mzt,
113 mwx, mwy, mwz, mwt));
114}
115// clang-format on
117 canvas_->setMatrix(original_transform_);
118}
119
121 ClipOp clip_op,
122 bool is_aa) {
123 canvas_->clipRect(rect, ToSk(clip_op), is_aa);
124}
126 ClipOp clip_op,
127 bool is_aa) {
128 canvas_->clipRRect(rrect, ToSk(clip_op), is_aa);
129}
131 ClipOp clip_op,
132 bool is_aa) {
133 canvas_->clipPath(path, ToSk(clip_op), is_aa);
134}
135
137 const SkPaint& sk_paint = paint();
138 SkImageFilter* filter = sk_paint.getImageFilter();
139 if (filter && !filter->asColorFilter(nullptr)) {
140 // drawPaint does an implicit saveLayer if an SkImageFilter is
141 // present that cannot be replaced by an SkColorFilter.
142 TRACE_EVENT0("flutter", "Canvas::saveLayer");
143 }
144 canvas_->drawPaint(sk_paint);
145}
147 // SkCanvas::drawColor(SkColor) does the following conversion anyway
148 // We do it here manually to increase precision on applying opacity
149 SkColor4f color4f = SkColor4f::FromColor(ToSk(color));
150 color4f.fA *= opacity();
151 canvas_->drawColor(color4f, ToSk(mode));
152}
154 canvas_->drawLine(p0, p1, paint());
155}
157 const DlPoint& p1,
158 DlScalar on_length,
159 DlScalar off_length) {
160 SkPaint dash_paint = paint();
161 SkScalar intervals[] = {on_length, off_length};
162 dash_paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f));
163 canvas_->drawLine(ToSkPoint(p0), ToSkPoint(p1), dash_paint);
164}
166 canvas_->drawRect(rect, paint());
167}
169 canvas_->drawOval(bounds, paint());
170}
172 canvas_->drawCircle(center, radius, paint());
173}
175 canvas_->drawRRect(rrect, paint());
176}
178 const SkRRect& inner) {
179 canvas_->drawDRRect(outer, inner, paint());
180}
182 canvas_->drawPath(path, paint());
183}
185 SkScalar start,
186 SkScalar sweep,
187 bool useCenter) {
188 canvas_->drawArc(bounds, start, sweep, useCenter, paint());
189}
191 uint32_t count,
192 const SkPoint pts[]) {
193 canvas_->drawPoints(ToSk(mode), count, pts, paint());
194}
197 canvas_->drawVertices(ToSk(vertices), ToSk(mode), paint());
198}
200 const SkPoint point,
202 bool render_with_attributes) {
203 canvas_->drawImage(image ? image->skia_image() : nullptr, point.fX, point.fY,
204 ToSk(sampling), safe_paint(render_with_attributes));
205}
207 const SkRect& src,
208 const SkRect& dst,
210 bool render_with_attributes,
211 SrcRectConstraint constraint) {
212 canvas_->drawImageRect(image ? image->skia_image() : nullptr, src, dst,
213 ToSk(sampling), safe_paint(render_with_attributes),
214 ToSk(constraint));
215}
217 const SkIRect& center,
218 const SkRect& dst,
219 DlFilterMode filter,
220 bool render_with_attributes) {
221 if (!image) {
222 return;
223 }
224 auto skia_image = image->skia_image();
225 if (!skia_image) {
226 return;
227 }
228 canvas_->drawImageNine(skia_image.get(), center, dst, ToSk(filter),
229 safe_paint(render_with_attributes));
230}
232 const SkRSXform xform[],
233 const SkRect tex[],
234 const DlColor colors[],
235 int count,
238 const SkRect* cullRect,
239 bool render_with_attributes) {
240 if (!atlas) {
241 return;
242 }
243 auto skia_atlas = atlas->skia_image();
244 if (!skia_atlas) {
245 return;
246 }
247 const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors);
248 canvas_->drawAtlas(skia_atlas.get(), xform, tex, sk_colors, count, ToSk(mode),
249 ToSk(sampling), cullRect,
250 safe_paint(render_with_attributes));
251}
253 const sk_sp<DisplayList> display_list,
254 SkScalar opacity) {
255 const int restore_count = canvas_->getSaveCount();
256
257 // Compute combined opacity and figure out whether we can apply it
258 // during dispatch or if we need a saveLayer.
260 if (combined_opacity < SK_Scalar1 &&
261 !display_list->can_apply_group_opacity()) {
262 TRACE_EVENT0("flutter", "Canvas::saveLayer");
263 canvas_->saveLayerAlphaf(&display_list->bounds(), combined_opacity);
265 } else {
266 canvas_->save();
267 }
268
269 // Create a new CanvasDispatcher to isolate the actions of the
270 // display_list from the current environment.
271 DlSkCanvasDispatcher dispatcher(canvas_, combined_opacity);
272 if (display_list->rtree()) {
273 display_list->Dispatch(dispatcher, canvas_->getLocalClipBounds());
274 } else {
275 display_list->Dispatch(dispatcher);
276 }
277
278 // Restore canvas state to what it was before dispatching.
279 canvas_->restoreToCount(restore_count);
280}
282 SkScalar x,
283 SkScalar y) {
284 canvas_->drawTextBlob(blob, x, y, paint());
285}
286
288 const std::shared_ptr<impeller::TextFrame>& text_frame,
289 SkScalar x,
290 SkScalar y) {
291 FML_CHECK(false);
292}
293
295 const SkPath& path,
297 float elevation,
298 bool transparentOccluder,
299 SkScalar dpr) {
300 const SkScalar kAmbientAlpha = 0.039f;
301 const SkScalar kSpotAlpha = 0.25f;
302
303 uint32_t flags = transparentOccluder
307 SkColor in_ambient =
308 SkColorSetA(ToSk(color), kAmbientAlpha * color.getAlpha());
309 SkColor in_spot = SkColorSetA(ToSk(color), kSpotAlpha * color.getAlpha());
310 SkColor ambient_color, spot_color;
311 SkShadowUtils::ComputeTonalColors(in_ambient, in_spot, &ambient_color,
312 &spot_color);
314 canvas, path, SkPoint3::Make(0, 0, dpr * elevation),
315 SkPoint3::Make(0, -1, 1),
317 ambient_color, spot_color, flags);
318}
319
321 const DlColor color,
322 const SkScalar elevation,
323 bool transparent_occluder,
324 SkScalar dpr) {
325 DrawShadow(canvas_, path, color, elevation, transparent_occluder, dpr);
326}
327
328} // namespace flutter
const char * options
int count
Definition: FontMgrTest.cpp:50
uint32_t SkColor
Definition: SkColor.h:37
static constexpr SkColor SkColorSetA(SkColor c, U8CPU a)
Definition: SkColor.h:82
#define SK_Scalar1
Definition: SkScalar.h:18
@ kDirectionalLight_ShadowFlag
Definition: SkShadowUtils.h:31
@ kTransparentOccluder_ShadowFlag
Definition: SkShadowUtils.h:27
@ kNone_ShadowFlag
Definition: SkShadowUtils.h:24
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition: SkCanvas.cpp:496
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
void drawOval(const SkRect &oval, const SkPaint &paint)
Definition: SkCanvas.cpp:1698
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
Definition: SkCanvas.cpp:1710
void restore()
Definition: SkCanvas.cpp:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawImageNine(const SkImage *image, const SkIRect &center, const SkRect &dst, SkFilterMode filter, const SkPaint *paint=nullptr)
Definition: SkCanvas.cpp:1769
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
SkRect getLocalClipBounds() const
Definition: SkCanvas.cpp:1586
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
int getSaveCount() const
Definition: SkCanvas.cpp:431
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
void restoreToCount(int saveCount)
Definition: SkCanvas.cpp:478
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
Definition: SkCanvas.cpp:1705
void drawArc(const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const SkPaint &paint)
Definition: SkCanvas.cpp:2728
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1456
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
Definition: SkCanvas.cpp:2333
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void drawAtlas(const SkImage *atlas, const SkRSXform xform[], const SkRect tex[], const SkColor colors[], int count, SkBlendMode mode, const SkSamplingOptions &sampling, const SkRect *cullRect, const SkPaint *paint)
Definition: SkCanvas.cpp:1810
void setMatrix(const SkM44 &matrix)
Definition: SkCanvas.cpp:1349
void drawDRRect(const SkRRect &outer, const SkRRect &inner, const SkPaint &paint)
Definition: SkCanvas.cpp:1645
void scale(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1289
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
Definition: SkCanvas.cpp:1720
void skew(SkScalar sx, SkScalar sy)
Definition: SkCanvas.cpp:1312
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
Definition: SkCanvas.cpp:2484
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition: SkCanvas.h:1528
void clipRRect(const SkRRect &rrect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1439
int saveLayerAlphaf(const SkRect *bounds, float alpha)
Definition: SkCanvas.cpp:1077
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
bool asColorFilter(SkColorFilter **filterPtr) const
Definition: SkImageFilter.h:67
Definition: SkM44.h:150
void setPathEffect(sk_sp< SkPathEffect > pathEffect)
SkImageFilter * getImageFilter() const
Definition: SkPaint.h:564
void setAlphaf(float a)
Definition: SkPaint.cpp:130
Definition: SkPath.h:59
static void DrawShadow(SkCanvas *canvas, const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, SkColor ambientColor, SkColor spotColor, uint32_t flags=SkShadowFlags::kNone_ShadowFlag)
static void ComputeTonalColors(SkColor inAmbientColor, SkColor inSpotColor, SkColor *outAmbientColor, SkColor *outSpotColor)
static constexpr SkScalar kShadowLightRadius
Definition: dl_canvas.h:231
static constexpr SkScalar kShadowLightHeight
Definition: dl_canvas.h:230
Backend implementation of |DlOpReceiver| for |SkCanvas|.
void drawTextBlob(const sk_sp< SkTextBlob > blob, SkScalar x, SkScalar y) override
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, SkScalar x, SkScalar y) override
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myt) override
void drawPoints(PointMode mode, uint32_t count, const SkPoint pts[]) override
void drawImageNine(const sk_sp< DlImage > image, const SkIRect &center, const SkRect &dst, DlFilterMode filter, bool render_with_attributes) override
void drawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length) override
const SkPaint * safe_paint(bool use_attributes)
void drawRRect(const SkRRect &rrect) override
void drawCircle(const SkPoint &center, SkScalar radius) override
void drawPath(const SkPath &path) override
void drawArc(const SkRect &bounds, SkScalar start, SkScalar sweep, bool useCenter) override
void drawShadow(const SkPath &path, const DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override
void drawImage(const sk_sp< DlImage > image, const SkPoint point, DlImageSampling sampling, bool render_with_attributes) override
void drawOval(const SkRect &bounds) override
void clipRect(const SkRect &rect, ClipOp clip_op, bool is_aa) override
void rotate(SkScalar degrees) override
void translate(SkScalar tx, SkScalar ty) override
void drawColor(DlColor color, DlBlendMode mode) override
void drawDisplayList(const sk_sp< DisplayList > display_list, SkScalar opacity) override
static void DrawShadow(SkCanvas *canvas, const SkPath &path, DlColor color, float elevation, bool transparentOccluder, SkScalar dpr)
void drawLine(const SkPoint &p0, const SkPoint &p1) override
void drawVertices(const DlVertices *vertices, DlBlendMode mode) override
void skew(SkScalar sx, SkScalar sy) override
void drawRect(const SkRect &rect) override
void transformFullPerspective(SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override
void clipPath(const SkPath &path, ClipOp clip_op, bool is_aa) override
void drawAtlas(const sk_sp< DlImage > atlas, const SkRSXform xform[], const SkRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const SkRect *cullRect, bool render_with_attributes) override
void saveLayer(const SkRect &bounds, const SaveLayerOptions options, const DlImageFilter *backdrop) override
void clipRRect(const SkRRect &rrect, ClipOp clip_op, bool is_aa) override
void scale(SkScalar sx, SkScalar sy) override
void drawDRRect(const SkRRect &outer, const SkRRect &inner) override
void drawImageRect(const sk_sp< DlImage > image, const SkRect &src, const SkRect &dst, DlImageSampling sampling, bool render_with_attributes, SrcRectConstraint constraint) override
const SkPaint & paint(bool uses_shader=true)
void save_opacity(SkScalar opacity_for_children)
Holds all of the data (both required and optional) for a DisplayList drawVertices call.
Definition: dl_vertices.h:71
T * get() const
Definition: SkRefCnt.h:303
DlColor color
float SkScalar
Definition: extension.cpp:12
FlutterSemanticsFlag flags
#define FML_CHECK(condition)
Definition: logging.h:85
double y
double x
sk_sp< const SkImage > atlas
Definition: SkRecords.h:331
Optional< SkRect > bounds
Definition: SkRecords.h:189
sk_sp< const SkImage > image
Definition: SkRecords.h:269
sk_sp< const SkImageFilter > backdrop
Definition: SkRecords.h:191
SkRRect rrect
Definition: SkRecords.h:232
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkSamplingOptions sampling
Definition: SkRecords.h:337
impeller::Scalar DlScalar
SkPaint ToSk(const DlPaint &paint)
const SkPoint & ToSkPoint(const DlPoint &point)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
Definition: switches.h:228
dst
Definition: cp.py:12
Definition: SkRect.h:32
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition: SkPoint3.h:18
float fX
x-axis value
Definition: SkPoint_impl.h:164
float fY
y-axis value
Definition: SkPoint_impl.h:165
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:131