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