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

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

Issue 2312173002: Revert of Improve usage of window rectangles (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_drawsinreducedclip
Patch Set: Created 4 years, 3 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/GrReducedClip.h ('k') | src/gpu/GrRenderTarget.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 2016 Google Inc. 2 * Copyright 2016 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 "GrReducedClip.h" 8 #include "GrReducedClip.h"
9 9
10 #include "GrAppliedClip.h" 10 #include "GrAppliedClip.h"
(...skipping 10 matching lines...) Expand all
21 21
22 typedef SkClipStack::Element Element; 22 typedef SkClipStack::Element Element;
23 23
24 /** 24 /**
25 * There are plenty of optimizations that could be added here. Maybe flips could be folded into 25 * There are plenty of optimizations that could be added here. Maybe flips could be folded into
26 * earlier operations. Or would inserting flips and reversing earlier ops ever b e a win? Perhaps 26 * earlier operations. Or would inserting flips and reversing earlier ops ever b e a win? Perhaps
27 * for the case where the bounds are kInsideOut_BoundsType. We could restrict ea rlier operations 27 * for the case where the bounds are kInsideOut_BoundsType. We could restrict ea rlier operations
28 * based on later intersect operations, and perhaps remove intersect-rects. We c ould optionally 28 * based on later intersect operations, and perhaps remove intersect-rects. We c ould optionally
29 * take a rect in case the caller knows a bound on what is to be drawn through t his clip. 29 * take a rect in case the caller knows a bound on what is to be drawn through t his clip.
30 */ 30 */
31 GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds , 31 GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds ) {
32 int maxWindowRectangles) {
33 SkASSERT(!queryBounds.isEmpty()); 32 SkASSERT(!queryBounds.isEmpty());
34 fHasIBounds = false; 33 fHasIBounds = false;
35 34
36 if (stack.isWideOpen()) { 35 if (stack.isWideOpen()) {
37 fInitialState = InitialState::kAllIn; 36 fInitialState = InitialState::kAllIn;
38 return; 37 return;
39 } 38 }
40 39
41 SkClipStack::BoundsType stackBoundsType; 40 SkClipStack::BoundsType stackBoundsType;
42 SkRect stackBounds; 41 SkRect stackBounds;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 // clip will be enforced by the scissor through fIBounds.) 87 // clip will be enforced by the scissor through fIBounds.)
89 SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds ))); 88 SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds )));
90 } 89 }
91 90
92 fIBounds = GrClip::GetPixelIBounds(tighterQuery); 91 fIBounds = GrClip::GetPixelIBounds(tighterQuery);
93 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid eClip above. 92 SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsid eClip above.
94 fHasIBounds = true; 93 fHasIBounds = true;
95 94
96 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the 95 // Now that we have determined the bounds to use and filtered out the trivia l cases, call the
97 // helper that actually walks the stack. 96 // helper that actually walks the stack.
98 this->walkStack(stack, tighterQuery, maxWindowRectangles); 97 this->walkStack(stack, tighterQuery);
99
100 if (fWindowRects.count() < maxWindowRectangles) {
101 this->addInteriorWindowRectangles(maxWindowRectangles);
102 }
103 } 98 }
104 99
105 void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBound s, 100 void GrReducedClip::walkStack(const SkClipStack& stack, const SkRect& queryBound s) {
106 int maxWindowRectangles) {
107 // walk backwards until we get to: 101 // walk backwards until we get to:
108 // a) the beginning 102 // a) the beginning
109 // b) an operation that is known to make the bounds all inside/outside 103 // b) an operation that is known to make the bounds all inside/outside
110 // c) a replace operation 104 // c) a replace operation
111 105
112 enum class InitialTriState { 106 enum class InitialTriState {
113 kUnknown = -1, 107 kUnknown = -1,
114 kAllIn = (int)GrReducedClip::InitialState::kAllIn, 108 kAllIn = (int)GrReducedClip::InitialState::kAllIn,
115 kAllOut = (int)GrReducedClip::InitialState::kAllOut 109 kAllOut = (int)GrReducedClip::InitialState::kAllOut
116 } initialTriState = InitialTriState::kUnknown; 110 } initialTriState = InitialTriState::kUnknown;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 149 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
156 initialTriState = InitialTriState::kAllOut; 150 initialTriState = InitialTriState::kAllOut;
157 skippable = true; 151 skippable = true;
158 } 152 }
159 } else { 153 } else {
160 if (element->contains(relaxedQueryBounds)) { 154 if (element->contains(relaxedQueryBounds)) {
161 initialTriState = InitialTriState::kAllOut; 155 initialTriState = InitialTriState::kAllOut;
162 skippable = true; 156 skippable = true;
163 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) { 157 } else if (GrClip::IsOutsideClip(element->getBounds(), query Bounds)) {
164 skippable = true; 158 skippable = true;
165 } else if (fWindowRects.count() < maxWindowRectangles && !em biggens &&
166 !element->isAA() && Element::kRect_Type == elemen t->getType()) {
167 this->addWindowRectangle(element->getRect(), false);
168 skippable = true;
169 } 159 }
170 } 160 }
171 if (!skippable) { 161 if (!skippable) {
172 emsmallens = true; 162 emsmallens = true;
173 } 163 }
174 break; 164 break;
175 case SkRegion::kIntersect_Op: 165 case SkRegion::kIntersect_Op:
176 // check if the shape intersected contains the entire bounds and therefore can 166 // check if the shape intersected contains the entire bounds and therefore can
177 // be skipped or it is outside the entire bounds and therefore m akes the clip 167 // be skipped or it is outside the entire bounds and therefore m akes the clip
178 // empty. 168 // empty.
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 element = fElements.headIter().get(); 413 element = fElements.headIter().get();
424 } 414 }
425 } 415 }
426 } 416 }
427 fRequiresAA = numAAElements > 0; 417 fRequiresAA = numAAElements > 0;
428 418
429 SkASSERT(InitialTriState::kUnknown != initialTriState); 419 SkASSERT(InitialTriState::kUnknown != initialTriState);
430 fInitialState = static_cast<GrReducedClip::InitialState>(initialTriState); 420 fInitialState = static_cast<GrReducedClip::InitialState>(initialTriState);
431 } 421 }
432 422
433 static bool element_is_pure_subtract(SkRegion::Op op) {
434 SkASSERT(op >= 0);
435 return op <= SkRegion::kIntersect_Op;
436
437 GR_STATIC_ASSERT(0 == SkRegion::kDifference_Op);
438 GR_STATIC_ASSERT(1 == SkRegion::kIntersect_Op);
439 }
440
441 void GrReducedClip::addInteriorWindowRectangles(int maxWindowRectangles) {
442 SkASSERT(fWindowRects.count() < maxWindowRectangles);
443 // Walk backwards through the element list and add window rectangles to the interiors of
444 // "difference" elements. Quit if we encounter an element that may grow the clip.
445 ElementList::Iter iter(fElements, ElementList::Iter::kTail_IterStart);
446 for (; iter.get() && element_is_pure_subtract(iter.get()->getOp()); iter.pre v()) {
447 const Element* element = iter.get();
448 if (SkRegion::kDifference_Op != element->getOp()) {
449 continue;
450 }
451
452 if (Element::kRect_Type == element->getType()) {
453 SkASSERT(element->isAA());
454 this->addWindowRectangle(element->getRect(), true);
455 if (fWindowRects.count() >= maxWindowRectangles) {
456 return;
457 }
458 continue;
459 }
460
461 if (Element::kRRect_Type == element->getType()) {
462 // For round rects we add two overlapping windows in the shape of a plus.
463 const SkRRect& clipRRect = element->getRRect();
464 SkVector insetTL = clipRRect.radii(SkRRect::kUpperLeft_Corner);
465 SkVector insetBR = clipRRect.radii(SkRRect::kLowerRight_Corner);
466 if (SkRRect::kComplex_Type == clipRRect.getType()) {
467 const SkVector& insetTR = clipRRect.radii(SkRRect::kUpperRight_C orner);
468 const SkVector& insetBL = clipRRect.radii(SkRRect::kLowerLeft_Co rner);
469 insetTL.fX = SkTMax(insetTL.x(), insetBL.x());
470 insetTL.fY = SkTMax(insetTL.y(), insetTR.y());
471 insetBR.fX = SkTMax(insetBR.x(), insetTR.x());
472 insetBR.fY = SkTMax(insetBR.y(), insetBL.y());
473 }
474 const SkRect& bounds = clipRRect.getBounds();
475 if (insetTL.x() + insetBR.x() >= bounds.width() ||
476 insetTL.y() + insetBR.y() >= bounds.height()) {
477 continue; // The interior "plus" is empty.
478 }
479
480 SkRect horzRect = SkRect::MakeLTRB(bounds.left(), bounds.top() + ins etTL.y(),
481 bounds.right(), bounds.bottom() - insetBR.y());
482 this->addWindowRectangle(horzRect, element->isAA());
483 if (fWindowRects.count() >= maxWindowRectangles) {
484 return;
485 }
486
487 SkRect vertRect = SkRect::MakeLTRB(bounds.left() + insetTL.x(), boun ds.top(),
488 bounds.right() - insetBR.x(), bou nds.bottom());
489 this->addWindowRectangle(vertRect, element->isAA());
490 if (fWindowRects.count() >= maxWindowRectangles) {
491 return;
492 }
493 continue;
494 }
495 }
496 }
497
498 inline void GrReducedClip::addWindowRectangle(const SkRect& elementInteriorRect, bool elementIsAA) {
499 SkIRect* window = &fWindowRects.addWindow();
500 if (!elementIsAA) {
501 elementInteriorRect.round(window);
502 } else {
503 elementInteriorRect.roundIn(window);
504 }
505 }
506
507 inline bool GrReducedClip::intersectIBounds(const SkIRect& irect) { 423 inline bool GrReducedClip::intersectIBounds(const SkIRect& irect) {
508 SkASSERT(fHasIBounds); 424 SkASSERT(fHasIBounds);
509 if (!fIBounds.intersect(irect)) { 425 if (!fIBounds.intersect(irect)) {
510 fHasIBounds = false; 426 fHasIBounds = false;
511 fWindowRects.reset();
512 fElements.reset(); 427 fElements.reset();
513 fRequiresAA = false; 428 fRequiresAA = false;
514 fInitialState = InitialState::kAllOut; 429 fInitialState = InitialState::kAllOut;
515 return false; 430 return false;
516 } 431 }
517 return true; 432 return true;
518 } 433 }
519 434
520 //////////////////////////////////////////////////////////////////////////////// 435 ////////////////////////////////////////////////////////////////////////////////
521 // Create a 8-bit clip mask in alpha 436 // Create a 8-bit clip mask in alpha
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 break; 496 break;
582 } 497 }
583 } 498 }
584 } 499 }
585 500
586 bool GrReducedClip::drawAlphaClipMask(GrDrawContext* dc) const { 501 bool GrReducedClip::drawAlphaClipMask(GrDrawContext* dc) const {
587 // The texture may be larger than necessary, this rect represents the part o f the texture 502 // The texture may be larger than necessary, this rect represents the part o f the texture
588 // we populate with a rasterization of the clip. 503 // we populate with a rasterization of the clip.
589 GrFixedClip clip(SkIRect::MakeWH(fIBounds.width(), fIBounds.height())); 504 GrFixedClip clip(SkIRect::MakeWH(fIBounds.width(), fIBounds.height()));
590 505
591 if (!fWindowRects.empty()) {
592 clip.setWindowRectangles(fWindowRects, {fIBounds.left(), fIBounds.top()} ,
593 GrWindowRectsState::Mode::kExclusive);
594 }
595
596 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 506 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
597 // clear the part that we care about. 507 // clear the part that we care about.
598 GrColor initialCoverage = InitialState::kAllIn == this->initialState() ? -1 : 0; 508 GrColor initialCoverage = InitialState::kAllIn == this->initialState() ? -1 : 0;
599 dc->drawContextPriv().clear(clip, initialCoverage, true); 509 dc->drawContextPriv().clear(clip, initialCoverage, true);
600 510
601 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip space. 511 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip space.
602 SkMatrix translate; 512 SkMatrix translate;
603 translate.setTranslate(SkIntToScalar(-fIBounds.left()), SkIntToScalar(-fIBou nds.top())); 513 translate.setTranslate(SkIntToScalar(-fIBounds.left()), SkIntToScalar(-fIBou nds.top()));
604 514
605 // walk through each clip element and perform its set op 515 // walk through each clip element and perform its set op
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 } 563 }
654 564
655 //////////////////////////////////////////////////////////////////////////////// 565 ////////////////////////////////////////////////////////////////////////////////
656 // Create a 1-bit clip mask in the stencil buffer. 566 // Create a 1-bit clip mask in the stencil buffer.
657 567
658 class StencilClip final : public GrClip { 568 class StencilClip final : public GrClip {
659 public: 569 public:
660 StencilClip(const SkIRect& scissorRect) : fFixedClip(scissorRect) {} 570 StencilClip(const SkIRect& scissorRect) : fFixedClip(scissorRect) {}
661 const GrFixedClip& fixedClip() const { return fFixedClip; } 571 const GrFixedClip& fixedClip() const { return fFixedClip; }
662 572
663 void setWindowRectangles(const GrWindowRectangles& windows, const SkIPoint& origin,
664 GrWindowRectsState::Mode mode) {
665 fFixedClip.setWindowRectangles(windows, origin, mode);
666 }
667
668 private: 573 private:
669 bool quickContains(const SkRect&) const override { 574 bool quickContains(const SkRect&) const final {
670 return false; 575 return false;
671 } 576 }
672 void getConservativeBounds(int width, int height, SkIRect* bounds, bool* iio r) const override { 577 void getConservativeBounds(int width, int height, SkIRect* devResult, bool* iior) const final {
673 fFixedClip.getConservativeBounds(width, height, bounds, iior); 578 fFixedClip.getConservativeBounds(width, height, devResult, iior);
674 } 579 }
675 bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const override { 580 bool isRRect(const SkRect& rtBounds, SkRRect* rr, bool* aa) const final {
676 return false; 581 return false;
677 } 582 }
678 bool apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA, 583 bool apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA,
679 bool hasUserStencilSettings, GrAppliedClip* out) const override { 584 bool hasUserStencilSettings, GrAppliedClip* out) const final {
680 if (!fFixedClip.apply(context, drawContext, useHWAA, hasUserStencilSetti ngs, out)) { 585 if (!fFixedClip.apply(context, drawContext, useHWAA, hasUserStencilSetti ngs, out)) {
681 return false; 586 return false;
682 } 587 }
683 out->addStencilClip(); 588 out->addStencilClip();
684 return true; 589 return true;
685 } 590 }
686 591
687 GrFixedClip fFixedClip; 592 GrFixedClip fFixedClip;
688 593
689 typedef GrClip INHERITED; 594 typedef GrClip INHERITED;
690 }; 595 };
691 596
692 bool GrReducedClip::drawStencilClipMask(GrContext* context, 597 bool GrReducedClip::drawStencilClipMask(GrContext* context,
693 GrDrawContext* drawContext, 598 GrDrawContext* drawContext,
694 const SkIPoint& clipOrigin) const { 599 const SkIPoint& clipOrigin) const {
695 // We set the current clip to the bounds so that our recursive draws are sci ssored to them. 600 // We set the current clip to the bounds so that our recursive draws are sci ssored to them.
696 StencilClip stencilClip(fIBounds.makeOffset(-clipOrigin.x(), -clipOrigin.y() )); 601 StencilClip stencilClip(fIBounds.makeOffset(-clipOrigin.x(), -clipOrigin.y() ));
697 602
698 if (!fWindowRects.empty()) {
699 stencilClip.setWindowRectangles(fWindowRects, clipOrigin,
700 GrWindowRectsState::Mode::kExclusive);
701 }
702
703 bool initialState = InitialState::kAllIn == this->initialState(); 603 bool initialState = InitialState::kAllIn == this->initialState();
704 drawContext->drawContextPriv().clearStencilClip(stencilClip.fixedClip(), ini tialState); 604 drawContext->drawContextPriv().clearStencilClip(stencilClip.fixedClip(), ini tialState);
705 605
706 // Set the matrix so that rendered clip elements are transformed from clip t o stencil space. 606 // Set the matrix so that rendered clip elements are transformed from clip t o stencil space.
707 SkMatrix viewMatrix; 607 SkMatrix viewMatrix;
708 viewMatrix.setTranslate(SkIntToScalar(-clipOrigin.x()), SkIntToScalar(-clipO rigin.y())); 608 viewMatrix.setTranslate(SkIntToScalar(-clipOrigin.x()), SkIntToScalar(-clipO rigin.y()));
709 609
710 // walk through each clip element and perform its set op 610 // walk through each clip element and perform its set op
711 // with the existing clip. 611 // with the existing clip.
712 for (ElementList::Iter iter(fElements); iter.get(); iter.next()) { 612 for (ElementList::Iter iter(fElements); iter.get(); iter.next()) {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 // The view matrix is setup to do clip space -> stencil space tr anslation, so 737 // The view matrix is setup to do clip space -> stencil space tr anslation, so
838 // draw rect in clip space. 738 // draw rect in clip space.
839 drawContext->drawContextPriv().stencilRect(stencilClip, *pass, 739 drawContext->drawContextPriv().stencilRect(stencilClip, *pass,
840 false, viewMatrix, 740 false, viewMatrix,
841 SkRect::Make(fIBounds )); 741 SkRect::Make(fIBounds ));
842 } 742 }
843 } 743 }
844 } 744 }
845 return true; 745 return true;
846 } 746 }
OLDNEW
« no previous file with comments | « src/gpu/GrReducedClip.h ('k') | src/gpu/GrRenderTarget.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698