| Index: src/gpu/GrClipMaskManager.cpp
|
| diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
|
| index 5af6fb69ff508d86f600f37b10b6c66ac0dfb4fe..d663c7939a1049decabce29306aa5267350afff1 100644
|
| --- a/src/gpu/GrClipMaskManager.cpp
|
| +++ b/src/gpu/GrClipMaskManager.cpp
|
| @@ -330,39 +330,15 @@ bool GrClipMaskManager::setupClipping(GrDrawState* drawState,
|
|
|
| namespace {
|
| ////////////////////////////////////////////////////////////////////////////////
|
| -// set up the OpenGL blend function to perform the specified
|
| -// boolean operation for alpha clip mask creation
|
| -void setup_boolean_blendcoeffs(SkRegion::Op op, GrDrawState* drawState) {
|
| - // TODO: once we have a coverageDrawing XP this will all use that instead of PD
|
| - switch (op) {
|
| - case SkRegion::kReplace_Op:
|
| - drawState->setPorterDuffXPFactory(kOne_GrBlendCoeff, kZero_GrBlendCoeff);
|
| - break;
|
| - case SkRegion::kIntersect_Op:
|
| - drawState->setPorterDuffXPFactory(kDC_GrBlendCoeff, kZero_GrBlendCoeff);
|
| - break;
|
| - case SkRegion::kUnion_Op:
|
| - drawState->setPorterDuffXPFactory(kOne_GrBlendCoeff, kISC_GrBlendCoeff);
|
| - break;
|
| - case SkRegion::kXOR_Op:
|
| - drawState->setPorterDuffXPFactory(kIDC_GrBlendCoeff, kISC_GrBlendCoeff);
|
| - break;
|
| - case SkRegion::kDifference_Op:
|
| - drawState->setPorterDuffXPFactory(kZero_GrBlendCoeff, kISC_GrBlendCoeff);
|
| - break;
|
| - case SkRegion::kReverseDifference_Op:
|
| - drawState->setPorterDuffXPFactory(kIDC_GrBlendCoeff, kZero_GrBlendCoeff);
|
| - break;
|
| - default:
|
| - SkASSERT(false);
|
| - break;
|
| - }
|
| +// Set a coverage drawing XPF on the drawState for the given op and invertCoverage mode
|
| +void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState* drawState) {
|
| + SkASSERT(op <= SkRegion::kLastOp);
|
| + drawState->setCoverageSetOpXPFactory(op, invertCoverage);
|
| }
|
| }
|
|
|
| ////////////////////////////////////////////////////////////////////////////////
|
| bool GrClipMaskManager::drawElement(GrDrawState* drawState,
|
| - GrColor color,
|
| GrTexture* target,
|
| const SkClipStack::Element* element,
|
| GrPathRenderer* pr) {
|
| @@ -370,6 +346,10 @@ bool GrClipMaskManager::drawElement(GrDrawState* drawState,
|
|
|
| drawState->setRenderTarget(target->asRenderTarget());
|
|
|
| + // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
|
| + // which ignores color.
|
| + GrColor color = GrColor_WHITE;
|
| +
|
| // TODO: Draw rrects directly here.
|
| switch (element->getType()) {
|
| case Element::kEmpty_Type:
|
| @@ -451,17 +431,19 @@ void GrClipMaskManager::mergeMask(GrDrawState* drawState,
|
|
|
| drawState->setRenderTarget(dstMask->asRenderTarget());
|
|
|
| - setup_boolean_blendcoeffs(op, drawState);
|
| + // We want to invert the coverage here
|
| + set_coverage_drawing_xpf(op, false, drawState);
|
|
|
| SkMatrix sampleM;
|
| sampleM.setIDiv(srcMask->width(), srcMask->height());
|
|
|
| - drawState->addColorProcessor(
|
| + drawState->addCoverageProcessor(
|
| GrTextureDomainEffect::Create(srcMask,
|
| sampleM,
|
| GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
|
| GrTextureDomain::kDecal_Mode,
|
| GrTextureParams::kNone_FilterMode))->unref();
|
| + // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound));
|
| }
|
|
|
| @@ -567,9 +549,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| bool invert = element->isInverseFilled();
|
| if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
|
| GrDrawState drawState(translate);
|
| - // We're drawing a coverage mask and want coverage to be run through the blend function.
|
| - drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
|
| - GrDrawState::kClip_StateBit);
|
| + drawState.enableState(GrDrawState::kClip_StateBit);
|
|
|
| GrPathRenderer* pr = NULL;
|
| bool useTemp = !this->canStencilAndDrawElement(&drawState, result, &pr, element);
|
| @@ -603,7 +583,7 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| invert ? 0xffffffff : 0x00000000,
|
| true,
|
| dst->asRenderTarget());
|
| - setup_boolean_blendcoeffs(SkRegion::kReplace_Op, &drawState);
|
| + set_coverage_drawing_xpf(SkRegion::kReplace_Op, invert, &drawState);
|
| } else {
|
| // draw directly into the result with the stencil set to make the pixels affected
|
| // by the clip shape be non-zero.
|
| @@ -616,29 +596,29 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| 0xffff,
|
| 0xffff);
|
| drawState.setStencil(kStencilInElement);
|
| - setup_boolean_blendcoeffs(op, &drawState);
|
| + set_coverage_drawing_xpf(op, invert, &drawState);
|
| }
|
|
|
| - // We have to backup the drawstate because the drawElement call may call into
|
| - // renderers which consume it.
|
| - GrDrawState backupDrawState(drawState);
|
| -
|
| - if (!this->drawElement(&drawState, invert ? GrColor_TRANS_BLACK :
|
| - GrColor_WHITE, dst, element, pr)) {
|
| + if (!this->drawElement(&drawState, dst, element, pr)) {
|
| fAACache.reset();
|
| return NULL;
|
| }
|
|
|
| + GrDrawState backgroundDrawState(translate);
|
| + backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
|
| + backgroundDrawState.setRenderTarget(result->asRenderTarget());
|
| +
|
| if (useTemp) {
|
| // Now draw into the accumulator using the real operation and the temp buffer as a
|
| // texture
|
| - this->mergeMask(&backupDrawState,
|
| + this->mergeMask(&backgroundDrawState,
|
| result,
|
| temp,
|
| op,
|
| maskSpaceIBounds,
|
| maskSpaceElementIBounds);
|
| } else {
|
| + set_coverage_drawing_xpf(op, !invert, &backgroundDrawState);
|
| // Draw to the exterior pixels (those with a zero stencil value).
|
| GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
|
| kZero_StencilOp,
|
| @@ -647,19 +627,18 @@ GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
|
| 0xffff,
|
| 0x0000,
|
| 0xffff);
|
| - backupDrawState.setStencil(kDrawOutsideElement);
|
| - fClipTarget->drawSimpleRect(&backupDrawState,
|
| - invert ? GrColor_WHITE : GrColor_TRANS_BLACK,
|
| - clipSpaceIBounds);
|
| + backgroundDrawState.setStencil(kDrawOutsideElement);
|
| + // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| + fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds);
|
| }
|
| } else {
|
| GrDrawState drawState(translate);
|
| - drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
|
| - GrDrawState::kClip_StateBit);
|
| + drawState.enableState(GrDrawState::kClip_StateBit);
|
|
|
| // all the remaining ops can just be directly draw into the accumulation buffer
|
| - setup_boolean_blendcoeffs(op, &drawState);
|
| - this->drawElement(&drawState, GrColor_WHITE, result, element);
|
| + set_coverage_drawing_xpf(op, false, &drawState);
|
| + // The color passed in here does not matter since the coverageSetOpXP won't read it.
|
| + this->drawElement(&drawState, result, element);
|
| }
|
| }
|
|
|
|
|