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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 return flags.type != SinkFlags::kRaster | 78 return flags.type != SinkFlags::kRaster |
| 79 || flags.approach != SinkFlags::kDirect; | 79 || flags.approach != SinkFlags::kDirect; |
| 80 } | 80 } |
| 81 | 81 |
| 82 SkScanlineDecoder* start_scanline_decoder(SkData* encoded, const SkImageInfo& in fo, | 82 SkScanlineDecoder* start_scanline_decoder(SkData* encoded, const SkImageInfo& in fo, |
| 83 SkPMColor* colorPtr, int* colorCountPtr) { | 83 SkPMColor* colorPtr, int* colorCountPtr) { |
| 84 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewFromD ata(encoded)); | 84 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewFromD ata(encoded)); |
| 85 if (nullptr == scanlineDecoder) { | 85 if (nullptr == scanlineDecoder) { |
| 86 return nullptr; | 86 return nullptr; |
| 87 } | 87 } |
| 88 // DM scanline test assume kTopDown scanline ordering. Other orderings are | |
| 89 // tested from within SkScaledCodec. | |
| 90 // TODO (msarett): Redesign the CodecSrc tests to improve our coverage of Sk Codec and | |
| 91 // SkScanlineDecoder functionality. Maybe we should write c ode to explicitly | |
| 92 // test kNone, kOutOfOrder, and kBottomUp. | |
| 93 if (SkScanlineDecoder::kTopDown_SkScanlineOrder != scanlineDecoder->getScanl ineOrder()) { | |
| 94 return nullptr; | |
| 95 } | |
| 96 if (SkCodec::kSuccess != scanlineDecoder->start(info, NULL, colorPtr, colorC ountPtr)) { | 88 if (SkCodec::kSuccess != scanlineDecoder->start(info, NULL, colorPtr, colorC ountPtr)) { |
| 97 return nullptr; | 89 return nullptr; |
| 98 } | 90 } |
| 99 return scanlineDecoder.detach(); | 91 return scanlineDecoder.detach(); |
| 100 } | 92 } |
| 101 | 93 |
| 102 Error CodecSrc::draw(SkCanvas* canvas) const { | 94 Error CodecSrc::draw(SkCanvas* canvas) const { |
| 103 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 95 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 104 if (!encoded) { | 96 if (!encoded) { |
| 105 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); | 97 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); |
| 106 } | 98 } |
| 107 SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromData(encoded)); | 99 SkAutoTDelete<SkCodec> codec(NULL); |
| 100 if (kScaledCodec_Mode == fMode) { | |
| 101 codec.reset(SkScaledCodec::NewFromData(encoded)); | |
| 102 // TODO (msarett): This should fall throught to a fatal error once we su pport scaled | |
|
scroggo
2015/08/31 19:35:24
nit: through*
msarett
2015/08/31 21:05:28
Done.
| |
| 103 // codecs for all image types. | |
| 104 if (nullptr == codec.get()) { | |
| 105 return Error::Nonfatal(SkStringPrintf("Couldn't create scaled codec for %s.", | |
| 106 fPath.c_str())); | |
| 107 } | |
| 108 } else { | |
| 109 codec.reset(SkCodec::NewFromData(encoded)); | |
| 110 } | |
| 108 if (nullptr == codec.get()) { | 111 if (nullptr == codec.get()) { |
| 109 // scaledCodec not supported, try normal codec | 112 return SkStringPrintf("Couldn't create codec for %s.", fPath.c_str()); |
| 110 codec.reset(SkCodec::NewFromData(encoded)); | |
| 111 if (nullptr == codec.get()) { | |
| 112 return SkStringPrintf("Couldn't create codec for %s.", fPath.c_str() ); | |
| 113 } | |
| 114 } | 113 } |
| 115 | 114 |
| 116 // Choose the color type to decode to | 115 // Choose the color type to decode to |
| 117 SkImageInfo decodeInfo = codec->getInfo(); | 116 SkImageInfo decodeInfo = codec->getInfo(); |
| 118 SkColorType canvasColorType = canvas->imageInfo().colorType(); | 117 SkColorType canvasColorType = canvas->imageInfo().colorType(); |
| 119 switch (fDstColorType) { | 118 switch (fDstColorType) { |
| 120 case kIndex8_Always_DstColorType: | 119 case kIndex8_Always_DstColorType: |
| 121 decodeInfo = codec->getInfo().makeColorType(kIndex_8_SkColorType); | 120 decodeInfo = codec->getInfo().makeColorType(kIndex_8_SkColorType); |
| 122 if (kRGB_565_SkColorType == canvasColorType) { | 121 if (kRGB_565_SkColorType == canvasColorType) { |
| 123 return Error::Nonfatal("Testing non-565 to 565 is uninteresting. "); | 122 return Error::Nonfatal("Testing non-565 to 565 is uninteresting. "); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 164 decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType); | 163 decodeInfo = decodeInfo.makeAlphaType(kPremul_SkAlphaType); |
| 165 } | 164 } |
| 166 | 165 |
| 167 SkBitmap bitmap; | 166 SkBitmap bitmap; |
| 168 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { | 167 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { |
| 169 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str( ), | 168 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPath.c_str( ), |
| 170 decodeInfo.width(), decodeInfo.height()); | 169 decodeInfo.width(), decodeInfo.height()); |
| 171 } | 170 } |
| 172 | 171 |
| 173 switch (fMode) { | 172 switch (fMode) { |
| 174 case kNormal_Mode: { | 173 case kScaledCodec_Mode: |
| 174 case kCodec_Mode: { | |
| 175 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), nullptr, | 175 switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowB ytes(), nullptr, |
| 176 colorPtr, colorCountPtr)) { | 176 colorPtr, colorCountPtr)) { |
| 177 case SkCodec::kSuccess: | 177 case SkCodec::kSuccess: |
| 178 // We consider incomplete to be valid, since we should still decode what is | 178 // We consider incomplete to be valid, since we should still decode what is |
| 179 // available. | 179 // available. |
| 180 case SkCodec::kIncompleteInput: | 180 case SkCodec::kIncompleteInput: |
| 181 break; | 181 break; |
| 182 case SkCodec::kInvalidConversion: | 182 case SkCodec::kInvalidConversion: |
| 183 return Error::Nonfatal("Incompatible colortype conversion"); | 183 return Error::Nonfatal("Incompatible colortype conversion"); |
| 184 default: | 184 default: |
| 185 // Everything else is considered a failure. | 185 // Everything else is considered a failure. |
| 186 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); | 186 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str( )); |
| 187 } | 187 } |
| 188 canvas->drawBitmap(bitmap, 0, 0); | 188 canvas->drawBitmap(bitmap, 0, 0); |
| 189 break; | 189 break; |
| 190 } | 190 } |
| 191 case kScanline_Mode: { | 191 case kScanline_Mode: { |
| 192 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( | 192 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( |
| 193 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr)); | 193 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr)); |
| 194 if (nullptr == scanlineDecoder) { | 194 if (nullptr == scanlineDecoder) { |
| 195 return Error::Nonfatal("Could not start top-down scanline decode r"); | 195 return Error::Nonfatal("Could not start scanline decoder"); |
| 196 } | 196 } |
| 197 | 197 |
| 198 const SkCodec::Result result = scanlineDecoder->getScanlines( | 198 const SkCodec::Result result = scanlineDecoder->getScanlines( |
| 199 bitmap.getAddr(0, 0), decodeInfo.height(), bitmap.rowBytes() ); | 199 bitmap.getAddr(0, 0), decodeInfo.height(), bitmap.rowBytes() ); |
| 200 switch (result) { | 200 switch (result) { |
| 201 case SkCodec::kSuccess: | 201 case SkCodec::kSuccess: |
| 202 case SkCodec::kIncompleteInput: | 202 case SkCodec::kIncompleteInput: |
| 203 break; | 203 break; |
| 204 default: | 204 default: |
| 205 return SkStringPrintf("%s failed with error message %d", | 205 return SkStringPrintf("%s failed with error message %d", |
| 206 fPath.c_str(), (int) result); | 206 fPath.c_str(), (int) result); |
| 207 } | 207 } |
| 208 canvas->drawBitmap(bitmap, 0, 0); | 208 canvas->drawBitmap(bitmap, 0, 0); |
| 209 break; | 209 break; |
| 210 } | 210 } |
| 211 case kScanline_Subset_Mode: { | 211 case kScanline_Subset_Mode: { |
|
msarett
2015/08/31 18:05:52
I'm wondering if maybe we should eliminate the sca
scroggo
2015/08/31 19:35:24
Yes, I think we should. This serves as a proof-of-
| |
| 212 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder | 212 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder |
| 213 const int divisor = 2; | 213 const int divisor = 2; |
| 214 const int w = decodeInfo.width(); | 214 const int w = decodeInfo.width(); |
| 215 const int h = decodeInfo.height(); | 215 const int h = decodeInfo.height(); |
| 216 if (divisor > w || divisor > h) { | 216 if (divisor > w || divisor > h) { |
| 217 return Error::Nonfatal(SkStringPrintf("Cannot decode subset: div isor %d is too big" | 217 return Error::Nonfatal(SkStringPrintf("Cannot decode subset: div isor %d is too big" |
| 218 "for %s with dimensions (%d x %d)", divisor, fPath.c_str (), w, h)); | 218 "for %s with dimensions (%d x %d)", divisor, fPath.c_str (), w, h)); |
| 219 } | 219 } |
| 220 const int subsetWidth = w/divisor; | 220 const int subsetWidth = w/divisor; |
| 221 const int subsetHeight = h/divisor; | 221 const int subsetHeight = h/divisor; |
| 222 // One of our subsets will be larger to contain any pixels that do n ot divide evenly. | 222 // One of our subsets will be larger to contain any pixels that do n ot divide evenly. |
| 223 const int extraX = w % divisor; | 223 const int extraX = w % divisor; |
| 224 const int extraY = h % divisor; | 224 const int extraY = h % divisor; |
| 225 /* | 225 /* |
| 226 * if w or h are not evenly divided by divisor need to adjust width a nd height of end | 226 * if w or h are not evenly divided by divisor need to adjust width a nd height of end |
| 227 * subsets to cover entire image. | 227 * subsets to cover entire image. |
| 228 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width | 228 * Add extraX and extraY to largestSubsetBm's width and height to adj ust width |
| 229 * and height of end subsets. | 229 * and height of end subsets. |
| 230 * subsetBm is extracted from largestSubsetBm. | 230 * subsetBm is extracted from largestSubsetBm. |
| 231 * subsetBm's size is determined based on the current subset and may be larger for end | 231 * subsetBm's size is determined based on the current subset and may be larger for end |
| 232 * subsets. | 232 * subsets. |
| 233 */ | 233 */ |
| 234 SkImageInfo largestSubsetDecodeInfo = | 234 SkImageInfo largestSubsetDecodeInfo = |
| 235 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); | 235 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); |
| 236 SkBitmap largestSubsetBm; | 236 SkBitmap largestSubsetBm; |
| 237 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, nullptr , colorTable.get())) { | 237 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, nullptr , |
| 238 colorTable.get())) { | |
| 238 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), | 239 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), |
| 239 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); | 240 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); |
| 240 } | 241 } |
| 241 const size_t rowBytes = decodeInfo.minRowBytes(); | 242 const size_t rowBytes = decodeInfo.minRowBytes(); |
| 242 char* buffer = new char[largestSubsetDecodeInfo.height() * rowBytes] ; | 243 char* buffer = new char[largestSubsetDecodeInfo.height() * rowBytes] ; |
| 243 SkAutoTDeleteArray<char> lineDeleter(buffer); | 244 SkAutoTDeleteArray<char> lineDeleter(buffer); |
| 244 for (int col = 0; col < divisor; col++) { | 245 for (int col = 0; col < divisor; col++) { |
| 245 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets | 246 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets |
| 246 const int currentSubsetWidth = (col + 1 == divisor) ? | 247 const int currentSubsetWidth = (col + 1 == divisor) ? |
| 247 subsetWidth + extraX : subsetWidth; | 248 subsetWidth + extraX : subsetWidth; |
| 248 const int x = col * subsetWidth; | 249 const int x = col * subsetWidth; |
| 249 for (int row = 0; row < divisor; row++) { | 250 for (int row = 0; row < divisor; row++) { |
| 250 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets | 251 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets |
| 251 const int currentSubsetHeight = (row + 1 == divisor) ? | 252 const int currentSubsetHeight = (row + 1 == divisor) ? |
| 252 subsetHeight + extraY : subsetHeight; | 253 subsetHeight + extraY : subsetHeight; |
| 253 const int y = row * subsetHeight; | 254 const int y = row * subsetHeight; |
| 254 //create scanline decoder for each subset | 255 //create scanline decoder for each subset |
| 255 SkAutoTDelete<SkScanlineDecoder> subsetScanlineDecoder( | 256 SkAutoTDelete<SkScanlineDecoder> decoder(start_scanline_deco der(encoded.get(), |
| 256 start_scanline_decoder(encoded.get(), decodeInfo, | 257 decodeInfo, colorPtr, colorCountPtr)); |
| 257 colorPtr, colorCountPtr)); | 258 // TODO (msarett): Support this mode for all scanline orderi ngs. |
| 258 if (nullptr == subsetScanlineDecoder) { | 259 if (nullptr == decoder || SkScanlineDecoder::kTopDown_SkScan lineOrder != |
| 260 decoder->getScanlineOrder()) { | |
| 259 if (x == 0 && y == 0) { | 261 if (x == 0 && y == 0) { |
| 260 //first try, image may not be compatible | 262 //first try, image may not be compatible |
| 261 return Error::Nonfatal("Could not start top-down sca nline decoder"); | 263 return Error::Nonfatal("Could not start top-down sca nline decoder"); |
| 262 } else { | 264 } else { |
| 263 return "Error scanline decoder is nullptr"; | 265 return "Error scanline decoder is nullptr"; |
| 264 } | 266 } |
| 265 } | 267 } |
| 266 //skip to first line of subset | 268 //skip to first line of subset |
| 267 const SkCodec::Result skipResult = | 269 const SkCodec::Result skipResult = decoder->skipScanlines(y) ; |
| 268 subsetScanlineDecoder->skipScanlines(y); | |
| 269 switch (skipResult) { | 270 switch (skipResult) { |
| 270 case SkCodec::kSuccess: | 271 case SkCodec::kSuccess: |
| 271 case SkCodec::kIncompleteInput: | 272 case SkCodec::kIncompleteInput: |
| 272 break; | 273 break; |
| 273 default: | 274 default: |
| 274 return SkStringPrintf("%s failed after attempting to skip %d scanlines" | 275 return SkStringPrintf("%s failed after attempting to skip %d scanlines" |
| 275 "with error message %d", fPath.c_str(), y, ( int) skipResult); | 276 "with error message %d", fPath.c_str(), y, ( int) skipResult); |
| 276 } | 277 } |
| 277 //create and set size of subsetBm | 278 //create and set size of subsetBm |
| 278 SkBitmap subsetBm; | 279 SkBitmap subsetBm; |
| 279 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); | 280 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); |
| 280 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); | 281 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); |
| 281 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); | 282 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); |
| 282 SkAutoLockPixels autlockSubsetBm(subsetBm, true); | 283 SkAutoLockPixels autlockSubsetBm(subsetBm, true); |
| 283 const SkCodec::Result subsetResult = | 284 const SkCodec::Result subsetResult = |
| 284 subsetScanlineDecoder->getScanlines(buffer, currentSubse tHeight, rowBytes); | 285 decoder->getScanlines(buffer, currentSubsetHeight, r owBytes); |
| 285 switch (subsetResult) { | 286 switch (subsetResult) { |
| 286 case SkCodec::kSuccess: | 287 case SkCodec::kSuccess: |
| 287 case SkCodec::kIncompleteInput: | 288 case SkCodec::kIncompleteInput: |
| 288 break; | 289 break; |
| 289 default: | 290 default: |
| 290 return SkStringPrintf("%s failed with error message %d", | 291 return SkStringPrintf("%s failed with error message %d", |
| 291 fPath.c_str(), (int) subsetResult); | 292 fPath.c_str(), (int) subsetResult); |
| 292 } | 293 } |
| 293 const size_t bpp = decodeInfo.bytesPerPixel(); | 294 const size_t bpp = decodeInfo.bytesPerPixel(); |
| 294 /* | 295 /* |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 316 case kStripe_Mode: { | 317 case kStripe_Mode: { |
| 317 const int height = decodeInfo.height(); | 318 const int height = decodeInfo.height(); |
| 318 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that | 319 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that |
| 319 // does not align with image blocks. | 320 // does not align with image blocks. |
| 320 const int stripeHeight = 37; | 321 const int stripeHeight = 37; |
| 321 const int numStripes = (height + stripeHeight - 1) / stripeHeight; | 322 const int numStripes = (height + stripeHeight - 1) / stripeHeight; |
| 322 | 323 |
| 323 // Decode odd stripes | 324 // Decode odd stripes |
| 324 SkAutoTDelete<SkScanlineDecoder> decoder( | 325 SkAutoTDelete<SkScanlineDecoder> decoder( |
| 325 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr)); | 326 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr)); |
| 326 if (nullptr == decoder) { | 327 if (nullptr == decoder || |
| 328 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS canlineOrder()) { | |
| 329 // This mode was designed to test the new skip scanlines API in libjpeg-turbo. | |
| 330 // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting | |
| 331 // to run this test for image types that do not have this scanli ne ordering. | |
| 327 return Error::Nonfatal("Could not start top-down scanline decode r"); | 332 return Error::Nonfatal("Could not start top-down scanline decode r"); |
| 328 } | 333 } |
| 329 for (int i = 0; i < numStripes; i += 2) { | 334 for (int i = 0; i < numStripes; i += 2) { |
| 330 // Skip a stripe | 335 // Skip a stripe |
| 331 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); | 336 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); |
| 332 SkCodec::Result result = decoder->skipScanlines(linesToSkip); | 337 SkCodec::Result result = decoder->skipScanlines(linesToSkip); |
| 333 switch (result) { | 338 switch (result) { |
| 334 case SkCodec::kSuccess: | 339 case SkCodec::kSuccess: |
| 335 case SkCodec::kIncompleteInput: | 340 case SkCodec::kIncompleteInput: |
| 336 break; | 341 break; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 350 break; | 355 break; |
| 351 default: | 356 default: |
| 352 return SkStringPrintf("Cannot get scanlines for %s." , fPath.c_str()); | 357 return SkStringPrintf("Cannot get scanlines for %s." , fPath.c_str()); |
| 353 } | 358 } |
| 354 } | 359 } |
| 355 } | 360 } |
| 356 | 361 |
| 357 // Decode even stripes | 362 // Decode even stripes |
| 358 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp tr, colorPtr, | 363 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp tr, colorPtr, |
| 359 colorCountPtr); | 364 colorCountPtr); |
| 360 if (SkCodec::kSuccess != startResult) { | 365 if (SkCodec::kSuccess != startResult || |
| 366 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS canlineOrder()) { | |
|
scroggo
2015/08/31 19:35:24
It seems like we should never reach here if kTopDo
msarett
2015/08/31 21:05:28
Not unless there is a bug in start(). I agree tha
| |
| 361 return "Failed to restart scanline decoder with same parameters. "; | 367 return "Failed to restart scanline decoder with same parameters. "; |
| 362 } | 368 } |
| 363 for (int i = 0; i < numStripes; i += 2) { | 369 for (int i = 0; i < numStripes; i += 2) { |
| 364 // Read a stripe | 370 // Read a stripe |
| 365 const int startY = i * stripeHeight; | 371 const int startY = i * stripeHeight; |
| 366 const int linesToRead = SkTMin(stripeHeight, height - startY); | 372 const int linesToRead = SkTMin(stripeHeight, height - startY); |
| 367 SkCodec::Result result = decoder->getScanlines(bitmap.getAddr(0, startY), | 373 SkCodec::Result result = decoder->getScanlines(bitmap.getAddr(0, startY), |
| 368 linesToRead, bitmap.rowBytes()); | 374 linesToRead, bitmap.rowBytes()); |
| 369 switch (result) { | 375 switch (result) { |
| 370 case SkCodec::kSuccess: | 376 case SkCodec::kSuccess: |
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1081 skr.visit<void>(i, drawsAsSingletonPictures); | 1087 skr.visit<void>(i, drawsAsSingletonPictures); |
| 1082 } | 1088 } |
| 1083 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1089 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
| 1084 | 1090 |
| 1085 canvas->drawPicture(macroPic); | 1091 canvas->drawPicture(macroPic); |
| 1086 return ""; | 1092 return ""; |
| 1087 }); | 1093 }); |
| 1088 } | 1094 } |
| 1089 | 1095 |
| 1090 } // namespace DM | 1096 } // namespace DM |
| OLD | NEW |