LCOV - code coverage report
Current view: top level - gfx/skia/skia/src/core - SkRasterClip.h (source / functions) Hit Total Coverage
Test: output.info Lines: 56 69 81.2 %
Date: 2017-07-14 16:53:18 Functions: 23 27 85.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright 2010 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 SkRasterClip_DEFINED
       9             : #define SkRasterClip_DEFINED
      10             : 
      11             : #include "SkRegion.h"
      12             : #include "SkAAClip.h"
      13             : 
      14             : class SkRRect;
      15             : 
      16             : class SkConservativeClip {
      17             :     SkIRect         fBounds;
      18             :     const SkIRect*  fClipRestrictionRect;
      19             : 
      20           0 :     inline void applyClipRestriction(SkRegion::Op op, SkIRect* bounds) {
      21           0 :         if (op >= SkRegion::kUnion_Op && fClipRestrictionRect
      22           0 :             && !fClipRestrictionRect->isEmpty()) {
      23           0 :             if (!bounds->intersect(*fClipRestrictionRect)) {
      24           0 :                 bounds->setEmpty();
      25             :             }
      26             :         }
      27           0 :     }
      28             : 
      29             : public:
      30          63 :     SkConservativeClip() : fBounds(SkIRect::MakeEmpty()), fClipRestrictionRect(nullptr) {}
      31             : 
      32         406 :     bool isEmpty() const { return fBounds.isEmpty(); }
      33             :     bool isRect() const { return true; }
      34        1654 :     const SkIRect& getBounds() const { return fBounds; }
      35             : 
      36           0 :     void setEmpty() { fBounds.setEmpty(); }
      37          85 :     void setRect(const SkIRect& r) { fBounds = r; }
      38          63 :     void setDeviceClipRestriction(const SkIRect* rect) {
      39          63 :         fClipRestrictionRect = rect;
      40          63 :     }
      41             : 
      42             :     void op(const SkRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
      43             :     void op(const SkRRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
      44             :     void op(const SkPath&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
      45             :     void op(const SkRegion&, SkRegion::Op);
      46             :     void op(const SkIRect&, SkRegion::Op);
      47             : };
      48             : 
      49             : /**
      50             :  *  Wraps a SkRegion and SkAAClip, so we have a single object that can represent either our
      51             :  *  BW or antialiased clips.
      52             :  *
      53             :  *  This class is optimized for the raster backend of canvas, but can be expense to keep up2date,
      54             :  *  so it supports a runtime option (force-conservative-rects) to turn it into a super-fast
      55             :  *  rect-only tracker. The gpu backend uses this since it does not need the result (it uses
      56             :  *  SkClipStack instead).
      57             :  */
      58           0 : class SkRasterClip {
      59             : public:
      60             :     SkRasterClip();
      61             :     SkRasterClip(const SkIRect&);
      62             :     SkRasterClip(const SkRegion&);
      63             :     SkRasterClip(const SkRasterClip&);
      64             :     ~SkRasterClip();
      65             : 
      66             :     // Only compares the current state. Does not compare isForceConservativeRects(), so that field
      67             :     // could be different but this could still return true.
      68             :     bool operator==(const SkRasterClip&) const;
      69             :     bool operator!=(const SkRasterClip& other) const {
      70             :         return !(*this == other);
      71             :     }
      72             : 
      73         895 :     bool isBW() const { return fIsBW; }
      74           0 :     bool isAA() const { return !fIsBW; }
      75         322 :     const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
      76         185 :     const SkAAClip& aaRgn() const { SkASSERT(!fIsBW); return fAA; }
      77             : 
      78        2326 :     bool isEmpty() const {
      79        2326 :         SkASSERT(this->computeIsEmpty() == fIsEmpty);
      80        2326 :         return fIsEmpty;
      81             :     }
      82             : 
      83         648 :     bool isRect() const {
      84         648 :         SkASSERT(this->computeIsRect() == fIsRect);
      85         648 :         return fIsRect;
      86             :     }
      87             : 
      88             :     bool isComplex() const;
      89             :     const SkIRect& getBounds() const;
      90             : 
      91             :     bool setEmpty();
      92             :     bool setRect(const SkIRect&);
      93             : 
      94             :     bool op(const SkIRect&, SkRegion::Op);
      95             :     bool op(const SkRegion&, SkRegion::Op);
      96             :     bool op(const SkRect&, const SkMatrix& matrix, const SkIRect&, SkRegion::Op, bool doAA);
      97             :     bool op(const SkRRect&, const SkMatrix& matrix, const SkIRect&, SkRegion::Op, bool doAA);
      98             :     bool op(const SkPath&, const SkMatrix& matrix, const SkIRect&, SkRegion::Op, bool doAA);
      99             : 
     100             :     void translate(int dx, int dy, SkRasterClip* dst) const;
     101             :     void translate(int dx, int dy) {
     102             :         this->translate(dx, dy, this);
     103             :     }
     104             : 
     105             :     bool quickContains(const SkIRect& rect) const;
     106          43 :     bool quickContains(int left, int top, int right, int bottom) const {
     107          43 :         return quickContains(SkIRect::MakeLTRB(left, top, right, bottom));
     108             :     }
     109             : 
     110             :     /**
     111             :      *  Return true if this region is empty, or if the specified rectangle does
     112             :      *  not intersect the region. Returning false is not a guarantee that they
     113             :      *  intersect, but returning true is a guarantee that they do not.
     114             :      */
     115         370 :     bool quickReject(const SkIRect& rect) const {
     116         370 :         return !SkIRect::Intersects(this->getBounds(), rect);
     117             :     }
     118             : 
     119             :     // hack for SkCanvas::getTotalClip
     120             :     const SkRegion& forceGetBW();
     121             : 
     122             : #ifdef SK_DEBUG
     123             :     void validate() const;
     124             : #else
     125             :     void validate() const {}
     126             : #endif
     127             : 
     128          85 :     void setDeviceClipRestriction(const SkIRect* rect) {
     129          85 :         fClipRestrictionRect = rect;
     130          85 :     }
     131             : 
     132             : private:
     133             :     SkRegion    fBW;
     134             :     SkAAClip    fAA;
     135             :     bool        fIsBW;
     136             :     // these 2 are caches based on querying the right obj based on fIsBW
     137             :     bool        fIsEmpty;
     138             :     bool        fIsRect;
     139             :     const SkIRect*    fClipRestrictionRect = nullptr;
     140             : 
     141        7645 :     bool computeIsEmpty() const {
     142        7645 :         return fIsBW ? fBW.isEmpty() : fAA.isEmpty();
     143             :     }
     144             : 
     145        5967 :     bool computeIsRect() const {
     146        5967 :         return fIsBW ? fBW.isRect() : fAA.isRect();
     147             :     }
     148             : 
     149         645 :     bool updateCacheAndReturnNonEmpty(bool detectAARect = true) {
     150         645 :         fIsEmpty = this->computeIsEmpty();
     151             : 
     152             :         // detect that our computed AA is really just a (hard-edged) rect
     153         645 :         if (detectAARect && !fIsEmpty && !fIsBW && fAA.isRect()) {
     154           7 :             fBW.setRect(fAA.getBounds());
     155           7 :             fAA.setEmpty(); // don't need this guy anymore
     156           7 :             fIsBW = true;
     157             :         }
     158             : 
     159         645 :         fIsRect = this->computeIsRect();
     160         645 :         return !fIsEmpty;
     161             :     }
     162             : 
     163             :     void convertToAA();
     164             : 
     165             :     bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
     166             :     bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
     167             :     bool op(const SkRasterClip&, SkRegion::Op);
     168             :     bool setConservativeRect(const SkRect& r, const SkIRect& clipR, bool isInverse);
     169             : 
     170         458 :     inline void applyClipRestriction(SkRegion::Op op, SkIRect* bounds) {
     171         916 :         if (op >= SkRegion::kUnion_Op && fClipRestrictionRect
     172         458 :             && !fClipRestrictionRect->isEmpty()) {
     173           0 :             if (!bounds->intersect(*fClipRestrictionRect)) {
     174           0 :                 bounds->setEmpty();
     175             :             }
     176             :         }
     177         458 :     }
     178             : 
     179         113 :     inline void applyClipRestriction(SkRegion::Op op, SkRect* bounds) {
     180         226 :         if (op >= SkRegion::kUnion_Op && fClipRestrictionRect
     181         113 :             && !fClipRestrictionRect->isEmpty()) {
     182           0 :             if (!bounds->intersect(SkRect::Make(*fClipRestrictionRect))) {
     183           0 :                 bounds->setEmpty();
     184             :             }
     185             :         }
     186         113 :     }
     187             : };
     188             : 
     189             : class SkAutoRasterClipValidate : SkNoncopyable {
     190             : public:
     191        1367 :     SkAutoRasterClipValidate(const SkRasterClip& rc) : fRC(rc) {
     192        1367 :         fRC.validate();
     193        1367 :     }
     194        2734 :     ~SkAutoRasterClipValidate() {
     195        1367 :         fRC.validate();
     196        1367 :     }
     197             : private:
     198             :     const SkRasterClip& fRC;
     199             : };
     200             : #define SkAutoRasterClipValidate(...) SK_REQUIRE_LOCAL_VAR(SkAutoRasterClipValidate)
     201             : 
     202             : #ifdef SK_DEBUG
     203             :     #define AUTO_RASTERCLIP_VALIDATE(rc)    SkAutoRasterClipValidate arcv(rc)
     204             : #else
     205             :     #define AUTO_RASTERCLIP_VALIDATE(rc)
     206             : #endif
     207             : 
     208             : ///////////////////////////////////////////////////////////////////////////////
     209             : 
     210             : /**
     211             :  *  Encapsulates the logic of deciding if we need to change/wrap the blitter
     212             :  *  for aaclipping. If so, getRgn and getBlitter return modified values. If
     213             :  *  not, they return the raw blitter and (bw) clip region.
     214             :  *
     215             :  *  We need to keep the constructor/destructor cost as small as possible, so we
     216             :  *  can freely put this guy on the stack, and not pay too much for the case when
     217             :  *  we're really BW anyways.
     218             :  */
     219         186 : class SkAAClipBlitterWrapper {
     220             : public:
     221             :     SkAAClipBlitterWrapper();
     222             :     SkAAClipBlitterWrapper(const SkRasterClip&, SkBlitter*);
     223             :     SkAAClipBlitterWrapper(const SkAAClip*, SkBlitter*);
     224             : 
     225             :     void init(const SkRasterClip&, SkBlitter*);
     226             : 
     227             :     const SkIRect& getBounds() const {
     228             :         SkASSERT(fClipRgn);
     229             :         return fClipRgn->getBounds();
     230             :     }
     231         150 :     const SkRegion& getRgn() const {
     232         150 :         SkASSERT(fClipRgn);
     233         150 :         return *fClipRgn;
     234             :     }
     235         171 :     SkBlitter* getBlitter() {
     236         171 :         SkASSERT(fBlitter);
     237         171 :         return fBlitter;
     238             :     }
     239             : 
     240             : private:
     241             :     SkRegion        fBWRgn;
     242             :     SkAAClipBlitter fAABlitter;
     243             :     // what we return
     244             :     const SkRegion* fClipRgn;
     245             :     SkBlitter* fBlitter;
     246             : };
     247             : 
     248             : #endif

Generated by: LCOV version 1.13