diff options
author | 2013-07-13 17:24:24 +0000 | |
---|---|---|
committer | 2013-07-13 17:24:24 +0000 | |
commit | 42dacab4e7366d9f53989558cc8d045c3d065bcd (patch) | |
tree | b4659c9888df3193960c1dd1cfb01650dcc12cdb | |
parent | 0408a346962ef0939704fe435a0cdde52da4613f (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.cpp | 2 | ||||
-rw-r--r-- | gyp/gpu.gypi | 1 | ||||
-rw-r--r-- | include/gpu/GrPaint.h | 153 | ||||
-rw-r--r-- | include/gpu/SkGpuDevice.h | 5 | ||||
-rw-r--r-- | src/core/SkImageFilter.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkBicubicImageFilter.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkBlendImageFilter.cpp | 5 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 3 | ||||
-rw-r--r-- | src/effects/SkDisplacementMapEffect.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkMorphologyImageFilter.cpp | 8 | ||||
-rw-r--r-- | src/effects/SkXfermodeImageFilter.cpp | 22 | ||||
-rw-r--r-- | src/gpu/GrAAConvexPathRenderer.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrAAHairLinePathRenderer.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 23 | ||||
-rw-r--r-- | src/gpu/GrDrawState.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrPaint.cpp | 36 | ||||
-rw-r--r-- | src/gpu/GrSWMaskHelper.cpp | 6 | ||||
-rw-r--r-- | src/gpu/GrTextContext.cpp | 2 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 149 | ||||
-rw-r--r-- | src/gpu/effects/GrConfigConversionEffect.cpp | 17 |
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); |