blob: ba368f3558225a87df3d0c36cfd3ed59403dd9ec [file] [log] [blame]
edisonn@google.comcf2cfa12013-08-21 16:31:37 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkTracker_DEFINED
9#define SkTracker_DEFINED
edisonn@google.comac03d912013-07-22 15:36:39 +000010
11#include "SkBitmap.h"
12#include "SkPoint.h"
13
edisonn@google.come50d9a12013-10-10 20:58:22 +000014// TODO(edisonn): draw plan from point! - list of draw ops of a point, like a tree!
15// TODO(edisonn): Minimal PDF to draw some points - remove everything that it is not needed,
16// save pdf uncompressed
17
edisonn@google.comac03d912013-07-22 15:36:39 +000018#define MAX_TRACKING_POINTS 100
19
edisonn@google.com2af2ad92013-10-11 16:17:44 +000020/** \class SkTracker
21 *
22 * A Tracker can be attached to a SkTrackDevice and it will store the track pixels.
23 * It can be used with SampleApp to investigate bugs (CL not checked in yet).
24 *
edisonn@google.comd03c2c72013-10-11 18:26:45 +000025 * The Tracker tracks 2 sets of points
26 * A) one which is expected to issue breackpoints if the pixels are changes
27 * B) one which if changes will disable the breackpoint
28 * For point in A) there are two modes:
29 * A.1) a breackpoint require that any of the points is changed
30 * A.2) a breackpoint require that all of the points is changed
31 * Points in B are allways in "any mode" - chaning the value of any pixel, will disable
32 * the breackpoint
33 *
34 * Point in A) are used to show what are the areas of interest, while poit in B are used to
35 * disable breackpoints which would be issued in background change.
36 *
edisonn@google.com2af2ad92013-10-11 16:17:44 +000037 */
edisonn@google.comac03d912013-07-22 15:36:39 +000038class SkTracker {
39public:
40 SkTracker() : fEnabled(false)
41 , fBreakOnAny(false)
42 , fCntExpectedTouched(0)
43 , fCntExpectedUntouched(0)
44 , fHits(0) {}
45
46 virtual ~SkTracker() {}
47
edisonn@google.comd03c2c72013-10-11 18:26:45 +000048 // Clears all the points, but preserves the break mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000049 void clearPoints() {
50 fCntExpectedTouched = 0;
51 fCntExpectedUntouched = 0;
52 }
53
edisonn@google.comd03c2c72013-10-11 18:26:45 +000054 // Enable the breackpoints.
edisonn@google.comac03d912013-07-22 15:36:39 +000055 void enableTracking(bool b) {
56 fEnabled = b;
57 }
58
edisonn@google.comd03c2c72013-10-11 18:26:45 +000059 // Returns true if breackpoints are enabled.
edisonn@google.comac03d912013-07-22 15:36:39 +000060 bool trackingEnabled() {
61 return fEnabled;
62 }
63
edisonn@google.comd03c2c72013-10-11 18:26:45 +000064 // Puts the tracker in Any mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000065 void any() {
66 fBreakOnAny = true;
67 }
68
edisonn@google.comd03c2c72013-10-11 18:26:45 +000069 // Puts the tracker in Any mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000070 void all() {
71 fBreakOnAny = false;
72 }
73
edisonn@google.comd03c2c72013-10-11 18:26:45 +000074 // returns true in in All mode. False for Any mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000075 bool requireAllExpectedTouched() {
76 return !fBreakOnAny;
77 }
78
edisonn@google.comd03c2c72013-10-11 18:26:45 +000079 // Returns the numbers of points in which if touched, would trigger a breackpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +000080 int cntExpectedTouched() {
81 return fCntExpectedTouched;
82 }
83
edisonn@google.comd03c2c72013-10-11 18:26:45 +000084 // Returns the points which if touched, would trigger a breackpoint.
85 // the Tracker owns the array
edisonn@google.comac03d912013-07-22 15:36:39 +000086 const SkIPoint* expectedTouched() {
87 return fExpectedTouched;
88 }
89
edisonn@google.comd03c2c72013-10-11 18:26:45 +000090 // Returns the numbers of points in which if touched, would disable a breackpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +000091 int cntExpectedUntouched() {
92 return fCntExpectedUntouched;
93 }
94
edisonn@google.comd03c2c72013-10-11 18:26:45 +000095 // Returns the points which if touched, would disable a breackpoint.
96 // the Tracker owns the array
edisonn@google.comac03d912013-07-22 15:36:39 +000097 const SkIPoint* expectedUntouched() {
98 return fExpectedUntouched;
99 }
100
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000101 // Adds a point which if changes in a drawFoo operation, would trigger a breakpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +0000102 bool addExpectTouch(int x, int y) {
103 if (fCntExpectedTouched >= MAX_TRACKING_POINTS) {
104 return false;
105 }
106 if (found(x, y)) {
107 return false;
108 }
109 fExpectedTouched[fCntExpectedTouched] = SkIPoint::Make(x, y);
110 fCntExpectedTouched++;
111 return true;
112 }
113
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000114 // Adds a point which if changes in a drawFoo operation, would disable a breakpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +0000115 bool addExpectUntouch(int x, int y) {
116 if (fCntExpectedUntouched >= MAX_TRACKING_POINTS) {
117 return false;
118 }
119 if (found(x, y)) {
120 return false;
121 }
122 fExpectedUntouched[fCntExpectedUntouched] = SkIPoint::Make(x, y);
123 fCntExpectedUntouched++;
124 return true;
125 }
126
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000127 // Starts a new rendering session - reset the number of hits.
edisonn@google.comac03d912013-07-22 15:36:39 +0000128 void newFrame() {
129 fHits = 0;
130 }
131
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000132 // returns the number of breackpoints issues in this rendering session.
edisonn@google.comac03d912013-07-22 15:36:39 +0000133 int hits() {
134 return fHits;
135 }
136
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000137 // Called before drawFoo to store the state of the pixels
edisonn@google.comac03d912013-07-22 15:36:39 +0000138 void before(const SkBitmap& bitmap) {
139 if (fCntExpectedTouched == 0) {
140 return;
141 }
142
143 for (int i = 0 ; i < fCntExpectedTouched; i++) {
144 fBeforeTouched[i] = pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
145 }
146 for (int i = 0 ; i < fCntExpectedUntouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000147 fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(),
148 fExpectedUntouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000149 }
150 }
151
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000152 // Called after drawFoo to evaluate what pixels have changed, it could issue a breakpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +0000153 // any/all of the expected touched has to be changed, and all expected untouched must be intact
154 void after(const SkBitmap& bitmap) {
155 if (fCntExpectedTouched == 0) {
156 return;
157 }
158
159 bool doBreak;
160 if (fBreakOnAny) {
161 doBreak = false;
162 for (int i = 0 ; i < fCntExpectedTouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000163 doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
164 fExpectedTouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000165 }
166 } else {
167 doBreak = true;
168 for (int i = 0 ; i < fCntExpectedTouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000169 doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
170 fExpectedTouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000171 }
172 }
173
174 for (int i = 0 ; i < fCntExpectedUntouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000175 doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(),
176 fExpectedUntouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000177 }
178
179 if (doBreak) {
180 fHits++;
181 if (fEnabled) {
182 breakExecution();
183 }
184 }
185 }
186
187private:
188 inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
189 return bitmap.getColor(x, y);
190 }
191
192 void breakExecution() {
193 printf("break;\n");
194 }
195
196 inline bool found(int x, int y) {
197 for (int i = 0 ; i < fCntExpectedTouched; i++) {
198 if (x == fExpectedTouched[i].x() && y == fExpectedTouched[i].y()) {
199 return true;
200 }
201 }
202 for (int i = 0 ; i < fCntExpectedUntouched; i++) {
203 if (x == fExpectedUntouched[i].x() && y == fExpectedUntouched[i].y()) {
204 return true;
205 }
206 }
207 return false;
208 }
209
210
211 bool fEnabled;
212 // break on any change on expected touched or all.
213 bool fBreakOnAny;
214 SkIPoint fExpectedTouched[MAX_TRACKING_POINTS];
215 SkColor fBeforeTouched[MAX_TRACKING_POINTS];
216 int fCntExpectedTouched;
217
218 SkIPoint fExpectedUntouched[MAX_TRACKING_POINTS];
219 SkColor fBeforeUntouched[MAX_TRACKING_POINTS];
220 int fCntExpectedUntouched;
221
222 int fHits;
223};
224
edisonn@google.comcf2cfa12013-08-21 16:31:37 +0000225#endif // SkTracker_DEFINED