diff options
author | 2017-04-03 10:35:42 -0400 | |
---|---|---|
committer | 2017-04-03 15:35:55 +0000 | |
commit | e6844834087cf9113c64fb638be3945049cf0f47 (patch) | |
tree | 46f20b457cf0b71938680d289c05c2ab235ba9b0 /src | |
parent | d3ccb0a37f0e62c84fdcd6a77b7b15476b04db7a (diff) |
Avoid extra bitmap copies in SkColorSpaceXformCanvas
Before:
ColorCanvasDrawBitmap_sRGB_to_sRGB 5.09us
ColorCanvasDrawBitmap_AdobeRGB_to_sRGB 50.7us
After:
ColorCanvasDrawBitmap_sRGB_to_sRGB 2.43us
ColorCanvasDrawBitmap_AdobeRGB_to_sRGB 37.1us
BUG=skia:6456
Change-Id: Ie382936c36fd347b59485882cf8f27f315a5d35f
Change-Id: Ie382936c36fd347b59485882cf8f27f315a5d35f
Reviewed-on: https://skia-review.googlesource.com/11040
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/core/SkColorSpaceXformCanvas.cpp | 49 | ||||
-rw-r--r-- | src/core/SkColorSpaceXformer.cpp | 13 | ||||
-rw-r--r-- | src/core/SkColorSpaceXformer.h | 1 |
3 files changed, 51 insertions, 12 deletions
diff --git a/src/core/SkColorSpaceXformCanvas.cpp b/src/core/SkColorSpaceXformCanvas.cpp index 5756905b96..f701d12336 100644 --- a/src/core/SkColorSpaceXformCanvas.cpp +++ b/src/core/SkColorSpaceXformCanvas.cpp @@ -10,16 +10,18 @@ #include "SkColorSpaceXformer.h" #include "SkGradientShader.h" #include "SkImage_Base.h" +#include "SkImagePriv.h" #include "SkMakeUnique.h" #include "SkNoDrawCanvas.h" #include "SkSurface.h" class SkColorSpaceXformCanvas : public SkNoDrawCanvas { public: - SkColorSpaceXformCanvas(SkCanvas* target, + SkColorSpaceXformCanvas(SkCanvas* target, sk_sp<SkColorSpace> targetCS, std::unique_ptr<SkColorSpaceXformer> xformer) : SkNoDrawCanvas(SkIRect::MakeSize(target->getBaseLayerSize())) , fTarget(target) + , fTargetCS(targetCS) , fXformer(std::move(xformer)) { // Set the matrix and clip to match |fTarget|. Otherwise, we'll answer queries for @@ -131,7 +133,7 @@ public: const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) override { fTarget->drawImageRect(fXformer->apply(img).get(), - src ? *src : dst, dst, + src ? *src : SkRect::MakeIWH(img->width(), img->height()), dst, fXformer->apply(paint), constraint); } void onDrawImageNine(const SkImage* img, @@ -165,30 +167,45 @@ public: void onDrawBitmap(const SkBitmap& bitmap, SkScalar l, SkScalar t, const SkPaint* paint) override { - if (auto image = SkImage::MakeFromBitmap(bitmap)) { - this->onDrawImage(image.get(), l, t, paint); + if (this->skipXform(bitmap)) { + return fTarget->drawBitmap(bitmap, l, t, fXformer->apply(paint)); } + + fTarget->drawImage(fXformer->apply(bitmap).get(), l, t, fXformer->apply(paint)); } void onDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src, const SkRect& dst, const SkPaint* paint, SrcRectConstraint constraint) override { - if (auto image = SkImage::MakeFromBitmap(bitmap)) { - this->onDrawImageRect(image.get(), src, dst, paint, constraint); + if (this->skipXform(bitmap)) { + return fTarget->drawBitmapRect(bitmap, + src ? *src : SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, + fXformer->apply(paint), constraint); } + + fTarget->drawImageRect(fXformer->apply(bitmap).get(), + src ? *src : SkRect::MakeIWH(bitmap.width(), bitmap.height()), dst, + fXformer->apply(paint), constraint); } void onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, const SkRect& dst, const SkPaint* paint) override { - if (auto image = SkImage::MakeFromBitmap(bitmap)) { - this->onDrawImageNine(image.get(), center, dst, paint); + if (this->skipXform(bitmap)) { + return fTarget->drawBitmapNine(bitmap, center, dst, fXformer->apply(paint)); } + + fTarget->drawImageNine(fXformer->apply(bitmap).get(), center, dst, fXformer->apply(paint)); + } void onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattice, const SkRect& dst, const SkPaint* paint) override { - if (auto image = SkImage::MakeFromBitmap(bitmap)) { - this->onDrawImageLattice(image.get(), lattice, dst, paint); + if (this->skipXform(bitmap)) { + return fTarget->drawBitmapLattice(bitmap, lattice, dst, fXformer->apply(paint)); } + + + fTarget->drawImageLattice(fXformer->apply(bitmap).get(), lattice, dst, + fXformer->apply(paint)); } // TODO: May not be ideal to unfurl pictures. @@ -265,16 +282,24 @@ public: void onFlush() override { return fTarget->flush(); } private: + bool skipXform(const SkBitmap& bitmap) { + return (!bitmap.colorSpace() && fTargetCS->isSRGB()) || + (SkColorSpace::Equals(bitmap.colorSpace(), fTargetCS.get())) || + (kAlpha_8_SkColorType == bitmap.colorType()); + } + SkCanvas* fTarget; + sk_sp<SkColorSpace> fTargetCS; std::unique_ptr<SkColorSpaceXformer> fXformer; }; std::unique_ptr<SkCanvas> SkCreateColorSpaceXformCanvas(SkCanvas* target, sk_sp<SkColorSpace> targetCS) { - std::unique_ptr<SkColorSpaceXformer> xformer = SkColorSpaceXformer::Make(std::move(targetCS)); + std::unique_ptr<SkColorSpaceXformer> xformer = SkColorSpaceXformer::Make(targetCS); if (!xformer) { return nullptr; } - return skstd::make_unique<SkColorSpaceXformCanvas>(target, std::move(xformer)); + return skstd::make_unique<SkColorSpaceXformCanvas>(target, std::move(targetCS), + std::move(xformer)); } diff --git a/src/core/SkColorSpaceXformer.cpp b/src/core/SkColorSpaceXformer.cpp index e983756426..4d93fae327 100644 --- a/src/core/SkColorSpaceXformer.cpp +++ b/src/core/SkColorSpaceXformer.cpp @@ -11,6 +11,7 @@ #include "SkDrawLooper.h" #include "SkGradientShader.h" #include "SkImage_Base.h" +#include "SkImagePriv.h" #include "SkMakeUnique.h" std::unique_ptr<SkColorSpaceXformer> SkColorSpaceXformer::Make(sk_sp<SkColorSpace> dst) { @@ -30,6 +31,18 @@ sk_sp<SkImage> SkColorSpaceXformer::apply(const SkImage* src) { return as_IB(src)->makeColorSpace(fDst); } +sk_sp<SkImage> SkColorSpaceXformer::apply(const SkBitmap& src) { + sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(src, kNever_SkCopyPixelsMode); + if (!image) { + return nullptr; + } + + sk_sp<SkImage> xformed = as_IB(image)->makeColorSpace(fDst); + // We want to be sure we don't let the kNever_SkCopyPixelsMode image escape this stack frame. + SkASSERT(xformed != image); + return xformed; +} + void SkColorSpaceXformer::apply(SkColor* xformed, const SkColor* srgb, int n) { SkAssertResult(fFromSRGB->apply(SkColorSpaceXform::kBGRA_8888_ColorFormat, xformed, SkColorSpaceXform::kBGRA_8888_ColorFormat, srgb, diff --git a/src/core/SkColorSpaceXformer.h b/src/core/SkColorSpaceXformer.h index b89fd8a333..020051b97e 100644 --- a/src/core/SkColorSpaceXformer.h +++ b/src/core/SkColorSpaceXformer.h @@ -17,6 +17,7 @@ public: static std::unique_ptr<SkColorSpaceXformer> Make(sk_sp<SkColorSpace> dst); sk_sp<SkImage> apply(const SkImage* src); + sk_sp<SkImage> apply(const SkBitmap& bitmap); const SkPaint* apply(const SkPaint* src); const SkPaint& apply(const SkPaint& src); void apply(SkColor dst[], const SkColor src[], int n); |