Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: src/gpu/GrClipMaskManager.cpp

Issue 1971343002: Convert GrClip to an abstract base class (Closed) Base URL: https://skia.googlesource.com/skia.git@upload2_clipout
Patch Set: fix crash Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrClipMaskManager.h" 8 #include "GrClipMaskManager.h"
9 #include "GrCaps.h" 9 #include "GrCaps.h"
10 #include "GrDrawingManager.h" 10 #include "GrDrawingManager.h"
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 PathNeedsSWRenderer(context, 130 PathNeedsSWRenderer(context,
131 kHasUserStencilSettings, 131 kHasUserStencilSettings,
132 texture->asRenderTarget(), 132 texture->asRenderTarget(),
133 viewMatrix, 133 viewMatrix,
134 element, 134 element,
135 &pr, 135 &pr,
136 kNeedsStencil); 136 kNeedsStencil);
137 return pr; 137 return pr;
138 } 138 }
139 139
140 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget)
141 : fDrawTarget(drawTarget)
142 , fClipMode(kIgnoreClip_StencilClipMode) {
143 }
144
145 GrContext* GrClipMaskManager::getContext() { 140 GrContext* GrClipMaskManager::getContext() {
146 return fDrawTarget->cmmAccess().context(); 141 return fDrawTarget->cmmAccess().context();
147 } 142 }
148 143
149 const GrCaps* GrClipMaskManager::caps() const { 144 const GrCaps* GrClipMaskManager::caps() const {
150 return fDrawTarget->caps(); 145 return fDrawTarget->caps();
151 } 146 }
152 147
153 GrResourceProvider* GrClipMaskManager::resourceProvider() { 148 GrResourceProvider* GrClipMaskManager::resourceProvider() {
154 return fDrawTarget->cmmAccess().resourceProvider(); 149 return fDrawTarget->cmmAccess().resourceProvider();
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 for (int i = 0; i < fpCnt; ++i) { 276 for (int i = 0; i < fpCnt; ++i) {
282 fps[i]->unref(); 277 fps[i]->unref();
283 } 278 }
284 return !failed; 279 return !failed;
285 } 280 }
286 281
287 //////////////////////////////////////////////////////////////////////////////// 282 ////////////////////////////////////////////////////////////////////////////////
288 // sort out what kind of clip mask needs to be created: alpha, stencil, 283 // sort out what kind of clip mask needs to be created: alpha, stencil,
289 // scissor, or entirely software 284 // scissor, or entirely software
290 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, 285 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
291 const GrClip& clip, 286 const GrClipStackClip& clip,
292 const SkRect* devBounds, 287 const SkRect* devBounds,
293 GrAppliedClip* out) { 288 GrAppliedClip* out) {
294 if (kRespectClip_StencilClipMode == fClipMode) { 289 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) {
295 fClipMode = kIgnoreClip_StencilClipMode; 290 return true;
296 } 291 }
297 292
298 GrReducedClip::ElementList elements; 293 GrReducedClip::ElementList elements;
299 int32_t genID = 0; 294 int32_t genID = 0;
300 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e; 295 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e;
301 SkIRect clipSpaceIBounds; 296 SkIRect clipSpaceIBounds;
302 bool requiresAA = false; 297 bool requiresAA = false;
303 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); 298 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
304 299
305 // GrDrawTarget should have filtered this for us 300 // GrDrawTarget should have filtered this for us
306 SkASSERT(rt); 301 SkASSERT(rt);
307 302
308 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 303 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
309 if (clip.isWideOpen(clipSpaceRTIBounds)) { 304 clipSpaceRTIBounds.offset(clip.origin());
310 return true; 305
306 SkIRect clipSpaceReduceQueryBounds;
307 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
308 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
309 SkIRect devIBounds = devBounds->roundOut();
310 devIBounds.offset(clip.origin());
311 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds )) {
312 return false;
313 }
314 } else {
315 clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
311 } 316 }
312 317 GrReducedClip::ReduceClipStack(*clip.clipStack(),
313 // The clip mask manager always draws with a single IRect so we special case that logic here 318 clipSpaceReduceQueryBounds,
314 // Image filters just use a rect, so we also special case that logic 319 &elements,
315 switch (clip.clipType()) { 320 &genID,
316 case GrClip::kWideOpen_ClipType: 321 &initialState,
317 SkFAIL("Should have caught this with clip.isWideOpen()"); 322 &clipSpaceIBounds,
318 return true; 323 &requiresAA);
319 case GrClip::kIRect_ClipType: { 324 if (elements.isEmpty()) {
320 SkIRect scissor = clip.irect(); 325 if (GrReducedClip::kAllIn_InitialState == initialState) {
321 if (scissor.intersect(clipSpaceRTIBounds)) { 326 if (clipSpaceIBounds == clipSpaceRTIBounds) {
322 out->fScissorState.set(scissor);
323 out->fHasStencilClip = kIgnoreClip_StencilClipMode != fClipMode;
324 return true; 327 return true;
325 } 328 }
329 } else {
326 return false; 330 return false;
327 } 331 }
328 case GrClip::kClipStack_ClipType: {
329 clipSpaceRTIBounds.offset(clip.origin());
330 SkIRect clipSpaceReduceQueryBounds;
331 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
332 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
333 SkIRect devIBounds = devBounds->roundOut();
334 devIBounds.offset(clip.origin());
335 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, de vIBounds)) {
336 return false;
337 }
338 } else {
339 clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
340 }
341 GrReducedClip::ReduceClipStack(*clip.clipStack(),
342 clipSpaceReduceQueryBounds,
343 &elements,
344 &genID,
345 &initialState,
346 &clipSpaceIBounds,
347 &requiresAA);
348 if (elements.isEmpty()) {
349 if (GrReducedClip::kAllIn_InitialState == initialState) {
350 if (clipSpaceIBounds == clipSpaceRTIBounds) {
351 return true;
352 }
353 } else {
354 return false;
355 }
356 }
357 } break;
358 } 332 }
359 333
360 SkASSERT(kIgnoreClip_StencilClipMode == fClipMode); // TODO: Remove fClipMod e.
361
362 // An element count of 4 was chosen because of the common pattern in Blink o f: 334 // An element count of 4 was chosen because of the common pattern in Blink o f:
363 // isect RR 335 // isect RR
364 // diff RR 336 // diff RR
365 // isect convex_poly 337 // isect convex_poly
366 // isect convex_poly 338 // isect convex_poly
367 // when drawing rounded div borders. This could probably be tuned based on a 339 // when drawing rounded div borders. This could probably be tuned based on a
368 // configuration's relative costs of switching RTs to generate a mask vs 340 // configuration's relative costs of switching RTs to generate a mask vs
369 // longer shaders. 341 // longer shaders.
370 if (elements.count() <= kMaxAnalyticElements) { 342 if (elements.count() <= kMaxAnalyticElements) {
371 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), 343 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 elements, 417 elements,
446 clipSpaceIBounds, 418 clipSpaceIBounds,
447 clipSpaceToStencilSpaceOffset); 419 clipSpaceToStencilSpaceOffset);
448 420
449 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 421 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
450 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 422 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
451 // use both stencil and scissor test to the bounds for the final draw. 423 // use both stencil and scissor test to the bounds for the final draw.
452 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 424 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
453 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 425 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
454 out->fScissorState.set(scissorSpaceIBounds); 426 out->fScissorState.set(scissorSpaceIBounds);
455 SkASSERT(kRespectClip_StencilClipMode == fClipMode); // TODO: Remove fClipMo de.
456 out->fHasStencilClip = true; 427 out->fHasStencilClip = true;
457 return true; 428 return true;
458 } 429 }
459 430
460 static bool stencil_element(GrDrawContext* dc, 431 static bool stencil_element(GrDrawContext* dc,
461 const GrClip& clip, 432 const GrFixedClip& clip,
462 const GrUserStencilSettings* ss, 433 const GrUserStencilSettings* ss,
463 const SkMatrix& viewMatrix, 434 const SkMatrix& viewMatrix,
464 const SkClipStack::Element* element) { 435 const SkClipStack::Element* element) {
465 436
466 // TODO: Draw rrects directly here. 437 // TODO: Draw rrects directly here.
467 switch (element->getType()) { 438 switch (element->getType()) {
468 case Element::kEmpty_Type: 439 case Element::kEmpty_Type:
469 SkDEBUGFAIL("Should never get here with an empty element."); 440 SkDEBUGFAIL("Should never get here with an empty element.");
470 break; 441 break;
471 case Element::kRect_Type: 442 case Element::kRect_Type:
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 GrPathRenderer* pr = GetPathRenderer(context, 567 GrPathRenderer* pr = GetPathRenderer(context,
597 texture, translate, element); 568 texture, translate, element);
598 if (Element::kRect_Type != element->getType() && !pr) { 569 if (Element::kRect_Type != element->getType() && !pr) {
599 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would 570 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would
600 // be performed (i.e., pr would be NULL for a non-rect path). 571 // be performed (i.e., pr would be NULL for a non-rect path).
601 // See https://bug.skia.org/4519 for rationale and details. 572 // See https://bug.skia.org/4519 for rationale and details.
602 SkASSERT(0); 573 SkASSERT(0);
603 } 574 }
604 #endif 575 #endif
605 576
606 GrClip clip(maskSpaceIBounds); 577 GrFixedClip clip(maskSpaceIBounds);
607 578
608 // draw directly into the result with the stencil set to make the pi xels affected 579 // draw directly into the result with the stencil set to make the pi xels affected
609 // by the clip shape be non-zero. 580 // by the clip shape be non-zero.
610 static constexpr GrUserStencilSettings kStencilInElement( 581 static constexpr GrUserStencilSettings kStencilInElement(
611 GrUserStencilSettings::StaticInit< 582 GrUserStencilSettings::StaticInit<
612 0xffff, 583 0xffff,
613 GrUserStencilTest::kAlways, 584 GrUserStencilTest::kAlways,
614 0xffff, 585 0xffff,
615 GrUserStencilOp::kReplace, 586 GrUserStencilOp::kReplace,
616 GrUserStencilOp::kReplace, 587 GrUserStencilOp::kReplace,
(...skipping 21 matching lines...) Expand all
638 SkRect::Make(clipSpace IBounds))) { 609 SkRect::Make(clipSpace IBounds))) {
639 texture->resourcePriv().removeUniqueKey(); 610 texture->resourcePriv().removeUniqueKey();
640 return nullptr; 611 return nullptr;
641 } 612 }
642 } else { 613 } else {
643 // all the remaining ops can just be directly draw into the accumula tion buffer 614 // all the remaining ops can just be directly draw into the accumula tion buffer
644 GrPaint paint; 615 GrPaint paint;
645 paint.setAntiAlias(element->isAA()); 616 paint.setAntiAlias(element->isAA());
646 paint.setCoverageSetOpXPFactory(op, false); 617 paint.setCoverageSetOpXPFactory(op, false);
647 618
648 draw_element(dc.get(), GrClip::WideOpen(), paint, translate, element ); 619 draw_element(dc.get(), GrNoClip(), paint, translate, element);
649 } 620 }
650 } 621 }
651 622
652 return texture.release(); 623 return texture.release();
653 } 624 }
654 625
655 //////////////////////////////////////////////////////////////////////////////// 626 ////////////////////////////////////////////////////////////////////////////////
656 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 627 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
657 // (as opposed to canvas) coordinates 628 // (as opposed to canvas) coordinates
658 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt, 629 bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
(...skipping 15 matching lines...) Expand all
674 SkVector translate = { 645 SkVector translate = {
675 SkIntToScalar(clipSpaceToStencilOffset.fX), 646 SkIntToScalar(clipSpaceToStencilOffset.fX),
676 SkIntToScalar(clipSpaceToStencilOffset.fY) 647 SkIntToScalar(clipSpaceToStencilOffset.fY)
677 }; 648 };
678 SkMatrix viewMatrix; 649 SkMatrix viewMatrix;
679 viewMatrix.setTranslate(translate); 650 viewMatrix.setTranslate(translate);
680 651
681 // We set the current clip to the bounds so that our recursive draws are scissored to them. 652 // We set the current clip to the bounds so that our recursive draws are scissored to them.
682 SkIRect stencilSpaceIBounds(clipSpaceIBounds); 653 SkIRect stencilSpaceIBounds(clipSpaceIBounds);
683 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 654 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
684 GrClip clip(stencilSpaceIBounds); 655 GrFixedClip clip(stencilSpaceIBounds);
685 656
686 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, 657 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
687 GrReducedClip::kAllIn_InitialState == initialState, rt); 658 GrReducedClip::kAllIn_InitialState == initialState, rt);
688 659
689 // walk through each clip element and perform its set op 660 // walk through each clip element and perform its set op
690 // with the existing clip. 661 // with the existing clip.
691 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 662 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
692 const Element* element = iter.get(); 663 const Element* element = iter.get();
693 664
694 GrPipelineBuilder pipelineBuilder; 665 GrPipelineBuilder pipelineBuilder;
695 pipelineBuilder.setRenderTarget(rt); 666 pipelineBuilder.setRenderTarget(rt);
696 667
697 pipelineBuilder.setDisableColorXPFactory(); 668 pipelineBuilder.setDisableColorXPFactory();
698 669
699 // if the target is MSAA then we want MSAA enabled when the clip is soft 670 // if the target is MSAA then we want MSAA enabled when the clip is soft
700 if (rt->isStencilBufferMultisampled()) { 671 if (rt->isStencilBufferMultisampled()) {
701 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, e lement->isAA()); 672 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, e lement->isAA());
702 } 673 }
703 674
704 bool fillInverted = false; 675 bool fillInverted = false;
705 // enabled at bottom of loop 676 // enabled at bottom of loop
706 fClipMode = kIgnoreClip_StencilClipMode; 677 clip.enableStencilClip(false);
707 678
708 // This will be used to determine whether the clip shape can be rend ered into the 679 // This will be used to determine whether the clip shape can be rend ered into the
709 // stencil with arbitrary stencil settings. 680 // stencil with arbitrary stencil settings.
710 GrPathRenderer::StencilSupport stencilSupport; 681 GrPathRenderer::StencilSupport stencilSupport;
711 682
712 SkRegion::Op op = element->getOp(); 683 SkRegion::Op op = element->getOp();
713 684
714 GrPathRenderer* pr = nullptr; 685 GrPathRenderer* pr = nullptr;
715 SkPath clipPath; 686 SkPath clipPath;
716 if (Element::kRect_Type == element->getType()) { 687 if (Element::kRect_Type == element->getType()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 args.fViewMatrix = &viewMatrix; 765 args.fViewMatrix = &viewMatrix;
795 args.fPath = &clipPath; 766 args.fPath = &clipPath;
796 pr->stencilPath(args); 767 pr->stencilPath(args);
797 } 768 }
798 } 769 }
799 } 770 }
800 } 771 }
801 772
802 // now we modify the clip bit by rendering either the clip 773 // now we modify the clip bit by rendering either the clip
803 // element directly or a bounding rect of the entire clip. 774 // element directly or a bounding rect of the entire clip.
804 fClipMode = kModifyClip_StencilClipMode; 775 clip.enableStencilClip(true);
805 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) { 776 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) {
806 pipelineBuilder.setUserStencil(*pass); 777 pipelineBuilder.setUserStencil(*pass);
807 778
808 if (drawDirectToClip) { 779 if (drawDirectToClip) {
809 if (Element::kRect_Type == element->getType()) { 780 if (Element::kRect_Type == element->getType()) {
810 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrC olor_WHITE, 781 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrC olor_WHITE,
811 viewMatrix, element->getRect()); 782 viewMatrix, element->getRect());
812 } else { 783 } else {
813 GrPathRenderer::DrawPathArgs args; 784 GrPathRenderer::DrawPathArgs args;
814 args.fTarget = fDrawTarget; 785 args.fTarget = fDrawTarget;
(...skipping 10 matching lines...) Expand all
825 } 796 }
826 } else { 797 } else {
827 // The view matrix is setup to do clip space -> stencil spac e translation, so 798 // The view matrix is setup to do clip space -> stencil spac e translation, so
828 // draw rect in clip space. 799 // draw rect in clip space.
829 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor _WHITE, viewMatrix, 800 draw_non_aa_rect(fDrawTarget, pipelineBuilder, clip, GrColor _WHITE, viewMatrix,
830 SkRect::Make(clipSpaceIBounds)); 801 SkRect::Make(clipSpaceIBounds));
831 } 802 }
832 } 803 }
833 } 804 }
834 } 805 }
835 fClipMode = kRespectClip_StencilClipMode;
836 return true; 806 return true;
837 } 807 }
838 808
839 //////////////////////////////////////////////////////////////////////////////// 809 ////////////////////////////////////////////////////////////////////////////////
840 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context, 810 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
841 int32_t elementsGenID, 811 int32_t elementsGenID,
842 GrReducedClip::InitialState initialState, 812 GrReducedClip::InitialState initialState,
843 const GrReducedClip::Elemen tList& elements, 813 const GrReducedClip::Elemen tList& elements,
844 const SkVector& clipToMaskO ffset, 814 const SkVector& clipToMaskO ffset,
845 const SkIRect& clipSpaceIBo unds) { 815 const SkIRect& clipSpaceIBo unds) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 ); 876 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 );
907 if (!result) { 877 if (!result) {
908 return nullptr; 878 return nullptr;
909 } 879 }
910 result->resourcePriv().setUniqueKey(key); 880 result->resourcePriv().setUniqueKey(key);
911 881
912 helper.toTexture(result); 882 helper.toTexture(result);
913 883
914 return result; 884 return result;
915 } 885 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698