OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #if SK_SUPPORT_GPU | 9 #if SK_SUPPORT_GPU |
10 | 10 |
11 #include "GrContext.h" | 11 #include "GrContext.h" |
12 #include "GrContextFactory.h" | 12 #include "GrContextFactory.h" |
13 #include "SkBitmap.h" | 13 #include "SkBitmap.h" |
14 #include "SkCanvas.h" | 14 #include "SkCanvas.h" |
15 #include "SkColor.h" | 15 #include "SkColor.h" |
16 #include "SkGpuDevice.h" | 16 #include "SkGpuDevice.h" |
17 #include "SkPaint.h" | 17 #include "SkPaint.h" |
18 #include "SkPixelRef.h" | 18 #include "SkPixelRef.h" |
19 #include "SkRect.h" | 19 #include "SkRect.h" |
20 #include "Test.h" | 20 #include "Test.h" |
21 | 21 |
22 static const char* boolStr(bool value) { | 22 static const char* boolStr(bool value) { |
23 return value ? "true" : "false"; | 23 return value ? "true" : "false"; |
24 } | 24 } |
25 | 25 |
26 // these are in the same order as the SkBitmap::Config enum | 26 // these are in the same order as the SkBitmap::Config enum |
27 static const char* gConfigName[] = { | 27 static const char* gColorTypeName[] = { |
28 "None", "8888" | 28 "None", "8888" |
29 }; | 29 }; |
30 | 30 |
31 struct Pair { | 31 struct Pair { |
32 SkBitmap::Config fConfig; | 32 SkColorType fColorType; |
33 const char* fValid; | 33 const char* fValid; |
34 }; | 34 }; |
35 | 35 |
36 /** | 36 /** |
37 * Check to ensure that copying a GPU-backed SkBitmap behaved as expected. | 37 * Check to ensure that copying a GPU-backed SkBitmap behaved as expected. |
38 * @param reporter Used to report failures. | 38 * @param reporter Used to report failures. |
39 * @param desiredConfig Config being copied to. If the copy succeeded, dst must
have this Config. | 39 * @param desiredCT colorType being copied to. If the copy succeeded, dst must
have this Config. |
40 * @param success True if the copy succeeded. | 40 * @param success True if the copy succeeded. |
41 * @param src A GPU-backed SkBitmap that had copyTo or deepCopyTo called on it. | 41 * @param src A GPU-backed SkBitmap that had copyTo or deepCopyTo called on it. |
42 * @param dst SkBitmap that was copied to. | 42 * @param dst SkBitmap that was copied to. |
43 * @param expectSameGenID Whether the genIDs should be the same if success is t
rue. | 43 * @param expectSameGenID Whether the genIDs should be the same if success is t
rue. |
44 */ | 44 */ |
45 static void TestIndividualCopy(skiatest::Reporter* reporter, const SkBitmap::Con
fig desiredConfig, | 45 static void TestIndividualCopy(skiatest::Reporter* reporter, const SkColorType d
esiredCT, |
46 const bool success, const SkBitmap& src, const Sk
Bitmap& dst, | 46 const bool success, const SkBitmap& src, const Sk
Bitmap& dst, |
47 const bool expectSameGenID) { | 47 const bool expectSameGenID) { |
48 if (success) { | 48 if (success) { |
49 REPORTER_ASSERT(reporter, src.width() == dst.width()); | 49 REPORTER_ASSERT(reporter, src.width() == dst.width()); |
50 REPORTER_ASSERT(reporter, src.height() == dst.height()); | 50 REPORTER_ASSERT(reporter, src.height() == dst.height()); |
51 REPORTER_ASSERT(reporter, dst.config() == desiredConfig); | 51 REPORTER_ASSERT(reporter, dst.colorType() == desiredCT); |
52 if (src.config() == dst.config()) { | 52 if (src.config() == dst.config()) { |
53 if (expectSameGenID) { | 53 if (expectSameGenID) { |
54 REPORTER_ASSERT(reporter, src.getGenerationID() == dst.getGenera
tionID()); | 54 REPORTER_ASSERT(reporter, src.getGenerationID() == dst.getGenera
tionID()); |
55 } else { | 55 } else { |
56 REPORTER_ASSERT(reporter, src.getGenerationID() != dst.getGenera
tionID()); | 56 REPORTER_ASSERT(reporter, src.getGenerationID() != dst.getGenera
tionID()); |
57 } | 57 } |
58 REPORTER_ASSERT(reporter, src.pixelRef() != NULL && dst.pixelRef() !
= NULL); | 58 REPORTER_ASSERT(reporter, src.pixelRef() != NULL && dst.pixelRef() !
= NULL); |
59 | 59 |
60 // Do read backs and make sure that the two are the same. | 60 // Do read backs and make sure that the two are the same. |
61 SkBitmap srcReadBack, dstReadBack; | 61 SkBitmap srcReadBack, dstReadBack; |
62 { | 62 { |
63 SkASSERT(src.getTexture() != NULL); | 63 SkASSERT(src.getTexture() != NULL); |
64 const SkIPoint origin = src.pixelRefOrigin(); | 64 const SkIPoint origin = src.pixelRefOrigin(); |
65 const SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, | 65 const SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, |
66 src.width(), src.height
()); | 66 src.width(), src.height
()); |
67 bool readBack = src.pixelRef()->readPixels(&srcReadBack, &subset
); | 67 bool readBack = src.pixelRef()->readPixels(&srcReadBack, &subset
); |
68 REPORTER_ASSERT(reporter, readBack); | 68 REPORTER_ASSERT(reporter, readBack); |
69 } | 69 } |
70 if (dst.getTexture() != NULL) { | 70 if (dst.getTexture() != NULL) { |
71 const SkIPoint origin = dst.pixelRefOrigin(); | 71 const SkIPoint origin = dst.pixelRefOrigin(); |
72 const SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, | 72 const SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, |
73 dst.width(), dst.height
()); | 73 dst.width(), dst.height
()); |
74 bool readBack = dst.pixelRef()->readPixels(&dstReadBack, &subset
); | 74 bool readBack = dst.pixelRef()->readPixels(&dstReadBack, &subset
); |
75 REPORTER_ASSERT(reporter, readBack); | 75 REPORTER_ASSERT(reporter, readBack); |
76 } else { | 76 } else { |
77 // If dst is not a texture, do a copy instead, to the same confi
g as srcReadBack. | 77 // If dst is not a texture, do a copy instead, to the same confi
g as srcReadBack. |
78 bool copy = dst.copyTo(&dstReadBack, srcReadBack.config()); | 78 bool copy = dst.copyTo(&dstReadBack, srcReadBack.colorType()); |
79 REPORTER_ASSERT(reporter, copy); | 79 REPORTER_ASSERT(reporter, copy); |
80 } | 80 } |
81 | 81 |
82 SkAutoLockPixels srcLock(srcReadBack); | 82 SkAutoLockPixels srcLock(srcReadBack); |
83 SkAutoLockPixels dstLock(dstReadBack); | 83 SkAutoLockPixels dstLock(dstReadBack); |
84 REPORTER_ASSERT(reporter, srcReadBack.readyToDraw() && dstReadBack.r
eadyToDraw()); | 84 REPORTER_ASSERT(reporter, srcReadBack.readyToDraw() && dstReadBack.r
eadyToDraw()); |
85 | 85 |
86 const char* srcP = static_cast<const char*>(srcReadBack.getAddr(0, 0
)); | 86 const char* srcP = static_cast<const char*>(srcReadBack.getAddr(0, 0
)); |
87 const char* dstP = static_cast<const char*>(dstReadBack.getAddr(0, 0
)); | 87 const char* dstP = static_cast<const char*>(dstReadBack.getAddr(0, 0
)); |
88 REPORTER_ASSERT(reporter, srcP != dstP); | 88 REPORTER_ASSERT(reporter, srcP != dstP); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 // (or kUnknown_SkColorType in the new world), hence much of this | 126 // (or kUnknown_SkColorType in the new world), hence much of this |
127 // test will be skipped, since it was checking that calling | 127 // test will be skipped, since it was checking that calling |
128 // copyTo or deepCopyTo with src or dst set to kUnknown/kNo would | 128 // copyTo or deepCopyTo with src or dst set to kUnknown/kNo would |
129 // successfully fail. | 129 // successfully fail. |
130 // | 130 // |
131 // If we can declare that you can *never* create a texture with | 131 // If we can declare that you can *never* create a texture with |
132 // kUnknown, then perhaps we can remove this entire test... | 132 // kUnknown, then perhaps we can remove this entire test... |
133 // | 133 // |
134 // { SkBitmap::kNo_Config, "00" }, | 134 // { SkBitmap::kNo_Config, "00" }, |
135 // { SkBitmap::kARGB_8888_Config, "01" }, | 135 // { SkBitmap::kARGB_8888_Config, "01" }, |
136 { SkBitmap::kARGB_8888_Config, "1" }, | 136 { kPMColor_SkColorType, "1" }, |
137 }; | 137 }; |
138 | 138 |
139 const int W = 20; | 139 const int W = 20; |
140 const int H = 33; | 140 const int H = 33; |
141 | 141 |
142 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { | 142 for (size_t i = 0; i < SK_ARRAY_COUNT(gPairs); i++) { |
143 SkImageInfo info = SkImageInfo::Make(W, H, | 143 SkImageInfo info = SkImageInfo::Make(W, H, |
144 SkBitmapConfigToColorType(gPair
s[i].fConfig), | 144 gPairs[i].fColorType, |
145 kPremul_SkAlphaType); | 145 kPremul_SkAlphaType); |
146 SkBitmap src, dst; | 146 SkBitmap src, dst; |
147 | 147 |
148 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(grContext, info
, 0)); | 148 SkAutoTUnref<SkGpuDevice> device(SkGpuDevice::Create(grContext, info
, 0)); |
149 SkASSERT(device.get()); | 149 SkASSERT(device.get()); |
150 | 150 |
151 src = device->accessBitmap(false); | 151 src = device->accessBitmap(false); |
152 device->clear(SK_ColorWHITE); | 152 device->clear(SK_ColorWHITE); |
153 | 153 |
154 // Draw something different to the same portion of the bitmap that w
e will extract as a | 154 // Draw something different to the same portion of the bitmap that w
e will extract as a |
155 // subset, so that comparing the pixels of the subset will be meanin
gful. | 155 // subset, so that comparing the pixels of the subset will be meanin
gful. |
156 SkIRect subsetRect = SkIRect::MakeLTRB(W/2, H/2, W, H); | 156 SkIRect subsetRect = SkIRect::MakeLTRB(W/2, H/2, W, H); |
157 SkCanvas drawingCanvas(device); | 157 SkCanvas drawingCanvas(device); |
158 SkPaint paint; | 158 SkPaint paint; |
159 paint.setColor(SK_ColorRED); | 159 paint.setColor(SK_ColorRED); |
160 drawingCanvas.drawRect(SkRect::Make(subsetRect), paint); | 160 drawingCanvas.drawRect(SkRect::Make(subsetRect), paint); |
161 | 161 |
162 // Extract a subset. If this succeeds we will test copying the subse
t. | 162 // Extract a subset. If this succeeds we will test copying the subse
t. |
163 SkBitmap subset; | 163 SkBitmap subset; |
164 #ifdef SK_SUPPORT_DEEPCOPYTO_CONFIG | 164 #ifdef SK_SUPPORT_DEEPCOPYTO_CONFIG |
165 const bool extracted = src.extractSubset(&subset, subsetRect); | 165 const bool extracted = src.extractSubset(&subset, subsetRect); |
166 | 166 |
167 for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) { | 167 for (size_t j = 0; j < SK_ARRAY_COUNT(gPairs); j++) { |
| 168 SkBitmap::Config pairsConfig = SkColorTypeToBitmapConfig(gPairs[
j].fColorType); |
168 dst.reset(); | 169 dst.reset(); |
169 bool success = src.deepCopyTo(&dst, gPairs[j].fConfig); | 170 bool success = src.deepCopyTo(&dst, pairsConfig); |
170 bool expected = gPairs[i].fValid[j] != '0'; | 171 bool expected = gPairs[i].fValid[j] != '0'; |
171 if (success != expected) { | 172 if (success != expected) { |
172 ERRORF(reporter, "SkBitmap::deepCopyTo from %s to %s. " | 173 ERRORF(reporter, "SkBitmap::deepCopyTo from %s to %s. " |
173 "expected %s returned %s", gConfigName[i], | 174 "expected %s returned %s", gColorTypeName[i], |
174 gConfigName[j], boolStr(expected), | 175 gColorTypeName[j], boolStr(expected), |
175 boolStr(success)); | 176 boolStr(success)); |
176 } | 177 } |
177 | 178 |
178 bool canSucceed = src.canCopyTo(gPairs[j].fConfig); | 179 bool canSucceed = src.canCopyTo(gPairs[j].fColorType); |
179 if (success != canSucceed) { | 180 if (success != canSucceed) { |
180 ERRORF(reporter, "SkBitmap::deepCopyTo from %s to %s " | 181 ERRORF(reporter, "SkBitmap::deepCopyTo from %s to %s " |
181 "returned %s, but canCopyTo returned %s", | 182 "returned %s, but canCopyTo returned %s", |
182 gConfigName[i], gConfigName[j], boolStr(success), | 183 gColorTypeName[i], gColorTypeName[j], boolStr(success
), |
183 boolStr(canSucceed)); | 184 boolStr(canSucceed)); |
184 } | 185 } |
185 | 186 |
186 TestIndividualCopy(reporter, gPairs[j].fConfig, success, src, ds
t, true); | 187 TestIndividualCopy(reporter, gPairs[j].fColorType, success, src,
dst, true); |
187 | 188 |
188 // Test copying the subset bitmap, using both copyTo and deepCop
yTo. | 189 // Test copying the subset bitmap, using both copyTo and deepCop
yTo. |
189 if (extracted) { | 190 if (extracted) { |
190 SkBitmap subsetCopy; | 191 SkBitmap subsetCopy; |
191 success = subset.copyTo(&subsetCopy, gPairs[j].fConfig); | 192 success = subset.copyTo(&subsetCopy, gPairs[j].fColorType); |
192 REPORTER_ASSERT(reporter, success == expected); | 193 REPORTER_ASSERT(reporter, success == expected); |
193 REPORTER_ASSERT(reporter, success == canSucceed); | 194 REPORTER_ASSERT(reporter, success == canSucceed); |
194 TestIndividualCopy(reporter, gPairs[j].fConfig, success, sub
set, subsetCopy, | 195 TestIndividualCopy(reporter, gPairs[j].fColorType, success,
subset, subsetCopy, |
195 true); | 196 true); |
196 | 197 |
197 // Reset the bitmap so that a failed copyTo will leave it in
the expected state. | 198 // Reset the bitmap so that a failed copyTo will leave it in
the expected state. |
198 subsetCopy.reset(); | 199 subsetCopy.reset(); |
199 success = subset.deepCopyTo(&subsetCopy, gPairs[j].fConfig); | 200 success = subset.deepCopyTo(&subsetCopy, pairsConfig); |
200 REPORTER_ASSERT(reporter, success == expected); | 201 REPORTER_ASSERT(reporter, success == expected); |
201 REPORTER_ASSERT(reporter, success == canSucceed); | 202 REPORTER_ASSERT(reporter, success == canSucceed); |
202 TestIndividualCopy(reporter, gPairs[j].fConfig, success, sub
set, subsetCopy, | 203 TestIndividualCopy(reporter, gPairs[j].fColorType, success,
subset, subsetCopy, |
203 true); | 204 true); |
204 | 205 |
205 // Now set a bitmap to be a subset that will share the same
pixelref. | 206 // Now set a bitmap to be a subset that will share the same
pixelref. |
206 // This allows testing another case of cloning the genID. Wh
en calling copyTo | 207 // This allows testing another case of cloning the genID. Wh
en calling copyTo |
207 // on a bitmap representing a subset of its pixelref, the re
sulting pixelref | 208 // on a bitmap representing a subset of its pixelref, the re
sulting pixelref |
208 // should not share the genID, since we only copied the subs
et. | 209 // should not share the genID, since we only copied the subs
et. |
209 SkBitmap trueSubset; | 210 SkBitmap trueSubset; |
210 // FIXME: Once https://codereview.chromium.org/109023008/ la
nds, call | 211 // FIXME: Once https://codereview.chromium.org/109023008/ la
nds, call |
211 // trueSubset.installPixelRef(src.pixelRef(), subset); | 212 // trueSubset.installPixelRef(src.pixelRef(), subset); |
212 trueSubset.setConfig(gPairs[i].fConfig, W/2, H/2); | 213 trueSubset.setConfig(SkImageInfo::Make(W/2, H/2, gPairs[i].f
ColorType, |
| 214 kPremul_SkAlphaType))
; |
213 trueSubset.setPixelRef(src.pixelRef(), W/2, H/2); | 215 trueSubset.setPixelRef(src.pixelRef(), W/2, H/2); |
214 | 216 |
215 subsetCopy.reset(); | 217 subsetCopy.reset(); |
216 success = trueSubset.copyTo(&subsetCopy, gPairs[j].fConfig); | 218 success = trueSubset.copyTo(&subsetCopy, gPairs[j].fColorTyp
e); |
217 REPORTER_ASSERT(reporter, success == expected); | 219 REPORTER_ASSERT(reporter, success == expected); |
218 REPORTER_ASSERT(reporter, success == canSucceed); | 220 REPORTER_ASSERT(reporter, success == canSucceed); |
219 TestIndividualCopy(reporter, gPairs[j].fConfig, success, tru
eSubset, subsetCopy, | 221 TestIndividualCopy(reporter, gPairs[j].fColorType, success,
trueSubset, subsetCopy, |
220 false); | 222 false); |
221 | 223 |
222 // deepCopyTo copies the entire pixelref, even if the bitmap
only represents | 224 // deepCopyTo copies the entire pixelref, even if the bitmap
only represents |
223 // a subset. Therefore, the result should share the same gen
ID. | 225 // a subset. Therefore, the result should share the same gen
ID. |
224 subsetCopy.reset(); | 226 subsetCopy.reset(); |
225 success = trueSubset.deepCopyTo(&subsetCopy, gPairs[j].fConf
ig); | 227 success = trueSubset.deepCopyTo(&subsetCopy, pairsConfig); |
226 REPORTER_ASSERT(reporter, success == expected); | 228 REPORTER_ASSERT(reporter, success == expected); |
227 REPORTER_ASSERT(reporter, success == canSucceed); | 229 REPORTER_ASSERT(reporter, success == canSucceed); |
228 TestIndividualCopy(reporter, gPairs[j].fConfig, success, tru
eSubset, subsetCopy, | 230 TestIndividualCopy(reporter, gPairs[j].fColorType, success,
trueSubset, subsetCopy, |
229 true); | 231 true); |
230 } | 232 } |
231 } // for (size_t j = ... | 233 } // for (size_t j = ... |
232 #endif | 234 #endif |
233 } // for (size_t i = ... | 235 } // for (size_t i = ... |
234 } // GrContextFactory::GLContextType | 236 } // GrContextFactory::GLContextType |
235 } | 237 } |
236 | 238 |
237 #endif | 239 #endif |
OLD | NEW |