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 10 matching lines...) Expand all Loading... |
21 #include "effects/GrConvexPolyEffect.h" | 21 #include "effects/GrConvexPolyEffect.h" |
22 #include "effects/GrRRectEffect.h" | 22 #include "effects/GrRRectEffect.h" |
23 #include "SkRasterClip.h" | 23 #include "SkRasterClip.h" |
24 #include "SkStrokeRec.h" | 24 #include "SkStrokeRec.h" |
25 #include "SkTLazy.h" | 25 #include "SkTLazy.h" |
26 | 26 |
27 #define GR_AA_CLIP 1 | 27 #define GR_AA_CLIP 1 |
28 | 28 |
29 typedef SkClipStack::Element Element; | 29 typedef SkClipStack::Element Element; |
30 | 30 |
31 using namespace GrReducedClip; | |
32 | |
33 //////////////////////////////////////////////////////////////////////////////// | 31 //////////////////////////////////////////////////////////////////////////////// |
34 namespace { | 32 namespace { |
35 // 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 |
36 // stage matrix this also alters the vertex layout | 34 // stage matrix this also alters the vertex layout |
37 void setup_drawstate_aaclip(GrGpu* gpu, | 35 void setup_drawstate_aaclip(GrGpu* gpu, |
38 GrTexture* result, | 36 GrTexture* result, |
39 const SkIRect &devBound) { | 37 const SkIRect &devBound) { |
40 GrDrawState* drawState = gpu->drawState(); | 38 GrDrawState* drawState = gpu->drawState(); |
41 SkASSERT(drawState); | 39 SkASSERT(drawState); |
42 | 40 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); | 76 return NULL == context->getPathRenderer(*path, stroke, gpu, false, type); |
79 } | 77 } |
80 | 78 |
81 } | 79 } |
82 | 80 |
83 /* | 81 /* |
84 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 82 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
85 * will be used on any element. If so, it returns true to indicate that the | 83 * will be used on any element. If so, it returns true to indicate that the |
86 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 84 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
87 */ | 85 */ |
88 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { | 86 bool GrClipMaskManager::useSWOnlyPath(const GrReducedClip::ElementList& elements
) { |
89 | 87 |
90 // TODO: generalize this function so that when | 88 // TODO: generalize this function so that when |
91 // a clip gets complex enough it can just be done in SW regardless | 89 // a clip gets complex enough it can just be done in SW regardless |
92 // of whether it would invoke the GrSoftwarePathRenderer. | 90 // of whether it would invoke the GrSoftwarePathRenderer. |
93 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 91 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
94 | 92 |
95 for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { | 93 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get();
iter.next()) { |
96 const Element* element = iter.get(); | 94 const Element* element = iter.get(); |
97 // rects can always be drawn directly w/o using the software path | 95 // rects can always be drawn directly w/o using the software path |
98 // Skip rrects once we're drawing them directly. | 96 // Skip rrects once we're drawing them directly. |
99 if (Element::kRect_Type != element->getType()) { | 97 if (Element::kRect_Type != element->getType()) { |
100 SkPath path; | 98 SkPath path; |
101 element->asPath(&path); | 99 element->asPath(&path); |
102 if (path_needs_SW_renderer(this->getContext(), fGpu, path, stroke, e
lement->isAA())) { | 100 if (path_needs_SW_renderer(this->getContext(), fGpu, path, stroke, e
lement->isAA())) { |
103 return true; | 101 return true; |
104 } | 102 } |
105 } | 103 } |
106 } | 104 } |
107 return false; | 105 return false; |
108 } | 106 } |
109 | 107 |
110 bool GrClipMaskManager::installClipEffects(const ElementList& elements, | 108 bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele
ments, |
111 GrDrawState::AutoRestoreEffects* are, | 109 GrDrawState::AutoRestoreEffects* are, |
112 const SkVector& clipToRTOffset, | 110 const SkVector& clipToRTOffset, |
113 const SkRect* drawBounds) { | 111 const SkRect* drawBounds) { |
114 | 112 |
115 GrDrawState* drawState = fGpu->drawState(); | 113 GrDrawState* drawState = fGpu->drawState(); |
116 SkRect boundsInClipSpace; | 114 SkRect boundsInClipSpace; |
117 if (drawBounds) { | 115 if (drawBounds) { |
118 boundsInClipSpace = *drawBounds; | 116 boundsInClipSpace = *drawBounds; |
119 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); | 117 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); |
120 } | 118 } |
121 | 119 |
122 are->set(drawState); | 120 are->set(drawState); |
123 GrRenderTarget* rt = drawState->getRenderTarget(); | 121 GrRenderTarget* rt = drawState->getRenderTarget(); |
124 ElementList::Iter iter(elements); | 122 GrReducedClip::ElementList::Iter iter(elements); |
125 | 123 |
126 bool setARE = false; | 124 bool setARE = false; |
127 bool failed = false; | 125 bool failed = false; |
128 | 126 |
129 while (iter.get()) { | 127 while (iter.get()) { |
130 SkRegion::Op op = iter.get()->getOp(); | 128 SkRegion::Op op = iter.get()->getOp(); |
131 bool invert; | 129 bool invert; |
132 bool skip = false; | 130 bool skip = false; |
133 switch (op) { | 131 switch (op) { |
134 case SkRegion::kReplace_Op: | 132 case SkRegion::kReplace_Op: |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 } | 208 } |
211 | 209 |
212 //////////////////////////////////////////////////////////////////////////////// | 210 //////////////////////////////////////////////////////////////////////////////// |
213 // sort out what kind of clip mask needs to be created: alpha, stencil, | 211 // sort out what kind of clip mask needs to be created: alpha, stencil, |
214 // scissor, or entirely software | 212 // scissor, or entirely software |
215 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, | 213 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, |
216 GrDrawState::AutoRestoreEffects* are, | 214 GrDrawState::AutoRestoreEffects* are, |
217 const SkRect* devBounds) { | 215 const SkRect* devBounds) { |
218 fCurrClipMaskType = kNone_ClipMaskType; | 216 fCurrClipMaskType = kNone_ClipMaskType; |
219 | 217 |
220 ElementList elements(16); | 218 GrReducedClip::ElementList elements(16); |
221 int32_t genID; | 219 int32_t genID; |
222 InitialState initialState; | 220 GrReducedClip::InitialState initialState; |
223 SkIRect clipSpaceIBounds; | 221 SkIRect clipSpaceIBounds; |
224 bool requiresAA; | 222 bool requiresAA; |
225 | 223 |
226 GrDrawState* drawState = fGpu->drawState(); | 224 GrDrawState* drawState = fGpu->drawState(); |
227 | 225 |
228 const GrRenderTarget* rt = drawState->getRenderTarget(); | 226 const GrRenderTarget* rt = drawState->getRenderTarget(); |
229 // GrDrawTarget should have filtered this for us | 227 // GrDrawTarget should have filtered this for us |
230 SkASSERT(rt); | 228 SkASSERT(rt); |
231 | 229 |
232 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid
eOpen(); | 230 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid
eOpen(); |
233 | 231 |
234 if (!ignoreClip) { | 232 if (!ignoreClip) { |
235 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); | 233 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); |
236 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); | 234 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); |
237 ReduceClipStack(*clipDataIn->fClipStack, | 235 GrReducedClip::ReduceClipStack(*clipDataIn->fClipStack, |
238 clipSpaceRTIBounds, | 236 clipSpaceRTIBounds, |
239 &elements, | 237 &elements, |
240 &genID, | 238 &genID, |
241 &initialState, | 239 &initialState, |
242 &clipSpaceIBounds, | 240 &clipSpaceIBounds, |
243 &requiresAA); | 241 &requiresAA); |
244 if (elements.isEmpty()) { | 242 if (elements.isEmpty()) { |
245 if (kAllIn_InitialState == initialState) { | 243 if (GrReducedClip::kAllIn_InitialState == initialState) { |
246 ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; | 244 ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; |
247 } else { | 245 } else { |
248 return false; | 246 return false; |
249 } | 247 } |
250 } | 248 } |
251 } | 249 } |
252 | 250 |
253 if (ignoreClip) { | 251 if (ignoreClip) { |
254 fGpu->disableScissor(); | 252 fGpu->disableScissor(); |
255 this->setGpuStencil(); | 253 this->setGpuStencil(); |
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 desc.fConfig = kAlpha_8_GrPixelConfig; | 525 desc.fConfig = kAlpha_8_GrPixelConfig; |
528 } | 526 } |
529 | 527 |
530 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds); | 528 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds); |
531 return fAACache.getLastMask(); | 529 return fAACache.getLastMask(); |
532 } | 530 } |
533 | 531 |
534 //////////////////////////////////////////////////////////////////////////////// | 532 //////////////////////////////////////////////////////////////////////////////// |
535 // Create a 8-bit clip mask in alpha | 533 // Create a 8-bit clip mask in alpha |
536 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, | 534 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, |
537 InitialState initialState, | 535 GrReducedClip::InitialState in
itialState, |
538 const ElementList& elements, | 536 const GrReducedClip::ElementLi
st& elements, |
539 const SkIRect& clipSpaceIBound
s) { | 537 const SkIRect& clipSpaceIBound
s) { |
540 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 538 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
541 | 539 |
542 // First, check for cached texture | 540 // First, check for cached texture |
543 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); | 541 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun
ds); |
544 if (result) { | 542 if (result) { |
545 fCurrClipMaskType = kAlpha_ClipMaskType; | 543 fCurrClipMaskType = kAlpha_ClipMaskType; |
546 return result; | 544 return result; |
547 } | 545 } |
548 | 546 |
(...skipping 19 matching lines...) Expand all Loading... |
568 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRI
nit, &translate); | 566 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRI
nit, &translate); |
569 | 567 |
570 GrDrawState* drawState = fGpu->drawState(); | 568 GrDrawState* drawState = fGpu->drawState(); |
571 | 569 |
572 // We're drawing a coverage mask and want coverage to be run through the ble
nd function. | 570 // We're drawing a coverage mask and want coverage to be run through the ble
nd function. |
573 drawState->enableState(GrDrawState::kCoverageDrawing_StateBit); | 571 drawState->enableState(GrDrawState::kCoverageDrawing_StateBit); |
574 | 572 |
575 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only | 573 // The scratch texture that we are drawing into can be substantially larger
than the mask. Only |
576 // clear the part that we care about. | 574 // clear the part that we care about. |
577 fGpu->clear(&maskSpaceIBounds, | 575 fGpu->clear(&maskSpaceIBounds, |
578 kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, | 576 GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff
: 0x00000000, |
579 true, | 577 true, |
580 result->asRenderTarget()); | 578 result->asRenderTarget()); |
581 | 579 |
582 // When we use the stencil in the below loop it is important to have this cl
ip installed. | 580 // When we use the stencil in the below loop it is important to have this cl
ip installed. |
583 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first | 581 // The second pass that zeros the stencil buffer renders the rect maskSpaceI
Bounds so the first |
584 // pass must not set values outside of this bounds or stencil values outside
the rect won't be | 582 // pass must not set values outside of this bounds or stencil values outside
the rect won't be |
585 // cleared. | 583 // cleared. |
586 GrDrawTarget::AutoClipRestore acr(fGpu, maskSpaceIBounds); | 584 GrDrawTarget::AutoClipRestore acr(fGpu, maskSpaceIBounds); |
587 drawState->enableState(GrDrawState::kClip_StateBit); | 585 drawState->enableState(GrDrawState::kClip_StateBit); |
588 | 586 |
589 SkAutoTUnref<GrTexture> temp; | 587 SkAutoTUnref<GrTexture> temp; |
590 // walk through each clip element and perform its set op | 588 // walk through each clip element and perform its set op |
591 for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next())
{ | 589 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get()
; iter.next()) { |
592 const Element* element = iter.get(); | 590 const Element* element = iter.get(); |
593 SkRegion::Op op = element->getOp(); | 591 SkRegion::Op op = element->getOp(); |
594 bool invert = element->isInverseFilled(); | 592 bool invert = element->isInverseFilled(); |
595 | 593 |
596 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { | 594 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere
nce_Op == op) { |
597 GrPathRenderer* pr = NULL; | 595 GrPathRenderer* pr = NULL; |
598 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; | 596 bool useTemp = !this->canStencilAndDrawElement(result, element, &pr)
; |
599 GrTexture* dst; | 597 GrTexture* dst; |
600 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary | 598 // This is the bounds of the clip element in the space of the alpha-
mask. The temporary |
601 // mask buffer can be substantially larger than the actually clip st
ack element. We | 599 // mask buffer can be substantially larger than the actually clip st
ack element. We |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 } | 679 } |
682 | 680 |
683 fCurrClipMaskType = kAlpha_ClipMaskType; | 681 fCurrClipMaskType = kAlpha_ClipMaskType; |
684 return result; | 682 return result; |
685 } | 683 } |
686 | 684 |
687 //////////////////////////////////////////////////////////////////////////////// | 685 //////////////////////////////////////////////////////////////////////////////// |
688 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 686 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
689 // (as opposed to canvas) coordinates | 687 // (as opposed to canvas) coordinates |
690 bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, | 688 bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, |
691 InitialState initialState, | 689 GrReducedClip::InitialState initia
lState, |
692 const ElementList& elements, | 690 const GrReducedClip::ElementList&
elements, |
693 const SkIRect& clipSpaceIBounds, | 691 const SkIRect& clipSpaceIBounds, |
694 const SkIPoint& clipSpaceToStencil
Offset) { | 692 const SkIPoint& clipSpaceToStencil
Offset) { |
695 | 693 |
696 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 694 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
697 | 695 |
698 GrDrawState* drawState = fGpu->drawState(); | 696 GrDrawState* drawState = fGpu->drawState(); |
699 SkASSERT(drawState->isClipState()); | 697 SkASSERT(drawState->isClipState()); |
700 | 698 |
701 GrRenderTarget* rt = drawState->getRenderTarget(); | 699 GrRenderTarget* rt = drawState->getRenderTarget(); |
702 SkASSERT(rt); | 700 SkASSERT(rt); |
(...skipping 27 matching lines...) Expand all Loading... |
730 drawState->enableState(GrDrawState::kClip_StateBit); | 728 drawState->enableState(GrDrawState::kClip_StateBit); |
731 | 729 |
732 #if !VISUALIZE_COMPLEX_CLIP | 730 #if !VISUALIZE_COMPLEX_CLIP |
733 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); | 731 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); |
734 #endif | 732 #endif |
735 | 733 |
736 int clipBit = stencilBuffer->bits(); | 734 int clipBit = stencilBuffer->bits(); |
737 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil
buffers"); | 735 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil
buffers"); |
738 clipBit = (1 << (clipBit-1)); | 736 clipBit = (1 << (clipBit-1)); |
739 | 737 |
740 fGpu->clearStencilClip(rt, stencilSpaceIBounds, kAllIn_InitialState == i
nitialState); | 738 fGpu->clearStencilClip(rt, stencilSpaceIBounds, |
| 739 GrReducedClip::kAllIn_InitialState == initialStat
e); |
741 | 740 |
742 // walk through each clip element and perform its set op | 741 // walk through each clip element and perform its set op |
743 // with the existing clip. | 742 // with the existing clip. |
744 for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next(
)) { | 743 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge
t(); iter.next()) { |
745 const Element* element = iter.get(); | 744 const Element* element = iter.get(); |
746 bool fillInverted = false; | 745 bool fillInverted = false; |
747 // enabled at bottom of loop | 746 // enabled at bottom of loop |
748 drawState->disableState(GrGpu::kModifyStencilClip_StateBit); | 747 drawState->disableState(GrGpu::kModifyStencilClip_StateBit); |
749 // if the target is MSAA then we want MSAA enabled when the clip is
soft | 748 // if the target is MSAA then we want MSAA enabled when the clip is
soft |
750 if (rt->isMultisampled()) { | 749 if (rt->isMultisampled()) { |
751 drawState->setState(GrDrawState::kHWAntialias_StateBit, element-
>isAA()); | 750 drawState->setState(GrDrawState::kHWAntialias_StateBit, element-
>isAA()); |
752 } | 751 } |
753 | 752 |
754 // This will be used to determine whether the clip shape can be rend
ered into the | 753 // This will be used to determine whether the clip shape can be rend
ered into the |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1051 // the top left corner of the resulting rect to the top left of the texture. | 1050 // the top left corner of the resulting rect to the top left of the texture. |
1052 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); | 1051 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa
ceIBounds.height()); |
1053 | 1052 |
1054 GrSWMaskHelper helper(this->getContext()); | 1053 GrSWMaskHelper helper(this->getContext()); |
1055 | 1054 |
1056 SkMatrix matrix; | 1055 SkMatrix matrix; |
1057 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), | 1056 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), |
1058 SkIntToScalar(-clipSpaceIBounds.fTop)); | 1057 SkIntToScalar(-clipSpaceIBounds.fTop)); |
1059 helper.init(maskSpaceIBounds, &matrix, false); | 1058 helper.init(maskSpaceIBounds, &matrix, false); |
1060 | 1059 |
1061 helper.clear(kAllIn_InitialState == initialState ? 0xFF : 0x00); | 1060 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0
0); |
1062 | 1061 |
1063 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 1062 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
1064 | 1063 |
1065 for (ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next())
{ | 1064 for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get()
; iter.next()) { |
1066 | 1065 |
1067 const Element* element = iter.get(); | 1066 const Element* element = iter.get(); |
1068 SkRegion::Op op = element->getOp(); | 1067 SkRegion::Op op = element->getOp(); |
1069 | 1068 |
1070 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op ==
op) { | 1069 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op ==
op) { |
1071 // Intersect and reverse difference require modifying pixels outside
of the geometry | 1070 // Intersect and reverse difference require modifying pixels outside
of the geometry |
1072 // that is being "drawn". In both cases we erase all the pixels outs
ide of the geometry | 1071 // that is being "drawn". In both cases we erase all the pixels outs
ide of the geometry |
1073 // but leave the pixels inside the geometry alone. For reverse diffe
rence we invert all | 1072 // but leave the pixels inside the geometry alone. For reverse diffe
rence we invert all |
1074 // the pixels before clearing the ones outside the geometry. | 1073 // the pixels before clearing the ones outside the geometry. |
1075 if (SkRegion::kReverseDifference_Op == op) { | 1074 if (SkRegion::kReverseDifference_Op == op) { |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1136 | 1135 |
1137 // TODO: dynamically attach a stencil buffer | 1136 // TODO: dynamically attach a stencil buffer |
1138 int stencilBits = 0; | 1137 int stencilBits = 0; |
1139 GrStencilBuffer* stencilBuffer = | 1138 GrStencilBuffer* stencilBuffer = |
1140 drawState.getRenderTarget()->getStencilBuffer(); | 1139 drawState.getRenderTarget()->getStencilBuffer(); |
1141 if (stencilBuffer) { | 1140 if (stencilBuffer) { |
1142 stencilBits = stencilBuffer->bits(); | 1141 stencilBits = stencilBuffer->bits(); |
1143 this->adjustStencilParams(settings, clipMode, stencilBits); | 1142 this->adjustStencilParams(settings, clipMode, stencilBits); |
1144 } | 1143 } |
1145 } | 1144 } |
OLD | NEW |