• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef GrScissorState_DEFINED
9 #define GrScissorState_DEFINED
10 
11 #include "include/core/SkRect.h"
12 
13 /**
14  * The scissor state is stored as the scissor rectangle and the backing store bounds of the render
15  * target that the scissor will apply to. If the render target is approximate fit and the padded
16  * content should not be modified, the clip should apply the render target context's logical bounds
17  * as part of the scissor (e.g. when stenciling). This puts the onus on the render target context
18  * to intentionally discard the scissor at its logical bounds when drawing into the padded content
19  * is acceptable (e.g. color-only updates).
20  */
21 class GrScissorState {
22 public:
23     // The disabled scissor state for a render target of the given size.
GrScissorState(const SkISize & rtDims)24     explicit GrScissorState(const SkISize& rtDims)
25             : fRTSize(rtDims)
26             , fRect(SkIRect::MakeSize(rtDims)) {}
27 
setDisabled()28     void setDisabled() { fRect = SkIRect::MakeSize(fRTSize); }
set(const SkIRect & rect)29     bool set(const SkIRect& rect) {
30         this->setDisabled();
31         return this->intersect(rect);
32     }
33 
intersect(const SkIRect & rect)34     bool SK_WARN_UNUSED_RESULT intersect(const SkIRect& rect) {
35         if (!fRect.intersect(rect)) {
36             fRect.setEmpty();
37             return false;
38         } else {
39             return true;
40         }
41     }
42 
43     // If the scissor was configured for the backing store dimensions and it's acceptable to
44     // draw outside the logical dimensions of the target, this will discard the scissor test if
45     // the test wouldn't modify the logical dimensions.
relaxTest(const SkISize & logicalDimensions)46     bool relaxTest(const SkISize& logicalDimensions) {
47         SkASSERT(logicalDimensions.fWidth <= fRTSize.fWidth &&
48                  logicalDimensions.fHeight <= fRTSize.fHeight);
49         if (fRect.fLeft == 0 && fRect.fTop == 0 && fRect.fRight >= logicalDimensions.fWidth &&
50             fRect.fBottom >= logicalDimensions.fHeight) {
51             this->setDisabled();
52             return true;
53         } else {
54             return false;
55         }
56     }
57 
58     bool operator==(const GrScissorState& other) const {
59         return fRTSize == other.fRTSize && fRect == other.fRect;
60     }
61     bool operator!=(const GrScissorState& other) const { return !(*this == other); }
62 
enabled()63     bool enabled() const {
64         SkASSERT(fRect.isEmpty() || SkIRect::MakeSize(fRTSize).contains(fRect));
65         // This is equivalent to a strict contains check on SkIRect::MakeSize(rtSize) w/o creating
66         // the render target bounding rectangle.
67         return fRect.fLeft > 0 || fRect.fTop > 0 ||
68                fRect.fRight < fRTSize.fWidth || fRect.fBottom < fRTSize.fHeight;
69     }
70 
71     // Will always be equal to or contained in the rt bounds, or empty if scissor rectangles were
72     // added that did not intersect with the render target or prior scissor.
rect()73     const SkIRect& rect() const {
74         SkASSERT(fRect.isEmpty() || SkIRect::MakeSize(fRTSize).contains(fRect));
75         return fRect;
76     }
77 
78 private:
79     // The scissor is considered enabled if the rectangle does not cover the render target
80     SkISize fRTSize;
81     SkIRect fRect;
82 };
83 
84 #endif
85