aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkConvertPixels.cpp
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-08-02 17:24:02 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-08-02 17:24:08 +0000
commit8289306771381298cf3b87183882cc1f1fef4dc3 (patch)
tree6565610bf4bcbf63d35bfa25c8a2bf1f32b27f44 /src/core/SkConvertPixels.cpp
parent0d056ba473160a3a8d39873f4e4162487f585d9e (diff)
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 <brianosman@google.com> > Commit-Queue: Mike Klein <mtklein@chromium.org> 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 <mtklein@chromium.org> Commit-Queue: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/core/SkConvertPixels.cpp')
-rw-r--r--src/core/SkConvertPixels.cpp82
1 files 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<SkColorSpaceXform> 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<void>(dstPixels, dstRB);
+ srcPixels = SkTAddOffset<const void>(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;