1
2/*
3 * Copyright 2012 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10#ifndef SKDEBUGCANVAS_H_
11#define SKDEBUGCANVAS_H_
12
13#include "SkCanvas.h"
14#include "SkDrawCommand.h"
15#include "SkPathOps.h"
16#include "SkPicture.h"
17#include "SkTArray.h"
18#include "SkString.h"
19
20class SkTexOverrideFilter;
21
22class SK_API SkDebugCanvas : public SkCanvas {
23public:
24    SkDebugCanvas(int width, int height);
25    virtual ~SkDebugCanvas();
26
27    void toggleFilter(bool toggle) { fFilter = toggle; }
28
29    void setMegaVizMode(bool megaVizMode) { fMegaVizMode = megaVizMode; }
30    bool getMegaVizMode() const { return fMegaVizMode; }
31
32    /**
33     * Enable or disable overdraw visualization
34     */
35    void setOverdrawViz(bool overdrawViz) { fOverdrawViz = overdrawViz; }
36    bool getOverdrawViz() const { return fOverdrawViz; }
37
38    void setOutstandingSaveCount(int saveCount) { fOutstandingSaveCount = saveCount; }
39    int getOutstandingSaveCount() const { return fOutstandingSaveCount; }
40
41    bool getAllowSimplifyClip() const { return fAllowSimplifyClip; }
42
43    void setPicture(SkPicture* picture) { fPicture = picture; }
44
45    /**
46     * Enable or disable texure filtering override
47     */
48    void overrideTexFiltering(bool overrideTexFiltering, SkPaint::FilterLevel level);
49
50    /**
51        Executes all draw calls to the canvas.
52        @param canvas  The canvas being drawn to
53     */
54    void draw(SkCanvas* canvas);
55
56    /**
57        Executes the draw calls up to the specified index.
58        @param canvas  The canvas being drawn to
59        @param index  The index of the final command being executed
60     */
61    void drawTo(SkCanvas* canvas, int index);
62
63    /**
64        Returns the most recently calculated transformation matrix
65     */
66    const SkMatrix& getCurrentMatrix() {
67        return fMatrix;
68    }
69
70    /**
71        Returns the most recently calculated clip
72     */
73    const SkIRect& getCurrentClip() {
74        return fClip;
75    }
76
77    /**
78        Returns the index of the last draw command to write to the pixel at (x,y)
79     */
80    int getCommandAtPoint(int x, int y, int index);
81
82    /**
83        Removes the command at the specified index
84        @param index  The index of the command to delete
85     */
86    void deleteDrawCommandAt(int index);
87
88    /**
89        Returns the draw command at the given index.
90        @param index  The index of the command
91     */
92    SkDrawCommand* getDrawCommandAt(int index);
93
94    /**
95        Sets the draw command for a given index.
96        @param index  The index to overwrite
97        @param command The new command
98     */
99    void setDrawCommandAt(int index, SkDrawCommand* command);
100
101    /**
102        Returns information about the command at the given index.
103        @param index  The index of the command
104     */
105    SkTDArray<SkString*>* getCommandInfo(int index);
106
107    /**
108        Returns the visibility of the command at the given index.
109        @param index  The index of the command
110     */
111    bool getDrawCommandVisibilityAt(int index);
112
113    /**
114        Returns the vector of draw commands
115     */
116    SK_ATTR_DEPRECATED("please use getDrawCommandAt and getSize instead")
117    const SkTDArray<SkDrawCommand*>& getDrawCommands() const;
118
119    /**
120        Returns the vector of draw commands. Do not use this entry
121        point - it is going away!
122     */
123    SkTDArray<SkDrawCommand*>& getDrawCommands();
124
125    /**
126     * Returns the string vector of draw commands
127     */
128    SkTArray<SkString>* getDrawCommandsAsStrings() const;
129
130    /**
131     * Returns an array containing an offset (in the SkPicture) for each command
132     */
133    SkTDArray<size_t>* getDrawCommandOffsets() const;
134
135    /**
136        Returns length of draw command vector.
137     */
138    int getSize() const {
139        return fCommandVector.count();
140    }
141
142    /**
143        Toggles the visibility / execution of the draw command at index i with
144        the value of toggle.
145     */
146    void toggleCommand(int index, bool toggle);
147
148    void setWindowSize(int width, int height) { fWindowSize.set(width, height); }
149
150    void setUserMatrix(SkMatrix matrix) {
151        fUserMatrix = matrix;
152    }
153
154    SkString clipStackData() const { return fClipStackData; }
155
156////////////////////////////////////////////////////////////////////////////////
157// Inherited from SkCanvas
158////////////////////////////////////////////////////////////////////////////////
159
160    virtual void clear(SkColor) SK_OVERRIDE;
161
162    virtual void drawBitmap(const SkBitmap&, SkScalar left, SkScalar top,
163                            const SkPaint*) SK_OVERRIDE;
164
165    virtual void drawBitmapRectToRect(const SkBitmap&, const SkRect* src,
166                                      const SkRect& dst, const SkPaint* paint,
167                                      DrawBitmapRectFlags flags) SK_OVERRIDE;
168
169    virtual void drawBitmapMatrix(const SkBitmap&, const SkMatrix&,
170                                  const SkPaint*) SK_OVERRIDE;
171
172    virtual void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
173                                const SkRect& dst, const SkPaint*) SK_OVERRIDE;
174
175    virtual void drawData(const void*, size_t) SK_OVERRIDE;
176
177    virtual void beginCommentGroup(const char* description) SK_OVERRIDE;
178
179    virtual void addComment(const char* kywd, const char* value) SK_OVERRIDE;
180
181    virtual void endCommentGroup() SK_OVERRIDE;
182
183    virtual void drawOval(const SkRect& oval, const SkPaint&) SK_OVERRIDE;
184
185    virtual void drawPaint(const SkPaint& paint) SK_OVERRIDE;
186
187    virtual void drawPath(const SkPath& path, const SkPaint&) SK_OVERRIDE;
188
189    virtual void drawPoints(PointMode, size_t count, const SkPoint pts[],
190                            const SkPaint&) SK_OVERRIDE;
191
192    virtual void drawRect(const SkRect& rect, const SkPaint&) SK_OVERRIDE;
193
194    virtual void drawRRect(const SkRRect& rrect, const SkPaint& paint) SK_OVERRIDE;
195
196    virtual void drawSprite(const SkBitmap&, int left, int top,
197                            const SkPaint*) SK_OVERRIDE;
198
199    virtual void drawVertices(VertexMode, int vertexCount,
200                              const SkPoint vertices[], const SkPoint texs[],
201                              const SkColor colors[], SkXfermode*,
202                              const uint16_t indices[], int indexCount,
203                              const SkPaint&) SK_OVERRIDE;
204
205    static const int kVizImageHeight = 256;
206    static const int kVizImageWidth = 256;
207
208    virtual bool isClipEmpty() const SK_OVERRIDE { return false; }
209    virtual bool isClipRect() const SK_OVERRIDE { return true; }
210    virtual bool getClipBounds(SkRect* bounds) const SK_OVERRIDE {
211        if (bounds) {
212            bounds->setXYWH(0, 0,
213                            SkIntToScalar(this->imageInfo().width()),
214                            SkIntToScalar(this->imageInfo().height()));
215        }
216        return true;
217    }
218    virtual bool getClipDeviceBounds(SkIRect* bounds) const SK_OVERRIDE {
219        if (bounds) {
220            bounds->setLargest();
221        }
222        return true;
223    }
224
225protected:
226    virtual void willSave() SK_OVERRIDE;
227    virtual SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SaveFlags) SK_OVERRIDE;
228    virtual void willRestore() SK_OVERRIDE;
229
230    virtual void didConcat(const SkMatrix&) SK_OVERRIDE;
231    virtual void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
232
233    virtual void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) SK_OVERRIDE;
234    virtual void onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y,
235                            const SkPaint&) SK_OVERRIDE;
236    virtual void onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[],
237                               const SkPaint&) SK_OVERRIDE;
238    virtual void onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[],
239                                SkScalar constY, const SkPaint&) SK_OVERRIDE;
240    virtual void onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path,
241                                  const SkMatrix* matrix, const SkPaint&) SK_OVERRIDE;
242    virtual void onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
243                                const SkPaint& paint) SK_OVERRIDE;
244    virtual void onPushCull(const SkRect& cullRect) SK_OVERRIDE;
245    virtual void onPopCull() SK_OVERRIDE;
246
247    virtual void onClipRect(const SkRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
248    virtual void onClipRRect(const SkRRect&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
249    virtual void onClipPath(const SkPath&, SkRegion::Op, ClipEdgeStyle) SK_OVERRIDE;
250    virtual void onClipRegion(const SkRegion& region, SkRegion::Op) SK_OVERRIDE;
251
252    virtual void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) SK_OVERRIDE;
253
254    void markActiveCommands(int index);
255
256private:
257    SkTDArray<SkDrawCommand*> fCommandVector;
258    SkPicture* fPicture;
259    SkISize fWindowSize;
260    bool fFilter;
261    bool fMegaVizMode;
262    int fIndex;
263    SkMatrix fUserMatrix;
264    SkMatrix fMatrix;
265    SkIRect fClip;
266
267    SkString fClipStackData;
268    bool fCalledAddStackData;
269    SkPath fSaveDevPath;
270
271    bool fOverdrawViz;
272    SkDrawFilter* fOverdrawFilter;
273
274    bool fOverrideTexFiltering;
275    SkTexOverrideFilter* fTexOverrideFilter;
276
277    /**
278        Number of unmatched save() calls at any point during a draw.
279        If there are any saveLayer() calls outstanding, we need to resolve
280        all of them, which in practice means resolving all save() calls,
281        to avoid corruption of our canvas.
282    */
283    int fOutstandingSaveCount;
284
285    /**
286        The active saveLayer commands at a given point in the renderering.
287        Only used when "mega" visualization is enabled.
288    */
289    SkTDArray<SkDrawCommand*> fActiveLayers;
290
291    /**
292        The active cull commands at a given point in the rendering.
293        Only used when "mega" visualization is enabled.
294    */
295    SkTDArray<SkDrawCommand*> fActiveCulls;
296
297    /**
298        Adds the command to the classes vector of commands.
299        @param command  The draw command for execution
300     */
301    void addDrawCommand(SkDrawCommand* command);
302
303    /**
304        Applies any panning and zooming the user has specified before
305        drawing anything else into the canvas.
306     */
307    void applyUserTransform(SkCanvas* canvas);
308
309    size_t getOpID() const {
310#if 0
311        if (fPicture) {
312            return fPicture->EXPERIMENTAL_curOpID();
313        }
314#endif
315        return 0;
316    }
317
318    void resetClipStackData() { fClipStackData.reset(); fCalledAddStackData = false; }
319
320    void addClipStackData(const SkPath& devPath, const SkPath& operand, SkRegion::Op elementOp);
321    void addPathData(const SkPath& path, const char* pathName);
322    bool lastClipStackData(const SkPath& devPath);
323    void outputConicPoints(const SkPoint* pts, SkScalar weight);
324    void outputPoints(const SkPoint* pts, int count);
325    void outputPointsCommon(const SkPoint* pts, int count);
326    void outputScalar(SkScalar num);
327
328    typedef SkCanvas INHERITED;
329};
330
331#endif
332