diff options
author | Chris Dalton <csmartdalton@google.com> | 2017-10-27 01:50:57 -0600 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-27 19:16:44 +0000 |
commit | 7947193c319bced2ef557971550e196adbe60966 (patch) | |
tree | 82f94198c9ce7a0c74363bbc478a3920c0fc50c0 /src/gpu/GrReducedClip.h | |
parent | 75e98c14e91cd94a2ac5751c39ff9b7e1dff1c20 (diff) |
Merge clip rects in GrReducedClip
Merges the intersection of all rect clips into a single clip rect
element. This is also the first step toward better handling of the
subtractive elements.
Bug: skia:
Change-Id: I36bd9c256874917adb68f43e8faddc609e65f37a
Reviewed-on: https://skia-review.googlesource.com/64380
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'src/gpu/GrReducedClip.h')
-rw-r--r-- | src/gpu/GrReducedClip.h | 77 |
1 files changed, 50 insertions, 27 deletions
diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h index c9cce361ec..0746439ba3 100644 --- a/src/gpu/GrReducedClip.h +++ b/src/gpu/GrReducedClip.h @@ -21,47 +21,54 @@ class GrRenderTargetContext; */ class SK_API GrReducedClip { public: + using Element = SkClipStack::Element; + using ElementList = SkTLList<SkClipStack::Element, 16>; + GrReducedClip(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles = 0); /** - * If hasIBounds() is true, this is the bounding box within which the clip elements are valid. - * The caller must not modify any pixels outside this box. Undefined if hasIBounds() is false. + * If hasScissor() is true, the clip mask is not valid outside this rect and the caller must + * enforce this scissor during draw. */ - const SkIRect& ibounds() const { SkASSERT(fHasIBounds); return fIBounds; } - int left() const { return this->ibounds().left(); } - int top() const { return this->ibounds().top(); } - int width() const { return this->ibounds().width(); } - int height() const { return this->ibounds().height(); } + const SkIRect& scissor() const { SkASSERT(fHasScissor); return fScissor; } + int left() const { return this->scissor().left(); } + int top() const { return this->scissor().top(); } + int width() const { return this->scissor().width(); } + int height() const { return this->scissor().height(); } /** - * Indicates whether ibounds() are defined. They will always be defined if the elements() are + * Indicates whether scissor() is defined. It will always be defined if the maskElements() are * nonempty. */ - bool hasIBounds() const { return fHasIBounds; } + bool hasScissor() const { return fHasScissor; } /** - * If nonempty, this is a set of "exclusive" windows within which the clip elements are NOT - * valid. The caller must not modify any pixels inside these windows. + * If nonempty, the clip mask is not valid inside these windows and the caller must clip them + * out using the window rectangles GPU extension. */ const GrWindowRectangles& windowRectangles() const { return fWindowRects; } - typedef SkTLList<SkClipStack::Element, 16> ElementList; - /** - * Populated with a minimal list of elements required to fully implement the clip. + * An ordered list of clip elements that could not be skipped or implemented by other means. If + * nonempty, the caller must create an alpha and/or stencil mask for these elements and apply it + * during draw. */ - const ElementList& elements() const { return fElements; } + const ElementList& maskElements() const { return fMaskElements; } /** - * If elements() are nonempty, uniquely identifies the list of elements within ibounds(). - * Otherwise undefined. + * If maskElements() are nonempty, uniquely identifies the region of the clip mask that falls + * inside of scissor(). + * NOTE: since clip elements might fall outside the query bounds, different regions of the same + * clip stack might have more or less restrictive IDs. + * FIXME: this prevents us from reusing a sub-rect of a perfectly good mask when that rect has + * been assigned a less restrictive ID. */ - uint32_t elementsGenID() const { SkASSERT(!fElements.isEmpty()); return fElementsGenID; } + uint32_t maskGenID() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskGenID; } /** - * Indicates whether antialiasing is required to process any of the clip elements. + * Indicates whether antialiasing is required to process any of the mask elements. */ - bool requiresAA() const { return fRequiresAA; } + bool maskRequiresAA() const { SkASSERT(!fMaskElements.isEmpty()); return fMaskRequiresAA; } enum class InitialState : bool { kAllIn, @@ -75,16 +82,32 @@ public: private: void walkStack(const SkClipStack&, const SkRect& queryBounds, int maxWindowRectangles); - void addInteriorWindowRectangles(int maxWindowRectangles); + + enum class ClipResult { + kNotClipped, + kClipped, + kMadeEmpty + }; + + // Clips the the given element's interior out of the final clip. + // NOTE: do not call for elements followed by ops that can grow the clip. + ClipResult clipInsideElement(const Element* element); + + // Clips the the given element's exterior out of the final clip. + // NOTE: do not call for elements followed by ops that can grow the clip. + ClipResult clipOutsideElement(const Element* element, int maxWindowRectangles); + void addWindowRectangle(const SkRect& elementInteriorRect, bool elementIsAA); - bool intersectIBounds(const SkIRect&); + void makeEmpty(); - SkIRect fIBounds; - bool fHasIBounds; + SkIRect fScissor; + bool fHasScissor; + SkRect fAAClipRect; + uint32_t fAAClipRectGenID; // GenID the mask will have if includes the AA clip rect. GrWindowRectangles fWindowRects; - ElementList fElements; - uint32_t fElementsGenID; - bool fRequiresAA; + ElementList fMaskElements; + uint32_t fMaskGenID; + bool fMaskRequiresAA; InitialState fInitialState; }; |