Flutter Engine
 
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
8
14
15#include "third_party/skia/include/core/SkColorFilter.h"
16#include "third_party/skia/include/effects/SkDashPathEffect.h"
17#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
18#include "third_party/skia/include/gpu/ganesh/GrRecordingContext.h"
19
20namespace flutter {
21
23 public:
24 // SkOptionalPaint is only valid for ops that do not use the ColorSource
25 explicit SkOptionalPaint(const DlPaint* dl_paint) {
26 if (dl_paint && !dl_paint->isDefault()) {
27 sk_paint_ = ToNonShaderSk(*dl_paint);
28 ptr_ = &sk_paint_;
29 } else {
30 ptr_ = nullptr;
31 }
32 }
33
34 SkPaint* operator()() { return ptr_; }
35
36 private:
37 SkPaint sk_paint_;
38 SkPaint* ptr_;
39};
40
41void DlSkCanvasAdapter::set_canvas(SkCanvas* canvas) {
42 delegate_ = canvas;
43}
44
46 return ToDlISize(delegate_->getBaseLayerSize());
47}
48
50 return delegate_->imageInfo();
51}
52
54 delegate_->save();
55}
56
57void DlSkCanvasAdapter::SaveLayer(const std::optional<DlRect>& bounds,
58 const DlPaint* paint,
59 const DlImageFilter* backdrop,
60 std::optional<int64_t> backdrop_id) {
61 sk_sp<SkImageFilter> sk_backdrop = ToSk(backdrop);
62 SkOptionalPaint sk_paint(paint);
63 TRACE_EVENT0("flutter", "Canvas::saveLayer");
64 SkCanvas::SaveLayerRec params(ToSkRect(bounds), sk_paint(), sk_backdrop.get(),
65 0);
66 if (sk_backdrop && backdrop->asBlur()) {
67 params.fBackdropTileMode = ToSk(backdrop->asBlur()->tile_mode());
68 }
69 delegate_->saveLayer(params);
70}
71
73 delegate_->restore();
74}
75
77 return delegate_->getSaveCount();
78}
79
80void DlSkCanvasAdapter::RestoreToCount(int restore_count) {
81 delegate_->restoreToCount(restore_count);
82}
83
84void DlSkCanvasAdapter::Translate(SkScalar tx, SkScalar ty) {
85 delegate_->translate(tx, ty);
86}
87
88void DlSkCanvasAdapter::Scale(SkScalar sx, SkScalar sy) {
89 delegate_->scale(sx, sy);
90}
91
92void DlSkCanvasAdapter::Rotate(SkScalar degrees) {
93 delegate_->rotate(degrees);
94}
95
96void DlSkCanvasAdapter::Skew(SkScalar sx, SkScalar sy) {
97 delegate_->skew(sx, sy);
98}
99
100// clang-format off
101
102// 2x3 2D affine subset of a 4x4 transform in row major order
104 SkScalar mxx, SkScalar mxy, SkScalar mxt,
105 SkScalar myx, SkScalar myy, SkScalar myt) {
106 delegate_->concat(SkMatrix::MakeAll(mxx, mxy, mxt, myx, myy, myt, 0, 0, 1));
107}
108
109// full 4x4 transform in row major order
111 SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
112 SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
113 SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
114 SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
115 delegate_->concat(SkM44(mxx, mxy, mxz, mxt,
116 myx, myy, myz, myt,
117 mzx, mzy, mzz, mzt,
118 mwx, mwy, mwz, mwt));
119}
120
121// clang-format on
122
124 delegate_->resetMatrix();
125}
126
128 delegate_->concat(ToSkM44(matrix));
129}
130
132 delegate_->setMatrix(ToSkM44(matrix));
133}
134
135/// Returns the 4x4 full perspective transform representing all transform
136/// operations executed so far in this DisplayList within the enclosing
137/// save stack.
139 return ToDlMatrix(delegate_->getLocalToDevice());
140}
141
143 DlClipOp clip_op,
144 bool is_aa) {
145 delegate_->clipRect(ToSkRect(rect), ToSk(clip_op), is_aa);
146}
147
149 DlClipOp clip_op,
150 bool is_aa) {
151 delegate_->clipRRect(SkRRect::MakeOval(ToSkRect(bounds)), ToSk(clip_op),
152 is_aa);
153}
154
156 DlClipOp clip_op,
157 bool is_aa) {
158 delegate_->clipRRect(ToSkRRect(rrect), ToSk(clip_op), is_aa);
159}
160
162 DlClipOp clip_op,
163 bool is_aa) {
164 // Skia doesn't support round superellipse, thus fall back to round rectangle.
165 delegate_->clipRRect(ToApproximateSkRRect(rse), ToSk(clip_op), is_aa);
166}
167
169 DlClipOp clip_op,
170 bool is_aa) {
171 path.WillRenderSkPath();
172 delegate_->clipPath(path.GetSkPath(), ToSk(clip_op), is_aa);
173}
174
175/// Conservative estimate of the bounds of all outstanding clip operations
176/// measured in the coordinate space within which this DisplayList will
177/// be rendered.
179 return ToDlRect(delegate_->getDeviceClipBounds());
180}
181
182/// Conservative estimate of the bounds of all outstanding clip operations
183/// transformed into the local coordinate space in which currently
184/// recorded rendering operations are interpreted.
186 return ToDlRect(delegate_->getLocalClipBounds());
187}
188
189/// Return true iff the supplied bounds are easily shown to be outside
190/// of the current clip bounds. This method may conservatively return
191/// false if it cannot make the determination.
192bool DlSkCanvasAdapter::QuickReject(const DlRect& bounds) const {
193 return delegate_->quickReject(ToSkRect(bounds));
194}
195
197 delegate_->drawPaint(ToSk(paint));
198}
199
201 delegate_->drawColor(ToSkColor4f(color), ToSk(mode));
202}
203
205 const DlPoint& p1,
206 const DlPaint& paint) {
207 delegate_->drawLine(ToSkPoint(p0), ToSkPoint(p1), ToStrokedSk(paint));
208}
209
211 const DlPoint& p1,
212 DlScalar on_length,
213 DlScalar off_length,
214 const DlPaint& paint) {
215 SkPaint dashed_paint = ToStrokedSk(paint);
216 SkScalar intervals[2] = {on_length, off_length};
217 dashed_paint.setPathEffect(SkDashPathEffect::Make({intervals, 2}, 0.0f));
218 delegate_->drawLine(ToSkPoint(p0), ToSkPoint(p1), dashed_paint);
219}
220
221void DlSkCanvasAdapter::DrawRect(const DlRect& rect, const DlPaint& paint) {
222 delegate_->drawRect(ToSkRect(rect), ToSk(paint));
223}
224
225void DlSkCanvasAdapter::DrawOval(const DlRect& bounds, const DlPaint& paint) {
226 delegate_->drawOval(ToSkRect(bounds), ToSk(paint));
227}
228
230 SkScalar radius,
231 const DlPaint& paint) {
232 delegate_->drawCircle(ToSkPoint(center), radius, ToSk(paint));
233}
234
236 const DlPaint& paint) {
237 delegate_->drawRRect(ToSkRRect(rrect), ToSk(paint));
238}
239
241 const DlRoundRect& inner,
242 const DlPaint& paint) {
243 delegate_->drawDRRect(ToSkRRect(outer), ToSkRRect(inner), ToSk(paint));
244}
245
247 const DlPaint& paint) {
248 // Skia doesn't support round superellipse, thus fall back to round rectangle.
249 delegate_->drawRRect(ToApproximateSkRRect(rse), ToSk(paint));
250}
251
252void DlSkCanvasAdapter::DrawPath(const DlPath& path, const DlPaint& paint) {
253 path.WillRenderSkPath();
254 delegate_->drawPath(path.GetSkPath(), ToSk(paint));
255}
256
258 DlScalar start,
259 DlScalar sweep,
260 bool useCenter,
261 const DlPaint& paint) {
262 delegate_->drawArc(ToSkRect(bounds), start, sweep, useCenter, ToSk(paint));
263}
264
266 uint32_t count,
267 const DlPoint pts[],
268 const DlPaint& paint) {
269 delegate_->drawPoints(ToSk(mode), {ToSkPoints(pts), count},
270 ToStrokedSk(paint));
271}
272
274 const std::shared_ptr<DlVertices>& vertices,
275 DlBlendMode mode,
276 const DlPaint& paint) {
277 delegate_->drawVertices(ToSk(vertices), ToSk(mode), ToSk(paint));
278}
279
280void DlSkCanvasAdapter::DrawImage(const sk_sp<DlImage>& image,
281 const DlPoint& point,
282 DlImageSampling sampling,
283 const DlPaint* paint) {
284 SkOptionalPaint sk_paint(paint);
285 sk_sp<SkImage> sk_image = image->skia_image();
286 delegate_->drawImage(sk_image.get(), point.x, point.y, ToSk(sampling),
287 sk_paint());
288}
289
290void DlSkCanvasAdapter::DrawImageRect(const sk_sp<DlImage>& image,
291 const DlRect& src,
292 const DlRect& dst,
293 DlImageSampling sampling,
294 const DlPaint* paint,
295 DlSrcRectConstraint constraint) {
296 SkOptionalPaint sk_paint(paint);
297 sk_sp<SkImage> sk_image = image->skia_image();
298 delegate_->drawImageRect(sk_image.get(), ToSkRect(src), ToSkRect(dst),
299 ToSk(sampling), sk_paint(), ToSk(constraint));
300}
301
302void DlSkCanvasAdapter::DrawImageNine(const sk_sp<DlImage>& image,
303 const DlIRect& center,
304 const DlRect& dst,
305 DlFilterMode filter,
306 const DlPaint* paint) {
307 SkOptionalPaint sk_paint(paint);
308 sk_sp<SkImage> sk_image = image->skia_image();
309 delegate_->drawImageNine(sk_image.get(), ToSkIRect(center), ToSkRect(dst),
310 ToSk(filter), sk_paint());
311}
312
313void DlSkCanvasAdapter::DrawAtlas(const sk_sp<DlImage>& atlas,
314 const DlRSTransform xform[],
315 const DlRect tex[],
316 const DlColor colors[],
317 int count,
318 DlBlendMode mode,
319 DlImageSampling sampling,
320 const DlRect* cullRect,
321 const DlPaint* paint) {
322 SkOptionalPaint sk_paint(paint);
323 sk_sp<SkImage> sk_image = atlas->skia_image();
324 std::vector<SkColor> sk_colors;
325 sk_colors.reserve(count);
326 for (int i = 0; i < count; ++i) {
327 sk_colors.push_back(colors[i].argb());
328 }
329 delegate_->drawAtlas(sk_image.get(), {ToSk(xform), count},
330 {ToSkRects(tex), count}, {sk_colors.data(), count},
331 ToSk(mode), ToSk(sampling), ToSkRect(cullRect),
332 sk_paint());
333}
334
335void DlSkCanvasAdapter::DrawDisplayList(const sk_sp<DisplayList> display_list,
336 SkScalar opacity) {
337 const int restore_count = delegate_->getSaveCount();
338
339 // Figure out whether we can apply the opacity during dispatch or
340 // if we need a saveLayer.
341 if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
342 TRACE_EVENT0("flutter", "Canvas::saveLayer");
343 delegate_->saveLayerAlphaf(ToSkRect(&display_list->GetBounds()), opacity);
344 opacity = SK_Scalar1;
345 } else {
346 delegate_->save();
347 }
348
349 DlSkCanvasDispatcher dispatcher(delegate_, opacity);
350 if (display_list->has_rtree()) {
351 display_list->Dispatch(dispatcher,
352 ToDlRect(delegate_->getLocalClipBounds()));
353 } else {
354 display_list->Dispatch(dispatcher);
355 }
356
357 delegate_->restoreToCount(restore_count);
358}
359
360void DlSkCanvasAdapter::DrawText(const std::shared_ptr<DlText>& text,
361 SkScalar x,
362 SkScalar y,
363 const DlPaint& paint) {
364 auto blob = text->GetTextBlob();
365 FML_CHECK(blob) << "Impeller DlText cannot be drawn to a Skia canvas.";
366 delegate_->drawTextBlob(blob, x, y, ToSk(paint));
367}
368
370 const DlColor color,
371 const SkScalar elevation,
372 bool transparent_occluder,
373 SkScalar dpr) {
374 path.WillRenderSkPath();
375 DlSkCanvasDispatcher::DrawShadow(delegate_, path.GetSkPath(), color,
376 elevation, transparent_occluder, dpr);
377}
378
380#if defined(SK_GANESH)
381 auto dContext = GrAsDirectContext(delegate_->recordingContext());
382
383 if (dContext) {
384 dContext->flushAndSubmit();
385 }
386#endif // defined(SK_GANESH)
387}
388
389} // namespace flutter
390
391#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
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)