Flutter Engine
canvas_spy.h
Go to the documentation of this file.
1 
2 // Copyright 2013 The Flutter Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 #include "flutter/fml/macros.h"
7 #include "third_party/skia/include/core/SkCanvas.h"
8 #include "third_party/skia/include/core/SkCanvasVirtualEnforcer.h"
9 #include "third_party/skia/include/utils/SkNWayCanvas.h"
10 #include "third_party/skia/include/utils/SkNoDrawCanvas.h"
11 
12 #ifndef FLUTTER_SHELL_COMMON_CANVAS_SPY_H_
13 #define FLUTTER_SHELL_COMMON_CANVAS_SPY_H_
14 
15 namespace flutter {
16 
17 class DidDrawCanvas;
18 
19 //------------------------------------------------------------------------------
20 /// Facilitates spying on drawing commands to an SkCanvas.
21 ///
22 /// This is used to determine whether anything was drawn into
23 /// a canvas so it is possible to implement optimizations that
24 /// are specific to empty canvases.
25 class CanvasSpy {
26  public:
27  CanvasSpy(SkCanvas* target_canvas);
28 
29  //----------------------------------------------------------------------------
30  /// @brief Returns true if any non transparent content has been drawn
31  /// into
32  /// the spying canvas. Note that this class does tries to detect
33  /// empty canvases but in some cases may return true even for
34  /// empty canvases (e.g when a transparent image is drawn into the
35  /// canvas).
36  bool DidDrawIntoCanvas();
37 
38  //----------------------------------------------------------------------------
39  /// @brief The returned canvas delegate all operations to the target
40  /// canvas
41  /// while spying on them.
42  SkCanvas* GetSpyingCanvas();
43 
44  private:
45  std::unique_ptr<SkNWayCanvas> n_way_canvas_;
46  std::unique_ptr<DidDrawCanvas> did_draw_canvas_;
47 
48  FML_DISALLOW_COPY_AND_ASSIGN(CanvasSpy);
49 };
50 
51 class DidDrawCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
52  public:
53  DidDrawCanvas(int width, int height);
54  ~DidDrawCanvas() override;
55  bool DidDrawIntoCanvas();
56 
57  private:
58  bool did_draw_ = false;
59 
60  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
61  void willSave() override;
62 
63  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
64  SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
65 
66  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
67  bool onDoSaveBehind(const SkRect*) override;
68 
69  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
70  void willRestore() override;
71 
72  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
73  void didConcat44(const SkM44&) override;
74  void didScale(SkScalar, SkScalar) override;
75  void didTranslate(SkScalar, SkScalar) override;
76 
77  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
78  void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
79 
80  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
81  virtual void onDrawTextBlob(const SkTextBlob* blob,
82  SkScalar x,
83  SkScalar y,
84  const SkPaint& paint) override;
85  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
86  virtual void onDrawPatch(const SkPoint cubics[12],
87  const SkColor colors[4],
88  const SkPoint texCoords[4],
89  SkBlendMode,
90  const SkPaint& paint) override;
91 
92  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
93  void onDrawPaint(const SkPaint&) override;
94 
95  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
96  void onDrawBehind(const SkPaint&) override;
97 
98  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
99  void onDrawPoints(PointMode,
100  size_t count,
101  const SkPoint pts[],
102  const SkPaint&) override;
103 
104  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
105  void onDrawRect(const SkRect&, const SkPaint&) override;
106 
107  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
108  void onDrawRegion(const SkRegion&, const SkPaint&) override;
109 
110  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
111  void onDrawOval(const SkRect&, const SkPaint&) override;
112 
113  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
114  void onDrawArc(const SkRect&,
115  SkScalar,
116  SkScalar,
117  bool,
118  const SkPaint&) override;
119 
120  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
121  void onDrawRRect(const SkRRect&, const SkPaint&) override;
122 
123  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
124  void onDrawPath(const SkPath&, const SkPaint&) override;
125 
126 #ifdef SK_SUPPORT_LEGACY_ONDRAWIMAGERECT
127  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
128  void onDrawImage(const SkImage*,
129  SkScalar left,
130  SkScalar top,
131  const SkPaint*) override;
132 
133  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
134  void onDrawImageRect(const SkImage*,
135  const SkRect* src,
136  const SkRect& dst,
137  const SkPaint*,
138  SrcRectConstraint) override;
139 
140  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
141  void onDrawImageLattice(const SkImage*,
142  const Lattice&,
143  const SkRect&,
144  const SkPaint*) override;
145 
146  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
147  void onDrawAtlas(const SkImage*,
148  const SkRSXform[],
149  const SkRect[],
150  const SkColor[],
151  int,
152  SkBlendMode,
153  const SkRect*,
154  const SkPaint*) override;
155  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
156  void onDrawEdgeAAImageSet(const ImageSetEntry[],
157  int count,
158  const SkPoint[],
159  const SkMatrix[],
160  const SkPaint*,
161  SrcRectConstraint) override;
162 #endif
163 
164  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
165  void onDrawImage2(const SkImage*,
166  SkScalar left,
167  SkScalar top,
168  const SkSamplingOptions&,
169  const SkPaint*) override;
170 
171  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
172  void onDrawImageRect2(const SkImage*,
173  const SkRect& src,
174  const SkRect& dst,
175  const SkSamplingOptions&,
176  const SkPaint*,
177  SrcRectConstraint) override;
178 
179  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
180  void onDrawImageLattice2(const SkImage*,
181  const Lattice&,
182  const SkRect&,
183  SkFilterMode,
184  const SkPaint*) override;
185 
186  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
187  void onDrawVerticesObject(const SkVertices*,
188  SkBlendMode,
189  const SkPaint&) override;
190 
191  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
192  void onDrawAtlas2(const SkImage*,
193  const SkRSXform[],
194  const SkRect[],
195  const SkColor[],
196  int,
197  SkBlendMode,
198  const SkSamplingOptions&,
199  const SkRect*,
200  const SkPaint*) override;
201 
202  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
203  void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
204 
205  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
206  void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
207 
208  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
209  void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
210 
211  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
212  void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
213 
214  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
215  void onClipRegion(const SkRegion&, SkClipOp) override;
216 
217  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
218  void onDrawPicture(const SkPicture*,
219  const SkMatrix*,
220  const SkPaint*) override;
221 
222  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
223  void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
224 
225  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
226  void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
227 
228  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
229  void onDrawEdgeAAQuad(const SkRect&,
230  const SkPoint[4],
231  SkCanvas::QuadAAFlags,
232  const SkColor4f&,
233  SkBlendMode) override;
234 
235  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
236  void onDrawEdgeAAImageSet2(const ImageSetEntry[],
237  int count,
238  const SkPoint[],
239  const SkMatrix[],
240  const SkSamplingOptions&,
241  const SkPaint*,
242  SrcRectConstraint) override;
243 
244  // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
245  void onFlush() override;
246 
247  void MarkDrawIfNonTransparentPaint(const SkPaint& paint);
248 
250 };
251 
252 } // namespace flutter
253 
254 #endif // FLUTTER_SHELL_COMMON_SKIA_EVENT_TRACER_IMPL_H_
SkCanvas * GetSpyingCanvas()
The returned canvas delegate all operations to the target canvas while spying on them.
Definition: canvas_spy.cc:19
bool DidDrawIntoCanvas()
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).
Definition: canvas_spy.cc:33
CanvasSpy(SkCanvas *target_canvas)
Definition: canvas_spy.cc:9
int32_t width
int32_t height
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: macros.h:27
constexpr SkColor colors[]