• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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
10 
11 #include <stdio.h>
12 
13 #include "SkBitmap.h"
14 #include "SkPoint.h"
15 
16 // 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 
20 #define MAX_TRACKING_POINTS 100
21 
22 /** \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  *
27  *   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  *
39  */
40 class SkTracker {
41 public:
SkTracker()42     SkTracker() : fEnabled(false)
43                 , fBreakOnAny(false)
44                 , fCntExpectedTouched(0)
45                 , fCntExpectedUntouched(0)
46                 , fHits(0) {}
47 
~SkTracker()48     virtual ~SkTracker() {}
49 
50     // Clears all the points, but preserves the break mode.
clearPoints()51     void clearPoints() {
52         fCntExpectedTouched = 0;
53         fCntExpectedUntouched = 0;
54     }
55 
56     // Enable the breackpoints.
enableTracking(bool b)57     void enableTracking(bool b) {
58         fEnabled = b;
59     }
60 
61     // Returns true if breackpoints are enabled.
trackingEnabled()62     bool trackingEnabled() {
63         return fEnabled;
64     }
65 
66     // Puts the tracker in Any mode.
any()67     void any() {
68         fBreakOnAny = true;
69     }
70 
71     // Puts the tracker in Any mode.
all()72     void all() {
73         fBreakOnAny = false;
74     }
75 
76     // returns true in in All mode. False for Any mode.
requireAllExpectedTouched()77     bool requireAllExpectedTouched() {
78         return !fBreakOnAny;
79     }
80 
81     // Returns the numbers of points in which if touched, would trigger a breackpoint.
cntExpectedTouched()82     int cntExpectedTouched() {
83         return fCntExpectedTouched;
84     }
85 
86     // Returns the points which if touched, would trigger a breackpoint.
87     // the Tracker owns the array
expectedTouched()88     const SkIPoint* expectedTouched() {
89         return fExpectedTouched;
90     }
91 
92     // Returns the numbers of points in which if touched, would disable a breackpoint.
cntExpectedUntouched()93     int cntExpectedUntouched() {
94         return fCntExpectedUntouched;
95     }
96 
97     // Returns the points which if touched, would disable a breackpoint.
98     // the Tracker owns the array
expectedUntouched()99     const SkIPoint* expectedUntouched() {
100         return fExpectedUntouched;
101     }
102 
103     // Adds a point which if changes in a drawFoo operation, would trigger a breakpoint.
addExpectTouch(int x,int y)104     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 
116     // Adds a point which if changes in a drawFoo operation, would disable a breakpoint.
addExpectUntouch(int x,int y)117     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 
129     // Starts a new rendering session - reset the number of hits.
newFrame()130     void newFrame() {
131         fHits = 0;
132     }
133 
134     // returns the number of breackpoints issues in this rendering session.
hits()135     int hits() {
136         return fHits;
137     }
138 
139     // Called before drawFoo to store the state of the pixels
before(const SkBitmap & bitmap)140     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++) {
149             fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(),
150                                             fExpectedUntouched[i].y());
151         }
152     }
153 
154     // Called after drawFoo to evaluate what pixels have changed, it could issue a breakpoint.
155     // any/all of the expected touched has to be changed, and all expected untouched must be intact
after(const SkBitmap & bitmap)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++) {
165                 doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
166                                                                     fExpectedTouched[i].y());
167             }
168         } else {
169             doBreak = true;
170             for (int i = 0 ; i < fCntExpectedTouched; i++) {
171                 doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
172                                                                     fExpectedTouched[i].y());
173             }
174         }
175 
176         for (int i = 0 ; i < fCntExpectedUntouched; i++) {
177             doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(),
178                                                                   fExpectedUntouched[i].y());
179         }
180 
181         if (doBreak) {
182             fHits++;
183             if (fEnabled) {
184                 breakExecution();
185             }
186         }
187     }
188 
189 private:
pickColor(const SkBitmap & bitmap,int x,int y)190     inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
191         return bitmap.getColor(x, y);
192     }
193 
breakExecution()194     void breakExecution() {
195         printf("break;\n");
196     }
197 
found(int x,int y)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 
227 #endif  // SkTracker_DEFINED
228