| 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 "SkAndroidCodec.h" | 9 #include "SkAndroidCodec.h" |
| 10 #include "SkCodec.h" | 10 #include "SkCodec.h" |
| 11 #include "SkCodecImageGenerator.h" | 11 #include "SkCodecImageGenerator.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 "SkImageGenerator.h" | 16 #include "SkImageGenerator.h" |
| 17 #include "SkImageGeneratorCG.h" |
| 17 #include "SkMallocPixelRef.h" | 18 #include "SkMallocPixelRef.h" |
| 18 #include "SkMultiPictureDraw.h" | 19 #include "SkMultiPictureDraw.h" |
| 19 #include "SkNullCanvas.h" | 20 #include "SkNullCanvas.h" |
| 20 #include "SkOSFile.h" | 21 #include "SkOSFile.h" |
| 21 #include "SkOpts.h" | 22 #include "SkOpts.h" |
| 22 #include "SkPictureData.h" | 23 #include "SkPictureData.h" |
| 23 #include "SkPictureRecorder.h" | 24 #include "SkPictureRecorder.h" |
| 24 #include "SkRandom.h" | 25 #include "SkRandom.h" |
| 25 #include "SkRecordDraw.h" | 26 #include "SkRecordDraw.h" |
| 26 #include "SkRecorder.h" | 27 #include "SkRecorder.h" |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 float scale) | 257 float scale) |
| 257 : fPath(path) | 258 : fPath(path) |
| 258 , fMode(mode) | 259 , fMode(mode) |
| 259 , fDstColorType(dstColorType) | 260 , fDstColorType(dstColorType) |
| 260 , fDstAlphaType(dstAlphaType) | 261 , fDstAlphaType(dstAlphaType) |
| 261 , fScale(scale) | 262 , fScale(scale) |
| 262 , fRunSerially(serial_from_path_name(path)) | 263 , fRunSerially(serial_from_path_name(path)) |
| 263 {} | 264 {} |
| 264 | 265 |
| 265 bool CodecSrc::veto(SinkFlags flags) const { | 266 bool CodecSrc::veto(SinkFlags flags) const { |
| 266 // Test CodecImageGenerator on 8888, 565, and gpu | 267 // Test to direct raster backends (8888 and 565). |
| 267 if (kGen_Mode == fMode) { | |
| 268 // For image generator, we want to test kDirect approaches for kRaster a
nd kGPU, | |
| 269 // while skipping everything else. | |
| 270 return (flags.type != SinkFlags::kRaster && flags.type != SinkFlags::kGP
U) || | |
| 271 flags.approach != SinkFlags::kDirect; | |
| 272 } | |
| 273 | |
| 274 // Test all other modes to direct raster backends (8888 and 565). | |
| 275 return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDir
ect; | 268 return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDir
ect; |
| 276 } | 269 } |
| 277 | 270 |
| 278 // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and s
kbug.com/3339. | 271 // FIXME: Currently we cannot draw unpremultiplied sources. skbug.com/3338 and s
kbug.com/3339. |
| 279 // This allows us to still test unpremultiplied decodes. | 272 // This allows us to still test unpremultiplied decodes. |
| 280 void premultiply_if_necessary(SkBitmap& bitmap) { | 273 void premultiply_if_necessary(SkBitmap& bitmap) { |
| 281 if (kUnpremul_SkAlphaType != bitmap.alphaType()) { | 274 if (kUnpremul_SkAlphaType != bitmap.alphaType()) { |
| 282 return; | 275 return; |
| 283 } | 276 } |
| 284 | 277 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 326 kOpaque_SkAlphaType != decodeInfo->alphaType()) { | 319 kOpaque_SkAlphaType != decodeInfo->alphaType()) { |
| 327 return false; | 320 return false; |
| 328 } | 321 } |
| 329 *decodeInfo = decodeInfo->makeColorType(canvasColorType); | 322 *decodeInfo = decodeInfo->makeColorType(canvasColorType); |
| 330 break; | 323 break; |
| 331 } | 324 } |
| 332 | 325 |
| 333 return true; | 326 return true; |
| 334 } | 327 } |
| 335 | 328 |
| 336 Error test_gen(SkCanvas* canvas, SkData* data) { | |
| 337 SkAutoTDelete<SkImageGenerator> gen = SkCodecImageGenerator::NewFromEncodedC
odec(data); | |
| 338 if (!gen) { | |
| 339 return "Could not create image generator."; | |
| 340 } | |
| 341 | |
| 342 // FIXME: The gpu backend does not draw kGray sources correctly. (skbug.com/
4822) | |
| 343 // Currently, we will avoid creating a CodecSrc for this case (see DM.cpp). | |
| 344 SkASSERT(kGray_8_SkColorType != gen->getInfo().colorType()); | |
| 345 | |
| 346 if (kOpaque_SkAlphaType != gen->getInfo().alphaType() && | |
| 347 kRGB_565_SkColorType == canvas->imageInfo().colorType()) { | |
| 348 return Error::Nonfatal("Skip testing non-opaque images to 565."); | |
| 349 } | |
| 350 | |
| 351 SkAutoTDelete<SkImage> image(SkImage::NewFromGenerator(gen.detach(), nullptr
)); | |
| 352 if (!image) { | |
| 353 return "Could not create image from codec image generator."; | |
| 354 } | |
| 355 | |
| 356 canvas->drawImage(image, 0, 0); | |
| 357 return ""; | |
| 358 } | |
| 359 | |
| 360 Error CodecSrc::draw(SkCanvas* canvas) const { | 329 Error CodecSrc::draw(SkCanvas* canvas) const { |
| 361 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 330 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 362 if (!encoded) { | 331 if (!encoded) { |
| 363 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); | 332 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); |
| 364 } | 333 } |
| 365 | 334 |
| 366 // The CodecImageGenerator test does not share much code with the other test
s, | |
| 367 // so we will handle it in its own function. | |
| 368 if (kGen_Mode == fMode) { | |
| 369 return test_gen(canvas, encoded); | |
| 370 } | |
| 371 | |
| 372 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 335 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 373 if (nullptr == codec.get()) { | 336 if (nullptr == codec.get()) { |
| 374 return SkStringPrintf("Couldn't create codec for %s.", fPath.c_str()); | 337 return SkStringPrintf("Couldn't create codec for %s.", fPath.c_str()); |
| 375 } | 338 } |
| 376 | 339 |
| 377 SkImageInfo decodeInfo = codec->getInfo().makeAlphaType(fDstAlphaType); | 340 SkImageInfo decodeInfo = codec->getInfo().makeAlphaType(fDstAlphaType); |
| 378 if (!get_decode_info(&decodeInfo, canvas->imageInfo().colorType(), fDstColor
Type)) { | 341 if (!get_decode_info(&decodeInfo, canvas->imageInfo().colorType(), fDstColor
Type)) { |
| 379 return Error::Nonfatal("Testing non-565 to 565 is uninteresting."); | 342 return Error::Nonfatal("Testing non-565 to 565 is uninteresting."); |
| 380 } | 343 } |
| 381 | 344 |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 795 // We will replicate the names used by CodecSrc so that images can | 758 // We will replicate the names used by CodecSrc so that images can |
| 796 // be compared in Gold. | 759 // be compared in Gold. |
| 797 if (1 == fSampleSize) { | 760 if (1 == fSampleSize) { |
| 798 return SkOSPath::Basename(fPath.c_str()); | 761 return SkOSPath::Basename(fPath.c_str()); |
| 799 } | 762 } |
| 800 return get_scaled_name(fPath, 1.0f / (float) fSampleSize); | 763 return get_scaled_name(fPath, 1.0f / (float) fSampleSize); |
| 801 } | 764 } |
| 802 | 765 |
| 803 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ | 766 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 804 | 767 |
| 768 ImageGenSrc::ImageGenSrc(Path path, Mode mode, SkAlphaType alphaType, bool isGpu
) |
| 769 : fPath(path) |
| 770 , fMode(mode) |
| 771 , fDstAlphaType(alphaType) |
| 772 , fIsGpu(isGpu) |
| 773 , fRunSerially(serial_from_path_name(path)) |
| 774 {} |
| 775 |
| 776 bool ImageGenSrc::veto(SinkFlags flags) const { |
| 777 if (fIsGpu) { |
| 778 return flags.type != SinkFlags::kGPU || flags.approach != SinkFlags::kDi
rect; |
| 779 } |
| 780 |
| 781 return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDir
ect; |
| 782 } |
| 783 |
| 784 Error ImageGenSrc::draw(SkCanvas* canvas) const { |
| 785 if (kRGB_565_SkColorType == canvas->imageInfo().colorType()) { |
| 786 return Error::Nonfatal("Uninteresting to test image generator to 565."); |
| 787 } |
| 788 |
| 789 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 790 if (!encoded) { |
| 791 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); |
| 792 } |
| 793 |
| 794 SkAutoTDelete<SkImageGenerator> gen(nullptr); |
| 795 switch (fMode) { |
| 796 case kCodec_Mode: |
| 797 gen.reset(SkCodecImageGenerator::NewFromEncodedCodec(encoded)); |
| 798 if (!gen) { |
| 799 return "Could not create codec image generator."; |
| 800 } |
| 801 break; |
| 802 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
| 803 case kPlatform_Mode: |
| 804 gen.reset(SkImageGeneratorCG::NewFromEncodedCG(encoded)); |
| 805 if (!gen) { |
| 806 return "Could not create CG image generator."; |
| 807 } |
| 808 break; |
| 809 #endif |
| 810 default: |
| 811 SkASSERT(false); |
| 812 return "Invalid image generator mode"; |
| 813 } |
| 814 |
| 815 // Test deferred decoding path on GPU |
| 816 if (fIsGpu) { |
| 817 // FIXME: The gpu backend does not draw kGray sources correctly. (skbug.
com/4822) |
| 818 // We have disabled these tests in DM.cpp. |
| 819 SkASSERT(kGray_8_SkColorType != gen->getInfo().colorType()); |
| 820 |
| 821 SkAutoTDelete<SkImage> image(SkImage::NewFromGenerator(gen.detach(), nul
lptr)); |
| 822 if (!image) { |
| 823 return "Could not create image from codec image generator."; |
| 824 } |
| 825 canvas->drawImage(image, 0, 0); |
| 826 return ""; |
| 827 } |
| 828 |
| 829 // Test various color and alpha types on CPU |
| 830 SkImageInfo decodeInfo = gen->getInfo().makeAlphaType(fDstAlphaType); |
| 831 |
| 832 if (kGray_8_SkColorType == decodeInfo.colorType() && |
| 833 kOpaque_SkAlphaType != decodeInfo.alphaType()) { |
| 834 return Error::Nonfatal("Avoid requesting non-opaque kGray8 decodes."); |
| 835 } |
| 836 |
| 837 SkAutoTUnref<SkColorTable> colorTable(nullptr); |
| 838 SkPMColor* colorPtr = nullptr; |
| 839 int* colorCountPtr = nullptr; |
| 840 int maxColors = 256; |
| 841 if (kIndex_8_SkColorType == decodeInfo.colorType()) { |
| 842 SkPMColor colors[256]; |
| 843 colorTable.reset(new SkColorTable(colors, maxColors)); |
| 844 colorPtr = const_cast<SkPMColor*>(colorTable->readColors()); |
| 845 colorCountPtr = &maxColors; |
| 846 } |
| 847 |
| 848 SkBitmap bitmap; |
| 849 if (!bitmap.tryAllocPixels(decodeInfo, nullptr, colorTable.get())) { |
| 850 return SkStringPrintf("Image(%s) is too large (%d x %d)", fPath.c_str(), |
| 851 decodeInfo.width(), decodeInfo.height()); |
| 852 } |
| 853 |
| 854 if (!gen->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), color
Ptr, |
| 855 colorCountPtr)) |
| 856 { |
| 857 return SkStringPrintf("Image generator could not getPixels() for %s\n",
fPath.c_str()); |
| 858 } |
| 859 |
| 860 premultiply_if_necessary(bitmap); |
| 861 canvas->drawBitmap(bitmap, 0, 0); |
| 862 return ""; |
| 863 } |
| 864 |
| 865 SkISize ImageGenSrc::size() const { |
| 866 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
| 867 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
| 868 if (nullptr == codec) { |
| 869 return SkISize::Make(0, 0); |
| 870 } |
| 871 return codec->getInfo().dimensions(); |
| 872 } |
| 873 |
| 874 Name ImageGenSrc::name() const { |
| 875 return SkOSPath::Basename(fPath.c_str()); |
| 876 } |
| 877 |
| 878 /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~*/ |
| 879 |
| 805 static const SkRect kSKPViewport = {0,0, 1000,1000}; | 880 static const SkRect kSKPViewport = {0,0, 1000,1000}; |
| 806 | 881 |
| 807 SKPSrc::SKPSrc(Path path) : fPath(path) {} | 882 SKPSrc::SKPSrc(Path path) : fPath(path) {} |
| 808 | 883 |
| 809 Error SKPSrc::draw(SkCanvas* canvas) const { | 884 Error SKPSrc::draw(SkCanvas* canvas) const { |
| 810 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(fPath.c_str())); | 885 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(fPath.c_str())); |
| 811 if (!stream) { | 886 if (!stream) { |
| 812 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); | 887 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); |
| 813 } | 888 } |
| 814 SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream)); | 889 SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream)); |
| (...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1412 skr.visit<void>(i, drawsAsSingletonPictures); | 1487 skr.visit<void>(i, drawsAsSingletonPictures); |
| 1413 } | 1488 } |
| 1414 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1489 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
| 1415 | 1490 |
| 1416 canvas->drawPicture(macroPic); | 1491 canvas->drawPicture(macroPic); |
| 1417 return check_against_reference(bitmap, src, fSink); | 1492 return check_against_reference(bitmap, src, fSink); |
| 1418 }); | 1493 }); |
| 1419 } | 1494 } |
| 1420 | 1495 |
| 1421 } // namespace DM | 1496 } // namespace DM |
| OLD | NEW |