OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef image_expectations_DEFINED | 8 #ifndef image_expectations_DEFINED |
9 #define image_expectations_DEFINED | 9 #define image_expectations_DEFINED |
10 | 10 |
11 #include "SkBitmap.h" | 11 #include "SkBitmap.h" |
12 #include "SkJSONCPP.h" | 12 #include "SkJSONCPP.h" |
13 #include "SkOSFile.h" | 13 #include "SkOSFile.h" |
14 #include "SkRefCnt.h" | |
15 | 14 |
16 namespace sk_tools { | 15 namespace sk_tools { |
17 | 16 |
18 /** | 17 /** |
19 * The digest of an image (either an image we have generated locally, or an
image expectation). | 18 * The digest of an image (either an image we have generated locally, or an
image expectation). |
20 * | 19 * |
21 * Currently, this is always a uint64_t hash digest of an SkBitmap. | 20 * Currently, this is always a uint64_t hash digest of an SkBitmap. |
22 */ | 21 */ |
23 class ImageDigest : public SkRefCnt { | 22 class ImageDigest { |
24 public: | 23 public: |
25 /** | 24 /** |
26 * Create an ImageDigest of a bitmap. | 25 * Create an ImageDigest of a bitmap. |
27 * | 26 * |
28 * Note that this is an expensive operation, because it has to examine a
ll pixels in | 27 * Computes the hash of the bitmap lazily, since that is an expensive op
eration. |
29 * the bitmap. You may wish to consider using the BitmapAndDigest class
, which will | |
30 * compute the ImageDigest lazily. | |
31 * | 28 * |
32 * @param bitmap image to get the digest of | 29 * @param bitmap image to get the digest of |
33 */ | 30 */ |
34 explicit ImageDigest(const SkBitmap &bitmap); | 31 explicit ImageDigest(const SkBitmap &bitmap); |
35 | 32 |
36 /** | 33 /** |
37 * Create an ImageDigest using a hashType/hashValue pair. | 34 * Create an ImageDigest using a hashType/hashValue pair. |
38 * | 35 * |
39 * @param hashType the algorithm used to generate the hash; for now, onl
y | 36 * @param hashType the algorithm used to generate the hash; for now, onl
y |
40 * kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed. | 37 * kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5 is allowed. |
41 * @param hashValue the value generated by the hash algorithm for a part
icular image. | 38 * @param hashValue the value generated by the hash algorithm for a part
icular image. |
42 */ | 39 */ |
43 explicit ImageDigest(const SkString &hashType, uint64_t hashValue); | 40 explicit ImageDigest(const SkString &hashType, uint64_t hashValue); |
44 | 41 |
45 /** | 42 /** |
| 43 * Returns true iff this and other ImageDigest represent identical image
s. |
| 44 */ |
| 45 bool equals(ImageDigest &other); |
| 46 |
| 47 /** |
46 * Returns the hash digest type as an SkString. | 48 * Returns the hash digest type as an SkString. |
47 * | 49 * |
48 * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitma
p64bitMD5 . | 50 * For now, this always returns kJsonValue_Image_ChecksumAlgorithm_Bitma
p64bitMD5 . |
49 */ | 51 */ |
50 SkString getHashType() const; | 52 SkString getHashType(); |
51 | 53 |
52 /** | 54 /** |
53 * Returns the hash digest value as a uint64_t. | 55 * Returns the hash digest value as a uint64_t. |
| 56 * |
| 57 * Since the hash is computed lazily, this may take some time, and it ma
y modify |
| 58 * some fields on this object. |
54 */ | 59 */ |
55 uint64_t getHashValue() const; | 60 uint64_t getHashValue(); |
56 | 61 |
57 private: | 62 private: |
| 63 const SkBitmap fBitmap; |
58 uint64_t fHashValue; | 64 uint64_t fHashValue; |
| 65 bool fComputedHashValue; |
59 }; | 66 }; |
60 | 67 |
61 /** | 68 /** |
62 * Container that holds a reference to an SkBitmap and computes its ImageDig
est lazily. | 69 * Container that holds a reference to an SkBitmap and its ImageDigest. |
63 * | |
64 * Computing the ImageDigest can be expensive, so this can help you postpone
(or maybe even | |
65 * avoid) that work. | |
66 */ | 70 */ |
67 class BitmapAndDigest { | 71 class BitmapAndDigest { |
68 public: | 72 public: |
69 explicit BitmapAndDigest(const SkBitmap &bitmap); | 73 explicit BitmapAndDigest(const SkBitmap &bitmap); |
70 | 74 |
71 const ImageDigest *getImageDigestPtr(); | |
72 const SkBitmap *getBitmapPtr() const; | 75 const SkBitmap *getBitmapPtr() const; |
| 76 |
| 77 /** |
| 78 * Returns a pointer to the ImageDigest. |
| 79 * |
| 80 * Since the hash is computed lazily within the ImageDigest object, we c
annot mandate |
| 81 * that it be held const. |
| 82 */ |
| 83 ImageDigest *getImageDigestPtr(); |
73 private: | 84 private: |
74 const SkBitmap fBitmap; | 85 const SkBitmap fBitmap; |
75 SkAutoTUnref<ImageDigest> fImageDigestRef; | 86 ImageDigest fImageDigest; |
76 }; | 87 }; |
77 | 88 |
78 /** | 89 /** |
| 90 * Expected test result: expected image (if any), and whether we want to ign
ore failures on |
| 91 * this test or not. |
| 92 * |
| 93 * This is just an ImageDigest (or lack thereof, if there is no expectation)
and a boolean |
| 94 * telling us whether to ignore failures. |
| 95 */ |
| 96 class Expectation { |
| 97 public: |
| 98 /** |
| 99 * No expectation at all. |
| 100 */ |
| 101 explicit Expectation(bool ignoreFailure=kDefaultIgnoreFailure); |
| 102 |
| 103 /** |
| 104 * Expect an image, passed as hashType/hashValue. |
| 105 */ |
| 106 explicit Expectation(const SkString &hashType, uint64_t hashValue, |
| 107 bool ignoreFailure=kDefaultIgnoreFailure); |
| 108 |
| 109 /** |
| 110 * Expect an image, passed as a bitmap. |
| 111 */ |
| 112 explicit Expectation(const SkBitmap& bitmap, |
| 113 bool ignoreFailure=kDefaultIgnoreFailure); |
| 114 |
| 115 /** |
| 116 * Returns true iff we want to ignore failed expectations. |
| 117 */ |
| 118 bool ignoreFailure() const; |
| 119 |
| 120 /** |
| 121 * Returns true iff there are no allowed results. |
| 122 */ |
| 123 bool empty() const; |
| 124 |
| 125 /** |
| 126 * Returns true iff we are expecting a particular image, and imageDigest
matches it. |
| 127 * |
| 128 * If empty() returns true, this will return false. |
| 129 * |
| 130 * If this expectation DOES contain an image, and imageDigest doesn't ma
tch it, |
| 131 * this method will return false regardless of what ignoreFailure() woul
d return. |
| 132 * (The caller can check that separately.) |
| 133 */ |
| 134 bool matches(ImageDigest &imageDigest); |
| 135 |
| 136 private: |
| 137 static const bool kDefaultIgnoreFailure = false; |
| 138 |
| 139 const bool fIsEmpty; |
| 140 const bool fIgnoreFailure; |
| 141 ImageDigest fImageDigest; // cannot be const, because it computes its h
ash lazily |
| 142 }; |
| 143 |
| 144 /** |
79 * Collects ImageDigests of actually rendered images, perhaps comparing to e
xpectations. | 145 * Collects ImageDigests of actually rendered images, perhaps comparing to e
xpectations. |
80 */ | 146 */ |
81 class ImageResultsAndExpectations { | 147 class ImageResultsAndExpectations { |
82 public: | 148 public: |
83 /** | 149 /** |
84 * Adds expectations from a JSON file, returning true if successful. | 150 * Adds expectations from a JSON file, returning true if successful. |
85 * | 151 * |
86 * If the file exists but is empty, it succeeds, and there will be no ex
pectations. | 152 * If the file exists but is empty, it succeeds, and there will be no ex
pectations. |
87 * If the file does not exist, this will fail. | 153 * If the file does not exist, this will fail. |
88 * | 154 * |
(...skipping 11 matching lines...) Expand all Loading... |
100 bool readExpectationsFile(const char *jsonPath); | 166 bool readExpectationsFile(const char *jsonPath); |
101 | 167 |
102 /** | 168 /** |
103 * Adds this image to the summary of results. | 169 * Adds this image to the summary of results. |
104 * | 170 * |
105 * @param sourceName name of the source file that generated this result | 171 * @param sourceName name of the source file that generated this result |
106 * @param fileName relative path to the image output file on local disk | 172 * @param fileName relative path to the image output file on local disk |
107 * @param digest description of the image's contents | 173 * @param digest description of the image's contents |
108 * @param tileNumber if not NULL, pointer to tile number | 174 * @param tileNumber if not NULL, pointer to tile number |
109 */ | 175 */ |
110 void add(const char *sourceName, const char *fileName, const ImageDigest
&digest, | 176 void add(const char *sourceName, const char *fileName, ImageDigest &dige
st, |
111 const int *tileNumber=NULL); | 177 const int *tileNumber=NULL); |
112 | 178 |
113 /** | 179 /** |
114 * Adds a key/value pair to the descriptions dict within the summary of
results. | 180 * Adds a key/value pair to the descriptions dict within the summary of
results. |
115 * | 181 * |
116 * @param key key within the descriptions dict | 182 * @param key key within the descriptions dict |
117 * @param value value to associate with that key | 183 * @param value value to associate with that key |
118 */ | 184 */ |
119 void addDescription(const char *key, const char *value); | 185 void addDescription(const char *key, const char *value); |
120 | 186 |
121 /** | 187 /** |
122 * Returns true if this test result matches its expectations. | 188 * Returns the Expectation for this test. |
123 * If there are no expectations for this test result, this will return f
alse. | |
124 * | 189 * |
125 * @param sourceName name of the source file that generated this result | 190 * @param sourceName name of the source file that generated this result |
126 * @param digest description of the image's contents | |
127 * @param tileNumber if not NULL, pointer to tile number | 191 * @param tileNumber if not NULL, pointer to tile number |
| 192 * |
| 193 * TODO(stephana): To make this work for GMs, we will need to add parame
ters for |
| 194 * config, and maybe renderMode/builder? |
128 */ | 195 */ |
129 bool matchesExpectation(const char *sourceName, const ImageDigest &diges
t, | 196 Expectation getExpectation(const char *sourceName, const int *tileNumber
=NULL); |
130 const int *tileNumber=NULL); | |
131 | 197 |
132 /** | 198 /** |
133 * Writes the summary (as constructed so far) to a file. | 199 * Writes the summary (as constructed so far) to a file. |
134 * | 200 * |
135 * @param filename path to write the summary to | 201 * @param filename path to write the summary to |
136 */ | 202 */ |
137 void writeToFile(const char *filename) const; | 203 void writeToFile(const char *filename) const; |
138 | 204 |
139 private: | 205 private: |
140 | 206 |
141 /** | 207 /** |
142 * Read the file contents from filePtr and parse them into jsonRoot. | 208 * Read the file contents from filePtr and parse them into jsonRoot. |
143 * | 209 * |
144 * It is up to the caller to close filePtr after this is done. | 210 * It is up to the caller to close filePtr after this is done. |
145 * | 211 * |
146 * Returns true if successful. | 212 * Returns true if successful. |
147 */ | 213 */ |
148 static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot); | 214 static bool Parse(SkFILE* filePtr, Json::Value *jsonRoot); |
149 | 215 |
150 Json::Value fActualResults; | 216 Json::Value fActualResults; |
151 Json::Value fDescriptions; | 217 Json::Value fDescriptions; |
152 Json::Value fExpectedJsonRoot; | 218 Json::Value fExpectedJsonRoot; |
153 Json::Value fExpectedResults; | 219 Json::Value fExpectedResults; |
154 }; | 220 }; |
155 | 221 |
156 } // namespace sk_tools | 222 } // namespace sk_tools |
157 | 223 |
158 #endif // image_expectations_DEFINED | 224 #endif // image_expectations_DEFINED |
OLD | NEW |