aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Matt Sarett <msarett@google.com>2017-06-06 10:11:34 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-06 14:34:03 +0000
commit3928ff8e0b617c3a00eee1963bc31ce5470fba6d (patch)
tree98bbe9e51b3316c175a8b1ffe1063877ca84eb55 /src
parent1608a1dd17187aeeada376e710ecfafb1e229af2 (diff)
Create an SkColorSpaceXform image generator
This should be immediately useful in the Skia-Android rendering pipeline. Possible future uses include creating a "renderable" SkImage from a bitmap with a funny color space. Inspired by: https://skia-review.googlesource.com/c/13981/ Bug: b/62347704 Change-Id: I388c7af1fc43834b8ad22022d0caf3ac90b734c8 Reviewed-on: https://skia-review.googlesource.com/18598 Reviewed-by: Mike Reed <reed@google.com> Commit-Queue: Matt Sarett <msarett@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/SkBitmap.cpp4
-rw-r--r--src/core/SkColorSpaceXformImageGenerator.cpp96
-rw-r--r--src/core/SkColorSpaceXformImageGenerator.h40
-rw-r--r--src/core/SkPixmap.cpp6
4 files changed, 141 insertions, 5 deletions
diff --git a/src/core/SkBitmap.cpp b/src/core/SkBitmap.cpp
index 72cac7cc9c..e88fa5ec57 100644
--- a/src/core/SkBitmap.cpp
+++ b/src/core/SkBitmap.cpp
@@ -512,12 +512,12 @@ bool SkBitmap::extractSubset(SkBitmap* result, const SkIRect& subset) const {
///////////////////////////////////////////////////////////////////////////////
bool SkBitmap::readPixels(const SkImageInfo& requestedDstInfo, void* dstPixels, size_t dstRB,
- int x, int y) const {
+ int x, int y, SkTransferFunctionBehavior behavior) const {
SkPixmap src;
if (!this->peekPixels(&src)) {
return false;
}
- return src.readPixels(requestedDstInfo, dstPixels, dstRB, x, y);
+ return src.readPixels(requestedDstInfo, dstPixels, dstRB, x, y, behavior);
}
bool SkBitmap::readPixels(const SkPixmap& dst, int srcX, int srcY) const {
diff --git a/src/core/SkColorSpaceXformImageGenerator.cpp b/src/core/SkColorSpaceXformImageGenerator.cpp
new file mode 100644
index 0000000000..d9bec78035
--- /dev/null
+++ b/src/core/SkColorSpaceXformImageGenerator.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkColorSpaceXformImageGenerator.h"
+
+std::unique_ptr<SkImageGenerator> SkColorSpaceXformImageGenerator::Make(
+ const SkBitmap& src, sk_sp<SkColorSpace> dst, SkCopyPixelsMode mode) {
+ if (!dst) {
+ return nullptr;
+ }
+
+ const SkBitmap* srcPtr = &src;
+ SkBitmap copy;
+ if (kAlways_SkCopyPixelsMode == mode ||
+ (kNever_SkCopyPixelsMode != mode && !src.isImmutable())) {
+ if (!copy.tryAllocPixels(src.info())) {
+ return nullptr;
+ }
+
+ SkAssertResult(src.readPixels(copy.info(), copy.getPixels(), copy.rowBytes(), 0, 0));
+ copy.setImmutable();
+ srcPtr = &copy;
+ }
+
+
+ return std::unique_ptr<SkImageGenerator>(
+ new SkColorSpaceXformImageGenerator(*srcPtr, std::move(dst)));
+}
+
+SkColorSpaceXformImageGenerator::SkColorSpaceXformImageGenerator(const SkBitmap& src,
+ sk_sp<SkColorSpace> dst)
+ : INHERITED(src.info().makeColorSpace(dst), kNeedNewImageUniqueID)
+ , fSrc(src)
+ , fDst(dst)
+{}
+
+bool SkColorSpaceXformImageGenerator::onGetPixels(const SkImageInfo& info, void* pixels,
+ size_t rowBytes, const Options& opts) {
+ SkImageInfo dstInfo = info;
+ if (!info.colorSpace()) {
+ dstInfo = dstInfo.makeColorSpace(fDst);
+ }
+ return fSrc.readPixels(dstInfo, pixels, rowBytes, 0, 0, opts.fBehavior);
+}
+
+#if SK_SUPPORT_GPU
+
+#include "GrClip.h"
+#include "GrContext.h"
+#include "GrPaint.h"
+#include "GrRenderTargetContext.h"
+#include "GrTextureProxy.h"
+#include "SkGr.h"
+#include "effects/GrNonlinearColorSpaceXformEffect.h"
+
+sk_sp<GrTextureProxy> SkColorSpaceXformImageGenerator::onGenerateTexture(GrContext* ctx,
+ const SkImageInfo& info,
+ const SkIPoint& origin) {
+ // FIXME:
+ // This always operates as if SkTranferFunctionBehavior is kIgnore. Should we add
+ // options so that caller can also request kRespect?
+
+ SkASSERT(ctx);
+
+ sk_sp<GrTextureProxy> proxy =
+ GrUploadBitmapToTextureProxy(ctx->resourceProvider(), fSrc, nullptr);
+
+ sk_sp<SkColorSpace> srcSpace =
+ fSrc.colorSpace() ? sk_ref_sp(fSrc.colorSpace()) : SkColorSpace::MakeSRGB();
+ auto xform = GrNonlinearColorSpaceXformEffect::Make(srcSpace.get(), fDst.get());
+ if (!xform) {
+ return nullptr;
+ }
+
+ sk_sp<GrRenderTargetContext> renderTargetContext = ctx->makeDeferredRenderTargetContext(
+ SkBackingFit::kExact, fSrc.width(), fSrc.height(), kRGBA_8888_GrPixelConfig, nullptr);
+ if (!renderTargetContext) {
+ return nullptr;
+ }
+
+ GrPaint paint;
+ paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
+ paint.addColorTextureProcessor(ctx->resourceProvider(), proxy, nullptr,
+ SkMatrix::MakeTrans(origin.fX, origin.fY));
+ paint.addColorFragmentProcessor(std::move(xform));
+
+ const SkRect rect = SkRect::MakeWH(info.width(), info.height());
+ renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
+ return sk_ref_sp(renderTargetContext->asTextureProxy());
+}
+
+#endif
diff --git a/src/core/SkColorSpaceXformImageGenerator.h b/src/core/SkColorSpaceXformImageGenerator.h
new file mode 100644
index 0000000000..29bf85bff9
--- /dev/null
+++ b/src/core/SkColorSpaceXformImageGenerator.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkColorSpaceXformImageGenerator_DEFINED
+#define SkColorSpaceXformImageGenerator_DEFINED
+
+#include "SkImageGenerator.h"
+#include "SkImagePriv.h"
+
+class SkColorSpaceXformImageGenerator : public SkImageGenerator {
+public:
+
+ static std::unique_ptr<SkImageGenerator> Make(
+ const SkBitmap& src, sk_sp<SkColorSpace> dst, SkCopyPixelsMode);
+
+protected:
+ bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+ const Options& opts) override;
+
+#if SK_SUPPORT_GPU
+ sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
+ const SkIPoint&) override;
+#endif
+
+private:
+ SkBitmap fSrc;
+ sk_sp<SkColorSpace> fDst;
+
+ SkColorSpaceXformImageGenerator(const SkBitmap& src, sk_sp<SkColorSpace> dst);
+
+ friend class SkImageGenerator;
+
+ typedef SkImageGenerator INHERITED;
+};
+
+#endif // SkColorSpaceXformImageGenerator_DEFINED
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index 02090b77c6..6425b29f92 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -74,8 +74,8 @@ bool SkPixmap::extractSubset(SkPixmap* result, const SkIRect& subset) const {
return true;
}
-bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, int x, int y)
-const {
+bool SkPixmap::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB, int x, int y,
+ SkTransferFunctionBehavior behavior) const {
if (!SkImageInfoValidConversion(dstInfo, fInfo)) {
return false;
}
@@ -88,7 +88,7 @@ const {
const void* srcPixels = this->addr(rec.fX, rec.fY);
const SkImageInfo srcInfo = fInfo.makeWH(rec.fInfo.width(), rec.fInfo.height());
SkConvertPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, srcInfo, srcPixels, this->rowBytes(),
- this->ctable(), SkTransferFunctionBehavior::kRespect);
+ this->ctable(), behavior);
return true;
}