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 12 matching lines...) Expand all Loading... |
23 #include "SkStrokeRec.h" | 23 #include "SkStrokeRec.h" |
24 #include "SkTLazy.h" | 24 #include "SkTLazy.h" |
25 | 25 |
26 #define GR_AA_CLIP 1 | 26 #define GR_AA_CLIP 1 |
27 | 27 |
28 typedef SkClipStack::Element Element; | 28 typedef SkClipStack::Element Element; |
29 | 29 |
30 using namespace GrReducedClip; | 30 using namespace GrReducedClip; |
31 | 31 |
32 //////////////////////////////////////////////////////////////////////////////// | 32 //////////////////////////////////////////////////////////////////////////////// |
33 namespace { | |
34 // set up the draw state to enable the aa clipping mask. Besides setting up the | 33 // set up the draw state to enable the aa clipping mask. Besides setting up the |
35 // stage matrix this also alters the vertex layout | 34 // stage matrix this also alters the vertex layout |
36 void setup_drawstate_aaclip(GrGpu* gpu, | 35 static void setup_drawstate_aaclip(GrGpu* gpu, |
37 GrTexture* result, | 36 GrTexture* result, |
38 const SkIRect &devBound) { | 37 const SkIRect &devBound) { |
39 GrDrawState* drawState = gpu->drawState(); | 38 GrDrawState* drawState = gpu->drawState(); |
40 SkASSERT(drawState); | 39 SkASSERT(drawState); |
41 | 40 |
42 SkMatrix mat; | 41 SkMatrix mat; |
43 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be | 42 // We want to use device coords to compute the texture coordinates. We set o
ur matrix to be |
44 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to | 43 // equal to the view matrix followed by an offset to the devBound, and then
a scaling matrix to |
45 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. | 44 // normalized coords. We apply this matrix to the vertex positions rather th
an local coords. |
46 mat.setIDiv(result->width(), result->height()); | 45 mat.setIDiv(result->width(), result->height()); |
47 mat.preTranslate(SkIntToScalar(-devBound.fLeft), | 46 mat.preTranslate(SkIntToScalar(-devBound.fLeft), |
48 SkIntToScalar(-devBound.fTop)); | 47 SkIntToScalar(-devBound.fTop)); |
49 mat.preConcat(drawState->getViewMatrix()); | 48 mat.preConcat(drawState->getViewMatrix()); |
50 | 49 |
51 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); | 50 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); |
52 // This could be a long-lived effect that is cached with the alpha-mask. | 51 // This could be a long-lived effect that is cached with the alpha-mask. |
53 drawState->addCoverageEffect( | 52 drawState->addCoverageEffect( |
54 GrTextureDomainEffect::Create(result, | 53 GrTextureDomainEffect::Create(result, |
55 mat, | 54 mat, |
56 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), | 55 GrTextureDomain::MakeTexelDomain(result, d
omainTexels), |
57 GrTextureDomain::kDecal_Mode, | 56 GrTextureDomain::kDecal_Mode, |
58 GrTextureParams::kNone_FilterMode, | 57 GrTextureParams::kNone_FilterMode, |
59 kPosition_GrCoordSet))->unref(); | 58 kPosition_GrCoordSet))->unref(); |
60 } | 59 } |
61 | 60 |
62 bool path_needs_SW_renderer(GrContext* context, | 61 static bool path_needs_SW_renderer(GrContext* context, |
63 GrGpu* gpu, | 62 GrGpu* gpu, |
64 const SkPath& origPath, | 63 const SkPath& origPath, |
65 const SkStrokeRec& stroke, | 64 const SkStrokeRec& stroke, |
66 bool doAA) { | 65 bool doAA) { |
67 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer | |
68 SkTCopyOnFirstWrite<SkPath> path(origPath); | |
69 if (path->isInverseFillType()) { | |
70 path.writable()->toggleInverseFillType(); | |
71 } | |
72 // last (false) parameter disallows use of the SW path renderer | |
73 GrPathRendererChain::DrawType type = doAA ? | 66 GrPathRendererChain::DrawType type = doAA ? |
74 GrPathRendererChain::kColorAntiAlias_Dr
awType : | 67 GrPathRendererChain::kColorAntiAlias_Dr
awType : |
75 GrPathRendererChain::kColor_DrawType; | 68 GrPathRendererChain::kColor_DrawType; |
| 69 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b
uffer |
| 70 SkPath::FillType fillType = SkPath::ConvertToNonInverseFillType(origPath.get
FillType()); |
76 | 71 |
77 return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); | 72 // the 'false' parameter disallows use of the SW path renderer |
78 } | 73 GrPathRenderer::AutoClearPath acp(context->getPathRenderer(origPath, stroke,
gpu, |
79 | 74 false, type, fill
Type)); |
| 75 return NULL == acp.renderer(); |
80 } | 76 } |
81 | 77 |
82 /* | 78 /* |
83 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 79 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
84 * will be used on any element. If so, it returns true to indicate that the | 80 * will be used on any element. If so, it returns true to indicate that the |
85 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 81 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
86 */ | 82 */ |
87 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { | 83 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { |
88 | 84 |
89 // TODO: generalize this function so that when | 85 // TODO: generalize this function so that when |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
306 break; | 302 break; |
307 default: | 303 default: |
308 SkASSERT(false); | 304 SkASSERT(false); |
309 break; | 305 break; |
310 } | 306 } |
311 } | 307 } |
312 | 308 |
313 } | 309 } |
314 | 310 |
315 //////////////////////////////////////////////////////////////////////////////// | 311 //////////////////////////////////////////////////////////////////////////////// |
316 bool GrClipMaskManager::drawElement(GrTexture* target, | 312 bool GrClipMaskManager::drawFilledPath(GrTexture* target, |
317 const SkClipStack::Element* element, | 313 GrPathRenderer* pathRenderer, |
318 GrPathRenderer* pr) { | 314 bool isAA) { |
319 GrDrawState* drawState = fGpu->drawState(); | 315 GrDrawState* drawState = fGpu->drawState(); |
320 | 316 |
321 drawState->setRenderTarget(target->asRenderTarget()); | 317 drawState->setRenderTarget(target->asRenderTarget()); |
| 318 |
| 319 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
| 320 pathRenderer->drawPath(stroke, fGpu, isAA); |
| 321 return true; |
| 322 } |
| 323 |
| 324 bool GrClipMaskManager::drawElement(GrTexture* target, |
| 325 const SkClipStack::Element* element) { |
| 326 GrDrawState* drawState = fGpu->drawState(); |
| 327 |
| 328 drawState->setRenderTarget(target->asRenderTarget()); |
322 | 329 |
323 switch (element->getType()) { | 330 switch (element->getType()) { |
324 case Element::kRect_Type: | 331 case Element::kRect_Type: |
325 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe
ct that covers the | 332 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe
ct that covers the |
326 // entire mask bounds and writes 0 outside the rect. | 333 // entire mask bounds and writes 0 outside the rect. |
327 if (element->isAA()) { | 334 if (element->isAA()) { |
328 getContext()->getAARectRenderer()->fillAARect(fGpu, | 335 getContext()->getAARectRenderer()->fillAARect(fGpu, |
329 fGpu, | 336 fGpu, |
330 element->getRect()
, | 337 element->getRect()
, |
331 SkMatrix::I(), | 338 SkMatrix::I(), |
332 element->getRect()
, | 339 element->getRect()
, |
333 false); | 340 false); |
334 } else { | 341 } else { |
335 fGpu->drawSimpleRect(element->getRect(), NULL); | 342 fGpu->drawSimpleRect(element->getRect(), NULL); |
336 } | 343 } |
337 return true; | 344 return true; |
338 case Element::kPath_Type: { | 345 case Element::kPath_Type: { |
339 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); | |
340 if (path->isInverseFillType()) { | |
341 path.writable()->toggleInverseFillType(); | |
342 } | |
343 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 346 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
344 if (NULL == pr) { | 347 GrPathRendererChain::DrawType type; |
345 GrPathRendererChain::DrawType type; | 348 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawTy
pe : |
346 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr
awType : | 349 GrPathRendererChain::kColor_DrawType; |
347 GrPathRendererChain::kColor_DrawType; | 350 SkPath::FillType fillType = element->getPath().getFillType(); |
348 pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, fa
lse, type); | 351 GrPathRenderer::AutoClearPath acp(this->getContext()->getPathRendere
r( |
349 } | 352 element->getPath(), |
350 if (NULL == pr) { | 353 stroke, fGpu, false, type, |
| 354 SkPath::ConvertToNonInverseFil
lType(fillType))); |
| 355 if (NULL == acp.renderer()) { |
351 return false; | 356 return false; |
352 } | 357 } |
353 pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); | 358 acp->drawPath(stroke, fGpu, element->isAA()); |
354 break; | 359 break; |
355 } | 360 } |
356 default: | 361 default: |
357 // something is wrong if we're trying to draw an empty element. | 362 // something is wrong if we're trying to draw an empty element. |
358 GrCrash("Unexpected element type"); | 363 GrCrash("Unexpected element type"); |
359 return false; | 364 return false; |
360 } | 365 } |
361 return true; | 366 return true; |
362 } | 367 } |
363 | 368 |
364 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, | 369 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, |
365 const SkClipStack::Element* ele
ment, | 370 const SkClipStack::Element* ele
ment, |
366 GrPathRenderer** pr) { | 371 GrPathRenderer::AutoClearPath*
acp) { |
367 GrDrawState* drawState = fGpu->drawState(); | 372 GrDrawState* drawState = fGpu->drawState(); |
368 drawState->setRenderTarget(target->asRenderTarget()); | 373 drawState->setRenderTarget(target->asRenderTarget()); |
369 | 374 |
370 switch (element->getType()) { | 375 switch (element->getType()) { |
371 case Element::kRect_Type: | 376 case Element::kRect_Type: |
372 return true; | 377 return true; |
373 case Element::kPath_Type: { | 378 case Element::kPath_Type: { |
374 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); | |
375 if (path->isInverseFillType()) { | |
376 path.writable()->toggleInverseFillType(); | |
377 } | |
378 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 379 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
379 GrPathRendererChain::DrawType type = element->isAA() ? | 380 GrPathRendererChain::DrawType type = element->isAA() ? |
380 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : | 381 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
381 GrPathRendererChain::kStencilAndColor_DrawType; | 382 GrPathRendererChain::kStencilAndColor_DrawType; |
382 *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false
, type); | 383 SkPath::FillType fillType = element->getPath().getFillType(); |
383 return NULL != *pr; | 384 acp->set(this->getContext()->getPathRenderer(element->getPath(), |
| 385 stroke, fGpu, false, type, |
| 386 SkPath::ConvertToNonInverseFi
llType(fillType))); |
| 387 return NULL != acp->renderer(); |
384 } | 388 } |
385 default: | 389 default: |
386 // something is wrong if we're trying to draw an empty element. | 390 // something is wrong if we're trying to draw an empty element. |
387 GrCrash("Unexpected element type"); | 391 GrCrash("Unexpected element type"); |
388 return false; | 392 return false; |
389 } | 393 } |
390 } | 394 } |
391 | 395 |
392 void GrClipMaskManager::mergeMask(GrTexture* dstMask, | 396 void GrClipMaskManager::mergeMask(GrTexture* dstMask, |
393 GrTexture* srcMask, | 397 GrTexture* srcMask, |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
518 drawState->enableState(GrDrawState::kClip_StateBit); | 522 drawState->enableState(GrDrawState::kClip_StateBit); |
519 | 523 |
520 GrAutoScratchTexture temp; | 524 GrAutoScratchTexture temp; |
521 // walk through each clip element and perform its set op | 525 // walk through each clip element and perform its set op |
522 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ | 526 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ |
523 const Element* element = iter.get(); | 527 const Element* element = iter.get(); |
524 SkRegion::Op op = element->getOp(); | 528 SkRegion::Op op = element->getOp(); |
525 bool invert = element->isInverseFilled(); | 529 bool invert = element->isInverseFilled(); |
526 | 530 |
527 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 531 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
528 GrPathRenderer* pr = NULL; | 532 GrPathRenderer::AutoClearPath acp; |
529 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; | 533 bool useTemp = !this->canStencilAndDrawElement(result, element, &acp
); |
530 GrTexture* dst; | 534 GrTexture* dst; |
531 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 535 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary |
532 // mask buffer can be substantially larger than the actually clip st
ack element. We | 536 // mask buffer can be substantially larger than the actually clip st
ack element. We |
533 // touch the minimum number of pixels necessary and use decal mode t
o combine it with | 537 // touch the minimum number of pixels necessary and use decal mode t
o combine it with |
534 // the accumulator. | 538 // the accumulator. |
535 SkIRect maskSpaceElementIBounds; | 539 SkIRect maskSpaceElementIBounds; |
536 | 540 |
537 if (useTemp) { | 541 if (useTemp) { |
538 if (invert) { | 542 if (invert) { |
539 maskSpaceElementIBounds = maskSpaceIBounds; | 543 maskSpaceElementIBounds = maskSpaceIBounds; |
(...skipping 26 matching lines...) Expand all Loading... |
566 kAlways_StencilFunc, | 570 kAlways_StencilFunc, |
567 0xffff, | 571 0xffff, |
568 0xffff, | 572 0xffff, |
569 0xffff); | 573 0xffff); |
570 drawState->setStencil(kStencilInElement); | 574 drawState->setStencil(kStencilInElement); |
571 setup_boolean_blendcoeffs(drawState, op); | 575 setup_boolean_blendcoeffs(drawState, op); |
572 } | 576 } |
573 | 577 |
574 drawState->setAlpha(invert ? 0x00 : 0xff); | 578 drawState->setAlpha(invert ? 0x00 : 0xff); |
575 | 579 |
576 if (!this->drawElement(dst, element, pr)) { | 580 if (NULL != acp.renderer()) { |
577 fAACache.reset(); | 581 this->drawFilledPath(dst, acp.renderer(), element->isAA()); |
578 return NULL; | 582 } else { |
| 583 if (!this->drawElement(dst, element)) { |
| 584 fAACache.reset(); |
| 585 return NULL; |
| 586 } |
579 } | 587 } |
580 | 588 |
581 if (useTemp) { | 589 if (useTemp) { |
582 // Now draw into the accumulator using the real operation and th
e temp buffer as a | 590 // Now draw into the accumulator using the real operation and th
e temp buffer as a |
583 // texture | 591 // texture |
584 this->mergeMask(result, | 592 this->mergeMask(result, |
585 temp.texture(), | 593 temp.texture(), |
586 op, | 594 op, |
587 maskSpaceIBounds, | 595 maskSpaceIBounds, |
588 maskSpaceElementIBounds); | 596 maskSpaceElementIBounds); |
589 } else { | 597 } else { |
590 // Draw to the exterior pixels (those with a zero stencil value)
. | 598 // Draw to the exterior pixels (those with a zero stencil value)
. |
591 drawState->setAlpha(invert ? 0xff : 0x00); | 599 drawState->setAlpha(invert ? 0xff : 0x00); |
592 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 600 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
593 kZero_StencilOp, | 601 kZero_StencilOp, |
594 kZero_StencilOp, | 602 kZero_StencilOp, |
595 kEqual_StencilFunc, | 603 kEqual_StencilFunc, |
596 0xffff, | 604 0xffff, |
597 0x0000, | 605 0x0000, |
598 0xffff); | 606 0xffff); |
599 drawState->setStencil(kDrawOutsideElement); | 607 drawState->setStencil(kDrawOutsideElement); |
600 fGpu->drawSimpleRect(clipSpaceIBounds); | 608 fGpu->drawSimpleRect(clipSpaceIBounds); |
601 drawState->disableStencil(); | 609 drawState->disableStencil(); |
602 } | 610 } |
603 } else { | 611 } else { |
604 // all the remaining ops can just be directly draw into the accumula
tion buffer | 612 // all the remaining ops can just be directly drawn into the accumul
ation buffer |
605 drawState->setAlpha(0xff); | 613 drawState->setAlpha(0xff); |
606 setup_boolean_blendcoeffs(drawState, op); | 614 setup_boolean_blendcoeffs(drawState, op); |
607 this->drawElement(result, element); | 615 this->drawElement(result, element); |
608 } | 616 } |
609 } | 617 } |
610 | 618 |
611 fCurrClipMaskType = kAlpha_ClipMaskType; | 619 fCurrClipMaskType = kAlpha_ClipMaskType; |
612 return result; | 620 return result; |
613 } | 621 } |
614 | 622 |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 } | 688 } |
681 | 689 |
682 // This will be used to determine whether the clip shape can be rend
ered into the | 690 // This will be used to determine whether the clip shape can be rend
ered into the |
683 // stencil with arbitrary stencil settings. | 691 // stencil with arbitrary stencil settings. |
684 GrPathRenderer::StencilSupport stencilSupport; | 692 GrPathRenderer::StencilSupport stencilSupport; |
685 | 693 |
686 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 694 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
687 | 695 |
688 SkRegion::Op op = element->getOp(); | 696 SkRegion::Op op = element->getOp(); |
689 | 697 |
690 GrPathRenderer* pr = NULL; | 698 GrPathRenderer::AutoClearPath acp; |
691 SkTCopyOnFirstWrite<SkPath> clipPath; | |
692 if (Element::kRect_Type == element->getType()) { | 699 if (Element::kRect_Type == element->getType()) { |
693 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 700 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
694 fillInverted = false; | 701 fillInverted = false; |
695 } else { | 702 } else { |
696 SkASSERT(Element::kPath_Type == element->getType()); | 703 SkASSERT(Element::kPath_Type == element->getType()); |
697 clipPath.init(element->getPath()); | 704 fillInverted = element->getPath().isInverseFillType(); |
698 fillInverted = clipPath->isInverseFillType(); | 705 SkPath::FillType fill = element->getPath().getFillType(); |
699 if (fillInverted) { | 706 acp.set(this->getContext()->getPathRenderer(element->getPath(), |
700 clipPath.writable()->toggleInverseFillType(); | |
701 } | |
702 pr = this->getContext()->getPathRenderer(*clipPath, | |
703 stroke, | 707 stroke, |
704 fGpu, | 708 fGpu, |
705 false, | 709 false, |
706 GrPathRendererChain::kS
tencilOnly_DrawType, | 710 GrPathRendererChain::kS
tencilOnly_DrawType, |
707 &stencilSupport); | 711 SkPath::ConvertToNonInv
erseFillType(fill), |
708 if (NULL == pr) { | 712 &stencilSupport)); |
| 713 if (NULL == acp.renderer()) { |
709 return false; | 714 return false; |
710 } | 715 } |
711 } | 716 } |
712 | 717 |
713 int passes; | 718 int passes; |
714 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; | 719 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip
Passes]; |
715 | 720 |
716 bool canRenderDirectToStencil = | 721 bool canRenderDirectToStencil = |
717 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; | 722 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; |
718 bool canDrawDirectToClip; // Given the renderer, the element, | 723 bool canDrawDirectToClip; // Given the renderer, the element, |
(...skipping 15 matching lines...) Expand all Loading... |
734 kAlways_StencilFunc, | 739 kAlways_StencilFunc, |
735 0xffff, | 740 0xffff, |
736 0x0000, | 741 0x0000, |
737 0xffff); | 742 0xffff); |
738 SET_RANDOM_COLOR | 743 SET_RANDOM_COLOR |
739 if (Element::kRect_Type == element->getType()) { | 744 if (Element::kRect_Type == element->getType()) { |
740 *drawState->stencil() = gDrawToStencil; | 745 *drawState->stencil() = gDrawToStencil; |
741 fGpu->drawSimpleRect(element->getRect(), NULL); | 746 fGpu->drawSimpleRect(element->getRect(), NULL); |
742 } else { | 747 } else { |
743 SkASSERT(Element::kPath_Type == element->getType()); | 748 SkASSERT(Element::kPath_Type == element->getType()); |
744 if (!clipPath->isEmpty()) { | 749 if (NULL != acp.renderer()) { |
745 if (canRenderDirectToStencil) { | 750 if (canRenderDirectToStencil) { |
746 *drawState->stencil() = gDrawToStencil; | 751 *drawState->stencil() = gDrawToStencil; |
747 pr->drawPath(*clipPath, stroke, fGpu, false); | 752 acp->drawPath(stroke, fGpu, false); |
748 } else { | 753 } else { |
749 pr->stencilPath(*clipPath, stroke, fGpu); | 754 acp->stencilPath(stroke, fGpu); |
750 } | 755 } |
751 } | 756 } |
752 } | 757 } |
753 } | 758 } |
754 | 759 |
755 // now we modify the clip bit by rendering either the clip | 760 // now we modify the clip bit by rendering either the clip |
756 // element directly or a bounding rect of the entire clip. | 761 // element directly or a bounding rect of the entire clip. |
757 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); | 762 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); |
758 for (int p = 0; p < passes; ++p) { | 763 for (int p = 0; p < passes; ++p) { |
759 *drawState->stencil() = stencilSettings[p]; | 764 *drawState->stencil() = stencilSettings[p]; |
760 if (canDrawDirectToClip) { | 765 if (canDrawDirectToClip) { |
761 if (Element::kRect_Type == element->getType()) { | 766 if (Element::kRect_Type == element->getType()) { |
762 SET_RANDOM_COLOR | 767 SET_RANDOM_COLOR |
763 fGpu->drawSimpleRect(element->getRect(), NULL); | 768 fGpu->drawSimpleRect(element->getRect(), NULL); |
764 } else { | 769 } else { |
765 SkASSERT(Element::kPath_Type == element->getType()); | 770 SkASSERT(Element::kPath_Type == element->getType()); |
766 SET_RANDOM_COLOR | 771 SET_RANDOM_COLOR |
767 pr->drawPath(*clipPath, stroke, fGpu, false); | 772 acp->drawPath(stroke, fGpu, false); |
768 } | 773 } |
769 } else { | 774 } else { |
770 SET_RANDOM_COLOR | 775 SET_RANDOM_COLOR |
771 // The view matrix is setup to do clip space -> stencil spac
e translation, so | 776 // The view matrix is setup to do clip space -> stencil spac
e translation, so |
772 // draw rect in clip space. | 777 // draw rect in clip space. |
773 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); | 778 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); |
774 } | 779 } |
775 } | 780 } |
776 } | 781 } |
777 } | 782 } |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1079 | 1084 |
1080 // TODO: dynamically attach a stencil buffer | 1085 // TODO: dynamically attach a stencil buffer |
1081 int stencilBits = 0; | 1086 int stencilBits = 0; |
1082 GrStencilBuffer* stencilBuffer = | 1087 GrStencilBuffer* stencilBuffer = |
1083 drawState.getRenderTarget()->getStencilBuffer(); | 1088 drawState.getRenderTarget()->getStencilBuffer(); |
1084 if (NULL != stencilBuffer) { | 1089 if (NULL != stencilBuffer) { |
1085 stencilBits = stencilBuffer->bits(); | 1090 stencilBits = stencilBuffer->bits(); |
1086 this->adjustStencilParams(settings, clipMode, stencilBits); | 1091 this->adjustStencilParams(settings, clipMode, stencilBits); |
1087 } | 1092 } |
1088 } | 1093 } |
OLD | NEW |