/* * 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 SkColorSpaceXformImageGenerator::Make( const SkBitmap& src, sk_sp dst, SkCopyPixelsMode mode) { return SkColorSpaceXformImageGenerator::Make(src, dst, mode, kNeedNewImageUniqueID); } std::unique_ptr SkColorSpaceXformImageGenerator::Make( const SkBitmap& src, sk_sp dst, SkCopyPixelsMode mode, uint32_t id) { 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 = © } return std::unique_ptr( new SkColorSpaceXformImageGenerator(*srcPtr, std::move(dst), id)); } SkColorSpaceXformImageGenerator::SkColorSpaceXformImageGenerator(const SkBitmap& src, sk_sp dst, uint32_t id) : INHERITED(src.info().makeColorSpace(dst), id) , fSrc(src) , fDst(std::move(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 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 proxy = GrUploadBitmapToTextureProxy(ctx->resourceProvider(), fSrc, nullptr); sk_sp srcSpace = fSrc.colorSpace() ? sk_ref_sp(fSrc.colorSpace()) : SkColorSpace::MakeSRGB(); auto xform = GrNonlinearColorSpaceXformEffect::Make(srcSpace.get(), fDst.get()); if (!xform) { return nullptr; } sk_sp 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