aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/texdata.cpp5
-rw-r--r--include/gpu/GrPaint.h165
-rw-r--r--src/effects/SkBlendImageFilter.cpp1
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp1
-rw-r--r--src/gpu/GrContext.cpp10
-rw-r--r--src/gpu/GrDrawState.cpp16
-rw-r--r--src/gpu/GrTextContext.cpp11
-rw-r--r--src/gpu/SkGpuDevice.cpp47
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp1
9 files changed, 163 insertions, 94 deletions
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index a87be453ea..724b4ec826 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -100,10 +100,7 @@ protected:
ctx->setRenderTarget(target);
GrPaint paint;
- paint.reset();
- paint.fColor = 0xffffffff;
- paint.fSrcBlendCoeff = kOne_GrBlendCoeff;
- paint.fDstBlendCoeff = kISA_GrBlendCoeff;
+ paint.setBlendFunc(kOne_GrBlendCoeff, kISA_GrBlendCoeff);
GrMatrix vm;
if (i) {
vm.setRotate(90 * SK_Scalar1,
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 9b07a4be16..9f9403e9e7 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -17,9 +17,31 @@
#include "SkXfermode.h"
/**
- * The paint describes how pixels are colored when the context draws to
- * them. TODO: Make this a "real" class with getters and setters, default
- * values, and documentation.
+ * The paint describes how color and coverage are computed at each pixel by GrContext draw
+ * functions and the how color is blended with the destination pixel.
+ *
+ * The paint allows installation of custom color and coverage stages. New types of stages are
+ * created by subclassing GrCustomStage.
+ *
+ * The primitive color computation starts with the color specified by setColor(). This color is the
+ * input to the first color stage. Each color stage feeds its output to the next color stage. The
+ * final color stage's output color is input to the color filter specified by
+ * setXfermodeColorFilter which it turn feeds into the color matrix. The output of the color matrix
+ * is the final source color, S.
+ *
+ * Fractional pixel coverage follows a similar flow. The coverage is initially the value specified
+ * by setCoverage(). This is input to the first coverage stage. Coverage stages are chained
+ * together in the same manner as color stages. The output of the last stage is modulated by any
+ * fractional coverage produced by anti-aliasing. This last step produces the final coverage, C.
+ *
+ * setBlendFunc() specifies blending coefficients for S (described above) and D, the initial value
+ * of the destination pixel, labeled Bs and Bd respectively. The final value of the destination
+ * pixel is then D' = (1-C)*D + C*(Bd*D + Bs*S).
+ *
+ * Note that the coverage is applied after the blend. This is why they are computed as distinct
+ * values.
+ *
+ * TODO: Encapsulate setXfermodeColorFilter and color matrix in stages and remove from GrPaint.
*/
class GrPaint {
public:
@@ -28,20 +50,90 @@ public:
kMaxCoverageStages = 1,
};
- // All the paint fields are public except textures/samplers
- GrBlendCoeff fSrcBlendCoeff;
- GrBlendCoeff fDstBlendCoeff;
- bool fAntiAlias;
- bool fDither;
- bool fColorMatrixEnabled;
+ GrPaint() { this->reset(); }
- GrColor fColor;
- uint8_t fCoverage;
+ GrPaint(const GrPaint& paint) { *this = paint; }
- GrColor fColorFilterColor;
- SkXfermode::Mode fColorFilterXfermode;
- float fColorMatrix[20];
+ ~GrPaint() {}
+
+ /**
+ * Sets the blending coefficients to use to blend the final primitive color with the
+ * destination color. Defaults to kOne for src and kZero for dst (i.e. src mode).
+ */
+ void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ fSrcBlendCoeff = srcCoeff;
+ fDstBlendCoeff = dstCoeff;
+ }
+ GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlendCoeff; }
+ GrBlendCoeff getDstBlendCoeff() const { return fDstBlendCoeff; }
+
+ /**
+ * The initial color of the drawn primitive. Defaults to solid white.
+ */
+ void setColor(GrColor color) { fColor = color; }
+ GrColor getColor() const { return fColor; }
+
+ /**
+ * Applies fractional coverage to the entire drawn primitive. Defaults to 0xff.
+ */
+ void setCoverage(uint8_t coverage) { fCoverage = coverage; }
+ uint8_t getCoverage() const { return fCoverage; }
+
+ /**
+ * Should primitives be anti-aliased or not. Defaults to false.
+ */
+ void setAntiAlias(bool aa) { fAntiAlias = aa; }
+ bool isAntiAlias() const { return fAntiAlias; }
+
+ /**
+ * Should dithering be applied. Defaults to false.
+ */
+ void setDither(bool dither) { fDither = dither; }
+ bool isDither() const { return fDither; }
+
+ /**
+ * Enables a SkXfermode::Mode-based color filter applied to the primitive color. The constant
+ * color passed to this function is considered the "src" color and the primitive's color is
+ * considered the "dst" color. Defaults to kDst_Mode which equates to simply passing through
+ * the primitive color unmodified.
+ */
+ void setXfermodeColorFilter(SkXfermode::Mode mode, GrColor color) {
+ fColorFilterColor = color;
+ fColorFilterXfermode = mode;
+ }
+ SkXfermode::Mode getColorFilterMode() const { return fColorFilterXfermode; }
+ GrColor getColorFilterColor() const { return fColorFilterColor; }
+
+ /**
+ * Turns off application of a color matrix. By default the color matrix is disabled.
+ */
+ void disableColorMatrix() { fColorMatrixEnabled = false; }
+
+ /**
+ * Specifies and enables a 4 x 5 color matrix.
+ */
+ void setColorMatrix(const float matrix[20]) {
+ fColorMatrixEnabled = true;
+ memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
+ }
+
+ bool isColorMatrixEnabled() const { return fColorMatrixEnabled; }
+ const float* getColorMatrix() const { return fColorMatrix; }
+
+ /**
+ * Disables both the matrix and SkXfermode::Mode color filters.
+ */
+ void resetColorFilter() {
+ fColorFilterXfermode = SkXfermode::kDst_Mode;
+ fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
+ fColorMatrixEnabled = false;
+ }
+ /**
+ * Specifies a stage of the color pipeline. Usually the texture matrices of color stages apply
+ * to the primitive's positions. Some GrContext calls take explicit coords as an array or a
+ * rect. In this case these are the pre-matrix coords to colorSampler(0).
+ */
GrSamplerState* colorSampler(int i) {
GrAssert((unsigned)i < kMaxColorStages);
return fColorSamplers + i;
@@ -57,8 +149,10 @@ public:
return (NULL != fColorSamplers[i].getCustomStage());
}
- // The coverage stage's sampler matrix is always applied to the positions
- // (i.e. no explicit texture coordinates)
+ /**
+ * Specifies a stage of the coverage pipeline. Coverage stages' texture matrices are always
+ * applied to the primitive's position, never to explicit texture coords.
+ */
GrSamplerState* coverageSampler(int i) {
GrAssert((unsigned)i < kMaxCoverageStages);
return fCoverageSamplers + i;
@@ -95,9 +189,9 @@ public:
bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
/**
- * Preconcats the matrix of all samplers in the mask with the inverse of a
- * matrix. If the matrix inverse cannot be computed (and there is at least
- * one enabled stage) then false is returned.
+ * Preconcats the matrix of all samplers in the mask with the inverse of a matrix. If the
+ * matrix inverse cannot be computed (and there is at least one enabled stage) then false is
+ * returned.
*/
bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
GrMatrix inv;
@@ -125,16 +219,6 @@ public:
return true;
}
- // uninitialized
- GrPaint() {
- }
-
- GrPaint(const GrPaint& paint) {
- *this = paint;
- }
-
- ~GrPaint() {}
-
GrPaint& operator=(const GrPaint& paint) {
fSrcBlendCoeff = paint.fSrcBlendCoeff;
fDstBlendCoeff = paint.fDstBlendCoeff;
@@ -164,7 +248,9 @@ public:
return *this;
}
- // sets paint to src-over, solid white, no texture, no mask
+ /**
+ * Resets the paint to the defaults.
+ */
void reset() {
this->resetBlend();
this->resetOptions();
@@ -175,12 +261,6 @@ public:
this->resetMasks();
}
- void resetColorFilter() {
- fColorFilterXfermode = SkXfermode::kDst_Mode;
- fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
- fColorMatrixEnabled = false;
- }
-
// internal use
// GrPaint's textures and masks map to the first N stages
// of GrDrawTarget in that order (textures followed by masks)
@@ -195,6 +275,19 @@ private:
GrSamplerState fColorSamplers[kMaxColorStages];
GrSamplerState fCoverageSamplers[kMaxCoverageStages];
+ GrBlendCoeff fSrcBlendCoeff;
+ GrBlendCoeff fDstBlendCoeff;
+ bool fAntiAlias;
+ bool fDither;
+ bool fColorMatrixEnabled;
+
+ GrColor fColor;
+ uint8_t fCoverage;
+
+ GrColor fColorFilterColor;
+ SkXfermode::Mode fColorFilterXfermode;
+ float fColorMatrix[20];
+
void resetBlend() {
fSrcBlendCoeff = kOne_GrBlendCoeff;
fDstBlendCoeff = kZero_GrBlendCoeff;
diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp
index f1714003b9..1388e336dc 100644
--- a/src/effects/SkBlendImageFilter.cpp
+++ b/src/effects/SkBlendImageFilter.cpp
@@ -217,7 +217,6 @@ GrTexture* SkBlendImageFilter::onFilterImageGPU(Proxy* proxy, GrTexture* src, co
GrMatrix sampleM;
sampleM.setIDiv(background->width(), background->height());
GrPaint paint;
- paint.reset();
paint.colorSampler(0)->reset(sampleM);
paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrSingleTextureEffect, (background.get())))->unref();
paint.colorSampler(1)->reset(sampleM);
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index 7a4f5a9dbf..e00d94a754 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -431,7 +431,6 @@ void apply_morphology_pass(GrContext* context,
GrMatrix sampleM;
sampleM.setIDiv(texture->width(), texture->height());
GrPaint paint;
- paint.reset();
paint.colorSampler(0)->reset(sampleM);
paint.colorSampler(0)->setCustomStage(SkNEW_ARGS(GrMorphologyEffect, (texture, direction, radius, morphType)))->unref();
context->drawRect(paint, rect);
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index d6e0b508eb..3e53c19ff8 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -613,13 +613,13 @@ void GrContext::drawPaint(const GrPaint& paint) {
am.set(this, GrMatrix::I());
}
// by definition this fills the entire clip, no need for AA
- if (paint.fAntiAlias) {
+ if (paint.isAntiAlias()) {
if (!tmpPaint.isValid()) {
tmpPaint.set(paint);
p = tmpPaint.get();
}
GrAssert(p == tmpPaint.get());
- tmpPaint.get()->fAntiAlias = false;
+ tmpPaint.get()->setAntiAlias(false);
}
this->drawRect(*p, r);
}
@@ -736,7 +736,7 @@ void GrContext::drawRect(const GrPaint& paint,
GrRect devRect = rect;
GrMatrix combinedMatrix;
bool useVertexCoverage;
- bool needAA = paint.fAntiAlias &&
+ bool needAA = paint.isAntiAlias() &&
!this->getRenderTarget()->isMultisampled();
bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix,
&combinedMatrix, &devRect,
@@ -1013,7 +1013,7 @@ void GrContext::drawOval(const GrPaint& paint,
SkScalar strokeWidth) {
GrAssert(strokeWidth <= 0);
if (!isSimilarityTransformation(this->getMatrix()) ||
- !paint.fAntiAlias ||
+ !paint.isAntiAlias() ||
rect.height() != rect.width()) {
SkPath path;
path.addOval(rect);
@@ -1125,7 +1125,7 @@ void GrContext::internalDrawPath(const GrPaint& paint, const SkPath& path,
GrDrawTarget* target = this->prepareToDraw(&paint, DEFAULT_BUFFERING);
GrDrawState::AutoStageDisable atr(fDrawState);
- bool prAA = paint.fAntiAlias && !this->getRenderTarget()->isMultisampled();
+ bool prAA = paint.isAntiAlias() && !this->getRenderTarget()->isMultisampled();
// An Assumption here is that path renderer would use some form of tweaking
// the src color (either the input alpha or in the frag shader) to implement
diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp
index bd6e2685bb..f798cda59c 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -31,18 +31,18 @@ void GrDrawState::setFromPaint(const GrPaint& paint) {
this->disableStage(s);
}
- this->setColor(paint.fColor);
+ this->setColor(paint.getColor());
- this->setState(GrDrawState::kDither_StateBit, paint.fDither);
- this->setState(GrDrawState::kHWAntialias_StateBit, paint.fAntiAlias);
+ this->setState(GrDrawState::kDither_StateBit, paint.isDither());
+ this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
- if (paint.fColorMatrixEnabled) {
+ if (paint.isColorMatrixEnabled()) {
this->enableState(GrDrawState::kColorMatrix_StateBit);
- this->setColorMatrix(paint.fColorMatrix);
+ this->setColorMatrix(paint.getColorMatrix());
} else {
this->disableState(GrDrawState::kColorMatrix_StateBit);
}
- this->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
- this->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
- this->setCoverage(paint.fCoverage);
+ this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
+ this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode());
+ this->setCoverage(paint.getCoverage());
}
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 5c8b9e50d3..c245401d9a 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -38,22 +38,21 @@ void GrTextContext::flushGlyphs() {
drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, params);
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
- if (kOne_GrBlendCoeff != fPaint.fSrcBlendCoeff ||
- kISA_GrBlendCoeff != fPaint.fDstBlendCoeff ||
+ if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
+ kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
fPaint.hasColorStage()) {
GrPrintf("LCD Text will not draw correctly.\n");
}
// setup blend so that we get mask * paintColor + (1-mask)*dstColor
- drawState->setBlendConstant(fPaint.fColor);
+ drawState->setBlendConstant(fPaint.getColor());
drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
// don't modulate by the paint's color in the frag since we're
// already doing it via the blend const.
drawState->setColor(0xffffffff);
} else {
// set back to normal in case we took LCD path previously.
- drawState->setBlendFunc(fPaint.fSrcBlendCoeff,
- fPaint.fDstBlendCoeff);
- drawState->setColor(fPaint.fColor);
+ drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ drawState->setColor(fPaint.getColor());
}
int nGlyphs = fCurrVertex / 4;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index a792977ff8..b0b5ed0453 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -510,9 +510,8 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
SkGpuDevice::SkAutoCachedTexture* act,
GrPaint* grPaint) {
- grPaint->fDither = skPaint.isDither();
- grPaint->fAntiAlias = skPaint.isAntiAlias();
- grPaint->fCoverage = 0xFF;
+ grPaint->setDither(skPaint.isDither());
+ grPaint->setAntiAlias(skPaint.isAntiAlias());
SkXfermode::Coeff sm = SkXfermode::kOne_Coeff;
SkXfermode::Coeff dm = SkXfermode::kISA_Coeff;
@@ -526,17 +525,16 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
#endif
}
}
- grPaint->fSrcBlendCoeff = sk_blend_to_grblend(sm);
- grPaint->fDstBlendCoeff = sk_blend_to_grblend(dm);
+ grPaint->setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
if (justAlpha) {
uint8_t alpha = skPaint.getAlpha();
- grPaint->fColor = GrColorPackRGBA(alpha, alpha, alpha, alpha);
+ grPaint->setColor(GrColorPackRGBA(alpha, alpha, alpha, alpha));
// justAlpha is currently set to true only if there is a texture,
// so constantColor should not also be true.
GrAssert(!constantColor);
} else {
- grPaint->fColor = SkColor2GrColor(skPaint.getColor());
+ grPaint->setColor(SkColor2GrColor(skPaint.getColor()));
GrAssert(!grPaint->isColorStageEnabled(kShaderTextureIdx));
}
SkColorFilter* colorFilter = skPaint.getColorFilter();
@@ -544,24 +542,17 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
SkXfermode::Mode filterMode;
SkScalar matrix[20];
SkBitmap colorTransformTable;
- grPaint->resetColorFilter();
// TODO: SkColorFilter::asCustomStage()
if (colorFilter != NULL && colorFilter->asColorMode(&color, &filterMode)) {
- grPaint->fColorMatrixEnabled = false;
if (!constantColor) {
- grPaint->fColorFilterColor = SkColor2GrColor(color);
- grPaint->fColorFilterXfermode = filterMode;
+ grPaint->setXfermodeColorFilter(filterMode, SkColor2GrColor(color));
} else {
SkColor filtered = colorFilter->filterColor(skPaint.getColor());
- grPaint->fColor = SkColor2GrColor(filtered);
+ grPaint->setColor(SkColor2GrColor(filtered));
}
} else if (colorFilter != NULL && colorFilter->asColorMatrix(matrix)) {
- grPaint->fColorMatrixEnabled = true;
- memcpy(grPaint->fColorMatrix, matrix, sizeof(matrix));
- grPaint->fColorFilterXfermode = SkXfermode::kDst_Mode;
+ grPaint->setColorMatrix(matrix);
} else if (colorFilter != NULL && colorFilter->asComponentTable(&colorTransformTable)) {
- grPaint->resetColorFilter();
-
// pass NULL because the color table effect doesn't use tiling or filtering.
GrTexture* texture = act->set(dev, colorTransformTable, NULL);
GrSamplerState* colorSampler = grPaint->colorSampler(kColorFilterTextureIdx);
@@ -895,18 +886,16 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
context->clear(NULL, 0);
GrPaint tempPaint;
- tempPaint.reset();
- tempPaint.fAntiAlias = grp->fAntiAlias;
- if (tempPaint.fAntiAlias) {
+ if (grp->isAntiAlias()) {
+ tempPaint.setAntiAlias(true);
// AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst
// blend coeff of zero requires dual source blending support in order
// to properly blend partially covered pixels. This means the AA
// code path may not be taken. So we use a dst blend coeff of ISA. We
// could special case AA draws to a dst surface with known alpha=0 to
// use a zero dst coeff when dual source blending isn't available.
- tempPaint.fSrcBlendCoeff = kOne_GrBlendCoeff;
- tempPaint.fDstBlendCoeff = kISC_GrBlendCoeff;
+ tempPaint.setBlendFunc(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
}
// Draw hard shadow to pathTexture with path topleft at origin 0,0.
context->drawPath(tempPaint, path, pathFillType, &offset);
@@ -928,18 +917,15 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path,
(GrSingleTextureEffect, (pathTexture)))->unref();
if (SkMaskFilter::kInner_BlurType == blurType) {
// inner: dst = dst * src
- paint.fSrcBlendCoeff = kDC_GrBlendCoeff;
- paint.fDstBlendCoeff = kZero_GrBlendCoeff;
+ paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
} else if (SkMaskFilter::kSolid_BlurType == blurType) {
// solid: dst = src + dst - src * dst
// = (1 - dst) * src + 1 * dst
- paint.fSrcBlendCoeff = kIDC_GrBlendCoeff;
- paint.fDstBlendCoeff = kOne_GrBlendCoeff;
+ paint.setBlendFunc(kIDC_GrBlendCoeff, kOne_GrBlendCoeff);
} else if (SkMaskFilter::kOuter_BlurType == blurType) {
// outer: dst = dst * (1 - src)
// = 0 * src + (1 - src) * dst
- paint.fSrcBlendCoeff = kZero_GrBlendCoeff;
- paint.fDstBlendCoeff = kISC_GrBlendCoeff;
+ paint.setBlendFunc(kZero_GrBlendCoeff, kISC_GrBlendCoeff);
}
context->drawRect(paint, srcRect);
}
@@ -1059,8 +1045,7 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
SkScalar hairlineCoverage;
if (SkDrawTreatAsHairline(paint, *draw.fMatrix, &hairlineCoverage)) {
doFill = false;
- grPaint.fCoverage = SkScalarRoundToInt(hairlineCoverage *
- grPaint.fCoverage);
+ grPaint.setCoverage(SkScalarRoundToInt(hairlineCoverage * grPaint.getCoverage()));
}
// If we have a prematrix, apply it to the path, optimizing for the case
@@ -1520,7 +1505,6 @@ void apply_custom_stage(GrContext* context,
GrMatrix sampleM;
sampleM.setIDiv(srcTexture->width(), srcTexture->height());
GrPaint paint;
- paint.reset();
paint.colorSampler(0)->reset(sampleM);
paint.colorSampler(0)->setCustomStage(stage);
context->drawRect(paint, rect);
@@ -1707,7 +1691,6 @@ bool SkGpuDevice::filterImage(SkImageFilter* filter, const SkBitmap& src,
}
GrPaint paint;
- paint.reset();
GrTexture* texture;
// We assume here that the filter will not attempt to tile the src. Otherwise, this cache lookup
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index 3af0979be9..b9c9f63ae3 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -176,7 +176,6 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
// We then verify that two reads produced the same values.
GrPaint paint;
- paint.reset();
SkAutoTUnref<GrCustomStage> pmToUPMStage1(SkNEW_ARGS(GrConfigConversionEffect,
(dataTex, false, *pmToUPMRule)));