Chromium Code Reviews| 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 20 matching lines...) Expand all Loading... | |
| 101 decodeInfo = codec->getInfo().makeColorType(kGray_8_SkColorType); | 102 decodeInfo = codec->getInfo().makeColorType(kGray_8_SkColorType); |
| 102 if (kRGB_565_SkColorType == canvasColorType) { | 103 if (kRGB_565_SkColorType == canvasColorType) { |
| 103 return Error::Nonfatal("Testing non-565 to 565 is uninteresting. "); | 104 return Error::Nonfatal("Testing non-565 to 565 is uninteresting. "); |
| 104 } | 105 } |
| 105 break; | 106 break; |
| 106 default: | 107 default: |
| 107 decodeInfo = decodeInfo.makeColorType(canvasColorType); | 108 decodeInfo = decodeInfo.makeColorType(canvasColorType); |
| 108 break; | 109 break; |
| 109 } | 110 } |
| 110 | 111 |
| 112 // Try to scale the image if it is desired | |
| 113 SkISize size = codec->getScaledDimensions(fScale); | |
| 114 if (size == decodeInfo.dimensions() && 1.0f != fScale) { | |
| 115 return Error::Nonfatal("Test without scaling is uninteresting."); | |
| 116 } | |
| 117 decodeInfo = decodeInfo.makeWH(size.width(), size.height()); | |
| 118 | |
| 111 // Construct a color table for the decode if necessary | 119 // Construct a color table for the decode if necessary |
| 112 SkAutoTUnref<SkColorTable> colorTable(NULL); | 120 SkAutoTUnref<SkColorTable> colorTable(NULL); |
| 113 SkPMColor* colorPtr = NULL; | 121 SkPMColor* colorPtr = NULL; |
| 114 int* colorCountPtr = NULL; | 122 int* colorCountPtr = NULL; |
| 115 int maxColors = 256; | 123 int maxColors = 256; |
| 116 if (kIndex_8_SkColorType == decodeInfo.colorType()) { | 124 if (kIndex_8_SkColorType == decodeInfo.colorType()) { |
| 117 SkPMColor colors[256]; | 125 SkPMColor colors[256]; |
| 118 colorTable.reset(SkNEW_ARGS(SkColorTable, (colors, maxColors))); | 126 colorTable.reset(SkNEW_ARGS(SkColorTable, (colors, maxColors))); |
| 119 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); | 127 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); |
| 120 colorCountPtr = &maxColors; | 128 colorCountPtr = &maxColors; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 const int extraY = h % divisor; | 196 const int extraY = h % divisor; |
| 189 /* | 197 /* |
| 190 * if w or h are not evenly divided by divisor need to adjust width a nd height of end | 198 * 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. | 199 * subsets to cover entire image. |
| 192 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width | 200 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width |
| 193 * and height of end subsets. | 201 * and height of end subsets. |
| 194 * subsetBm is extracted from largestSubsetBm. | 202 * subsetBm is extracted from largestSubsetBm. |
| 195 * subsetBm's size is determined based on the current subset and may be larger for end | 203 * subsetBm's size is determined based on the current subset and may be larger for end |
| 196 * subsets. | 204 * subsets. |
| 197 */ | 205 */ |
| 198 SkImageInfo largestSubsetDecodeInfo = | 206 SkImageInfo largestSubsetDecodeInfo = |
| 199 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); | 207 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); |
| 200 SkBitmap largestSubsetBm; | 208 SkBitmap largestSubsetBm; |
| 201 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { | 209 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, NULL, c olorTable.get())) { |
| 202 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), | 210 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), |
| 203 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); | 211 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); |
| 204 } | 212 } |
| 205 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); | 213 char* line = SkNEW_ARRAY(char, decodeInfo.minRowBytes()); |
| 206 SkAutoTDeleteArray<char> lineDeleter(line); | 214 SkAutoTDeleteArray<char> lineDeleter(line); |
| 207 for (int col = 0; col < divisor; col++) { | 215 for (int col = 0; col < divisor; col++) { |
| 208 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets | 216 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 219 NULL, colorPtr, colorCountPtr); | 227 NULL, colorPtr, colorCountPtr); |
| 220 if (NULL == subsetScanlineDecoder) { | 228 if (NULL == subsetScanlineDecoder) { |
| 221 if (x == 0 && y == 0) { | 229 if (x == 0 && y == 0) { |
| 222 //first try, image may not be compatible | 230 //first try, image may not be compatible |
| 223 return Error::Nonfatal("Cannot use scanline decoder for all images"); | 231 return Error::Nonfatal("Cannot use scanline decoder for all images"); |
| 224 } else { | 232 } else { |
| 225 return "Error scanline decoder is NULL"; | 233 return "Error scanline decoder is NULL"; |
| 226 } | 234 } |
| 227 } | 235 } |
| 228 //skip to first line of subset | 236 //skip to first line of subset |
| 229 const SkImageGenerator::Result skipResult = | 237 const SkImageGenerator::Result skipResult = |
| 230 subsetScanlineDecoder->skipScanlines(y); | 238 subsetScanlineDecoder->skipScanlines(y); |
| 231 switch (skipResult) { | 239 switch (skipResult) { |
| 232 case SkImageGenerator::kSuccess: | 240 case SkImageGenerator::kSuccess: |
| 233 case SkImageGenerator::kIncompleteInput: | 241 case SkImageGenerator::kIncompleteInput: |
| 234 break; | 242 break; |
| 235 default: | 243 default: |
| 236 return SkStringPrintf("%s failed after attempting to skip %d scanlines" | 244 return SkStringPrintf("%s failed after attempting to skip %d scanlines" |
| 237 "with error message %d", fPath.c_str(), y, ( int) skipResult); | 245 "with error message %d", fPath.c_str(), y, ( int) skipResult); |
| 238 } | 246 } |
| 239 //create and set size of subsetBm | 247 //create and set size of subsetBm |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 255 default: | 263 default: |
| 256 return SkStringPrintf("%s failed after %d scanli nes with error" | 264 return SkStringPrintf("%s failed after %d scanli nes with error" |
| 257 "message %d", fPath.c_str(), y-1, (int) subsetResult); | 265 "message %d", fPath.c_str(), y-1, (int) subsetResult); |
| 258 } | 266 } |
| 259 } | 267 } |
| 260 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); | 268 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y)); |
| 261 } | 269 } |
| 262 } | 270 } |
| 263 break; | 271 break; |
| 264 } | 272 } |
| 273 // This mode tests the skipping of scanlines. | |
|
scroggo
2015/06/11 20:12:48
Maybe the description belongs in the header, by th
msarett
2015/06/11 21:20:27
Done.
| |
| 274 case kStripe_Mode: { | |
| 275 int width = decodeInfo.width(); | |
|
scroggo
2015/06/11 20:12:48
Can these be const?
msarett
2015/06/11 21:20:27
Done.
| |
| 276 int height = decodeInfo.height(); | |
| 277 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that | |
| 278 // does not align with image blocks. | |
| 279 const int stripeHeight = 37; | |
| 280 const int numStripes = (height + stripeHeight - 1) / stripeHeight; | |
| 281 | |
| 282 // Create bitmap | |
| 283 SkBitmap bitmap; | |
| 284 if (!bitmap.tryAllocPixels(decodeInfo, NULL, colorTable.get())) { | |
| 285 return SkStringPrintf("Cannot allocate pixels for %s %dx%d", fPa th.c_str(), | |
| 286 width, height); | |
| 287 } | |
| 288 | |
| 289 // Decode odd stripes | |
| 290 SkScanlineDecoder* decoder = codec->getScanlineDecoder(decodeInfo, N ULL, colorPtr, | |
| 291 colorCountPtr); | |
| 292 if (NULL == decoder) { | |
| 293 return Error::Nonfatal("Cannot use scanline decoder for all imag es"); | |
| 294 } | |
| 295 for (int i = 0; i < numStripes; i += 2) { | |
| 296 // Skip a stripe | |
| 297 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); | |
|
scroggo
2015/06/11 20:12:48
Will this ever be less than stripeHeight? It seems
msarett
2015/06/11 21:20:27
Yes, we might read 0 scanlines below.
| |
| 298 decoder->skipScanlines(linesToSkip); | |
|
scroggo
2015/06/11 20:12:48
I think we want to return an error if this or getS
msarett
2015/06/11 21:20:27
Done.
| |
| 299 | |
| 300 // Read a stripe | |
| 301 const int startY = SkTMin((i + 1) * stripeHeight, height - 1); | |
|
scroggo
2015/06/11 20:12:48
When will we use height - 1? It seems like if the
msarett
2015/06/11 21:20:27
Yes this is tricky and a bug. The original code w
| |
| 302 const int linesToRead = SkTMax(0, SkTMin(stripeHeight, height - startY)); | |
| 303 decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bi tmap.rowBytes()); | |
| 304 } | |
| 305 | |
| 306 // Decode even stripes | |
| 307 decoder = codec->getScanlineDecoder(decodeInfo, NULL, colorPtr, colo rCountPtr); | |
|
scroggo
2015/06/11 20:12:48
I think we want to return an error if decoder is n
msarett
2015/06/11 21:20:27
Done.
| |
| 308 for (int i = 0; i < numStripes; i += 2) { | |
| 309 // Read a stripe | |
| 310 const int startY = i * stripeHeight; | |
| 311 const int linesToRead = SkTMin(stripeHeight, height - startY); | |
| 312 decoder->getScanlines(bitmap.getAddr(0, startY), linesToRead, bi tmap.rowBytes()); | |
| 313 | |
| 314 // Skip a stripe | |
| 315 const int linesToSkip = SkTMax(0, SkTMin(stripeHeight, | |
| 316 height - (i + 1) * stripeHeight)); | |
| 317 decoder->skipScanlines(linesToSkip); | |
| 318 } | |
| 319 canvas->drawBitmap(bitmap, 0, 0); | |
| 320 } | |
| 265 } | 321 } |
| 266 return ""; | 322 return ""; |
| 267 } | 323 } |
| 268 | 324 |
| 269 SkISize CodecSrc::size() const { | 325 SkISize CodecSrc::size() const { |
| 270 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 326 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 271 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 327 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 272 if (NULL != codec) { | 328 if (NULL != codec) { |
| 273 return codec->getInfo().dimensions(); | 329 SkISize size = codec->getScaledDimensions(fScale); |
| 330 return size; | |
| 274 } else { | 331 } else { |
| 275 return SkISize::Make(0, 0); | 332 return SkISize::Make(0, 0); |
| 276 } | 333 } |
| 277 } | 334 } |
| 278 | 335 |
| 279 Name CodecSrc::name() const { | 336 Name CodecSrc::name() const { |
| 280 return SkOSPath::Basename(fPath.c_str()); | 337 if (1.0f == fScale) { |
| 338 return SkOSPath::Basename(fPath.c_str()); | |
| 339 } else { | |
| 340 return SkStringPrintf("%s_%.3f", SkOSPath::Basename(fPath.c_str()).c_str (), fScale); | |
| 341 } | |
| 281 } | 342 } |
| 282 | 343 |
| 283 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ | 344 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~*/ |
| 284 | 345 |
| 285 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} | 346 ImageSrc::ImageSrc(Path path, int divisor) : fPath(path), fDivisor(divisor) {} |
| 286 | 347 |
| 287 Error ImageSrc::draw(SkCanvas* canvas) const { | 348 Error ImageSrc::draw(SkCanvas* canvas) const { |
| 288 SkImageInfo canvasInfo; | 349 SkImageInfo canvasInfo; |
| 289 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { | 350 if (NULL == canvas->peekPixels(&canvasInfo, NULL)) { |
| 290 // TODO: Instead, use lazy decoding to allow the GPU to handle cases lik e YUV. | 351 // 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); | 943 skr.visit<void>(i, drawsAsSingletonPictures); |
| 883 } | 944 } |
| 884 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 945 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
| 885 | 946 |
| 886 canvas->drawPicture(macroPic); | 947 canvas->drawPicture(macroPic); |
| 887 return ""; | 948 return ""; |
| 888 }); | 949 }); |
| 889 } | 950 } |
| 890 | 951 |
| 891 } // namespace DM | 952 } // namespace DM |
| OLD | NEW |