diff options
Diffstat (limited to 'src/gpu/GrClipMaskManager.cpp')
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 79 |
1 files changed, 29 insertions, 50 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 5af6fb69ff..d663c7939a 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); } } |