diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/effects/SkToSRGBColorFilter.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrProcessor.cpp | 2 | ||||
-rw-r--r-- | src/gpu/GrProcessor.h | 1 | ||||
-rw-r--r-- | src/gpu/GrYUVProvider.cpp | 4 | ||||
-rw-r--r-- | src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp | 259 | ||||
-rw-r--r-- | src/gpu/effects/GrNonlinearColorSpaceXformEffect.h | 75 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 4 |
7 files changed, 7 insertions, 343 deletions
diff --git a/src/effects/SkToSRGBColorFilter.cpp b/src/effects/SkToSRGBColorFilter.cpp index 5831bf0b1a..a9bd65c625 100644 --- a/src/effects/SkToSRGBColorFilter.cpp +++ b/src/effects/SkToSRGBColorFilter.cpp @@ -13,7 +13,7 @@ #include "SkWriteBuffer.h" #if SK_SUPPORT_GPU - #include "effects/GrNonlinearColorSpaceXformEffect.h" + #include "GrColorSpaceXform.h" #endif void SkToSRGBColorFilter::onAppendStages(SkRasterPipeline* p, @@ -73,7 +73,6 @@ void SkToSRGBColorFilter::flatten(SkWriteBuffer& buffer) const { #if SK_SUPPORT_GPU std::unique_ptr<GrFragmentProcessor> SkToSRGBColorFilter::asFragmentProcessor( GrContext*, const GrColorSpaceInfo&) const { - return GrNonlinearColorSpaceXformEffect::Make(fSrcColorSpace.get(), - SkColorSpace::MakeSRGB().get()); + return GrColorSpaceXformEffect::Make(fSrcColorSpace.get(), SkColorSpace::MakeSRGB().get()); } #endif diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 561fd4fee8..f2b810252f 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -57,7 +57,7 @@ SkTArray<GrXPFactoryTestFactory*, true>* GrXPFactoryTestFactory::GetFactories() * we verify the count is as expected. If a new factory is added, then these numbers must be * manually adjusted. */ -static const int kFPFactoryCount = 38; +static const int kFPFactoryCount = 37; static const int kGPFactoryCount = 14; static const int kXPFactoryCount = 4; diff --git a/src/gpu/GrProcessor.h b/src/gpu/GrProcessor.h index 5d7fbd7a62..f8b336d9fb 100644 --- a/src/gpu/GrProcessor.h +++ b/src/gpu/GrProcessor.h @@ -120,7 +120,6 @@ public: kGrMatrixConvolutionEffect_ClassID, kGrMeshTestProcessor_ClassID, kGrMorphologyEffect_ClassID, - kGrNonlinearColorSpaceXformEffect_ClassID, kGrOverdrawFragmentProcessor_ClassID, kGrPathProcessor_ClassID, kGrPerlinNoise2Effect_ClassID, diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index 65dd46d71a..f235684f88 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -7,6 +7,7 @@ #include "GrYUVProvider.h" #include "GrClip.h" +#include "GrColorSpaceXform.h" #include "GrContext.h" #include "GrContextPriv.h" #include "GrProxyProvider.h" @@ -17,7 +18,6 @@ #include "SkRefCnt.h" #include "SkResourceCache.h" #include "SkYUVPlanesCache.h" -#include "effects/GrNonlinearColorSpaceXformEffect.h" #include "effects/GrSRGBEffect.h" #include "effects/GrYUVtoRGBEffect.h" @@ -143,7 +143,7 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS // If the caller expects the pixels in a different color space than the one from the image, // apply a color conversion to do this. std::unique_ptr<GrFragmentProcessor> colorConversionProcessor = - GrNonlinearColorSpaceXformEffect::Make(srcColorSpace, dstColorSpace); + GrColorSpaceXformEffect::Make(srcColorSpace, dstColorSpace); if (colorConversionProcessor) { paint.addColorFragmentProcessor(std::move(colorConversionProcessor)); } diff --git a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp deleted file mode 100644 index cec9da3590..0000000000 --- a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/* - * 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 "GrNonlinearColorSpaceXformEffect.h" -#include "GrColorSpaceXform.h" -#include "GrProcessor.h" -#include "glsl/GrGLSLFragmentProcessor.h" -#include "glsl/GrGLSLFragmentShaderBuilder.h" - -class GrGLNonlinearColorSpaceXformEffect : public GrGLSLFragmentProcessor { -public: - void emitCode(EmitArgs& args) override { - const GrNonlinearColorSpaceXformEffect& csxe = - args.fFp.cast<GrNonlinearColorSpaceXformEffect>(); - GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder; - GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; - - const char* srcCoeffsName = nullptr; - if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kSrcTransfer_Op)) { - fSrcTransferFnUni = uniformHandler->addUniformArray( - kFragment_GrShaderFlag, kHalf_GrSLType, "SrcTransferFn", - GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, &srcCoeffsName); - } - - const char* dstCoeffsName = nullptr; - if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kDstTransfer_Op)) { - fDstTransferFnUni = uniformHandler->addUniformArray( - kFragment_GrShaderFlag, kHalf_GrSLType, "DstTransferFn", - GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, &dstCoeffsName); - } - - const char* gamutXformName = nullptr; - if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kGamutXform_Op)) { - fGamutXformUni = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4x4_GrSLType, - "GamutXform", &gamutXformName); - } - - // Helper function to apply the src or dst transfer function to a single value - SkString tfFuncNames[2]; - for (size_t i = 0; i < 2; ++i) { - const char* coeffsName = i ? dstCoeffsName : srcCoeffsName; - if (!coeffsName) { - continue; - } - const char* fnName = i ? "dst_transfer_fn" : "src_transfer_fn"; - static const GrShaderVar gTransferFnFuncArgs[] = { - GrShaderVar("x", kHalf_GrSLType), - }; - SkString transferFnBody; - // Temporaries to make evaluation line readable - transferFnBody.printf("half A = %s[0];", coeffsName); - transferFnBody.appendf("half B = %s[1];", coeffsName); - transferFnBody.appendf("half C = %s[2];", coeffsName); - transferFnBody.appendf("half D = %s[3];", coeffsName); - transferFnBody.appendf("half E = %s[4];", coeffsName); - transferFnBody.appendf("half F = %s[5];", coeffsName); - transferFnBody.appendf("half G = %s[6];", coeffsName); - transferFnBody.append("half s = sign(x);"); - transferFnBody.append("x = abs(x);"); - transferFnBody.appendf("return s * ((x < D) ? (C * x) + F : pow(A * x + B, G) + E);"); - fragBuilder->emitFunction(kHalf_GrSLType, fnName, SK_ARRAY_COUNT(gTransferFnFuncArgs), - gTransferFnFuncArgs, transferFnBody.c_str(), &tfFuncNames[i]); - } - - if (nullptr == args.fInputColor) { - args.fInputColor = "half4(1)"; - } - fragBuilder->codeAppendf("half4 color = %s;", args.fInputColor); - - // 1: Un-premultiply the input color (if necessary) - fragBuilder->codeAppendf("half nonZeroAlpha = max(color.a, 0.00001);"); - fragBuilder->codeAppendf("color = half4(color.rgb / nonZeroAlpha, nonZeroAlpha);"); - - // 2: Apply src transfer function (to get to linear RGB) - if (srcCoeffsName) { - fragBuilder->codeAppendf("color.r = %s(color.r);", tfFuncNames[0].c_str()); - fragBuilder->codeAppendf("color.g = %s(color.g);", tfFuncNames[0].c_str()); - fragBuilder->codeAppendf("color.b = %s(color.b);", tfFuncNames[0].c_str()); - } - - // 3: Apply gamut matrix - if (gamutXformName) { - fragBuilder->codeAppendf( - "color.rgb = (%s * half4(color.rgb, 1.0)).rgb;", gamutXformName); - } - - // 4: Apply dst transfer fn - if (dstCoeffsName) { - fragBuilder->codeAppendf("color.r = %s(color.r);", tfFuncNames[1].c_str()); - fragBuilder->codeAppendf("color.g = %s(color.g);", tfFuncNames[1].c_str()); - fragBuilder->codeAppendf("color.b = %s(color.b);", tfFuncNames[1].c_str()); - } - - // 5: Premultiply again - fragBuilder->codeAppendf("%s = half4(color.rgb * color.a, color.a);", args.fOutputColor); - } - - static inline void GenKey(const GrProcessor& processor, const GrShaderCaps&, - GrProcessorKeyBuilder* b) { - const GrNonlinearColorSpaceXformEffect& csxe = - processor.cast<GrNonlinearColorSpaceXformEffect>(); - b->add32(csxe.ops()); - } - -protected: - void onSetData(const GrGLSLProgramDataManager& pdman, - const GrFragmentProcessor& processor) override { - const GrNonlinearColorSpaceXformEffect& csxe = - processor.cast<GrNonlinearColorSpaceXformEffect>(); - if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kSrcTransfer_Op)) { - pdman.set1fv(fSrcTransferFnUni, GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, - csxe.srcTransferFnCoeffs()); - } - if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kDstTransfer_Op)) { - pdman.set1fv(fDstTransferFnUni, GrNonlinearColorSpaceXformEffect::kNumTransferFnCoeffs, - csxe.dstTransferFnCoeffs()); - } - if (SkToBool(csxe.ops() & GrNonlinearColorSpaceXformEffect::kGamutXform_Op)) { - pdman.setSkMatrix44(fGamutXformUni, csxe.gamutXform()); - } - } - -private: - GrGLSLProgramDataManager::UniformHandle fSrcTransferFnUni; - GrGLSLProgramDataManager::UniformHandle fDstTransferFnUni; - GrGLSLProgramDataManager::UniformHandle fGamutXformUni; - - typedef GrGLSLFragmentProcessor INHERITED; -}; - -/////////////////////////////////////////////////////////////////////////////// - -GrNonlinearColorSpaceXformEffect::GrNonlinearColorSpaceXformEffect( - uint32_t ops, const SkColorSpaceTransferFn& srcTransferFn, - const SkColorSpaceTransferFn& dstTransferFn, const SkMatrix44& gamutXform) - : INHERITED(kGrNonlinearColorSpaceXformEffect_ClassID, - kPreservesOpaqueInput_OptimizationFlag) - , fGamutXform(gamutXform) - , fOps(ops) { - - fSrcTransferFnCoeffs[0] = srcTransferFn.fA; - fSrcTransferFnCoeffs[1] = srcTransferFn.fB; - fSrcTransferFnCoeffs[2] = srcTransferFn.fC; - fSrcTransferFnCoeffs[3] = srcTransferFn.fD; - fSrcTransferFnCoeffs[4] = srcTransferFn.fE; - fSrcTransferFnCoeffs[5] = srcTransferFn.fF; - fSrcTransferFnCoeffs[6] = srcTransferFn.fG; - - fDstTransferFnCoeffs[0] = dstTransferFn.fA; - fDstTransferFnCoeffs[1] = dstTransferFn.fB; - fDstTransferFnCoeffs[2] = dstTransferFn.fC; - fDstTransferFnCoeffs[3] = dstTransferFn.fD; - fDstTransferFnCoeffs[4] = dstTransferFn.fE; - fDstTransferFnCoeffs[5] = dstTransferFn.fF; - fDstTransferFnCoeffs[6] = dstTransferFn.fG; -} - -GrNonlinearColorSpaceXformEffect::GrNonlinearColorSpaceXformEffect( - const GrNonlinearColorSpaceXformEffect& that) - : INHERITED(kGrNonlinearColorSpaceXformEffect_ClassID, - kPreservesOpaqueInput_OptimizationFlag) - , fGamutXform(that.fGamutXform) - , fOps(that.fOps) { - memcpy(fSrcTransferFnCoeffs, that.fSrcTransferFnCoeffs, sizeof(fSrcTransferFnCoeffs)); - memcpy(fDstTransferFnCoeffs, that.fDstTransferFnCoeffs, sizeof(fDstTransferFnCoeffs)); -} - -std::unique_ptr<GrFragmentProcessor> GrNonlinearColorSpaceXformEffect::clone() const { - return std::unique_ptr<GrFragmentProcessor>(new GrNonlinearColorSpaceXformEffect(*this)); -} - -bool GrNonlinearColorSpaceXformEffect::onIsEqual(const GrFragmentProcessor& s) const { - const GrNonlinearColorSpaceXformEffect& other = s.cast<GrNonlinearColorSpaceXformEffect>(); - if (other.fOps != fOps) { - return false; - } - if (SkToBool(fOps & kSrcTransfer_Op) && - memcmp(&other.fSrcTransferFnCoeffs, &fSrcTransferFnCoeffs, sizeof(fSrcTransferFnCoeffs))) { - return false; - } - if (SkToBool(fOps & kDstTransfer_Op) && - memcmp(&other.fDstTransferFnCoeffs, &fDstTransferFnCoeffs, sizeof(fDstTransferFnCoeffs))) { - return false; - } - if (SkToBool(fOps & kGamutXform_Op) && other.fGamutXform != fGamutXform) { - return false; - } - return true; -} - -/////////////////////////////////////////////////////////////////////////////// - -GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrNonlinearColorSpaceXformEffect); - -#if GR_TEST_UTILS -std::unique_ptr<GrFragmentProcessor> GrNonlinearColorSpaceXformEffect::TestCreate( - GrProcessorTestData* d) { - // TODO: Generate a random variety of color spaces for this effect (it can handle wacky - // transfer functions, etc...) - sk_sp<SkColorSpace> srcSpace = SkColorSpace::MakeSRGBLinear(); - sk_sp<SkColorSpace> dstSpace = SkColorSpace::MakeSRGB(); - return GrNonlinearColorSpaceXformEffect::Make(srcSpace.get(), dstSpace.get()); -} -#endif - -/////////////////////////////////////////////////////////////////////////////// - -void GrNonlinearColorSpaceXformEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, - GrProcessorKeyBuilder* b) const { - GrGLNonlinearColorSpaceXformEffect::GenKey(*this, caps, b); -} - -GrGLSLFragmentProcessor* GrNonlinearColorSpaceXformEffect::onCreateGLSLInstance() const { - return new GrGLNonlinearColorSpaceXformEffect(); -} - -std::unique_ptr<GrFragmentProcessor> GrNonlinearColorSpaceXformEffect::Make(SkColorSpace* src, - SkColorSpace* dst) { - if (!src || !dst || SkColorSpace::Equals(src, dst)) { - // No conversion possible (or necessary) - return nullptr; - } - - uint32_t ops = 0; - - const SkMatrix44* toXYZ = src->toXYZD50(); - const SkMatrix44* fromXYZ = dst->fromXYZD50(); - SkMatrix44 srcToDstMtx(SkMatrix44::kUninitialized_Constructor); - if (toXYZ && fromXYZ && src->toXYZD50Hash() != dst->toXYZD50Hash()) { - srcToDstMtx.setConcat(*fromXYZ, *toXYZ); - ops |= kGamutXform_Op; - } - - SkColorSpaceTransferFn srcTransferFn; - if (!src->gammaIsLinear()) { - if (src->isNumericalTransferFn(&srcTransferFn)) { - ops |= kSrcTransfer_Op; - } else { - return nullptr; - } - } - - SkColorSpaceTransferFn dstTransferFn; - if (!dst->gammaIsLinear()) { - if (dst->isNumericalTransferFn(&dstTransferFn)) { - dstTransferFn = dstTransferFn.invert(); - ops |= kDstTransfer_Op; - } else { - return nullptr; - } - } - - return std::unique_ptr<GrFragmentProcessor>( - new GrNonlinearColorSpaceXformEffect(ops, srcTransferFn, dstTransferFn, srcToDstMtx)); -} diff --git a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.h b/src/gpu/effects/GrNonlinearColorSpaceXformEffect.h deleted file mode 100644 index 6dfb778071..0000000000 --- a/src/gpu/effects/GrNonlinearColorSpaceXformEffect.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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 GrNonlinearColorSpaceXformEffect_DEFINED -#define GrNonlinearColorSpaceXformEffect_DEFINED - -#include "GrFragmentProcessor.h" -#include "SkColorSpace.h" -#include "SkMatrix44.h" - -/** - * The output of this effect is the input, transformed into a different color space. - * This effect is used for nonlinear blending color space support - it does not assume HW sRGB - * capabilities, and performs both the source and destination transfer functions numerically in - * the shader. Any parametric transfer function is supported. Because of the nonlinear blending, - * premultiplication is also nonlinear - source pixels are unpremultiplied before the source - * transfer function, and then premultiplied after the destination transfer function. - */ -class GrNonlinearColorSpaceXformEffect : public GrFragmentProcessor { -public: - /** - * The conversion effect is only well defined with a valid source and destination color space. - * This will return nullptr if either space is nullptr, if both spaces are equal, or if either - * space has a non-parametric transfer funcion (e.g. lookup table or A2B). - */ - static std::unique_ptr<GrFragmentProcessor> Make(SkColorSpace* src, SkColorSpace* dst); - - const char* name() const override { return "NonlinearColorSpaceXform"; } - - std::unique_ptr<GrFragmentProcessor> clone() const override; - - static const int kNumTransferFnCoeffs = 7; - - /** - * Flags that specify which operations are performed for one particular conversion. - * Some color space pairs may not need all operations, if one or both transfer functions - * is linear, or if the gamuts are the same. - */ - enum Ops { - kSrcTransfer_Op = 0x1, - kGamutXform_Op = 0x2, - kDstTransfer_Op = 0x4, - }; - - uint32_t ops() const { return fOps; } - const float* srcTransferFnCoeffs() const { return fSrcTransferFnCoeffs; } - const float* dstTransferFnCoeffs() const { return fDstTransferFnCoeffs; } - const SkMatrix44& gamutXform() const { return fGamutXform; } - -private: - GrNonlinearColorSpaceXformEffect(uint32_t ops, - const SkColorSpaceTransferFn& srcTransferFn, - const SkColorSpaceTransferFn& dstTransferFn, - const SkMatrix44& gamutXform); - GrNonlinearColorSpaceXformEffect(const GrNonlinearColorSpaceXformEffect&); - - GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; - void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override; - bool onIsEqual(const GrFragmentProcessor&) const override; - - float fSrcTransferFnCoeffs[kNumTransferFnCoeffs]; - float fDstTransferFnCoeffs[kNumTransferFnCoeffs]; - SkMatrix44 fGamutXform; - uint32_t fOps; - - GR_DECLARE_FRAGMENT_PROCESSOR_TEST - - typedef GrFragmentProcessor INHERITED; -}; - -#endif diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index faba37383c..b13abe1d45 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -15,6 +15,7 @@ #include "GrAHardwareBufferImageGenerator.h" #include "GrBitmapTextureMaker.h" #include "GrCaps.h" +#include "GrColorSpaceXform.h" #include "GrContext.h" #include "GrContextPriv.h" #include "GrGpu.h" @@ -30,7 +31,6 @@ #include "GrTextureProxy.h" #include "GrTextureProxyPriv.h" #include "gl/GrGLDefines.h" -#include "effects/GrNonlinearColorSpaceXformEffect.h" #include "effects/GrYUVtoRGBEffect.h" #include "SkCanvas.h" #include "SkBitmapCache.h" @@ -974,7 +974,7 @@ sk_sp<SkImage> SkImage_Gpu::onMakeColorSpace(sk_sp<SkColorSpace> target, SkColor srcSpace = SkColorSpace::MakeSRGB(); } - auto xform = GrNonlinearColorSpaceXformEffect::Make(srcSpace.get(), target.get()); + auto xform = GrColorSpaceXformEffect::Make(srcSpace.get(), target.get()); if (!xform) { return sk_ref_sp(const_cast<SkImage_Gpu*>(this)); } |