Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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
13
14namespace flutter {
15
16const SkPaint* DlSkCanvasDispatcher::safe_paint(bool use_attributes) {
17 if (use_attributes) {
18 // The accumulated SkPaint object will already have incorporated
19 // any attribute overrides.
20 // Any rendering operation that uses an optional paint will ignore
21 // the shader in the paint so we inform that |paint()| method so
22 // that it can set the dither flag appropriately.
23 return &paint(false);
24 } else if (has_opacity()) {
25 temp_paint_.setAlphaf(opacity());
26 return &temp_paint_;
27 } else {
28 return nullptr;
29 }
30}
31
33 canvas_->save();
34 // save has no impact on attributes, but it needs to register a record
35 // on the restore stack so that the eventual call to restore() will
36 // know what to do at that time. We could annotate the restore record
37 // with a flag that the record came from a save call, but it is simpler
38 // to just pass in the current opacity value as the value to be used by
39 // the children and let the utility calls notice that it didn't change.
41}
43 canvas_->restore();
45}
48 const DlImageFilter* backdrop) {
49 if (!options.content_is_clipped() && options.can_distribute_opacity() &&
50 backdrop == nullptr) {
51 // We know that:
52 // - no bounds is needed for clipping here
53 // - no backdrop filter is used to initialize the layer
54 // - the current attributes only have an alpha
55 // - the children are compatible with individually rendering with
56 // an inherited opacity
57 // Therefore we can just use a save instead of a saveLayer and pass the
58 // intended opacity to the children.
59 canvas_->save();
60 // If the saveLayer does not use attributes, the children should continue
61 // to render with the inherited opacity unmodified. If attributes are to
62 // be applied, the children should render with the combination of the
63 // inherited opacity combined with the alpha from the current color.
64 save_opacity(options.renders_with_attributes() ? combined_opacity()
65 : opacity());
66 } else {
67 TRACE_EVENT0("flutter", "Canvas::saveLayer");
68 const SkPaint* paint = safe_paint(options.renders_with_attributes());
69 const sk_sp<SkImageFilter> sk_backdrop = ToSk(backdrop);
70 const SkRect* sl_bounds = options.bounds_from_caller() ? &bounds : nullptr;
71 canvas_->saveLayer(
72 SkCanvas::SaveLayerRec(sl_bounds, paint, sk_backdrop.get(), 0));
73 // saveLayer will apply the current opacity on behalf of the children
74 // so they will inherit an opaque opacity.
76 }
77}
78
80 canvas_->translate(tx, ty);
81}
83 canvas_->scale(sx, sy);
84}
86 canvas_->rotate(degrees);
87}
89 canvas_->skew(sx, sy);
90}
91// clang-format off
92// 2x3 2D affine subset of a 4x4 transform in row major order
94 SkScalar mxx, SkScalar mxy, SkScalar mxt,
95 SkScalar myx, SkScalar myy, SkScalar myt) {
96 // Internally concat(SkMatrix) gets redirected to concat(SkM44)
97 // so we just jump directly to the SkM44 version
98 canvas_->concat(SkM44(mxx, mxy, 0, mxt,
99 myx, myy, 0, myt,
100 0, 0, 1, 0,
101 0, 0, 0, 1));
102}
103// full 4x4 transform in row major order
105 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
106 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
107 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
108 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
109 canvas_->concat(SkM44(mxx, mxy, mxz, mxt,
110 myx, myy, myz, myt,
111 mzx, mzy, mzz, mzt,
112 mwx, mwy, mwz, mwt));
113}
114// clang-format on
116 canvas_->setMatrix(original_transform_);
117}
118
120 ClipOp clip_op,
121 bool is_aa) {
122 canvas_->clipRect(rect, ToSk(clip_op), is_aa);
123}
125 ClipOp clip_op,
126 bool is_aa) {
127 canvas_->clipRRect(rrect, ToSk(clip_op), is_aa);
128}
130 ClipOp clip_op,
131 bool is_aa) {
132 canvas_->clipPath(path, ToSk(clip_op), is_aa);
133}
134
136 const SkPaint& sk_paint = paint();
137 SkImageFilter* filter = sk_paint.getImageFilter();
138 if (filter && !filter->asColorFilter(nullptr)) {
139 // drawPaint does an implicit saveLayer if an SkImageFilter is
140 // present that cannot be replaced by an SkColorFilter.
141 TRACE_EVENT0("flutter", "Canvas::saveLayer");
142 }
143 canvas_->drawPaint(sk_paint);
144}
146 // SkCanvas::drawColor(SkColor) does the following conversion anyway
147 // We do it here manually to increase precision on applying opacity
149 color4f.fA *= opacity();
150 canvas_->drawColor(color4f, ToSk(mode));
151}
153 canvas_->drawLine(p0, p1, paint());
154}
156 canvas_->drawRect(rect, paint());
157}
159 canvas_->drawOval(bounds, paint());
160}
162 canvas_->drawCircle(center, radius, paint());
163}
165 canvas_->drawRRect(rrect, paint());
166}
168 const SkRRect& inner) {
169 canvas_->drawDRRect(outer, inner, paint());
170}
172 canvas_->drawPath(path, paint());
173}
176 SkScalar sweep,
177 bool useCenter) {
178 canvas_->drawArc(bounds, start, sweep, useCenter, paint());
179}
181 uint32_t count,
182 const SkPoint pts[]) {
183 canvas_->drawPoints(ToSk(mode), count, pts, paint());
184}
187 canvas_->drawVertices(ToSk(vertices), ToSk(mode), paint());
188}
190 const SkPoint point,
191 DlImageSampling sampling,
192 bool render_with_attributes) {
193 canvas_->drawImage(image ? image->skia_image() : nullptr, point.fX, point.fY,
194 ToSk(sampling), safe_paint(render_with_attributes));
195}
197 const SkRect& src,
198 const SkRect& dst,
199 DlImageSampling sampling,
200 bool render_with_attributes,
201 SrcRectConstraint constraint) {
202 canvas_->drawImageRect(image ? image->skia_image() : nullptr, src, dst,
203 ToSk(sampling), safe_paint(render_with_attributes),
204 ToSk(constraint));
205}
207 const SkIRect& center,
208 const SkRect& dst,
209 DlFilterMode filter,
210 bool render_with_attributes) {
211 if (!image) {
212 return;
213 }
214 auto skia_image = image->skia_image();
215 if (!skia_image) {
216 return;
217 }
218 canvas_->drawImageNine(skia_image.get(), center, dst, ToSk(filter),
219 safe_paint(render_with_attributes));
220}
222 const SkRSXform xform[],
223 const SkRect tex[],
224 const DlColor colors[],
225 int count,
227 DlImageSampling sampling,
228 const SkRect* cullRect,
229 bool render_with_attributes) {
230 if (!atlas) {
231 return;
232 }
233 auto skia_atlas = atlas->skia_image();
234 if (!skia_atlas) {
235 return;
236 }
237 const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors);
238 canvas_->drawAtlas(skia_atlas.get(), xform, tex, sk_colors, count, ToSk(mode),
239 ToSk(sampling), cullRect,
240 safe_paint(render_with_attributes));
241}
243 const sk_sp<DisplayList> display_list,
244 SkScalar opacity) {
245 const int restore_count = canvas_->getSaveCount();
246
247 // Compute combined opacity and figure out whether we can apply it
248 // during dispatch or if we need a saveLayer.
250 if (combined_opacity < SK_Scalar1 &&
251 !display_list->can_apply_group_opacity()) {
252 TRACE_EVENT0("flutter", "Canvas::saveLayer");
253 canvas_->saveLayerAlphaf(&display_list->bounds(), combined_opacity);
255 } else {
256 canvas_->save();
257 }
258
259 // Create a new CanvasDispatcher to isolate the actions of the
260 // display_list from the current environment.
261 DlSkCanvasDispatcher dispatcher(canvas_, combined_opacity);
262 if (display_list->rtree()) {
263 display_list->Dispatch(dispatcher, canvas_->getLocalClipBounds());
264 } else {
265 display_list->Dispatch(dispatcher);
266 }
267
268 // Restore canvas state to what it was before dispatching.
269 canvas_->restoreToCount(restore_count);
270}
272 SkScalar x,
273 SkScalar y) {
274 canvas_->drawTextBlob(blob, x, y, paint());
275}
276
278 const std::shared_ptr<impeller::TextFrame>& text_frame,
279 SkScalar x,
280 SkScalar y) {
281 FML_CHECK(false);
282}
283
285 const SkPath& path,
287 float elevation,
288 bool transparentOccluder,
289 SkScalar dpr) {
290 const SkScalar kAmbientAlpha = 0.039f;
291 const SkScalar kSpotAlpha = 0.25f;
292
293 uint32_t flags = transparentOccluder
297 SkColor in_ambient =
298 SkColorSetA(ToSk(color), kAmbientAlpha * color.getAlpha());
299 SkColor in_spot = SkColorSetA(ToSk(color), kSpotAlpha * color.getAlpha());
300 SkColor ambient_color, spot_color;
301 SkShadowUtils::ComputeTonalColors(in_ambient, in_spot, &ambient_color,
302 &spot_color);
304 canvas, path, SkPoint3::Make(0, 0, dpr * elevation),
305 SkPoint3::Make(0, -1, 1),
307 ambient_color, spot_color, flags);
308}
309
311 const DlColor color,
312 const SkScalar elevation,
313 bool transparent_occluder,
314 SkScalar dpr) {
315 DrawShadow(canvas_, path, color, elevation, transparent_occluder, dpr);
316}
317
318} // namespace flutter
const char * options
int count
SkColor4f color
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
@ kTransparentOccluder_ShadowFlag
@ kNone_ShadowFlag
static SkScalar center(float pos0, float pos1)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
Definition SkCanvas.cpp:500
void drawRect(const SkRect &rect, const SkPaint &paint)
void drawOval(const SkRect &oval, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void drawImageNine(const SkImage *image, const SkIRect &center, const SkRect &dst, SkFilterMode filter, const SkPaint *paint=nullptr)
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition SkCanvas.h:1182
SkRect getLocalClipBounds() const
void drawPaint(const SkPaint &paint)
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
int getSaveCount() const
Definition SkCanvas.cpp:435
void rotate(SkScalar degrees)
void restoreToCount(int saveCount)
Definition SkCanvas.cpp:482
void drawRRect(const SkRRect &rrect, const SkPaint &paint)
void drawArc(const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, const SkPaint &paint)
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
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)
void setMatrix(const SkM44 &matrix)
void drawDRRect(const SkRRect &outer, const SkRRect &inner, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void concat(const SkMatrix &matrix)
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
void skew(SkScalar sx, SkScalar sy)
void drawTextBlob(const SkTextBlob *blob, SkScalar x, SkScalar y, const SkPaint &paint)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
Definition SkCanvas.h:1528
void clipRRect(const SkRRect &rrect, SkClipOp op, bool doAntiAlias)
int saveLayerAlphaf(const SkRect *bounds, float alpha)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
bool asColorFilter(SkColorFilter **filterPtr) const
Definition SkM44.h:150
SkImageFilter * getImageFilter() const
Definition SkPaint.h:564
void setAlphaf(float a)
Definition SkPaint.cpp:130
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:225
static constexpr SkScalar kShadowLightHeight
Definition dl_canvas.h:224
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
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
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
const Paint & paint
sk_sp< SkImage > image
Definition examples.cpp:29
float SkScalar
Definition extension.cpp:12
FlutterSemanticsFlag flags
#define FML_CHECK(condition)
Definition logging.h:85
double y
double x
SkPaint ToSk(const DlPaint &paint)
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
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition SkPoint3.h:18
float fX
x-axis value
float fY
y-axis value
static SkRGBA4f FromColor(SkColor color)
#define TRACE_EVENT0(category_group, name)