Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(320)

Side by Side Diff: dm/DMSrcSink.cpp

Issue 1390213002: Add subsetting to SkScanlineDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@fill-refactor
Patch Set: Rebase to manage dependencies Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « dm/DM.cpp ('k') | gyp/bench.gypi » ('j') | src/codec/SkCodec.cpp » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "SkCodecTools.h" 11 #include "SkCodecPriv.h"
12 #include "SkCommonFlags.h" 12 #include "SkCommonFlags.h"
13 #include "SkData.h" 13 #include "SkData.h"
14 #include "SkDocument.h" 14 #include "SkDocument.h"
15 #include "SkError.h" 15 #include "SkError.h"
16 #include "SkFunction.h" 16 #include "SkFunction.h"
17 #include "SkImageGenerator.h" 17 #include "SkImageGenerator.h"
18 #include "SkMultiPictureDraw.h" 18 #include "SkMultiPictureDraw.h"
19 #include "SkNullCanvas.h" 19 #include "SkNullCanvas.h"
20 #include "SkOSFile.h" 20 #include "SkOSFile.h"
21 #include "SkPictureData.h" 21 #include "SkPictureData.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 bool BRDSrc::veto(SinkFlags flags) const { 79 bool BRDSrc::veto(SinkFlags flags) const {
80 // No need to test to non-raster or indirect backends. 80 // No need to test to non-raster or indirect backends.
81 return flags.type != SinkFlags::kRaster 81 return flags.type != SinkFlags::kRaster
82 || flags.approach != SinkFlags::kDirect; 82 || flags.approach != SinkFlags::kDirect;
83 } 83 }
84 84
85 static SkBitmapRegionDecoderInterface* create_brd(Path path, 85 static SkBitmapRegionDecoderInterface* create_brd(Path path,
86 SkBitmapRegionDecoderInterface::Strategy strategy) { 86 SkBitmapRegionDecoderInterface::Strategy strategy) {
87 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 87 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
88 if (!encoded) { 88 if (!encoded) {
89 return NULL; 89 return nullptr;
90 } 90 }
91 return SkBitmapRegionDecoderInterface::CreateBitmapRegionDecoder(new SkMemor yStream(encoded), 91 return SkBitmapRegionDecoderInterface::CreateBitmapRegionDecoder(new SkMemor yStream(encoded),
92 strategy); 92 strategy);
93 } 93 }
94 94
95 Error BRDSrc::draw(SkCanvas* canvas) const { 95 Error BRDSrc::draw(SkCanvas* canvas) const {
96 SkColorType colorType = canvas->imageInfo().colorType(); 96 SkColorType colorType = canvas->imageInfo().colorType();
97 if (kRGB_565_SkColorType == colorType && 97 if (kRGB_565_SkColorType == colorType &&
98 CodecSrc::kGetFromCanvas_DstColorType != fDstColorType) { 98 CodecSrc::kGetFromCanvas_DstColorType != fDstColorType) {
99 return Error::Nonfatal("Testing non-565 to 565 is uninteresting."); 99 return Error::Nonfatal("Testing non-565 to 565 is uninteresting.");
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 // let the GPU handle it. 237 // let the GPU handle it.
238 return flags.type != SinkFlags::kRaster 238 return flags.type != SinkFlags::kRaster
239 || flags.approach != SinkFlags::kDirect; 239 || flags.approach != SinkFlags::kDirect;
240 } 240 }
241 241
242 Error CodecSrc::draw(SkCanvas* canvas) const { 242 Error CodecSrc::draw(SkCanvas* canvas) const {
243 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); 243 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str()));
244 if (!encoded) { 244 if (!encoded) {
245 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); 245 return SkStringPrintf("Couldn't read %s.", fPath.c_str());
246 } 246 }
247 SkAutoTDelete<SkCodec> codec(NULL); 247 SkAutoTDelete<SkCodec> codec(nullptr);
248 if (kScaledCodec_Mode == fMode) { 248 if (kScaledCodec_Mode == fMode) {
249 codec.reset(SkScaledCodec::NewFromData(encoded)); 249 codec.reset(SkScaledCodec::NewFromData(encoded));
250 // TODO (msarett): This should fall through to a fatal error once we sup port scaled 250 // TODO (msarett): This should fall through to a fatal error once we sup port scaled
251 // codecs for all image types. 251 // codecs for all image types.
252 if (nullptr == codec.get()) { 252 if (nullptr == codec.get()) {
253 return Error::Nonfatal(SkStringPrintf("Couldn't create scaled codec for %s.", 253 return Error::Nonfatal(SkStringPrintf("Couldn't create scaled codec for %s.",
254 fPath.c_str())); 254 fPath.c_str()));
255 } 255 }
256 } else { 256 } else {
257 codec.reset(SkCodec::NewFromData(encoded)); 257 codec.reset(SkCodec::NewFromData(encoded));
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 * subsets. 393 * subsets.
394 */ 394 */
395 SkImageInfo largestSubsetDecodeInfo = 395 SkImageInfo largestSubsetDecodeInfo =
396 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y); 396 decodeInfo.makeWH(subsetWidth + extraX, subsetHeight + extra Y);
397 SkBitmap largestSubsetBm; 397 SkBitmap largestSubsetBm;
398 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, nullptr , 398 if (!largestSubsetBm.tryAllocPixels(largestSubsetDecodeInfo, nullptr ,
399 colorTable.get())) { 399 colorTable.get())) {
400 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(), 400 return SkStringPrintf("Image(%s) is too large (%d x %d)\n", fPat h.c_str(),
401 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height()); 401 largestSubsetDecodeInfo.width(), largestSubsetDecodeInfo .height());
402 } 402 }
403 const size_t rowBytes = decodeInfo.minRowBytes();
404 char* buffer = new char[largestSubsetDecodeInfo.height() * rowBytes] ;
405 SkAutoTDeleteArray<char> lineDeleter(buffer);
406 for (int col = 0; col < divisor; col++) { 403 for (int col = 0; col < divisor; col++) {
407 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets 404 //currentSubsetWidth may be larger than subsetWidth for rightmos t subsets
408 const int currentSubsetWidth = (col + 1 == divisor) ? 405 const int currentSubsetWidth = (col + 1 == divisor) ?
409 subsetWidth + extraX : subsetWidth; 406 subsetWidth + extraX : subsetWidth;
410 const int x = col * subsetWidth; 407 const int x = col * subsetWidth;
411 for (int row = 0; row < divisor; row++) { 408 for (int row = 0; row < divisor; row++) {
412 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets 409 //currentSubsetHeight may be larger than subsetHeight for bo ttom subsets
413 const int currentSubsetHeight = (row + 1 == divisor) ? 410 const int currentSubsetHeight = (row + 1 == divisor) ?
414 subsetHeight + extraY : subsetHeight; 411 subsetHeight + extraY : subsetHeight;
415 const int y = row * subsetHeight; 412 const int y = row * subsetHeight;
416 //create scanline decoder for each subset 413 //create scanline decoder for each subset
417 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeIn fo, NULL, colorPtr, 414 SkCodec::Options options;
418 colorCou ntPtr) 415 SkIRect subset = SkIRect::MakeXYWH(x, 0, currentSubsetWidth, h);
419 // TODO (msarett): Support this mode for all scanlin e orderings. 416 options.fSubset = &subset;
420 || SkCodec::kTopDown_SkScanlineOrder != codec->getSc anlineOrder()) { 417 // TODO (msarett): Support this mode for all scanline orderi ngs.
418 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeIn fo, &options,
419 colorPtr, colorCountPtr) ||
420 SkCodec::kTopDown_SkScanlineOrder != codec->getScanl ineOrder()) {
421 if (x == 0 && y == 0) { 421 if (x == 0 && y == 0) {
422 //first try, image may not be compatible 422 //first try, image may not be compatible
423 return Error::Nonfatal("Could not start top-down sca nline decoder"); 423 return Error::Nonfatal("Could not start top-down sca nline decoder");
424 } else { 424 } else {
425 return "Error scanline decoder is nullptr"; 425 return "Error scanline decoder is nullptr";
426 } 426 }
427 } 427 }
428 // Skip to the first line of subset. We ignore the result v alue here. 428 // Skip to the first line of subset. We ignore the result v alue here.
429 // If the skip value fails, this will indicate an incomplete image. 429 // If the skip value fails, this will indicate an incomplete image.
430 // This means that the call to getScanlines() will also fail , but it 430 // This means that the call to getScanlines() will also fail , but it
431 // will fill the buffer with a default value, so we can stil l draw the 431 // will fill the buffer with a default value, so we can stil l draw the
432 // image. 432 // image.
433 codec->skipScanlines(y); 433 codec->skipScanlines(y);
434 434
435 //create and set size of subsetBm 435 //create and set size of subsetBm
436 SkBitmap subsetBm; 436 SkBitmap bitmap;
scroggo 2015/10/08 20:16:07 Why did you change this name? The comment above no
msarett 2015/10/09 20:03:44 Can't remember. Changing it back sorry.
437 SkIRect bounds = SkIRect::MakeWH(currentSubsetWidth, current SubsetHeight); 437 SkIRect bounds = SkIRect::MakeWH(currentSubsetWidth, current SubsetHeight);
438 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); 438 SkAssertResult(largestSubsetBm.extractSubset(&bitmap, bounds ));
439 SkAutoLockPixels autlockSubsetBm(subsetBm, true); 439 SkAutoLockPixels autolock(bitmap, true);
440 codec->getScanlines(buffer, currentSubsetHeight, rowBytes); 440 codec->getScanlines(bitmap.getAddr(0, 0), currentSubsetHeigh t,
441 441 bitmap.rowBytes());
442 const size_t bpp = decodeInfo.bytesPerPixel(); 442 bitmap.notifyPixelsChanged();
443 char* bufferRow = buffer; 443 canvas->drawBitmap(bitmap, SkIntToScalar(x), SkIntToScalar(y ));
444 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) {
445 memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp,
446 currentSubsetWidth*bpp);
447 bufferRow += rowBytes;
448 }
449
450 subsetBm.notifyPixelsChanged();
451 canvas->drawBitmap(subsetBm, SkIntToScalar(x), SkIntToScalar (y));
452 } 444 }
453 } 445 }
454 break; 446 break;
455 } 447 }
456 case kStripe_Mode: { 448 case kStripe_Mode: {
457 const int height = decodeInfo.height(); 449 const int height = decodeInfo.height();
458 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that 450 // This value is chosen arbitrarily. We exercise more cases by choo sing a value that
459 // does not align with image blocks. 451 // does not align with image blocks.
460 const int stripeHeight = 37; 452 const int stripeHeight = 37;
461 const int numStripes = (height + stripeHeight - 1) / stripeHeight; 453 const int numStripes = (height + stripeHeight - 1) / stripeHeight;
(...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after
1204 skr.visit<void>(i, drawsAsSingletonPictures); 1196 skr.visit<void>(i, drawsAsSingletonPictures);
1205 } 1197 }
1206 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); 1198 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture());
1207 1199
1208 canvas->drawPicture(macroPic); 1200 canvas->drawPicture(macroPic);
1209 return ""; 1201 return "";
1210 }); 1202 });
1211 } 1203 }
1212 1204
1213 } // namespace DM 1205 } // namespace DM
OLDNEW
« no previous file with comments | « dm/DM.cpp ('k') | gyp/bench.gypi » ('j') | src/codec/SkCodec.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698