// 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/skia/dl_sk_canvas.h" #include "flutter/fml/macros.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkCanvasVirtualEnforcer.h" #include "third_party/skia/include/utils/SkNWayCanvas.h" #include "third_party/skia/include/utils/SkNoDrawCanvas.h" #ifndef FLUTTER_SHELL_COMMON_CANVAS_SPY_H_ #define FLUTTER_SHELL_COMMON_CANVAS_SPY_H_ namespace flutter { class DidDrawCanvas; //------------------------------------------------------------------------------ /// Facilitates spying on drawing commands to an SkCanvas. /// /// This is used to determine whether anything was drawn into /// a canvas so it is possible to implement optimizations that /// are specific to empty canvases. class CanvasSpy { public: explicit CanvasSpy(SkCanvas* target_canvas); //---------------------------------------------------------------------------- /// @brief Returns true if any non transparent content has been drawn /// into /// the spying canvas. Note that this class does tries to detect /// empty canvases but in some cases may return true even for /// empty canvases (e.g when a transparent image is drawn into the /// canvas). bool DidDrawIntoCanvas(); //---------------------------------------------------------------------------- /// @brief The returned canvas delegate all operations to the target /// canvas /// while spying on them. DlCanvas* GetSpyingCanvas(); //---------------------------------------------------------------------------- /// @brief The underlying Skia canvas that implements the spying /// (mainly for testing) SkCanvas* GetRawSpyingCanvas(); private: std::unique_ptr n_way_canvas_; std::unique_ptr did_draw_canvas_; DlSkCanvasAdapter adapter_; FML_DISALLOW_COPY_AND_ASSIGN(CanvasSpy); }; class DidDrawCanvas final : public SkCanvasVirtualEnforcer { public: DidDrawCanvas(int width, int height); ~DidDrawCanvas() override; bool DidDrawIntoCanvas(); private: bool did_draw_ = false; // |SkCanvasVirtualEnforcer| void willSave() override; // |SkCanvasVirtualEnforcer| SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override; // |SkCanvasVirtualEnforcer| bool onDoSaveBehind(const SkRect*) override; // |SkCanvasVirtualEnforcer| void willRestore() override; // |SkCanvasVirtualEnforcer| void didConcat44(const SkM44&) override; void didScale(SkScalar, SkScalar) override; void didTranslate(SkScalar, SkScalar) override; // |SkCanvasVirtualEnforcer| void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override; // |SkCanvasVirtualEnforcer| virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y, const SkPaint& paint) override; // |SkCanvasVirtualEnforcer| virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint) override; // |SkCanvasVirtualEnforcer| void onDrawPaint(const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawBehind(const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawRect(const SkRect&, const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawRegion(const SkRegion&, const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawOval(const SkRect&, const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawRRect(const SkRRect&, const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawPath(const SkPath&, const SkPaint&) override; #ifdef SK_SUPPORT_LEGACY_ONDRAWIMAGERECT // |SkCanvasVirtualEnforcer| void onDrawImage(const SkImage*, SkScalar left, SkScalar top, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawImageRect(const SkImage*, const SkRect* src, const SkRect& dst, const SkPaint*, SrcRectConstraint) override; // |SkCanvasVirtualEnforcer| void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int, SkBlendMode, const SkRect*, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawEdgeAAImageSet(const ImageSetEntry[], int count, const SkPoint[], const SkMatrix[], const SkPaint*, SrcRectConstraint) override; #endif // |SkCanvasVirtualEnforcer| void onDrawImage2(const SkImage*, SkScalar left, SkScalar top, const SkSamplingOptions&, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawImageRect2(const SkImage*, const SkRect& src, const SkRect& dst, const SkSamplingOptions&, const SkPaint*, SrcRectConstraint) override; // |SkCanvasVirtualEnforcer| void onDrawImageLattice2(const SkImage*, const Lattice&, const SkRect&, SkFilterMode, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawVerticesObject(const SkVertices*, SkBlendMode, const SkPaint&) override; // |SkCanvasVirtualEnforcer| void onDrawAtlas2(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int, SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override; // |SkCanvasVirtualEnforcer| void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override; // |SkCanvasVirtualEnforcer| void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override; // |SkCanvasVirtualEnforcer| void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override; // |SkCanvasVirtualEnforcer| void onClipRegion(const SkRegion&, SkClipOp) override; // |SkCanvasVirtualEnforcer| void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override; // |SkCanvasVirtualEnforcer| void onDrawDrawable(SkDrawable*, const SkMatrix*) override; // |SkCanvasVirtualEnforcer| void onDrawAnnotation(const SkRect&, const char[], SkData*) override; // |SkCanvasVirtualEnforcer| void onDrawEdgeAAQuad(const SkRect&, const SkPoint[4], SkCanvas::QuadAAFlags, const SkColor4f&, SkBlendMode) override; // |SkCanvasVirtualEnforcer| void onDrawEdgeAAImageSet2(const ImageSetEntry[], int count, const SkPoint[], const SkMatrix[], const SkSamplingOptions&, const SkPaint*, SrcRectConstraint) override; // |SkCanvasVirtualEnforcer| void onFlush() override; void MarkDrawIfNonTransparentPaint(const SkPaint& paint); FML_DISALLOW_COPY_AND_ASSIGN(DidDrawCanvas); }; } // namespace flutter #endif // FLUTTER_SHELL_COMMON_SKIA_EVENT_TRACER_IMPL_H_