OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 #include "DMSrcSink.h" | 8 #include "DMSrcSink.h" |
9 #include "SamplePipeControllers.h" | 9 #include "SamplePipeControllers.h" |
10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 return gm->getName(); | 57 return gm->getName(); |
58 } | 58 } |
59 | 59 |
60 void GMSrc::modifyGrContextOptions(GrContextOptions* options) const { | 60 void GMSrc::modifyGrContextOptions(GrContextOptions* options) const { |
61 SkAutoTDelete<skiagm::GM> gm(fFactory(NULL)); | 61 SkAutoTDelete<skiagm::GM> gm(fFactory(NULL)); |
62 gm->modifyGrContextOptions(options); | 62 gm->modifyGrContextOptions(options); |
63 } | 63 } |
64 | 64 |
65 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 65 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
66 | 66 |
67 CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType) | 67 CodecSrc::CodecSrc(Path path, Mode mode, DstColorType dstColorType, float scale) |
68 : fPath(path) | 68 : fPath(path) |
69 , fMode(mode) | 69 , fMode(mode) |
70 , fDstColorType(dstColorType) | 70 , fDstColorType(dstColorType) |
71 , fScale(scale) | |
71 {} | 72 {} |
72 | 73 |
73 Error CodecSrc::draw(SkCanvas* canvas) const { | 74 Error CodecSrc::draw(SkCanvas* canvas) const { |
74 SkImageInfo canvasInfo; | 75 SkImageInfo canvasInfo; |
75 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { | 76 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { |
76 // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a de ferred decode to | 77 // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a de ferred decode to |
77 // let the GPU handle it. | 78 // let the GPU handle it. |
78 return Error::Nonfatal("No need to test decoding to non-raster backend." ); | 79 return Error::Nonfatal("No need to test decoding to non-raster backend." ); |
79 } | 80 } |
80 | 81 |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
188 const int extraY = h % divisor; | 189 const int extraY = h % divisor; |
189 /* | 190 /* |
190 * if w or h are not evenly divided by divisor need to adjust width a nd height of end | 191 * if w or h are not evenly divided by divisor need to adjust width a nd height of end |
191 * subsets to cover entire image. | 192 * subsets to cover entire image. |
192 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width | 193 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width |
193 * and height of end subsets. | 194 * and height of end subsets. |
194 * subsetBm is extracted from largestSubsetBm. | 195 * subsetBm is extracted from largestSubsetBm. |
195 * subsetBm's size is determined based on the current subset and may be larger for end | 196 * subsetBm's size is determined based on the current subset and may be larger for end |
196 * subsets. | 197 * subsets. |
197 */ | 198 */ |
198 SkImageInfo largestSubsetDecodeInfo = | 199 SkImageInfo largestSubsetDecodeInfo = |
199 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); | 200 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); |
200 SkBitmap largestSubsetBm; | 201 SkBitmap largestSubsetBm; |
201 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { | 202 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { |
202 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), | 203 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), |
203 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); | 204 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); |
204 } | 205 } |
205 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); | 206 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); |
206 SkAutoTDeleteArray<char> lineDeleter(line); | 207 SkAutoTDeleteArray<char> lineDeleter(line); |
207 for (int col = 0; col < divisor; col++) { | 208 for (int col = 0; col < divisor; col++) { |
208 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets | 209 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets |
(...skipping 10 matching lines...) Expand all Loading... | |
219 NULL, colorPtr, colorCountPtr); | 220 NULL, colorPtr, colorCountPtr); |
220 if (NULL == subsetScanlineDecoder) { | 221 if (NULL == subsetScanlineDecoder) { |
221 if (x == 0 && y == 0) { | 222 if (x == 0 && y == 0) { |
222 //first try, image may not be compatible | 223 //first try, image may not be compatible |
223 return Error::Nonfatal("Cannot use scanline decoder for all images"); | 224 return Error::Nonfatal("Cannot use scanline decoder for all images"); |
224 } else { | 225 } else { |
225 return "Error scanline decoder is NULL"; | 226 return "Error scanline decoder is NULL"; |
226 } | 227 } |
227 } | 228 } |
228 //skip to first line of subset | 229 //skip to first line of subset |
229 const SkImageGenerator::Result skipResult = | 230 const SkImageGenerator::Result skipResult = |
230 subsetScanlineDecoder->skipScanlines(y); | 231 subsetScanlineDecoder->skipScanlines(y); |
231 switch (skipResult) { | 232 switch (skipResult) { |
232 case SkImageGenerator::kSuccess: | 233 case SkImageGenerator::kSuccess: |
233 case SkImageGenerator::kIncompleteInput: | 234 case SkImageGenerator::kIncompleteInput: |
234 break; | 235 break; |
235 default: | 236 default: |
236 return SkStringPrintf("%s failed after attempting to skip %d scanlines" | 237 return SkStringPrintf("%s failed after attempting to skip %d scanlines" |
237 "with error message %d", fPath.c_str(), y, ( int) skipResult); | 238 "with error message %d", fPath.c_str(), y, ( int) skipResult); |
238 } | 239 } |
239 //create and set size of subsetBm | 240 //create and set size of subsetBm |
(...skipping 15 matching lines...) Expand all Loading... | |
255 default: | 256 default: |
256 return SkStringPrintf("%s failed after %d scanli nes with error" | 257 return SkStringPrintf("%s failed after %d scanli nes with error" |
257 "message %d", fPath.c_str(), y-1, (int) subsetResult); | 258 "message %d", fPath.c_str(), y-1, (int) subsetResult); |
258 } | 259 } |
259 } | 260 } |
260 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); | 261 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); |
261 } | 262 } |
262 } | 263 } |
263 break; | 264 break; |
264 } | 265 } |
266 // This mode tests scaling and skipping. The decode is performed for th e scaled image | |
267 // dimensions using stripes. | |
scroggo
2015/06/11 15:50:02
It is curious to me that we combine scaling with s
msarett
2015/06/11 19:29:36
Yes this was an odd decision that didn't make much
| |
268 case kScale_Mode: { | |
269 SkISize size = codec->getScaledDimensions(fScale); | |
270 SkImageInfo info = decodeInfo.makeWH(size.width(), size.height()); | |
271 int width = info.width(); | |
272 int height = info.height(); | |
273 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that | |
274 // does not align with image blocks. | |
275 const int stripeHeight = 37; | |
276 const int numStripes = (height + stripeHeight - 1) / stripeHeight; | |
277 | |
278 // Create bitmap | |
279 SkBitmap bitmap; | |
280 if (!bitmap.tryAllocPixels(info, NULL, colorTable.get())) { | |
281 return SkStringPrintf("Cannot allocate pixels for %s %dx%d", fPa th.c_str(), | |
282 width, height); | |
283 } | |
284 | |
285 // Decode odd stripes | |
286 SkScanlineDecoder* decoder = codec->getScanlineDecoder(info, NULL, c olorPtr, | |
287 colorCountPtr); | |
288 if (NULL == decoder) { | |
289 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); | |
290 } | |
291 for (int i = 0; i < numStripes; i += 2) { | |
292 // Skip a stripe | |
293 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); | |
294 decoder->skipScanlines(linesToSkip); | |
295 | |
296 // Read a stripe | |
297 const int startY = SkTMin((i + 1) * stripeHeight, height - 1); | |
298 const int linesToRead = SkTMax(0, SkTMin(stripeHeight, height - startY)); | |
299 decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bi tmap.rowBytes()); | |
300 } | |
301 | |
302 // Decode even stripes | |
303 decoder = codec->getScanlineDecoder(info, NULL, colorPtr, colorCount Ptr); | |
304 for (int i = 0; i < numStripes; i += 2) { | |
305 // Read a stripe | |
306 const int startY = i * stripeHeight; | |
307 const int linesToRead = SkTMin(stripeHeight, height - startY); | |
308 decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bi tmap.rowBytes()); | |
309 | |
310 // Skip a stripe | |
311 const int linesToSkip = SkTMax(0, SkTMin(stripeHeight, | |
312 height - (i + 1) * stripeHeight)); | |
313 decoder->skipScanlines(linesToSkip); | |
314 } | |
315 canvas->drawBitmap(bitmap, 0, 0); | |
316 } | |
265 } | 317 } |
266 return ""; | 318 return ""; |
267 } | 319 } |
268 | 320 |
269 SkISize CodecSrc::size() const { | 321 SkISize CodecSrc::size() const { |
270 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 322 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
271 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 323 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
272 if (NULL != codec) { | 324 if (NULL != codec) { |
273 return codec->getInfo().dimensions(); | 325 SkISize size = codec->getScaledDimensions(fScale); |
scroggo
2015/06/11 15:50:02
For png (for example) this will return the origina
msarett
2015/06/11 19:29:36
We are now returning Error::Nonfatal for tests whe
| |
326 return size; | |
274 } else { | 327 } else { |
275 return SkISize::Make(0, 0); | 328 return SkISize::Make(0, 0); |
276 } | 329 } |
277 } | 330 } |
278 | 331 |
279 Name CodecSrc::name() const { | 332 Name CodecSrc::name() const { |
280 return SkOSPath::Basename(fPath.c_str()); | 333 if (1.0f == fScale) { |
334 return SkOSPath::Basename(fPath.c_str()); | |
335 } else { | |
336 return SkStringPrintf("%s_%.3f", SkOSPath::Basename(fPath.c_str()).c_str (), fScale); | |
337 } | |
281 } | 338 } |
282 | 339 |
283 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 340 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
284 | 341 |
285 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} | 342 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} |
286 | 343 |
287 Error ImageSrc::draw(SkCanvas* canvas) const { | 344 Error ImageSrc::draw(SkCanvas* canvas) const { |
288 SkImageInfo canvasInfo; | 345 SkImageInfo canvasInfo; |
289 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { | 346 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { |
290 // TODO: Instead, use lazy decoding to allow the GPU to handle cases lik e YUV. | 347 // TODO: Instead, use lazy decoding to allow the GPU to handle cases lik e YUV. |
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
882 skr.visit<void>(i, drawsAsSingletonPictures); | 939 skr.visit<void>(i, drawsAsSingletonPictures); |
883 } | 940 } |
884 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 941 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
885 | 942 |
886 canvas->drawPicture(macroPic); | 943 canvas->drawPicture(macroPic); |
887 return ""; | 944 return ""; |
888 }); | 945 }); |
889 } | 946 } |
890 | 947 |
891 } // namespace DM | 948 } // namespace DM |
OLD | NEW |