| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrClipMaskManager.h" | 9 #include "GrClipMaskManager.h" |
| 10 #include "GrAAConvexPathRenderer.h" | 10 #include "GrAAConvexPathRenderer.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "SkStrokeRec.h" | 22 #include "SkStrokeRec.h" |
| 23 #include "SkTLazy.h" | 23 #include "SkTLazy.h" |
| 24 | 24 |
| 25 #define GR_AA_CLIP 1 | 25 #define GR_AA_CLIP 1 |
| 26 | 26 |
| 27 typedef SkClipStack::Element Element; | 27 typedef SkClipStack::Element Element; |
| 28 | 28 |
| 29 using namespace GrReducedClip; | 29 using namespace GrReducedClip; |
| 30 | 30 |
| 31 //////////////////////////////////////////////////////////////////////////////// | 31 //////////////////////////////////////////////////////////////////////////////// |
| 32 namespace { | |
| 33 // set up the draw state to enable the aa clipping mask. Besides setting up the | 32 // set up the draw state to enable the aa clipping mask. Besides setting up the |
| 34 // stage matrix this also alters the vertex layout | 33 // stage matrix this also alters the vertex layout |
| 35 void setup_drawstate_aaclip(GrGpu* gpu, | 34 static void setup_drawstate_aaclip(GrGpu* gpu, |
| 36 GrTexture* result, | 35 GrTexture* result, |
| 37 const SkIRect &devBound) { | 36 const SkIRect &devBound) { |
| 38 GrDrawState* drawState = gpu->drawState(); | 37 GrDrawState* drawState = gpu->drawState(); |
| 39 SkASSERT(drawState); | 38 SkASSERT(drawState); |
| 40 | 39 |
| 41 SkMatrix mat; | 40 SkMatrix mat; |
| 42 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be | 41 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be |
| 43 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to | 42 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to |
| 44 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. | 43 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. |
| 45 mat.setIDiv(result->width(), result->height()); | 44 mat.setIDiv(result->width(), result->height()); |
| 46 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 45 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
| 47 SkIntToScalar(-devBound.fTop)); | 46 SkIntToScalar(-devBound.fTop)); |
| 48 mat.preConcat(drawState->getViewMatrix()); | 47 mat.preConcat(drawState->getViewMatrix()); |
| 49 | 48 |
| 50 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 49 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
| 51 // This could be a long-lived effect that is cached with the alpha-mask. | 50 // This could be a long-lived effect that is cached with the alpha-mask. |
| 52 drawState->addCoverageEffect( | 51 drawState->addCoverageEffect( |
| 53 GrTextureDomainEffect::Create(result, | 52 GrTextureDomainEffect::Create(result, |
| 54 mat, | 53 mat, |
| 55 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), | 54 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), |
| 56 GrTextureDomain::kDecal_Mode, | 55 GrTextureDomain::kDecal_Mode, |
| 57 GrTextureParams::kNone_FilterMode, | 56 GrTextureParams::kNone_FilterMode, |
| 58 kPosition_GrCoordSet))->unref(); | 57 kPosition_GrCoordSet))->unref(); |
| 59 } | 58 } |
| 60 | 59 |
| 61 bool path_needs_SW_renderer(GrContext* context, | 60 static bool path_needs_SW_renderer(GrContext* context, |
| 62 GrGpu* gpu, | 61 GrGpu* gpu, |
| 63 const SkPath& origPath, | 62 const SkPath& origPath, |
| 64 const SkStrokeRec& stroke, | 63 const SkStrokeRec& stroke, |
| 65 bool doAA) { | 64 bool doAA) { |
| 66 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer | |
| 67 SkTCopyOnFirstWrite<SkPath> path(origPath); | |
| 68 if (path->isInverseFillType()) { | |
| 69 path.writable()->toggleInverseFillType(); | |
| 70 } | |
| 71 // last (false) parameter disallows use of the SW path renderer | |
| 72 GrPathRendererChain::DrawType type = doAA ? | 65 GrPathRendererChain::DrawType type = doAA ? |
| 73 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 66 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
| 74 GrPathRendererChain::kColor_DrawType; | 67 GrPathRendererChain::kColor_DrawType; |
| 68 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer |
| 69 SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.get
FillType()); |
| 75 | 70 |
| 76 return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); | 71 // the 'false' parameter disallows use of the SW path renderer |
| 77 } | 72 GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke,
gpu, |
| 78 | 73 false, type, fill
Type)); |
| 74 return NULL == acp.renderer(); |
| 79 } | 75 } |
| 80 | 76 |
| 81 /* | 77 /* |
| 82 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 78 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
| 83 * will be used on any element. If so, it returns true to indicate that the | 79 * will be used on any element. If so, it returns true to indicate that the |
| 84 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 80 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
| 85 */ | 81 */ |
| 86 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { | 82 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { |
| 87 | 83 |
| 88 // TODO: generalize this function so that when | 84 // TODO: generalize this function so that when |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 break; | 258 break; |
| 263 default: | 259 default: |
| 264 SkASSERT(false); | 260 SkASSERT(false); |
| 265 break; | 261 break; |
| 266 } | 262 } |
| 267 } | 263 } |
| 268 | 264 |
| 269 } | 265 } |
| 270 | 266 |
| 271 //////////////////////////////////////////////////////////////////////////////// | 267 //////////////////////////////////////////////////////////////////////////////// |
| 272 bool GrClipMaskManager::drawElement(GrTexture* target, | 268 bool GrClipMaskManager::drawFilledPath(GrTexture* target, |
| 273 const SkClipStack::Element* element, | 269 GrPathRenderer* pathRenderer, |
| 274 GrPathRenderer* pr) { | 270 bool isAA) { |
| 275 GrDrawState* drawState = fGpu->drawState(); | 271 GrDrawState* drawState = fGpu->drawState(); |
| 276 | 272 |
| 277 drawState->setRenderTarget(target->asRenderTarget()); | 273 drawState->setRenderTarget(target->asRenderTarget()); |
| 274 |
| 275 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 276 pathRenderer->drawPath(stroke, fGpu, isAA); |
| 277 return true; |
| 278 } |
| 279 |
| 280 bool GrClipMaskManager::drawElement(GrTexture* target, |
| 281 const SkClipStack::Element* element) { |
| 282 GrDrawState* drawState = fGpu->drawState(); |
| 283 |
| 284 drawState->setRenderTarget(target->asRenderTarget()); |
| 278 | 285 |
| 279 switch (element->getType()) { | 286 switch (element->getType()) { |
| 280 case Element::kRect_Type: | 287 case Element::kRect_Type: |
| 281 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe
ct that covers the | 288 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe
ct that covers the |
| 282 // entire mask bounds and writes 0 outside the rect. | 289 // entire mask bounds and writes 0 outside the rect. |
| 283 if (element->isAA()) { | 290 if (element->isAA()) { |
| 284 getContext()->getAARectRenderer()->fillAARect(fGpu, | 291 getContext()->getAARectRenderer()->fillAARect(fGpu, |
| 285 fGpu, | 292 fGpu, |
| 286 element->getRect()
, | 293 element->getRect()
, |
| 287 SkMatrix::I(), | 294 SkMatrix::I(), |
| 288 element->getRect()
, | 295 element->getRect()
, |
| 289 false); | 296 false); |
| 290 } else { | 297 } else { |
| 291 fGpu->drawSimpleRect(element->getRect(), NULL); | 298 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 292 } | 299 } |
| 293 return true; | 300 return true; |
| 294 case Element::kPath_Type: { | 301 case Element::kPath_Type: { |
| 295 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); | |
| 296 if (path->isInverseFillType()) { | |
| 297 path.writable()->toggleInverseFillType(); | |
| 298 } | |
| 299 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 302 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 300 if (NULL == pr) { | 303 GrPathRendererChain::DrawType type; |
| 301 GrPathRendererChain::DrawType type; | 304 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawTy
pe : |
| 302 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : | 305 GrPathRendererChain::kColor_DrawType; |
| 303 GrPathRendererChain::kColor_DrawType; | 306 SkPath::FillType fillType = element->getPath().getFillType(); |
| 304 pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, fa
lse, type); | 307 GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRendere
r( |
| 305 } | 308 element->getPath(), |
| 306 if (NULL == pr) { | 309 stroke, fGpu, false, type, |
| 310 SkPath::ConvertToNonInverseFil
lType(fillType))); |
| 311 if (NULL == acp.renderer()) { |
| 307 return false; | 312 return false; |
| 308 } | 313 } |
| 309 pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); | 314 acp->drawPath(stroke, fGpu, element->isAA()); |
| 310 break; | 315 break; |
| 311 } | 316 } |
| 312 default: | 317 default: |
| 313 // something is wrong if we're trying to draw an empty element. | 318 // something is wrong if we're trying to draw an empty element. |
| 314 GrCrash("Unexpected element type"); | 319 GrCrash("Unexpected element type"); |
| 315 return false; | 320 return false; |
| 316 } | 321 } |
| 317 return true; | 322 return true; |
| 318 } | 323 } |
| 319 | 324 |
| 320 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, | 325 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, |
| 321 const SkClipStack::Element* ele
ment, | 326 const SkClipStack::Element* ele
ment, |
| 322 GrPathRenderer** pr) { | 327 GrPathRenderer::AutoClearPath*
acp) { |
| 323 GrDrawState* drawState = fGpu->drawState(); | 328 GrDrawState* drawState = fGpu->drawState(); |
| 324 drawState->setRenderTarget(target->asRenderTarget()); | 329 drawState->setRenderTarget(target->asRenderTarget()); |
| 325 | 330 |
| 326 switch (element->getType()) { | 331 switch (element->getType()) { |
| 327 case Element::kRect_Type: | 332 case Element::kRect_Type: |
| 328 return true; | 333 return true; |
| 329 case Element::kPath_Type: { | 334 case Element::kPath_Type: { |
| 330 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); | |
| 331 if (path->isInverseFillType()) { | |
| 332 path.writable()->toggleInverseFillType(); | |
| 333 } | |
| 334 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 335 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 335 GrPathRendererChain::DrawType type = element->isAA() ? | 336 GrPathRendererChain::DrawType type = element->isAA() ? |
| 336 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : | 337 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
| 337 GrPathRendererChain::kStencilAndColor_DrawType; | 338 GrPathRendererChain::kStencilAndColor_DrawType; |
| 338 *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false
, type); | 339 SkPath::FillType fillType = element->getPath().getFillType(); |
| 339 return NULL != *pr; | 340 acp->set(this->getContext()->getPathRenderer(element->getPath(), |
| 341 stroke, fGpu, false, type, |
| 342 SkPath::ConvertToNonInverseFi
llType(fillType))); |
| 343 return NULL != acp->renderer(); |
| 340 } | 344 } |
| 341 default: | 345 default: |
| 342 // something is wrong if we're trying to draw an empty element. | 346 // something is wrong if we're trying to draw an empty element. |
| 343 GrCrash("Unexpected element type"); | 347 GrCrash("Unexpected element type"); |
| 344 return false; | 348 return false; |
| 345 } | 349 } |
| 346 } | 350 } |
| 347 | 351 |
| 348 void GrClipMaskManager::mergeMask(GrTexture* dstMask, | 352 void GrClipMaskManager::mergeMask(GrTexture* dstMask, |
| 349 GrTexture* srcMask, | 353 GrTexture* srcMask, |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 474 drawState->enableState(GrDrawState::kClip_StateBit); | 478 drawState->enableState(GrDrawState::kClip_StateBit); |
| 475 | 479 |
| 476 GrAutoScratchTexture temp; | 480 GrAutoScratchTexture temp; |
| 477 // walk through each clip element and perform its set op | 481 // walk through each clip element and perform its set op |
| 478 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ | 482 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ |
| 479 const Element* element = iter.get(); | 483 const Element* element = iter.get(); |
| 480 SkRegion::Op op = element->getOp(); | 484 SkRegion::Op op = element->getOp(); |
| 481 bool invert = element->isInverseFilled(); | 485 bool invert = element->isInverseFilled(); |
| 482 | 486 |
| 483 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 487 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
| 484 GrPathRenderer* pr = NULL; | 488 GrPathRenderer::AutoClearPath acp; |
| 485 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; | 489 bool useTemp = !this->canStencilAndDrawElement(result, element, &acp
); |
| 486 GrTexture* dst; | 490 GrTexture* dst; |
| 487 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 491 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary |
| 488 // mask buffer can be substantially larger than the actually clip st
ack element. We | 492 // mask buffer can be substantially larger than the actually clip st
ack element. We |
| 489 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 493 // touch the minimum number of pixels necessary and use decal mode t
o combine it with |
| 490 // the accumulator. | 494 // the accumulator. |
| 491 SkIRect maskSpaceElementIBounds; | 495 SkIRect maskSpaceElementIBounds; |
| 492 | 496 |
| 493 if (useTemp) { | 497 if (useTemp) { |
| 494 if (invert) { | 498 if (invert) { |
| 495 maskSpaceElementIBounds = maskSpaceIBounds; | 499 maskSpaceElementIBounds = maskSpaceIBounds; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 522 kAlways_StencilFunc, | 526 kAlways_StencilFunc, |
| 523 0xffff, | 527 0xffff, |
| 524 0xffff, | 528 0xffff, |
| 525 0xffff); | 529 0xffff); |
| 526 drawState->setStencil(kStencilInElement); | 530 drawState->setStencil(kStencilInElement); |
| 527 setup_boolean_blendcoeffs(drawState, op); | 531 setup_boolean_blendcoeffs(drawState, op); |
| 528 } | 532 } |
| 529 | 533 |
| 530 drawState->setAlpha(invert ? 0x00 : 0xff); | 534 drawState->setAlpha(invert ? 0x00 : 0xff); |
| 531 | 535 |
| 532 if (!this->drawElement(dst, element, pr)) { | 536 if (NULL != acp.renderer()) { |
| 533 fAACache.reset(); | 537 this->drawFilledPath(dst, acp.renderer(), element->isAA()); |
| 534 return NULL; | 538 } else { |
| 539 if (!this->drawElement(dst, element)) { |
| 540 fAACache.reset(); |
| 541 return NULL; |
| 542 } |
| 535 } | 543 } |
| 536 | 544 |
| 537 if (useTemp) { | 545 if (useTemp) { |
| 538 // Now draw into the accumulator using the real operation and th
e temp buffer as a | 546 // Now draw into the accumulator using the real operation and th
e temp buffer as a |
| 539 // texture | 547 // texture |
| 540 this->mergeMask(result, | 548 this->mergeMask(result, |
| 541 temp.texture(), | 549 temp.texture(), |
| 542 op, | 550 op, |
| 543 maskSpaceIBounds, | 551 maskSpaceIBounds, |
| 544 maskSpaceElementIBounds); | 552 maskSpaceElementIBounds); |
| 545 } else { | 553 } else { |
| 546 // Draw to the exterior pixels (those with a zero stencil value)
. | 554 // Draw to the exterior pixels (those with a zero stencil value)
. |
| 547 drawState->setAlpha(invert ? 0xff : 0x00); | 555 drawState->setAlpha(invert ? 0xff : 0x00); |
| 548 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 556 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
| 549 kZero_StencilOp, | 557 kZero_StencilOp, |
| 550 kZero_StencilOp, | 558 kZero_StencilOp, |
| 551 kEqual_StencilFunc, | 559 kEqual_StencilFunc, |
| 552 0xffff, | 560 0xffff, |
| 553 0x0000, | 561 0x0000, |
| 554 0xffff); | 562 0xffff); |
| 555 drawState->setStencil(kDrawOutsideElement); | 563 drawState->setStencil(kDrawOutsideElement); |
| 556 fGpu->drawSimpleRect(clipSpaceIBounds); | 564 fGpu->drawSimpleRect(clipSpaceIBounds); |
| 557 drawState->disableStencil(); | 565 drawState->disableStencil(); |
| 558 } | 566 } |
| 559 } else { | 567 } else { |
| 560 // all the remaining ops can just be directly draw into the accumula
tion buffer | 568 // all the remaining ops can just be directly drawn into the accumul
ation buffer |
| 561 drawState->setAlpha(0xff); | 569 drawState->setAlpha(0xff); |
| 562 setup_boolean_blendcoeffs(drawState, op); | 570 setup_boolean_blendcoeffs(drawState, op); |
| 563 this->drawElement(result, element); | 571 this->drawElement(result, element); |
| 564 } | 572 } |
| 565 } | 573 } |
| 566 | 574 |
| 567 fCurrClipMaskType = kAlpha_ClipMaskType; | 575 fCurrClipMaskType = kAlpha_ClipMaskType; |
| 568 return result; | 576 return result; |
| 569 } | 577 } |
| 570 | 578 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 } | 644 } |
| 637 | 645 |
| 638 // This will be used to determine whether the clip shape can be rend
ered into the | 646 // This will be used to determine whether the clip shape can be rend
ered into the |
| 639 // stencil with arbitrary stencil settings. | 647 // stencil with arbitrary stencil settings. |
| 640 GrPathRenderer::StencilSupport stencilSupport; | 648 GrPathRenderer::StencilSupport stencilSupport; |
| 641 | 649 |
| 642 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 650 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 643 | 651 |
| 644 SkRegion::Op op = element->getOp(); | 652 SkRegion::Op op = element->getOp(); |
| 645 | 653 |
| 646 GrPathRenderer* pr = NULL; | 654 GrPathRenderer::AutoClearPath acp; |
| 647 SkTCopyOnFirstWrite<SkPath> clipPath; | |
| 648 if (Element::kRect_Type == element->getType()) { | 655 if (Element::kRect_Type == element->getType()) { |
| 649 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 656 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
| 650 fillInverted = false; | 657 fillInverted = false; |
| 651 } else { | 658 } else { |
| 652 SkASSERT(Element::kPath_Type == element->getType()); | 659 SkASSERT(Element::kPath_Type == element->getType()); |
| 653 clipPath.init(element->getPath()); | 660 fillInverted = element->getPath().isInverseFillType(); |
| 654 fillInverted = clipPath->isInverseFillType(); | 661 SkPath::FillType fill = element->getPath().getFillType(); |
| 655 if (fillInverted) { | 662 acp.set(this->getContext()->getPathRenderer(element->getPath(), |
| 656 clipPath.writable()->toggleInverseFillType(); | |
| 657 } | |
| 658 pr = this->getContext()->getPathRenderer(*clipPath, | |
| 659 stroke, | 663 stroke, |
| 660 fGpu, | 664 fGpu, |
| 661 false, | 665 false, |
| 662 GrPathRendererChain::kS
tencilOnly_DrawType, | 666 GrPathRendererChain::kS
tencilOnly_DrawType, |
| 663 &stencilSupport); | 667 SkPath::ConvertToNonInv
erseFillType(fill), |
| 664 if (NULL == pr) { | 668 &stencilSupport)); |
| 669 if (NULL == acp.renderer()) { |
| 665 return false; | 670 return false; |
| 666 } | 671 } |
| 667 } | 672 } |
| 668 | 673 |
| 669 int passes; | 674 int passes; |
| 670 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; | 675 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; |
| 671 | 676 |
| 672 bool canRenderDirectToStencil = | 677 bool canRenderDirectToStencil = |
| 673 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; | 678 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; |
| 674 bool canDrawDirectToClip; // Given the renderer, the element, | 679 bool canDrawDirectToClip; // Given the renderer, the element, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 690 kAlways_StencilFunc, | 695 kAlways_StencilFunc, |
| 691 0xffff, | 696 0xffff, |
| 692 0x0000, | 697 0x0000, |
| 693 0xffff); | 698 0xffff); |
| 694 SET_RANDOM_COLOR | 699 SET_RANDOM_COLOR |
| 695 if (Element::kRect_Type == element->getType()) { | 700 if (Element::kRect_Type == element->getType()) { |
| 696 *drawState->stencil() = gDrawToStencil; | 701 *drawState->stencil() = gDrawToStencil; |
| 697 fGpu->drawSimpleRect(element->getRect(), NULL); | 702 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 698 } else { | 703 } else { |
| 699 SkASSERT(Element::kPath_Type == element->getType()); | 704 SkASSERT(Element::kPath_Type == element->getType()); |
| 700 if (!clipPath->isEmpty()) { | 705 if (NULL != acp.renderer()) { |
| 701 if (canRenderDirectToStencil) { | 706 if (canRenderDirectToStencil) { |
| 702 *drawState->stencil() = gDrawToStencil; | 707 *drawState->stencil() = gDrawToStencil; |
| 703 pr->drawPath(*clipPath, stroke, fGpu, false); | 708 acp->drawPath(stroke, fGpu, false); |
| 704 } else { | 709 } else { |
| 705 pr->stencilPath(*clipPath, stroke, fGpu); | 710 acp->stencilPath(stroke, fGpu); |
| 706 } | 711 } |
| 707 } | 712 } |
| 708 } | 713 } |
| 709 } | 714 } |
| 710 | 715 |
| 711 // now we modify the clip bit by rendering either the clip | 716 // now we modify the clip bit by rendering either the clip |
| 712 // element directly or a bounding rect of the entire clip. | 717 // element directly or a bounding rect of the entire clip. |
| 713 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); | 718 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); |
| 714 for (int p = 0; p < passes; ++p) { | 719 for (int p = 0; p < passes; ++p) { |
| 715 *drawState->stencil() = stencilSettings[p]; | 720 *drawState->stencil() = stencilSettings[p]; |
| 716 if (canDrawDirectToClip) { | 721 if (canDrawDirectToClip) { |
| 717 if (Element::kRect_Type == element->getType()) { | 722 if (Element::kRect_Type == element->getType()) { |
| 718 SET_RANDOM_COLOR | 723 SET_RANDOM_COLOR |
| 719 fGpu->drawSimpleRect(element->getRect(), NULL); | 724 fGpu->drawSimpleRect(element->getRect(), NULL); |
| 720 } else { | 725 } else { |
| 721 SkASSERT(Element::kPath_Type == element->getType()); | 726 SkASSERT(Element::kPath_Type == element->getType()); |
| 722 SET_RANDOM_COLOR | 727 SET_RANDOM_COLOR |
| 723 pr->drawPath(*clipPath, stroke, fGpu, false); | 728 acp->drawPath(stroke, fGpu, false); |
| 724 } | 729 } |
| 725 } else { | 730 } else { |
| 726 SET_RANDOM_COLOR | 731 SET_RANDOM_COLOR |
| 727 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 732 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
| 728 // draw rect in clip space. | 733 // draw rect in clip space. |
| 729 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); | 734 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); |
| 730 } | 735 } |
| 731 } | 736 } |
| 732 } | 737 } |
| 733 } | 738 } |
| (...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 | 1040 |
| 1036 // TODO: dynamically attach a stencil buffer | 1041 // TODO: dynamically attach a stencil buffer |
| 1037 int stencilBits = 0; | 1042 int stencilBits = 0; |
| 1038 GrStencilBuffer* stencilBuffer = | 1043 GrStencilBuffer* stencilBuffer = |
| 1039 drawState.getRenderTarget()->getStencilBuffer(); | 1044 drawState.getRenderTarget()->getStencilBuffer(); |
| 1040 if (NULL != stencilBuffer) { | 1045 if (NULL != stencilBuffer) { |
| 1041 stencilBits = stencilBuffer->bits(); | 1046 stencilBits = stencilBuffer->bits(); |
| 1042 this->adjustStencilParams(settings, clipMode, stencilBits); | 1047 this->adjustStencilParams(settings, clipMode, stencilBits); |
| 1043 } | 1048 } |
| 1044 } | 1049 } |
| OLD | NEW |