diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 8b3ebc77a7aeb..d322cf51c70fb 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -58,6 +58,8 @@ FILE: ../../../flutter/display_list/display_list_builder.h FILE: ../../../flutter/display_list/display_list_builder_benchmarks.cc FILE: ../../../flutter/display_list/display_list_builder_multiplexer.cc FILE: ../../../flutter/display_list/display_list_builder_multiplexer.h +FILE: ../../../flutter/display_list/display_list_canvas.cc +FILE: ../../../flutter/display_list/display_list_canvas.h FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.cc FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.h FILE: ../../../flutter/display_list/display_list_canvas_recorder.cc @@ -106,6 +108,8 @@ FILE: ../../../flutter/display_list/display_list_path_effect_unittests.cc FILE: ../../../flutter/display_list/display_list_rtree.cc FILE: ../../../flutter/display_list/display_list_rtree.h FILE: ../../../flutter/display_list/display_list_sampling_options.h +FILE: ../../../flutter/display_list/display_list_skcanvas_adapter.cc +FILE: ../../../flutter/display_list/display_list_skcanvas_adapter.h FILE: ../../../flutter/display_list/display_list_test_utils.cc FILE: ../../../flutter/display_list/display_list_test_utils.h FILE: ../../../flutter/display_list/display_list_tile_mode.h diff --git a/display_list/BUILD.gn b/display_list/BUILD.gn index 077209220e69b..00fb96d7ca4e9 100644 --- a/display_list/BUILD.gn +++ b/display_list/BUILD.gn @@ -18,6 +18,8 @@ source_set("display_list") { "display_list_builder.h", "display_list_builder_multiplexer.cc", "display_list_builder_multiplexer.h", + "display_list_canvas.cc", + "display_list_canvas.h", "display_list_canvas_dispatcher.cc", "display_list_canvas_dispatcher.h", "display_list_canvas_recorder.cc", @@ -54,6 +56,8 @@ source_set("display_list") { "display_list_rtree.cc", "display_list_rtree.h", "display_list_sampling_options.h", + "display_list_skcanvas_adapter.cc", + "display_list_skcanvas_adapter.h", "display_list_tile_mode.h", "display_list_utils.cc", "display_list_utils.h", diff --git a/display_list/display_list_builder.cc b/display_list/display_list_builder.cc index 788938e4b05b7..1bf9e6e4aca3d 100644 --- a/display_list/display_list_builder.cc +++ b/display_list/display_list_builder.cc @@ -508,9 +508,9 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds, } } } -void DisplayListBuilder::saveLayer(const SkRect* bounds, - const DlPaint* paint, - const DlImageFilter* backdrop) { +void DisplayListBuilder::onSaveLayer(const SkRect* bounds, + const DlPaint* paint, + const DlImageFilter* backdrop) { if (paint != nullptr) { setAttributesFromDlPaint(*paint, DisplayListOpFlags::kSaveLayerWithPaintFlags); @@ -700,7 +700,7 @@ void DisplayListBuilder::intersect(const SkRect& rect) { current_layer_->clip_bounds.setEmpty(); } } -SkRect DisplayListBuilder::getLocalClipBounds() { +SkRect DisplayListBuilder::getLocalClipBounds() const { SkM44 inverse; if (current_layer_->matrix.invert(&inverse)) { SkRect devBounds; @@ -897,10 +897,10 @@ void DisplayListBuilder::drawImage(const sk_sp image, : Push(0, 1, std::move(image), point, sampling); CheckLayerOpacityCompatibility(render_with_attributes); } -void DisplayListBuilder::drawImage(const sk_sp image, - const SkPoint point, - DlImageSampling sampling, - const DlPaint* paint) { +void DisplayListBuilder::onDrawImage(const sk_sp image, + const SkPoint point, + DlImageSampling sampling, + const DlPaint* paint) { if (paint != nullptr) { setAttributesFromDlPaint(*paint, DisplayListOpFlags::kDrawImageWithPaintFlags); @@ -919,12 +919,13 @@ void DisplayListBuilder::drawImageRect(const sk_sp image, render_with_attributes, constraint); CheckLayerOpacityCompatibility(render_with_attributes); } -void DisplayListBuilder::drawImageRect(const sk_sp image, - const SkRect& src, - const SkRect& dst, - DlImageSampling sampling, - const DlPaint* paint, - SkCanvas::SrcRectConstraint constraint) { +void DisplayListBuilder::onDrawImageRect( + const sk_sp image, + const SkRect& src, + const SkRect& dst, + DlImageSampling sampling, + const DlPaint* paint, + SkCanvas::SrcRectConstraint constraint) { if (paint != nullptr) { setAttributesFromDlPaint(*paint, DisplayListOpFlags::kDrawImageRectWithPaintFlags); @@ -944,11 +945,11 @@ void DisplayListBuilder::drawImageNine(const sk_sp image, : Push(0, 1, std::move(image), center, dst, filter); CheckLayerOpacityCompatibility(render_with_attributes); } -void DisplayListBuilder::drawImageNine(const sk_sp image, - const SkIRect& center, - const SkRect& dst, - DlFilterMode filter, - const DlPaint* paint) { +void DisplayListBuilder::onDrawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + DlFilterMode filter, + const DlPaint* paint) { if (paint != nullptr) { setAttributesFromDlPaint(*paint, DisplayListOpFlags::kDrawImageNineWithPaintFlags); @@ -1017,15 +1018,15 @@ void DisplayListBuilder::drawAtlas(const sk_sp atlas, // of the transforms and texture rectangles. UpdateLayerOpacityCompatibility(false); } -void DisplayListBuilder::drawAtlas(const sk_sp atlas, - const SkRSXform xform[], - const SkRect tex[], - const DlColor colors[], - int count, - DlBlendMode mode, - DlImageSampling sampling, - const SkRect* cull_rect, - const DlPaint* paint) { +void DisplayListBuilder::onDrawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const DlColor colors[], + int count, + DlBlendMode mode, + DlImageSampling sampling, + const SkRect* cull_rect, + const DlPaint* paint) { if (paint != nullptr) { setAttributesFromDlPaint(*paint, DisplayListOpFlags::kDrawAtlasWithPaintFlags); @@ -1073,6 +1074,13 @@ void DisplayListBuilder::drawTextBlob(const sk_sp blob, Push(0, 1, std::move(blob), x, y); CheckLayerOpacityCompatibility(); } +void DisplayListBuilder::drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y, + const DlPaint& paint) { + setAttributesFromDlPaint(paint, DisplayListOpFlags::kDrawTextBlobFlags); + drawTextBlob(blob, x, y); +} void DisplayListBuilder::drawShadow(const SkPath& path, const DlColor color, const SkScalar elevation, diff --git a/display_list/display_list_builder.h b/display_list/display_list_builder.h index 759b7280ed0f1..be1d4fc18ff22 100644 --- a/display_list/display_list_builder.h +++ b/display_list/display_list_builder.h @@ -7,6 +7,7 @@ #include "flutter/display_list/display_list.h" #include "flutter/display_list/display_list_blend_mode.h" +#include "flutter/display_list/display_list_canvas.h" #include "flutter/display_list/display_list_comparable.h" #include "flutter/display_list/display_list_dispatcher.h" #include "flutter/display_list/display_list_flags.h" @@ -25,6 +26,7 @@ namespace flutter { // those rendering commands can be captured into a DisplayList using // the DisplayListCanvasRecorder class. class DisplayListBuilder final : public virtual Dispatcher, + public virtual DlCanvas, public SkRefCnt, DisplayListOpFlags { public: @@ -166,12 +168,9 @@ class DisplayListBuilder final : public virtual Dispatcher, : SaveLayerOptions::kNoAttributes, nullptr); } - void saveLayer(const SkRect* bounds, - const DlPaint* paint, - const DlImageFilter* backdrop = nullptr); void restore() override; - int getSaveCount() { return layer_stack_.size(); } - void restoreToCount(int restore_count); + int getSaveCount() override { return layer_stack_.size(); } + void restoreToCount(int restore_count) override; void translate(SkScalar tx, SkScalar ty) override; void scale(SkScalar sx, SkScalar sy) override; @@ -194,19 +193,21 @@ class DisplayListBuilder final : public virtual Dispatcher, SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override; // clang-format on void transformReset() override; - void transform(const SkMatrix* matrix); - void transform(const SkM44* matrix44); - void transform(const SkMatrix& matrix) { transform(&matrix); } - void transform(const SkM44& matrix44) { transform(&matrix44); } + void transform(const SkMatrix* matrix) override; + void transform(const SkM44* matrix44) override; /// Returns the 4x4 full perspective transform representing all transform /// operations executed so far in this DisplayList within the enclosing /// save stack. - SkM44 getTransformFullPerspective() { return current_layer_->matrix; } + SkM44 getTransformFullPerspective() const override { + return current_layer_->matrix; + } /// Returns the 3x3 partial perspective transform representing all transform /// operations executed so far in this DisplayList within the enclosing /// save stack. - SkMatrix getTransform() { return current_layer_->matrix.asM33(); } + SkMatrix getTransform() const override { + return current_layer_->matrix.asM33(); + } void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override; void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override; @@ -215,31 +216,37 @@ class DisplayListBuilder final : public virtual Dispatcher, /// Conservative estimate of the bounds of all outstanding clip operations /// measured in the coordinate space within which this DisplayList will /// be rendered. - SkRect getDestinationClipBounds() { return current_layer_->clip_bounds; } + SkRect getDestinationClipBounds() const override { + return current_layer_->clip_bounds; + } /// Conservative estimate of the bounds of all outstanding clip operations /// transformed into the local coordinate space in which currently /// recorded rendering operations are interpreted. - SkRect getLocalClipBounds(); + SkRect getLocalClipBounds() const override; void drawPaint() override; - void drawPaint(const DlPaint& paint); + void drawPaint(const DlPaint& paint) override; void drawColor(DlColor color, DlBlendMode mode) override; void drawLine(const SkPoint& p0, const SkPoint& p1) override; - void drawLine(const SkPoint& p0, const SkPoint& p1, const DlPaint& paint); + void drawLine(const SkPoint& p0, + const SkPoint& p1, + const DlPaint& paint) override; void drawRect(const SkRect& rect) override; - void drawRect(const SkRect& rect, const DlPaint& paint); + void drawRect(const SkRect& rect, const DlPaint& paint) override; void drawOval(const SkRect& bounds) override; - void drawOval(const SkRect& bounds, const DlPaint& paint); + void drawOval(const SkRect& bounds, const DlPaint& paint) override; void drawCircle(const SkPoint& center, SkScalar radius) override; - void drawCircle(const SkPoint& center, SkScalar radius, const DlPaint& paint); + void drawCircle(const SkPoint& center, + SkScalar radius, + const DlPaint& paint) override; void drawRRect(const SkRRect& rrect) override; - void drawRRect(const SkRRect& rrect, const DlPaint& paint); + void drawRRect(const SkRRect& rrect, const DlPaint& paint) override; void drawDRRect(const SkRRect& outer, const SkRRect& inner) override; void drawDRRect(const SkRRect& outer, const SkRRect& inner, - const DlPaint& paint); + const DlPaint& paint) override; void drawPath(const SkPath& path) override; - void drawPath(const SkPath& path, const DlPaint& paint); + void drawPath(const SkPath& path, const DlPaint& paint) override; void drawArc(const SkRect& bounds, SkScalar start, SkScalar sweep, @@ -248,14 +255,14 @@ class DisplayListBuilder final : public virtual Dispatcher, SkScalar start, SkScalar sweep, bool useCenter, - const DlPaint& paint); + const DlPaint& paint) override; void drawPoints(SkCanvas::PointMode mode, uint32_t count, const SkPoint pts[]) override; void drawPoints(SkCanvas::PointMode mode, uint32_t count, const SkPoint pts[], - const DlPaint& paint); + const DlPaint& paint) override; void drawSkVertices(const sk_sp vertices, SkBlendMode mode) override; void drawVertices(const DlVertices* vertices, DlBlendMode mode) override; @@ -265,20 +272,11 @@ class DisplayListBuilder final : public virtual Dispatcher, } void drawVertices(const DlVertices* vertices, DlBlendMode mode, - const DlPaint& paint); - void drawVertices(const std::shared_ptr vertices, - DlBlendMode mode, - const DlPaint& paint) { - drawVertices(vertices.get(), mode, paint); - } + const DlPaint& paint) override; void drawImage(const sk_sp image, const SkPoint point, DlImageSampling sampling, bool render_with_attributes) override; - void drawImage(const sk_sp image, - const SkPoint point, - DlImageSampling sampling, - const DlPaint* paint = nullptr); void drawImageRect( const sk_sp image, const SkRect& src, @@ -287,23 +285,11 @@ class DisplayListBuilder final : public virtual Dispatcher, bool render_with_attributes, SkCanvas::SrcRectConstraint constraint = SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint) override; - void drawImageRect(const sk_sp image, - const SkRect& src, - const SkRect& dst, - DlImageSampling sampling, - const DlPaint* paint = nullptr, - SkCanvas::SrcRectConstraint constraint = - SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint); void drawImageNine(const sk_sp image, const SkIRect& center, const SkRect& dst, DlFilterMode filter, bool render_with_attributes) override; - void drawImageNine(const sk_sp image, - const SkIRect& center, - const SkRect& dst, - DlFilterMode filter, - const DlPaint* paint = nullptr); void drawImageLattice(const sk_sp image, const SkCanvas::Lattice& lattice, const SkRect& dst, @@ -318,15 +304,6 @@ class DisplayListBuilder final : public virtual Dispatcher, DlImageSampling sampling, const SkRect* cullRect, bool render_with_attributes) override; - void drawAtlas(const sk_sp atlas, - const SkRSXform xform[], - const SkRect tex[], - const DlColor colors[], - int count, - DlBlendMode mode, - DlImageSampling sampling, - const SkRect* cullRect, - const DlPaint* paint = nullptr); void drawPicture(const sk_sp picture, const SkMatrix* matrix, bool render_with_attributes) override; @@ -334,14 +311,59 @@ class DisplayListBuilder final : public virtual Dispatcher, void drawTextBlob(const sk_sp blob, SkScalar x, SkScalar y) override; + void drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y, + const DlPaint& paint) override; void drawShadow(const SkPath& path, const DlColor color, const SkScalar elevation, bool transparent_occluder, SkScalar dpr) override; + // These using calls draw in the overloads in DlCanvas that implement + // default parameters. + using DlCanvas::drawAtlas; + using DlCanvas::drawImage; + using DlCanvas::drawImageNine; + using DlCanvas::drawImageRect; + using DlCanvas::drawVertices; + using DlCanvas::saveLayer; + using DlCanvas::transform; + sk_sp Build(); + protected: + // The "on" versios of these calls are used to avoid conflicts with + // the methods in DlCanvas that have default parametrs. + void onSaveLayer(const SkRect* bounds, + const DlPaint* paint, + const DlImageFilter* backdrop) override; + void onDrawImage(const sk_sp image, + const SkPoint point, + DlImageSampling sampling, + const DlPaint* paint) override; + void onDrawImageRect(const sk_sp image, + const SkRect& src, + const SkRect& dst, + DlImageSampling sampling, + const DlPaint* paint, + SkCanvas::SrcRectConstraint constraint) override; + void onDrawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + DlFilterMode filter, + const DlPaint* paint) override; + void onDrawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const DlColor colors[], + int count, + DlBlendMode mode, + DlImageSampling sampling, + const SkRect* cullRect, + const DlPaint* paint) override; + private: void checkForDeferredSave(); diff --git a/display_list/display_list_canvas.cc b/display_list/display_list_canvas.cc new file mode 100644 index 0000000000000..4ad29e680c6a3 --- /dev/null +++ b/display_list/display_list_canvas.cc @@ -0,0 +1,11 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/display_list/display_list_canvas.h" + +namespace flutter { + +// + +} // namespace flutter diff --git a/display_list/display_list_canvas.h b/display_list/display_list_canvas.h new file mode 100644 index 0000000000000..11608ad7a4841 --- /dev/null +++ b/display_list/display_list_canvas.h @@ -0,0 +1,194 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_CANVAS_H_ +#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_CANVAS_H_ + +#include "flutter/display_list/display_list_blend_mode.h" +#include "flutter/display_list/display_list_image.h" +#include "flutter/display_list/display_list_paint.h" +#include "flutter/display_list/display_list_sampling_options.h" +#include "flutter/display_list/display_list_vertices.h" + +namespace flutter { + +// The convenience API based on DisplayList objects that defines how +// to talk to either an SkCanvas adapter or a DisplayListBuilder in +// a loss-less fashion. +class DlCanvas { + public: + virtual void save() = 0; + void saveLayer(const SkRect* bounds, + const DlPaint* paint, + const DlImageFilter* backdrop = nullptr) { + onSaveLayer(bounds, paint, backdrop); + } + virtual void restore() = 0; + virtual int getSaveCount() = 0; + virtual void restoreToCount(int restore_count) = 0; + + virtual void translate(SkScalar tx, SkScalar ty) = 0; + virtual void scale(SkScalar sx, SkScalar sy) = 0; + virtual void rotate(SkScalar degrees) = 0; + virtual void skew(SkScalar sx, SkScalar sy) = 0; + + // clang-format off + + // 2x3 2D affine subset of a 4x4 transform in row major order + virtual void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, + SkScalar myx, SkScalar myy, SkScalar myt) = 0; + // full 4x4 transform in row major order + virtual void transformFullPerspective( + SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, + SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, + SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, + SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) = 0; + // clang-format on + virtual void transformReset() = 0; + virtual void transform(const SkMatrix* matrix) = 0; + virtual void transform(const SkM44* matrix44) = 0; + void transform(const SkMatrix& matrix) { transform(&matrix); } + void transform(const SkM44& matrix44) { transform(&matrix44); } + + /// Returns the 4x4 full perspective transform representing all transform + /// operations executed so far in this DisplayList within the enclosing + /// save stack. + virtual SkM44 getTransformFullPerspective() const = 0; + /// Returns the 3x3 partial perspective transform representing all transform + /// operations executed so far in this DisplayList within the enclosing + /// save stack. + virtual SkMatrix getTransform() const = 0; + + virtual void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) = 0; + virtual void clipRRect(const SkRRect& rrect, + SkClipOp clip_op, + bool is_aa) = 0; + virtual void clipPath(const SkPath& path, SkClipOp clip_op, bool is_aa) = 0; + + /// Conservative estimate of the bounds of all outstanding clip operations + /// measured in the coordinate space within which this DisplayList will + /// be rendered. + virtual SkRect getDestinationClipBounds() const = 0; + /// Conservative estimate of the bounds of all outstanding clip operations + /// transformed into the local coordinate space in which currently + /// recorded rendering operations are interpreted. + virtual SkRect getLocalClipBounds() const = 0; + + virtual void drawPaint(const DlPaint& paint) = 0; + virtual void drawColor(DlColor color, DlBlendMode mode) = 0; + virtual void drawLine(const SkPoint& p0, + const SkPoint& p1, + const DlPaint& paint) = 0; + virtual void drawRect(const SkRect& rect, const DlPaint& paint) = 0; + virtual void drawOval(const SkRect& bounds, const DlPaint& paint) = 0; + virtual void drawCircle(const SkPoint& center, + SkScalar radius, + const DlPaint& paint) = 0; + virtual void drawRRect(const SkRRect& rrect, const DlPaint& paint) = 0; + virtual void drawDRRect(const SkRRect& outer, + const SkRRect& inner, + const DlPaint& paint) = 0; + virtual void drawPath(const SkPath& path, const DlPaint& paint) = 0; + virtual void drawArc(const SkRect& bounds, + SkScalar start, + SkScalar sweep, + bool useCenter, + const DlPaint& paint) = 0; + virtual void drawPoints(SkCanvas::PointMode mode, + uint32_t count, + const SkPoint pts[], + const DlPaint& paint) = 0; + virtual void drawVertices(const DlVertices* vertices, + DlBlendMode mode, + const DlPaint& paint) = 0; + void drawVertices(const std::shared_ptr vertices, + DlBlendMode mode, + const DlPaint& paint) { + drawVertices(vertices.get(), mode, paint); + } + void drawImage(const sk_sp image, + const SkPoint point, + DlImageSampling sampling, + const DlPaint* paint = nullptr) { + onDrawImage(image, point, sampling, paint); + } + void drawImageRect(const sk_sp image, + const SkRect& src, + const SkRect& dst, + DlImageSampling sampling, + const DlPaint* paint = nullptr, + SkCanvas::SrcRectConstraint constraint = + SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint) { + onDrawImageRect(image, src, dst, sampling, paint, constraint); + } + void drawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + DlFilterMode filter, + const DlPaint* paint = nullptr) { + onDrawImageNine(image, center, dst, filter, paint); + } + void drawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const DlColor colors[], + int count, + DlBlendMode mode, + DlImageSampling sampling, + const SkRect* cullRect = nullptr, + const DlPaint* paint = nullptr) { + onDrawAtlas(atlas, xform, tex, colors, count, mode, sampling, cullRect, + paint); + } + virtual void drawDisplayList(const sk_sp display_list) = 0; + virtual void drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y, + const DlPaint& paint) = 0; + virtual void drawShadow(const SkPath& path, + const DlColor color, + const SkScalar elevation, + bool transparent_occluder, + SkScalar dpr) = 0; + + protected: + // Protected default-less versions of methods that will have default + // parameters in the public API above. Virtual methods with default + // arguments are problematic for exposing those default parameters + // in derived classes and our lint code that runs on some platforms + // even blocks it, so forwarding to a non-defaulting "onFoo" method + // is the best practice here. Derived classes then inherit the + // defaulting method naturally. + virtual void onSaveLayer(const SkRect* bounds, + const DlPaint* paint, + const DlImageFilter* backdrop) = 0; + virtual void onDrawImage(const sk_sp image, + const SkPoint point, + DlImageSampling sampling, + const DlPaint* paint) = 0; + virtual void onDrawImageRect(const sk_sp image, + const SkRect& src, + const SkRect& dst, + DlImageSampling sampling, + const DlPaint* paint, + SkCanvas::SrcRectConstraint constraint) = 0; + virtual void onDrawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + DlFilterMode filter, + const DlPaint* paint) = 0; + virtual void onDrawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const DlColor colors[], + int count, + DlBlendMode mode, + DlImageSampling sampling, + const SkRect* cullRect, + const DlPaint* paint) = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_CANVAS_H_ diff --git a/display_list/display_list_skcanvas_adapter.cc b/display_list/display_list_skcanvas_adapter.cc new file mode 100644 index 0000000000000..ae1aa3a3563fe --- /dev/null +++ b/display_list/display_list_skcanvas_adapter.cc @@ -0,0 +1,312 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/display_list/display_list_skcanvas_adapter.h" + +#include "flutter/display_list/display_list_canvas_dispatcher.h" + +namespace flutter { + +static sk_sp ToSk(const DlColorSource* source) { + return source ? source->skia_object() : nullptr; +} + +static sk_sp ToSk(const DlImageFilter* filter) { + return filter ? filter->skia_object() : nullptr; +} + +static sk_sp ToSk(const DlColorFilter* filter) { + return filter ? filter->skia_object() : nullptr; +} + +static sk_sp ToSk(const DlMaskFilter* filter) { + return filter ? filter->skia_object() : nullptr; +} + +static sk_sp ToSk(const DlPathEffect* effect) { + return effect ? effect->skia_object() : nullptr; +} + +static SkPaint ToSk(const DlPaint& paint) { + SkPaint sk_paint; + + sk_paint.setColor(paint.getColor()); + sk_paint.setBlendMode(ToSk(paint.getBlendMode())); + sk_paint.setStyle(ToSk(paint.getDrawStyle())); + sk_paint.setStrokeWidth(paint.getStrokeWidth()); + sk_paint.setStrokeMiter(paint.getStrokeMiter()); + sk_paint.setStrokeCap(ToSk(paint.getStrokeCap())); + sk_paint.setStrokeJoin(ToSk(paint.getStrokeJoin())); + + sk_paint.setShader(ToSk(paint.getColorSourcePtr())); + sk_paint.setImageFilter(ToSk(paint.getImageFilterPtr())); + sk_paint.setColorFilter(ToSk(paint.getColorFilterPtr())); + sk_paint.setMaskFilter(ToSk(paint.getMaskFilterPtr())); + sk_paint.setPathEffect(ToSk(paint.getPathEffectPtr())); + + return sk_paint; +} + +class SkOptionalPaint { + public: + explicit SkOptionalPaint(const DlPaint* paint) { + if (paint) { + paint_ = ToSk(*paint); + ptr_ = &paint_; + } else { + ptr_ = nullptr; + } + } + + SkPaint* operator()() { return ptr_; } + + private: + SkPaint paint_; + SkPaint* ptr_; +}; + +void DlSkCanvasAdapter::save() { + delegate_->save(); +} + +void DlSkCanvasAdapter::onSaveLayer(const SkRect* bounds, + const DlPaint* paint, + const DlImageFilter* backdrop) { + sk_sp sk_filter = backdrop ? backdrop->skia_object() : nullptr; + SkOptionalPaint sk_paint(paint); + delegate_->saveLayer( + SkCanvas::SaveLayerRec{bounds, sk_paint(), sk_filter.get(), 0}); +} + +void DlSkCanvasAdapter::restore() { + delegate_->restore(); +} + +int DlSkCanvasAdapter::getSaveCount() { + return delegate_->getSaveCount(); +} + +void DlSkCanvasAdapter::restoreToCount(int restore_count) { + delegate_->restoreToCount(restore_count); +} + +void DlSkCanvasAdapter::translate(SkScalar tx, SkScalar ty) { + delegate_->translate(tx, ty); +} + +void DlSkCanvasAdapter::scale(SkScalar sx, SkScalar sy) { + delegate_->scale(sx, sy); +} + +void DlSkCanvasAdapter::rotate(SkScalar degrees) { + delegate_->rotate(degrees); +} + +void DlSkCanvasAdapter::skew(SkScalar sx, SkScalar sy) { + delegate_->skew(sx, sy); +} + +// clang-format off +void DlSkCanvasAdapter::transform2DAffine( + SkScalar mxx, SkScalar mxy, SkScalar mxt, + SkScalar myx, SkScalar myy, SkScalar myt) { + delegate_->concat(SkMatrix::MakeAll(mxx, mxy, mxt, myx, myy, myt, 0, 0, 1)); +} + +void DlSkCanvasAdapter::transformFullPerspective( + SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, + SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, + SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, + SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) { + delegate_->concat(SkM44(mxx, mxy, mxz, mxt, + myx, myy, myz, myt, + mzx, mzy, mzz, mzt, + mwx, mwy, mwz, mwt)); +} +// clang-format on + +void DlSkCanvasAdapter::transformReset() { + delegate_->resetMatrix(); +} + +void DlSkCanvasAdapter::transform(const SkMatrix* matrix) { + if (matrix) { + delegate_->concat(*matrix); + } +} +void DlSkCanvasAdapter::transform(const SkM44* matrix44) { + if (matrix44) { + delegate_->concat(*matrix44); + } +} + +SkM44 DlSkCanvasAdapter::getTransformFullPerspective() const { + return delegate_->getLocalToDevice(); +} + +SkMatrix DlSkCanvasAdapter::getTransform() const { + return delegate_->getTotalMatrix(); +} + +void DlSkCanvasAdapter::clipRect(const SkRect& rect, + SkClipOp clip_op, + bool is_aa) { + delegate_->clipRect(rect, clip_op, is_aa); +} + +void DlSkCanvasAdapter::clipRRect(const SkRRect& rrect, + SkClipOp clip_op, + bool is_aa) { + delegate_->clipRRect(rrect, clip_op, is_aa); +} + +void DlSkCanvasAdapter::clipPath(const SkPath& path, + SkClipOp clip_op, + bool is_aa) { + delegate_->clipPath(path, clip_op, is_aa); +} + +SkRect DlSkCanvasAdapter::getDestinationClipBounds() const { + return SkRect::Make(delegate_->getDeviceClipBounds()); +} + +SkRect DlSkCanvasAdapter::getLocalClipBounds() const { + return delegate_->getLocalClipBounds(); +} + +void DlSkCanvasAdapter::drawPaint(const DlPaint& paint) { + delegate_->drawPaint(ToSk(paint)); +} + +void DlSkCanvasAdapter::drawColor(DlColor color, DlBlendMode mode) { + delegate_->drawColor(color, ToSk(mode)); +} + +void DlSkCanvasAdapter::drawLine(const SkPoint& p0, + const SkPoint& p1, + const DlPaint& paint) { + delegate_->drawLine(p0, p1, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawRect(const SkRect& rect, const DlPaint& paint) { + delegate_->drawRect(rect, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawOval(const SkRect& bounds, const DlPaint& paint) { + delegate_->drawOval(bounds, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawCircle(const SkPoint& center, + SkScalar radius, + const DlPaint& paint) { + delegate_->drawCircle(center, radius, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawRRect(const SkRRect& rrect, const DlPaint& paint) { + delegate_->drawRRect(rrect, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawDRRect(const SkRRect& outer, + const SkRRect& inner, + const DlPaint& paint) { + delegate_->drawDRRect(outer, inner, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawPath(const SkPath& path, const DlPaint& paint) { + delegate_->drawPath(path, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawArc(const SkRect& bounds, + SkScalar start, + SkScalar sweep, + bool useCenter, + const DlPaint& paint) { + delegate_->drawArc(bounds, start, sweep, useCenter, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawPoints(SkCanvas::PointMode mode, + uint32_t count, + const SkPoint pts[], + const DlPaint& paint) { + delegate_->drawPoints(mode, count, pts, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawVertices(const DlVertices* vertices, + DlBlendMode mode, + const DlPaint& paint) { + auto sk_vertices = vertices->skia_object(); + delegate_->drawVertices(sk_vertices, ToSk(mode), ToSk(paint)); +} + +void DlSkCanvasAdapter::onDrawImage(const sk_sp image, + const SkPoint point, + DlImageSampling sampling, + const DlPaint* paint) { + SkOptionalPaint sk_paint(paint); + sk_sp sk_image = image->skia_image(); + delegate_->drawImage(sk_image.get(), point.fX, point.fY, ToSk(sampling), + sk_paint()); +} + +void DlSkCanvasAdapter::onDrawImageRect( + const sk_sp image, + const SkRect& src, + const SkRect& dst, + DlImageSampling sampling, + const DlPaint* paint, + SkCanvas::SrcRectConstraint constraint) { + SkOptionalPaint sk_paint(paint); + sk_sp sk_image = image->skia_image(); + delegate_->drawImageRect(sk_image.get(), src, dst, ToSk(sampling), sk_paint(), + constraint); +} + +void DlSkCanvasAdapter::onDrawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + DlFilterMode filter, + const DlPaint* paint) { + SkOptionalPaint sk_paint(paint); + sk_sp sk_image = image->skia_image(); + delegate_->drawImageNine(sk_image.get(), center, dst, ToSk(filter), + sk_paint()); +} + +void DlSkCanvasAdapter::onDrawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const DlColor colors[], + int count, + DlBlendMode mode, + DlImageSampling sampling, + const SkRect* cullRect, + const DlPaint* paint) { + SkOptionalPaint sk_paint(paint); + sk_sp sk_image = atlas->skia_image(); + const SkColor* sk_colors = reinterpret_cast(colors); + delegate_->drawAtlas(sk_image.get(), xform, tex, sk_colors, count, ToSk(mode), + ToSk(sampling), cullRect, sk_paint()); +} + +void DlSkCanvasAdapter::drawDisplayList(const sk_sp display_list) { + display_list->RenderTo(delegate_); +} + +void DlSkCanvasAdapter::drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y, + const DlPaint& paint) { + delegate_->drawTextBlob(blob, x, y, ToSk(paint)); +} + +void DlSkCanvasAdapter::drawShadow(const SkPath& path, + const DlColor color, + const SkScalar elevation, + bool transparent_occluder, + SkScalar dpr) { + DisplayListCanvasDispatcher::DrawShadow(delegate_, path, color, elevation, + SkColorGetA(color) != 0xff, dpr); +} + +} // namespace flutter diff --git a/display_list/display_list_skcanvas_adapter.h b/display_list/display_list_skcanvas_adapter.h new file mode 100644 index 0000000000000..6110abe0ae867 --- /dev/null +++ b/display_list/display_list_skcanvas_adapter.h @@ -0,0 +1,151 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_SKCANVAS_ADAPTER_H_ +#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_SKCANVAS_ADAPTER_H_ + +#include "flutter/display_list/display_list_canvas.h" + +namespace flutter { + +// This adapter object implements the developer-facing DisplayListCanvas +// interface but translates and directs the calls to an SkCanvas instance. +class DlSkCanvasAdapter : public virtual DlCanvas { + public: + DlSkCanvasAdapter(SkCanvas* delegate) : delegate_(delegate) {} + + void save() override; + void restore() override; + int getSaveCount() override; + void restoreToCount(int restore_count) override; + + void translate(SkScalar tx, SkScalar ty) override; + void scale(SkScalar sx, SkScalar sy) override; + void rotate(SkScalar degrees) override; + void skew(SkScalar sx, SkScalar sy) override; + + // clang-format off + + // 2x3 2D affine subset of a 4x4 transform in row major order + void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, + SkScalar myx, SkScalar myy, SkScalar myt) override; + // full 4x4 transform in row major order + void transformFullPerspective( + SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, + SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, + SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, + SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override; + // clang-format on + void transformReset() override; + void transform(const SkMatrix* matrix) override; + void transform(const SkM44* matrix44) override; + + /// Returns the 4x4 full perspective transform representing all transform + /// operations executed so far in this DisplayList within the enclosing + /// save stack. + SkM44 getTransformFullPerspective() const override; + /// Returns the 3x3 partial perspective transform representing all transform + /// operations executed so far in this DisplayList within the enclosing + /// save stack. + SkMatrix getTransform() const override; + + void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override; + void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override; + void clipPath(const SkPath& path, SkClipOp clip_op, bool is_aa) override; + + /// Conservative estimate of the bounds of all outstanding clip operations + /// measured in the coordinate space within which this DisplayList will + /// be rendered. + SkRect getDestinationClipBounds() const override; + /// Conservative estimate of the bounds of all outstanding clip operations + /// transformed into the local coordinate space in which currently + /// recorded rendering operations are interpreted. + SkRect getLocalClipBounds() const override; + + void drawPaint(const DlPaint& paint) override; + void drawColor(DlColor color, DlBlendMode mode) override; + void drawLine(const SkPoint& p0, + const SkPoint& p1, + const DlPaint& paint) override; + void drawRect(const SkRect& rect, const DlPaint& paint) override; + void drawOval(const SkRect& bounds, const DlPaint& paint) override; + void drawCircle(const SkPoint& center, + SkScalar radius, + const DlPaint& paint) override; + void drawRRect(const SkRRect& rrect, const DlPaint& paint) override; + void drawDRRect(const SkRRect& outer, + const SkRRect& inner, + const DlPaint& paint) override; + void drawPath(const SkPath& path, const DlPaint& paint) override; + void drawArc(const SkRect& bounds, + SkScalar start, + SkScalar sweep, + bool useCenter, + const DlPaint& paint) override; + void drawPoints(SkCanvas::PointMode mode, + uint32_t count, + const SkPoint pts[], + const DlPaint& paint) override; + void drawVertices(const DlVertices* vertices, + DlBlendMode mode, + const DlPaint& paint) override; + void drawDisplayList(const sk_sp display_list) override; + void drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y, + const DlPaint& paint) override; + void drawShadow(const SkPath& path, + const DlColor color, + const SkScalar elevation, + bool transparent_occluder, + SkScalar dpr) override; + + // These using calls draw in the overloads in DlCanvas that implement + // default parameters. + using DlCanvas::drawAtlas; + using DlCanvas::drawImage; + using DlCanvas::drawImageNine; + using DlCanvas::drawImageRect; + using DlCanvas::drawVertices; + using DlCanvas::saveLayer; + using DlCanvas::transform; + + protected: + // The "on" versios of these calls are used to avoid conflicts with + // the methods in DlCanvas that have default parametrs. + void onSaveLayer(const SkRect* bounds, + const DlPaint* paint, + const DlImageFilter* backdrop) override; + void onDrawImage(const sk_sp image, + const SkPoint point, + DlImageSampling sampling, + const DlPaint* paint) override; + void onDrawImageRect(const sk_sp image, + const SkRect& src, + const SkRect& dst, + DlImageSampling sampling, + const DlPaint* paint, + SkCanvas::SrcRectConstraint constraint) override; + void onDrawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + DlFilterMode filter, + const DlPaint* paint) override; + void onDrawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const DlColor colors[], + int count, + DlBlendMode mode, + DlImageSampling sampling, + const SkRect* cullRect, + const DlPaint* paint) override; + + private: + SkCanvas* delegate_; +}; + +} // namespace flutter + +#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_SKCANVAS_ADAPTER_H_