Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
dl_sk_canvas.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#if !SLIMPELLER
6
9
15
16#include "third_party/skia/include/core/SkColorFilter.h"
17#include "third_party/skia/include/effects/SkDashPathEffect.h"
18#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
19#include "third_party/skia/include/gpu/ganesh/GrRecordingContext.h"
20
21namespace flutter {
22
24 public:
25 // SkOptionalPaint is only valid for ops that do not use the ColorSource
26 explicit SkOptionalPaint(const DlPaint* dl_paint) {
27 if (dl_paint && !dl_paint->isDefault()) {
28 sk_paint_ = ToNonShaderSk(*dl_paint);
29 ptr_ = &sk_paint_;
30 } else {
31 ptr_ = nullptr;
32 }
33 }
34
35 SkPaint* operator()() { return ptr_; }
36
37 private:
38 SkPaint sk_paint_;
39 SkPaint* ptr_;
40};
41
42void DlSkCanvasAdapter::set_canvas(SkCanvas* canvas) {
43 delegate_ = canvas;
44}
45
47 return ToDlISize(delegate_->getBaseLayerSize());
48}
49
51 return delegate_->imageInfo();
52}
53
55 delegate_->save();
56}
57
58void DlSkCanvasAdapter::SaveLayer(const std::optional<DlRect>& bounds,
59 const DlPaint* paint,
60 const DlImageFilter* backdrop,
61 std::optional<int64_t> backdrop_id) {
62 sk_sp<SkImageFilter> sk_backdrop = ToSk(backdrop);
63 SkOptionalPaint sk_paint(paint);
64 TRACE_EVENT0("flutter", "Canvas::saveLayer");
65 SkCanvas::SaveLayerRec params(ToSkRect(bounds), sk_paint(), sk_backdrop.get(),
66 0);
67 if (sk_backdrop && backdrop->asBlur()) {
68 params.fBackdropTileMode = ToSk(backdrop->asBlur()->tile_mode());
69 }
70 delegate_->saveLayer(params);
71}
72
74 delegate_->restore();
75}
76
78 return delegate_->getSaveCount();
79}
80
81void DlSkCanvasAdapter::RestoreToCount(int restore_count) {
82 delegate_->restoreToCount(restore_count);
83}
84
85void DlSkCanvasAdapter::Translate(SkScalar tx, SkScalar ty) {
86 delegate_->translate(tx, ty);
87}
88
89void DlSkCanvasAdapter::Scale(SkScalar sx, SkScalar sy) {
90 delegate_->scale(sx, sy);
91}
92
93void DlSkCanvasAdapter::Rotate(SkScalar degrees) {
94 delegate_->rotate(degrees);
95}
96
97void DlSkCanvasAdapter::Skew(SkScalar sx, SkScalar sy) {
98 delegate_->skew(sx, sy);
99}
100
101// clang-format off
102
103// 2x3 2D affine subset of a 4x4 transform in row major order
105 SkScalar mxx, SkScalar mxy, SkScalar mxt,
106 SkScalar myx, SkScalar myy, SkScalar myt) {
107 delegate_->concat(SkMatrix::MakeAll(mxx, mxy, mxt, myx, myy, myt, 0, 0, 1));
108}
109
110// full 4x4 transform in row major order
112 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
113 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
114 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
115 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
116 delegate_->concat(SkM44(mxx, mxy, mxz, mxt,
117 myx, myy, myz, myt,
118 mzx, mzy, mzz, mzt,
119 mwx, mwy, mwz, mwt));
120}
121
122// clang-format on
123
125 delegate_->resetMatrix();
126}
127
129 delegate_->concat(ToSkM44(matrix));
130}
131
133 delegate_->setMatrix(ToSkM44(matrix));
134}
135
136/// Returns the 4x4 full perspective transform representing all transform
137/// operations executed so far in this DisplayList within the enclosing
138/// save stack.
140 return ToDlMatrix(delegate_->getLocalToDevice());
141}
142
144 DlClipOp clip_op,
145 bool is_aa) {
146 delegate_->clipRect(ToSkRect(rect), ToSk(clip_op), is_aa);
147}
148
150 DlClipOp clip_op,
151 bool is_aa) {
152 delegate_->clipRRect(SkRRect::MakeOval(ToSkRect(bounds)), ToSk(clip_op),
153 is_aa);
154}
155
157 DlClipOp clip_op,
158 bool is_aa) {
159 delegate_->clipRRect(ToSkRRect(rrect), ToSk(clip_op), is_aa);
160}
161
163 DlClipOp clip_op,
164 bool is_aa) {
165 // Skia doesn't support round superellipse, thus fall back to round rectangle.
166 delegate_->clipRRect(ToApproximateSkRRect(rse), ToSk(clip_op), is_aa);
167}
168
170 DlClipOp clip_op,
171 bool is_aa) {
172 path.WillRenderSkPath();
173 delegate_->clipPath(path.GetSkPath(), ToSk(clip_op), is_aa);
174}
175
176/// Conservative estimate of the bounds of all outstanding clip operations
177/// measured in the coordinate space within which this DisplayList will
178/// be rendered.
180 return ToDlRect(delegate_->getDeviceClipBounds());
181}
182
183/// Conservative estimate of the bounds of all outstanding clip operations
184/// transformed into the local coordinate space in which currently
185/// recorded rendering operations are interpreted.
187 return ToDlRect(delegate_->getLocalClipBounds());
188}
189
190/// Return true iff the supplied bounds are easily shown to be outside
191/// of the current clip bounds. This method may conservatively return
192/// false if it cannot make the determination.
193bool DlSkCanvasAdapter::QuickReject(const DlRect& bounds) const {
194 return delegate_->quickReject(ToSkRect(bounds));
195}
196
198 delegate_->drawPaint(ToSk(paint));
199}
200
202 delegate_->drawColor(ToSkColor4f(color), ToSk(mode));
203}
204
206 const DlPoint& p1,
207 const DlPaint& paint) {
208 delegate_->drawLine(ToSkPoint(p0), ToSkPoint(p1), ToStrokedSk(paint));
209}
210
212 const DlPoint& p1,
213 DlScalar on_length,
214 DlScalar off_length,
215 const DlPaint& paint) {
216 SkPaint dashed_paint = ToStrokedSk(paint);
217 SkScalar intervals[2] = {on_length, off_length};
218 dashed_paint.setPathEffect(SkDashPathEffect::Make({intervals, 2}, 0.0f));
219 delegate_->drawLine(ToSkPoint(p0), ToSkPoint(p1), dashed_paint);
220}
221
222void DlSkCanvasAdapter::DrawRect(const DlRect& rect, const DlPaint& paint) {
223 delegate_->drawRect(ToSkRect(rect), ToSk(paint));
224}
225
226void DlSkCanvasAdapter::DrawOval(const DlRect& bounds, const DlPaint& paint) {
227 delegate_->drawOval(ToSkRect(bounds), ToSk(paint));
228}
229
231 SkScalar radius,
232 const DlPaint& paint) {
233 delegate_->drawCircle(ToSkPoint(center), radius, ToSk(paint));
234}
235
237 const DlPaint& paint) {
238 delegate_->drawRRect(ToSkRRect(rrect), ToSk(paint));
239}
240
242 const DlRoundRect& inner,
243 const DlPaint& paint) {
244 delegate_->drawDRRect(ToSkRRect(outer), ToSkRRect(inner), ToSk(paint));
245}
246
248 const DlPaint& paint) {
249 // Skia doesn't support round superellipse, thus fall back to round rectangle.
250 delegate_->drawRRect(ToApproximateSkRRect(rse), ToSk(paint));
251}
252
253void DlSkCanvasAdapter::DrawPath(const DlPath& path, const DlPaint& paint) {
254 path.WillRenderSkPath();
255 delegate_->drawPath(path.GetSkPath(), ToSk(paint));
256}
257
259 DlScalar start,
260 DlScalar sweep,
261 bool useCenter,
262 const DlPaint& paint) {
263 delegate_->drawArc(ToSkRect(bounds), start, sweep, useCenter, ToSk(paint));
264}
265
267 uint32_t count,
268 const DlPoint pts[],
269 const DlPaint& paint) {
270 delegate_->drawPoints(ToSk(mode), {ToSkPoints(pts), count},
271 ToStrokedSk(paint));
272}
273
275 const std::shared_ptr<DlVertices>& vertices,
276 DlBlendMode mode,
277 const DlPaint& paint) {
278 delegate_->drawVertices(ToSk(vertices), ToSk(mode), ToSk(paint));
279}
280
281void DlSkCanvasAdapter::DrawImage(const sk_sp<DlImage>& image,
282 const DlPoint& point,
283 DlImageSampling sampling,
284 const DlPaint* paint) {
285 SkOptionalPaint sk_paint(paint);
287 auto skia_image = image->asSkiaImage();
288 FML_DCHECK(skia_image);
289 delegate_->drawImage(skia_image->skia_image().get(), point.x, point.y,
290 ToSk(sampling), sk_paint());
291}
292
293void DlSkCanvasAdapter::DrawImageRect(const sk_sp<DlImage>& image,
294 const DlRect& src,
295 const DlRect& dst,
296 DlImageSampling sampling,
297 const DlPaint* paint,
298 DlSrcRectConstraint constraint) {
299 SkOptionalPaint sk_paint(paint);
301 auto skia_image = image->asSkiaImage();
302 FML_DCHECK(skia_image);
303 delegate_->drawImageRect(skia_image->skia_image().get(), ToSkRect(src),
304 ToSkRect(dst), ToSk(sampling), sk_paint(),
305 ToSk(constraint));
306}
307
308void DlSkCanvasAdapter::DrawImageNine(const sk_sp<DlImage>& image,
309 const DlIRect& center,
310 const DlRect& dst,
311 DlFilterMode filter,
312 const DlPaint* paint) {
313 SkOptionalPaint sk_paint(paint);
315 auto skia_image = image->asSkiaImage();
316 FML_DCHECK(skia_image);
317 delegate_->drawImageNine(skia_image->skia_image().get(), ToSkIRect(center),
318 ToSkRect(dst), ToSk(filter), sk_paint());
319}
320
321void DlSkCanvasAdapter::DrawAtlas(const sk_sp<DlImage>& atlas,
322 const DlRSTransform xform[],
323 const DlRect tex[],
324 const DlColor colors[],
325 int count,
326 DlBlendMode mode,
327 DlImageSampling sampling,
328 const DlRect* cullRect,
329 const DlPaint* paint) {
330 SkOptionalPaint sk_paint(paint);
331 FML_DCHECK(atlas);
332 auto skia_atlas = atlas->asSkiaImage();
333 FML_DCHECK(skia_atlas);
334 std::vector<SkColor> sk_colors;
335 sk_colors.reserve(count);
336 for (int i = 0; i < count; ++i) {
337 sk_colors.push_back(colors[i].argb());
338 }
339 delegate_->drawAtlas(skia_atlas->skia_image().get(), {ToSk(xform), count},
340 {ToSkRects(tex), count}, {sk_colors.data(), count},
341 ToSk(mode), ToSk(sampling), ToSkRect(cullRect),
342 sk_paint());
343}
344
345void DlSkCanvasAdapter::DrawDisplayList(const sk_sp<DisplayList> display_list,
346 SkScalar opacity) {
347 const int restore_count = delegate_->getSaveCount();
348
349 // Figure out whether we can apply the opacity during dispatch or
350 // if we need a saveLayer.
351 if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
352 TRACE_EVENT0("flutter", "Canvas::saveLayer");
353 delegate_->saveLayerAlphaf(ToSkRect(&display_list->GetBounds()), opacity);
354 opacity = SK_Scalar1;
355 } else {
356 delegate_->save();
357 }
358
359 DlSkCanvasDispatcher dispatcher(delegate_, opacity);
360 if (display_list->has_rtree()) {
361 display_list->Dispatch(dispatcher,
362 ToDlRect(delegate_->getLocalClipBounds()));
363 } else {
364 display_list->Dispatch(dispatcher);
365 }
366
367 delegate_->restoreToCount(restore_count);
368}
369
370void DlSkCanvasAdapter::DrawText(const std::shared_ptr<DlText>& text,
371 SkScalar x,
372 SkScalar y,
373 const DlPaint& paint) {
374 auto blob = text->GetTextBlob();
375 FML_CHECK(blob) << "Impeller DlText cannot be drawn to a Skia canvas.";
376 delegate_->drawTextBlob(blob, x, y, ToSk(paint));
377}
378
380 const DlColor color,
381 const SkScalar elevation,
382 bool transparent_occluder,
383 SkScalar dpr) {
384 path.WillRenderSkPath();
385 DlSkCanvasDispatcher::DrawShadow(delegate_, path.GetSkPath(), color,
386 elevation, transparent_occluder, dpr);
387}
388
390#if defined(SK_GANESH)
391 auto dContext = GrAsDirectContext(delegate_->recordingContext());
392
393 if (dContext) {
394 dContext->flushAndSubmit();
395 }
396#endif // defined(SK_GANESH)
397}
398
399} // namespace flutter
400
401#endif // !SLIMPELLER
virtual const DlBlurImageFilter * asBlur() const
bool isDefault() const
Definition dl_paint.h:198
void DrawRect(const DlRect &rect, const DlPaint &paint) override
void Transform(const DlMatrix &matrix) override
void Scale(DlScalar sx, DlScalar sy) override
void Rotate(DlScalar degrees) override
int GetSaveCount() const override
void ClipOval(const DlRect &bounds, DlClipOp clip_op, bool is_aa) override
void DrawRoundSuperellipse(const DlRoundSuperellipse &rse, const DlPaint &paint) override
void TransformFullPerspective(DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt, DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt, DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override
void TransformReset() override
void Skew(DlScalar sx, DlScalar sy) override
void DrawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[], const DlPaint &paint) override
void DrawColor(DlColor color, DlBlendMode mode) override
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void SetTransform(const DlMatrix &matrix) override
void ClipPath(const DlPath &path, DlClipOp clip_op, bool is_aa) override
void DrawPath(const DlPath &path, const DlPaint &paint) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
DlISize GetBaseLayerDimensions() const override
void Translate(DlScalar tx, DlScalar ty) override
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
DlMatrix GetMatrix() const override
void DrawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner, const DlPaint &paint) override
void DrawShadow(const DlPath &path, const DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
Draws the shadow of the given |path| rendered in the provided |color| (which is only consulted for it...
DlRect GetLocalClipCoverage() const override
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint) override
DlRect GetDestinationClipCoverage() const override
void DrawAtlas(const sk_sp< DlImage > &atlas, const DlRSTransform xform[], const DlRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const DlRect *cullRect, const DlPaint *paint=nullptr) override
void ClipRect(const DlRect &rect, DlClipOp clip_op, bool is_aa) override
void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint) override
void ClipRoundSuperellipse(const DlRoundSuperellipse &rse, DlClipOp clip_op, bool is_aa) override
bool QuickReject(const DlRect &bounds) const override
void DrawImageNine(const sk_sp< DlImage > &image, const DlIRect &center, const DlRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr) override
void DrawCircle(const DlPoint &center, DlScalar radius, const DlPaint &paint) override
void DrawText(const std::shared_ptr< DlText > &text, DlScalar x, DlScalar y, const DlPaint &paint) override
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawDisplayList(const sk_sp< DisplayList > display_list, DlScalar opacity=SK_Scalar1) override
void set_canvas(SkCanvas *canvas)
void DrawOval(const DlRect &bounds, const DlPaint &paint) override
void DrawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length, const DlPaint &paint) override
void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op, bool is_aa) override
void RestoreToCount(int restore_count) override
SkImageInfo GetImageInfo() const override
void Transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
void DrawPaint(const DlPaint &paint) override
Backend implementation of |DlOpReceiver| for |SkCanvas|.
static void DrawShadow(SkCanvas *canvas, const SkPath &path, DlColor color, float elevation, bool transparentOccluder, DlScalar dpr)
SkOptionalPaint(const DlPaint *dl_paint)
int32_t x
const EmbeddedViewParams * params
FlutterVulkanImage * image
#define FML_CHECK(condition)
Definition logging.h:104
#define FML_DCHECK(condition)
Definition logging.h:122
std::u16string text
double y
impeller::Scalar DlScalar
SkPaint ToSk(const DlPaint &paint)
const SkPoint & ToSkPoint(const DlPoint &point)
const DlISize & ToDlISize(const SkISize &size)
const SkIRect & ToSkIRect(const DlIRect &rect)
const SkRRect ToApproximateSkRRect(const DlRoundSuperellipse &rse)
SkPaint ToStrokedSk(const DlPaint &paint)
DlPointMode
Definition dl_types.h:15
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 switch_defs.h:52
SkColor4f ToSkColor4f(DlColor color)
SkPaint ToNonShaderSk(const DlPaint &paint)
const SkPoint * ToSkPoints(const DlPoint *points)
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all 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
const SkRRect ToSkRRect(const DlRoundRect &round_rect)
DlMatrix ToDlMatrix(const SkMatrix &matrix)
SkM44 ToSkM44(const DlMatrix &matrix)
const DlRect & ToDlRect(const SkRect &rect)
const SkRect & ToSkRect(const DlRect &rect)
DlSrcRectConstraint
Definition dl_types.h:21
BlendMode
Definition color.h:58
A 4x4 matrix using column-major storage.
Definition matrix.h:37
const size_t start
#define TRACE_EVENT0(category_group, name)