2013-08-21 16:31:37 +00:00
|
|
|
/*
|
|
|
|
* Copyright 2013 Google Inc.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
|
|
* found in the LICENSE file.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef SkTracker_DEFINED
|
|
|
|
#define SkTracker_DEFINED
|
2013-07-22 15:36:39 +00:00
|
|
|
|
2013-11-07 22:07:34 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
|
2013-07-22 15:36:39 +00:00
|
|
|
#include "SkBitmap.h"
|
|
|
|
#include "SkPoint.h"
|
|
|
|
|
2013-10-10 20:58:22 +00:00
|
|
|
// TODO(edisonn): draw plan from point! - list of draw ops of a point, like a tree!
|
|
|
|
// TODO(edisonn): Minimal PDF to draw some points - remove everything that it is not needed,
|
|
|
|
// save pdf uncompressed
|
|
|
|
|
2013-07-22 15:36:39 +00:00
|
|
|
#define MAX_TRACKING_POINTS 100
|
|
|
|
|
2013-10-11 16:17:44 +00:00
|
|
|
/** \class SkTracker
|
|
|
|
*
|
|
|
|
* A Tracker can be attached to a SkTrackDevice and it will store the track pixels.
|
|
|
|
* It can be used with SampleApp to investigate bugs (CL not checked in yet).
|
|
|
|
*
|
2013-10-11 18:26:45 +00:00
|
|
|
* The Tracker tracks 2 sets of points
|
|
|
|
* A) one which is expected to issue breackpoints if the pixels are changes
|
|
|
|
* B) one which if changes will disable the breackpoint
|
|
|
|
* For point in A) there are two modes:
|
|
|
|
* A.1) a breackpoint require that any of the points is changed
|
|
|
|
* A.2) a breackpoint require that all of the points is changed
|
|
|
|
* Points in B are allways in "any mode" - chaning the value of any pixel, will disable
|
|
|
|
* the breackpoint
|
|
|
|
*
|
|
|
|
* Point in A) are used to show what are the areas of interest, while poit in B are used to
|
|
|
|
* disable breackpoints which would be issued in background change.
|
|
|
|
*
|
2013-10-11 16:17:44 +00:00
|
|
|
*/
|
2013-07-22 15:36:39 +00:00
|
|
|
class SkTracker {
|
|
|
|
public:
|
|
|
|
SkTracker() : fEnabled(false)
|
|
|
|
, fBreakOnAny(false)
|
|
|
|
, fCntExpectedTouched(0)
|
|
|
|
, fCntExpectedUntouched(0)
|
|
|
|
, fHits(0) {}
|
|
|
|
|
|
|
|
virtual ~SkTracker() {}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Clears all the points, but preserves the break mode.
|
2013-07-22 15:36:39 +00:00
|
|
|
void clearPoints() {
|
|
|
|
fCntExpectedTouched = 0;
|
|
|
|
fCntExpectedUntouched = 0;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Enable the breackpoints.
|
2013-07-22 15:36:39 +00:00
|
|
|
void enableTracking(bool b) {
|
|
|
|
fEnabled = b;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Returns true if breackpoints are enabled.
|
2013-07-22 15:36:39 +00:00
|
|
|
bool trackingEnabled() {
|
|
|
|
return fEnabled;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Puts the tracker in Any mode.
|
2013-07-22 15:36:39 +00:00
|
|
|
void any() {
|
|
|
|
fBreakOnAny = true;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Puts the tracker in Any mode.
|
2013-07-22 15:36:39 +00:00
|
|
|
void all() {
|
|
|
|
fBreakOnAny = false;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// returns true in in All mode. False for Any mode.
|
2013-07-22 15:36:39 +00:00
|
|
|
bool requireAllExpectedTouched() {
|
|
|
|
return !fBreakOnAny;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Returns the numbers of points in which if touched, would trigger a breackpoint.
|
2013-07-22 15:36:39 +00:00
|
|
|
int cntExpectedTouched() {
|
|
|
|
return fCntExpectedTouched;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Returns the points which if touched, would trigger a breackpoint.
|
|
|
|
// the Tracker owns the array
|
2013-07-22 15:36:39 +00:00
|
|
|
const SkIPoint* expectedTouched() {
|
|
|
|
return fExpectedTouched;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Returns the numbers of points in which if touched, would disable a breackpoint.
|
2013-07-22 15:36:39 +00:00
|
|
|
int cntExpectedUntouched() {
|
|
|
|
return fCntExpectedUntouched;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Returns the points which if touched, would disable a breackpoint.
|
|
|
|
// the Tracker owns the array
|
2013-07-22 15:36:39 +00:00
|
|
|
const SkIPoint* expectedUntouched() {
|
|
|
|
return fExpectedUntouched;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Adds a point which if changes in a drawFoo operation, would trigger a breakpoint.
|
2013-07-22 15:36:39 +00:00
|
|
|
bool addExpectTouch(int x, int y) {
|
|
|
|
if (fCntExpectedTouched >= MAX_TRACKING_POINTS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (found(x, y)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
fExpectedTouched[fCntExpectedTouched] = SkIPoint::Make(x, y);
|
|
|
|
fCntExpectedTouched++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Adds a point which if changes in a drawFoo operation, would disable a breakpoint.
|
2013-07-22 15:36:39 +00:00
|
|
|
bool addExpectUntouch(int x, int y) {
|
|
|
|
if (fCntExpectedUntouched >= MAX_TRACKING_POINTS) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (found(x, y)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
fExpectedUntouched[fCntExpectedUntouched] = SkIPoint::Make(x, y);
|
|
|
|
fCntExpectedUntouched++;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Starts a new rendering session - reset the number of hits.
|
2013-07-22 15:36:39 +00:00
|
|
|
void newFrame() {
|
|
|
|
fHits = 0;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// returns the number of breackpoints issues in this rendering session.
|
2013-07-22 15:36:39 +00:00
|
|
|
int hits() {
|
|
|
|
return fHits;
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Called before drawFoo to store the state of the pixels
|
2013-07-22 15:36:39 +00:00
|
|
|
void before(const SkBitmap& bitmap) {
|
|
|
|
if (fCntExpectedTouched == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0 ; i < fCntExpectedTouched; i++) {
|
|
|
|
fBeforeTouched[i] = pickColor(bitmap, fExpectedTouched[i].x(), fExpectedTouched[i].y());
|
|
|
|
}
|
|
|
|
for (int i = 0 ; i < fCntExpectedUntouched; i++) {
|
2013-10-10 20:58:22 +00:00
|
|
|
fBeforeUntouched[i] = pickColor(bitmap, fExpectedUntouched[i].x(),
|
|
|
|
fExpectedUntouched[i].y());
|
2013-07-22 15:36:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-11 18:26:45 +00:00
|
|
|
// Called after drawFoo to evaluate what pixels have changed, it could issue a breakpoint.
|
2013-07-22 15:36:39 +00:00
|
|
|
// any/all of the expected touched has to be changed, and all expected untouched must be intact
|
|
|
|
void after(const SkBitmap& bitmap) {
|
|
|
|
if (fCntExpectedTouched == 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool doBreak;
|
|
|
|
if (fBreakOnAny) {
|
|
|
|
doBreak = false;
|
|
|
|
for (int i = 0 ; i < fCntExpectedTouched; i++) {
|
2013-10-10 20:58:22 +00:00
|
|
|
doBreak = doBreak || fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
|
|
|
|
fExpectedTouched[i].y());
|
2013-07-22 15:36:39 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
doBreak = true;
|
|
|
|
for (int i = 0 ; i < fCntExpectedTouched; i++) {
|
2013-10-10 20:58:22 +00:00
|
|
|
doBreak = doBreak && fBeforeTouched[i] != pickColor(bitmap, fExpectedTouched[i].x(),
|
|
|
|
fExpectedTouched[i].y());
|
2013-07-22 15:36:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0 ; i < fCntExpectedUntouched; i++) {
|
2013-10-10 20:58:22 +00:00
|
|
|
doBreak = doBreak && fBeforeUntouched[i] == pickColor(bitmap, fExpectedUntouched[i].x(),
|
|
|
|
fExpectedUntouched[i].y());
|
2013-07-22 15:36:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (doBreak) {
|
|
|
|
fHits++;
|
|
|
|
if (fEnabled) {
|
|
|
|
breakExecution();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
inline SkColor pickColor(const SkBitmap& bitmap, int x, int y) {
|
|
|
|
return bitmap.getColor(x, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
void breakExecution() {
|
|
|
|
printf("break;\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
inline bool found(int x, int y) {
|
|
|
|
for (int i = 0 ; i < fCntExpectedTouched; i++) {
|
|
|
|
if (x == fExpectedTouched[i].x() && y == fExpectedTouched[i].y()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0 ; i < fCntExpectedUntouched; i++) {
|
|
|
|
if (x == fExpectedUntouched[i].x() && y == fExpectedUntouched[i].y()) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool fEnabled;
|
|
|
|
// break on any change on expected touched or all.
|
|
|
|
bool fBreakOnAny;
|
|
|
|
SkIPoint fExpectedTouched[MAX_TRACKING_POINTS];
|
|
|
|
SkColor fBeforeTouched[MAX_TRACKING_POINTS];
|
|
|
|
int fCntExpectedTouched;
|
|
|
|
|
|
|
|
SkIPoint fExpectedUntouched[MAX_TRACKING_POINTS];
|
|
|
|
SkColor fBeforeUntouched[MAX_TRACKING_POINTS];
|
|
|
|
int fCntExpectedUntouched;
|
|
|
|
|
|
|
|
int fHits;
|
|
|
|
};
|
|
|
|
|
2013-08-21 16:31:37 +00:00
|
|
|
#endif // SkTracker_DEFINED
|