• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
GrAppliedClip()36     GrAppliedClip() {}
clipCoverageFragmentProcessor()37     const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; }
scissorState()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