Home | History | Annotate | Download | only in gpu
      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 GrAppliedClip_DEFINED
      9 #define GrAppliedClip_DEFINED
     10 
     11 #include "GrFragmentProcessor.h"
     12 #include "GrScissorState.h"
     13 #include "GrWindowRectsState.h"
     14 
     15 #include "SkClipStack.h"
     16 
     17 
     18 /**
     19  * Produced by GrHardClip. It provides a set of modifications to the hardware drawing state that
     20  * implement the clip.
     21  */
     22 class GrAppliedHardClip {
     23 public:
     24     GrAppliedHardClip() = default;
     25     GrAppliedHardClip(GrAppliedHardClip&& that) = default;
     26     GrAppliedHardClip(const GrAppliedHardClip&) = delete;
     27 
     28     const GrScissorState& scissorState() const { return fScissorState; }
     29     const GrWindowRectsState& windowRectsState() const { return fWindowRectsState; }
     30     uint32_t stencilStackID() const { return fStencilStackID; }
     31     bool hasStencilClip() const { return SkClipStack::kInvalidGenID != fStencilStackID; }
     32 
     33     /**
     34      * Intersects the applied clip with the provided rect. Returns false if the draw became empty.
     35      * 'clippedDrawBounds' will be intersected with 'irect'. This returns false if the clip becomes
     36      * empty or the draw no longer intersects the clip. In either case the draw can be skipped.
     37      */
     38     bool addScissor(const SkIRect& irect, SkRect* clippedDrawBounds) {
     39         return fScissorState.intersect(irect) && clippedDrawBounds->intersect(SkRect::Make(irect));
     40     }
     41 
     42     void addWindowRectangles(const GrWindowRectsState& windowState) {
     43         SkASSERT(!fWindowRectsState.enabled());
     44         fWindowRectsState = windowState;
     45     }
     46 
     47     void addWindowRectangles(const GrWindowRectangles& windows, GrWindowRectsState::Mode mode) {
     48         SkASSERT(!fWindowRectsState.enabled());
     49         fWindowRectsState.set(windows, mode);
     50     }
     51 
     52     void addStencilClip(uint32_t stencilStackID) {
     53         SkASSERT(SkClipStack::kInvalidGenID == fStencilStackID);
     54         fStencilStackID = stencilStackID;
     55     }
     56 
     57     bool doesClip() const {
     58         return fScissorState.enabled() || this->hasStencilClip() || fWindowRectsState.enabled();
     59     }
     60 
     61     bool operator==(const GrAppliedHardClip& that) const {
     62         return fScissorState == that.fScissorState &&
     63                fWindowRectsState == that.fWindowRectsState &&
     64                fStencilStackID == that.fStencilStackID;
     65     }
     66     bool operator!=(const GrAppliedHardClip& that) const { return !(*this == that); }
     67 
     68 private:
     69     GrScissorState             fScissorState;
     70     GrWindowRectsState         fWindowRectsState;
     71     uint32_t                   fStencilStackID = SkClipStack::kInvalidGenID;
     72 };
     73 
     74 /**
     75  * Produced by GrClip. It provides a set of modifications to GrPipeline that implement the clip.
     76  */
     77 class GrAppliedClip {
     78 public:
     79     GrAppliedClip() = default;
     80     GrAppliedClip(GrAppliedClip&& that) = default;
     81     GrAppliedClip(const GrAppliedClip&) = delete;
     82 
     83     const GrScissorState& scissorState() const { return fHardClip.scissorState(); }
     84     const GrWindowRectsState& windowRectsState() const { return fHardClip.windowRectsState(); }
     85     uint32_t stencilStackID() const { return fHardClip.stencilStackID(); }
     86     bool hasStencilClip() const { return fHardClip.hasStencilClip(); }
     87     int numClipCoverageFragmentProcessors() const { return fClipCoverageFPs.count(); }
     88     const GrFragmentProcessor* clipCoverageFragmentProcessor(int i) const {
     89         SkASSERT(fClipCoverageFPs[i]);
     90         return fClipCoverageFPs[i].get();
     91     }
     92     std::unique_ptr<const GrFragmentProcessor> detachClipCoverageFragmentProcessor(int i) {
     93         SkASSERT(fClipCoverageFPs[i]);
     94         return std::move(fClipCoverageFPs[i]);
     95     }
     96 
     97     GrAppliedHardClip& hardClip() { return fHardClip; }
     98 
     99     void addCoverageFP(std::unique_ptr<GrFragmentProcessor> fp) {
    100         SkASSERT(fp);
    101         fClipCoverageFPs.push_back(std::move(fp));
    102     }
    103 
    104     bool doesClip() const {
    105         return fHardClip.doesClip() || !fClipCoverageFPs.empty();
    106     }
    107 
    108     bool operator==(const GrAppliedClip& that) const {
    109         if (fHardClip != that.fHardClip ||
    110             fClipCoverageFPs.count() != that.fClipCoverageFPs.count()) {
    111             return false;
    112         }
    113         for (int i = 0; i < fClipCoverageFPs.count(); ++i) {
    114             if (!fClipCoverageFPs[i] || !that.fClipCoverageFPs[i]) {
    115                 if (fClipCoverageFPs[i] == that.fClipCoverageFPs[i]) {
    116                     continue; // Both are null.
    117                 }
    118                 return false;
    119             }
    120             if (!fClipCoverageFPs[i]->isEqual(*that.fClipCoverageFPs[i])) {
    121                 return false;
    122             }
    123         }
    124         return true;
    125     }
    126     bool operator!=(const GrAppliedClip& that) const { return !(*this == that); }
    127 
    128     void visitProxies(const std::function<void(GrSurfaceProxy*)>& func) const {
    129         for (const std::unique_ptr<GrFragmentProcessor>& fp : fClipCoverageFPs) {
    130             if (fp) { // This might be called after detach.
    131                 fp->visitProxies(func);
    132             }
    133         }
    134     }
    135 
    136 private:
    137     GrAppliedHardClip fHardClip;
    138     SkSTArray<4, std::unique_ptr<GrFragmentProcessor>> fClipCoverageFPs;
    139 };
    140 
    141 #endif
    142