diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-10-16 15:19:45 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-10-16 15:19:45 +0000 |
commit | dfdb7e5240276493077b7c6e1f3cc8b8a0e195ba (patch) | |
tree | 8052c43cb50ba6f2c5c2f8fb9a3c518e17b43d2c | |
parent | f6eac8af585e44d56e6b18d269e6c34f9917ea88 (diff) |
Reland r5963 with two fixes:
Missing ref in GrSweepGradient::TestCreate.
Must reset() the sampler in setup_drawstate_aaclip() to avoid hitting a (dubious) assert.
git-svn-id: http://skia.googlecode.com/svn/trunk@5964 2bbb7eff-a529-9590-31e7-b0007b416f81
22 files changed, 210 insertions, 179 deletions
diff --git a/gm/texdata.cpp b/gm/texdata.cpp index 724b4ec826..09721acc13 100644 --- a/gm/texdata.cpp +++ b/gm/texdata.cpp @@ -112,12 +112,9 @@ protected: ctx->setMatrix(vm); GrMatrix tm; tm = vm; - GrMatrix* sampleMat = paint.colorSampler(0)->matrix(); - *sampleMat = vm; - sampleMat->postIDiv(2*S, 2*S); - paint.colorSampler(0)->setCustomStage( - SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); - + tm.postIDiv(2*S, 2*S); + paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, + (texture)), tm)->unref(); ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S)); diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 8eb695cd14..a0a1b056d4 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -306,14 +306,13 @@ public: virtual GradientType asAGradient(GradientInfo* info) const; /** - * If the shader subclass has a GrCustomStage implementation, this returns - * a new custom stage (the caller assumes ownership, and will need to - * unref it). A GrContext pointer is required since custom stages may - * need to create textures. The sampler parameter is necessary to set - * up matrix/tile modes/etc, and will eventually be removed. + * If the shader subclass has a GrCustomStage implementation, this installs + * a custom stage on the sampler. A GrContext pointer is required since custom + * stages may need to create textures. The sampler parameter is necessary to set a + * texture matrix. It will eventually be removed and this function will operate as a + * GrCustomStage factory. */ - virtual GrCustomStage* asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const; + virtual bool asNewCustomStage(GrContext* context, GrSamplerState* sampler) const; ////////////////////////////////////////////////////////////////////////// // Factory methods for stock shaders diff --git a/include/gpu/GrSamplerState.h b/include/gpu/GrSamplerState.h index 385dba7bdd..da52e95277 100644 --- a/include/gpu/GrSamplerState.h +++ b/include/gpu/GrSamplerState.h @@ -19,14 +19,7 @@ class GrSamplerState { public: - static const bool kBilerpDefault = false; - static const SkShader::TileMode kTileModeDefault = SkShader::kClamp_TileMode; - - /** - * Default sampler state is set to clamp, use normal sampling mode, be - * unfiltered, and use identity matrix. - */ GrSamplerState() : fCustomStage (NULL) { memset(this, 0, sizeof(GrSamplerState)); @@ -63,12 +56,6 @@ public: const GrMatrix& getMatrix() const { return fMatrix; } /** - * Access the sampler's matrix. See SampleMode for explanation of - * relationship between the matrix and sample mode. - */ - GrMatrix* matrix() { return &fMatrix; } - - /** * Multiplies the current sampler matrix a matrix * * After this call M' = M*m where M is the old matrix, m is the parameter @@ -80,10 +67,10 @@ public: */ void preConcatMatrix(const GrMatrix& matrix) { fMatrix.preConcat(matrix); } - void reset(const GrMatrix& matrix) { - fMatrix = matrix; - GrSafeSetNull(fCustomStage); - } + /** + * Do not call this function. It will be removed soon. + */ + void setMatrixDeprecated(const GrMatrix& matrix) { fMatrix = matrix; } void reset() { fMatrix.reset(); @@ -92,8 +79,16 @@ public: GrCustomStage* setCustomStage(GrCustomStage* stage) { GrSafeAssign(fCustomStage, stage); + fMatrix.reset(); return stage; } + + GrCustomStage* setCustomStage(GrCustomStage* stage, const GrMatrix& matrix) { + GrSafeAssign(fCustomStage, stage); + fMatrix = matrix; + return stage; + } + const GrCustomStage* getCustomStage() const { return fCustomStage; } private: diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp index 2f1def62c1..7e3a92bc57 100644 --- a/src/core/SkShader.cpp +++ b/src/core/SkShader.cpp @@ -205,9 +205,8 @@ SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { return kNone_GradientType; } -GrCustomStage* SkShader::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { - return NULL; +bool SkShader::asNewCustomStage(GrContext*, GrSamplerState*) const { + return false; } SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp index 7933e27999..1fa3c0da6b 100644 --- a/src/effects/SkBlendImageFilter.cpp +++ b/src/effects/SkBlendImageFilter.cpp @@ -206,10 +206,8 @@ GrTexture* SkBlendImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* src, co GrMatrix sampleM; sampleM.setIDiv(background->width(), background->height()); GrPaint paint; - paint.colorSampler(0)->reset(sampleM); - paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (background.get())))->unref(); - paint.colorSampler(1)->reset(sampleM); - paint.colorSampler(1)->setCustomStage(SkNEW_ARGS(GrBlendEffect, (fMode, foreground.get())))->unref(); + paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (background.get())), sampleM)->unref(); + paint.colorSampler(1)->setCustomStage(SkNEW_ARGS(GrBlendEffect, (fMode, foreground.get())), sampleM)->unref(); context->drawRect(paint, rect); return dst; } diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp index 64d22be56e..9bddb9b9e6 100644 --- a/src/effects/SkMorphologyImageFilter.cpp +++ b/src/effects/SkMorphologyImageFilter.cpp @@ -431,8 +431,7 @@ void apply_morphology_pass(GrContext* context, GrMatrix sampleM; sampleM.setIDiv(texture->width(), texture->height()); GrPaint paint; - paint.colorSampler(0)->reset(sampleM); - paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)))->unref(); + paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)), sampleM)->unref(); context->drawRect(paint, rect); } diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp index 4b673f6691..fff218010a 100644 --- a/src/effects/gradients/SkLinearGradient.cpp +++ b/src/effects/gradients/SkLinearGradient.cpp @@ -539,9 +539,11 @@ GrCustomStage* GrLinearGradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); GrSamplerState sampler; - GrCustomStage* stage = shader->asNewCustomStage(context, &sampler); - GrAssert(NULL != stage); - return stage; + shader->asNewCustomStage(context, &sampler); + GrAssert(NULL != sampler.getCustomStage()); + // const_cast and ref is a hack! Will remove when asNewCustomStage returns GrCustomStage* + sampler.getCustomStage()->ref(); + return const_cast<GrCustomStage*>(sampler.getCustomStage()); } ///////////////////////////////////////////////////////////////////// @@ -557,19 +559,30 @@ void GrGLLinearGradient::emitFS(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrCustomStage* SkLinearGradient::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { +bool SkLinearGradient::asNewCustomStage(GrContext* context, GrSamplerState* sampler) const { SkASSERT(NULL != context && NULL != sampler); - sampler->matrix()->preConcat(fPtsToUnit); - return SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode)); + + SkAutoTUnref<GrCustomStage> stage(SkNEW_ARGS(GrLinearGradient, (context, *this, fTileMode))); + + SkMatrix matrix; + if (this->getLocalMatrix(&matrix)) { + if (!matrix.invert(&matrix)) { + return false; + } + matrix.postConcat(fPtsToUnit); + sampler->setCustomStage(stage, matrix); + } else { + sampler->setCustomStage(stage, fPtsToUnit); + } + + return true; } #else -GrCustomStage* SkLinearGradient::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { +bool SkLinearGradient::asNewCustomStage(GrContext*, GrSamplerState*) const { SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; + return false; } #endif diff --git a/src/effects/gradients/SkLinearGradient.h b/src/effects/gradients/SkLinearGradient.h index 129a56aadc..fe60543d52 100644 --- a/src/effects/gradients/SkLinearGradient.h +++ b/src/effects/gradients/SkLinearGradient.h @@ -22,8 +22,7 @@ public: virtual void shadeSpan16(int x, int y, uint16_t dstC[], int count) SK_OVERRIDE; virtual BitmapType asABitmap(SkBitmap*, SkMatrix*, TileMode*) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrCustomStage* asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const SK_OVERRIDE; + virtual bool asNewCustomStage(GrContext* context, GrSamplerState* sampler) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLinearGradient) diff --git a/src/effects/gradients/SkRadialGradient.cpp b/src/effects/gradients/SkRadialGradient.cpp index 512eafb2ba..0156acdd54 100644 --- a/src/effects/gradients/SkRadialGradient.cpp +++ b/src/effects/gradients/SkRadialGradient.cpp @@ -538,9 +538,11 @@ GrCustomStage* GrRadialGradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); GrSamplerState sampler; - GrCustomStage* stage = shader->asNewCustomStage(context, &sampler); - GrAssert(NULL != stage); - return stage; + shader->asNewCustomStage(context, &sampler); + GrAssert(NULL != sampler.getCustomStage()); + // const_cast and ref is a hack! Will remove when asNewCustomStage returns GrCustomStage* + sampler.getCustomStage()->ref(); + return const_cast<GrCustomStage*>(sampler.getCustomStage()); } ///////////////////////////////////////////////////////////////////// @@ -556,19 +558,29 @@ void GrGLRadialGradient::emitFS(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrCustomStage* SkRadialGradient::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { +bool SkRadialGradient::asNewCustomStage(GrContext* context, GrSamplerState* sampler) const { SkASSERT(NULL != context && NULL != sampler); - sampler->matrix()->preConcat(fPtsToUnit); - return SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode)); + SkAutoTUnref<GrCustomStage> stage(SkNEW_ARGS(GrRadialGradient, (context, *this, fTileMode))); + + SkMatrix matrix; + if (this->getLocalMatrix(&matrix)) { + if (!matrix.invert(&matrix)) { + return false; + } + matrix.postConcat(fPtsToUnit); + sampler->setCustomStage(stage, matrix); + } else { + sampler->setCustomStage(stage, fPtsToUnit); + } + + return true; } #else -GrCustomStage* SkRadialGradient::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { +bool SkRadialGradient::asNewCustomStage(GrContext*, GrSamplerState*) const { SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; + return false; } #endif diff --git a/src/effects/gradients/SkRadialGradient.h b/src/effects/gradients/SkRadialGradient.h index 23a35f7fd2..fc17520e29 100644 --- a/src/effects/gradients/SkRadialGradient.h +++ b/src/effects/gradients/SkRadialGradient.h @@ -24,8 +24,7 @@ public: SkMatrix* matrix, TileMode* xy) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrCustomStage* asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const SK_OVERRIDE; + virtual bool asNewCustomStage(GrContext* context, GrSamplerState* sampler) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkRadialGradient) diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index f18b08ea9c..9fb51760e7 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -444,9 +444,11 @@ GrCustomStage* GrSweepGradient::TestCreate(SkRandom* random, SkAutoTUnref<SkShader> shader(SkGradientShader::CreateSweep(center.fX, center.fY, colors, stops, colorCount)); GrSamplerState sampler; - GrCustomStage* stage = shader->asNewCustomStage(context, &sampler); - GrAssert(NULL != stage); - return stage; + shader->asNewCustomStage(context, &sampler); + GrAssert(NULL != sampler.getCustomStage()); + // const_cast and ref is a hack! Will remove when asNewCustomStage returns GrCustomStage* + sampler.getCustomStage()->ref(); + return const_cast<GrCustomStage*>(sampler.getCustomStage()); } ///////////////////////////////////////////////////////////////////// @@ -463,18 +465,29 @@ void GrGLSweepGradient::emitFS(GrGLShaderBuilder* builder, ///////////////////////////////////////////////////////////////////// -GrCustomStage* SkSweepGradient::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { - sampler->matrix()->preConcat(fPtsToUnit); - return SkNEW_ARGS(GrSweepGradient, (context, *this)); +bool SkSweepGradient::asNewCustomStage(GrContext* context, GrSamplerState* sampler) const { + SkAutoTUnref<GrCustomStage> stage(SkNEW_ARGS(GrSweepGradient, (context, *this))); + + + SkMatrix matrix; + if (this->getLocalMatrix(&matrix)) { + if (!matrix.invert(&matrix)) { + return false; + } + matrix.postConcat(fPtsToUnit); + sampler->setCustomStage(stage, matrix); + } else { + sampler->setCustomStage(stage, fPtsToUnit); + } + + return true; } #else -GrCustomStage* SkSweepGradient::asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const { +bool SkSweepGradient::asNewCustomStage(GrContext*, GrSamplerState*) const { SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; + return false; } #endif diff --git a/src/effects/gradients/SkSweepGradient.h b/src/effects/gradients/SkSweepGradient.h index 2b9dfeb675..8e42be0921 100644 --- a/src/effects/gradients/SkSweepGradient.h +++ b/src/effects/gradients/SkSweepGradient.h @@ -24,8 +24,7 @@ public: virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrCustomStage* asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const SK_OVERRIDE; + virtual bool asNewCustomStage(GrContext* context, GrSamplerState* sampler) const SK_OVERRIDE; SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSweepGradient) diff --git a/src/effects/gradients/SkTwoPointConicalGradient.cpp b/src/effects/gradients/SkTwoPointConicalGradient.cpp index 31e3b37c13..19b1228c88 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.cpp +++ b/src/effects/gradients/SkTwoPointConicalGradient.cpp @@ -441,9 +441,11 @@ GrCustomStage* GrConical2Gradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); GrSamplerState sampler; - GrCustomStage* stage = shader->asNewCustomStage(context, &sampler); - GrAssert(NULL != stage); - return stage; + shader->asNewCustomStage(context, &sampler); + GrAssert(NULL != sampler.getCustomStage()); + // const_cast and ref is a hack! Will remove when asNewCustomStage returns GrCustomStage* + sampler.getCustomStage()->ref(); + return const_cast<GrCustomStage*>(sampler.getCustomStage()); } @@ -673,28 +675,40 @@ GrCustomStage::StageKey GrGLConical2Gradient::GenKey(const GrCustomStage& s, con ///////////////////////////////////////////////////////////////////// -GrCustomStage* SkTwoPointConicalGradient::asNewCustomStage( - GrContext* context, GrSamplerState* sampler) const { +bool SkTwoPointConicalGradient::asNewCustomStage(GrContext* context, + GrSamplerState* sampler) const { SkASSERT(NULL != context && NULL != sampler); + + SkMatrix matrix; SkPoint diff = fCenter2 - fCenter1; SkScalar diffLen = diff.length(); if (0 != diffLen) { SkScalar invDiffLen = SkScalarInvert(diffLen); - sampler->matrix()->setSinCos(-SkScalarMul(invDiffLen, diff.fY), - SkScalarMul(invDiffLen, diff.fX)); + matrix.setSinCos(-SkScalarMul(invDiffLen, diff.fY), + SkScalarMul(invDiffLen, diff.fX)); } else { - sampler->matrix()->reset(); + matrix.reset(); + } + matrix.preTranslate(-fCenter1.fX, -fCenter1.fY); + + SkMatrix localM; + if (this->getLocalMatrix(&localM)) { + if (!localM.invert(&localM)) { + return false; + } + matrix.preConcat(localM); } - sampler->matrix()->preTranslate(-fCenter1.fX, -fCenter1.fY); - return SkNEW_ARGS(GrConical2Gradient, (context, *this, fTileMode)); + + sampler->setCustomStage(SkNEW_ARGS(GrConical2Gradient, (context, *this, fTileMode)), matrix)->unref(); + + return true; } #else -GrCustomStage* SkTwoPointConicalGradient::asNewCustomStage( - GrContext* context, GrSamplerState* sampler) const { +bool SkTwoPointConicalGradient::asNewCustomStage(GrContext*, GrSamplerState*) const { SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; + return false; } #endif diff --git a/src/effects/gradients/SkTwoPointConicalGradient.h b/src/effects/gradients/SkTwoPointConicalGradient.h index 4ce72801e0..40544919c3 100644 --- a/src/effects/gradients/SkTwoPointConicalGradient.h +++ b/src/effects/gradients/SkTwoPointConicalGradient.h @@ -61,8 +61,7 @@ public: SkMatrix* matrix, TileMode* xy) const; virtual SkShader::GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrCustomStage* asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const SK_OVERRIDE; + virtual bool asNewCustomStage(GrContext* context, GrSamplerState* sampler) const SK_OVERRIDE; SkScalar getCenterX1() const { return SkPoint::Distance(fCenter1, fCenter2); } SkScalar getStartRadius() const { return fRadius1; } diff --git a/src/effects/gradients/SkTwoPointRadialGradient.cpp b/src/effects/gradients/SkTwoPointRadialGradient.cpp index 97f335d97c..2715511e1b 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.cpp +++ b/src/effects/gradients/SkTwoPointRadialGradient.cpp @@ -475,9 +475,11 @@ GrCustomStage* GrRadial2Gradient::TestCreate(SkRandom* random, colors, stops, colorCount, tm)); GrSamplerState sampler; - GrCustomStage* stage = shader->asNewCustomStage(context, &sampler); - GrAssert(NULL != stage); - return stage; + shader->asNewCustomStage(context, &sampler); + GrAssert(NULL != sampler.getCustomStage()); + // const_cast and ref is a hack! Will remove when asNewCustomStage returns GrCustomStage* + sampler.getCustomStage()->ref(); + return const_cast<GrCustomStage*>(sampler.getCustomStage()); } ///////////////////////////////////////////////////////////////////// @@ -647,27 +649,38 @@ GrCustomStage::StageKey GrGLRadial2Gradient::GenKey(const GrCustomStage& s, cons ///////////////////////////////////////////////////////////////////// -GrCustomStage* SkTwoPointRadialGradient::asNewCustomStage( - GrContext* context, GrSamplerState* sampler) const { +bool SkTwoPointRadialGradient::asNewCustomStage(GrContext* context, + GrSamplerState* sampler) const { SkASSERT(NULL != context && NULL != sampler); SkScalar diffLen = fDiff.length(); + SkMatrix matrix; if (0 != diffLen) { SkScalar invDiffLen = SkScalarInvert(diffLen); - sampler->matrix()->setSinCos(-SkScalarMul(invDiffLen, fDiff.fY), - SkScalarMul(invDiffLen, fDiff.fX)); + matrix.setSinCos(-SkScalarMul(invDiffLen, fDiff.fY), + SkScalarMul(invDiffLen, fDiff.fX)); } else { - sampler->matrix()->reset(); + matrix.reset(); } - sampler->matrix()->preConcat(fPtsToUnit); - return SkNEW_ARGS(GrRadial2Gradient, (context, *this, fTileMode)); + + matrix.preConcat(fPtsToUnit); + + SkMatrix localM; + if (this->getLocalMatrix(&localM)) { + if (!localM.invert(&localM)) { + return false; + } + matrix.preConcat(localM); + } + + sampler->setCustomStage(SkNEW_ARGS(GrRadial2Gradient, (context, *this, fTileMode)), matrix)->unref(); + return true; } #else -GrCustomStage* SkTwoPointRadialGradient::asNewCustomStage( - GrContext* context, GrSamplerState* sampler) const { +bool SkTwoPointRadialGradient::asNewCustomStage(GrContext*, GrSamplerState*) const { SkDEBUGFAIL("Should not call in GPU-less build"); - return NULL; + return false; } #endif diff --git a/src/effects/gradients/SkTwoPointRadialGradient.h b/src/effects/gradients/SkTwoPointRadialGradient.h index a6036f176f..adbb602265 100644 --- a/src/effects/gradients/SkTwoPointRadialGradient.h +++ b/src/effects/gradients/SkTwoPointRadialGradient.h @@ -23,8 +23,7 @@ public: SkMatrix* matrix, TileMode* xy) const SK_OVERRIDE; virtual GradientType asAGradient(GradientInfo* info) const SK_OVERRIDE; - virtual GrCustomStage* asNewCustomStage(GrContext* context, - GrSamplerState* sampler) const SK_OVERRIDE; + virtual bool asNewCustomStage(GrContext* context, GrSamplerState* sampler) const SK_OVERRIDE; virtual void shadeSpan(int x, int y, SkPMColor* dstCParam, int count) SK_OVERRIDE; diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 322fba146a..6104f66e81 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -33,7 +33,7 @@ void setup_drawstate_aaclip(GrGpu* gpu, GrDrawState* drawState = gpu->drawState(); GrAssert(drawState); - static const int maskStage = GrPaint::kTotalStages+1; + static const int kMaskStage = GrPaint::kTotalStages+1; GrMatrix mat; mat.setIDiv(result->width(), result->height()); @@ -41,9 +41,8 @@ void setup_drawstate_aaclip(GrGpu* gpu, SkIntToScalar(-devBound.fTop)); mat.preConcat(drawState->getViewMatrix()); - drawState->sampler(maskStage)->reset(mat); - - drawState->createTextureEffect(maskStage, result); + drawState->sampler(kMaskStage)->reset(); + drawState->createTextureEffect(kMaskStage, result, mat); } bool path_needs_SW_renderer(GrContext* context, @@ -495,8 +494,7 @@ void GrClipMaskManager::drawTexture(GrTexture* target, GrMatrix sampleM; sampleM.setIDiv(texture->width(), texture->height()); - drawState->sampler(0)->reset(sampleM); - drawState->createTextureEffect(0, texture); + drawState->createTextureEffect(0, texture, sampleM); GrRect rect = GrRect::MakeWH(SkIntToScalar(target->width()), SkIntToScalar(target->height())); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index ee3a4e1afb..8b7d2d0285 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -202,11 +202,10 @@ void convolve_gaussian(GrDrawTarget* target, drawState->setRenderTarget(rt); GrMatrix sampleM; sampleM.setIDiv(texture->width(), texture->height()); - drawState->sampler(0)->reset(sampleM); SkAutoTUnref<GrConvolutionEffect> conv(SkNEW_ARGS(GrConvolutionEffect, (texture, direction, radius, sigma))); - drawState->sampler(0)->setCustomStage(conv); + drawState->sampler(0)->setCustomStage(conv, sampleM); target->drawSimpleRect(rect, NULL); } @@ -313,9 +312,8 @@ GrTexture* GrContext::createResizedTexture(const GrTextureDesc& desc, // if filtering is not desired then we want to ensure all // texels in the resampled image are copies of texels from // the original. - drawState->sampler(0)->reset(); GrTextureParams params(SkShader::kClamp_TileMode, needsFiltering); - drawState->createTextureEffect(0, clampedTexture, params); + drawState->createTextureEffect(0, clampedTexture, GrMatrix::I(), params); static const GrVertexLayout layout = GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); @@ -1348,8 +1346,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target, matrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top); } matrix.postIDiv(src->width(), src->height()); - drawState->sampler(0)->reset(matrix); - drawState->sampler(0)->setCustomStage(stage); + drawState->sampler(0)->setCustomStage(stage, matrix); GrRect rect = GrRect::MakeWH(GrIntToScalar(width), GrIntToScalar(height)); fGpu->drawSimpleRect(rect, NULL); // we want to read back from the scratch's origin @@ -1449,8 +1446,7 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) { drawState->setRenderTarget(dst); GrMatrix sampleM; sampleM.setIDiv(src->width(), src->height()); - drawState->sampler(0)->reset(sampleM); - drawState->createTextureEffect(0, src); + drawState->createTextureEffect(0, src, sampleM); SkRect rect = SkRect::MakeXYWH(0, 0, SK_Scalar1 * src->width(), SK_Scalar1 * src->height()); @@ -1558,8 +1554,7 @@ void GrContext::writeRenderTargetPixels(GrRenderTarget* target, drawState->setRenderTarget(target); matrix.setIDiv(texture->width(), texture->height()); - drawState->sampler(0)->reset(matrix); - drawState->sampler(0)->setCustomStage(stage); + drawState->sampler(0)->setCustomStage(stage, matrix); fGpu->drawSimpleRect(GrRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)), NULL); } @@ -1813,14 +1808,15 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, paint.reset(); for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { - paint.colorSampler(0)->matrix()->setIDiv(srcTexture->width(), - srcTexture->height()); + GrMatrix matrix; + matrix.setIDiv(srcTexture->width(), srcTexture->height()); this->setRenderTarget(dstTexture->asRenderTarget()); SkRect dstRect(srcRect); scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, - i < scaleFactorY ? 0.5f : 1.0f); + i < scaleFactorY ? 0.5f : 1.0f); + paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, - (srcTexture, true)))->unref(); + (srcTexture, true)), matrix)->unref(); this->drawRectToRect(paint, dstRect, srcRect); srcRect = dstRect; srcTexture = dstTexture; @@ -1873,12 +1869,13 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 1, srcIRect.height()); this->clear(&clearRect, 0x0); + GrMatrix matrix; // FIXME: This should be mitchell, not bilinear. - paint.colorSampler(0)->matrix()->setIDiv(srcTexture->width(), - srcTexture->height()); + matrix.setIDiv(srcTexture->width(), srcTexture->height()); this->setRenderTarget(dstTexture->asRenderTarget()); paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, - (srcTexture, true)))->unref(); + (srcTexture, true)), + matrix)->unref(); SkRect dstRect(srcRect); scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); this->drawRectToRect(paint, dstRect, srcRect); diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index da81a76a73..cc11f6cd87 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -54,7 +54,7 @@ void GrDrawState::AutoViewMatrixRestore::restore() { fDrawState->setViewMatrix(fViewMatrix); for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (fRestoreMask & (1 << s)) { - *fDrawState->sampler(s)->matrix() = fSamplerMatrices[s]; + fDrawState->sampler(s)->setMatrixDeprecated(fSamplerMatrices[s]); } } } @@ -77,6 +77,7 @@ void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState, for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) { fRestoreMask |= (1 << s); + fSamplerMatrices[s] = drawState->sampler(s)->getMatrix(); drawState->sampler(s)->preConcatMatrix(preconcatMatrix); } } @@ -89,7 +90,7 @@ void GrDrawState::AutoDeviceCoordDraw::restore() { fDrawState->setViewMatrix(fViewMatrix); for (int s = 0; s < GrDrawState::kNumStages; ++s) { if (fRestoreMask & (1 << s)) { - *fDrawState->sampler(s)->matrix() = fSamplerMatrices[s]; + fDrawState->sampler(s)->setMatrixDeprecated(fSamplerMatrices[s]); } } } diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 69f0aea0a9..f3d5e37d20 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -42,8 +42,9 @@ public: * * Stages 0 through GrPaint::kTotalStages-1 are reserved for setting up * the draw (i.e., textures and filter masks). Stages GrPaint::kTotalStages - * through kNumStages-1 are earmarked for use by GrTextContext and - * GrPathRenderer-derived classes. + * through kNumStages-2 are earmarked for use by GrTextContext and + * GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping + * by GrClipMaskManager. */ enum { kNumStages = 5, @@ -194,10 +195,17 @@ public: this->sampler(stage)->setCustomStage( SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); } - void createTextureEffect(int stage, GrTexture* texture, const GrTextureParams& params) { + void createTextureEffect(int stage, GrTexture* texture, const GrMatrix& matrix) { GrAssert(!this->getSampler(stage).getCustomStage()); - this->sampler(stage)->setCustomStage( - SkNEW_ARGS(GrSingleTextureEffect, (texture, params)))->unref(); + GrCustomStage* customStage = SkNEW_ARGS(GrSingleTextureEffect, (texture)); + this->sampler(stage)->setCustomStage(customStage, matrix)->unref(); + } + void createTextureEffect(int stage, GrTexture* texture, + const GrMatrix& matrix, + const GrTextureParams& params) { + GrAssert(!this->getSampler(stage).getCustomStage()); + GrCustomStage* customStage = SkNEW_ARGS(GrSingleTextureEffect, (texture, params)); + this->sampler(stage)->setCustomStage(customStage, matrix)->unref(); } diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp index c9944b9942..59b9cb3fa0 100644 --- a/src/gpu/GrTextContext.cpp +++ b/src/gpu/GrTextContext.cpp @@ -19,7 +19,6 @@ #include "SkPath.h" enum { - kGlyphMaskStage = GrPaint::kTotalStages, }; @@ -35,7 +34,7 @@ void GrTextContext::flushGlyphs() { GrAssert(GrIsALIGN4(fCurrVertex)); GrAssert(fCurrTexture); GrTextureParams params(SkShader::kRepeat_TileMode, false); - drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, params); + drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, GrMatrix::I(), params); if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) { if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() || diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index a09b57ff10..02bfdbd215 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -548,25 +548,14 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev, } GrSamplerState* sampler = grPaint->colorSampler(kShaderTextureIdx); - GrCustomStage* stage = shader->asNewCustomStage(dev->context(), sampler); - - if (NULL != stage) { - sampler->setCustomStage(stage)->unref(); - SkMatrix localM; - if (shader->getLocalMatrix(&localM)) { - SkMatrix inverse; - if (localM.invert(&inverse)) { - sampler->matrix()->preConcat(inverse); - } - } + if (shader->asNewCustomStage(dev->context(), sampler)) { return true; } SkBitmap bitmap; - SkMatrix* matrix = sampler->matrix(); + SkMatrix matrix; SkShader::TileMode tileModes[2]; - SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, matrix, - tileModes); + SkShader::BitmapType bmptype = shader->asABitmap(&bitmap, &matrix, tileModes); if (SkShader::kNone_BitmapType == bmptype) { SkShader::GradientInfo info; @@ -600,23 +589,21 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev, return false; } - sampler->reset(); - sampler->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (texture, params)))->unref(); - - // since our texture coords will be in local space, we wack the texture + // since our texture coords will be in local space, we whack the texture // matrix to map them back into 0...1 before we load it SkMatrix localM; if (shader->getLocalMatrix(&localM)) { SkMatrix inverse; if (localM.invert(&inverse)) { - matrix->preConcat(inverse); + matrix.preConcat(inverse); } } if (SkShader::kDefault_BitmapType == bmptype) { GrScalar sx = SkFloatToScalar(1.f / bitmap.width()); GrScalar sy = SkFloatToScalar(1.f / bitmap.height()); - matrix->postScale(sx, sy); + matrix.postScale(sx, sy); } + sampler->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (texture, params)), matrix)->unref(); return true; } @@ -876,13 +863,11 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, if (!isNormalBlur) { context->setIdentityMatrix(); GrPaint paint; - paint.reset(); - paint.colorSampler(0)->matrix()->setIDiv(pathTexture->width(), - pathTexture->height()); + GrMatrix matrix; + matrix.setIDiv(pathTexture->width(), pathTexture->height()); // Blend pathTexture over blurTexture. context->setRenderTarget(blurTexture->asRenderTarget()); - paint.colorSampler(0)->setCustomStage(SkNEW_ARGS - (GrSingleTextureEffect, (pathTexture)))->unref(); + paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (pathTexture)), matrix)->unref(); if (SkMaskFilter::kInner_BlurType == blurType) { // inner: dst = dst * src paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff); @@ -907,13 +892,13 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& devPath, static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; // we assume the last mask index is available for use GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); + + GrMatrix matrix; + matrix.setTranslate(-finalRect.fLeft, -finalRect.fTop); + matrix.postIDiv(blurTexture->width(), blurTexture->height()); + grp->coverageSampler(MASK_IDX)->reset(); - grp->coverageSampler(MASK_IDX)->setCustomStage( - SkNEW_ARGS(GrSingleTextureEffect, (blurTexture)))->unref(); - grp->coverageSampler(MASK_IDX)->matrix()->setTranslate(-finalRect.fLeft, - -finalRect.fTop); - grp->coverageSampler(MASK_IDX)->matrix()->postIDiv(blurTexture->width(), - blurTexture->height()); + grp->coverageSampler(MASK_IDX)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (blurTexture)), matrix)->unref(); context->drawRect(*grp, finalRect); return true; } @@ -964,19 +949,18 @@ bool drawWithMaskFilter(GrContext* context, const SkPath& devPath, static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1; // we assume the last mask index is available for use GrAssert(!grp->isCoverageStageEnabled(MASK_IDX)); - grp->coverageSampler(MASK_IDX)->reset(); - grp->coverageSampler(MASK_IDX)->setCustomStage( - SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref(); + + GrMatrix m; + m.setTranslate(-dstM.fBounds.fLeft*SK_Scalar1, -dstM.fBounds.fTop*SK_Scalar1); + m.postIDiv(texture->width(), texture->height()); + + grp->coverageSampler(MASK_IDX)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (texture)), m)->unref(); GrRect d; d.setLTRB(GrIntToScalar(dstM.fBounds.fLeft), GrIntToScalar(dstM.fBounds.fTop), GrIntToScalar(dstM.fBounds.fRight), GrIntToScalar(dstM.fBounds.fBottom)); - GrMatrix* m = grp->coverageSampler(MASK_IDX)->matrix(); - m->setTranslate(-dstM.fBounds.fLeft*SK_Scalar1, - -dstM.fBounds.fTop*SK_Scalar1); - m->postIDiv(texture->width(), texture->height()); context->drawRect(*grp, d); return true; } @@ -1385,8 +1369,6 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap, GrSamplerState* sampler = grPaint->colorSampler(kBitmapTextureIdx); - sampler->matrix()->reset(); - GrTexture* texture; SkAutoCachedTexture act(this, bitmap, ¶ms, &texture); if (NULL == texture) { @@ -1469,8 +1451,7 @@ void apply_custom_stage(GrContext* context, GrMatrix sampleM; sampleM.setIDiv(srcTexture->width(), srcTexture->height()); GrPaint paint; - paint.colorSampler(0)->reset(sampleM); - paint.colorSampler(0)->setCustomStage(stage); + paint.colorSampler(0)->setCustomStage(stage, sampleM); context->drawRect(paint, rect); } |