diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 2f3764c0be..a9ecad84c1 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -360,7 +360,8 @@ public: * color. The GrContext may be used by the effect to create textures. The GPU device does not * call createContext. Instead we pass the SkPaint here in case the shader needs paint info. */ - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint, + const SkMatrix* localMatrixOrNull) const; ////////////////////////////////////////////////////////////////////////// // Factory methods for stock shaders diff --git a/include/effects/SkPerlinNoiseShader.h b/include/effects/SkPerlinNoiseShader.h index 5082a07f3b..63e74155a6 100644 --- a/include/effects/SkPerlinNoiseShader.h +++ b/include/effects/SkPerlinNoiseShader.h @@ -95,7 +95,8 @@ public: typedef SkShader::Context INHERITED; }; - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix*) const SK_OVERRIDE; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPerlinNoiseShader) diff --git a/src/core/SkBitmapProcShader.cpp b/src/core/SkBitmapProcShader.cpp index 00d938be27..d726a46f11 100644 --- a/src/core/SkBitmapProcShader.cpp +++ b/src/core/SkBitmapProcShader.cpp @@ -393,7 +393,8 @@ static SkScalar get_combined_min_stretch(const SkMatrix& viewMatrix, const SkMat } } -GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint) const { +GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& paint, + const SkMatrix* localMatrix) const { SkMatrix matrix; matrix.setIDiv(fRawBitmap.width(), fRawBitmap.height()); @@ -401,6 +402,13 @@ GrEffectRef* SkBitmapProcShader::asNewEffect(GrContext* context, const SkPaint& if (!this->getLocalMatrix().invert(&lmInverse)) { return NULL; } + if (localMatrix) { + SkMatrix inv; + if (!localMatrix->invert(&inv)) { + return NULL; + } + lmInverse.postConcat(inv); + } matrix.preConcat(lmInverse); SkShader::TileMode tm[] = { diff --git a/src/core/SkBitmapProcShader.h b/src/core/SkBitmapProcShader.h index 8d31256469..80e4550279 100644 --- a/src/core/SkBitmapProcShader.h +++ b/src/core/SkBitmapProcShader.h @@ -31,7 +31,7 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapProcShader) #if SK_SUPPORT_GPU - GrEffectRef* asNewEffect(GrContext*, const SkPaint&) const SK_OVERRIDE; + GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE; #endif class BitmapProcShaderContext : public SkShader::Context { diff --git a/src/core/SkLocalMatrixShader.cpp b/src/core/SkLocalMatrixShader.cpp index 802e72ef3f..7af025c442 100644 --- a/src/core/SkLocalMatrixShader.cpp +++ b/src/core/SkLocalMatrixShader.cpp @@ -30,8 +30,13 @@ public: } // TODO: need to augment this API to pass in a localmatrix (which we can augment) - virtual GrEffectRef* asNewEffect(GrContext* ctx, const SkPaint& paint) const SK_OVERRIDE { - return fProxyShader->asNewEffect(ctx, paint); + virtual GrEffectRef* asNewEffect(GrContext* ctx, const SkPaint& paint, + const SkMatrix* localMatrix) const SK_OVERRIDE { + SkMatrix tmp = fProxyLocalMatrix; + if (localMatrix) { + tmp.preConcat(*localMatrix); + } + return fProxyShader->asNewEffect(ctx, paint, &tmp); } virtual SkShader* refAsALocalMatrixShader(SkMatrix* localMatrix) const SK_OVERRIDE { diff --git a/src/core/SkPictureShader.cpp b/src/core/SkPictureShader.cpp index 9655e85bd1..300a65329b 100644 --- a/src/core/SkPictureShader.cpp +++ b/src/core/SkPictureShader.cpp @@ -192,11 +192,12 @@ void SkPictureShader::toString(SkString* str) const { #endif #if SK_SUPPORT_GPU -GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint) const { - SkAutoTUnref bitmapShader(this->refBitmapShader(context->getMatrix(), NULL)); +GrEffectRef* SkPictureShader::asNewEffect(GrContext* context, const SkPaint& paint, + const SkMatrix* localMatrix) const { + SkAutoTUnref bitmapShader(this->refBitmapShader(context->getMatrix(), localMatrix)); if (!bitmapShader) { return NULL; } - return bitmapShader->asNewEffect(context, paint); + return bitmapShader->asNewEffect(context, paint, NULL); } #endif diff --git a/src/core/SkPictureShader.h b/src/core/SkPictureShader.h index 27fb674b01..936a69ebe0 100644 --- a/src/core/SkPictureShader.h +++ b/src/core/SkPictureShader.h @@ -30,7 +30,7 @@ public: SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkPictureShader) #if SK_SUPPORT_GPU - GrEffectRef* asNewEffect(GrContext*, const SkPaint&) const SK_OVERRIDE; + GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE; #endif protected: diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index ebe1a74cc2..75a5fdbd36 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -211,7 +211,7 @@ SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { return kNone_GradientType; } -GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { +GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const { return NULL; } diff --git a/src/effects/SkPerlinNoiseShader.cpp b/src/effects/SkPerlinNoiseShader.cpp index c6d6118002..101537798e 100644 --- a/src/effects/SkPerlinNoiseShader.cpp +++ b/src/effects/SkPerlinNoiseShader.cpp @@ -723,7 +723,7 @@ GrEffectRef* GrPerlinNoiseEffect::TestCreate(SkRandom* random, stitchTiles ? &tileSize : NULL); SkPaint paint; - GrEffectRef* effect = shader->asNewEffect(context, paint); + GrEffectRef* effect = shader->asNewEffect(context, paint, NULL); SkDELETE(shader); @@ -1275,9 +1275,15 @@ void GrGLSimplexNoise::setData(const GrGLUniformManager& uman, const GrDrawEffec ///////////////////////////////////////////////////////////////////// -GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint) const { +GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& paint, + const SkMatrix* externalLocalMatrix) const { SkASSERT(NULL != context); + SkMatrix localMatrix = this->getLocalMatrix(); + if (externalLocalMatrix) { + localMatrix.preConcat(*externalLocalMatrix); + } + if (0 == fNumOctaves) { SkColor clearColor = 0; if (kFractalNoise_Type == fType) { @@ -1309,7 +1315,7 @@ GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& fNumOctaves, fStitchTiles, fPaintingData->fStitchDataInit, permutationsTexture, noiseTexture, - this->getLocalMatrix(), paint.getAlpha()) : + localMatrix, paint.getAlpha()) : NULL; // Unlock immediately, this is not great, but we don't have a way of @@ -1328,7 +1334,7 @@ GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext* context, const SkPaint& #else -GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext*, const SkPaint&) const { +GrEffectRef* SkPerlinNoiseShader::asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const { SkDEBUGFAIL("Should not call in GPU-less build"); return NULL; } diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp index f37759c1a9..4fe65470ae 100644 --- a/src/effects/gradients/SkLinearGradient.cpp +++ b/src/effects/gradients/SkLinearGradient.cpp @@ -527,7 +527,7 @@ GrEffectRef* GrLinearGradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } ///////////////////////////////////////////////////////////////////// @@ -547,12 +547,20 @@ void GrGLLinearGradient::emitCode(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrEffectRef* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkLinearGradient::asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix* localMatrix) const { SkASSERT(NULL != context); SkMatrix matrix; if (!this->getLocalMatrix().invert(&matrix)) { return NULL; } + if (localMatrix) { + SkMatrix inv; + if (!localMatrix->invert(&inv)) { + return NULL; + } + matrix.postConcat(inv); + } matrix.postConcat(fPtsToUnit); return GrLinearGradient::Create(context, *this, matrix, fTileMode); } diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h index e892fe33d0..432dac0ff8 100644 --- a/src/effects/gradients/SkLinearGradient.h +++ b/src/effects/gradients/SkLinearGradient.h @@ -30,7 +30,7 @@ public: virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient) diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp index e379f36c95..ce4c16a654 100644 --- a/src/effects/gradients/SkRadialGradient.cpp +++ b/src/effects/gradients/SkRadialGradient.cpp @@ -538,7 +538,7 @@ GrEffectRef* GrRadialGradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } ///////////////////////////////////////////////////////////////////// @@ -559,13 +559,21 @@ void GrGLRadialGradient::emitCode(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrEffectRef* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkRadialGradient::asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix* localMatrix) const { SkASSERT(NULL != context); SkMatrix matrix; if (!this->getLocalMatrix().invert(&matrix)) { return NULL; } + if (localMatrix) { + SkMatrix inv; + if (!localMatrix->invert(&inv)) { + return NULL; + } + matrix.postConcat(inv); + } matrix.postConcat(fPtsToUnit); return GrRadialGradient::Create(context, *this, matrix, fTileMode); } diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h index 2c60ba5e08..aade31ef52 100644 --- a/src/effects/gradients/SkRadialGradient.h +++ b/src/effects/gradients/SkRadialGradient.h @@ -33,7 +33,7 @@ public: SkMatrix* matrix, TileMode* xy) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient) diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index 81ebb3441e..ba43571c9b 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -247,7 +247,7 @@ GrEffectRef* GrSweepGradient::TestCreate(SkRandom* random, SkAutoTUnref shader(SkGradientShader::CreateSweep(center.fX, center.fY, colors, stops, colorCount)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } ///////////////////////////////////////////////////////////////////// @@ -279,11 +279,19 @@ void GrGLSweepGradient::emitCode(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrEffectRef* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkSweepGradient::asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix* localMatrix) const { SkMatrix matrix; if (!this->getLocalMatrix().invert(&matrix)) { return NULL; } + if (localMatrix) { + SkMatrix inv; + if (!localMatrix->invert(&inv)) { + return NULL; + } + matrix.postConcat(inv); + } matrix.postConcat(fPtsToUnit); return GrSweepGradient::Create(context, *this, matrix); } diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h index 36cdd63811..2f798e87a0 100644 --- a/src/effects/gradients/SkSweepGradient.h +++ b/src/effects/gradients/SkSweepGradient.h @@ -35,7 +35,7 @@ public: virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient) diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp index 574df08294..cbe9e83a96 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp @@ -380,11 +380,12 @@ void SkTwoPointConicalGradient::flatten( #if SK_SUPPORT_GPU -GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkTwoPointConicalGradient::asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix* localMatrix) const { SkASSERT(NULL != context); SkASSERT(fPtsToUnit.isIdentity()); - return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode); + return Gr2PtConicalGradientEffect::Create(context, *this, fTileMode, localMatrix); } #else diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h index 85e0bc0b4e..78998a8d98 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.h +++ b/src/effects/gradients/SkTwoPointConicalGradient.h @@ -65,7 +65,7 @@ public: SkMatrix* matrix, TileMode* xy) const; virtual SkShader::GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext*, const SkPaint&, const SkMatrix*) const SK_OVERRIDE; virtual bool isOpaque() const SK_OVERRIDE; SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); } diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp index 7986d82b96..23fee850f5 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.cpp @@ -199,7 +199,7 @@ GrEffectRef* Edge2PtConicalEffect::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } GLEdge2PtConicalEffect::GLEdge2PtConicalEffect(const GrBackendEffectFactory& factory, @@ -470,7 +470,7 @@ GrEffectRef* FocalOutside2PtConicalEffect::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } GLFocalOutside2PtConicalEffect::GLFocalOutside2PtConicalEffect(const GrBackendEffectFactory& factory, @@ -679,7 +679,7 @@ GrEffectRef* FocalInside2PtConicalEffect::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } GLFocalInside2PtConicalEffect::GLFocalInside2PtConicalEffect(const GrBackendEffectFactory& factory, @@ -920,7 +920,7 @@ GrEffectRef* CircleInside2PtConicalEffect::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } GLCircleInside2PtConicalEffect::GLCircleInside2PtConicalEffect(const GrBackendEffectFactory& factory, @@ -1148,7 +1148,7 @@ GrEffectRef* CircleOutside2PtConicalEffect::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } GLCircleOutside2PtConicalEffect::GLCircleOutside2PtConicalEffect(const GrBackendEffectFactory& factory, @@ -1267,11 +1267,19 @@ GrGLEffect::EffectKey GLCircleOutside2PtConicalEffect::GenKey(const GrDrawEffect GrEffectRef* Gr2PtConicalGradientEffect::Create(GrContext* ctx, const SkTwoPointConicalGradient& shader, - SkShader::TileMode tm) { + SkShader::TileMode tm, + const SkMatrix* localMatrix) { SkMatrix matrix; if (!shader.getLocalMatrix().invert(&matrix)) { return NULL; } + if (localMatrix) { + SkMatrix inv; + if (!localMatrix->invert(&inv)) { + return NULL; + } + matrix.postConcat(inv); + } if (shader.getStartRadius() < kErrorTol) { SkScalar focalX; diff --git a/src/effects/gradients/SkTwoPointConicalGradient_gpu.h b/src/effects/gradients/SkTwoPointConicalGradient_gpu.h index f8c0493dd2..2b0f0612d7 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient_gpu.h +++ b/src/effects/gradients/SkTwoPointConicalGradient_gpu.h @@ -19,7 +19,7 @@ namespace Gr2PtConicalGradientEffect { * shader passed in. */ GrEffectRef* Create(GrContext* ctx, const SkTwoPointConicalGradient& shader, - SkShader::TileMode tm); + SkShader::TileMode tm, const SkMatrix* localMatrix); }; #endif diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp index d85be5d3ba..ac0b0bdf1c 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.cpp +++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp @@ -530,7 +530,7 @@ GrEffectRef* GrRadial2Gradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); SkPaint paint; - return shader->asNewEffect(context, paint); + return shader->asNewEffect(context, paint, NULL); } ///////////////////////////////////////////////////////////////////// @@ -670,13 +670,21 @@ GrGLEffect::EffectKey GrGLRadial2Gradient::GenKey(const GrDrawEffect& drawEffect ///////////////////////////////////////////////////////////////////// -GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&) const { +GrEffectRef* SkTwoPointRadialGradient::asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix* localMatrix) const { SkASSERT(NULL != context); // invert the localM, translate to center1 (fPtsToUni), rotate so center2 is on x axis. SkMatrix matrix; if (!this->getLocalMatrix().invert(&matrix)) { return NULL; } + if (localMatrix) { + SkMatrix inv; + if (!localMatrix->invert(&inv)) { + return NULL; + } + matrix.postConcat(inv); + } matrix.postConcat(fPtsToUnit); SkScalar diffLen = fDiff.length(); diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h index 6d36fe448e..90052eba20 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.h +++ b/src/effects/gradients/SkTwoPointRadialGradient.h @@ -21,7 +21,8 @@ public: SkMatrix* matrix, TileMode* xy) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; + virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&, + const SkMatrix*) const SK_OVERRIDE; virtual size_t contextSize() const SK_OVERRIDE; diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index f90b906b19..0aee983f75 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -463,7 +463,7 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev, GrContext::AutoWideOpenIdentityDraw awo(dev->context(), NULL); // setup the shader as the first color effect on the paint - SkAutoTUnref effect(shader->asNewEffect(dev->context(), skPaint)); + SkAutoTUnref effect(shader->asNewEffect(dev->context(), skPaint, NULL)); if (NULL != effect.get()) { grPaint->addColorEffect(effect); // Now setup the rest of the paint.