Revert "Remove dlCanvasRecorder from flutter::PictureRecorder (#38127)"
This reverts commit 6aa4ccd60d20ee8f00f91bb526dd5c5546b4f260.
diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc
index 18c5288..733b8a2 100644
--- a/lib/ui/painting/canvas.cc
+++ b/lib/ui/painting/canvas.cc
@@ -56,16 +56,16 @@
fml::RefPtr<Canvas> canvas = fml::MakeRefCounted<Canvas>(
recorder->BeginRecording(SkRect::MakeLTRB(left, top, right, bottom)));
recorder->set_canvas(canvas);
+ canvas->display_list_recorder_ = recorder->display_list_recorder();
canvas->AssociateWithDartWrapper(wrapper);
}
-Canvas::Canvas(sk_sp<DisplayListBuilder> builder)
- : display_list_builder_(std::move(builder)) {}
+Canvas::Canvas(SkCanvas* canvas) : canvas_(canvas) {}
Canvas::~Canvas() {}
void Canvas::save() {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->save();
}
}
@@ -75,7 +75,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
bool restore_with_paint =
paint.sync_to(builder(), kSaveLayerWithPaintFlags);
FML_DCHECK(restore_with_paint);
@@ -94,7 +94,7 @@
FML_DCHECK(paint.isNotNull());
SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom);
- if (display_list_builder_) {
+ if (display_list_recorder_) {
bool restore_with_paint =
paint.sync_to(builder(), kSaveLayerWithPaintFlags);
FML_DCHECK(restore_with_paint);
@@ -104,13 +104,13 @@
}
void Canvas::restore() {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->restore();
}
}
int Canvas::getSaveCount() {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
return builder()->getSaveCount();
} else {
return 0;
@@ -118,31 +118,31 @@
}
void Canvas::restoreToCount(int count) {
- if (display_list_builder_ && count < getSaveCount()) {
+ if (display_list_recorder_ && count < getSaveCount()) {
builder()->restoreToCount(count);
}
}
void Canvas::translate(double dx, double dy) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->translate(dx, dy);
}
}
void Canvas::scale(double sx, double sy) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->scale(sx, sy);
}
}
void Canvas::rotate(double radians) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->rotate(radians * 180.0 / M_PI);
}
}
void Canvas::skew(double sx, double sy) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->skew(sx, sy);
}
}
@@ -150,7 +150,7 @@
void Canvas::transform(const tonic::Float64List& matrix4) {
// The Float array stored by Dart Matrix4 is in column-major order
// Both DisplayList and SkM44 constructor take row-major matrix order
- if (display_list_builder_) {
+ if (display_list_recorder_) {
// clang-format off
builder()->transformFullPerspective(
matrix4[ 0], matrix4[ 4], matrix4[ 8], matrix4[12],
@@ -162,7 +162,10 @@
}
void Canvas::getTransform(Dart_Handle matrix4_handle) {
- SkM44 sk_m44 = display_list_builder_->getTransformFullPerspective();
+ SkM44 sk_m44 =
+ display_list_recorder_
+ ? display_list_recorder_->builder()->getTransformFullPerspective()
+ : canvas_->getLocalToDevice();
SkScalar m44_values[16];
// The Float array stored by Dart Matrix4 is in column-major order
sk_m44.getColMajor(m44_values);
@@ -178,14 +181,14 @@
double bottom,
SkClipOp clipOp,
bool doAntiAlias) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->clipRect(SkRect::MakeLTRB(left, top, right, bottom), clipOp,
doAntiAlias);
}
}
void Canvas::clipRRect(const RRect& rrect, bool doAntiAlias) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->clipRRect(rrect.sk_rrect, SkClipOp::kIntersect, doAntiAlias);
}
}
@@ -196,13 +199,13 @@
ToDart("Canvas.clipPath called with non-genuine Path."));
return;
}
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->clipPath(path->path(), SkClipOp::kIntersect, doAntiAlias);
}
}
void Canvas::getDestinationClipBounds(Dart_Handle rect_handle) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
auto rect = tonic::Float64List(rect_handle);
SkRect bounds = builder()->getDestinationClipBounds();
rect[0] = bounds.fLeft;
@@ -213,9 +216,9 @@
}
void Canvas::getLocalClipBounds(Dart_Handle rect_handle) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
auto rect = tonic::Float64List(rect_handle);
- SkRect bounds = display_list_builder_->getLocalClipBounds();
+ SkRect bounds = display_list_recorder_->builder()->getLocalClipBounds();
rect[0] = bounds.fLeft;
rect[1] = bounds.fTop;
rect[2] = bounds.fRight;
@@ -224,7 +227,7 @@
}
void Canvas::drawColor(SkColor color, DlBlendMode blend_mode) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->drawColor(color, blend_mode);
}
}
@@ -238,7 +241,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawLineFlags);
builder()->drawLine(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2));
}
@@ -248,7 +251,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawPaintFlags);
std::shared_ptr<const DlImageFilter> filter = builder()->getImageFilter();
if (filter && !filter->asColorFilter()) {
@@ -269,7 +272,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawRectFlags);
builder()->drawRect(SkRect::MakeLTRB(left, top, right, bottom));
}
@@ -281,7 +284,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawRRectFlags);
builder()->drawRRect(rrect.sk_rrect);
}
@@ -294,7 +297,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawDRRectFlags);
builder()->drawDRRect(outer.sk_rrect, inner.sk_rrect);
}
@@ -309,7 +312,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawOvalFlags);
builder()->drawOval(SkRect::MakeLTRB(left, top, right, bottom));
}
@@ -323,7 +326,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawCircleFlags);
builder()->drawCircle(SkPoint::Make(x, y), radius);
}
@@ -341,7 +344,7 @@
Paint paint(paint_objects, paint_data);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(),
useCenter //
? kDrawArcWithCenterFlags
@@ -363,7 +366,7 @@
ToDart("Canvas.drawPath called with non-genuine Path."));
return;
}
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawPathFlags);
builder()->drawPath(path->path());
}
@@ -392,7 +395,7 @@
}
auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex);
- if (display_list_builder_) {
+ if (display_list_recorder_) {
bool with_attributes = paint.sync_to(builder(), kDrawImageWithPaintFlags);
builder()->drawImage(dl_image, SkPoint::Make(x, y), sampling,
with_attributes);
@@ -431,7 +434,7 @@
SkRect src = SkRect::MakeLTRB(src_left, src_top, src_right, src_bottom);
SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom);
auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex);
- if (display_list_builder_) {
+ if (display_list_recorder_) {
bool with_attributes =
paint.sync_to(builder(), kDrawImageRectWithPaintFlags);
builder()->drawImageRect(dl_image, src, dst, sampling, with_attributes,
@@ -473,7 +476,7 @@
center.round(&icenter);
SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom);
auto filter = ImageFilter::FilterModeFromIndex(bitmapSamplingIndex);
- if (display_list_builder_) {
+ if (display_list_recorder_) {
bool with_attributes =
paint.sync_to(builder(), kDrawImageNineWithPaintFlags);
builder()->drawImageNine(dl_image, icenter, dst, filter, with_attributes);
@@ -488,8 +491,10 @@
return;
}
if (picture->display_list()) {
- if (display_list_builder_) {
+ if (display_list_recorder_) {
builder()->drawDisplayList(picture->display_list());
+ } else if (canvas_) {
+ picture->display_list()->RenderTo(canvas_);
}
} else {
FML_DCHECK(false);
@@ -506,7 +511,7 @@
"SkPoint doesn't use floats.");
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
switch (point_mode) {
case SkCanvas::kPoints_PointMode:
paint.sync_to(builder(), kDrawPointsAsPointsFlags);
@@ -536,7 +541,7 @@
return;
}
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
paint.sync_to(builder(), kDrawVerticesFlags);
builder()->drawVertices(vertices->vertices(), blend_mode);
}
@@ -573,7 +578,7 @@
auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex);
FML_DCHECK(paint.isNotNull());
- if (display_list_builder_) {
+ if (display_list_recorder_) {
tonic::Float32List transforms(transforms_handle);
tonic::Float32List rects(rects_handle);
tonic::Int32List colors(colors_handle);
@@ -605,7 +610,7 @@
->get_window(0)
->viewport_metrics()
.device_pixel_ratio;
- if (display_list_builder_) {
+ if (display_list_recorder_) {
// The DrawShadow mechanism results in non-public operations to be
// performed on the canvas involving an SkDrawShadowRec. Since we
// cannot include the header that defines that structure, we cannot
@@ -619,7 +624,8 @@
}
void Canvas::Invalidate() {
- display_list_builder_ = nullptr;
+ canvas_ = nullptr;
+ display_list_recorder_ = nullptr;
if (dart_wrapper()) {
ClearDartWrapper();
}
diff --git a/lib/ui/painting/canvas.h b/lib/ui/painting/canvas.h
index bf793ae..0855c52 100644
--- a/lib/ui/painting/canvas.h
+++ b/lib/ui/painting/canvas.h
@@ -14,6 +14,8 @@
#include "flutter/lib/ui/painting/rrect.h"
#include "flutter/lib/ui/painting/vertices.h"
#include "flutter/lib/ui/ui_dart_state.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+#include "third_party/skia/include/utils/SkShadowUtils.h"
#include "third_party/tonic/typed_data/typed_list.h"
namespace flutter {
@@ -185,12 +187,21 @@
double elevation,
bool transparentOccluder);
+ SkCanvas* canvas() const { return canvas_; }
void Invalidate();
- DisplayListBuilder* builder() { return display_list_builder_.get(); }
+ DisplayListBuilder* builder() {
+ return display_list_recorder_ ? display_list_recorder_->builder().get()
+ : nullptr;
+ }
private:
- explicit Canvas(sk_sp<DisplayListBuilder> canvas);
+ explicit Canvas(SkCanvas* canvas);
+
+ // The SkCanvas is supplied by a call to SkPictureRecorder::beginRecording,
+ // which does not transfer ownership. For this reason, we hold a raw
+ // pointer and manually set to null in Clear.
+ SkCanvas* canvas_;
// A copy of the recorder used by the SkCanvas->DisplayList adapter for cases
// where we cannot record the SkCanvas method call through the various OnOp()
@@ -198,7 +209,7 @@
// the DisplayList operation lexicon. The recorder has a method for recording
// paint attributes from an SkPaint and an operation type as well as access
// to the raw DisplayListBuilder for emitting custom rendering operations.
- sk_sp<DisplayListBuilder> display_list_builder_;
+ sk_sp<DisplayListCanvasRecorder> display_list_recorder_;
};
} // namespace flutter
diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h
index fbe800c..33bee19 100644
--- a/lib/ui/painting/picture.h
+++ b/lib/ui/painting/picture.h
@@ -11,6 +11,7 @@
#include "flutter/lib/ui/dart_wrapper.h"
#include "flutter/lib/ui/painting/image.h"
#include "flutter/lib/ui/ui_dart_state.h"
+#include "third_party/skia/include/core/SkPicture.h"
namespace flutter {
class Canvas;
diff --git a/lib/ui/painting/picture_recorder.cc b/lib/ui/painting/picture_recorder.cc
index 97e101a..8a62560 100644
--- a/lib/ui/painting/picture_recorder.cc
+++ b/lib/ui/painting/picture_recorder.cc
@@ -26,9 +26,9 @@
PictureRecorder::~PictureRecorder() {}
-sk_sp<DisplayListBuilder> PictureRecorder::BeginRecording(SkRect bounds) {
- display_list_builder_ = sk_make_sp<DisplayListBuilder>(bounds);
- return display_list_builder_;
+SkCanvas* PictureRecorder::BeginRecording(SkRect bounds) {
+ display_list_recorder_ = sk_make_sp<DisplayListCanvasRecorder>(bounds);
+ return display_list_recorder_.get();
}
fml::RefPtr<Picture> PictureRecorder::endRecording(Dart_Handle dart_picture) {
@@ -39,8 +39,8 @@
fml::RefPtr<Picture> picture;
picture = Picture::Create(dart_picture, UIDartState::CreateGPUObject(
- display_list_builder_->Build()));
- display_list_builder_ = nullptr;
+ display_list_recorder_->Build()));
+ display_list_recorder_ = nullptr;
canvas_->Invalidate();
canvas_ = nullptr;
diff --git a/lib/ui/painting/picture_recorder.h b/lib/ui/painting/picture_recorder.h
index 1fc9dbe..f510da7 100644
--- a/lib/ui/painting/picture_recorder.h
+++ b/lib/ui/painting/picture_recorder.h
@@ -5,8 +5,9 @@
#ifndef FLUTTER_LIB_UI_PAINTING_PICTURE_RECORDER_H_
#define FLUTTER_LIB_UI_PAINTING_PICTURE_RECORDER_H_
-#include "flutter/display_list/display_list_builder.h"
+#include "flutter/display_list/display_list_canvas_recorder.h"
#include "flutter/lib/ui/dart_wrapper.h"
+#include "third_party/skia/include/core/SkPictureRecorder.h"
namespace flutter {
class Canvas;
@@ -21,11 +22,11 @@
~PictureRecorder() override;
- sk_sp<DisplayListBuilder> BeginRecording(SkRect bounds);
+ SkCanvas* BeginRecording(SkRect bounds);
fml::RefPtr<Picture> endRecording(Dart_Handle dart_picture);
- sk_sp<DisplayListBuilder> display_list_builder() {
- return display_list_builder_;
+ sk_sp<DisplayListCanvasRecorder> display_list_recorder() {
+ return display_list_recorder_;
}
void set_canvas(fml::RefPtr<Canvas> canvas) { canvas_ = std::move(canvas); }
@@ -33,7 +34,7 @@
private:
PictureRecorder();
- sk_sp<DisplayListBuilder> display_list_builder_;
+ sk_sp<DisplayListCanvasRecorder> display_list_recorder_;
fml::RefPtr<Canvas> canvas_;
};
diff --git a/lib/ui/text/paragraph.cc b/lib/ui/text/paragraph.cc
index 624ed14..4b3df64 100644
--- a/lib/ui/text/paragraph.cc
+++ b/lib/ui/text/paragraph.cc
@@ -65,8 +65,13 @@
}
DisplayListBuilder* builder = canvas->builder();
- if (builder) {
- m_paragraph->Paint(builder, x, y);
+ if (builder && m_paragraph->Paint(builder, x, y)) {
+ return;
+ }
+ // Fall back to SkCanvas if painting to DisplayListBuilder is not supported.
+ SkCanvas* sk_canvas = canvas->canvas();
+ if (sk_canvas) {
+ m_paragraph->Paint(sk_canvas, x, y);
}
}