diff --git a/engine/src/flutter/lib/ui/painting/canvas.cc b/engine/src/flutter/lib/ui/painting/canvas.cc index 733b8a2903e..0f7da4a50c6 100644 --- a/engine/src/flutter/lib/ui/painting/canvas.cc +++ b/engine/src/flutter/lib/ui/painting/canvas.cc @@ -3,27 +3,16 @@ // found in the LICENSE file. #include "flutter/lib/ui/painting/canvas.h" -#include "flutter/lib/ui/painting/image_filter.h" #include -#include "flutter/display_list/display_list_blend_mode.h" #include "flutter/display_list/display_list_builder.h" -#include "flutter/display_list/display_list_canvas_dispatcher.h" -#include "flutter/flow/layers/physical_shape_layer.h" #include "flutter/lib/ui/painting/image.h" -#include "flutter/lib/ui/painting/matrix.h" +#include "flutter/lib/ui/painting/image_filter.h" #include "flutter/lib/ui/painting/paint.h" #include "flutter/lib/ui/ui_dart_state.h" #include "flutter/lib/ui/window/platform_configuration.h" #include "flutter/lib/ui/window/window.h" -#include "third_party/skia/include/core/SkBitmap.h" -#include "third_party/skia/include/core/SkCanvas.h" -#include "third_party/skia/include/core/SkRSXform.h" -#include "third_party/tonic/converter/dart_converter.h" -#include "third_party/tonic/dart_args.h" -#include "third_party/tonic/dart_binding_macros.h" -#include "third_party/tonic/dart_library_natives.h" using tonic::ToDart; @@ -45,27 +34,19 @@ void Canvas::Create(Dart_Handle wrapper, return; } - // This call will implicitly initialize the |canvas_| field with an SkCanvas - // whether or not we are using display_list. Now that all of the code here - // in canvas.cc will direct calls to the DisplayListBuilder we could almost - // stop initializing that field for the display list case. Unfortunately, - // the text code in paragraph.cc still needs to present its output to an - // SkCanvas* which means without significant work to the internals of the - // paragraph code, we are going to continue to need the canvas adapter and - // field and getter. fml::RefPtr canvas = fml::MakeRefCounted( 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(SkCanvas* canvas) : canvas_(canvas) {} +Canvas::Canvas(sk_sp builder) + : display_list_builder_(std::move(builder)) {} Canvas::~Canvas() {} void Canvas::save() { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->save(); } } @@ -75,7 +56,7 @@ void Canvas::saveLayerWithoutBounds(Dart_Handle paint_objects, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { bool restore_with_paint = paint.sync_to(builder(), kSaveLayerWithPaintFlags); FML_DCHECK(restore_with_paint); @@ -94,7 +75,7 @@ void Canvas::saveLayer(double left, FML_DCHECK(paint.isNotNull()); SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom); - if (display_list_recorder_) { + if (display_list_builder_) { bool restore_with_paint = paint.sync_to(builder(), kSaveLayerWithPaintFlags); FML_DCHECK(restore_with_paint); @@ -104,13 +85,13 @@ void Canvas::saveLayer(double left, } void Canvas::restore() { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->restore(); } } int Canvas::getSaveCount() { - if (display_list_recorder_) { + if (display_list_builder_) { return builder()->getSaveCount(); } else { return 0; @@ -118,31 +99,31 @@ int Canvas::getSaveCount() { } void Canvas::restoreToCount(int count) { - if (display_list_recorder_ && count < getSaveCount()) { + if (display_list_builder_ && count < getSaveCount()) { builder()->restoreToCount(count); } } void Canvas::translate(double dx, double dy) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->translate(dx, dy); } } void Canvas::scale(double sx, double sy) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->scale(sx, sy); } } void Canvas::rotate(double radians) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->rotate(radians * 180.0 / M_PI); } } void Canvas::skew(double sx, double sy) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->skew(sx, sy); } } @@ -150,7 +131,7 @@ void Canvas::skew(double sx, double sy) { 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_recorder_) { + if (display_list_builder_) { // clang-format off builder()->transformFullPerspective( matrix4[ 0], matrix4[ 4], matrix4[ 8], matrix4[12], @@ -162,16 +143,15 @@ void Canvas::transform(const tonic::Float64List& matrix4) { } void Canvas::getTransform(Dart_Handle matrix4_handle) { - 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); - auto matrix4 = tonic::Float64List(matrix4_handle); - for (int i = 0; i < 16; i++) { - matrix4[i] = m44_values[i]; + if (display_list_builder_) { + SkM44 sk_m44 = builder()->getTransformFullPerspective(); + SkScalar m44_values[16]; + // The Float array stored by Dart Matrix4 is in column-major order + sk_m44.getColMajor(m44_values); + auto matrix4 = tonic::Float64List(matrix4_handle); + for (int i = 0; i < 16; i++) { + matrix4[i] = m44_values[i]; + } } } @@ -181,14 +161,14 @@ void Canvas::clipRect(double left, double bottom, SkClipOp clipOp, bool doAntiAlias) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->clipRect(SkRect::MakeLTRB(left, top, right, bottom), clipOp, doAntiAlias); } } void Canvas::clipRRect(const RRect& rrect, bool doAntiAlias) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->clipRRect(rrect.sk_rrect, SkClipOp::kIntersect, doAntiAlias); } } @@ -199,13 +179,13 @@ void Canvas::clipPath(const CanvasPath* path, bool doAntiAlias) { ToDart("Canvas.clipPath called with non-genuine Path.")); return; } - if (display_list_recorder_) { + if (display_list_builder_) { builder()->clipPath(path->path(), SkClipOp::kIntersect, doAntiAlias); } } void Canvas::getDestinationClipBounds(Dart_Handle rect_handle) { - if (display_list_recorder_) { + if (display_list_builder_) { auto rect = tonic::Float64List(rect_handle); SkRect bounds = builder()->getDestinationClipBounds(); rect[0] = bounds.fLeft; @@ -216,9 +196,9 @@ void Canvas::getDestinationClipBounds(Dart_Handle rect_handle) { } void Canvas::getLocalClipBounds(Dart_Handle rect_handle) { - if (display_list_recorder_) { + if (display_list_builder_) { auto rect = tonic::Float64List(rect_handle); - SkRect bounds = display_list_recorder_->builder()->getLocalClipBounds(); + SkRect bounds = builder()->getLocalClipBounds(); rect[0] = bounds.fLeft; rect[1] = bounds.fTop; rect[2] = bounds.fRight; @@ -227,7 +207,7 @@ void Canvas::getLocalClipBounds(Dart_Handle rect_handle) { } void Canvas::drawColor(SkColor color, DlBlendMode blend_mode) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->drawColor(color, blend_mode); } } @@ -241,7 +221,7 @@ void Canvas::drawLine(double x1, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawLineFlags); builder()->drawLine(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2)); } @@ -251,7 +231,7 @@ void Canvas::drawPaint(Dart_Handle paint_objects, Dart_Handle paint_data) { Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawPaintFlags); std::shared_ptr filter = builder()->getImageFilter(); if (filter && !filter->asColorFilter()) { @@ -272,7 +252,7 @@ void Canvas::drawRect(double left, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawRectFlags); builder()->drawRect(SkRect::MakeLTRB(left, top, right, bottom)); } @@ -284,7 +264,7 @@ void Canvas::drawRRect(const RRect& rrect, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawRRectFlags); builder()->drawRRect(rrect.sk_rrect); } @@ -297,7 +277,7 @@ void Canvas::drawDRRect(const RRect& outer, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawDRRectFlags); builder()->drawDRRect(outer.sk_rrect, inner.sk_rrect); } @@ -312,7 +292,7 @@ void Canvas::drawOval(double left, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawOvalFlags); builder()->drawOval(SkRect::MakeLTRB(left, top, right, bottom)); } @@ -326,7 +306,7 @@ void Canvas::drawCircle(double x, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawCircleFlags); builder()->drawCircle(SkPoint::Make(x, y), radius); } @@ -344,7 +324,7 @@ void Canvas::drawArc(double left, Paint paint(paint_objects, paint_data); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), useCenter // ? kDrawArcWithCenterFlags @@ -366,7 +346,7 @@ void Canvas::drawPath(const CanvasPath* path, ToDart("Canvas.drawPath called with non-genuine Path.")); return; } - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawPathFlags); builder()->drawPath(path->path()); } @@ -395,7 +375,7 @@ Dart_Handle Canvas::drawImage(const CanvasImage* image, } auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex); - if (display_list_recorder_) { + if (display_list_builder_) { bool with_attributes = paint.sync_to(builder(), kDrawImageWithPaintFlags); builder()->drawImage(dl_image, SkPoint::Make(x, y), sampling, with_attributes); @@ -434,7 +414,7 @@ Dart_Handle Canvas::drawImageRect(const CanvasImage* image, 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_recorder_) { + if (display_list_builder_) { bool with_attributes = paint.sync_to(builder(), kDrawImageRectWithPaintFlags); builder()->drawImageRect(dl_image, src, dst, sampling, with_attributes, @@ -476,7 +456,7 @@ Dart_Handle Canvas::drawImageNine(const CanvasImage* image, center.round(&icenter); SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom); auto filter = ImageFilter::FilterModeFromIndex(bitmapSamplingIndex); - if (display_list_recorder_) { + if (display_list_builder_) { bool with_attributes = paint.sync_to(builder(), kDrawImageNineWithPaintFlags); builder()->drawImageNine(dl_image, icenter, dst, filter, with_attributes); @@ -491,10 +471,8 @@ void Canvas::drawPicture(Picture* picture) { return; } if (picture->display_list()) { - if (display_list_recorder_) { + if (display_list_builder_) { builder()->drawDisplayList(picture->display_list()); - } else if (canvas_) { - picture->display_list()->RenderTo(canvas_); } } else { FML_DCHECK(false); @@ -511,7 +489,7 @@ void Canvas::drawPoints(Dart_Handle paint_objects, "SkPoint doesn't use floats."); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { switch (point_mode) { case SkCanvas::kPoints_PointMode: paint.sync_to(builder(), kDrawPointsAsPointsFlags); @@ -541,7 +519,7 @@ void Canvas::drawVertices(const Vertices* vertices, return; } FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { paint.sync_to(builder(), kDrawVerticesFlags); builder()->drawVertices(vertices->vertices(), blend_mode); } @@ -578,7 +556,7 @@ Dart_Handle Canvas::drawAtlas(Dart_Handle paint_objects, auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex); FML_DCHECK(paint.isNotNull()); - if (display_list_recorder_) { + if (display_list_builder_) { tonic::Float32List transforms(transforms_handle); tonic::Float32List rects(rects_handle); tonic::Int32List colors(colors_handle); @@ -610,7 +588,7 @@ void Canvas::drawShadow(const CanvasPath* path, ->get_window(0) ->viewport_metrics() .device_pixel_ratio; - if (display_list_recorder_) { + if (display_list_builder_) { // 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 @@ -624,8 +602,7 @@ void Canvas::drawShadow(const CanvasPath* path, } void Canvas::Invalidate() { - canvas_ = nullptr; - display_list_recorder_ = nullptr; + display_list_builder_ = nullptr; if (dart_wrapper()) { ClearDartWrapper(); } diff --git a/engine/src/flutter/lib/ui/painting/canvas.h b/engine/src/flutter/lib/ui/painting/canvas.h index 0855c52c20f..f953a31687e 100644 --- a/engine/src/flutter/lib/ui/painting/canvas.h +++ b/engine/src/flutter/lib/ui/painting/canvas.h @@ -6,16 +6,13 @@ #define FLUTTER_LIB_UI_PAINTING_CANVAS_H_ #include "flutter/display_list/display_list_blend_mode.h" +#include "flutter/display_list/display_list_flags.h" #include "flutter/lib/ui/dart_wrapper.h" -#include "flutter/lib/ui/painting/paint.h" #include "flutter/lib/ui/painting/path.h" #include "flutter/lib/ui/painting/picture.h" #include "flutter/lib/ui/painting/picture_recorder.h" #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 { @@ -187,21 +184,12 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { double elevation, bool transparentOccluder); - SkCanvas* canvas() const { return canvas_; } void Invalidate(); - DisplayListBuilder* builder() { - return display_list_recorder_ ? display_list_recorder_->builder().get() - : nullptr; - } + DisplayListBuilder* builder() { return display_list_builder_.get(); } private: - 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_; + explicit Canvas(sk_sp builder); // 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() @@ -209,7 +197,7 @@ class Canvas : public RefCountedDartWrappable, DisplayListOpFlags { // 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 display_list_recorder_; + sk_sp display_list_builder_; }; } // namespace flutter diff --git a/engine/src/flutter/lib/ui/painting/picture_recorder.cc b/engine/src/flutter/lib/ui/painting/picture_recorder.cc index fb382546a82..effbb196dce 100644 --- a/engine/src/flutter/lib/ui/painting/picture_recorder.cc +++ b/engine/src/flutter/lib/ui/painting/picture_recorder.cc @@ -4,7 +4,6 @@ #include "flutter/lib/ui/painting/picture_recorder.h" -#include "flutter/display_list/display_list.h" #include "flutter/lib/ui/painting/canvas.h" #include "flutter/lib/ui/painting/picture.h" #include "third_party/tonic/converter/dart_converter.h" @@ -26,10 +25,10 @@ PictureRecorder::PictureRecorder() {} PictureRecorder::~PictureRecorder() {} -SkCanvas* PictureRecorder::BeginRecording(SkRect bounds) { - display_list_recorder_ = - sk_make_sp(bounds, /*prepare_rtree=*/true); - return display_list_recorder_.get(); +sk_sp PictureRecorder::BeginRecording(SkRect bounds) { + display_list_builder_ = + sk_make_sp(bounds, /*prepare_rtree=*/true); + return display_list_builder_; } fml::RefPtr PictureRecorder::endRecording(Dart_Handle dart_picture) { @@ -40,8 +39,8 @@ fml::RefPtr PictureRecorder::endRecording(Dart_Handle dart_picture) { fml::RefPtr picture; picture = Picture::Create(dart_picture, UIDartState::CreateGPUObject( - display_list_recorder_->Build())); - display_list_recorder_ = nullptr; + display_list_builder_->Build())); + display_list_builder_ = nullptr; canvas_->Invalidate(); canvas_ = nullptr; diff --git a/engine/src/flutter/lib/ui/painting/picture_recorder.h b/engine/src/flutter/lib/ui/painting/picture_recorder.h index f510da77a19..34a11fe0cc1 100644 --- a/engine/src/flutter/lib/ui/painting/picture_recorder.h +++ b/engine/src/flutter/lib/ui/painting/picture_recorder.h @@ -5,9 +5,8 @@ #ifndef FLUTTER_LIB_UI_PAINTING_PICTURE_RECORDER_H_ #define FLUTTER_LIB_UI_PAINTING_PICTURE_RECORDER_H_ -#include "flutter/display_list/display_list_canvas_recorder.h" +#include "flutter/display_list/display_list_builder.h" #include "flutter/lib/ui/dart_wrapper.h" -#include "third_party/skia/include/core/SkPictureRecorder.h" namespace flutter { class Canvas; @@ -22,19 +21,15 @@ class PictureRecorder : public RefCountedDartWrappable { ~PictureRecorder() override; - SkCanvas* BeginRecording(SkRect bounds); + sk_sp BeginRecording(SkRect bounds); fml::RefPtr endRecording(Dart_Handle dart_picture); - sk_sp display_list_recorder() { - return display_list_recorder_; - } - void set_canvas(fml::RefPtr canvas) { canvas_ = std::move(canvas); } private: PictureRecorder(); - sk_sp display_list_recorder_; + sk_sp display_list_builder_; fml::RefPtr canvas_; };