Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2012 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 #ifndef GrClipMaskManager_DEFINED
      8 #define GrClipMaskManager_DEFINED
      9 
     10 #include "GrPipelineBuilder.h"
     11 #include "GrReducedClip.h"
     12 #include "GrStencil.h"
     13 #include "GrTexture.h"
     14 #include "SkClipStack.h"
     15 #include "SkDeque.h"
     16 #include "SkPath.h"
     17 #include "SkRefCnt.h"
     18 #include "SkTLList.h"
     19 #include "SkTypes.h"
     20 
     21 class GrDrawTarget;
     22 class GrPathRenderer;
     23 class GrPathRendererChain;
     24 class GrResourceProvider;
     25 class GrTexture;
     26 class SkPath;
     27 
     28 /**
     29  * Produced by GrClipMaskManager. It provides a set of modifications to the drawing state that
     30  * are used to create the final GrPipeline for a GrBatch. This is a work in progress. It will
     31  * eventually encapsulate all mechanisms for modifying the scissor, shaders, and stencil state
     32  * to implement clipping.
     33  */
     34 class GrAppliedClip : public SkNoncopyable {
     35 public:
     36     GrAppliedClip() {}
     37     const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; }
     38     const GrScissorState& scissorState() const { return fScissorState; }
     39 
     40 private:
     41     SkAutoTUnref<const GrFragmentProcessor> fClipCoverageFP;
     42     GrScissorState                          fScissorState;
     43     friend class GrClipMaskManager;
     44 
     45     typedef SkNoncopyable INHERITED;
     46 };
     47 
     48 /**
     49  * The clip mask creator handles the generation of the clip mask. If anti
     50  * aliasing is requested it will (in the future) generate a single channel
     51  * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit
     52  * mask in the stencil buffer. In the non anti-aliasing case, if the clip
     53  * mask can be represented as a rectangle then scissoring is used. In all
     54  * cases scissoring is used to bound the range of the clip mask.
     55  */
     56 class GrClipMaskManager : SkNoncopyable {
     57 public:
     58     GrClipMaskManager(GrDrawTarget* owner, bool debugClipBatchToBounds);
     59 
     60     /**
     61      * Creates a clip mask if necessary as a stencil buffer or alpha texture
     62      * and sets the GrGpu's scissor and stencil state. If the return is false
     63      * then the draw can be skipped. The AutoRestoreEffects is initialized by
     64      * the manager when it must install additional effects to implement the
     65      * clip. devBounds is optional but can help optimize clipping.
     66      */
     67     bool setupClipping(const GrPipelineBuilder&,
     68                        GrPipelineBuilder::AutoRestoreStencil*,
     69                        const SkRect* devBounds,
     70                        GrAppliedClip*);
     71 
     72     void adjustPathStencilParams(const GrStencilAttachment*, GrStencilSettings*);
     73 
     74 private:
     75     inline GrContext* getContext();
     76     inline const GrCaps* caps() const;
     77     inline GrResourceProvider* resourceProvider();
     78 
     79     static bool PathNeedsSWRenderer(GrContext* context,
     80                                     bool isStencilDisabled,
     81                                     const GrRenderTarget* rt,
     82                                     const SkMatrix& viewMatrix,
     83                                     const SkClipStack::Element* element,
     84                                     GrPathRenderer** prOut,
     85                                     bool needsStencil);
     86     static GrPathRenderer* GetPathRenderer(GrContext* context,
     87                                            GrTexture* texture,
     88                                            const SkMatrix& viewMatrix,
     89                                            const SkClipStack::Element* element);
     90 
     91     /**
     92      * Informs the helper function adjustStencilParams() about how the stencil
     93      * buffer clip is being used.
     94      */
     95     enum StencilClipMode {
     96         // Draw to the clip bit of the stencil buffer
     97         kModifyClip_StencilClipMode,
     98         // Clip against the existing representation of the clip in the high bit
     99         // of the stencil buffer.
    100         kRespectClip_StencilClipMode,
    101         // Neither writing to nor clipping against the clip bit.
    102         kIgnoreClip_StencilClipMode,
    103     };
    104 
    105     // Attempts to install a series of coverage effects to implement the clip. Return indicates
    106     // whether the element list was successfully converted to processors. *fp may be nullptr even
    107     // when the function succeeds because all the elements were ignored. TODO: Make clip reduction
    108     // bounds-aware and stop checking bounds in this function. Similarly, we shouldn't need to pass
    109     // abortIfAA, but we don't yet know if all the AA elements will be eliminated.
    110     bool getAnalyticClipProcessor(const GrReducedClip::ElementList&,
    111                                   bool abortIfAA,
    112                                   SkVector& clipOffset,
    113                                   const SkRect* devBounds,
    114                                   const GrFragmentProcessor** fp);
    115 
    116     // Draws the clip into the stencil buffer
    117     bool createStencilClipMask(GrRenderTarget*,
    118                                int32_t elementsGenID,
    119                                GrReducedClip::InitialState initialState,
    120                                const GrReducedClip::ElementList& elements,
    121                                const SkIRect& clipSpaceIBounds,
    122                                const SkIPoint& clipSpaceToStencilOffset);
    123 
    124     // Creates an alpha mask of the clip. The mask is a rasterization of elements through the
    125     // rect specified by clipSpaceIBounds.
    126     GrTexture* createAlphaClipMask(int32_t elementsGenID,
    127                                    GrReducedClip::InitialState initialState,
    128                                    const GrReducedClip::ElementList& elements,
    129                                    const SkVector& clipToMaskOffset,
    130                                    const SkIRect& clipSpaceIBounds);
    131 
    132     // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
    133     GrTexture* createSoftwareClipMask(int32_t elementsGenID,
    134                                       GrReducedClip::InitialState initialState,
    135                                       const GrReducedClip::ElementList& elements,
    136                                       const SkVector& clipToMaskOffset,
    137                                       const SkIRect& clipSpaceIBounds);
    138 
    139    bool useSWOnlyPath(const GrPipelineBuilder&,
    140                       const GrRenderTarget* rt,
    141                       const SkVector& clipToMaskOffset,
    142                       const GrReducedClip::ElementList& elements);
    143 
    144     // Draws a clip element into the target alpha mask. The caller should have already setup the
    145     // desired blend operation. Optionally if the caller already selected a path renderer it can
    146     // be passed. Otherwise the function will select one if the element is a path.
    147     bool drawElement(GrPipelineBuilder*,
    148                      const SkMatrix& viewMatrix,
    149                      GrTexture* target,
    150                      const SkClipStack::Element*,
    151                      GrPathRenderer* pr = nullptr);
    152 
    153     /**
    154      * Called prior to return control back the GrGpu in setupClipping. It updates the
    155      * GrPipelineBuilder with stencil settings that account for stencil-based clipping.
    156      */
    157     void setPipelineBuilderStencil(const GrPipelineBuilder&,
    158                                    GrPipelineBuilder::AutoRestoreStencil*);
    159 
    160     /**
    161      * Adjusts the stencil settings to account for interaction with stencil
    162      * clipping.
    163      */
    164     void adjustStencilParams(GrStencilSettings* settings,
    165                              StencilClipMode mode,
    166                              int stencilBitCnt);
    167 
    168     GrTexture* createCachedMask(int width, int height, const GrUniqueKey& key, bool renderTarget);
    169 
    170     static const int kMaxAnalyticElements = 4;
    171 
    172     GrDrawTarget*   fDrawTarget;    // This is our owning draw target.
    173     StencilClipMode fClipMode;
    174     bool            fDebugClipBatchToBounds;
    175 
    176     typedef SkNoncopyable INHERITED;
    177 };
    178 #endif // GrClipMaskManager_DEFINED
    179