1cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com/*
2cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Copyright 2013 Google Inc.
3cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com *
4cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * Use of this source code is governed by a BSD-style license that can be
5cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com * found in the LICENSE file.
6cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com */
7cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com
8cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#ifndef SkTrackDevice_DEFINED
9cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#define SkTrackDevice_DEFINED
10ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
11e91260c3e75d9d26e391be6823ea37373b27d1ffedisonn@google.com#include "SkBitmapDevice.h"
12ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com#include "SkTracker.h"
13ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
142af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com/** \class SkTrackDevice
152af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *
162af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *   A Track Device is used to track that callstack of an operation that affected some pixels.
172af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *   It can be used with SampleApp to investigate bugs (CL not checked in yet).
182af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com *
19d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com *   every drawFoo is implemented as such:
20d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com *      before();   // - collects state of interesting pixels
21d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com *      INHERITED::drawFoo(...);
22d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com *      after();  // - checks if pixels of interest, and issue a breakpoint.
23d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com *
242af2ad9cc0b2c7d911aed2e8d2ac77c0b7d3b5dfedisonn@google.com */
251f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comclass SkTrackDevice : public SkBitmapDevice {
26ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.compublic:
27ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    SK_DECLARE_INST_COUNT(SkTrackDevice)
28ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
291f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    SkTrackDevice(const SkBitmap& bitmap) : SkBitmapDevice(bitmap)
30ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                                          , fTracker(NULL) {}
31ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
32ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual ~SkTrackDevice() {}
33ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
34d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com    // Install a tracker - we can reuse the tracker between multiple devices, and the state of the
35d03c2c732e2e914f8429cfc8b077a7b9b853dd8eedisonn@google.com    // tracker is preserved - number and location of poinbts, ...
36ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    void installTracker(SkTracker* tracker) {
37ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        fTracker = tracker;
38ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        fTracker->newFrame();
39ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
40ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
41ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.comprotected:
42b19ce3146c58373ccdb6c74f4cb6ca6fc35e9f2creed#if 0   // clear is deprecated (and private)
43ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void clear(SkColor color) {
44ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
45ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::clear(color);
46ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
47ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
48b19ce3146c58373ccdb6c74f4cb6ca6fc35e9f2creed#endif
49ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
50ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawPaint(const SkDraw& dummy1, const SkPaint& paint) {
51ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
52ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawPaint(dummy1, paint);
53ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
54ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
55ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
56ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawPoints(const SkDraw& dummy1, SkCanvas::PointMode mode, size_t count,
57ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                            const SkPoint dummy2[], const SkPaint& paint) {
58ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
59ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawPoints(dummy1, mode, count, dummy2, paint);
60ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
61ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
62ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
63ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawRect(const SkDraw& dummy1, const SkRect& r,
64ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                          const SkPaint& paint) {
65ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
66ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawRect(dummy1, r, paint);
67ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
68ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
69ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
70ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
71ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawOval(const SkDraw& dummy1, const SkRect& oval,
72ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                          const SkPaint& paint) {
73ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
74ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawOval(dummy1, oval, paint);
75ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
76ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
77ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
78ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawRRect(const SkDraw& dummy1, const SkRRect& rr,
79ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                           const SkPaint& paint) {
80ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
81ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawRRect(dummy1, rr, paint);
82ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
83ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
84ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
85ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawPath(const SkDraw& dummy1, const SkPath& path,
86ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                          const SkPaint& paint,
87ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                          const SkMatrix* prePathMatrix = NULL,
88ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                          bool pathIsMutable = false) {
89ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
90ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawPath(dummy1, path, paint, prePathMatrix, pathIsMutable);
91ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
92ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
93ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
94ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawBitmap(const SkDraw& dummy1, const SkBitmap& bitmap,
95ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                            const SkMatrix& matrix, const SkPaint& paint) {
96ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
9750bbdb4f3edc5005a71c438651732f53c00a5331edisonn@google.com        INHERITED::drawBitmap(dummy1, bitmap, matrix, paint);
98ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
99ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
100ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
101ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawSprite(const SkDraw& dummy1, const SkBitmap& bitmap,
102ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                            int x, int y, const SkPaint& paint) {
103ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
104ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawSprite(dummy1, bitmap, x, y, paint);
105ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
106ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
107ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
108ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawBitmapRect(const SkDraw& dummy1, const SkBitmap& dummy2,
109ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                                const SkRect* srcOrNull, const SkRect& dst,
1102c8177767a4b3b6c27c6ac071c8619b557472521edisonn@google.com                                const SkPaint& paint,
1112c8177767a4b3b6c27c6ac071c8619b557472521edisonn@google.com                                SkCanvas::DrawBitmapRectFlags flags) {
112ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
1132c8177767a4b3b6c27c6ac071c8619b557472521edisonn@google.com        INHERITED::drawBitmapRect(dummy1, dummy2, srcOrNull, dst, paint, flags);
114ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
115ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
116ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
117ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawText(const SkDraw& dummy1, const void* text, size_t len,
118ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                          SkScalar x, SkScalar y, const SkPaint& paint) {
119ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
120ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawText(dummy1, text, len, x, y, paint);
121ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
122ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
123ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
124ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawPosText(const SkDraw& dummy1, const void* text, size_t len,
12505c4a4322e7d4f3417b7df33825bab8603d52051fmalita                             const SkScalar pos[], int scalarsPerPos,
12605c4a4322e7d4f3417b7df33825bab8603d52051fmalita                             const SkPoint& offset, const SkPaint& paint) {
127ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
12805c4a4322e7d4f3417b7df33825bab8603d52051fmalita        INHERITED::drawPosText(dummy1, text, len, pos, scalarsPerPos, offset, paint);
129ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
130ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
131ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
132ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawTextOnPath(const SkDraw& dummy1, const void* text, size_t len,
133ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                                const SkPath& path, const SkMatrix* matrix,
134ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                                const SkPaint& paint)  {
135ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
136ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawTextOnPath(dummy1, text, len, path, matrix, paint);
137ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
138ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
139ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
140ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    virtual void drawVertices(const SkDraw& dummy1, SkCanvas::VertexMode dummy2, int vertexCount,
141ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                              const SkPoint verts[], const SkPoint texs[],
142ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                              const SkColor colors[], SkXfermode* xmode,
143ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                              const uint16_t indices[], int indexCount,
144ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                              const SkPaint& paint) {
145ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
146e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com        INHERITED::drawVertices(dummy1, dummy2, vertexCount,verts, texs,colors, xmode, indices,
147e50d9a1fcd9c4298079ff54f9a40c9708d30f8c6edisonn@google.com                                indexCount, paint);
148ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
149ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
150ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
1511f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    virtual void drawDevice(const SkDraw& dummy1, SkBaseDevice* dummy2, int x, int y,
152ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com                            const SkPaint& dummy3) {
153ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        before();
154ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        INHERITED::drawDevice(dummy1, dummy2, x, y, dummy3);
155ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        after();
156ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
157ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
158ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.comprivate:
159ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    void before() {
160ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        if (fTracker) {
161ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com            fTracker->before(accessBitmap(false));
162ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        }
163ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
164ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
165ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    // any/all of the expected touched has to be changed, and all expected untouched must be intact
166ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    void after() {
167ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        if (fTracker) {
168ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com            fTracker->after(accessBitmap(false));
169ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com        }
170ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    }
171ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
172ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.comprivate:
173ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com    SkTracker* fTracker;
174ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
1751f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    typedef SkBitmapDevice INHERITED;
176ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com};
177ac03d91ee03599eab946a8ad25e33f9fc5f3166eedisonn@google.com
178cf2cfa174ca878c144e17e9fc60ca8e9070d7dededisonn@google.com#endif  // SkTrackDevice_DEFINED
179