Skip to content

Commit d5cadd2

Browse files
authored
Build DisplayList directly from flutter::Canvas (flutter#29470)
1 parent ea2caa8 commit d5cadd2

13 files changed

+3631
-2026
lines changed

flow/display_list.cc

Lines changed: 295 additions & 50 deletions
Large diffs are not rendered by default.

flow/display_list.h

Lines changed: 447 additions & 21 deletions
Large diffs are not rendered by default.

flow/display_list_canvas.cc

Lines changed: 29 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ void DisplayListCanvasRecorder::willSave() {
261261
SkCanvas::SaveLayerStrategy DisplayListCanvasRecorder::getSaveLayerStrategy(
262262
const SaveLayerRec& rec) {
263263
if (rec.fPaint) {
264-
RecordPaintAttributes(rec.fPaint, DrawType::kSaveLayerOpType);
264+
builder_->setAttributesFromPaint(*rec.fPaint, kSaveLayerWithPaintFlags);
265265
builder_->saveLayer(rec.fBounds, true);
266266
} else {
267267
builder_->saveLayer(rec.fBounds, false);
@@ -273,49 +273,62 @@ void DisplayListCanvasRecorder::didRestore() {
273273
}
274274

275275
void DisplayListCanvasRecorder::onDrawPaint(const SkPaint& paint) {
276-
RecordPaintAttributes(&paint, DrawType::kFillOpType);
276+
builder_->setAttributesFromPaint(paint, kDrawPaintFlags);
277277
builder_->drawPaint();
278278
}
279279
void DisplayListCanvasRecorder::onDrawRect(const SkRect& rect,
280280
const SkPaint& paint) {
281-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
281+
builder_->setAttributesFromPaint(paint, kDrawRectFlags);
282282
builder_->drawRect(rect);
283283
}
284284
void DisplayListCanvasRecorder::onDrawRRect(const SkRRect& rrect,
285285
const SkPaint& paint) {
286-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
286+
builder_->setAttributesFromPaint(paint, kDrawRRectFlags);
287287
builder_->drawRRect(rrect);
288288
}
289289
void DisplayListCanvasRecorder::onDrawDRRect(const SkRRect& outer,
290290
const SkRRect& inner,
291291
const SkPaint& paint) {
292-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
292+
builder_->setAttributesFromPaint(paint, kDrawDRRectFlags);
293293
builder_->drawDRRect(outer, inner);
294294
}
295295
void DisplayListCanvasRecorder::onDrawOval(const SkRect& rect,
296296
const SkPaint& paint) {
297-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
297+
builder_->setAttributesFromPaint(paint, kDrawOvalFlags);
298298
builder_->drawOval(rect);
299299
}
300300
void DisplayListCanvasRecorder::onDrawArc(const SkRect& rect,
301301
SkScalar startAngle,
302302
SkScalar sweepAngle,
303303
bool useCenter,
304304
const SkPaint& paint) {
305-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
305+
builder_->setAttributesFromPaint(paint,
306+
useCenter //
307+
? kDrawArcWithCenterFlags
308+
: kDrawArcNoCenterFlags);
306309
builder_->drawArc(rect, startAngle, sweepAngle, useCenter);
307310
}
308311
void DisplayListCanvasRecorder::onDrawPath(const SkPath& path,
309312
const SkPaint& paint) {
310-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
313+
builder_->setAttributesFromPaint(paint, kDrawPathFlags);
311314
builder_->drawPath(path);
312315
}
313316

314317
void DisplayListCanvasRecorder::onDrawPoints(SkCanvas::PointMode mode,
315318
size_t count,
316319
const SkPoint pts[],
317320
const SkPaint& paint) {
318-
RecordPaintAttributes(&paint, DrawType::kStrokeOpType);
321+
switch (mode) {
322+
case SkCanvas::kPoints_PointMode:
323+
builder_->setAttributesFromPaint(paint, kDrawPointsAsPointsFlags);
324+
break;
325+
case SkCanvas::kLines_PointMode:
326+
builder_->setAttributesFromPaint(paint, kDrawPointsAsLinesFlags);
327+
break;
328+
case SkCanvas::kPolygon_PointMode:
329+
builder_->setAttributesFromPaint(paint, kDrawPointsAsPolygonFlags);
330+
break;
331+
}
319332
if (mode == SkCanvas::PointMode::kLines_PointMode && count == 2) {
320333
builder_->drawLine(pts[0], pts[1]);
321334
} else {
@@ -330,7 +343,7 @@ void DisplayListCanvasRecorder::onDrawPoints(SkCanvas::PointMode mode,
330343
void DisplayListCanvasRecorder::onDrawVerticesObject(const SkVertices* vertices,
331344
SkBlendMode mode,
332345
const SkPaint& paint) {
333-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
346+
builder_->setAttributesFromPaint(paint, kDrawVerticesFlags);
334347
builder_->drawVertices(sk_ref_sp(vertices), mode);
335348
}
336349

@@ -340,7 +353,7 @@ void DisplayListCanvasRecorder::onDrawImage2(const SkImage* image,
340353
const SkSamplingOptions& sampling,
341354
const SkPaint* paint) {
342355
if (paint != nullptr) {
343-
RecordPaintAttributes(paint, DrawType::kImageOpType);
356+
builder_->setAttributesFromPaint(*paint, kDrawImageWithPaintFlags);
344357
}
345358
builder_->drawImage(sk_ref_sp(image), SkPoint::Make(dx, dy), sampling,
346359
paint != nullptr);
@@ -353,7 +366,7 @@ void DisplayListCanvasRecorder::onDrawImageRect2(
353366
const SkPaint* paint,
354367
SrcRectConstraint constraint) {
355368
if (paint != nullptr) {
356-
RecordPaintAttributes(paint, DrawType::kImageRectOpType);
369+
builder_->setAttributesFromPaint(*paint, kDrawImageRectWithPaintFlags);
357370
}
358371
builder_->drawImageRect(sk_ref_sp(image), src, dst, sampling,
359372
paint != nullptr, constraint);
@@ -370,7 +383,7 @@ void DisplayListCanvasRecorder::onDrawImageLattice2(const SkImage* image,
370383
if (*paint == default_paint) {
371384
paint = nullptr;
372385
} else {
373-
RecordPaintAttributes(paint, DrawType::kImageOpType);
386+
builder_->setAttributesFromPaint(*paint, kDrawImageLatticeWithPaintFlags);
374387
}
375388
}
376389
builder_->drawImageLattice(sk_ref_sp(image), lattice, dst, filter,
@@ -386,7 +399,7 @@ void DisplayListCanvasRecorder::onDrawAtlas2(const SkImage* image,
386399
const SkRect* cull,
387400
const SkPaint* paint) {
388401
if (paint != nullptr) {
389-
RecordPaintAttributes(paint, DrawType::kImageOpType);
402+
builder_->setAttributesFromPaint(*paint, kDrawAtlasWithPaintFlags);
390403
}
391404
builder_->drawAtlas(sk_ref_sp(image), xform, src, colors, count, mode,
392405
sampling, cull, paint != nullptr);
@@ -396,7 +409,7 @@ void DisplayListCanvasRecorder::onDrawTextBlob(const SkTextBlob* blob,
396409
SkScalar x,
397410
SkScalar y,
398411
const SkPaint& paint) {
399-
RecordPaintAttributes(&paint, DrawType::kDrawOpType);
412+
builder_->setAttributesFromPaint(paint, kDrawTextBlobFlags);
400413
builder_->drawTextBlob(sk_ref_sp(blob), x, y);
401414
}
402415
void DisplayListCanvasRecorder::onDrawShadowRec(const SkPath& path,
@@ -411,119 +424,9 @@ void DisplayListCanvasRecorder::onDrawPicture(const SkPicture* picture,
411424
const SkMatrix* matrix,
412425
const SkPaint* paint) {
413426
if (paint != nullptr) {
414-
RecordPaintAttributes(paint, DrawType::kSaveLayerOpType);
427+
builder_->setAttributesFromPaint(*paint, kDrawPictureWithPaintFlags);
415428
}
416429
builder_->drawPicture(sk_ref_sp(picture), matrix, paint != nullptr);
417430
}
418431

419-
void DisplayListCanvasRecorder::RecordPaintAttributes(const SkPaint* paint,
420-
DrawType type) {
421-
int dataNeeded;
422-
switch (type) {
423-
case DrawType::kDrawOpType:
424-
dataNeeded = kDrawMask_;
425-
break;
426-
case DrawType::kFillOpType:
427-
dataNeeded = kPaintMask_;
428-
break;
429-
case DrawType::kStrokeOpType:
430-
dataNeeded = kStrokeMask_;
431-
break;
432-
case DrawType::kImageOpType:
433-
dataNeeded = kImageMask_;
434-
break;
435-
case DrawType::kImageRectOpType:
436-
dataNeeded = kImageRectMask_;
437-
break;
438-
case DrawType::kSaveLayerOpType:
439-
dataNeeded = kSaveLayerMask_;
440-
break;
441-
default:
442-
FML_DCHECK(false);
443-
return;
444-
}
445-
if (paint == nullptr) {
446-
paint = new SkPaint();
447-
}
448-
if ((dataNeeded & kAaNeeded_) != 0 && current_aa_ != paint->isAntiAlias()) {
449-
builder_->setAntiAlias(current_aa_ = paint->isAntiAlias());
450-
}
451-
if ((dataNeeded & kDitherNeeded_) != 0 &&
452-
current_dither_ != paint->isDither()) {
453-
builder_->setDither(current_dither_ = paint->isDither());
454-
}
455-
if ((dataNeeded & kColorNeeded_) != 0 &&
456-
current_color_ != paint->getColor()) {
457-
builder_->setColor(current_color_ = paint->getColor());
458-
}
459-
if ((dataNeeded & kBlendNeeded_)) {
460-
skstd::optional<SkBlendMode> mode_optional = paint->asBlendMode();
461-
if (mode_optional) {
462-
SkBlendMode mode = mode_optional.value();
463-
if (current_blender_ || current_blend_ != mode) {
464-
builder_->setBlendMode(current_blend_ = mode);
465-
current_blender_ = nullptr;
466-
}
467-
} else {
468-
if (current_blender_.get() != paint->getBlender()) {
469-
builder_->setBlender(current_blender_ = sk_ref_sp(paint->getBlender()));
470-
}
471-
}
472-
}
473-
// invert colors is a Flutter::Paint thing, not an SkPaint thing
474-
// if ((dataNeeded & invertColorsNeeded_) != 0 &&
475-
// currentInvertColors_ != paint->???) {
476-
// currentInvertColors_ = paint->invertColors;
477-
// addOp_(currentInvertColors_
478-
// ? _CanvasOp.setInvertColors
479-
// : _CanvasOp.clearInvertColors, 0);
480-
// }
481-
if ((dataNeeded & kPaintStyleNeeded_) != 0) {
482-
if (current_style_ != paint->getStyle()) {
483-
builder_->setStyle(current_style_ = paint->getStyle());
484-
}
485-
if (current_style_ == SkPaint::Style::kStroke_Style) {
486-
dataNeeded |= kStrokeStyleNeeded_;
487-
}
488-
}
489-
if ((dataNeeded & kStrokeStyleNeeded_) != 0) {
490-
if (current_stroke_width_ != paint->getStrokeWidth()) {
491-
builder_->setStrokeWidth(current_stroke_width_ = paint->getStrokeWidth());
492-
}
493-
if (current_cap_ != paint->getStrokeCap()) {
494-
builder_->setStrokeCap(current_cap_ = paint->getStrokeCap());
495-
}
496-
if (current_join_ != paint->getStrokeJoin()) {
497-
builder_->setStrokeJoin(current_join_ = paint->getStrokeJoin());
498-
}
499-
if (current_miter_limit_ != paint->getStrokeMiter()) {
500-
builder_->setStrokeMiter(current_miter_limit_ = paint->getStrokeMiter());
501-
}
502-
}
503-
if ((dataNeeded & kShaderNeeded_) != 0 &&
504-
current_shader_.get() != paint->getShader()) {
505-
builder_->setShader(current_shader_ = sk_ref_sp(paint->getShader()));
506-
}
507-
if ((dataNeeded & kColorFilterNeeded_) != 0 &&
508-
current_color_filter_.get() != paint->getColorFilter()) {
509-
builder_->setColorFilter(current_color_filter_ =
510-
sk_ref_sp(paint->getColorFilter()));
511-
}
512-
if ((dataNeeded & kImageFilterNeeded_) != 0 &&
513-
current_image_filter_.get() != paint->getImageFilter()) {
514-
builder_->setImageFilter(current_image_filter_ =
515-
sk_ref_sp(paint->getImageFilter()));
516-
}
517-
if ((dataNeeded & kPathEffectNeeded_) != 0 &&
518-
current_path_effect_.get() != paint->getPathEffect()) {
519-
builder_->setPathEffect(current_path_effect_ =
520-
sk_ref_sp(paint->getPathEffect()));
521-
}
522-
if ((dataNeeded & kMaskFilterNeeded_) != 0 &&
523-
current_mask_filter_.get() != paint->getMaskFilter()) {
524-
builder_->setMaskFilter(current_mask_filter_ =
525-
sk_ref_sp(paint->getMaskFilter()));
526-
}
527-
}
528-
529432
} // namespace flutter

flow/display_list_canvas.h

Lines changed: 5 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ class DisplayListCanvasDispatcher : public virtual Dispatcher,
4949
SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override;
5050
// clang-format on
5151

52-
void clipRect(const SkRect& rect, SkClipOp clip_op, bool isAA) override;
53-
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool isAA) override;
54-
void clipPath(const SkPath& path, SkClipOp clip_op, bool isAA) override;
52+
void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override;
53+
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override;
54+
void clipPath(const SkPath& path, SkClipOp clip_op, bool is_aa) override;
5555

5656
void drawPaint() override;
5757
void drawColor(SkColor color, SkBlendMode mode) override;
@@ -120,7 +120,8 @@ class DisplayListCanvasDispatcher : public virtual Dispatcher,
120120
// Receives all methods on SkCanvas and sends them to a DisplayListBuilder
121121
class DisplayListCanvasRecorder
122122
: public SkCanvasVirtualEnforcer<SkNoDrawCanvas>,
123-
public SkRefCnt {
123+
public SkRefCnt,
124+
DisplayListOpFlags {
124125
public:
125126
DisplayListCanvasRecorder(const SkRect& bounds);
126127

@@ -233,80 +234,8 @@ class DisplayListCanvasRecorder
233234
const SkMatrix* matrix,
234235
const SkPaint* paint) override;
235236

236-
enum class DrawType {
237-
// The operation will be an image operation
238-
kImageOpType,
239-
// The operation will be an imageRect operation
240-
kImageRectOpType,
241-
// The operation will be a fill or stroke depending on the paint.style
242-
kDrawOpType,
243-
// The operation will be a fill (ignoring paint.style)
244-
kFillOpType,
245-
// The operation will be a stroke (ignoring paint.style)
246-
kStrokeOpType,
247-
// The operation will be a saveLayer with a paint object
248-
kSaveLayerOpType,
249-
};
250-
251-
void RecordPaintAttributes(const SkPaint* paint, DrawType type);
252-
253237
private:
254238
sk_sp<DisplayListBuilder> builder_;
255-
256-
// Mask bits for the various attributes that might be needed for a given
257-
// operation.
258-
// clang-format off
259-
static constexpr int kAaNeeded_ = 1 << 0;
260-
static constexpr int kColorNeeded_ = 1 << 1;
261-
static constexpr int kBlendNeeded_ = 1 << 2;
262-
static constexpr int kInvertColorsNeeded_ = 1 << 3;
263-
static constexpr int kPaintStyleNeeded_ = 1 << 4;
264-
static constexpr int kStrokeStyleNeeded_ = 1 << 5;
265-
static constexpr int kShaderNeeded_ = 1 << 6;
266-
static constexpr int kColorFilterNeeded_ = 1 << 7;
267-
static constexpr int kImageFilterNeeded_ = 1 << 8;
268-
static constexpr int kPathEffectNeeded_ = 1 << 9;
269-
static constexpr int kMaskFilterNeeded_ = 1 << 10;
270-
static constexpr int kDitherNeeded_ = 1 << 11;
271-
// clang-format on
272-
273-
// Combinations of the above mask bits that are common to typical "draw"
274-
// calls.
275-
// Note that the strokeStyle_ is handled conditionally depending on whether
276-
// the paintStyle_ attribute value is synchronized. It can also be manually
277-
// specified for operations that will be always stroking, like [drawLine].
278-
static constexpr int kPaintMask_ = kAaNeeded_ | kColorNeeded_ |
279-
kBlendNeeded_ | kInvertColorsNeeded_ |
280-
kColorFilterNeeded_ | kShaderNeeded_ |
281-
kDitherNeeded_ | kImageFilterNeeded_;
282-
static constexpr int kDrawMask_ = kPaintMask_ | kPaintStyleNeeded_ |
283-
kMaskFilterNeeded_ | kPathEffectNeeded_;
284-
static constexpr int kStrokeMask_ = kPaintMask_ | kStrokeStyleNeeded_ |
285-
kMaskFilterNeeded_ | kPathEffectNeeded_;
286-
static constexpr int kImageMask_ = kColorNeeded_ | kBlendNeeded_ |
287-
kInvertColorsNeeded_ |
288-
kColorFilterNeeded_ | kDitherNeeded_ |
289-
kImageFilterNeeded_ | kMaskFilterNeeded_;
290-
static constexpr int kImageRectMask_ = kImageMask_ | kAaNeeded_;
291-
static constexpr int kSaveLayerMask_ =
292-
kColorNeeded_ | kBlendNeeded_ | kInvertColorsNeeded_ |
293-
kColorFilterNeeded_ | kImageFilterNeeded_;
294-
295-
bool current_aa_ = false;
296-
bool current_dither_ = false;
297-
SkColor current_color_ = 0xFF000000;
298-
SkBlendMode current_blend_ = SkBlendMode::kSrcOver;
299-
SkPaint::Style current_style_ = SkPaint::Style::kFill_Style;
300-
SkScalar current_stroke_width_ = 0.0;
301-
SkScalar current_miter_limit_ = 4.0;
302-
SkPaint::Cap current_cap_ = SkPaint::Cap::kButt_Cap;
303-
SkPaint::Join current_join_ = SkPaint::Join::kMiter_Join;
304-
sk_sp<SkBlender> current_blender_;
305-
sk_sp<SkShader> current_shader_;
306-
sk_sp<SkColorFilter> current_color_filter_;
307-
sk_sp<SkImageFilter> current_image_filter_;
308-
sk_sp<SkPathEffect> current_path_effect_;
309-
sk_sp<SkMaskFilter> current_mask_filter_;
310239
};
311240

312241
} // namespace flutter

0 commit comments

Comments
 (0)