diff options
Diffstat (limited to 'src/gpu')
22 files changed, 253 insertions, 71 deletions
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp index 371f7fb0ba..3ad225bfff 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 c1edb5b9ad..77d5ea1d03 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -44,6 +44,7 @@ static sk_sp<GrFragmentProcessor> create_fp_for_mask(GrTexture* result, SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); return sk_sp<GrFragmentProcessor>(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 0000000000..f60dbcd1c0 --- /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> 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<GrColorSpaceXform>(srcToDst); +} diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 4154854a93..4a2b2b0228 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 02518c0464..dda687e7c1 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<GrColorSpaceXform> 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<GrColorSpaceXform> 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 a7556eb59d..06c843fe53 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 0b3bdb2228..b966264789 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 77743916c5..b30731acec 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<GrFragmentProcessor> create_fp_for_domain_and_filter( GrTexture* texture, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& textureMatrix, DomainMode domainMode, const SkRect& domain, @@ -357,20 +359,23 @@ static sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor> 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<GrColorSpaceXform> 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<GrFragmentProcessor> 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<GrColorSpaceXform> 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 58c4b9ac5e..da98547d97 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<GrFragmentProcessor> 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 e5d42cd811..23f5798c1a 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<GrColorSpaceXform> 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<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make(texture.get(), SkMatrix::I())); + sk_sp<GrFragmentProcessor> 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 519d6dbeb5..d300f2d523 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 5e6967ce4b..db42f35669 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<GrBicubicEffect>().domain(); - b->add32(GrTextureDomain::GLDomain::DomainKey(domain)); + const GrBicubicEffect& bicubicEffect = effect.cast<GrBicubicEffect>(); + 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<GrBicubicEffect>().domain(); + const GrBicubicEffect& bicubicEffect = args.fFp.cast<GrBicubicEffect>(); 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<GrColorSpaceXform> 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<GrBicubicEffect>(); convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coefficients); } GrBicubicEffect::GrBicubicEffect(GrTexture* texture, + sk_sp<GrColorSpaceXform> 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<GrBicubicEffect>(); convert_row_major_scalar_coeffs_to_column_major_floats(fCoefficients, coefficients); } @@ -186,7 +205,7 @@ sk_sp<GrFragmentProcessor> 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 3c84f97919..58bb068d5f 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<GrFragmentProcessor> Make(GrTexture* tex, const SkScalar coefficients[16], + static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> 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<GrFragmentProcessor>( - 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<GrFragmentProcessor> Make(GrTexture* tex, const SkMatrix& matrix, + static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> 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<GrFragmentProcessor> Make(GrTexture* tex, const SkScalar coefficients[16], + static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> colorSpaceXform, + const SkScalar coefficients[16], const SkMatrix& matrix, const SkShader::TileMode tileModes[2]) { - return sk_sp<GrFragmentProcessor>(new GrBicubicEffect(tex, coefficients, matrix, - tileModes)); + return sk_sp<GrFragmentProcessor>(new GrBicubicEffect(tex, std::move(colorSpaceXform), + coefficients, matrix, tileModes)); } /** * Create a Mitchell filter effect with a texture matrix and a domain. */ - static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, const SkMatrix& matrix, + static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> colorSpaceXform, + const SkMatrix& matrix, const SkRect& domain) { - return sk_sp<GrFragmentProcessor>(new GrBicubicEffect(tex, gMitchellCoefficients, matrix, + return sk_sp<GrFragmentProcessor>(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<GrColorSpaceXform>, const SkScalar coefficients[16], + const SkMatrix &matrix, const SkShader::TileMode tileModes[2]); + GrBicubicEffect(GrTexture*, sk_sp<GrColorSpaceXform>, 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<GrColorSpaceXform> fColorSpaceXform; GR_DECLARE_FRAGMENT_PROCESSOR_TEST; diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp index d2fde96bb3..ed532768db 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<GrConfigConversionEffect>(); @@ -296,7 +296,7 @@ sk_sp<GrFragmentProcessor> 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 5422755c2e..8f031904ca 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 7e7b828d3d..a452d3e6fd 100644 --- a/src/gpu/effects/GrSimpleTextureEffect.cpp +++ b/src/gpu/effects/GrSimpleTextureEffect.cpp @@ -68,5 +68,5 @@ sk_sp<GrFragmentProcessor> 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 08eb8c17e1..44e5c06530 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<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, GrCoordSet coordSet = kLocal_GrCoordSet) { return sk_sp<GrFragmentProcessor>( - new GrSimpleTextureEffect(tex, matrix, GrTextureParams::kNone_FilterMode, coordSet)); + new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, + GrTextureParams::kNone_FilterMode, coordSet)); } /* clamp mode */ static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, GrTextureParams::FilterMode filterMode, GrCoordSet coordSet = kLocal_GrCoordSet) { return sk_sp<GrFragmentProcessor>( - new GrSimpleTextureEffect(tex, matrix, filterMode, coordSet)); + new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), matrix, filterMode, + coordSet)); } static sk_sp<GrFragmentProcessor> Make(GrTexture* tex, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, const GrTextureParams& p, GrCoordSet coordSet = kLocal_GrCoordSet) { - return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(tex, matrix, p, coordSet)); + return sk_sp<GrFragmentProcessor>(new GrSimpleTextureEffect(tex, std::move(colorSpaceXform), + matrix, p, coordSet)); } virtual ~GrSimpleTextureEffect() {} @@ -50,18 +56,20 @@ public: private: GrSimpleTextureEffect(GrTexture* texture, + sk_sp<GrColorSpaceXform> 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>(); } GrSimpleTextureEffect(GrTexture* texture, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, const GrTextureParams& params, GrCoordSet coordSet) - : GrSingleTextureEffect(texture, matrix, params, coordSet) { + : GrSingleTextureEffect(texture, std::move(colorSpaceXform), matrix, params, coordSet) { this->initClassID<GrSimpleTextureEffect>(); } diff --git a/src/gpu/effects/GrSingleTextureEffect.cpp b/src/gpu/effects/GrSingleTextureEffect.cpp index c291735c0d..c84e95ed0a 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<GrColorSpaceXform> 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<GrColorSpaceXform> 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<GrColorSpaceXform> 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 4169e40469..ae7c69426f 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<GrColorSpaceXform>, const SkMatrix&, GrCoordSet = kLocal_GrCoordSet); + /** clamp mode */ + GrSingleTextureEffect(GrTexture*, sk_sp<GrColorSpaceXform>, const SkMatrix&, + GrTextureParams::FilterMode filterMode, GrCoordSet = kLocal_GrCoordSet); GrSingleTextureEffect(GrTexture*, + sk_sp<GrColorSpaceXform>, const SkMatrix&, const GrTextureParams&, GrCoordSet = kLocal_GrCoordSet); @@ -58,6 +61,7 @@ protected: private: GrCoordTransform fCoordTransform; GrTextureAccess fTextureAccess; + sk_sp<GrColorSpaceXform> fColorSpaceXform; typedef GrFragmentProcessor INHERITED; }; diff --git a/src/gpu/effects/GrTextureDomain.cpp b/src/gpu/effects/GrTextureDomain.cpp index 3fbf0008a4..814d193fde 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<GrFragmentProcessor> GrTextureDomainEffect::Make(GrTexture* texture, + sk_sp<GrColorSpaceXform> colorSpaceXform, const SkMatrix& matrix, const SkRect& domain, GrTextureDomain::Mode mode, @@ -227,20 +228,22 @@ sk_sp<GrFragmentProcessor> 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<GrFragmentProcessor>( - 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<GrColorSpaceXform> 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<GrFragmentProcessor> 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 a86ce95497..9edecac667 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<GrFragmentProcessor> Make(GrTexture*, + sk_sp<GrColorSpaceXform>, const SkMatrix&, const SkRect& domain, GrTextureDomain::Mode, @@ -193,6 +194,7 @@ protected: private: GrTextureDomainEffect(GrTexture*, + sk_sp<GrColorSpaceXform>, 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 0000000000..940be57126 --- /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 |