Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2012 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #ifndef GrClipMaskManager_DEFINED
     10 #define GrClipMaskManager_DEFINED
     11 
     12 #include "GrContext.h"
     13 #include "GrNoncopyable.h"
     14 #include "GrRect.h"
     15 #include "GrReducedClip.h"
     16 #include "GrStencil.h"
     17 #include "GrTexture.h"
     18 
     19 #include "SkClipStack.h"
     20 #include "SkDeque.h"
     21 #include "SkPath.h"
     22 #include "SkRefCnt.h"
     23 #include "SkTLList.h"
     24 
     25 #include "GrClipMaskCache.h"
     26 
     27 class GrGpu;
     28 class GrPathRenderer;
     29 class GrPathRendererChain;
     30 class SkPath;
     31 class GrTexture;
     32 class GrDrawState;
     33 
     34 /**
     35  * The clip mask creator handles the generation of the clip mask. If anti
     36  * aliasing is requested it will (in the future) generate a single channel
     37  * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit
     38  * mask in the stencil buffer. In the non anti-aliasing case, if the clip
     39  * mask can be represented as a rectangle then scissoring is used. In all
     40  * cases scissoring is used to bound the range of the clip mask.
     41  */
     42 class GrClipMaskManager : public GrNoncopyable {
     43 public:
     44     GrClipMaskManager()
     45         : fGpu(NULL)
     46         , fCurrClipMaskType(kNone_ClipMaskType) {
     47     }
     48 
     49     /**
     50      * Creates a clip mask if necessary as a stencil buffer or alpha texture
     51      * and sets the GrGpu's scissor and stencil state. If the return is false
     52      * then the draw can be skipped.
     53      */
     54     bool setupClipping(const GrClipData* clipDataIn);
     55 
     56     void releaseResources();
     57 
     58     bool isClipInStencil() const {
     59         return kStencil_ClipMaskType == fCurrClipMaskType;
     60     }
     61     bool isClipInAlpha() const {
     62         return kAlpha_ClipMaskType == fCurrClipMaskType;
     63     }
     64 
     65     void invalidateStencilMask() {
     66         if (kStencil_ClipMaskType == fCurrClipMaskType) {
     67             fCurrClipMaskType = kNone_ClipMaskType;
     68         }
     69     }
     70 
     71     void setContext(GrContext* context) {
     72         fAACache.setContext(context);
     73     }
     74 
     75     GrContext* getContext() {
     76         return fAACache.getContext();
     77     }
     78 
     79     void setGpu(GrGpu* gpu) {
     80         fGpu = gpu;
     81     }
     82 
     83 private:
     84     /**
     85      * Informs the helper function adjustStencilParams() about how the stencil
     86      * buffer clip is being used.
     87      */
     88     enum StencilClipMode {
     89         // Draw to the clip bit of the stencil buffer
     90         kModifyClip_StencilClipMode,
     91         // Clip against the existing representation of the clip in the high bit
     92         // of the stencil buffer.
     93         kRespectClip_StencilClipMode,
     94         // Neither writing to nor clipping against the clip bit.
     95         kIgnoreClip_StencilClipMode,
     96     };
     97 
     98     GrGpu* fGpu;
     99 
    100     /**
    101      * We may represent the clip as a mask in the stencil buffer or as an alpha
    102      * texture. It may be neither because the scissor rect suffices or we
    103      * haven't yet examined the clip.
    104      */
    105     enum ClipMaskType {
    106         kNone_ClipMaskType,
    107         kStencil_ClipMaskType,
    108         kAlpha_ClipMaskType,
    109     } fCurrClipMaskType;
    110 
    111     GrClipMaskCache fAACache;       // cache for the AA path
    112 
    113     // Draws the clip into the stencil buffer
    114     bool createStencilClipMask(GrReducedClip::InitialState initialState,
    115                                const GrReducedClip::ElementList& elements,
    116                                const SkIRect& clipSpaceIBounds,
    117                                const SkIPoint& clipSpaceToStencilOffset);
    118     // Creates an alpha mask of the clip. The mask is a rasterization of elements through the
    119     // rect specified by clipSpaceIBounds.
    120     GrTexture* createAlphaClipMask(int32_t clipStackGenID,
    121                                    GrReducedClip::InitialState initialState,
    122                                    const GrReducedClip::ElementList& elements,
    123                                    const SkIRect& clipSpaceIBounds);
    124     // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
    125     GrTexture* createSoftwareClipMask(int32_t clipStackGenID,
    126                                       GrReducedClip::InitialState initialState,
    127                                       const GrReducedClip::ElementList& elements,
    128                                       const SkIRect& clipSpaceIBounds);
    129 
    130     // Gets a texture to use for the clip mask. If true is returned then a cached mask was found
    131     // that already contains the rasterization of the clip stack, otherwise an uninitialized texture
    132     // is returned.
    133     bool getMaskTexture(int32_t clipStackGenID,
    134                         const SkIRect& clipSpaceIBounds,
    135                         GrTexture** result);
    136 
    137     bool useSWOnlyPath(const GrReducedClip::ElementList& elements);
    138 
    139     // Draws a clip element into the target alpha mask. The caller should have already setup the
    140     // desired blend operation. Optionally if the caller already selected a path renderer it can
    141     // be passed. Otherwise the function will select one if the element is a path.
    142     bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL);
    143 
    144     // Determines whether it is possible to draw the element to both the stencil buffer and the
    145     // alpha mask simultaneously. If so and the element is a path a compatible path renderer is
    146     // also returned.
    147     bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**);
    148 
    149     void mergeMask(GrTexture* dstMask,
    150                    GrTexture* srcMask,
    151                    SkRegion::Op op,
    152                    const GrIRect& dstBound,
    153                    const GrIRect& srcBound);
    154 
    155     void getTemp(int width, int height, GrAutoScratchTexture* temp);
    156 
    157     void setupCache(const SkClipStack& clip,
    158                     const GrIRect& bounds);
    159 
    160     /**
    161      * Called prior to return control back the GrGpu in setupClipping. It
    162      * updates the GrGpu with stencil settings that account stencil-based
    163      * clipping.
    164      */
    165     void setGpuStencil();
    166 
    167     /**
    168      * Adjusts the stencil settings to account for interaction with stencil
    169      * clipping.
    170      */
    171     void adjustStencilParams(GrStencilSettings* settings,
    172                              StencilClipMode mode,
    173                              int stencilBitCnt);
    174 
    175     typedef GrNoncopyable INHERITED;
    176 };
    177 
    178 #endif // GrClipMaskManager_DEFINED
    179