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
15namespace flutter {
16
17class 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.
25class 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
51class 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 didConcat(const SkMatrix&) override;
74 void didConcat44(const SkM44&) override;
75 void didScale(SkScalar, SkScalar) override;
76 void didTranslate(SkScalar, SkScalar) override;
77
78 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
79 void didSetMatrix(const SkMatrix&) override;
80
81 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
82 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
83
84 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
85 virtual void onDrawTextBlob(const SkTextBlob* blob,
86 SkScalar x,
87 SkScalar y,
88 const SkPaint& paint) override;
89 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
90 virtual void onDrawPatch(const SkPoint cubics[12],
91 const SkColor colors[4],
92 const SkPoint texCoords[4],
93 SkBlendMode,
94 const SkPaint& paint) override;
95
96 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
97 void onDrawPaint(const SkPaint&) override;
98
99 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
100 void onDrawBehind(const SkPaint&) override;
101
102 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
103 void onDrawPoints(PointMode,
104 size_t count,
105 const SkPoint pts[],
106 const SkPaint&) override;
107
108 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
109 void onDrawRect(const SkRect&, const SkPaint&) override;
110
111 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
112 void onDrawRegion(const SkRegion&, const SkPaint&) override;
113
114 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
115 void onDrawOval(const SkRect&, const SkPaint&) override;
116
117 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
118 void onDrawArc(const SkRect&,
119 SkScalar,
120 SkScalar,
121 bool,
122 const SkPaint&) override;
123
124 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
125 void onDrawRRect(const SkRRect&, const SkPaint&) override;
126
127 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
128 void onDrawPath(const SkPath&, const SkPaint&) override;
129
130 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
131 void onDrawImage(const SkImage*,
132 SkScalar left,
133 SkScalar top,
134 const SkPaint*) override;
135
136 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
137 void onDrawImageRect(const SkImage*,
138 const SkRect* src,
139 const SkRect& dst,
140 const SkPaint*,
141 SrcRectConstraint) override;
142
143 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
144 void onDrawImageLattice(const SkImage*,
145 const Lattice&,
146 const SkRect&,
147 const SkPaint*) override;
148
149 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
150 void onDrawImageNine(const SkImage*,
151 const SkIRect& center,
152 const SkRect& dst,
153 const SkPaint*) override;
154
155 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
156 void onDrawVerticesObject(const SkVertices*,
157 SkBlendMode,
158 const SkPaint&) override;
159
160 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
161 void onDrawAtlas(const SkImage*,
162 const SkRSXform[],
163 const SkRect[],
164 const SkColor[],
165 int,
166 SkBlendMode,
167 const SkRect*,
168 const SkPaint*) override;
169
170 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
171 void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
172
173 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
174 void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
175
176 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
177 void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
178
179 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
180 void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
181
182 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
183 void onClipRegion(const SkRegion&, SkClipOp) override;
184
185 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
186 void onDrawPicture(const SkPicture*,
187 const SkMatrix*,
188 const SkPaint*) override;
189
190 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
191 void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
192
193 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
194 void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
195
196 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
197 void onDrawEdgeAAQuad(const SkRect&,
198 const SkPoint[4],
199 SkCanvas::QuadAAFlags,
200 const SkColor4f&,
201 SkBlendMode) override;
202
203 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
204 void onDrawEdgeAAImageSet(const ImageSetEntry[],
205 int count,
206 const SkPoint[],
207 const SkMatrix[],
208 const SkPaint*,
209 SrcRectConstraint) override;
210
211 // |SkCanvasVirtualEnforcer<SkNoDrawCanvas>|
212 void onFlush() override;
213
214 void MarkDrawIfNonTransparentPaint(const SkPaint& paint);
215
216 FML_DISALLOW_COPY_AND_ASSIGN(DidDrawCanvas);
217};
218
219} // namespace flutter
220
221#endif // FLUTTER_SHELL_COMMON_SKIA_EVENT_TRACER_IMPL_H_
222