aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-13 17:24:24 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-07-13 17:24:24 +0000
commit42dacab4e7366d9f53989558cc8d045c3d065bcd (patch)
treeb4659c9888df3193960c1dd1cfb01650dcc12cdb
parent0408a346962ef0939704fe435a0cdde52da4613f (diff)
Make GrPaint have a variable sized array of color and coverage stages rather than a fixed size.
R=robertphillips@google.com, jvanverth@google.com Author: bsalomon@google.com Review URL: https://chromiumcodereview.appspot.com/18686007 git-svn-id: http://skia.googlecode.com/svn/trunk@10062 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--gm/texdata.cpp2
-rw-r--r--gyp/gpu.gypi1
-rw-r--r--include/gpu/GrPaint.h153
-rw-r--r--include/gpu/SkGpuDevice.h5
-rw-r--r--src/core/SkImageFilter.cpp2
-rw-r--r--src/effects/SkBicubicImageFilter.cpp2
-rw-r--r--src/effects/SkBlendImageFilter.cpp5
-rw-r--r--src/effects/SkBlurMaskFilter.cpp3
-rw-r--r--src/effects/SkDisplacementMapEffect.cpp2
-rw-r--r--src/effects/SkMorphologyImageFilter.cpp8
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp22
-rw-r--r--src/gpu/GrAAConvexPathRenderer.cpp6
-rw-r--r--src/gpu/GrAAHairLinePathRenderer.cpp6
-rw-r--r--src/gpu/GrContext.cpp23
-rw-r--r--src/gpu/GrDrawState.cpp12
-rw-r--r--src/gpu/GrPaint.cpp36
-rw-r--r--src/gpu/GrSWMaskHelper.cpp6
-rw-r--r--src/gpu/GrTextContext.cpp2
-rw-r--r--src/gpu/SkGpuDevice.cpp149
-rw-r--r--src/gpu/effects/GrConfigConversionEffect.cpp17
20 files changed, 200 insertions, 262 deletions
diff --git a/gm/texdata.cpp b/gm/texdata.cpp
index 6281825d25..cfb27f6f91 100644
--- a/gm/texdata.cpp
+++ b/gm/texdata.cpp
@@ -113,7 +113,7 @@ protected:
SkMatrix tm;
tm = vm;
tm.postIDiv(2*S, 2*S);
- paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(texture, tm))->unref();
+ paint.addColorTextureEffect(texture, tm);
ctx->drawRect(paint, GrRect::MakeWH(2*S, 2*S));
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 2191ff230a..fff79220ff 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -84,6 +84,7 @@
'<(skia_src_path)/gpu/GrMemoryPool.cpp',
'<(skia_src_path)/gpu/GrMemoryPool.h',
'<(skia_src_path)/gpu/GrOvalRenderer.cpp',
+ '<(skia_src_path)/gpu/GrPaint.cpp',
'<(skia_src_path)/gpu/GrPath.cpp',
'<(skia_src_path)/gpu/GrPath.h',
'<(skia_src_path)/gpu/GrPathRendererChain.cpp',
diff --git a/include/gpu/GrPaint.h b/include/gpu/GrPaint.h
index 25ec699762..9e326f0495 100644
--- a/include/gpu/GrPaint.h
+++ b/include/gpu/GrPaint.h
@@ -43,11 +43,6 @@
*/
class GrPaint {
public:
- enum {
- kMaxColorStages = 3,
- kMaxCoverageStages = 1,
- };
-
GrPaint() { this->reset(); }
GrPaint(const GrPaint& paint) { *this = paint; }
@@ -111,63 +106,43 @@ public:
}
/**
- * 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 colorStage(0).
+ * Appends an additional color effect to the color computation.
*/
- GrEffectStage* colorStage(int i) {
- GrAssert((unsigned)i < kMaxColorStages);
- return fColorStages + i;
- }
-
- const GrEffectStage& getColorStage(int i) const {
- GrAssert((unsigned)i < kMaxColorStages);
- return fColorStages[i];
- }
-
- bool isColorStageEnabled(int i) const {
- GrAssert((unsigned)i < kMaxColorStages);
- return (NULL != fColorStages[i].getEffect());
+ const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
+ GrAssert(NULL != effect);
+ SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1));
+ return effect;
}
/**
- * Specifies a stage of the coverage pipeline. Coverage stages' texture matrices are always
- * applied to the primitive's position, never to explicit texture coords.
+ * Appends an additional coverage effect to the coverage computation.
*/
- GrEffectStage* coverageStage(int i) {
- GrAssert((unsigned)i < kMaxCoverageStages);
- return fCoverageStages + i;
- }
-
- const GrEffectStage& getCoverageStage(int i) const {
- GrAssert((unsigned)i < kMaxCoverageStages);
- return fCoverageStages[i];
+ const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
+ GrAssert(NULL != effect);
+ SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1));
+ return effect;
}
- bool isCoverageStageEnabled(int i) const {
- GrAssert((unsigned)i < kMaxCoverageStages);
- return (NULL != fCoverageStages[i].getEffect());
- }
+ /**
+ * Helpers for adding color or coverage effects that sample a texture. The matrix is applied
+ * to the src space position to compute texture coordinates.
+ */
+ void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix);
+ void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix);
- bool hasCoverageStage() const {
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- if (this->isCoverageStageEnabled(i)) {
- return true;
- }
- }
- return false;
- }
+ void addColorTextureEffect(GrTexture* texture,
+ const SkMatrix& matrix,
+ const GrTextureParams& params);
+ void addCoverageTextureEffect(GrTexture* texture,
+ const SkMatrix& matrix,
+ const GrTextureParams& params);
- bool hasColorStage() const {
- for (int i = 0; i < kMaxColorStages; ++i) {
- if (this->isColorStageEnabled(i)) {
- return true;
- }
- }
- return false;
- }
+ int numColorStages() const { return fColorStages.count(); }
+ int numCoverageStages() const { return fCoverageStages.count(); }
+ int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
- bool hasStage() const { return this->hasColorStage() || this->hasCoverageStage(); }
+ const GrEffectStage& getColorStage(int s) const { return fColorStages[s]; }
+ const GrEffectStage& getCoverageStage(int s) const { return fCoverageStages[s]; }
GrPaint& operator=(const GrPaint& paint) {
fSrcBlendCoeff = paint.fSrcBlendCoeff;
@@ -181,16 +156,9 @@ public:
fColorFilterColor = paint.fColorFilterColor;
fColorFilterXfermode = paint.fColorFilterXfermode;
- for (int i = 0; i < kMaxColorStages; ++i) {
- if (paint.isColorStageEnabled(i)) {
- fColorStages[i] = paint.fColorStages[i];
- }
- }
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- if (paint.isCoverageStageEnabled(i)) {
- fCoverageStages[i] = paint.fCoverageStages[i];
- }
- }
+ fColorStages = paint.fColorStages;
+ fCoverageStages = paint.fCoverageStages;
+
return *this;
}
@@ -206,15 +174,6 @@ public:
this->resetColorFilter();
}
- // internal use
- // GrPaint's textures and masks map to the first N stages
- // of GrDrawTarget in that order (textures followed by masks)
- enum {
- kFirstColorStage = 0,
- kFirstCoverageStage = kMaxColorStages,
- kTotalStages = kFirstColorStage + kMaxColorStages + kMaxCoverageStages,
- };
-
private:
/**
* Called when the source coord system from which geometry is rendered changes. It ensures that
@@ -222,48 +181,40 @@ private:
* from the previous coord system to the new coord system.
*/
void localCoordChange(const SkMatrix& oldToNew) {
- for (int i = 0; i < kMaxColorStages; ++i) {
- if (this->isColorStageEnabled(i)) {
- fColorStages[i].localCoordChange(oldToNew);
- }
+ for (int i = 0; i < fColorStages.count(); ++i) {
+ fColorStages[i].localCoordChange(oldToNew);
}
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- if (this->isCoverageStageEnabled(i)) {
- fCoverageStages[i].localCoordChange(oldToNew);
- }
+ for (int i = 0; i < fCoverageStages.count(); ++i) {
+ fCoverageStages[i].localCoordChange(oldToNew);
}
}
bool localCoordChangeInverse(const SkMatrix& newToOld) {
SkMatrix oldToNew;
bool computed = false;
- for (int i = 0; i < kMaxColorStages; ++i) {
- if (this->isColorStageEnabled(i)) {
- if (!computed && !newToOld.invert(&oldToNew)) {
- return false;
- } else {
- computed = true;
- }
- fColorStages[i].localCoordChange(oldToNew);
+ for (int i = 0; i < fColorStages.count(); ++i) {
+ if (!computed && !newToOld.invert(&oldToNew)) {
+ return false;
+ } else {
+ computed = true;
}
+ fColorStages[i].localCoordChange(oldToNew);
}
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- if (this->isCoverageStageEnabled(i)) {
- if (!computed && !newToOld.invert(&oldToNew)) {
- return false;
- } else {
- computed = true;
- }
- fCoverageStages[i].localCoordChange(oldToNew);
+ for (int i = 0; i < fCoverageStages.count(); ++i) {
+ if (!computed && !newToOld.invert(&oldToNew)) {
+ return false;
+ } else {
+ computed = true;
}
+ fCoverageStages[i].localCoordChange(oldToNew);
}
return true;
}
friend class GrContext; // To access above two functions
- GrEffectStage fColorStages[kMaxColorStages];
- GrEffectStage fCoverageStages[kMaxCoverageStages];
+ SkSTArray<4, GrEffectStage> fColorStages;
+ SkSTArray<2, GrEffectStage> fCoverageStages;
GrBlendCoeff fSrcBlendCoeff;
GrBlendCoeff fDstBlendCoeff;
@@ -295,12 +246,8 @@ private:
}
void resetStages() {
- for (int i = 0; i < kMaxColorStages; ++i) {
- fColorStages[i].reset();
- }
- for (int i = 0; i < kMaxCoverageStages; ++i) {
- fCoverageStages[i].reset();
- }
+ fColorStages.reset();
+ fCoverageStages.reset();
}
};
diff --git a/include/gpu/SkGpuDevice.h b/include/gpu/SkGpuDevice.h
index 0dd363fa36..b0b15591ca 100644
--- a/include/gpu/SkGpuDevice.h
+++ b/include/gpu/SkGpuDevice.h
@@ -152,7 +152,6 @@ private:
Usage usage) SK_OVERRIDE;
SkDrawProcs* initDrawForText(GrTextContext*);
- bool bindDeviceAsTexture(GrPaint* paint);
// sets the render target, clip, and matrix on GrContext. Use forceIdenity to override
// SkDraw's matrix and draw in device coords.
@@ -178,12 +177,12 @@ private:
const SkRect&,
const SkMatrix&,
const GrTextureParams& params,
- GrPaint* grPaint);
+ const SkPaint& paint);
void drawTiledBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
const SkMatrix& m,
const GrTextureParams& params,
- GrPaint* grPaint);
+ const SkPaint& paint);
/**
* Returns non-initialized instance.
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 33caf75a9d..ddd6449490 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -127,7 +127,7 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBitmap*
SkASSERT(effect);
SkAutoUnref effectRef(effect);
GrPaint paint;
- paint.colorStage(0)->setEffect(effect);
+ paint.addColorEffect(effect);
context->drawRect(paint, rect);
SkAutoTUnref<GrTexture> resultTex(dst.detach());
SkImageFilterUtils::WrapTexture(resultTex, input.width(), input.height(), result);
diff --git a/src/effects/SkBicubicImageFilter.cpp b/src/effects/SkBicubicImageFilter.cpp
index a97a768de9..5161f6dd8d 100644
--- a/src/effects/SkBicubicImageFilter.cpp
+++ b/src/effects/SkBicubicImageFilter.cpp
@@ -365,7 +365,7 @@ bool SkBicubicImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkB
}
GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
GrPaint paint;
- paint.colorStage(0)->setEffect(GrBicubicEffect::Create(srcTexture, fCoefficients))->unref();
+ paint.addColorEffect(GrBicubicEffect::Create(srcTexture, fCoefficients))->unref();
SkRect srcRect;
srcBM.getBounds(&srcRect);
context->drawRectToRect(paint, dstRect, srcRect);
diff --git a/src/effects/SkBlendImageFilter.cpp b/src/effects/SkBlendImageFilter.cpp
index 1c40ca8a39..9aae35a450 100644
--- a/src/effects/SkBlendImageFilter.cpp
+++ b/src/effects/SkBlendImageFilter.cpp
@@ -194,8 +194,9 @@ bool SkBlendImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBit
GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
GrPaint paint;
- paint.colorStage(0)->setEffect(
- GrBlendEffect::Create(fMode, foreground, foregroundOffset, background, backgroundOffset))->unref();
+ paint.addColorEffect(GrBlendEffect::Create(fMode,
+ foreground, foregroundOffset,
+ background, backgroundOffset))->unref();
SkRect srcRect;
src.getBounds(&srcRect);
context->drawRect(paint, srcRect);
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 85176d69b7..66a07c4169 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -423,8 +423,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src,
matrix.setIDiv(src->width(), src->height());
// Blend pathTexture over blurTexture.
GrContext::AutoRenderTarget art(context, (*result)->asRenderTarget());
- paint.colorStage(0)->setEffect(
- GrSimpleTextureEffect::Create(src, matrix))->unref();
+ paint.addColorEffect(GrSimpleTextureEffect::Create(src, matrix))->unref();
if (SkBlurMaskFilter::kInner_BlurStyle == fBlurStyle) {
// inner: dst = dst * src
paint.setBlendFunc(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 8d287b2704..7b64d1da1a 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -305,7 +305,7 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src,
GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
GrPaint paint;
- paint.colorStage(0)->setEffect(
+ paint.addColorEffect(
GrDisplacementMapEffect::Create(fXChannelSelector,
fYChannelSelector,
fScale,
diff --git a/src/effects/SkMorphologyImageFilter.cpp b/src/effects/SkMorphologyImageFilter.cpp
index cb17c9011b..4783abdce9 100644
--- a/src/effects/SkMorphologyImageFilter.cpp
+++ b/src/effects/SkMorphologyImageFilter.cpp
@@ -452,10 +452,10 @@ void apply_morphology_pass(GrContext* context,
GrMorphologyEffect::MorphologyType morphType,
Gr1DKernelEffect::Direction direction) {
GrPaint paint;
- paint.colorStage(0)->setEffect(GrMorphologyEffect::Create(texture,
- direction,
- radius,
- morphType))->unref();
+ paint.addColorEffect(GrMorphologyEffect::Create(texture,
+ direction,
+ radius,
+ morphType))->unref();
context->drawRect(paint, SkRect::MakeFromIRect(rect));
}
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index a318ceb908..3df59a87d2 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -119,23 +119,23 @@ bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
SkIntToScalar(backgroundOffset.fY-foregroundOffset.fY));
- GrPaint paint;
SkRect srcRect;
src.getBounds(&srcRect);
if (NULL != xferEffect) {
- paint.colorStage(0)->setEffect(
- GrSimpleTextureEffect::Create(foregroundTex, foregroundMatrix))->unref();
- paint.colorStage(1)->setEffect(xferEffect)->unref();
+ GrPaint paint;
+ paint.addColorTextureEffect(foregroundTex, foregroundMatrix);
+ paint.addColorEffect(xferEffect)->unref();
context->drawRect(paint, srcRect);
} else {
+ GrPaint backgroundPaint;
SkMatrix backgroundMatrix = GrEffect::MakeDivByTextureWHMatrix(backgroundTex);
- paint.colorStage(0)->setEffect(
- GrSimpleTextureEffect::Create(backgroundTex, backgroundMatrix))->unref();
- context->drawRect(paint, srcRect);
- paint.setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
- paint.colorStage(0)->setEffect(
- GrSimpleTextureEffect::Create(foregroundTex, foregroundMatrix))->unref();
- context->drawRect(paint, srcRect);
+ backgroundPaint.addColorTextureEffect(backgroundTex, backgroundMatrix);
+ context->drawRect(backgroundPaint, srcRect);
+
+ GrPaint foregroundPaint;
+ foregroundPaint.setBlendFunc(sk_blend_to_grblend(sm), sk_blend_to_grblend(dm));
+ foregroundPaint.addColorTextureEffect(foregroundTex, foregroundMatrix);
+ context->drawRect(foregroundPaint, srcRect);
}
offset->fX += backgroundOffset.fX;
offset->fY += backgroundOffset.fY;
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index 5d461ab3ed..408fcb541f 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -637,12 +637,6 @@ bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
drawState->setVertexAttribs<gPathAttribs>(SK_ARRAY_COUNT(gPathAttribs));
- enum {
- // the edge effects share this stage with glyph rendering
- // (kGlyphMaskStage in GrTextContext) && SW path rendering
- // (kPathMaskStage in GrSWMaskHelper)
- kEdgeEffectStage = GrPaint::kTotalStages,
- };
static const int kEdgeAttrIndex = 1;
GrEffectRef* quadEffect = QuadEdgeEffect::Create();
drawState->addCoverageEffect(quadEffect, kEdgeAttrIndex)->unref();
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 332c6bb5a1..85121bbc44 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -1100,12 +1100,6 @@ bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
// TODO: See whether rendering lines as degenerate quads improves perf
// when we have a mix
- enum {
- // the edge effects share this stage with glyph rendering
- // (kGlyphMaskStage in GrTextContext) && SW path rendering
- // (kPathMaskStage in GrSWMaskHelper)
- kEdgeEffectStage = GrPaint::kTotalStages,
- };
static const int kEdgeAttrIndex = 1;
GrEffectRef* hairLineEffect = HairLineEdgeEffect::Create();
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index d9924bf314..31d5ff1e33 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1766,20 +1766,16 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
return NULL;
}
- GrPaint paint;
- paint.reset();
-
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
+ GrPaint paint;
SkMatrix 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);
-
- paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture,
- matrix,
- true))->unref();
+ GrTextureParams params(SkShader::kClamp_TileMode, true);
+ paint.addColorTextureEffect(srcTexture, matrix, params);
this->drawRectToRect(paint, dstRect, srcRect);
srcRect = dstRect;
srcTexture = dstTexture;
@@ -1797,7 +1793,7 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
radiusX, srcIRect.height());
this->clear(&clearRect, 0x0);
}
-
+ GrPaint paint;
this->setRenderTarget(dstTexture->asRenderTarget());
AutoRestoreEffects are;
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are);
@@ -1817,6 +1813,7 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
}
this->setRenderTarget(dstTexture->asRenderTarget());
+ GrPaint paint;
AutoRestoreEffects are;
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW, &are);
convolve_gaussian(target, srcTexture, srcRect, sigmaY, radiusY,
@@ -1835,12 +1832,14 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture,
1, srcIRect.height());
this->clear(&clearRect, 0x0);
SkMatrix matrix;
- // FIXME: This should be mitchell, not bilinear.
matrix.setIDiv(srcTexture->width(), srcTexture->height());
this->setRenderTarget(dstTexture->asRenderTarget());
- paint.colorStage(0)->setEffect(GrSimpleTextureEffect::Create(srcTexture,
- matrix,
- true))->unref();
+
+ GrPaint paint;
+ // FIXME: This should be mitchell, not bilinear.
+ GrTextureParams params(SkShader::kClamp_TileMode, true);
+ paint.addColorTextureEffect(srcTexture, matrix, params);
+
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 7c68543479..ab800d24e7 100644
--- a/src/gpu/GrDrawState.cpp
+++ b/src/gpu/GrDrawState.cpp
@@ -32,16 +32,12 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende
fColorStages.reset();
fCoverageStages.reset();
- for (int i = 0; i < GrPaint::kMaxColorStages; ++i) {
- if (paint.isColorStageEnabled(i)) {
- fColorStages.push_back(paint.getColorStage(i));
- }
+ for (int i = 0; i < paint.numColorStages(); ++i) {
+ fColorStages.push_back(paint.getColorStage(i));
}
- for (int i = 0; i < GrPaint::kMaxCoverageStages; ++i) {
- if (paint.isCoverageStageEnabled(i)) {
- fCoverageStages.push_back(paint.getCoverageStage(i));
- }
+ for (int i = 0; i < paint.numCoverageStages(); ++i) {
+ fCoverageStages.push_back(paint.getCoverageStage(i));
}
this->setRenderTarget(rt);
diff --git a/src/gpu/GrPaint.cpp b/src/gpu/GrPaint.cpp
new file mode 100644
index 0000000000..b05c3c3628
--- /dev/null
+++ b/src/gpu/GrPaint.cpp
@@ -0,0 +1,36 @@
+
+/*
+ * Copyright 2013 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrPaint.h"
+
+#include "effects/GrSimpleTextureEffect.h"
+
+void GrPaint::addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
+ this->addColorEffect(effect)->unref();
+}
+
+void GrPaint::addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
+ this->addCoverageEffect(effect)->unref();
+}
+
+void GrPaint::addColorTextureEffect(GrTexture* texture,
+ const SkMatrix& matrix,
+ const GrTextureParams& params) {
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
+ this->addColorEffect(effect)->unref();
+}
+
+void GrPaint::addCoverageTextureEffect(GrTexture* texture,
+ const SkMatrix& matrix,
+ const GrTextureParams& params) {
+ GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
+ this->addCoverageEffect(effect)->unref();
+}
+
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 0fab55c361..c9f3989ebb 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -192,12 +192,6 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
return;
}
GrDrawState::AutoRestoreEffects are(drawState);
- enum {
- // the SW path renderer shares this stage with glyph
- // rendering (kGlyphMaskStage in GrTextContext)
- // && edge rendering (kEdgeEffectStage in GrContext)
- kPathMaskStage = GrPaint::kTotalStages,
- };
GrRect dstRect = GrRect::MakeLTRB(
SK_Scalar1 * rect.fLeft,
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 65c5c7a1fa..c929d0c56c 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -43,7 +43,7 @@ void GrTextContext::flushGlyphs() {
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
- fPaint.hasColorStage()) {
+ fPaint.numColorStages()) {
GrPrintf("LCD Text will not draw correctly.\n");
}
// setup blend so that we get mask * paintColor + (1-mask)*dstColor
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 3b0d143c5b..ab7693c7f1 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -38,15 +38,6 @@
#define CHECK_SHOULD_DRAW(draw, forceI) this->prepareDraw(draw, forceI)
#endif
-// we use the same effect slot on GrPaint for bitmaps and shaders (since drawBitmap, drawSprite,
-// and drawDevice ignore SkShader)
-enum {
- kShaderEffectIdx = 0,
- kBitmapEffectIdx = 0,
- kColorFilterEffectIdx = 1,
- kXfermodeEffectIdx = 2,
-};
-
// This constant represents the screen alignment criterion in texels for
// requiring texture domain clamping to prevent color bleeding when drawing
// a sub region of a larger source image.
@@ -442,16 +433,6 @@ GrRenderTarget* SkGpuDevice::accessRenderTarget() {
return fRenderTarget;
}
-bool SkGpuDevice::bindDeviceAsTexture(GrPaint* paint) {
- GrTexture* texture = fRenderTarget->asTexture();
- if (NULL != texture) {
- paint->colorStage(kBitmapEffectIdx)->setEffect(
- GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref();
- return true;
- }
- return false;
-}
-
///////////////////////////////////////////////////////////////////////////////
SK_COMPILE_ASSERT(SkShader::kNone_BitmapType == 0, shader_type_mismatch);
@@ -489,7 +470,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
GrEffectRef* xferEffect = NULL;
if (SkXfermode::AsNewEffectOrCoeff(mode, dev->context(), &xferEffect, &sm, &dm)) {
if (NULL != xferEffect) {
- grPaint->colorStage(kXfermodeEffectIdx)->setEffect(xferEffect)->unref();
+ grPaint->addColorEffect(xferEffect)->unref();
sm = SkXfermode::kOne_Coeff;
dm = SkXfermode::kZero_Coeff;
}
@@ -513,7 +494,6 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
GrAssert(!constantColor);
} else {
grPaint->setColor(SkColor2GrColor(skPaint.getColor()));
- GrAssert(!grPaint->isColorStageEnabled(kShaderEffectIdx));
}
SkColorFilter* colorFilter = skPaint.getColorFilter();
@@ -526,7 +506,7 @@ inline bool skPaint2GrPaintNoShader(SkGpuDevice* dev,
} else {
SkAutoTUnref<GrEffectRef> effect(colorFilter->asNewEffect(dev->context()));
if (NULL != effect.get()) {
- grPaint->colorStage(kColorFilterEffectIdx)->setEffect(effect);
+ grPaint->addColorEffect(effect);
} else {
// TODO: rewrite this using asNewEffect()
SkColor color;
@@ -552,32 +532,33 @@ inline bool skPaint2GrPaintShader(SkGpuDevice* dev,
SkShader* shader = skPaint.getShader();
if (NULL == shader) {
return skPaint2GrPaintNoShader(dev, skPaint, false, constantColor, grPaint);
- } else if (!skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint)) {
- return false;
}
+ // setup the shader as the first color effect on the paint
SkAutoTUnref<GrEffectRef> effect(shader->asNewEffect(dev->context(), skPaint));
if (NULL != effect.get()) {
- grPaint->colorStage(kShaderEffectIdx)->setEffect(effect);
- return true;
- }
-
- // We still don't have SkColorShader::asNewEffect() implemented.
- SkShader::GradientInfo info;
- SkColor color;
-
- info.fColors = &color;
- info.fColorOffsets = NULL;
- info.fColorCount = 1;
- if (SkShader::kColor_GradientType == shader->asAGradient(&info)) {
- SkPaint copy(skPaint);
- copy.setShader(NULL);
- // modulate the paint alpha by the shader's solid color alpha
- U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha());
- copy.setColor(SkColorSetA(color, newA));
- return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPaint);
+ grPaint->addColorEffect(effect);
+ // Now setup the rest of the paint.
+ return skPaint2GrPaintNoShader(dev, skPaint, true, false, grPaint);
+ } else {
+ // We still don't have SkColorShader::asNewEffect() implemented.
+ SkShader::GradientInfo info;
+ SkColor color;
+
+ info.fColors = &color;
+ info.fColorOffsets = NULL;
+ info.fColorCount = 1;
+ if (SkShader::kColor_GradientType == shader->asAGradient(&info)) {
+ SkPaint copy(skPaint);
+ copy.setShader(NULL);
+ // modulate the paint alpha by the shader's solid color alpha
+ U8CPU newA = SkMulDiv255Round(SkColorGetA(color), copy.getAlpha());
+ copy.setColor(SkColorSetA(color, newA));
+ return skPaint2GrPaintNoShader(dev, copy, false, constantColor, grPaint);
+ } else {
+ return false;
+ }
}
- return false;
}
}
@@ -769,22 +750,16 @@ namespace {
// Return true if the mask was successfully drawn.
bool draw_mask(GrContext* context, const SkRect& maskRect,
GrPaint* grp, GrTexture* mask) {
-
GrContext::AutoMatrix am;
if (!am.setIdentity(context, grp)) {
return false;
}
- static const int MASK_IDX = GrPaint::kMaxCoverageStages - 1;
- // we assume the last mask index is available for use
- GrAssert(!grp->isCoverageStageEnabled(MASK_IDX));
-
SkMatrix matrix;
matrix.setTranslate(-maskRect.fLeft, -maskRect.fTop);
matrix.postIDiv(mask->width(), mask->height());
- grp->coverageStage(MASK_IDX)->reset();
- grp->coverageStage(MASK_IDX)->setEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref();
+ grp->addCoverageEffect(GrSimpleTextureEffect::Create(mask, matrix))->unref();
context->drawRect(*grp, maskRect);
return true;
}
@@ -1169,20 +1144,14 @@ void SkGpuDevice::drawBitmapCommon(const SkDraw& draw,
return;
}
- GrPaint grPaint;
-
- bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config());
- if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) {
- return;
- }
GrTextureParams params;
params.setBilerp(paint.isFilterBitmap());
if (!this->shouldTileBitmap(bitmap, params, srcRectPtr)) {
// take the simple case
- this->internalDrawBitmap(bitmap, srcRect, m, params, &grPaint);
+ this->internalDrawBitmap(bitmap, srcRect, m, params, paint);
} else {
- this->drawTiledBitmap(bitmap, srcRect, m, params, &grPaint);
+ this->drawTiledBitmap(bitmap, srcRect, m, params, paint);
}
}
@@ -1192,7 +1161,7 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
const SkMatrix& m,
const GrTextureParams& params,
- GrPaint* grPaint) {
+ const SkPaint& paint) {
const int maxTextureSize = fContext->getMaxTextureSize();
int tileSize = determine_tile_size(bitmap, srcRect, maxTextureSize);
@@ -1241,7 +1210,7 @@ void SkGpuDevice::drawTiledBitmap(const SkBitmap& bitmap,
tmpM.preTranslate(SkIntToScalar(iTileR.fLeft),
SkIntToScalar(iTileR.fTop));
- this->internalDrawBitmap(tmpB, tileR, tmpM, params, grPaint);
+ this->internalDrawBitmap(tmpB, tileR, tmpM, params, paint);
}
}
}
@@ -1301,7 +1270,7 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
const SkRect& srcRect,
const SkMatrix& m,
const GrTextureParams& params,
- GrPaint* grPaint) {
+ const SkPaint& paint) {
SkASSERT(bitmap.width() <= fContext->getMaxTextureSize() &&
bitmap.height() <= fContext->getMaxTextureSize());
@@ -1371,8 +1340,17 @@ void SkGpuDevice::internalDrawBitmap(const SkBitmap& bitmap,
} else {
effect.reset(GrSimpleTextureEffect::Create(texture, SkMatrix::I(), params));
}
- grPaint->colorStage(kBitmapEffectIdx)->setEffect(effect);
- fContext->drawRectToRect(*grPaint, dstRect, paintRect, &m);
+
+ // Construct a GrPaint by setting the bitmap texture as the first effect and then configuring
+ // the rest from the SkPaint.
+ GrPaint grPaint;
+ grPaint.addColorEffect(effect);
+ bool alphaOnly = !(SkBitmap::kA8_Config == bitmap.config());
+ if (!skPaint2GrPaintNoShader(this, paint, alphaOnly, false, &grPaint)) {
+ return;
+ }
+
+ fContext->drawRectToRect(grPaint, dstRect, paintRect, &m);
}
static bool filter_texture(SkDevice* device, GrContext* context,
@@ -1404,33 +1382,28 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
int w = bitmap.width();
int h = bitmap.height();
- GrPaint grPaint;
- if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) {
- return;
- }
-
- GrEffectStage* stage = grPaint.colorStage(kBitmapEffectIdx);
-
GrTexture* texture;
- stage->reset();
// draw sprite uses the default texture params
SkAutoCachedTexture act(this, bitmap, NULL, &texture);
- grPaint.colorStage(kBitmapEffectIdx)->setEffect(
- GrSimpleTextureEffect::Create(texture, SkMatrix::I()))->unref();
SkImageFilter* filter = paint.getImageFilter();
SkIPoint offset = SkIPoint::Make(0, 0);
if (NULL != filter) {
SkBitmap filterBitmap;
if (filter_texture(this, fContext, texture, filter, w, h, &filterBitmap, &offset)) {
- grPaint.colorStage(kBitmapEffectIdx)->setEffect(
- GrSimpleTextureEffect::Create(filterBitmap.getTexture(), SkMatrix::I()))->unref();
- texture = filterBitmap.getTexture();
+ texture = (GrTexture*) filterBitmap.getTexture();
w = filterBitmap.width();
h = filterBitmap.height();
}
}
+ GrPaint grPaint;
+ grPaint.addColorTextureEffect(texture, SkMatrix::I());
+
+ if(!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) {
+ return;
+ }
+
fContext->drawRectToRect(grPaint,
GrRect::MakeXYWH(SkIntToScalar(left),
SkIntToScalar(top),
@@ -1484,27 +1457,22 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device,
// drawDevice is defined to be in device coords.
CHECK_SHOULD_DRAW(draw, true);
- GrPaint grPaint;
- grPaint.colorStage(kBitmapEffectIdx)->reset();
- if (!dev->bindDeviceAsTexture(&grPaint) ||
- !skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) {
+ GrRenderTarget* devRT = device->accessRenderTarget();
+ GrTexture* devTex;
+ if (NULL == (devTex = devRT->asTexture())) {
return;
}
- GrTexture* devTex = (*grPaint.getColorStage(kBitmapEffectIdx).getEffect())->texture(0);
- SkASSERT(NULL != devTex);
-
const SkBitmap& bm = dev->accessBitmap(false);
int w = bm.width();
int h = bm.height();
SkImageFilter* filter = paint.getImageFilter();
+
if (NULL != filter) {
SkBitmap filterBitmap;
SkIPoint offset = SkIPoint::Make(0, 0);
if (filter_texture(this, fContext, devTex, filter, w, h, &filterBitmap, &offset)) {
- grPaint.colorStage(kBitmapEffectIdx)->setEffect(
- GrSimpleTextureEffect::Create(filterBitmap.getTexture(), SkMatrix::I()))->unref();
devTex = filterBitmap.getTexture();
w = filterBitmap.width();
h = filterBitmap.height();
@@ -1513,13 +1481,20 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkDevice* device,
}
}
+ GrPaint grPaint;
+ grPaint.addColorTextureEffect(devTex, SkMatrix::I());
+
+ if (!skPaint2GrPaintNoShader(this, paint, true, false, &grPaint)) {
+ return;
+ }
+
GrRect dstRect = GrRect::MakeXYWH(SkIntToScalar(x),
SkIntToScalar(y),
SkIntToScalar(w),
SkIntToScalar(h));
- // The device being drawn may not fill up its texture (saveLayer uses
- // the approximate ).
+ // The device being drawn may not fill up its texture (e.g. saveLayer uses approximate
+ // scratch texture).
GrRect srcRect = GrRect::MakeWH(SK_Scalar1 * w / devTex->width(),
SK_Scalar1 * h / devTex->height());
diff --git a/src/gpu/effects/GrConfigConversionEffect.cpp b/src/gpu/effects/GrConfigConversionEffect.cpp
index fd6264ffe2..db6141f8e9 100644
--- a/src/gpu/effects/GrConfigConversionEffect.cpp
+++ b/src/gpu/effects/GrConfigConversionEffect.cpp
@@ -219,7 +219,6 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
// from readTex to tempTex followed by a PM->UPM draw to readTex and finally read the data.
// We then verify that two reads produced the same values.
- GrPaint paint;
AutoEffectUnref pmToUPM1(SkNEW_ARGS(GrConfigConversionEffect, (dataTex,
false,
*pmToUPMRule,
@@ -238,17 +237,21 @@ void GrConfigConversionEffect::TestForPreservingPMConversions(GrContext* context
SkAutoTUnref<GrEffectRef> pmToUPMEffect2(CreateEffectRef(pmToUPM2));
context->setRenderTarget(readTex->asRenderTarget());
- paint.colorStage(0)->setEffect(pmToUPMEffect1);
- context->drawRectToRect(paint, kDstRect, kSrcRect);
+ GrPaint paint1;
+ paint1.addColorEffect(pmToUPMEffect1);
+ context->drawRectToRect(paint1, kDstRect, kSrcRect);
readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, firstRead);
context->setRenderTarget(tempTex->asRenderTarget());
- paint.colorStage(0)->setEffect(upmToPMEffect);
- context->drawRectToRect(paint, kDstRect, kSrcRect);
+ GrPaint paint2;
+ paint2.addColorEffect(upmToPMEffect);
+ context->drawRectToRect(paint2, kDstRect, kSrcRect);
context->setRenderTarget(readTex->asRenderTarget());
- paint.colorStage(0)->setEffect(pmToUPMEffect2);
- context->drawRectToRect(paint, kDstRect, kSrcRect);
+
+ GrPaint paint3;
+ paint3.addColorEffect(pmToUPMEffect2);
+ context->drawRectToRect(paint3, kDstRect, kSrcRect);
readTex->readPixels(0, 0, 256, 256, kRGBA_8888_GrPixelConfig, secondRead);