Chromium Code Reviews| Index: src/gpu/GrClipMaskManager.cpp |
| diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp |
| index 5af6fb69ff508d86f600f37b10b6c66ac0dfb4fe..5371d19407178665eee58e9fee80d52b302fa67c 100644 |
| --- a/src/gpu/GrClipMaskManager.cpp |
| +++ b/src/gpu/GrClipMaskManager.cpp |
| @@ -330,33 +330,10 @@ 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); |
| } |
| } |
| @@ -451,7 +428,8 @@ void GrClipMaskManager::mergeMask(GrDrawState* drawState, |
| drawState->setRenderTarget(dstMask->asRenderTarget()); |
| - setup_boolean_blendcoeffs(op, drawState); |
| + // We want to invert the coverage here |
|
bsalomon
2014/12/16 17:35:56
we do??
egdaniel
2014/12/17 21:12:37
changed to false and changed to use coverageProces
|
| + set_coverage_drawing_xpf(op, true, drawState); |
| SkMatrix sampleM; |
| sampleM.setIDiv(srcMask->width(), srcMask->height()); |
| @@ -462,6 +440,7 @@ void GrClipMaskManager::mergeMask(GrDrawState* drawState, |
| 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 +546,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 +580,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 +593,33 @@ 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)) { |
| + // The color passed in here does not matter since the coverageSetOpXP won't read it. |
| + if (!this->drawElement(&drawState, GrColor_WHITE, dst, element, pr)) { |
|
bsalomon
2014/12/16 17:35:56
Can drawElement just not take a color then?
egdaniel
2014/12/17 21:12:37
Done.
|
| fAACache.reset(); |
| return NULL; |
| } |
| + // We have to make a new drawstate because the drawElement call may call into |
|
bsalomon
2014/12/16 17:35:56
I'm not sure this comment adds much value. A new d
egdaniel
2014/12/17 21:12:37
removed
|
| + // renderers which consume it. We also need to use a different coverage drawing xp which |
| + // inverts the coverage. |
| + 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,18 +628,17 @@ 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); |
| + 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, GrColor_WHITE, result, element); |
| } |
| } |