From 8289306771381298cf3b87183882cc1f1fef4dc3 Mon Sep 17 00:00:00 2001 From: Mike Klein Date: Wed, 2 Aug 2017 17:24:02 +0000 Subject: [PATCH] Revert "remove another SkConvertPixels "fast path"" This reverts commit 706a076879359207b1da292e5ee7750083e50152. Reason for revert: this looks less a "fast path" and more "completely essential path" according to Chrome roll tests and some layout tests (most are small diffs, but some are radical). Original change's description: > remove another SkConvertPixels "fast path" > > SkColorSpaceXform now uses the same mechanism as our default path, > SkRasterPipeline. There's no real reason to jump out to it as a > special case any more. > > Change-Id: I19490de5b331267209cf117534942fb175c624c9 > Reviewed-on: https://skia-review.googlesource.com/29900 > Reviewed-by: Brian Osman > Commit-Queue: Mike Klein TBR=mtklein@chromium.org,brianosman@google.com Change-Id: I92b17fe0d44e609d8c06e8fa2933f1f572a98094 No-Presubmit: true No-Tree-Checks: true No-Try: true Reviewed-on: https://skia-review.googlesource.com/30160 Reviewed-by: Mike Klein Commit-Queue: Mike Klein --- src/core/SkConvertPixels.cpp | 82 +++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/src/core/SkConvertPixels.cpp b/src/core/SkConvertPixels.cpp index 1dec7ce9dc..b447edaa02 100644 --- a/src/core/SkConvertPixels.cpp +++ b/src/core/SkConvertPixels.cpp @@ -87,7 +87,79 @@ void swizzle_and_multiply(const SkImageInfo& dstInfo, void* dstPixels, size_t ds } } -// Fast Path 3: Alpha 8 dsts. +// Fast Path 3: Color space xform. +static inline bool optimized_color_xform(const SkImageInfo& dstInfo, const SkImageInfo& srcInfo, + SkTransferFunctionBehavior behavior) { + // Unpremultiplication is unsupported by SkColorSpaceXform. Note that if |src| is non-linearly + // premultiplied, we're always going to have to unpremultiply before doing anything. + if (kPremul_SkAlphaType == srcInfo.alphaType() && + (kUnpremul_SkAlphaType == dstInfo.alphaType() || + SkTransferFunctionBehavior::kIgnore == behavior)) { + return false; + } + + switch (dstInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + case kRGBA_F16_SkColorType: + break; + default: + return false; + } + + switch (srcInfo.colorType()) { + case kRGBA_8888_SkColorType: + case kBGRA_8888_SkColorType: + break; + default: + return false; + } + + return true; +} + +static inline void apply_color_xform(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, + const SkImageInfo& srcInfo, const void* srcPixels, + size_t srcRB, SkTransferFunctionBehavior behavior) { + SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType()); + SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(srcInfo.colorType()); + SkAlphaType xformAlpha; + switch (srcInfo.alphaType()) { + case kOpaque_SkAlphaType: + xformAlpha = kOpaque_SkAlphaType; + break; + case kPremul_SkAlphaType: + SkASSERT(kPremul_SkAlphaType == dstInfo.alphaType()); + + // This signal means: copy the src alpha to the dst, do not premultiply (in this + // case because the pixels are already premultiplied). + xformAlpha = kUnpremul_SkAlphaType; + break; + case kUnpremul_SkAlphaType: + SkASSERT(kPremul_SkAlphaType == dstInfo.alphaType() || + kUnpremul_SkAlphaType == dstInfo.alphaType()); + + xformAlpha = dstInfo.alphaType(); + break; + default: + SkASSERT(false); + xformAlpha = kUnpremul_SkAlphaType; + break; + } + + std::unique_ptr xform = + SkColorSpaceXform_Base::New(srcInfo.colorSpace(), dstInfo.colorSpace(), behavior); + SkASSERT(xform); + + for (int y = 0; y < dstInfo.height(); y++) { + SkAssertResult(xform->apply(dstFormat, dstPixels, srcFormat, srcPixels, dstInfo.width(), + xformAlpha)); + dstPixels = SkTAddOffset(dstPixels, dstRB); + srcPixels = SkTAddOffset(srcPixels, srcRB); + } +} + +// Fast Path 4: Alpha 8 dsts. static void convert_to_alpha8(uint8_t* dst, size_t dstRB, const SkImageInfo& srcInfo, const void* src, size_t srcRB, SkColorTable* ctable) { if (srcInfo.isOpaque()) { @@ -285,7 +357,13 @@ void SkConvertPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, return; } - // Fast Path 3: Alpha 8 dsts. + // Fast Path 3: Color space xform. + if (isColorAware && optimized_color_xform(dstInfo, srcInfo, behavior)) { + apply_color_xform(dstInfo, dstPixels, dstRB, srcInfo, srcPixels, srcRB, behavior); + return; + } + + // Fast Path 4: Alpha 8 dsts. if (kAlpha_8_SkColorType == dstInfo.colorType()) { convert_to_alpha8((uint8_t*) dstPixels, dstRB, srcInfo, srcPixels, srcRB, ctable); return;