blob: 3da24c1ee00d436312606c89d551904db2aee785 [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
edisonn@google.comb9731e72013-11-07 22:07:34 +000011#include <stdio.h>
12
edisonn@google.comac03d912013-07-22 15:36:39 +000013#include "SkBitmap.h"
14#include "SkPoint.h"
15
edisonn@google.come50d9a12013-10-10 20:58:22 +000016// TODO(edisonn): draw plan from point! - list of draw ops of a point, like a tree!
17// TODO(edisonn): Minimal PDF to draw some points - remove everything that it is not needed,
18// save pdf uncompressed
19
edisonn@google.comac03d912013-07-22 15:36:39 +000020#define MAX_TRACKING_POINTS 100
21
edisonn@google.com2af2ad92013-10-11 16:17:44 +000022/** \class SkTracker
23 *
24 * A Tracker can be attached to a SkTrackDevice and it will store the track pixels.
25 * It can be used with SampleApp to investigate bugs (CL not checked in yet).
26 *
edisonn@google.comd03c2c72013-10-11 18:26:45 +000027 * The Tracker tracks 2 sets of points
28 * A) one which is expected to issue breackpoints if the pixels are changes
29 * B) one which if changes will disable the breackpoint
30 * For point in A) there are two modes:
31 * A.1) a breackpoint require that any of the points is changed
32 * A.2) a breackpoint require that all of the points is changed
33 * Points in B are allways in "any mode" - chaning the value of any pixel, will disable
34 * the breackpoint
35 *
36 * Point in A) are used to show what are the areas of interest, while poit in B are used to
37 * disable breackpoints which would be issued in background change.
38 *
edisonn@google.com2af2ad92013-10-11 16:17:44 +000039 */
edisonn@google.comac03d912013-07-22 15:36:39 +000040class SkTracker {
41public:
42 SkTracker() : fEnabled(false)
43 , fBreakOnAny(false)
44 , fCntExpectedTouched(0)
45 , fCntExpectedUntouched(0)
46 , fHits(0) {}
47
48 virtual ~SkTracker() {}
49
edisonn@google.comd03c2c72013-10-11 18:26:45 +000050 // Clears all the points, but preserves the break mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000051 void clearPoints() {
52 fCntExpectedTouched = 0;
53 fCntExpectedUntouched = 0;
54 }
55
edisonn@google.comd03c2c72013-10-11 18:26:45 +000056 // Enable the breackpoints.
edisonn@google.comac03d912013-07-22 15:36:39 +000057 void enableTracking(bool b) {
58 fEnabled = b;
59 }
60
edisonn@google.comd03c2c72013-10-11 18:26:45 +000061 // Returns true if breackpoints are enabled.
edisonn@google.comac03d912013-07-22 15:36:39 +000062 bool trackingEnabled() {
63 return fEnabled;
64 }
65
edisonn@google.comd03c2c72013-10-11 18:26:45 +000066 // Puts the tracker in Any mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000067 void any() {
68 fBreakOnAny = true;
69 }
70
edisonn@google.comd03c2c72013-10-11 18:26:45 +000071 // Puts the tracker in Any mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000072 void all() {
73 fBreakOnAny = false;
74 }
75
edisonn@google.comd03c2c72013-10-11 18:26:45 +000076 // returns true in in All mode. False for Any mode.
edisonn@google.comac03d912013-07-22 15:36:39 +000077 bool requireAllExpectedTouched() {
78 return !fBreakOnAny;
79 }
80
edisonn@google.comd03c2c72013-10-11 18:26:45 +000081 // Returns the numbers of points in which if touched, would trigger a breackpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +000082 int cntExpectedTouched() {
83 return fCntExpectedTouched;
84 }
85
edisonn@google.comd03c2c72013-10-11 18:26:45 +000086 // Returns the points which if touched, would trigger a breackpoint.
87 // the Tracker owns the array
edisonn@google.comac03d912013-07-22 15:36:39 +000088 const SkIPoint* expectedTouched() {
89 return fExpectedTouched;
90 }
91
edisonn@google.comd03c2c72013-10-11 18:26:45 +000092 // Returns the numbers of points in which if touched, would disable a breackpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +000093 int cntExpectedUntouched() {
94 return fCntExpectedUntouched;
95 }
96
edisonn@google.comd03c2c72013-10-11 18:26:45 +000097 // Returns the points which if touched, would disable a breackpoint.
98 // the Tracker owns the array
edisonn@google.comac03d912013-07-22 15:36:39 +000099 const SkIPoint* expectedUntouched() {
100 return fExpectedUntouched;
101 }
102
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000103 // Adds a point which if changes in a drawFoo operation, would trigger a breakpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +0000104 bool addExpectTouch(int x, int y) {
105 if (fCntExpectedTouched >= MAX_TRACKING_POINTS) {
106 return false;
107 }
108 if (found(x, y)) {
109 return false;
110 }
111 fExpectedTouched[fCntExpectedTouched] = SkIPoint::Make(x, y);
112 fCntExpectedTouched++;
113 return true;
114 }
115
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000116 // Adds a point which if changes in a drawFoo operation, would disable a breakpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +0000117 bool addExpectUntouch(int x, int y) {
118 if (fCntExpectedUntouched >= MAX_TRACKING_POINTS) {
119 return false;
120 }
121 if (found(x, y)) {
122 return false;
123 }
124 fExpectedUntouched[fCntExpectedUntouched] = SkIPoint::Make(x, y);
125 fCntExpectedUntouched++;
126 return true;
127 }
128
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000129 // Starts a new rendering session - reset the number of hits.
edisonn@google.comac03d912013-07-22 15:36:39 +0000130 void newFrame() {
131 fHits = 0;
132 }
133
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000134 // returns the number of breackpoints issues in this rendering session.
edisonn@google.comac03d912013-07-22 15:36:39 +0000135 int hits() {
136 return fHits;
137 }
138
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000139 // Called before drawFoo to store the state of the pixels
edisonn@google.comac03d912013-07-22 15:36:39 +0000140 void before(const SkBitmap& bitmap) {
141 if (fCntExpectedTouched == 0) {
142 return;
143 }
144
145 for (int i = 0 ; i < fCntExpectedTouched; i++) {
146 fBeforeTouched[i] = pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
147 }
148 for (int i = 0 ; i < fCntExpectedUntouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000149 fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(),
150 fExpectedUntouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000151 }
152 }
153
edisonn@google.comd03c2c72013-10-11 18:26:45 +0000154 // Called after drawFoo to evaluate what pixels have changed, it could issue a breakpoint.
edisonn@google.comac03d912013-07-22 15:36:39 +0000155 // any/all of the expected touched has to be changed, and all expected untouched must be intact
156 void after(const SkBitmap& bitmap) {
157 if (fCntExpectedTouched == 0) {
158 return;
159 }
160
161 bool doBreak;
162 if (fBreakOnAny) {
163 doBreak = false;
164 for (int i = 0 ; i < fCntExpectedTouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000165 doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
166 fExpectedTouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000167 }
168 } else {
169 doBreak = true;
170 for (int i = 0 ; i < fCntExpectedTouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000171 doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
172 fExpectedTouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000173 }
174 }
175
176 for (int i = 0 ; i < fCntExpectedUntouched; i++) {
edisonn@google.come50d9a12013-10-10 20:58:22 +0000177 doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(),
178 fExpectedUntouched[i].y());
edisonn@google.comac03d912013-07-22 15:36:39 +0000179 }
180
181 if (doBreak) {
182 fHits++;
183 if (fEnabled) {
184 breakExecution();
185 }
186 }
187 }
188
189private:
190 inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
191 return bitmap.getColor(x, y);
192 }
193
194 void breakExecution() {
195 printf("break;\n");
196 }
197
198 inline bool found(int x, int y) {
199 for (int i = 0 ; i < fCntExpectedTouched; i++) {
200 if (x == fExpectedTouched[i].x() && y == fExpectedTouched[i].y()) {
201 return true;
202 }
203 }
204 for (int i = 0 ; i < fCntExpectedUntouched; i++) {
205 if (x == fExpectedUntouched[i].x() && y == fExpectedUntouched[i].y()) {
206 return true;
207 }
208 }
209 return false;
210 }
211
212
213 bool fEnabled;
214 // break on any change on expected touched or all.
215 bool fBreakOnAny;
216 SkIPoint fExpectedTouched[MAX_TRACKING_POINTS];
217 SkColor fBeforeTouched[MAX_TRACKING_POINTS];
218 int fCntExpectedTouched;
219
220 SkIPoint fExpectedUntouched[MAX_TRACKING_POINTS];
221 SkColor fBeforeUntouched[MAX_TRACKING_POINTS];
222 int fCntExpectedUntouched;
223
224 int fHits;
225};
226
edisonn@google.comcf2cfa12013-08-21 16:31:37 +0000227#endif // SkTracker_DEFINED