From 54f30c13fc0a5d89797fc9be5f0fb1050d96b6f4 Mon Sep 17 00:00:00 2001 From: brianosman Date: Mon, 18 Jul 2016 10:53:52 -0700 Subject: [PATCH] Introduce GrColorSpaceXform, for gamut conversion on textures GrTextureAccess optionally includes an instance, computed from the src and dst color spaces. In all common cases (no color space for either src or dst, or same color space for both), no object is allocated. This change is orthogonal to my attempts to get color space attached to render targets - regardless of how we choose to do that, this will give us the source color space at all points where we are connecting src to dst. There are many dangling injection points where I've been inserting nullptr, but I have a record of all of them. Additionally, there are now three places (the most common simple paths for bitmap/image rendering) where things are plumbed enough that I expect to have access to the dst color space (all marked with XFORMTODO). In addition to getting the dst color space, I need to inject shader code and uniform uploading for appendTextureLookup and friends. BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2154753003 Review-Url: https://codereview.chromium.org/2154753003 --- gm/texdata.cpp | 2 +- gm/texturedomaineffect.cpp | 2 +- gyp/gpu.gypi | 3 ++ include/gpu/GrColorSpaceXform.h | 31 ++++++++++++++ include/gpu/GrPaint.h | 6 ++- src/core/SkBitmapProcShader.cpp | 8 ++-- src/effects/SkBlurMaskFilter.cpp | 2 +- src/effects/SkGpuBlurUtils.cpp | 5 ++- src/effects/SkLightingImageFilter.cpp | 2 +- src/effects/SkMagnifierImageFilter.cpp | 2 +- src/effects/SkXfermodeImageFilter.cpp | 4 +- src/gpu/GrBlurUtils.cpp | 2 +- src/gpu/GrClipMaskManager.cpp | 1 + src/gpu/GrColorSpaceXform.cpp | 58 +++++++++++++++++++++++++++ src/gpu/GrContext.cpp | 2 +- src/gpu/GrPaint.cpp | 18 ++++++--- src/gpu/GrPipelineBuilder.h | 10 +++-- src/gpu/GrSWMaskHelper.cpp | 1 + src/gpu/GrTextureParamsAdjuster.cpp | 32 ++++++++++----- src/gpu/GrTextureToYUVPlanes.cpp | 2 +- src/gpu/SkGpuDevice.cpp | 18 ++++++--- src/gpu/effects/Gr1DKernelEffect.h | 2 +- src/gpu/effects/GrBicubicEffect.cpp | 37 ++++++++++++----- src/gpu/effects/GrBicubicEffect.h | 42 ++++++++++++------- src/gpu/effects/GrConfigConversionEffect.cpp | 4 +- src/gpu/effects/GrMatrixConvolutionEffect.cpp | 2 +- src/gpu/effects/GrSimpleTextureEffect.cpp | 2 +- src/gpu/effects/GrSimpleTextureEffect.h | 18 ++++++--- src/gpu/effects/GrSingleTextureEffect.cpp | 12 ++++-- src/gpu/effects/GrSingleTextureEffect.h | 10 +++-- src/gpu/effects/GrTextureDomain.cpp | 10 +++-- src/gpu/effects/GrTextureDomain.h | 2 + src/gpu/glsl/GrGLSLColorSpaceXformHelper.h | 39 ++++++++++++++++++ src/image/SkImageShader.cpp | 4 +- tests/SRGBMipMapTest.cpp | 2 +- tools/gpu/GrTest.cpp | 2 +- 36 files changed, 310 insertions(+), 89 deletions(-) create mode 100644 include/gpu/GrColorSpaceXform.h create mode 100644 src/gpu/GrColorSpaceXform.cpp create mode 100644 src/gpu/glsl/GrGLSLColorSpaceXformHelper.h diff --git a/gm/texdata.cpp b/gm/texdata.cpp index 01eedec..4cad113 100644 --- a/gm/texdata.cpp +++ b/gm/texdata.cpp @@ -98,7 +98,7 @@ DEF_SIMPLE_GM_BG(texdata, canvas, 2 * S, 2 * S, SK_ColorBLACK) { SkMatrix tm; tm = vm; tm.postIDiv(2*S, 2*S); - paint.addColorTextureProcessor(texture, tm); + paint.addColorTextureProcessor(texture, nullptr, tm); drawContext->drawRect(clip, paint, vm, SkRect::MakeWH(2*S, 2*S)); diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp index 3680006..ba574b6 100644 --- a/gm/texturedomaineffect.cpp +++ b/gm/texturedomaineffect.cpp @@ -115,7 +115,7 @@ protected: GrPaint grPaint; grPaint.setXPFactory(GrPorterDuffXPFactory::Make(SkXfermode::kSrc_Mode)); sk_sp fp( - GrTextureDomainEffect::Make(texture, textureMatrices[tm], + GrTextureDomainEffect::Make(texture, nullptr, textureMatrices[tm], GrTextureDomain::MakeTexelDomain(texture, texelDomains[d]), mode, GrTextureParams::kNone_FilterMode)); diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index e6f5f16..52830bf 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -18,6 +18,7 @@ '<(skia_include_path)/gpu/GrCaps.h', '<(skia_include_path)/gpu/GrClip.h', '<(skia_include_path)/gpu/GrColor.h', + '<(skia_include_path)/gpu/GrColorSpaceXform.h', '<(skia_include_path)/gpu/GrConfig.h', '<(skia_include_path)/gpu/GrContextOptions.h', '<(skia_include_path)/gpu/GrContext.h', @@ -85,6 +86,7 @@ '<(skia_src_path)/gpu/GrClip.cpp', '<(skia_src_path)/gpu/GrClipMaskManager.h', '<(skia_src_path)/gpu/GrClipMaskManager.cpp', + '<(skia_src_path)/gpu/GrColorSpaceXform.cpp', '<(skia_src_path)/gpu/GrContext.cpp', '<(skia_src_path)/gpu/GrCoordTransform.cpp', '<(skia_src_path)/gpu/GrDefaultGeoProcFactory.cpp', @@ -395,6 +397,7 @@ '<(skia_src_path)/gpu/glsl/GrGLSLBlend.h', '<(skia_src_path)/gpu/glsl/GrGLSLCaps.cpp', '<(skia_src_path)/gpu/glsl/GrGLSLCaps.h', + '<(skia_src_path)/gpu/glsl/GrGLSLColorSpaceXformHelper.h', '<(skia_src_path)/gpu/glsl/GrGLSLFragmentProcessor.cpp', '<(skia_src_path)/gpu/glsl/GrGLSLFragmentProcessor.h', '<(skia_src_path)/gpu/glsl/GrGLSLFragmentShaderBuilder.cpp', diff --git a/include/gpu/GrColorSpaceXform.h b/include/gpu/GrColorSpaceXform.h new file mode 100644 index 0000000..ea90739 --- /dev/null +++ b/include/gpu/GrColorSpaceXform.h @@ -0,0 +1,31 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrColorSpaceXform_DEFINED +#define GrColorSpaceXform_DEFINED + +#include "SkMatrix44.h" +#include "SkRefCnt.h" + +class SkColorSpace; + + /** + * Represents a color gamut transformation (as a 4x4 color matrix) + */ +class GrColorSpaceXform : public SkRefCnt { +public: + GrColorSpaceXform(const SkMatrix44& srcToDst) : fSrcToDst(srcToDst) {} + + static sk_sp Make(SkColorSpace* src, SkColorSpace* dst); + + const SkMatrix44& srcToDst() { return fSrcToDst; } + +private: + SkMatrix44 fSrcToDst; +}; + +#endif diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h index 70067ae..8be1d50 100644 --- a/include/gpu/GrPaint.h +++ b/include/gpu/GrPaint.h @@ -11,6 +11,7 @@ #define GrPaint_DEFINED #include "GrColor.h" +#include "GrColorSpaceXform.h" #include "GrXferProcessor.h" #include "effects/GrPorterDuffXferProcessor.h" #include "GrFragmentProcessor.h" @@ -115,9 +116,10 @@ public: * Helpers for adding color or coverage effects that sample a texture. The matrix is applied * to the src space position to compute texture coordinates. */ - void addColorTextureProcessor(GrTexture*, const SkMatrix&); + void addColorTextureProcessor(GrTexture*, sk_sp, const SkMatrix&); void addCoverageTextureProcessor(GrTexture*, const SkMatrix&); - void addColorTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&); + void addColorTextureProcessor(GrTexture*, sk_sp, const SkMatrix&, + const GrTextureParams&); void addCoverageTextureProcessor(GrTexture*, const SkMatrix&, const GrTextureParams&); int numColorFragmentProcessors() const { return fColorFragmentProcessors.count(); } diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index b2dee0b..8fad0b1 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -460,12 +460,14 @@ sk_sp SkBitmapProcShader::asFragmentProcessor(GrContext* co "Couldn't convert bitmap to texture."); return nullptr; } - + SkColorSpace* dstColorSpace = nullptr; // XFORMTODO + sk_sp colorSpaceXform = GrColorSpaceXform::Make(fRawBitmap.colorSpace(), + dstColorSpace); sk_sp inner; if (doBicubic) { - inner = GrBicubicEffect::Make(texture, matrix, tm); + inner = GrBicubicEffect::Make(texture, std::move(colorSpaceXform), matrix, tm); } else { - inner = GrSimpleTextureEffect::Make(texture, matrix, params); + inner = GrSimpleTextureEffect::Make(texture, std::move(colorSpaceXform), matrix, params); } if (kAlpha_8_SkColorType == fRawBitmap.colorType()) { diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index 6a20d48..b7893c5 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -1260,7 +1260,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, SkMatrix matrix; matrix.setIDiv(src->width(), src->height()); // Blend pathTexture over blurTexture. - paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(src, matrix)); + paint.addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(src, nullptr, matrix)); if (kInner_SkBlurStyle == fBlurStyle) { // inner: dst = dst * src paint.setCoverageSetOpXPFactory(SkRegion::kIntersect_Op); diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp index 9bc1265..f0f684d 100644 --- a/src/effects/SkGpuBlurUtils.cpp +++ b/src/effects/SkGpuBlurUtils.cpp @@ -275,6 +275,7 @@ sk_sp GaussianBlur(GrContext* context, (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height() : 0.0f); sk_sp fp(GrTextureDomainEffect::Make( srcTexture.get(), + nullptr, matrix, domain, GrTextureDomain::kDecal_Mode, @@ -284,7 +285,7 @@ sk_sp GaussianBlur(GrContext* context, srcOffset.set(0, 0); } else { GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); - paint.addColorTextureProcessor(srcTexture.get(), matrix, params); + paint.addColorTextureProcessor(srcTexture.get(), nullptr, matrix, params); } paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); shrink_irect_by_2(&dstRect, i < scaleFactorX, i < scaleFactorY); @@ -361,7 +362,7 @@ sk_sp GaussianBlur(GrContext* context, // FIXME: this should be mitchell, not bilinear. GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); sk_sp tex(srcDrawContext->asTexture()); - paint.addColorTextureProcessor(tex.get(), matrix, params); + paint.addColorTextureProcessor(tex.get(), nullptr, matrix, params); paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); SkIRect dstRect(srcRect); diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index 8bf4077..71503b5 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -1699,7 +1699,7 @@ GrLightingEffect::GrLightingEffect(GrTexture* texture, const SkMatrix& matrix, BoundaryMode boundaryMode, const SkIRect* srcBounds) - : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) + : INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) , fLight(light) , fSurfaceScale(surfaceScale) , fFilterMatrix(matrix) diff --git a/src/effects/SkMagnifierImageFilter.cpp b/src/effects/SkMagnifierImageFilter.cpp index cc2d243..aebbad8 100644 --- a/src/effects/SkMagnifierImageFilter.cpp +++ b/src/effects/SkMagnifierImageFilter.cpp @@ -68,7 +68,7 @@ private: float yInvZoom, float xInvInset, float yInvInset) - : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) + : INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) , fBounds(bounds) , fXOffset(xOffset) , fYOffset(yOffset) diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp index 785b46f..345e6e5 100644 --- a/src/effects/SkXfermodeImageFilter.cpp +++ b/src/effects/SkXfermodeImageFilter.cpp @@ -188,7 +188,7 @@ sk_sp SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* sour backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), SkIntToScalar(-backgroundOffset.fY)); bgFP = GrTextureDomainEffect::Make( - backgroundTex.get(), backgroundMatrix, + backgroundTex.get(), nullptr, backgroundMatrix, GrTextureDomain::MakeTexelDomain(backgroundTex.get(), background->subset()), GrTextureDomain::kDecal_Mode, @@ -207,7 +207,7 @@ sk_sp SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* sour sk_sp foregroundFP; foregroundFP = GrTextureDomainEffect::Make( - foregroundTex.get(), foregroundMatrix, + foregroundTex.get(), nullptr, foregroundMatrix, GrTextureDomain::MakeTexelDomain(foregroundTex.get(), foreground->subset()), GrTextureDomain::kDecal_Mode, diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp index 371f7fb..3ad225b 100644 --- a/src/gpu/GrBlurUtils.cpp +++ b/src/gpu/GrBlurUtils.cpp @@ -35,7 +35,7 @@ static bool draw_mask(GrDrawContext* drawContext, matrix.setTranslate(-SkIntToScalar(maskRect.fLeft), -SkIntToScalar(maskRect.fTop)); matrix.postIDiv(mask->width(), mask->height()); - grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, matrix, + grp->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(mask, nullptr, matrix, kDevice_GrCoordSet)); SkMatrix inverse; diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index c1edb5b..77d5ea1 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -44,6 +44,7 @@ static sk_sp create_fp_for_mask(GrTexture* result, SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); return sk_sp(GrTextureDomainEffect::Make( result, + nullptr, mat, GrTextureDomain::MakeTexelDomain(result, domainTexels), GrTextureDomain::kDecal_Mode, diff --git a/src/gpu/GrColorSpaceXform.cpp b/src/gpu/GrColorSpaceXform.cpp new file mode 100644 index 0000000..f60dbcd --- /dev/null +++ b/src/gpu/GrColorSpaceXform.cpp @@ -0,0 +1,58 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrColorSpaceXform.h" +#include "SkColorSpace.h" + +static inline bool sk_float_almost_equals(float x, float y, float tol) { + return sk_float_abs(x - y) <= tol; +} + +static inline bool matrix_is_almost_identity(const SkMatrix44& m, + SkMScalar tol = SK_MScalar1 / (1 << 12)) { + return + sk_float_almost_equals(m.getFloat(0, 0), 1.0f, tol) && + sk_float_almost_equals(m.getFloat(0, 1), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(0, 2), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(0, 3), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(1, 0), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(1, 1), 1.0f, tol) && + sk_float_almost_equals(m.getFloat(1, 2), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(1, 3), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(2, 0), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(2, 1), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(2, 2), 1.0f, tol) && + sk_float_almost_equals(m.getFloat(2, 3), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(3, 0), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(3, 1), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(3, 2), 0.0f, tol) && + sk_float_almost_equals(m.getFloat(3, 3), 1.0f, tol); +} + +sk_sp GrColorSpaceXform::Make(SkColorSpace* src, SkColorSpace* dst) { + if (!src || !dst) { + // Invalid + return nullptr; + } + + if (src == dst) { + // Quick equality check - no conversion needed in this case + return nullptr; + } + + SkMatrix44 srcToDst(SkMatrix44::kUninitialized_Constructor); + if (!dst->xyz().invert(&srcToDst)) { + return nullptr; + } + srcToDst.postConcat(src->xyz()); + + if (matrix_is_almost_identity(srcToDst)) { + return nullptr; + } + + return sk_make_sp(srcToDst); +} diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 4154854..4a2b2b0 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -543,7 +543,7 @@ bool GrContext::applyGamma(GrRenderTarget* dst, GrTexture* src, SkScalar gamma){ } GrPaint paint; - paint.addColorTextureProcessor(src, GrCoordTransform::MakeDivByTextureWHMatrix(src)); + paint.addColorTextureProcessor(src, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(src)); if (!SkScalarNearlyEqual(gamma, 1.0f)) { paint.addColorFragmentProcessor(GrGammaEffect::Make(gamma)); } diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp index 02518c0..dda687e 100644 --- a/src/gpu/GrPaint.cpp +++ b/src/gpu/GrPaint.cpp @@ -22,24 +22,32 @@ void GrPaint::setCoverageSetOpXPFactory(SkRegion::Op regionOp, bool invertCovera fXPFactory = GrCoverageSetOpXPFactory::Make(regionOp, invertCoverage); } -void GrPaint::addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { - this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix)); +void GrPaint::addColorTextureProcessor(GrTexture* texture, + sk_sp colorSpaceXform, + const SkMatrix& matrix) { + this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, + std::move(colorSpaceXform), + matrix)); } void GrPaint::addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { - this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix)); + this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix)); } void GrPaint::addColorTextureProcessor(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& matrix, const GrTextureParams& params) { - this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix, params)); + this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, + std::move(colorSpaceXform), + matrix, params)); } void GrPaint::addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params) { - this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix, params)); + this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix, + params)); } bool GrPaint::isConstantBlendedColor(GrColor* color) const { diff --git a/src/gpu/GrPipelineBuilder.h b/src/gpu/GrPipelineBuilder.h index a7556eb..06c843f 100644 --- a/src/gpu/GrPipelineBuilder.h +++ b/src/gpu/GrPipelineBuilder.h @@ -77,23 +77,25 @@ public: * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates. */ void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { - this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix)); + this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix)); } void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) { - this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix)); + this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix)); } void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params) { - this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix, params)); + this->addColorFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix, + params)); } void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix, const GrTextureParams& params) { - this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, matrix, params)); + this->addCoverageFragmentProcessor(GrSimpleTextureEffect::Make(texture, nullptr, matrix, + params)); } /** diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 0b3bdb2..b966264 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -186,6 +186,7 @@ void GrSWMaskHelper::DrawToTargetWithShapeMask(GrTexture* texture, pipelineBuilder.addCoverageFragmentProcessor( GrSimpleTextureEffect::Make(texture, + nullptr, maskMatrix, GrTextureParams::kNone_FilterMode, kDevice_GrCoordSet)); diff --git a/src/gpu/GrTextureParamsAdjuster.cpp b/src/gpu/GrTextureParamsAdjuster.cpp index 7774391..b30731a 100644 --- a/src/gpu/GrTextureParamsAdjuster.cpp +++ b/src/gpu/GrTextureParamsAdjuster.cpp @@ -8,6 +8,7 @@ #include "GrTextureParamsAdjuster.h" #include "GrCaps.h" +#include "GrColorSpaceXform.h" #include "GrContext.h" #include "GrDrawContext.h" #include "GrGpu.h" @@ -94,12 +95,12 @@ static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset, // better! SkASSERT(copyParams.fFilter != GrTextureParams::kMipMap_FilterMode); paint.addColorFragmentProcessor( - GrTextureDomainEffect::Make(inputTexture, SkMatrix::I(), domain, + GrTextureDomainEffect::Make(inputTexture, nullptr, SkMatrix::I(), domain, GrTextureDomain::kClamp_Mode, copyParams.fFilter)); } else { GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter); - paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); + paint.addColorTextureProcessor(inputTexture, nullptr, SkMatrix::I(), params); } paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); @@ -350,6 +351,7 @@ static DomainMode determine_domain_mode( static sk_sp create_fp_for_domain_and_filter( GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& textureMatrix, DomainMode domainMode, const SkRect& domain, @@ -357,20 +359,23 @@ static sk_sp create_fp_for_domain_and_filter( SkASSERT(kTightCopy_DomainMode != domainMode); if (filterOrNullForBicubic) { if (kDomain_DomainMode == domainMode) { - return GrTextureDomainEffect::Make(texture, textureMatrix, domain, - GrTextureDomain::kClamp_Mode, + return GrTextureDomainEffect::Make(texture, std::move(colorSpaceXform), textureMatrix, + domain, GrTextureDomain::kClamp_Mode, *filterOrNullForBicubic); } else { GrTextureParams params(SkShader::kClamp_TileMode, *filterOrNullForBicubic); - return GrSimpleTextureEffect::Make(texture, textureMatrix, params); + return GrSimpleTextureEffect::Make(texture, std::move(colorSpaceXform), textureMatrix, + params); } } else { if (kDomain_DomainMode == domainMode) { - return GrBicubicEffect::Make(texture, textureMatrix, domain); + return GrBicubicEffect::Make(texture, std::move(colorSpaceXform), textureMatrix, + domain); } else { static const SkShader::TileMode kClampClamp[] = { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode }; - return GrBicubicEffect::Make(texture, textureMatrix, kClampClamp); + return GrBicubicEffect::Make(texture, std::move(colorSpaceXform), textureMatrix, + kClampClamp); } } } @@ -433,8 +438,11 @@ sk_sp GrTextureAdjuster::createFragmentProcessor( SkASSERT(kNoDomain_DomainMode == domainMode || (domain.fLeft <= domain.fRight && domain.fTop <= domain.fBottom)); textureMatrix.postIDiv(texture->width(), texture->height()); - return create_fp_for_domain_and_filter(texture, textureMatrix, domainMode, domain, - filterOrNullForBicubic); + SkColorSpace* dstColorSpace = nullptr; // XFORMTODO + sk_sp colorSpaceXform = GrColorSpaceXform::Make(this->getColorSpace(), + dstColorSpace); + return create_fp_for_domain_and_filter(texture, std::move(colorSpaceXform), textureMatrix, + domainMode, domain, filterOrNullForBicubic); } ////////////////////////////////////////////////////////////////////////////// @@ -512,7 +520,11 @@ sk_sp GrTextureMaker::createFragmentProcessor( SkASSERT(kTightCopy_DomainMode != domainMode); SkMatrix normalizedTextureMatrix = textureMatrix; normalizedTextureMatrix.postIDiv(texture->width(), texture->height()); - return create_fp_for_domain_and_filter(texture, normalizedTextureMatrix, domainMode, domain, + SkColorSpace* dstColorSpace = nullptr; // XFORMTODO + sk_sp colorSpaceXform = GrColorSpaceXform::Make(this->getColorSpace(), + dstColorSpace); + return create_fp_for_domain_and_filter(texture, std::move(colorSpaceXform), + normalizedTextureMatrix, domainMode, domain, filterOrNullForBicubic); } diff --git a/src/gpu/GrTextureToYUVPlanes.cpp b/src/gpu/GrTextureToYUVPlanes.cpp index 58c4b9a..da98547 100644 --- a/src/gpu/GrTextureToYUVPlanes.cpp +++ b/src/gpu/GrTextureToYUVPlanes.cpp @@ -32,7 +32,7 @@ static bool convert_texture(GrTexture* src, GrDrawContext* dst, int dstW, int ds } sk_sp fp( - GrSimpleTextureEffect::Make(src, SkMatrix::MakeScale(xScale, yScale), filter)); + GrSimpleTextureEffect::Make(src, nullptr, SkMatrix::MakeScale(xScale, yScale), filter)); if (!fp) { return false; } diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index e5d42cd..23f5798 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -1145,6 +1145,9 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, return; } + SkColorSpace* dstColorSpace = nullptr; // XFORMTODO + sk_sp colorSpaceXform = GrColorSpaceXform::Make(bitmap.colorSpace(), + dstColorSpace); SkRect dstRect = {0, 0, srcRect.width(), srcRect.height() }; SkRect paintRect; SkScalar wInv = SkScalarInvert(SkIntToScalar(texture->width())); @@ -1189,17 +1192,19 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, } textureDomain.setLTRB(left, top, right, bottom); if (bicubic) { - fp = GrBicubicEffect::Make(texture, texMatrix, textureDomain); + fp = GrBicubicEffect::Make(texture, std::move(colorSpaceXform), texMatrix, + textureDomain); } else { - fp = GrTextureDomainEffect::Make(texture, texMatrix, textureDomain, - GrTextureDomain::kClamp_Mode, params.filterMode()); + fp = GrTextureDomainEffect::Make(texture, std::move(colorSpaceXform), texMatrix, + textureDomain, GrTextureDomain::kClamp_Mode, + params.filterMode()); } } else if (bicubic) { SkASSERT(GrTextureParams::kNone_FilterMode == params.filterMode()); SkShader::TileMode tileModes[2] = { params.getTileModeX(), params.getTileModeY() }; - fp = GrBicubicEffect::Make(texture, texMatrix, tileModes); + fp = GrBicubicEffect::Make(texture, std::move(colorSpaceXform), texMatrix, tileModes); } else { - fp = GrSimpleTextureEffect::Make(texture, texMatrix, params); + fp = GrSimpleTextureEffect::Make(texture, std::move(colorSpaceXform), texMatrix, params); } GrPaint grPaint; @@ -1287,7 +1292,8 @@ void SkGpuDevice::drawSpecial(const SkDraw& draw, tmpUnfiltered.setImageFilter(nullptr); GrPaint grPaint; - sk_sp fp(GrSimpleTextureEffect::Make(texture.get(), SkMatrix::I())); + sk_sp fp(GrSimpleTextureEffect::Make(texture.get(), nullptr, + SkMatrix::I())); if (GrPixelConfigIsAlphaOnly(texture->config())) { fp = GrFragmentProcessor::MulOutputByInputUnpremulColor(std::move(fp)); } else { diff --git a/src/gpu/effects/Gr1DKernelEffect.h b/src/gpu/effects/Gr1DKernelEffect.h index 519d6db..d300f2d 100644 --- a/src/gpu/effects/Gr1DKernelEffect.h +++ b/src/gpu/effects/Gr1DKernelEffect.h @@ -31,7 +31,7 @@ public: Gr1DKernelEffect(GrTexture* texture, Direction direction, int radius) - : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) + : INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture)) , fDirection(direction) , fRadius(radius) {} diff --git a/src/gpu/effects/GrBicubicEffect.cpp b/src/gpu/effects/GrBicubicEffect.cpp index 5e6967c..db42f35 100644 --- a/src/gpu/effects/GrBicubicEffect.cpp +++ b/src/gpu/effects/GrBicubicEffect.cpp @@ -7,6 +7,7 @@ #include "GrBicubicEffect.h" #include "GrInvariantOutput.h" +#include "glsl/GrGLSLColorSpaceXformHelper.h" #include "glsl/GrGLSLFragmentShaderBuilder.h" #include "glsl/GrGLSLProgramDataManager.h" #include "glsl/GrGLSLUniformHandler.h" @@ -27,8 +28,9 @@ public: static inline void GenKey(const GrProcessor& effect, const GrGLSLCaps&, GrProcessorKeyBuilder* b) { - const GrTextureDomain& domain = effect.cast().domain(); - b->add32(GrTextureDomain::GLDomain::DomainKey(domain)); + const GrBicubicEffect& bicubicEffect = effect.cast(); + b->add32(GrTextureDomain::GLDomain::DomainKey(bicubicEffect.domain())); + b->add32(SkToInt(SkToBool(bicubicEffect.colorSpaceXform()))); } protected: @@ -39,13 +41,14 @@ private: UniformHandle fCoefficientsUni; UniformHandle fImageIncrementUni; + UniformHandle fColorSpaceXformUni; GrTextureDomain::GLDomain fDomain; typedef GrGLSLFragmentProcessor INHERITED; }; void GrGLBicubicEffect::emitCode(EmitArgs& args) { - const GrTextureDomain& domain = args.fFp.cast().domain(); + const GrBicubicEffect& bicubicEffect = args.fFp.cast(); GrGLSLUniformHandler* uniformHandler = args.fUniformHandler; fCoefficientsUni = uniformHandler->addUniform(kFragment_GrShaderFlag, @@ -58,6 +61,9 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) { const char* imgInc = uniformHandler->getUniformCStr(fImageIncrementUni); const char* coeff = uniformHandler->getUniformCStr(fCoefficientsUni); + GrGLSLColorSpaceXformHelper colorSpaceHelper(uniformHandler, bicubicEffect.colorSpaceXform(), + &fColorSpaceXformUni); + SkString cubicBlendName; static const GrGLSLShaderVar gCubicBlendArgs[] = { @@ -96,7 +102,7 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) { fDomain.sampleTexture(fragBuilder, args.fUniformHandler, args.fGLSLCaps, - domain, + bicubicEffect.domain(), sampleVar.c_str(), coord, args.fTexSamplers[0]); @@ -107,6 +113,9 @@ void GrGLBicubicEffect::emitCode(EmitArgs& args) { } SkString bicubicColor; bicubicColor.printf("%s(%s, f.y, s0, s1, s2, s3)", cubicBlendName.c_str(), coeff); + if (colorSpaceHelper.getXformMatrix()) { + bicubicColor.appendf(" * %s", colorSpaceHelper.getXformMatrix()); + } fragBuilder->codeAppendf("\t%s = %s;\n", args.fOutputColor, (GrGLSLExpr4(bicubicColor.c_str()) * GrGLSLExpr4(args.fInputColor)).c_str()); @@ -122,6 +131,11 @@ void GrGLBicubicEffect::onSetData(const GrGLSLProgramDataManager& pdman, pdman.set2fv(fImageIncrementUni, 1, imageIncrement); pdman.setMatrix4f(fCoefficientsUni, bicubicEffect.coefficients()); fDomain.setData(pdman, bicubicEffect.domain(), texture.origin()); + if (SkToBool(bicubicEffect.colorSpaceXform())) { + float xformMatrix[16]; + bicubicEffect.colorSpaceXform()->srcToDst().asColMajorf(xformMatrix); + pdman.setMatrix4f(fColorSpaceXformUni, xformMatrix); + } } static inline void convert_row_major_scalar_coeffs_to_column_major_floats(float dst[16], @@ -134,22 +148,27 @@ static inline void convert_row_major_scalar_coeffs_to_column_major_floats(float } GrBicubicEffect::GrBicubicEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkScalar coefficients[16], const SkMatrix &matrix, const SkShader::TileMode tileModes[2]) - : INHERITED(texture, matrix, GrTextureParams(tileModes, GrTextureParams::kNone_FilterMode)) - , fDomain(GrTextureDomain::IgnoredDomain()) { + : INHERITED(texture, nullptr, matrix, + GrTextureParams(tileModes, GrTextureParams::kNone_FilterMode)) + , fDomain(GrTextureDomain::IgnoredDomain()) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->initClassID(); convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coefficients); } GrBicubicEffect::GrBicubicEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkScalar coefficients[16], const SkMatrix &matrix, const SkRect& domain) - : INHERITED(texture, matrix, + : INHERITED(texture, nullptr, matrix, GrTextureParams(SkShader::kClamp_TileMode, GrTextureParams::kNone_FilterMode)) - , fDomain(domain, GrTextureDomain::kClamp_Mode) { + , fDomain(domain, GrTextureDomain::kClamp_Mode) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->initClassID(); convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coefficients); } @@ -186,7 +205,7 @@ sk_sp GrBicubicEffect::TestCreate(GrProcessorTestData* d) { for (int i = 0; i < 16; i++) { coefficients[i] = d->fRandom->nextSScalar1(); } - return GrBicubicEffect::Make(d->fTextures[texIdx], coefficients); + return GrBicubicEffect::Make(d->fTextures[texIdx], nullptr, coefficients); } ////////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/effects/GrBicubicEffect.h b/src/gpu/effects/GrBicubicEffect.h index 3c84f97..58bb068 100644 --- a/src/gpu/effects/GrBicubicEffect.h +++ b/src/gpu/effects/GrBicubicEffect.h @@ -29,19 +29,23 @@ public: const GrTextureDomain& domain() const { return fDomain; } + GrColorSpaceXform* colorSpaceXform() const { return fColorSpaceXform.get(); } + /** * Create a simple filter effect with custom bicubic coefficients and optional domain. */ - static sk_sp Make(GrTexture* tex, const SkScalar coefficients[16], + static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, + const SkScalar coefficients[16], const SkRect* domain = nullptr) { if (nullptr == domain) { static const SkShader::TileMode kTileModes[] = { SkShader::kClamp_TileMode, SkShader::kClamp_TileMode }; - return Make(tex, coefficients, GrCoordTransform::MakeDivByTextureWHMatrix(tex), - kTileModes); + return Make(tex, std::move(colorSpaceXform), coefficients, + GrCoordTransform::MakeDivByTextureWHMatrix(tex), kTileModes); } else { return sk_sp( - new GrBicubicEffect(tex, coefficients, + new GrBicubicEffect(tex, std::move(colorSpaceXform), coefficients, GrCoordTransform::MakeDivByTextureWHMatrix(tex), *domain)); } } @@ -49,28 +53,35 @@ public: /** * Create a Mitchell filter effect with specified texture matrix and x/y tile modes. */ - static sk_sp Make(GrTexture* tex, const SkMatrix& matrix, + static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, + const SkMatrix& matrix, const SkShader::TileMode tileModes[2]) { - return Make(tex, gMitchellCoefficients, matrix, tileModes); + return Make(tex, std::move(colorSpaceXform), gMitchellCoefficients, matrix, tileModes); } /** * Create a filter effect with custom bicubic coefficients, the texture matrix, and the x/y * tilemodes. */ - static sk_sp Make(GrTexture* tex, const SkScalar coefficients[16], + static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, + const SkScalar coefficients[16], const SkMatrix& matrix, const SkShader::TileMode tileModes[2]) { - return sk_sp(new GrBicubicEffect(tex, coefficients, matrix, - tileModes)); + return sk_sp(new GrBicubicEffect(tex, std::move(colorSpaceXform), + coefficients, matrix, tileModes)); } /** * Create a Mitchell filter effect with a texture matrix and a domain. */ - static sk_sp Make(GrTexture* tex, const SkMatrix& matrix, + static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, + const SkMatrix& matrix, const SkRect& domain) { - return sk_sp(new GrBicubicEffect(tex, gMitchellCoefficients, matrix, + return sk_sp(new GrBicubicEffect(tex, std::move(colorSpaceXform), + gMitchellCoefficients, matrix, domain)); } @@ -85,10 +96,10 @@ public: GrTextureParams::FilterMode* filterMode); private: - GrBicubicEffect(GrTexture*, const SkScalar coefficients[16], const SkMatrix &matrix, - const SkShader::TileMode tileModes[2]); - GrBicubicEffect(GrTexture*, const SkScalar coefficients[16], const SkMatrix &matrix, - const SkRect& domain); + GrBicubicEffect(GrTexture*, sk_sp, const SkScalar coefficients[16], + const SkMatrix &matrix, const SkShader::TileMode tileModes[2]); + GrBicubicEffect(GrTexture*, sk_sp, const SkScalar coefficients[16], + const SkMatrix &matrix, const SkRect& domain); GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; @@ -100,6 +111,7 @@ private: float fCoefficients[16]; GrTextureDomain fDomain; + sk_sp fColorSpaceXform; GR_DECLARE_FRAGMENT_PROCESSOR_TEST; diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index d2fde96..ed53276 100644 --- a/src/gpu/effects/GrConfigConversionEffect.cpp +++ b/src/gpu/effects/GrConfigConversionEffect.cpp @@ -98,7 +98,7 @@ GrConfigConversionEffect::GrConfigConversionEffect(GrTexture* texture, const GrSwizzle& swizzle, PMConversion pmConversion, const SkMatrix& matrix) - : INHERITED(texture, matrix) + : INHERITED(texture, nullptr, matrix) , fSwizzle(swizzle) , fPMConversion(pmConversion) { this->initClassID(); @@ -296,7 +296,7 @@ sk_sp GrConfigConversionEffect::Make(GrTexture* texture, // If we returned a GrConfigConversionEffect that was equivalent to a GrSimpleTextureEffect // then we may pollute our texture cache with redundant shaders. So in the case that no // conversions were requested we instead return a GrSimpleTextureEffect. - return GrSimpleTextureEffect::Make(texture, matrix); + return GrSimpleTextureEffect::Make(texture, nullptr, matrix); } else { if (kRGBA_8888_GrPixelConfig != texture->config() && kBGRA_8888_GrPixelConfig != texture->config() && diff --git a/src/gpu/effects/GrMatrixConvolutionEffect.cpp b/src/gpu/effects/GrMatrixConvolutionEffect.cpp index 5422755..8f03190 100644 --- a/src/gpu/effects/GrMatrixConvolutionEffect.cpp +++ b/src/gpu/effects/GrMatrixConvolutionEffect.cpp @@ -155,7 +155,7 @@ GrMatrixConvolutionEffect::GrMatrixConvolutionEffect(GrTexture* texture, const SkIPoint& kernelOffset, GrTextureDomain::Mode tileMode, bool convolveAlpha) - : INHERITED(texture, GrCoordTransform::MakeDivByTextureWHMatrix(texture)), + : INHERITED(texture, nullptr, GrCoordTransform::MakeDivByTextureWHMatrix(texture)), fKernelSize(kernelSize), fGain(SkScalarToFloat(gain)), fBias(SkScalarToFloat(bias) / 255.0f), diff --git a/src/gpu/effects/GrSimpleTextureEffect.cpp b/src/gpu/effects/GrSimpleTextureEffect.cpp index 7e7b828..a452d3e 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -68,5 +68,5 @@ sk_sp GrSimpleTextureEffect::TestCreate(GrProcessorTestData GrCoordSet coordSet = kCoordSets[d->fRandom->nextULessThan(SK_ARRAY_COUNT(kCoordSets))]; const SkMatrix& matrix = GrTest::TestMatrix(d->fRandom); - return GrSimpleTextureEffect::Make(d->fTextures[texIdx], matrix, coordSet); + return GrSimpleTextureEffect::Make(d->fTextures[texIdx], nullptr, matrix, coordSet); } diff --git a/src/gpu/effects/GrSimpleTextureEffect.h b/src/gpu/effects/GrSimpleTextureEffect.h index 08eb8c1..44e5c06 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.h +++ b/src/gpu/effects/GrSimpleTextureEffect.h @@ -22,26 +22,32 @@ class GrSimpleTextureEffect : public GrSingleTextureEffect { public: /* unfiltered, clamp mode */ static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, const SkMatrix& matrix, GrCoordSet coordSet = kLocal_GrCoordSet) { return sk_sp( - new GrSimpleTextureEffect(tex, matrix, GrTextureParams::kNone_FilterMode, coordSet)); + new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, + GrTextureParams::kNone_FilterMode, coordSet)); } /* clamp mode */ static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, const SkMatrix& matrix, GrTextureParams::FilterMode filterMode, GrCoordSet coordSet = kLocal_GrCoordSet) { return sk_sp( - new GrSimpleTextureEffect(tex, matrix, filterMode, coordSet)); + new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode, + coordSet)); } static sk_sp Make(GrTexture* tex, + sk_sp colorSpaceXform, const SkMatrix& matrix, const GrTextureParams& p, GrCoordSet coordSet = kLocal_GrCoordSet) { - return sk_sp(new GrSimpleTextureEffect(tex, matrix, p, coordSet)); + return sk_sp(new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), + matrix, p, coordSet)); } virtual ~GrSimpleTextureEffect() {} @@ -50,18 +56,20 @@ public: private: GrSimpleTextureEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& matrix, GrTextureParams::FilterMode filterMode, GrCoordSet coordSet) - : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) { + : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode, coordSet) { this->initClassID(); } GrSimpleTextureEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& matrix, const GrTextureParams& params, GrCoordSet coordSet) - : GrSingleTextureEffect(texture, matrix, params, coordSet) { + : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, params, coordSet) { this->initClassID(); } diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index c291735..c84e95e 100644 --- a/src/gpu/effects/GrSingleTextureEffect.cpp +++ b/src/gpu/effects/GrSingleTextureEffect.cpp @@ -8,30 +8,36 @@ #include "effects/GrSingleTextureEffect.h" GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& m, GrCoordSet coordSet) : fCoordTransform(coordSet, m, texture, GrTextureParams::kNone_FilterMode) - , fTextureAccess(texture) { + , fTextureAccess(texture) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureAccess(&fTextureAccess); } GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& m, GrTextureParams::FilterMode filterMode, GrCoordSet coordSet) : fCoordTransform(coordSet, m, texture, filterMode) - , fTextureAccess(texture, filterMode) { + , fTextureAccess(texture, filterMode) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureAccess(&fTextureAccess); } GrSingleTextureEffect::GrSingleTextureEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& m, const GrTextureParams& params, GrCoordSet coordSet) : fCoordTransform(coordSet, m, texture, params.filterMode()) - , fTextureAccess(texture, params) { + , fTextureAccess(texture, params) + , fColorSpaceXform(std::move(colorSpaceXform)) { this->addCoordTransform(&fCoordTransform); this->addTextureAccess(&fTextureAccess); } diff --git a/src/gpu/effects/GrSingleTextureEffect.h b/src/gpu/effects/GrSingleTextureEffect.h index 4169e40..ae7c694 100644 --- a/src/gpu/effects/GrSingleTextureEffect.h +++ b/src/gpu/effects/GrSingleTextureEffect.h @@ -9,6 +9,7 @@ #define GrSingleTextureEffect_DEFINED #include "GrFragmentProcessor.h" +#include "GrColorSpaceXform.h" #include "GrCoordTransform.h" #include "GrInvariantOutput.h" #include "SkMatrix.h" @@ -31,11 +32,13 @@ public: protected: /** unfiltered, clamp mode */ - GrSingleTextureEffect(GrTexture*, const SkMatrix&, GrCoordSet = kLocal_GrCoordSet); - /** clamp mode */ - GrSingleTextureEffect(GrTexture*, const SkMatrix&, GrTextureParams::FilterMode filterMode, + GrSingleTextureEffect(GrTexture*, sk_sp, const SkMatrix&, GrCoordSet = kLocal_GrCoordSet); + /** clamp mode */ + GrSingleTextureEffect(GrTexture*, sk_sp, const SkMatrix&, + GrTextureParams::FilterMode filterMode, GrCoordSet = kLocal_GrCoordSet); GrSingleTextureEffect(GrTexture*, + sk_sp, const SkMatrix&, const GrTextureParams&, GrCoordSet = kLocal_GrCoordSet); @@ -58,6 +61,7 @@ protected: private: GrCoordTransform fCoordTransform; GrTextureAccess fTextureAccess; + sk_sp fColorSpaceXform; typedef GrFragmentProcessor INHERITED; }; diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 3fbf000..814d193 100644 --- a/src/gpu/effects/GrTextureDomain.cpp +++ b/src/gpu/effects/GrTextureDomain.cpp @@ -219,6 +219,7 @@ void GrGLTextureDomainEffect::GenKey(const GrProcessor& processor, const GrGLSLC /////////////////////////////////////////////////////////////////////////////// sk_sp GrTextureDomainEffect::Make(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& matrix, const SkRect& domain, GrTextureDomain::Mode mode, @@ -227,20 +228,22 @@ sk_sp GrTextureDomainEffect::Make(GrTexture* texture, static const SkRect kFullRect = {0, 0, SK_Scalar1, SK_Scalar1}; if (GrTextureDomain::kIgnore_Mode == mode || (GrTextureDomain::kClamp_Mode == mode && domain.contains(kFullRect))) { - return GrSimpleTextureEffect::Make(texture, matrix, filterMode); + return GrSimpleTextureEffect::Make(texture, std::move(colorSpaceXform), matrix, filterMode); } else { return sk_sp( - new GrTextureDomainEffect(texture, matrix, domain, mode, filterMode, coordSet)); + new GrTextureDomainEffect(texture, std::move(colorSpaceXform), matrix, domain, mode, + filterMode, coordSet)); } } GrTextureDomainEffect::GrTextureDomainEffect(GrTexture* texture, + sk_sp colorSpaceXform, const SkMatrix& matrix, const SkRect& domain, GrTextureDomain::Mode mode, GrTextureParams::FilterMode filterMode, GrCoordSet coordSet) - : GrSingleTextureEffect(texture, matrix, filterMode, coordSet) + : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, filterMode, coordSet) , fTextureDomain(domain, mode) { SkASSERT(mode != GrTextureDomain::kRepeat_Mode || filterMode == GrTextureParams::kNone_FilterMode); @@ -294,6 +297,7 @@ sk_sp GrTextureDomainEffect::TestCreate(GrProcessorTestData GrCoordSet coords = d->fRandom->nextBool() ? kLocal_GrCoordSet : kDevice_GrCoordSet; return GrTextureDomainEffect::Make( d->fTextures[texIdx], + nullptr, matrix, domain, mode, diff --git a/src/gpu/effects/GrTextureDomain.h b/src/gpu/effects/GrTextureDomain.h index a86ce95..9edecac 100644 --- a/src/gpu/effects/GrTextureDomain.h +++ b/src/gpu/effects/GrTextureDomain.h @@ -167,6 +167,7 @@ class GrTextureDomainEffect : public GrSingleTextureEffect { public: static sk_sp Make(GrTexture*, + sk_sp, const SkMatrix&, const SkRect& domain, GrTextureDomain::Mode, @@ -193,6 +194,7 @@ protected: private: GrTextureDomainEffect(GrTexture*, + sk_sp, const SkMatrix&, const SkRect& domain, GrTextureDomain::Mode, diff --git a/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h new file mode 100644 index 0000000..940be57 --- /dev/null +++ b/src/gpu/glsl/GrGLSLColorSpaceXformHelper.h @@ -0,0 +1,39 @@ +/* + * Copyright 2016 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrGLSLColorSpaceXformHelper_DEFINED +#define GrGLSLColorSpaceXformHelper_DEFINED + +#include "GrGLSLUniformHandler.h" + +class GrColorSpaceXform; + +/** + * Stack helper class to assist with using GrColorSpaceXform within an FP's emitCode function. + */ +class GrGLSLColorSpaceXformHelper : public SkNoncopyable { +public: + GrGLSLColorSpaceXformHelper(GrGLSLUniformHandler* uniformHandler, + GrColorSpaceXform* colorSpaceXform, + GrGLSLProgramDataManager::UniformHandle* handle) { + SkASSERT(uniformHandler && handle); + if (colorSpaceXform) { + *handle = uniformHandler->addUniform(kFragment_GrShaderFlag, kMat44f_GrSLType, + kDefault_GrSLPrecision, "ColorXform", + &fXformMatrix); + } else { + fXformMatrix = nullptr; + } + } + + const char* getXformMatrix() const { return fXformMatrix; } + +private: + const char* fXformMatrix; +}; + +#endif diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp index 33edfde..77639b2 100644 --- a/src/image/SkImageShader.cpp +++ b/src/image/SkImageShader.cpp @@ -122,9 +122,9 @@ sk_sp SkImageShader::asFragmentProcessor( sk_sp inner; if (doBicubic) { - inner = GrBicubicEffect::Make(texture, matrix, tm); + inner = GrBicubicEffect::Make(texture, nullptr, matrix, tm); } else { - inner = GrSimpleTextureEffect::Make(texture, matrix, params); + inner = GrSimpleTextureEffect::Make(texture, nullptr, matrix, params); } if (GrPixelConfigIsAlphaOnly(texture->config())) { diff --git a/tests/SRGBMipMapTest.cpp b/tests/SRGBMipMapTest.cpp index f9ee037..5001a9e 100644 --- a/tests/SRGBMipMapTest.cpp +++ b/tests/SRGBMipMapTest.cpp @@ -146,7 +146,7 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SRGBMipMaps, reporter, ctxInfo) { GrPaint paint; paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); GrTextureParams mipMapParams(SkShader::kRepeat_TileMode, GrTextureParams::kMipMap_FilterMode); - paint.addColorTextureProcessor(texture, SkMatrix::MakeScale(0.5f), mipMapParams); + paint.addColorTextureProcessor(texture, nullptr, SkMatrix::MakeScale(0.5f), mipMapParams); // 1) Draw texture to S32 surface (should generate/use sRGB mips) paint.setGammaCorrect(true); diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp index 83ab4ea..c96cb37 100644 --- a/tools/gpu/GrTest.cpp +++ b/tools/gpu/GrTest.cpp @@ -149,7 +149,7 @@ void SkGpuDevice::drawTexture(GrTexture* tex, const SkRect& dst, const SkPaint& textureMat[SkMatrix::kMTransX] = -dst.fLeft/dst.width(); textureMat[SkMatrix::kMTransY] = -dst.fTop/dst.height(); - grPaint.addColorTextureProcessor(tex, textureMat); + grPaint.addColorTextureProcessor(tex, nullptr, textureMat); fDrawContext->drawRect(GrNoClip(), grPaint, mat, dst); } -- 2.7.4