diff options
author | 2014-12-09 13:31:14 -0800 | |
---|---|---|
committer | 2014-12-09 13:31:15 -0800 | |
commit | 2e3b3e369d79e78f7635d4c20e83a47ab571bdf2 (patch) | |
tree | 95378f3e35a21192f0db62e60bc6e408803050b7 /src/gpu | |
parent | f3c78ccf5694d22d2e4a7061a80399a7e69b59db (diff) |
This cl moves color and coverage off of drawstate. In an effort to keep this CL manageable, I have left the compute invariant input / output in a bit of a strange state(fixing this will be complicated).
In addition, NVPR makes this very complicated, and I haven't quite figured out a good way to handle it, so for now color and coverage DO live on optstate, but I will figure out some way to refactor that in future CLs.
BUG=skia:
Review URL: https://codereview.chromium.org/783763002
Diffstat (limited to 'src/gpu')
46 files changed, 509 insertions, 392 deletions
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp index f7c6e7f6b1..44782dd279 100644 --- a/src/gpu/GrAAConvexPathRenderer.cpp +++ b/src/gpu/GrAAConvexPathRenderer.cpp @@ -505,8 +505,8 @@ static void create_vertices(const SegmentArray& segments, class QuadEdgeEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create() { - return SkNEW(QuadEdgeEffect); + static GrGeometryProcessor* Create(GrColor color) { + return SkNEW_ARGS(QuadEdgeEffect, (color)); } virtual ~QuadEdgeEffect() {} @@ -586,7 +586,7 @@ public: } private: - QuadEdgeEffect() { + QuadEdgeEffect(GrColor color) : INHERITED(color) { this->initClassID<QuadEdgeEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInQuadEdge = &this->addVertexAttrib(GrAttribute("inQuadEdge", kVec4f_GrVertexAttribType)); @@ -605,7 +605,7 @@ private: GR_DECLARE_GEOMETRY_PROCESSOR_TEST; - typedef GrFragmentProcessor INHERITED; + typedef GrGeometryProcessor INHERITED; }; GR_DEFINE_GEOMETRY_PROCESSOR_TEST(QuadEdgeEffect); @@ -615,7 +615,7 @@ GrGeometryProcessor* QuadEdgeEffect::TestCreate(SkRandom* random, const GrDrawTargetCaps& caps, GrTexture*[]) { // Doesn't work without derivative instructions. - return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create() : NULL; + return caps.shaderDerivativeSupport() ? QuadEdgeEffect::Create(GrRandomColor(random)) : NULL; } /////////////////////////////////////////////////////////////////////////////// @@ -631,6 +631,7 @@ bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target, bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& origPath, const SkStrokeRec&, bool antiAlias) { @@ -678,7 +679,7 @@ bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target, // Our computed verts should all be within one pixel of the segment control points. devBounds.outset(SK_Scalar1, SK_Scalar1); - GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create(); + GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create(color); drawState->setGeometryProcessor(quadProcessor)->unref(); GrDrawTarget::AutoReleaseGeometry arg(target, vCount, quadProcessor->getVertexStride(), iCount); diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h index bb40e19c21..05f60fb48f 100644 --- a/src/gpu/GrAAConvexPathRenderer.h +++ b/src/gpu/GrAAConvexPathRenderer.h @@ -24,6 +24,7 @@ public: protected: virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 6ac504a948..7a7c1e4379 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -105,6 +105,7 @@ GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, bool antiAlias) { @@ -143,7 +144,7 @@ bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, } // use signed distance field to render - return this->internalDrawPath(target, drawState, path, pathData); + return this->internalDrawPath(target, drawState, color, path, pathData); } // padding around path bounds to allow for antialiased pixels @@ -306,6 +307,7 @@ bool GrAADistanceFieldPathRenderer::freeUnusedPlot() { bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const PathData* pathData) { GrTexture* texture = fAtlas->getTexture(); @@ -321,8 +323,9 @@ bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target, flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_FilterMode); - if (flags != fEffectFlags) { - fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(texture, + if (flags != fEffectFlags || fCachedGeometryProcessor->getColor() != color) { + fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color, + texture, params, flags)); fEffectFlags = flags; diff --git a/src/gpu/GrAADistanceFieldPathRenderer.h b/src/gpu/GrAADistanceFieldPathRenderer.h index 88c9d328cc..7b40d94598 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.h +++ b/src/gpu/GrAADistanceFieldPathRenderer.h @@ -38,6 +38,7 @@ protected: virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) SK_OVERRIDE; @@ -78,7 +79,7 @@ private: SkTDynamicHash<PathData, PathData::Key> fPathCache; PathDataList fPathList; - bool internalDrawPath(GrDrawTarget*, GrDrawState*, const SkPath& path, + bool internalDrawPath(GrDrawTarget*, GrDrawState*, GrColor, const SkPath& path, const PathData* pathData); PathData* addPathToAtlas(const SkPath& path, const SkStrokeRec& stroke, bool antiAlias, uint32_t dimension, SkScalar scale); diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index 15a5569b30..37150bd9a5 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -643,6 +643,7 @@ void add_line(const SkPoint p[2], bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target, GrDrawState* drawState, + uint8_t coverage, GrDrawTarget::AutoReleaseGeometry* arg, SkRect* devBounds, const SkPath& path, @@ -670,7 +671,7 @@ bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target, } devBounds->set(lines.begin(), lines.count()); for (int i = 0; i < lineCnt; ++i) { - add_line(&lines[2*i], toSrc, drawState->getCoverage(), &verts); + add_line(&lines[2*i], toSrc, coverage, &verts); } // All the verts computed by add_line are within sqrt(1^2 + 0.5^2) of the end points. static const SkScalar kSqrtOfOneAndAQuarter = 1.118f; @@ -803,14 +804,15 @@ bool check_bounds(GrDrawState* drawState, const SkRect& devBounds, void* vertice bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, bool antiAlias) { SkScalar hairlineCoverage; + uint8_t newCoverage = 0xff; if (IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(), &hairlineCoverage)) { - uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->getCoverage()); - drawState->setCoverage(newCoverage); + newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); } SkIRect devClipBounds; @@ -837,10 +839,13 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, uint32_t gpFlags = GrDefaultGeoProcFactory::kPosition_GPType | GrDefaultGeoProcFactory::kCoverage_GPType; GrDrawState::AutoRestoreEffects are(drawState); - drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(gpFlags))->unref(); + drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, + gpFlags, + newCoverage))->unref(); if (!this->createLineGeom(target, drawState, + newCoverage, &arg, &devBounds, path, @@ -911,7 +916,10 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, if (quadCnt > 0) { GrGeometryProcessor* hairQuadProcessor = - GrQuadEffect::Create(kHairlineAA_GrProcessorEdgeType, *target->caps()); + GrQuadEffect::Create(color, + kHairlineAA_GrProcessorEdgeType, + *target->caps(), + newCoverage); SkASSERT(hairQuadProcessor); GrDrawState::AutoRestoreEffects are(drawState); target->setIndexSourceToBuffer(fQuadsIndexBuffer); @@ -934,7 +942,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, if (conicCnt > 0) { GrDrawState::AutoRestoreEffects are(drawState); GrGeometryProcessor* hairConicProcessor = GrConicEffect::Create( - kHairlineAA_GrProcessorEdgeType, *target->caps()); + color, kHairlineAA_GrProcessorEdgeType, *target->caps(), newCoverage); SkASSERT(hairConicProcessor); drawState->setGeometryProcessor(hairConicProcessor)->unref(); diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h index 2f44860c6c..5d00e7e9f1 100644 --- a/src/gpu/GrAAHairLinePathRenderer.h +++ b/src/gpu/GrAAHairLinePathRenderer.h @@ -30,6 +30,7 @@ public: protected: virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) SK_OVERRIDE; @@ -41,6 +42,7 @@ private: bool createLineGeom(GrDrawTarget* target, GrDrawState*, + uint8_t coverage, GrDrawTarget::AutoReleaseGeometry* arg, SkRect* devBounds, const SkPath& path, diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 7f61840d73..0cf757502e 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -25,16 +25,16 @@ enum CoverageAttribType { }; } -static CoverageAttribType set_rect_attribs(GrDrawState* drawState) { +static CoverageAttribType set_rect_attribs(GrDrawState* drawState, GrColor color) { uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; if (drawState->canTweakAlphaForCoverage()) { - drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref(); + drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref(); SkASSERT(drawState->getGeometryProcessor()->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); return kUseColor_CoverageAttribType; } else { flags |= GrDefaultGeoProcFactory::kCoverage_GPType; - drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref(); + drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref(); SkASSERT(drawState->getGeometryProcessor()->getVertexStride() == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); return kUseCoverage_CoverageAttribType; @@ -176,14 +176,13 @@ GrIndexBuffer* GrAARectRenderer::aaStrokeRectIndexBuffer(bool miterStroke) { void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect) { GrDrawState::AutoRestoreEffects are(drawState); - GrColor color = drawState->getColor(); - - CoverageAttribType covAttribType = set_rect_attribs(drawState); + CoverageAttribType covAttribType = set_rect_attribs(drawState, color); if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) { drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); } @@ -308,6 +307,7 @@ void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, void GrAARectRenderer::strokeAARect(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect, @@ -354,7 +354,7 @@ void GrAARectRenderer::strokeAARect(GrDrawTarget* target, } if (spare <= 0 && miterStroke) { - this->fillAARect(target, drawState, devOutside, SkMatrix::I(), devOutside); + this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), devOutside); return; } @@ -371,20 +371,20 @@ void GrAARectRenderer::strokeAARect(GrDrawTarget* target, devOutsideAssist.outset(0, ry); } - this->geometryStrokeAARect(target, drawState, devOutside, devOutsideAssist, devInside, + this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideAssist, devInside, miterStroke); } void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkRect& devOutside, const SkRect& devOutsideAssist, const SkRect& devInside, bool miterStroke) { GrDrawState::AutoRestoreEffects are(drawState); - CoverageAttribType covAttribType = set_rect_attribs(drawState); + CoverageAttribType covAttribType = set_rect_attribs(drawState, color); - GrColor color = drawState->getColor(); if (kUseCoverage_CoverageAttribType == covAttribType && GrColorIsOpaque(color)) { drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); } @@ -510,6 +510,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkRect rects[2], const SkMatrix& combinedMatrix) { SkASSERT(combinedMatrix.rectStaysRect()); @@ -521,9 +522,10 @@ void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target, combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2); if (devInside.isEmpty()) { - this->fillAARect(target, drawState, devOutside, SkMatrix::I(), devOutside); + this->fillAARect(target, drawState, color, devOutside, SkMatrix::I(), devOutside); return; } - this->geometryStrokeAARect(target, drawState, devOutside, devOutsideAssist, devInside, true); + this->geometryStrokeAARect(target, drawState, color, devOutside, devOutsideAssist, devInside, + true); } diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h index a8ba085108..b1780ad46a 100644 --- a/src/gpu/GrAARectRenderer.h +++ b/src/gpu/GrAARectRenderer.h @@ -8,6 +8,7 @@ #ifndef GrAARectRenderer_DEFINED #define GrAARectRenderer_DEFINED +#include "GrColor.h" #include "SkMatrix.h" #include "SkRect.h" #include "SkRefCnt.h" @@ -43,14 +44,16 @@ public: void fillAARect(GrDrawTarget* target, GrDrawState* ds, + GrColor color, const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect) { - this->geometryFillAARect(target, ds, rect, combinedMatrix, devRect); + this->geometryFillAARect(target, ds, color, rect, combinedMatrix, devRect); } void strokeAARect(GrDrawTarget*, GrDrawState*, + GrColor, const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect, @@ -59,6 +62,7 @@ public: // First rect is outer; second rect is inner void fillAANestedRects(GrDrawTarget*, GrDrawState*, + GrColor, const SkRect rects[2], const SkMatrix& combinedMatrix); @@ -67,12 +71,14 @@ private: void geometryFillAARect(GrDrawTarget*, GrDrawState*, + GrColor, const SkRect& rect, const SkMatrix& combinedMatrix, const SkRect& devRect); void geometryStrokeAARect(GrDrawTarget*, GrDrawState*, + GrColor, const SkRect& devOutside, const SkRect& devOutsideAssist, const SkRect& devInside, diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp index 1853fa4f93..6a624ae23e 100755 --- a/src/gpu/GrBitmapTextContext.cpp +++ b/src/gpu/GrBitmapTextContext.cpp @@ -528,34 +528,15 @@ void GrBitmapTextContext::flush() { SkASSERT(SkIsAlign4(fCurrVertex)); SkASSERT(fCurrTexture); - // This effect could be stored with one of the cache objects (atlas?) - GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode); - if (kARGB_GrMaskFormat == fCurrMaskFormat) { - uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType; - drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref(); - GrFragmentProcessor* fragProcessor = GrSimpleTextureEffect::Create(fCurrTexture, - SkMatrix::I(), - params); - drawState.addColorProcessor(fragProcessor)->unref(); - } else { - uint32_t textureUniqueID = fCurrTexture->getUniqueID(); - if (textureUniqueID != fEffectTextureUniqueID) { - bool useColorAttrib = kA8_GrMaskFormat == fCurrMaskFormat; - fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(fCurrTexture, - params, - useColorAttrib)); - fEffectTextureUniqueID = textureUniqueID; - } - drawState.setGeometryProcessor(fCachedGeometryProcessor.get()); - } - SkASSERT(fStrike); + GrColor color = fPaint.getColor(); switch (fCurrMaskFormat) { // Color bitmap text - case kARGB_GrMaskFormat: - SkASSERT(!drawState.hasColorVertexAttribute()); - drawState.setAlpha(fSkPaint.getAlpha()); + case kARGB_GrMaskFormat: { + int a = fSkPaint.getAlpha(); + color = SkColorSetARGB(a, a, a, a); break; + } // LCD text case kA565_GrMaskFormat: { // TODO: move supportsRGBCoverage check to setupCoverageEffect and only add LCD @@ -564,19 +545,45 @@ void GrBitmapTextContext::flush() { if (!drawState.getXPFactory()->supportsRGBCoverage(0, kRGBA_GrColorComponentFlags)) { SkDebugf("LCD Text will not draw correctly.\n"); } - SkASSERT(!drawState.hasColorVertexAttribute()); break; } // Grayscale/BW text case kA8_GrMaskFormat: drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint, 0xFF == GrColorUnpackA(fPaint.getColor())); - // We're using per-vertex color. - SkASSERT(drawState.hasColorVertexAttribute()); break; default: SkFAIL("Unexpected mask format."); } + + GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode); + // TODO cache these GPs + if (kARGB_GrMaskFormat == fCurrMaskFormat) { + uint32_t textureUniqueID = fCurrTexture->getUniqueID(); + if (textureUniqueID != fEffectTextureUniqueID || + fCachedGeometryProcessor->getColor() != color) { + uint32_t flags = GrDefaultGeoProcFactory::kLocalCoord_GPType; + fCachedGeometryProcessor.reset(GrDefaultGeoProcFactory::Create(color, flags)); + fCachedTextureProcessor.reset(GrSimpleTextureEffect::Create(fCurrTexture, + SkMatrix::I(), + params)); + } + drawState.setGeometryProcessor(fCachedGeometryProcessor.get()); + drawState.addColorProcessor(fCachedTextureProcessor.get()); + } else { + uint32_t textureUniqueID = fCurrTexture->getUniqueID(); + if (textureUniqueID != fEffectTextureUniqueID || + fCachedGeometryProcessor->getColor() != color) { + bool hasColor = kA8_GrMaskFormat == fCurrMaskFormat; + fCachedGeometryProcessor.reset(GrBitmapTextGeoProc::Create(color, + fCurrTexture, + params, + hasColor)); + fEffectTextureUniqueID = textureUniqueID; + } + drawState.setGeometryProcessor(fCachedGeometryProcessor.get()); + } + int nGlyphs = fCurrVertex / kVerticesPerGlyph; fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); fDrawTarget->drawIndexedInstances(&drawState, diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h index 747facf60b..9aa5dbdc63 100644 --- a/src/gpu/GrBitmapTextContext.h +++ b/src/gpu/GrBitmapTextContext.h @@ -31,7 +31,8 @@ private: SkRect fVertexBounds; GrTexture* fCurrTexture; GrMaskFormat fCurrMaskFormat; - SkAutoTUnref<GrGeometryProcessor> fCachedGeometryProcessor; + SkAutoTUnref<const GrGeometryProcessor> fCachedGeometryProcessor; + SkAutoTUnref<const GrFragmentProcessor> fCachedTextureProcessor; // Used to check whether fCachedEffect is still valid. uint32_t fEffectTextureUniqueID; diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index e87c7e1bc5..5af6fb69ff 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -362,6 +362,7 @@ void setup_boolean_blendcoeffs(SkRegion::Op op, GrDrawState* drawState) { //////////////////////////////////////////////////////////////////////////////// bool GrClipMaskManager::drawElement(GrDrawState* drawState, + GrColor color, GrTexture* target, const SkClipStack::Element* element, GrPathRenderer* pr) { @@ -380,11 +381,12 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState, if (element->isAA()) { this->getContext()->getAARectRenderer()->fillAARect(fClipTarget, drawState, + color, element->getRect(), SkMatrix::I(), element->getRect()); } else { - fClipTarget->drawSimpleRect(drawState, element->getRect()); + fClipTarget->drawSimpleRect(drawState, color, element->getRect()); } return true; default: { @@ -406,7 +408,7 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState, return false; } - pr->drawPath(fClipTarget, drawState, path, stroke, element->isAA()); + pr->drawPath(fClipTarget, drawState, color, path, stroke, element->isAA()); break; } } @@ -460,7 +462,7 @@ void GrClipMaskManager::mergeMask(GrDrawState* drawState, GrTextureDomain::MakeTexelDomain(srcMask, srcBound), GrTextureDomain::kDecal_Mode, GrTextureParams::kNone_FilterMode))->unref(); - fClipTarget->drawSimpleRect(drawState, SkRect::Make(dstBound)); + fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound)); } GrTexture* GrClipMaskManager::createTempMask(int width, int height) { @@ -617,13 +619,12 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, setup_boolean_blendcoeffs(op, &drawState); } - drawState.setAlpha(invert ? 0x00 : 0xff); - // We have to backup the drawstate because the drawElement call may call into // renderers which consume it. GrDrawState backupDrawState(drawState); - if (!this->drawElement(&drawState, dst, element, pr)) { + if (!this->drawElement(&drawState, invert ? GrColor_TRANS_BLACK : + GrColor_WHITE, dst, element, pr)) { fAACache.reset(); return NULL; } @@ -639,7 +640,6 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, maskSpaceElementIBounds); } else { // Draw to the exterior pixels (those with a zero stencil value). - backupDrawState.setAlpha(invert ? 0xff : 0x00); GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, kZero_StencilOp, kZero_StencilOp, @@ -648,7 +648,9 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, 0x0000, 0xffff); backupDrawState.setStencil(kDrawOutsideElement); - fClipTarget->drawSimpleRect(&backupDrawState, clipSpaceIBounds); + fClipTarget->drawSimpleRect(&backupDrawState, + invert ? GrColor_WHITE : GrColor_TRANS_BLACK, + clipSpaceIBounds); } } else { GrDrawState drawState(translate); @@ -656,9 +658,8 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, GrDrawState::kClip_StateBit); // all the remaining ops can just be directly draw into the accumulation buffer - drawState.setAlpha(0xff); setup_boolean_blendcoeffs(op, &drawState); - this->drawElement(&drawState, result, element); + this->drawElement(&drawState, GrColor_WHITE, result, element); } } @@ -783,13 +784,14 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, 0xffff); if (Element::kRect_Type == element->getType()) { *drawState.stencil() = gDrawToStencil; - fClipTarget->drawSimpleRect(&drawState, element->getRect()); + fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, element->getRect()); } else { if (!clipPath.isEmpty()) { GrDrawTarget::AutoGeometryPush agp(fClipTarget); if (canRenderDirectToStencil) { *drawState.stencil() = gDrawToStencil; - pr->drawPath(fClipTarget, &drawState, clipPath, stroke, false); + pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, clipPath, stroke, + false); } else { pr->stencilPath(fClipTarget, &drawState, clipPath, stroke); } @@ -806,15 +808,17 @@ bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, if (canDrawDirectToClip) { if (Element::kRect_Type == element->getType()) { - fClipTarget->drawSimpleRect(&drawStateCopy, element->getRect()); + fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, + element->getRect()); } else { GrDrawTarget::AutoGeometryPush agp(fClipTarget); - pr->drawPath(fClipTarget, &drawStateCopy, clipPath, stroke, false); + pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, clipPath, stroke, false); } } else { // The view matrix is setup to do clip space -> stencil space translation, so // draw rect in clip space. - fClipTarget->drawSimpleRect(&drawStateCopy, SkRect::Make(clipSpaceIBounds)); + fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, + SkRect::Make(clipSpaceIBounds)); } } } diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index 3aec257075..f93fa4af0d 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -152,6 +152,7 @@ private: // desired blend operation. Optionally if the caller already selected a path renderer it can // be passed. Otherwise the function will select one if the element is a path. bool drawElement(GrDrawState*, + GrColor, GrTexture* target, const SkClipStack::Element*, GrPathRenderer* pr = NULL); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 78d005ff40..9d07fdfd9c 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -315,7 +315,7 @@ GrTexture* GrContext::createResizedTexture(const GrSurfaceDesc& desc, uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType | GrDefaultGeoProcFactory::kLocalCoord_GPType; - const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(flags); + const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(GrColor_WHITE, flags); drawState.setGeometryProcessor(gp)->unref(); GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, gp->getVertexStride(), 0); @@ -622,8 +622,10 @@ static bool apply_aa_to_rect(GrDrawTarget* target, SkRect* devBoundRect, const SkRect& rect, SkScalar strokeWidth, - const SkMatrix& combinedMatrix) { - if (!ds->canTweakAlphaForCoverage() && !ds->couldApplyCoverage(*target->caps())) { + const SkMatrix& combinedMatrix, + GrColor color) { + if (!ds->canTweakAlphaForCoverage() && !ds->canUseFracCoveragePrimProc(color, + *target->caps())) { #ifdef SK_DEBUG //SkDebugf("Turning off AA to correctly apply blend.\n"); #endif @@ -722,9 +724,11 @@ void GrContext::drawRect(const GrPaint& paint, } } + GrColor color = paint.getColor(); SkRect devBoundRect; bool needAA = paint.isAntiAlias() && !drawState.getRenderTarget()->isMultisampled(); - bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width, matrix); + bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width, matrix, + color); if (doAA) { GrDrawState::AutoViewMatrixRestore avmr; @@ -736,13 +740,14 @@ void GrContext::drawRect(const GrPaint& paint, const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec(); fAARectRenderer->strokeAARect(target, &drawState, + color, rect, matrix, devBoundRect, strokeRec); } else { // filled AA rect - fAARectRenderer->fillAARect(target, &drawState, rect, matrix, devBoundRect); + fAARectRenderer->fillAARect(target, &drawState, color, rect, matrix, devBoundRect); } return; } @@ -753,7 +758,7 @@ void GrContext::drawRect(const GrPaint& paint, // unitSquareVertexBuffer() static const int worstCaseVertCount = 10; - const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(); + const GrGeometryProcessor* gp = GrDefaultGeoProcFactory::Create(color); drawState.setGeometryProcessor(gp)->unref(); GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, @@ -788,7 +793,7 @@ void GrContext::drawRect(const GrPaint& paint, target->drawNonIndexed(&drawState, primType, 0, vertCount); } else { // filled BW rect - target->drawSimpleRect(&drawState, rect); + target->drawSimpleRect(&drawState, color, rect); } } @@ -805,14 +810,15 @@ void GrContext::drawRectToRect(const GrPaint& paint, GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target); - target->drawRect(&drawState, dstRect, &localRect, localMatrix); + target->drawRect(&drawState, paint.getColor(), dstRect, &localRect, localMatrix); } static void set_vertex_attributes(GrDrawState* drawState, const SkPoint* texCoords, const GrColor* colors, int* colorOffset, - int* texOffset) { + int* texOffset, + GrColor color) { *texOffset = -1; *colorOffset = -1; @@ -829,7 +835,7 @@ static void set_vertex_attributes(GrDrawState* drawState, *colorOffset = sizeof(SkPoint); flags |= GrDefaultGeoProcFactory::kColor_GPType; } - drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref(); + drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref(); } void GrContext::drawVertices(const GrPaint& paint, @@ -852,7 +858,8 @@ void GrContext::drawVertices(const GrPaint& paint, GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target); int colorOffset = -1, texOffset = -1; - set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset); + set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset, + paint.getColor()); size_t vertexStride = drawState.getGeometryProcessor()->getVertexStride(); SkASSERT(vertexStride == sizeof(SkPoint) + (SkToBool(texCoords) ? sizeof(SkPoint) : 0) @@ -915,11 +922,12 @@ void GrContext::drawRRect(const GrPaint& paint, const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); - if (!fOvalRenderer->drawRRect(target, &drawState, this, paint.isAntiAlias(), rrect, + GrColor color = paint.getColor(); + if (!fOvalRenderer->drawRRect(target, &drawState, color, this, paint.isAntiAlias(), rrect, strokeRec)) { SkPath path; path.addRRect(rrect); - this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo); + this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, strokeInfo); } } @@ -938,14 +946,16 @@ void GrContext::drawDRRect(const GrPaint& paint, GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target); - if (!fOvalRenderer->drawDRRect(target, &drawState, this, paint.isAntiAlias(), outer, inner)) { + GrColor color = paint.getColor(); + if (!fOvalRenderer->drawDRRect(target, &drawState, color, this, paint.isAntiAlias(), outer, + inner)) { SkPath path; path.addRRect(inner); path.addRRect(outer); path.setFillType(SkPath::kEvenOdd_FillType); GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle); - this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, fillRec); + this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, fillRec); } } @@ -976,17 +986,19 @@ void GrContext::drawOval(const GrPaint& paint, const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec(); - - if (!fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(), oval, strokeRec)) { + GrColor color = paint.getColor(); + if (!fOvalRenderer->drawOval(target, &drawState, color, this, paint.isAntiAlias(), oval, + strokeRec)) { SkPath path; path.addOval(oval); - this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo); + this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, strokeInfo); } } // Can 'path' be drawn as a pair of filled nested rectangles? static bool is_nested_rects(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, SkRect rects[2]) { @@ -1002,7 +1014,8 @@ static bool is_nested_rects(GrDrawTarget* target, return false; } - if (!drawState->canTweakAlphaForCoverage() && !drawState->couldApplyCoverage(*target->caps())) { + if (!drawState->canTweakAlphaForCoverage() && + !drawState->canUseFracCoveragePrimProc(color, *target->caps())) { return false; } @@ -1048,6 +1061,7 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok return; } + GrColor color = paint.getColor(); if (strokeInfo.isDashed()) { SkPoint pts[2]; if (path.isLine(pts)) { @@ -1061,7 +1075,7 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok SkMatrix origViewMatrix = drawState.getViewMatrix(); GrDrawState::AutoViewMatrixRestore avmr; if (avmr.setIdentity(&drawState)) { - if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, pts, paint, + if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, color, pts, paint, strokeInfo, origViewMatrix)) { return; } @@ -1104,14 +1118,14 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok // Concave AA paths are expensive - try to avoid them for special cases SkRect rects[2]; - if (is_nested_rects(target, &drawState, path, strokeRec, rects)) { + if (is_nested_rects(target, &drawState, color, path, strokeRec, rects)) { SkMatrix origViewMatrix = drawState.getViewMatrix(); GrDrawState::AutoViewMatrixRestore avmr; if (!avmr.setIdentity(&drawState)) { return; } - fAARectRenderer->fillAANestedRects(target, &drawState, rects, origViewMatrix); + fAARectRenderer->fillAANestedRects(target, &drawState, color, rects, origViewMatrix); return; } } @@ -1120,14 +1134,15 @@ void GrContext::drawPath(const GrPaint& paint, const SkPath& path, const GrStrok bool isOval = path.isOval(&ovalRect); if (!isOval || path.isInverseFillType() - || !fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(), ovalRect, + || !fOvalRenderer->drawOval(target, &drawState, color, this, paint.isAntiAlias(), ovalRect, strokeRec)) { - this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo); + this->internalDrawPath(target, &drawState, color, paint.isAntiAlias(), path, strokeInfo); } } void GrContext::internalDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, bool useAA, const SkPath& path, const GrStrokeInfo& strokeInfo) { @@ -1142,7 +1157,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, // thing WRT to the blend then we'll need some query on the PR. bool useCoverageAA = useAA && !drawState->getRenderTarget()->isMultisampled() && - drawState->couldApplyCoverage(*target->caps()); + drawState->canUseFracCoveragePrimProc(color, *target->caps()); GrPathRendererChain::DrawType type = @@ -1179,7 +1194,7 @@ void GrContext::internalDrawPath(GrDrawTarget* target, return; } - pr->drawPath(target, drawState, *pathPtr, *stroke, useCoverageAA); + pr->drawPath(target, drawState, color, *pathPtr, *stroke, useCoverageAA); } //////////////////////////////////////////////////////////////////////////////// @@ -1320,8 +1335,8 @@ bool GrContext::writeSurfacePixels(GrSurface* surface, GrDrawState drawState(matrix); drawState.addColorProcessor(fp); drawState.setRenderTarget(renderTarget); - drawTarget->drawSimpleRect(&drawState, SkRect::MakeWH(SkIntToScalar(width), - SkIntToScalar(height))); + drawTarget->drawSimpleRect(&drawState, GrColor_WHITE,SkRect::MakeWH(SkIntToScalar(width), + SkIntToScalar(height))); } if (kFlushWrites_PixelOp & pixelOpsFlags) { @@ -1442,7 +1457,7 @@ bool GrContext::readRenderTargetPixels(GrRenderTarget* target, drawState.setRenderTarget(tempTexture->asRenderTarget()); SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); - fDrawBuffer->drawSimpleRect(&drawState, rect); + fDrawBuffer->drawSimpleRect(&drawState, GrColor_WHITE, rect); // we want to read back from the scratch's origin left = 0; top = 0; @@ -1543,8 +1558,8 @@ GrDrawTarget* GrContext::prepareToDraw(GrDrawState* ds, SkASSERT(acf); ds->setFromPaint(*paint, fViewMatrix, fRenderTarget.get()); #if GR_DEBUG_PARTIAL_COVERAGE_CHECK - if ((paint->hasMask() || 0xff != paint->fCoverage) && - !fDrawState->couldApplyCoverage(fGpu->caps())) { + if ((paint->hasMask()) && + !fDrawState->canUseFracCoveragePrimProc(paint.getColor(), fGpu->caps())) { SkDebugf("Partial pixel coverage will be incorrectly blended.\n"); } #endif diff --git a/src/gpu/GrDefaultGeoProcFactory.cpp b/src/gpu/GrDefaultGeoProcFactory.cpp index 6b9d2c2aeb..dca6c1c017 100644 --- a/src/gpu/GrDefaultGeoProcFactory.cpp +++ b/src/gpu/GrDefaultGeoProcFactory.cpp @@ -21,8 +21,8 @@ typedef GrDefaultGeoProcFactory Flag; class DefaultGeoProc : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(uint32_t gpTypeFlags) { - return SkNEW_ARGS(DefaultGeoProc, (gpTypeFlags)); + static GrGeometryProcessor* Create(GrColor color, uint8_t coverage, uint32_t gpTypeFlags) { + return SkNEW_ARGS(DefaultGeoProc, (color, coverage, gpTypeFlags)); } virtual const char* name() const SK_OVERRIDE { return "DefaultGeometryProcessor"; } @@ -95,8 +95,9 @@ public: } private: - DefaultGeoProc(uint32_t gpTypeFlags) - : fInPosition(NULL) + DefaultGeoProc(GrColor color, uint8_t coverage, uint32_t gpTypeFlags) + : INHERITED(color, coverage) + , fInPosition(NULL) , fInColor(NULL) , fInLocalCoords(NULL) , fInCoverage(NULL) @@ -143,7 +144,7 @@ private: GR_DECLARE_GEOMETRY_PROCESSOR_TEST; - typedef GrFragmentProcessor INHERITED; + typedef GrGeometryProcessor INHERITED; }; GR_DEFINE_GEOMETRY_PROCESSOR_TEST(DefaultGeoProc); @@ -163,9 +164,10 @@ GrGeometryProcessor* DefaultGeoProc::TestCreate(SkRandom* random, flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType; } - return DefaultGeoProc::Create(flags); + return DefaultGeoProc::Create(GrRandomColor(random), GrRandomCoverage(random), flags); } -const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(uint32_t gpTypeFlags) { - return DefaultGeoProc::Create(gpTypeFlags); +const GrGeometryProcessor* GrDefaultGeoProcFactory::Create(GrColor color, uint32_t gpTypeFlags, + uint8_t coverage) { + return DefaultGeoProc::Create(color, coverage, gpTypeFlags); } diff --git a/src/gpu/GrDefaultGeoProcFactory.h b/src/gpu/GrDefaultGeoProcFactory.h index a39c76da19..53fb4b8dcc 100644 --- a/src/gpu/GrDefaultGeoProcFactory.h +++ b/src/gpu/GrDefaultGeoProcFactory.h @@ -80,7 +80,9 @@ public: * * You must unref the return from Create. */ - static const GrGeometryProcessor* Create(uint32_t gpTypeFlags = 0); + static const GrGeometryProcessor* Create(GrColor, uint32_t gpTypeFlags = 0, + uint8_t coverage = 0xff); + static size_t DefaultVertexStride() { return sizeof(PositionAttr); } }; #endif diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index 4d9026f086..24d3c456cb 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -233,12 +233,10 @@ bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target, } } - // TODO this is really wierd, I just need default vertex stride, can I think of a better way? - SkAutoTUnref<const GrGeometryProcessor> gp(GrDefaultGeoProcFactory::Create()); - if (!arg->set(target, maxPts, gp->getVertexStride(), maxIdxs)) { + if (!arg->set(target, maxPts, GrDefaultGeoProcFactory::DefaultVertexStride(), maxIdxs)) { return false; } - SkASSERT(gp->getVertexStride() == sizeof(SkPoint)); + SkASSERT(GrDefaultGeoProcFactory::DefaultVertexStride() == sizeof(SkPoint)); uint16_t* idxBase = reinterpret_cast<uint16_t*>(arg->indices()); uint16_t* idx = idxBase; @@ -330,6 +328,7 @@ FINISHED: bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& origStroke, bool stencilOnly) { @@ -337,10 +336,10 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke); SkScalar hairlineCoverage; + uint8_t newCoverage = 0xff; if (IsStrokeHairlineOrEquivalent(*stroke, drawState->getViewMatrix(), &hairlineCoverage)) { - uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->getCoverage()); - drawState->setCoverage(newCoverage); + newCoverage = SkScalarRoundToInt(hairlineCoverage * 0xff); if (!stroke->isHairlineStyle()) { stroke.writable()->setHairlineStyle(); @@ -493,13 +492,16 @@ bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target, bounds = path.getBounds(); } GrDrawTarget::AutoGeometryPush agp(target); - target->drawSimpleRect(drawState, bounds); + target->drawSimpleRect(drawState, color, bounds); } else { if (passCount > 1) { drawState->enableState(GrDrawState::kNoColorWrites_StateBit); } GrDrawState::AutoRestoreEffects are(drawState); - drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create())->unref(); + drawState->setGeometryProcessor( + GrDefaultGeoProcFactory::Create(color, + GrDefaultGeoProcFactory::kPosition_GPType, + newCoverage))->unref(); if (indexCnt) { target->drawIndexed(drawState, primType, @@ -530,11 +532,13 @@ bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target, bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, bool antiAlias) { return this->internalDrawPath(target, drawState, + color, path, stroke, false); @@ -546,5 +550,5 @@ void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target, const SkStrokeRec& stroke) { SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType()); SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType()); - this->internalDrawPath(target, drawState, path, stroke, true); + this->internalDrawPath(target, drawState, GrColor_WHITE, path, stroke, true); } diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h index 0f90daa27f..aa481e5c9c 100644 --- a/src/gpu/GrDefaultPathRenderer.h +++ b/src/gpu/GrDefaultPathRenderer.h @@ -34,6 +34,7 @@ private: virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) SK_OVERRIDE; @@ -45,6 +46,7 @@ private: bool internalDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool stencilOnly); diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp index 1f4070f4f5..d35ba233e7 100755 --- a/src/gpu/GrDistanceFieldTextContext.cpp +++ b/src/gpu/GrDistanceFieldTextContext.cpp @@ -403,9 +403,11 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo if (textureUniqueID != fEffectTextureUniqueID || filteredColor != fEffectColor || flags != fEffectFlags) { + GrColor color = fPaint.getColor(); if (fUseLCDText) { GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); - fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(fCurrTexture, + fCachedGeometryProcessor.reset(GrDistanceFieldLCDTextureEffect::Create(color, + fCurrTexture, params, fGammaTexture, gammaParams, @@ -416,15 +418,18 @@ void GrDistanceFieldTextContext::setupCoverageEffect(const SkColor& filteredColo #ifdef SK_GAMMA_APPLY_TO_A8 U8CPU lum = SkColorSpaceLuminance::computeLuminance(fDeviceProperties.gamma(), filteredColor); - fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(fCurrTexture, + fCachedGeometryProcessor.reset(GrDistanceFieldTextureEffect::Create(color, + fCurrTexture, params, fGammaTexture, gammaParams, lum/255.f, flags)); #else - fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(fCurrTexture, - params, flags)); + fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Create(color, + fCurrTexture, + params, + flags)); #endif } fEffectTextureUniqueID = textureUniqueID; diff --git a/src/gpu/GrDrawState.cpp b/src/gpu/GrDrawState.cpp index 51ef6cf5d3..a91a43c44e 100644 --- a/src/gpu/GrDrawState.cpp +++ b/src/gpu/GrDrawState.cpp @@ -15,11 +15,6 @@ #include "effects/GrPorterDuffXferProcessor.h" bool GrDrawState::isEqual(const GrDrawState& that) const { - bool usingVertexColors = this->hasColorVertexAttribute(); - if (!usingVertexColors && this->fColor != that.fColor) { - return false; - } - if (this->getRenderTarget() != that.getRenderTarget() || this->fColorStages.count() != that.fColorStages.count() || this->fCoverageStages.count() != that.fCoverageStages.count() || @@ -30,11 +25,6 @@ bool GrDrawState::isEqual(const GrDrawState& that) const { return false; } - bool usingVertexCoverage = this->hasCoverageVertexAttribute(); - if (!usingVertexCoverage && this->fCoverage != that.fCoverage) { - return false; - } - bool explicitLocalCoords = this->hasLocalCoordAttribute(); if (this->hasGeometryProcessor()) { if (!that.hasGeometryProcessor()) { @@ -83,11 +73,9 @@ GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr GrDrawState& GrDrawState::operator=(const GrDrawState& that) { fRenderTarget.reset(SkSafeRef(that.fRenderTarget.get())); - fColor = that.fColor; fViewMatrix = that.fViewMatrix; fFlagBits = that.fFlagBits; fStencilSettings = that.fStencilSettings; - fCoverage = that.fCoverage; fDrawFace = that.fDrawFace; fGeometryProcessor.reset(SkSafeRef(that.fGeometryProcessor.get())); fXPFactory.reset(SkRef(that.getXPFactory())); @@ -116,7 +104,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { fColorStages.reset(); fCoverageStages.reset(); - fColor = 0xffffffff; if (NULL == initialViewMatrix) { fViewMatrix.reset(); } else { @@ -124,7 +111,6 @@ void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { } fFlagBits = 0x0; fStencilSettings.setDisabled(); - fCoverage = 0xff; fDrawFace = kBoth_DrawFace; fHints = 0; @@ -181,29 +167,34 @@ void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRende // Enable the clip bit this->enableState(GrDrawState::kClip_StateBit); - this->setColor(paint.getColor()); this->setState(GrDrawState::kDither_StateBit, paint.isDither()); this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); - this->setCoverage(0xFF); fColorProcInfoValid = false; fCoverageProcInfoValid = false; + + fColorCache = GrColor_ILLEGAL; + fCoverageCache = GrColor_ILLEGAL; } //////////////////////////////////////////////////////////////////////////////// -bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { +bool GrDrawState::canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const { if (caps.dualSourceBlendingSupport()) { return true; } - this->calcColorInvariantOutput(); - this->calcCoverageInvariantOutput(); + this->calcColorInvariantOutput(color); + + // The coverage isn't actually white, its unknown, but this will produce the same effect + // TODO we want to cache the result of this call, but we can probably clean up the interface + // so we don't have to pass in a seemingly known coverage + this->calcCoverageInvariantOutput(GrColor_WHITE); return fXPFactory->canApplyCoverage(fColorProcInfo, fCoverageProcInfo, this->isCoverageDrawing(), this->isColorWriteDisabled()); } -bool GrDrawState::hasSolidCoverage() const { +bool GrDrawState::hasSolidCoverage(GrColor coverage) const { // If we're drawing coverage directly then coverage is effectively treated as color. if (this->isCoverageDrawing()) { return true; @@ -213,15 +204,15 @@ bool GrDrawState::hasSolidCoverage() const { return false; } - this->calcCoverageInvariantOutput(); + this->calcCoverageInvariantOutput(coverage); return fCoverageProcInfo.isSolidWhite(); } //////////////////////////////////////////////////////////////////////////////s -bool GrDrawState::willEffectReadDstColor() const { - this->calcColorInvariantOutput(); - this->calcCoverageInvariantOutput(); +bool GrDrawState::willEffectReadDstColor(GrColor color, GrColor coverage) const { + this->calcColorInvariantOutput(color); + this->calcCoverageInvariantOutput(coverage); // TODO: Remove need to create the XP here. // Also once all custom blends are turned into XPs we can remove the need // to check other stages since only xp's will be able to read dst @@ -378,25 +369,24 @@ GrDrawState::~GrDrawState() { //////////////////////////////////////////////////////////////////////////////// -bool GrDrawState::srcAlphaWillBeOne() const { - this->calcColorInvariantOutput(); +bool GrDrawState::srcAlphaWillBeOne(GrColor color, GrColor coverage) const { + this->calcColorInvariantOutput(color); if (this->isCoverageDrawing()) { - this->calcCoverageInvariantOutput(); + this->calcCoverageInvariantOutput(coverage); return (fColorProcInfo.isOpaque() && fCoverageProcInfo.isOpaque()); } return fColorProcInfo.isOpaque(); } -bool GrDrawState::willBlendWithDst() const { - this->calcColorInvariantOutput(); - this->calcCoverageInvariantOutput(); +bool GrDrawState::willBlendWithDst(GrColor color, GrColor coverage) const { + this->calcColorInvariantOutput(color); + this->calcCoverageInvariantOutput(coverage); return fXPFactory->willBlendWithDst(fColorProcInfo, fCoverageProcInfo, this->isCoverageDrawing(), this->isColorWriteDisabled()); } -void GrDrawState::calcColorInvariantOutput() const { - if (!fColorProcInfoValid) { - GrColor color; +void GrDrawState::calcColorInvariantOutput(GrColor color) const { + if (!fColorProcInfoValid || color != fColorCache) { GrColorComponentFlags flags; if (this->hasColorVertexAttribute()) { if (fHints & kVertexColorsAreOpaque_Hint) { @@ -408,28 +398,27 @@ void GrDrawState::calcColorInvariantOutput() const { } } else { flags = kRGBA_GrColorComponentFlags; - color = this->getColor(); } fColorProcInfo.calcWithInitialValues(fColorStages.begin(), this->numColorStages(), color, flags, false); fColorProcInfoValid = true; + fColorCache = color; } } -void GrDrawState::calcCoverageInvariantOutput() const { - if (!fCoverageProcInfoValid) { - GrColor color; +void GrDrawState::calcCoverageInvariantOutput(GrColor coverage) const { + if (!fCoverageProcInfoValid || coverage != fCoverageCache) { GrColorComponentFlags flags; // Check if per-vertex or constant color may have partial alpha if (this->hasCoverageVertexAttribute()) { flags = static_cast<GrColorComponentFlags>(0); - color = 0; + coverage = 0; } else { flags = kRGBA_GrColorComponentFlags; - color = this->getCoverageColor(); } fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->numCoverageStages(), - color, flags, true, fGeometryProcessor.get()); + coverage, flags, true, fGeometryProcessor.get()); fCoverageProcInfoValid = true; + fCoverageCache = coverage; } } diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 68c71f020a..17bd0f43df 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -92,73 +92,21 @@ public: * * This function considers the current draw state and the draw target's capabilities to * determine whether coverage can be handled correctly. This function assumes that the caller - * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex - * attribute, or a coverage effect) but may not have specified it yet. + * intends to specify fractional pixel coverage via a primitive processor but may not have + * specified it yet. */ - bool couldApplyCoverage(const GrDrawTargetCaps& caps) const; + bool canUseFracCoveragePrimProc(GrColor color, const GrDrawTargetCaps& caps) const; /** * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw. */ - bool hasSolidCoverage() const; + bool hasSolidCoverage(GrColor coverage) const; /** * This function returns true if the render target destination pixel values will be read for * blending during draw. */ - bool willBlendWithDst() const; - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Color - //// - - GrColor getColor() const { return fColor; } - - /** - * Sets color for next draw to a premultiplied-alpha color. - * - * @param color the color to set. - */ - void setColor(GrColor color) { - if (color != fColor) { - fColor = color; - fColorProcInfoValid = false; - } - } - - /** - * Sets the color to be used for the next draw to be - * (r,g,b,a) = (alpha, alpha, alpha, alpha). - * - * @param alpha The alpha value to set as the color. - */ - void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); } - - /// @} - - /////////////////////////////////////////////////////////////////////////// - /// @name Coverage - //// - - uint8_t getCoverage() const { return fCoverage; } - - GrColor getCoverageColor() const { - return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage); - } - - /** - * Sets a constant fractional coverage to be applied to the draw. The - * initial value (after construction or reset()) is 0xff. The constant - * coverage is ignored when per-vertex coverage is provided. - */ - void setCoverage(uint8_t coverage) { - if (coverage != fCoverage) { - fCoverage = coverage; - fCoverageProcInfoValid = false; - } - } + bool willBlendWithDst(GrColor color, GrColor coverage) const; /// @} @@ -213,8 +161,9 @@ public: /** * Checks whether any of the effects will read the dst pixel color. + * TODO remove when we have an XP */ - bool willEffectReadDstColor() const; + bool willEffectReadDstColor(GrColor color, GrColor coverage) const; /** * The xfer processor factory. @@ -608,32 +557,32 @@ public: private: bool isEqual(const GrDrawState& that) const; - const GrProcOptInfo& colorProcInfo() const { - this->calcColorInvariantOutput(); + const GrProcOptInfo& colorProcInfo(GrColor color) const { + this->calcColorInvariantOutput(color); return fColorProcInfo; } - const GrProcOptInfo& coverageProcInfo() const { - this->calcCoverageInvariantOutput(); + const GrProcOptInfo& coverageProcInfo(GrColor coverage) const { + this->calcCoverageInvariantOutput(coverage); return fCoverageProcInfo; } /** * Determines whether src alpha is guaranteed to be one for all src pixels */ - bool srcAlphaWillBeOne() const; + bool srcAlphaWillBeOne(GrColor color, GrColor coverage) const; /** * If fColorProcInfoValid is false, function calculates the invariant output for the color * stages and results are stored in fColorProcInfo. */ - void calcColorInvariantOutput() const; + void calcColorInvariantOutput(GrColor) const; /** * If fCoverageProcInfoValid is false, function calculates the invariant output for the coverage * stages and results are stored in fCoverageProcInfo. */ - void calcCoverageInvariantOutput() const; + void calcCoverageInvariantOutput(GrColor) const; void onReset(const SkMatrix* initialViewMatrix); @@ -644,11 +593,9 @@ private: typedef SkSTArray<4, GrFragmentStage> FragmentStageArray; SkAutoTUnref<GrRenderTarget> fRenderTarget; - GrColor fColor; SkMatrix fViewMatrix; uint32_t fFlagBits; GrStencilSettings fStencilSettings; - uint8_t fCoverage; DrawFace fDrawFace; SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor; SkAutoTUnref<const GrXPFactory> fXPFactory; @@ -660,6 +607,8 @@ private: mutable GrProcOptInfo fCoverageProcInfo; mutable bool fColorProcInfoValid; mutable bool fCoverageProcInfoValid; + mutable GrColor fColorCache; + mutable GrColor fCoverageCache; friend class GrOptDrawState; }; diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index 0d6a388609..adb7128e1c 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -383,9 +383,12 @@ bool GrDrawTarget::checkDraw(const GrDrawState& drawState, } bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds, + GrColor color, + uint8_t coverage, GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) { - if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor()) { + GrColor c = GrColorPackRGBA(coverage, coverage, coverage, coverage); + if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor(color, c)) { return true; } SkIRect copyRect; @@ -468,10 +471,12 @@ void GrDrawTarget::drawIndexed(GrDrawState* ds, // TODO: We should continue with incorrect blending. GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) { + const GrGeometryProcessor* gp = ds->getGeometryProcessor(); + if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy, + devBounds)) { return; } - this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride()); + this->setDrawBuffers(&info, gp->getVertexStride()); this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); } @@ -510,11 +515,13 @@ void GrDrawTarget::drawNonIndexed(GrDrawState* ds, // TODO: We should continue with incorrect blending. GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) { + const GrGeometryProcessor* gp = ds->getGeometryProcessor(); + if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy, + devBounds)) { return; } - this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride()); + this->setDrawBuffers(&info, gp->getVertexStride()); this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); } @@ -581,6 +588,7 @@ void GrDrawTarget::stencilPath(GrDrawState* ds, } void GrDrawTarget::drawPath(GrDrawState* ds, + GrColor color, const GrPath* path, GrPathRendering::FillType fill) { // TODO: extract portions of checkDraw that are relevant to path rendering. @@ -607,14 +615,16 @@ void GrDrawTarget::drawPath(GrDrawState* ds, &stencilSettings); GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(ds, &dstCopy, &devBounds)) { + if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, &devBounds)) { return; } - this->onDrawPath(*ds, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL); + this->onDrawPath(*ds, color, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : + NULL); } void GrDrawTarget::drawPaths(GrDrawState* ds, + GrColor color, const GrPathRange* pathRange, const void* indices, PathIndexType indexType, @@ -649,12 +659,12 @@ void GrDrawTarget::drawPaths(GrDrawState* ds, // point, because any context that supports NV_path_rendering will also // support NV_blend_equation_advanced. GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(ds, &dstCopy, NULL)) { + if (!this->setupDstReadIfNecessary(ds, color, 0xff, &dstCopy, NULL)) { return; } - this->onDrawPaths(*ds, pathRange, indices, indexType, transformValues, transformType, count, - scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL); + this->onDrawPaths(*ds, color, pathRange, indices, indexType, transformValues, transformType, + count, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL); } void GrDrawTarget::clear(const SkIRect* rect, @@ -673,11 +683,9 @@ void GrDrawTarget::clear(const SkIRect* rect, } GrDrawState drawState; - - drawState.setColor(color); drawState.setRenderTarget(renderTarget); - this->drawSimpleRect(&drawState, *rect); + this->drawSimpleRect(&drawState, color, *rect); } else { this->onClear(rect, color, canIgnoreRect, renderTarget); } @@ -763,7 +771,8 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds, // TODO: We should continue with incorrect blending. GrDeviceCoordTexture dstCopy; - if (!this->setupDstReadIfNecessary(ds, &dstCopy, devBounds)) { + const GrGeometryProcessor* gp = ds->getGeometryProcessor(); + if (!this->setupDstReadIfNecessary(ds, gp->getColor(), gp->getCoverage(), &dstCopy,devBounds)) { return; } @@ -778,7 +787,7 @@ void GrDrawTarget::drawIndexedInstances(GrDrawState* ds, info.fStartIndex, info.fVertexCount, info.fIndexCount)) { - this->setDrawBuffers(&info, ds->getGeometryProcessor()->getVertexStride()); + this->setDrawBuffers(&info, gp->getVertexStride()); this->onDraw(*ds, info, scissorState, dstCopy.texture() ? &dstCopy : NULL); } info.fStartVertex += info.fVertexCount; @@ -944,7 +953,7 @@ bool GrDrawTarget::copySurface(GrSurface* dst, clippedDstPoint.fY, clippedSrcRect.width(), clippedSrcRect.height()); - this->drawSimpleRect(&drawState, dstRect); + this->drawSimpleRect(&drawState, GrColor_WHITE, dstRect); return true; } diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index c7f45d32ca..fc2ee76231 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -269,7 +269,7 @@ public: * Draws a path. Fill must not be a hairline. It will respect the HW * antialias flag on the draw state (if possible in the 3D API). */ - void drawPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill); + void drawPath(GrDrawState*, GrColor, const GrPath*, GrPathRendering::FillType fill); /** * Draws the aggregate path from combining multiple. Note that this will not @@ -284,7 +284,9 @@ public: * @param count Number of paths to draw * @param fill Fill type for drawing all the paths */ - void drawPaths(GrDrawState*, const GrPathRange* pathRange, + void drawPaths(GrDrawState*, + GrColor, + const GrPathRange* pathRange, const void* indices, PathIndexType indexType, const float transformValues[], @@ -305,22 +307,23 @@ public: * srcMatrix can be NULL when no srcMatrix is desired. */ void drawRect(GrDrawState* ds, + GrColor color, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { AutoGeometryPush agp(this); - this->onDrawRect(ds, rect, localRect, localMatrix); + this->onDrawRect(ds, color, rect, localRect, localMatrix); } /** * Helper for drawRect when the caller doesn't need separate local rects or matrices. */ - void drawSimpleRect(GrDrawState* ds, const SkRect& rect) { - this->drawRect(ds, rect, NULL, NULL); + void drawSimpleRect(GrDrawState* ds, GrColor color, const SkRect& rect) { + this->drawRect(ds, color, rect, NULL, NULL); } - void drawSimpleRect(GrDrawState* ds, const SkIRect& irect) { + void drawSimpleRect(GrDrawState* ds, GrColor color, const SkIRect& irect) { SkRect rect = SkRect::Make(irect); - this->drawRect(ds, rect, NULL, NULL); + this->drawRect(ds, color, rect, NULL, NULL); } /** @@ -653,6 +656,8 @@ protected: // but couldn't be made. Otherwise, returns true. This method needs to be protected because it // needs to be accessed by GLPrograms to setup a correct drawstate bool setupDstReadIfNecessary(GrDrawState*, + GrColor, + uint8_t, GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds); @@ -698,6 +703,7 @@ private: const GrDeviceCoordTexture* dstCopy) = 0; // TODO copy in order drawbuffer onDrawRect to here virtual void onDrawRect(GrDrawState*, + GrColor color, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) = 0; @@ -707,11 +713,13 @@ private: const GrClipMaskManager::ScissorState&, const GrStencilSettings&) = 0; virtual void onDrawPath(const GrDrawState&, + GrColor, const GrPath*, const GrClipMaskManager::ScissorState&, const GrStencilSettings&, const GrDeviceCoordTexture* dstCopy) = 0; virtual void onDrawPaths(const GrDrawState&, + GrColor, const GrPathRange*, const void* indices, PathIndexType, diff --git a/src/gpu/GrGeometryProcessor.h b/src/gpu/GrGeometryProcessor.h index 9e621d82a0..4801069005 100644 --- a/src/gpu/GrGeometryProcessor.h +++ b/src/gpu/GrGeometryProcessor.h @@ -8,6 +8,7 @@ #ifndef GrGeometryProcessor_DEFINED #define GrGeometryProcessor_DEFINED +#include "GrColor.h" #include "GrGeometryData.h" #include "GrProcessor.h" #include "GrShaderVar.h" @@ -50,8 +51,10 @@ class GrOptDrawState; */ class GrGeometryProcessor : public GrProcessor { public: - GrGeometryProcessor() + GrGeometryProcessor(GrColor color, uint8_t coverage = 0xff) : fVertexStride(0) + , fColor(color) + , fCoverage(coverage) , fWillUseGeoShader(false) , fHasVertexColor(false) , fHasVertexCoverage(false) @@ -107,6 +110,14 @@ public: if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) { return false; } + + if (!fHasVertexColor && this->getColor() != that.getColor()) { + return false; + } + + if (!fHasVertexCoverage && this->getCoverage() != that.getCoverage()) { + return false; + } return this->onIsEqual(that); } @@ -119,12 +130,17 @@ public: virtual void initBatchTracker(GrBatchTracker*, const InitBT&) const {} + GrColor getColor() const { return fColor; } + uint8_t getCoverage() const { return fCoverage; } + // TODO this is a total hack until the gp can own whether or not it uses uniform // color / coverage bool hasVertexColor() const { return fHasVertexColor; } bool hasVertexCoverage() const { return fHasVertexCoverage; } bool hasLocalCoords() const { return fHasLocalCoords; } + void computeInvariantColor(GrInvariantOutput* inout) const; + protected: /** * Subclasses call this from their constructor to register vertex attributes. Attributes @@ -149,6 +165,8 @@ private: SkSTArray<kMaxVertexAttribs, GrAttribute, true> fAttribs; size_t fVertexStride; + GrColor fColor; + uint8_t fCoverage; bool fWillUseGeoShader; bool fHasVertexColor; bool fHasVertexCoverage; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index 3c7b14677b..493420db0b 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -66,7 +66,7 @@ static void set_vertex_attributes(GrDrawState* drawState, bool hasLocalCoords, G uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType | GrDefaultGeoProcFactory::kColor_GPType; flags |= hasLocalCoords ? GrDefaultGeoProcFactory::kLocalCoord_GPType : 0; - drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(flags))->unref(); + drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(color, flags))->unref(); if (0xFF == GrColorUnpackA(color)) { drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true); } @@ -110,12 +110,12 @@ static inline uint8_t strip_trace_bit(uint8_t cmd) { return cmd & kCmdMask; } static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); } void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds, + GrColor color, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) { GrDrawState::AutoRestoreEffects are(ds); - GrColor color = ds->getColor(); set_vertex_attributes(ds, SkToBool(localRect), color); size_t vstride = ds->getGeometryProcessor()->getVertexStride(); @@ -226,7 +226,9 @@ void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds, const GrDeviceCoordTexture* dstCopy) { SkASSERT(info.vertexBuffer() && (!info.isIndexed() || info.indexBuffer())); - if (!this->recordStateAndShouldDraw(ds, GrGpu::PrimTypeToDrawType(info.primitiveType()), + const GrGeometryProcessor* gp = ds.getGeometryProcessor(); + if (!this->recordStateAndShouldDraw(ds, gp->getColor(), gp->getCoverage(), + GrGpu::PrimTypeToDrawType(info.primitiveType()), scissorState, dstCopy)) { return; } @@ -251,7 +253,8 @@ void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, const GrClipMaskManager::ScissorState& scissorState, const GrStencilSettings& stencilSettings) { // Only compare the subset of GrDrawState relevant to path stenciling? - if (!this->recordStateAndShouldDraw(ds, GrGpu::kStencilPath_DrawType, scissorState, NULL)) { + if (!this->recordStateAndShouldDraw(ds, GrColor_WHITE, 0xff, GrGpu::kStencilPath_DrawType, + scissorState, NULL)) { return; } StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path)); @@ -260,12 +263,14 @@ void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds, } void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, + GrColor color, const GrPath* path, const GrClipMaskManager::ScissorState& scissorState, const GrStencilSettings& stencilSettings, const GrDeviceCoordTexture* dstCopy) { // TODO: Only compare the subset of GrDrawState relevant to path covering? - if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) { + if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState, + dstCopy)) { return; } DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path)); @@ -274,6 +279,7 @@ void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds, } void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, + GrColor color, const GrPathRange* pathRange, const void* indices, PathIndexType indexType, @@ -287,7 +293,8 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, SkASSERT(indices); SkASSERT(transformValues); - if (!this->recordStateAndShouldDraw(ds, GrGpu::kDrawPath_DrawType, scissorState, dstCopy)) { + if (!this->recordStateAndShouldDraw(ds, color, 0xff, GrGpu::kDrawPath_DrawType, scissorState, + dstCopy)) { return; } @@ -317,7 +324,7 @@ void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds, transformType == previous->fTransformType && stencilSettings == previous->fStencilSettings && path_fill_type_is_winding(stencilSettings) && - !ds.willBlendWithDst()) { + !ds.willBlendWithDst(color, GrColor_WHITE)) { // Fold this DrawPaths call into the one previous. previous->fCount += count; return; @@ -483,12 +490,14 @@ bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst, } bool GrInOrderDrawBuffer::recordStateAndShouldDraw(const GrDrawState& ds, + GrColor color, + uint8_t coverage, GrGpu::DrawType drawType, const GrClipMaskManager::ScissorState& scissor, const GrDeviceCoordTexture* dstCopy) { SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, - (ds, *this->getGpu()->caps(), scissor, dstCopy, - drawType)); + (ds, color, coverage, *this->getGpu()->caps(), scissor, + dstCopy, drawType)); if (ss->fState.mustSkip()) { fCmdBuffer.pop_back(); return false; diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h index 01e560ac08..6771fccd66 100644 --- a/src/gpu/GrInOrderDrawBuffer.h +++ b/src/gpu/GrInOrderDrawBuffer.h @@ -171,11 +171,11 @@ private: }; struct SetState : public Cmd { - SetState(const GrDrawState& drawState, const GrDrawTargetCaps& caps, - const ScissorState& scissor, const GrDeviceCoordTexture* dstCopy, - GrGpu::DrawType drawType) + SetState(const GrDrawState& drawState, GrColor color, uint8_t coverage, + const GrDrawTargetCaps& caps, const ScissorState& scissor, + const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType) : Cmd(kSetState_Cmd) - , fState(drawState, caps, scissor, dstCopy, drawType) {} + , fState(drawState, color, coverage, caps, scissor, dstCopy, drawType) {} void execute(GrInOrderDrawBuffer*, const GrOptDrawState*) SK_OVERRIDE; @@ -194,6 +194,7 @@ private: const ScissorState&, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; void onDrawRect(GrDrawState*, + GrColor, const SkRect& rect, const SkRect* localRect, const SkMatrix* localMatrix) SK_OVERRIDE; @@ -203,11 +204,13 @@ private: const ScissorState&, const GrStencilSettings&) SK_OVERRIDE; void onDrawPath(const GrDrawState&, + GrColor, const GrPath*, const ScissorState&, const GrStencilSettings&, const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE; void onDrawPaths(const GrDrawState&, + GrColor, const GrPathRange*, const void* indices, PathIndexType, @@ -234,6 +237,8 @@ private: // records it. If the draw can be skipped false is returned and no new GrOptDrawState is // recorded. bool SK_WARN_UNUSED_RESULT recordStateAndShouldDraw(const GrDrawState&, + GrColor, + uint8_t coverage, GrGpu::DrawType, const GrClipMaskManager::ScissorState&, const GrDeviceCoordTexture*); diff --git a/src/gpu/GrOptDrawState.cpp b/src/gpu/GrOptDrawState.cpp index d3172010ed..409305ce33 100644 --- a/src/gpu/GrOptDrawState.cpp +++ b/src/gpu/GrOptDrawState.cpp @@ -14,18 +14,21 @@ #include "GrXferProcessor.h" GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, + GrColor color, + uint8_t coverage, const GrDrawTargetCaps& caps, const ScissorState& scissorState, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType) : fFinalized(false) { + GrColor coverageColor = GrColorPackRGBA(coverage, coverage, coverage, coverage); fDrawType = drawType; - const GrProcOptInfo& colorPOI = drawState.colorProcInfo(); - const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(); + const GrProcOptInfo& colorPOI = drawState.colorProcInfo(color); + const GrProcOptInfo& coveragePOI = drawState.coverageProcInfo(coverageColor); fColor = colorPOI.inputColorToEffectiveStage(); - fCoverage = drawState.getCoverage(); + fCoverage = coverage; // Create XferProcessor from DS's XPFactory SkAutoTUnref<GrXferProcessor> xferProcessor( @@ -144,10 +147,11 @@ GrOptDrawState::GrOptDrawState(const GrDrawState& drawState, fGeometryProcessor->initBatchTracker(&fBatchTracker, init); } - this->setOutputStateInfo(drawState, optFlags, caps); + this->setOutputStateInfo(drawState, coverageColor, optFlags, caps); } void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds, + GrColor coverage, GrXferProcessor::OptFlags optFlags, const GrDrawTargetCaps& caps) { // Set this default and then possibly change our mind if there is coverage. @@ -157,7 +161,7 @@ void GrOptDrawState::setOutputStateInfo(const GrDrawState& ds, // Determine whether we should use dual source blending or shader code to keep coverage // separate from color. bool keepCoverageSeparate = !(optFlags & GrXferProcessor::kSetCoverageDrawing_OptFlag); - if (keepCoverageSeparate && !ds.hasSolidCoverage()) { + if (keepCoverageSeparate && !ds.hasSolidCoverage(coverage)) { if (caps.dualSourceBlendingSupport()) { if (kZero_GrBlendCoeff == fDstBlend) { // write the coverage value to second color diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h index 1878d16af3..cf5737373c 100644 --- a/src/gpu/GrOptDrawState.h +++ b/src/gpu/GrOptDrawState.h @@ -30,8 +30,8 @@ public: typedef GrClipMaskManager::ScissorState ScissorState; - GrOptDrawState(const GrDrawState& drawState, const GrDrawTargetCaps&, const ScissorState&, - const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType); + GrOptDrawState(const GrDrawState& drawState, GrColor, uint8_t coverage, const GrDrawTargetCaps&, + const ScissorState&, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType); bool operator== (const GrOptDrawState& that) const; bool operator!= (const GrOptDrawState& that) const { return !(*this == that); } @@ -206,7 +206,7 @@ private: * the function may adjust the blend coefficients. After this function is called the src and dst * blend coeffs will represent those used by backend API. */ - void setOutputStateInfo(const GrDrawState& ds, GrXferProcessor::OptFlags, + void setOutputStateInfo(const GrDrawState& ds, GrColor coverage, GrXferProcessor::OptFlags, const GrDrawTargetCaps&); enum Flags { diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 4d7912ae67..eac6fb4a3a 100644 --- a/src/gpu/GrOvalRenderer.cpp +++ b/src/gpu/GrOvalRenderer.cpp @@ -59,8 +59,8 @@ inline bool circle_stays_circle(const SkMatrix& m) { class CircleEdgeEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(bool stroke) { - return SkNEW_ARGS(CircleEdgeEffect, (stroke)); + static GrGeometryProcessor* Create(GrColor color, bool stroke) { + return SkNEW_ARGS(CircleEdgeEffect, (color, stroke)); } const GrAttribute* inPosition() const { return fInPosition; } @@ -131,7 +131,7 @@ public: } private: - CircleEdgeEffect(bool stroke) { + CircleEdgeEffect(GrColor color, bool stroke) : INHERITED(color) { this->initClassID<CircleEdgeEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInCircleEdge = &this->addVertexAttrib(GrAttribute("inCircleEdge", @@ -163,7 +163,7 @@ GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, GrContext* context, const GrDrawTargetCaps&, GrTexture* textures[]) { - return CircleEdgeEffect::Create(random->nextBool()); + return CircleEdgeEffect::Create(GrRandomColor(random), random->nextBool()); } /////////////////////////////////////////////////////////////////////////////// @@ -178,8 +178,8 @@ GrGeometryProcessor* CircleEdgeEffect::TestCreate(SkRandom* random, class EllipseEdgeEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(bool stroke) { - return SkNEW_ARGS(EllipseEdgeEffect, (stroke)); + static GrGeometryProcessor* Create(GrColor color, bool stroke) { + return SkNEW_ARGS(EllipseEdgeEffect, (color, stroke)); } virtual ~EllipseEdgeEffect() {} @@ -275,7 +275,7 @@ public: } private: - EllipseEdgeEffect(bool stroke) { + EllipseEdgeEffect(GrColor color, bool stroke) : INHERITED(color) { this->initClassID<EllipseEdgeEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInEllipseOffset = &this->addVertexAttrib(GrAttribute("inEllipseOffset", @@ -310,7 +310,7 @@ GrGeometryProcessor* EllipseEdgeEffect::TestCreate(SkRandom* random, GrContext* context, const GrDrawTargetCaps&, GrTexture* textures[]) { - return EllipseEdgeEffect::Create(random->nextBool()); + return EllipseEdgeEffect::Create(GrRandomColor(random), random->nextBool()); } /////////////////////////////////////////////////////////////////////////////// @@ -328,8 +328,8 @@ class DIEllipseEdgeEffect : public GrGeometryProcessor { public: enum Mode { kStroke = 0, kHairline, kFill }; - static GrGeometryProcessor* Create(Mode mode) { - return SkNEW_ARGS(DIEllipseEdgeEffect, (mode)); + static GrGeometryProcessor* Create(GrColor color, Mode mode) { + return SkNEW_ARGS(DIEllipseEdgeEffect, (color, mode)); } virtual ~DIEllipseEdgeEffect() {} @@ -440,7 +440,7 @@ public: } private: - DIEllipseEdgeEffect(Mode mode) { + DIEllipseEdgeEffect(GrColor color, Mode mode) : INHERITED(color) { this->initClassID<DIEllipseEdgeEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInEllipseOffsets0 = &this->addVertexAttrib(GrAttribute("inEllipseOffsets0", @@ -475,7 +475,7 @@ GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, GrContext* context, const GrDrawTargetCaps&, GrTexture* textures[]) { - return DIEllipseEdgeEffect::Create((Mode)(random->nextRangeU(0,2))); + return DIEllipseEdgeEffect::Create(GrRandomColor(random), (Mode)(random->nextRangeU(0,2))); } /////////////////////////////////////////////////////////////////////////////// @@ -487,6 +487,7 @@ void GrOvalRenderer::reset() { bool GrOvalRenderer::drawOval(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const GrContext* context, bool useAA, const SkRect& oval, @@ -494,7 +495,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, { bool useCoverageAA = useAA && !drawState->getRenderTarget()->isMultisampled() && - drawState->couldApplyCoverage(*target->caps()); + drawState->canUseFracCoveragePrimProc(color, *target->caps()); if (!useCoverageAA) { return false; @@ -505,13 +506,13 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, // we can draw circles if (SkScalarNearlyEqual(oval.width(), oval.height()) && circle_stays_circle(vm)) { - this->drawCircle(target, drawState, context, useCoverageAA, oval, stroke); + this->drawCircle(target, drawState, color, context, useCoverageAA, oval, stroke); // if we have shader derivative support, render as device-independent } else if (target->caps()->shaderDerivativeSupport()) { - return this->drawDIEllipse(target, drawState, context, useCoverageAA, oval, stroke); + return this->drawDIEllipse(target, drawState, color, context, useCoverageAA, oval, stroke); // otherwise axis-aligned ellipses only } else if (vm.rectStaysRect()) { - return this->drawEllipse(target, drawState, context, useCoverageAA, oval, stroke); + return this->drawEllipse(target, drawState, color, context, useCoverageAA, oval, stroke); } else { return false; } @@ -523,6 +524,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, void GrOvalRenderer::drawCircle(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const GrContext* context, bool useCoverageAA, const SkRect& circle, @@ -560,7 +562,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, } } - GrGeometryProcessor* gp = CircleEdgeEffect::Create(isStrokeOnly && innerRadius > 0); + GrGeometryProcessor* gp = CircleEdgeEffect::Create(color, isStrokeOnly && innerRadius > 0); drawState->setGeometryProcessor(gp)->unref(); GrDrawTarget::AutoReleaseGeometry geo(target, 4, gp->getVertexStride(), 0); @@ -615,6 +617,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const GrContext* context, bool useCoverageAA, const SkRect& ellipse, @@ -686,7 +689,8 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, return false; } - GrGeometryProcessor* gp = EllipseEdgeEffect::Create(isStrokeOnly && + GrGeometryProcessor* gp = EllipseEdgeEffect::Create(color, + isStrokeOnly && innerXRadius > 0 && innerYRadius > 0); drawState->setGeometryProcessor(gp)->unref(); @@ -748,6 +752,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const GrContext* context, bool useCoverageAA, const SkRect& ellipse, @@ -804,7 +809,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, SkScalar innerRatioX = SkScalarDiv(xRadius, innerXRadius); SkScalar innerRatioY = SkScalarDiv(yRadius, innerYRadius); - GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(mode); + GrGeometryProcessor* gp = DIEllipseEdgeEffect::Create(color, mode); drawState->setGeometryProcessor(gp)->unref(); @@ -905,13 +910,14 @@ GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(bool isStrokeOnly, GrGpu* gpu) { bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, GrContext* context, bool useAA, const SkRRect& origOuter, const SkRRect& origInner) { bool applyAA = useAA && !drawState->getRenderTarget()->isMultisampled() && - drawState->couldApplyCoverage(*target->caps()); + drawState->canUseFracCoveragePrimProc(color, *target->caps()); GrDrawState::AutoRestoreEffects are; if (!origInner.isEmpty()) { SkTCopyOnFirstWrite<SkRRect> inner(origInner); @@ -923,6 +929,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrPrimitiveEdgeType edgeType = applyAA ? kInverseFillAA_GrProcessorEdgeType : kInverseFillBW_GrProcessorEdgeType; + // TODO this needs to be a geometry processor GrFragmentProcessor* fp = GrRRectEffect::Create(edgeType, *inner); if (NULL == fp) { return false; @@ -932,7 +939,7 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, } SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle); - if (this->drawRRect(target, drawState, context, useAA, origOuter, fillRec)) { + if (this->drawRRect(target, drawState, color, context, useAA, origOuter, fillRec)) { return true; } @@ -961,23 +968,24 @@ bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, if (applyAA) { bounds.outset(SK_ScalarHalf, SK_ScalarHalf); } - target->drawRect(drawState, bounds, NULL, NULL); + target->drawRect(drawState, color, bounds, NULL, NULL); return true; } bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, GrContext* context, bool useAA, const SkRRect& rrect, const SkStrokeRec& stroke) { if (rrect.isOval()) { - return this->drawOval(target, drawState, context, useAA, rrect.getBounds(), stroke); + return this->drawOval(target, drawState, color, context, useAA, rrect.getBounds(), stroke); } bool useCoverageAA = useAA && !drawState->getRenderTarget()->isMultisampled() && - drawState->couldApplyCoverage(*target->caps()); + drawState->canUseFracCoveragePrimProc(color, *target->caps()); // only anti-aliased rrects for now if (!useCoverageAA) { @@ -1069,7 +1077,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, isStrokeOnly = (isStrokeOnly && innerRadius >= 0); - GrGeometryProcessor* effect = CircleEdgeEffect::Create(isStrokeOnly); + GrGeometryProcessor* effect = CircleEdgeEffect::Create(color, isStrokeOnly); drawState->setGeometryProcessor(effect)->unref(); GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0); @@ -1171,7 +1179,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); - GrGeometryProcessor* effect = EllipseEdgeEffect::Create(isStrokeOnly); + GrGeometryProcessor* effect = EllipseEdgeEffect::Create(color, isStrokeOnly); drawState->setGeometryProcessor(effect)->unref(); GrDrawTarget::AutoReleaseGeometry geo(target, 16, effect->getVertexStride(), 0); diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h index abad623589..85a9354959 100644 --- a/src/gpu/GrOvalRenderer.h +++ b/src/gpu/GrOvalRenderer.h @@ -33,18 +33,21 @@ public: bool drawOval(GrDrawTarget*, GrDrawState*, + GrColor, const GrContext*, bool useAA, const SkRect& oval, const SkStrokeRec& stroke); bool drawRRect(GrDrawTarget*, GrDrawState*, + GrColor, GrContext*, bool useAA, const SkRRect& rrect, const SkStrokeRec& stroke); bool drawDRRect(GrDrawTarget* target, GrDrawState*, + GrColor, GrContext* context, bool useAA, const SkRRect& outer, @@ -53,18 +56,21 @@ public: private: bool drawEllipse(GrDrawTarget* target, GrDrawState*, + GrColor, const GrContext* context, bool useCoverageAA, const SkRect& ellipse, const SkStrokeRec& stroke); bool drawDIEllipse(GrDrawTarget* target, GrDrawState*, + GrColor, const GrContext* context, bool useCoverageAA, const SkRect& ellipse, const SkStrokeRec& stroke); void drawCircle(GrDrawTarget* target, GrDrawState*, + GrColor, const GrContext* context, bool useCoverageAA, const SkRect& circle, diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h index 8f2d465b16..f4276b406f 100644 --- a/src/gpu/GrPathRenderer.h +++ b/src/gpu/GrPathRenderer.h @@ -117,6 +117,7 @@ public: */ bool drawPath(GrDrawTarget* target, GrDrawState* ds, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, bool antiAlias) { @@ -125,7 +126,7 @@ public: SkASSERT(ds->getStencil().isDisabled() || kNoRestriction_StencilSupport == this->getStencilSupport(target, ds, path, stroke)); - return this->onDrawPath(target, ds, path, stroke, antiAlias); + return this->onDrawPath(target, ds, color, path, stroke, antiAlias); } /** @@ -175,6 +176,7 @@ protected: */ virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) = 0; @@ -196,7 +198,7 @@ protected: 0xffff); drawState->setStencil(kIncrementStencil); drawState->enableState(GrDrawState::kNoColorWrites_StateBit); - this->drawPath(target, drawState, path, stroke, false); + this->drawPath(target, drawState, GrColor_WHITE, path, stroke, false); } // Helper for getting the device bounds of a path. Inverse filled paths will have bounds set diff --git a/src/gpu/GrProcessor.cpp b/src/gpu/GrProcessor.cpp index 96dd9eac6f..ccd4d7f7e8 100644 --- a/src/gpu/GrProcessor.cpp +++ b/src/gpu/GrProcessor.cpp @@ -9,6 +9,7 @@ #include "GrContext.h" #include "GrCoordTransform.h" #include "GrGeometryData.h" +#include "GrGeometryProcessor.h" #include "GrInvariantOutput.h" #include "GrMemoryPool.h" #include "GrXferProcessor.h" @@ -170,6 +171,12 @@ bool GrFragmentProcessor::hasSameTransforms(const GrFragmentProcessor& that) con /////////////////////////////////////////////////////////////////////////////////////////////////// +void GrGeometryProcessor::computeInvariantColor(GrInvariantOutput* intout) const { + +} + +/////////////////////////////////////////////////////////////////////////////////////////////////// + /* * GrGeometryData shares the same pool so it lives in this file too */ diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp index 590a040133..142cd92718 100644 --- a/src/gpu/GrSWMaskHelper.cpp +++ b/src/gpu/GrSWMaskHelper.cpp @@ -348,6 +348,7 @@ GrTexture* GrSWMaskHelper::DrawPathMaskToTexture(GrContext* context, void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture, GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkIRect& rect) { GrDrawState::AutoViewMatrixRestore avmr; if (!avmr.setIdentity(drawState)) { @@ -375,5 +376,5 @@ void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture, GrTextureParams::kNone_FilterMode, kPosition_GrCoordSet))->unref(); - target->drawSimpleRect(drawState, dstRect); + target->drawSimpleRect(drawState, color, dstRect); } diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h index 54a3897153..1eef46ecff 100644 --- a/src/gpu/GrSWMaskHelper.h +++ b/src/gpu/GrSWMaskHelper.h @@ -93,6 +93,7 @@ public: static void DrawToTargetWithPathMask(GrTexture* texture, GrDrawTarget* target, GrDrawState* drawState, + GrColor, const SkIRect& rect); private: diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp index 9a9cf328c8..157e81d108 100644 --- a/src/gpu/GrSoftwarePathRenderer.cpp +++ b/src/gpu/GrSoftwarePathRenderer.cpp @@ -78,6 +78,7 @@ bool get_path_and_clip_bounds(const GrDrawTarget* target, //////////////////////////////////////////////////////////////////////////////// void draw_around_inv_path(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkIRect& devClipBounds, const SkIRect& devPathBounds) { GrDrawState::AutoViewMatrixRestore avmr; @@ -88,22 +89,22 @@ void draw_around_inv_path(GrDrawTarget* target, if (devClipBounds.fTop < devPathBounds.fTop) { rect.iset(devClipBounds.fLeft, devClipBounds.fTop, devClipBounds.fRight, devPathBounds.fTop); - target->drawSimpleRect(drawState, rect); + target->drawSimpleRect(drawState, color, rect); } if (devClipBounds.fLeft < devPathBounds.fLeft) { rect.iset(devClipBounds.fLeft, devPathBounds.fTop, devPathBounds.fLeft, devPathBounds.fBottom); - target->drawSimpleRect(drawState, rect); + target->drawSimpleRect(drawState, color, rect); } if (devClipBounds.fRight > devPathBounds.fRight) { rect.iset(devPathBounds.fRight, devPathBounds.fTop, devClipBounds.fRight, devPathBounds.fBottom); - target->drawSimpleRect(drawState, rect); + target->drawSimpleRect(drawState, color, rect); } if (devClipBounds.fBottom > devPathBounds.fBottom) { rect.iset(devClipBounds.fLeft, devPathBounds.fBottom, devClipBounds.fRight, devClipBounds.fBottom); - target->drawSimpleRect(drawState, rect); + target->drawSimpleRect(drawState, color, rect); } } @@ -113,6 +114,7 @@ void draw_around_inv_path(GrDrawTarget* target, // return true on success; false on failure bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, bool antiAlias) { @@ -127,7 +129,7 @@ bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target, if (!get_path_and_clip_bounds(target, drawState, path, vm, &devPathBounds, &devClipBounds)) { if (path.isInverseFillType()) { - draw_around_inv_path(target, drawState, devClipBounds, devPathBounds); + draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds); } return true; } @@ -141,10 +143,10 @@ bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target, } GrDrawState copy = *drawState; - GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, ©, devPathBounds); + GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, ©, color, devPathBounds); if (path.isInverseFillType()) { - draw_around_inv_path(target, drawState, devClipBounds, devPathBounds); + draw_around_inv_path(target, drawState, color, devClipBounds, devPathBounds); } return true; diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h index 620e00b993..226cb35e79 100644 --- a/src/gpu/GrSoftwarePathRenderer.h +++ b/src/gpu/GrSoftwarePathRenderer.h @@ -36,6 +36,7 @@ protected: virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp index 022ed949f5..e7c4fc8899 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.cpp +++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp @@ -91,6 +91,7 @@ void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target, bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target, GrDrawState* drawState, + GrColor color, const SkPath& path, const SkStrokeRec& stroke, bool antiAlias) { @@ -133,7 +134,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target, } else { avmr.setIdentity(drawState); } - target->drawSimpleRect(drawState, bounds); + target->drawSimpleRect(drawState, color, bounds); } else { GR_STATIC_CONST_SAME_STENCIL(kStencilPass, kZero_StencilOp, @@ -144,7 +145,7 @@ bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target, 0xffff); drawState->setStencil(kStencilPass); - target->drawPath(drawState, p, convert_skpath_filltype(path.getFillType())); + target->drawPath(drawState, color, p, convert_skpath_filltype(path.getFillType())); } drawState->stencil()->setDisabled(); diff --git a/src/gpu/GrStencilAndCoverPathRenderer.h b/src/gpu/GrStencilAndCoverPathRenderer.h index dacdcd0695..be04c4a6fd 100644 --- a/src/gpu/GrStencilAndCoverPathRenderer.h +++ b/src/gpu/GrStencilAndCoverPathRenderer.h @@ -39,6 +39,7 @@ protected: virtual bool onDrawPath(GrDrawTarget*, GrDrawState*, + GrColor, const SkPath&, const SkStrokeRec&, bool antiAlias) SK_OVERRIDE; diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp index a8653fe3dc..bf1e58dae8 100644 --- a/src/gpu/GrStencilAndCoverTextContext.cpp +++ b/src/gpu/GrStencilAndCoverTextContext.cpp @@ -399,7 +399,7 @@ static const SkScalar* get_xy_scalar_array(const SkPoint* pointArray) { void GrStencilAndCoverTextContext::flush() { if (fQueuedGlyphCount > 0) { - fDrawTarget->drawPaths(&fDrawState, fGlyphs, + fDrawTarget->drawPaths(&fDrawState, fPaint.getColor(), fGlyphs, fGlyphIndices, GrPathRange::kU16_PathIndexType, get_xy_scalar_array(fGlyphPositions), GrPathRendering::kTranslate_PathTransformType, diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp index 5abd29324d..6ad1537f62 100644 --- a/src/gpu/effects/GrBezierEffect.cpp +++ b/src/gpu/effects/GrBezierEffect.cpp @@ -139,8 +139,8 @@ GrGLGeometryProcessor* GrConicEffect::createGLInstance(const GrBatchTracker& bt) return SkNEW_ARGS(GrGLConicEffect, (*this, bt)); } -GrConicEffect::GrConicEffect(GrPrimitiveEdgeType edgeType) - : fEdgeType(edgeType) { +GrConicEffect::GrConicEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType) + : INHERITED(color, coverage), fEdgeType(edgeType) { this->initClassID<GrConicEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInConicCoeffs = &this->addVertexAttrib(GrAttribute("inConicCoeffs", @@ -164,7 +164,7 @@ GrGeometryProcessor* GrConicEffect::TestCreate(SkRandom* random, do { GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( random->nextULessThan(kGrProcessorEdgeTypeCnt)); - gp = GrConicEffect::Create(edgeType, caps); + gp = GrConicEffect::Create(GrRandomColor(random), edgeType, caps); } while (NULL == gp); return gp; } @@ -286,8 +286,8 @@ GrGLGeometryProcessor* GrQuadEffect::createGLInstance(const GrBatchTracker& bt) return SkNEW_ARGS(GrGLQuadEffect, (*this, bt)); } -GrQuadEffect::GrQuadEffect(GrPrimitiveEdgeType edgeType) - : fEdgeType(edgeType) { +GrQuadEffect::GrQuadEffect(GrColor color, uint8_t coverage, GrPrimitiveEdgeType edgeType) + : INHERITED(color, coverage), fEdgeType(edgeType) { this->initClassID<GrQuadEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInHairQuadEdge = &this->addVertexAttrib(GrAttribute("inHairQuadEdge", @@ -311,7 +311,7 @@ GrGeometryProcessor* GrQuadEffect::TestCreate(SkRandom* random, do { GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( random->nextULessThan(kGrProcessorEdgeTypeCnt)); - gp = GrQuadEffect::Create(edgeType, caps); + gp = GrQuadEffect::Create(GrRandomColor(random), edgeType, caps); } while (NULL == gp); return gp; } @@ -474,8 +474,8 @@ GrGLGeometryProcessor* GrCubicEffect::createGLInstance(const GrBatchTracker& bt) return SkNEW_ARGS(GrGLCubicEffect, (*this, bt)); } -GrCubicEffect::GrCubicEffect(GrPrimitiveEdgeType edgeType) - : fEdgeType(edgeType) { +GrCubicEffect::GrCubicEffect(GrColor color, GrPrimitiveEdgeType edgeType) + : INHERITED(color), fEdgeType(edgeType) { this->initClassID<GrCubicEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInCubicCoeffs = &this->addVertexAttrib(GrAttribute("inCubicCoeffs", @@ -499,7 +499,7 @@ GrGeometryProcessor* GrCubicEffect::TestCreate(SkRandom* random, do { GrPrimitiveEdgeType edgeType = static_cast<GrPrimitiveEdgeType>( random->nextULessThan(kGrProcessorEdgeTypeCnt)); - gp = GrCubicEffect::Create(edgeType, caps); + gp = GrCubicEffect::Create(GrRandomColor(random), edgeType, caps); } while (NULL == gp); return gp; } diff --git a/src/gpu/effects/GrBezierEffect.h b/src/gpu/effects/GrBezierEffect.h index dfab3a9d9b..a9cbeb0dcb 100644 --- a/src/gpu/effects/GrBezierEffect.h +++ b/src/gpu/effects/GrBezierEffect.h @@ -58,21 +58,24 @@ class GrGLConicEffect; class GrConicEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType, - const GrDrawTargetCaps& caps) { + static GrGeometryProcessor* Create(GrColor color, + const GrPrimitiveEdgeType edgeType, + const GrDrawTargetCaps& caps, + uint8_t coverage = 0xff) { switch (edgeType) { case kFillAA_GrProcessorEdgeType: if (!caps.shaderDerivativeSupport()) { return NULL; } - return SkNEW_ARGS(GrConicEffect, (kFillAA_GrProcessorEdgeType)); + return SkNEW_ARGS(GrConicEffect, (color, coverage, kFillAA_GrProcessorEdgeType)); case kHairlineAA_GrProcessorEdgeType: if (!caps.shaderDerivativeSupport()) { return NULL; } - return SkNEW_ARGS(GrConicEffect, (kHairlineAA_GrProcessorEdgeType)); + return SkNEW_ARGS(GrConicEffect, (color, coverage, + kHairlineAA_GrProcessorEdgeType)); case kFillBW_GrProcessorEdgeType: - return SkNEW_ARGS(GrConicEffect, (kFillBW_GrProcessorEdgeType));; + return SkNEW_ARGS(GrConicEffect, (color, coverage, kFillBW_GrProcessorEdgeType));; default: return NULL; } @@ -95,7 +98,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrConicEffect(GrPrimitiveEdgeType); + GrConicEffect(GrColor, uint8_t coverage, GrPrimitiveEdgeType); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; @@ -125,21 +128,23 @@ class GrGLQuadEffect; class GrQuadEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType, - const GrDrawTargetCaps& caps) { + static GrGeometryProcessor* Create(GrColor color, + const GrPrimitiveEdgeType edgeType, + const GrDrawTargetCaps& caps, + uint8_t coverage = 0xff) { switch (edgeType) { case kFillAA_GrProcessorEdgeType: if (!caps.shaderDerivativeSupport()) { return NULL; } - return SkNEW_ARGS(GrQuadEffect, (kFillAA_GrProcessorEdgeType)); + return SkNEW_ARGS(GrQuadEffect, (color, coverage, kFillAA_GrProcessorEdgeType)); case kHairlineAA_GrProcessorEdgeType: if (!caps.shaderDerivativeSupport()) { return NULL; } - return SkNEW_ARGS(GrQuadEffect, (kHairlineAA_GrProcessorEdgeType)); + return SkNEW_ARGS(GrQuadEffect, (color, coverage, kHairlineAA_GrProcessorEdgeType)); case kFillBW_GrProcessorEdgeType: - return SkNEW_ARGS(GrQuadEffect, (kFillBW_GrProcessorEdgeType)); + return SkNEW_ARGS(GrQuadEffect, (color, coverage, kFillBW_GrProcessorEdgeType)); default: return NULL; } @@ -162,7 +167,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrQuadEffect(GrPrimitiveEdgeType); + GrQuadEffect(GrColor, uint8_t coverage, GrPrimitiveEdgeType); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; @@ -194,21 +199,22 @@ class GrGLCubicEffect; class GrCubicEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(const GrPrimitiveEdgeType edgeType, + static GrGeometryProcessor* Create(GrColor color, + const GrPrimitiveEdgeType edgeType, const GrDrawTargetCaps& caps) { switch (edgeType) { case kFillAA_GrProcessorEdgeType: if (!caps.shaderDerivativeSupport()) { return NULL; } - return SkNEW_ARGS(GrCubicEffect, (kFillAA_GrProcessorEdgeType)); + return SkNEW_ARGS(GrCubicEffect, (color, kFillAA_GrProcessorEdgeType)); case kHairlineAA_GrProcessorEdgeType: if (!caps.shaderDerivativeSupport()) { return NULL; } - return SkNEW_ARGS(GrCubicEffect, (kHairlineAA_GrProcessorEdgeType)); + return SkNEW_ARGS(GrCubicEffect, (color, kHairlineAA_GrProcessorEdgeType)); case kFillBW_GrProcessorEdgeType: - return SkNEW_ARGS(GrCubicEffect, (kFillBW_GrProcessorEdgeType)); + return SkNEW_ARGS(GrCubicEffect, (color, kFillBW_GrProcessorEdgeType)); default: return NULL; } @@ -231,7 +237,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrCubicEffect(GrPrimitiveEdgeType); + GrCubicEffect(GrColor, GrPrimitiveEdgeType); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; diff --git a/src/gpu/effects/GrBitmapTextGeoProc.cpp b/src/gpu/effects/GrBitmapTextGeoProc.cpp index 6eaaf306cb..1578fd8fe4 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.cpp +++ b/src/gpu/effects/GrBitmapTextGeoProc.cpp @@ -65,9 +65,9 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrTexture* texture, const GrTextureParams& params, - bool useColorAttrib) - : fTextureAccess(texture, params), fInColor(NULL) { +GrBitmapTextGeoProc::GrBitmapTextGeoProc(GrColor color, GrTexture* texture, + const GrTextureParams& params, bool useColorAttrib) + : INHERITED(color), fTextureAccess(texture, params), fInColor(NULL) { this->initClassID<GrBitmapTextGeoProc>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); if (useColorAttrib) { @@ -128,5 +128,6 @@ GrGeometryProcessor* GrBitmapTextGeoProc::TestCreate(SkRandom* random, GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode); - return GrBitmapTextGeoProc::Create(textures[texIdx], params, random->nextBool()); + return GrBitmapTextGeoProc::Create(GrRandomColor(random), textures[texIdx], params, + random->nextBool()); } diff --git a/src/gpu/effects/GrBitmapTextGeoProc.h b/src/gpu/effects/GrBitmapTextGeoProc.h index ecbf4f9470..ce235ae154 100644 --- a/src/gpu/effects/GrBitmapTextGeoProc.h +++ b/src/gpu/effects/GrBitmapTextGeoProc.h @@ -21,9 +21,9 @@ class GrInvariantOutput; */ class GrBitmapTextGeoProc : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& p, + static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& p, bool useColorAttrib) { - return SkNEW_ARGS(GrBitmapTextGeoProc, (tex, p, useColorAttrib)); + return SkNEW_ARGS(GrBitmapTextGeoProc, (color, tex, p, useColorAttrib)); } virtual ~GrBitmapTextGeoProc() {} @@ -41,7 +41,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrBitmapTextGeoProc(GrTexture* texture, const GrTextureParams& params, bool useColorAttrib); + GrBitmapTextGeoProc(GrColor, GrTexture* texture, const GrTextureParams& params, bool useColorAttrib); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 53485f6ed7..b59b2a6e5c 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -165,7 +165,7 @@ static void setup_dashed_rect_pos(const SkRect& rect, int idx, const SkMatrix& m } bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState* drawState, - const SkPoint pts[2], const GrPaint& paint, + GrColor color, const SkPoint pts[2], const GrPaint& paint, const GrStrokeInfo& strokeInfo, const SkMatrix& vm) { if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, vm)) { @@ -347,10 +347,10 @@ bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState bool isRoundCap = SkPaint::kRound_Cap == cap; GrDashingEffect::DashCap capType = isRoundCap ? GrDashingEffect::kRound_DashCap : GrDashingEffect::kNonRound_DashCap; - gp = GrDashingEffect::Create(edgeType, devInfo, strokeWidth, capType); + gp = GrDashingEffect::Create(color, edgeType, devInfo, strokeWidth, capType); } else { // Set up the vertex data for the line and start/end dashes - gp = GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType); + gp = GrDefaultGeoProcFactory::Create(color, GrDefaultGeoProcFactory::kPosition_GPType); } drawState->setGeometryProcessor(gp)->unref(); @@ -456,7 +456,8 @@ class DashingCircleEffect : public GrGeometryProcessor { public: typedef SkPathEffect::DashInfo DashInfo; - static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, + static GrGeometryProcessor* Create(GrColor, + GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar radius); @@ -483,7 +484,8 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker&) const SK_OVERRIDE; private: - DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar radius); + DashingCircleEffect(GrColor, GrPrimitiveEdgeType edgeType, const DashInfo& info, + SkScalar radius); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; @@ -599,13 +601,15 @@ void GLDashingCircleEffect::GenKey(const GrGeometryProcessor& processor, ////////////////////////////////////////////////////////////////////////////// -GrGeometryProcessor* DashingCircleEffect::Create(GrPrimitiveEdgeType edgeType, const DashInfo& info, +GrGeometryProcessor* DashingCircleEffect::Create(GrColor color, + GrPrimitiveEdgeType edgeType, + const DashInfo& info, SkScalar radius) { if (info.fCount != 2 || info.fIntervals[0] != 0) { return NULL; } - return SkNEW_ARGS(DashingCircleEffect, (edgeType, info, radius)); + return SkNEW_ARGS(DashingCircleEffect, (color, edgeType, info, radius)); } DashingCircleEffect::~DashingCircleEffect() {} @@ -624,9 +628,11 @@ GrGLGeometryProcessor* DashingCircleEffect::createGLInstance(const GrBatchTracke return SkNEW_ARGS(GLDashingCircleEffect, (*this, bt)); } -DashingCircleEffect::DashingCircleEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, +DashingCircleEffect::DashingCircleEffect(GrColor color, + GrPrimitiveEdgeType edgeType, + const DashInfo& info, SkScalar radius) - : fEdgeType(edgeType) { + : INHERITED(color), fEdgeType(edgeType) { this->initClassID<DashingCircleEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType)); @@ -662,7 +668,7 @@ GrGeometryProcessor* DashingCircleEffect::TestCreate(SkRandom* random, info.fIntervals[1] = random->nextRangeScalar(0, 10.f); info.fPhase = random->nextRangeScalar(0, info.fIntervals[1]); - return DashingCircleEffect::Create(edgeType, info, strokeWidth); + return DashingCircleEffect::Create(GrRandomColor(random), edgeType, info, strokeWidth); } ////////////////////////////////////////////////////////////////////////////// @@ -682,7 +688,8 @@ class DashingLineEffect : public GrGeometryProcessor { public: typedef SkPathEffect::DashInfo DashInfo; - static GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, + static GrGeometryProcessor* Create(GrColor, + GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth); @@ -707,7 +714,8 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth); + DashingLineEffect(GrColor, GrPrimitiveEdgeType edgeType, const DashInfo& info, + SkScalar strokeWidth); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; @@ -836,14 +844,15 @@ void GLDashingLineEffect::GenKey(const GrGeometryProcessor& processor, ////////////////////////////////////////////////////////////////////////////// -GrGeometryProcessor* DashingLineEffect::Create(GrPrimitiveEdgeType edgeType, +GrGeometryProcessor* DashingLineEffect::Create(GrColor color, + GrPrimitiveEdgeType edgeType, const DashInfo& info, SkScalar strokeWidth) { if (info.fCount != 2) { return NULL; } - return SkNEW_ARGS(DashingLineEffect, (edgeType, info, strokeWidth)); + return SkNEW_ARGS(DashingLineEffect, (color, edgeType, info, strokeWidth)); } DashingLineEffect::~DashingLineEffect() {} @@ -862,9 +871,11 @@ GrGLGeometryProcessor* DashingLineEffect::createGLInstance(const GrBatchTracker& return SkNEW_ARGS(GLDashingLineEffect, (*this, bt)); } -DashingLineEffect::DashingLineEffect(GrPrimitiveEdgeType edgeType, const DashInfo& info, +DashingLineEffect::DashingLineEffect(GrColor color, + GrPrimitiveEdgeType edgeType, + const DashInfo& info, SkScalar strokeWidth) - : fEdgeType(edgeType) { + : INHERITED(color), fEdgeType(edgeType) { this->initClassID<DashingLineEffect>(); fInPosition = &this->addVertexAttrib(GrAttribute("inPosition", kVec2f_GrVertexAttribType)); fInCoord = &this->addVertexAttrib(GrAttribute("inCoord", kVec2f_GrVertexAttribType)); @@ -900,20 +911,21 @@ GrGeometryProcessor* DashingLineEffect::TestCreate(SkRandom* random, info.fIntervals[1] = random->nextRangeScalar(0, 10.f); info.fPhase = random->nextRangeScalar(0, info.fIntervals[0] + info.fIntervals[1]); - return DashingLineEffect::Create(edgeType, info, strokeWidth); + return DashingLineEffect::Create(GrRandomColor(random), edgeType, info, strokeWidth); } ////////////////////////////////////////////////////////////////////////////// -GrGeometryProcessor* GrDashingEffect::Create(GrPrimitiveEdgeType edgeType, +GrGeometryProcessor* GrDashingEffect::Create(GrColor color, + GrPrimitiveEdgeType edgeType, const SkPathEffect::DashInfo& info, SkScalar strokeWidth, GrDashingEffect::DashCap cap) { switch (cap) { case GrDashingEffect::kRound_DashCap: - return DashingCircleEffect::Create(edgeType, info, SkScalarHalf(strokeWidth)); + return DashingCircleEffect::Create(color, edgeType, info, SkScalarHalf(strokeWidth)); case GrDashingEffect::kNonRound_DashCap: - return DashingLineEffect::Create(edgeType, info, strokeWidth); + return DashingLineEffect::Create(color, edgeType, info, strokeWidth); default: SkFAIL("Unexpected dashed cap."); } diff --git a/src/gpu/effects/GrDashingEffect.h b/src/gpu/effects/GrDashingEffect.h index 14df1ae7d5..492c6905fc 100644 --- a/src/gpu/effects/GrDashingEffect.h +++ b/src/gpu/effects/GrDashingEffect.h @@ -9,6 +9,7 @@ #ifndef GrDashingEffect_DEFINED #define GrDashingEffect_DEFINED +#include "GrColor.h" #include "GrTypesPriv.h" #include "SkPathEffect.h" @@ -23,7 +24,7 @@ class GrGLDashingEffect; class SkPath; namespace GrDashingEffect { - bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, const SkPoint pts[2], + bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, GrColor, const SkPoint pts[2], const GrPaint& paint, const GrStrokeInfo& strokeInfo, const SkMatrix& vm); @@ -38,7 +39,8 @@ namespace GrDashingEffect { * Bounding geometry is rendered and the effect computes coverage based on the fragment's * position relative to the dashed line. */ - GrGeometryProcessor* Create(GrPrimitiveEdgeType edgeType, + GrGeometryProcessor* Create(GrColor, + GrPrimitiveEdgeType edgeType, const SkPathEffect::DashInfo& info, SkScalar strokeWidth, DashCap cap); diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp index eff2ee5517..f408d2dfec 100755 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.cpp +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.cpp @@ -165,7 +165,8 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, +GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrColor color, + GrTexture* texture, const GrTextureParams& params, #ifdef SK_GAMMA_APPLY_TO_A8 GrTexture* gamma, @@ -173,7 +174,8 @@ GrDistanceFieldTextureEffect::GrDistanceFieldTextureEffect(GrTexture* texture, float luminance, #endif uint32_t flags) - : fTextureAccess(texture, params) + : INHERITED(color) + , fTextureAccess(texture, params) #ifdef SK_GAMMA_APPLY_TO_A8 , fGammaTextureAccess(gamma, gammaParams) , fLuminance(luminance) @@ -249,7 +251,7 @@ GrGeometryProcessor* GrDistanceFieldTextureEffect::TestCreate(SkRandom* random, GrTextureParams::kNone_FilterMode); #endif - return GrDistanceFieldTextureEffect::Create(textures[texIdx], params, + return GrDistanceFieldTextureEffect::Create(GrRandomColor(random), textures[texIdx], params, #ifdef SK_GAMMA_APPLY_TO_A8 textures[texIdx2], params2, random->nextF(), @@ -378,10 +380,13 @@ private: /////////////////////////////////////////////////////////////////////////////// -GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect(GrTexture* texture, - const GrTextureParams& params, - uint32_t flags) - : fTextureAccess(texture, params) +GrDistanceFieldNoGammaTextureEffect::GrDistanceFieldNoGammaTextureEffect( + GrColor color, + GrTexture* texture, + const GrTextureParams& params, + uint32_t flags) + : INHERITED(color) + , fTextureAccess(texture, params) , fFlags(flags & kNonLCD_DistanceFieldEffectMask) , fInColor(NULL) { SkASSERT(!(flags & ~kNonLCD_DistanceFieldEffectMask)); @@ -439,7 +444,8 @@ GrGeometryProcessor* GrDistanceFieldNoGammaTextureEffect::TestCreate(SkRandom* r GrTextureParams params(tileModes, random->nextBool() ? GrTextureParams::kBilerp_FilterMode : GrTextureParams::kNone_FilterMode); - return GrDistanceFieldNoGammaTextureEffect::Create(textures[texIdx], params, + return GrDistanceFieldNoGammaTextureEffect::Create(GrRandomColor(random), textures[texIdx], + params, random->nextBool() ? kSimilarity_DistanceFieldEffectFlag : 0); } @@ -634,11 +640,13 @@ private: /////////////////////////////////////////////////////////////////////////////// GrDistanceFieldLCDTextureEffect::GrDistanceFieldLCDTextureEffect( + GrColor color, GrTexture* texture, const GrTextureParams& params, GrTexture* gamma, const GrTextureParams& gParams, SkColor textColor, uint32_t flags) - : fTextureAccess(texture, params) + : INHERITED(color) + , fTextureAccess(texture, params) , fGammaTextureAccess(gamma, gParams) , fTextColor(textColor) , fFlags(flags & kLCD_DistanceFieldEffectMask){ @@ -705,7 +713,7 @@ GrGeometryProcessor* GrDistanceFieldLCDTextureEffect::TestCreate(SkRandom* rando uint32_t flags = kUseLCD_DistanceFieldEffectFlag; flags |= random->nextBool() ? kUniformScale_DistanceFieldEffectMask : 0; flags |= random->nextBool() ? kBGR_DistanceFieldEffectFlag : 0; - return GrDistanceFieldLCDTextureEffect::Create(textures[texIdx], params, + return GrDistanceFieldLCDTextureEffect::Create(GrRandomColor(random), textures[texIdx], params, textures[texIdx2], params2, textColor, flags); diff --git a/src/gpu/effects/GrDistanceFieldTextureEffect.h b/src/gpu/effects/GrDistanceFieldTextureEffect.h index 1dfa1b4711..f0f7e3b8c9 100644 --- a/src/gpu/effects/GrDistanceFieldTextureEffect.h +++ b/src/gpu/effects/GrDistanceFieldTextureEffect.h @@ -47,16 +47,16 @@ enum GrDistanceFieldEffectFlags { class GrDistanceFieldTextureEffect : public GrGeometryProcessor { public: #ifdef SK_GAMMA_APPLY_TO_A8 - static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params, + static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params, GrTexture* gamma, const GrTextureParams& gammaParams, float lum, uint32_t flags) { - return SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params, gamma, gammaParams, lum, + return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, gamma, gammaParams, lum, flags)); } #else - static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params, + static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params, uint32_t flags) { - return SkNEW_ARGS(GrDistanceFieldTextureEffect, (tex, params, flags)); + return SkNEW_ARGS(GrDistanceFieldTextureEffect, (color, tex, params, flags)); } #endif @@ -79,7 +79,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrDistanceFieldTextureEffect(GrTexture* texture, const GrTextureParams& params, + GrDistanceFieldTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params, #ifdef SK_GAMMA_APPLY_TO_A8 GrTexture* gamma, const GrTextureParams& gammaParams, float lum, #endif @@ -113,9 +113,9 @@ private: */ class GrDistanceFieldNoGammaTextureEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params, + static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params, uint32_t flags) { - return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (tex, params, flags)); + return SkNEW_ARGS(GrDistanceFieldNoGammaTextureEffect, (color, tex, params, flags)); } virtual ~GrDistanceFieldNoGammaTextureEffect() {} @@ -134,7 +134,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrDistanceFieldNoGammaTextureEffect(GrTexture* texture, const GrTextureParams& params, + GrDistanceFieldNoGammaTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params, uint32_t flags); virtual bool onIsEqual(const GrGeometryProcessor& other) const SK_OVERRIDE; @@ -160,11 +160,11 @@ private: */ class GrDistanceFieldLCDTextureEffect : public GrGeometryProcessor { public: - static GrGeometryProcessor* Create(GrTexture* tex, const GrTextureParams& params, + static GrGeometryProcessor* Create(GrColor color, GrTexture* tex, const GrTextureParams& params, GrTexture* gamma, const GrTextureParams& gammaParams, SkColor textColor, uint32_t flags) { return SkNEW_ARGS(GrDistanceFieldLCDTextureEffect, - (tex, params, gamma, gammaParams, textColor, flags)); + (color, tex, params, gamma, gammaParams, textColor, flags)); } virtual ~GrDistanceFieldLCDTextureEffect() {} @@ -183,7 +183,7 @@ public: virtual GrGLGeometryProcessor* createGLInstance(const GrBatchTracker& bt) const SK_OVERRIDE; private: - GrDistanceFieldLCDTextureEffect(GrTexture* texture, const GrTextureParams& params, + GrDistanceFieldLCDTextureEffect(GrColor, GrTexture* texture, const GrTextureParams& params, GrTexture* gamma, const GrTextureParams& gammaParams, SkColor textColor, uint32_t flags); |