2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrClipMaskManager_DEFINED
9 #define GrClipMaskManager_DEFINED
11 #include "GrClipMaskCache.h"
12 #include "GrContext.h"
13 #include "GrDrawState.h"
14 #include "GrReducedClip.h"
15 #include "GrStencil.h"
16 #include "GrTexture.h"
18 #include "SkClipStack.h"
27 class GrPathRendererChain;
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.
39 class GrClipMaskManager : SkNoncopyable {
43 , fCurrClipMaskType(kNone_ClipMaskType) {
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.
53 bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*,
54 const SkRect* devBounds);
57 * Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
58 * which will allow ResourceCache2 to automatically purge anything this class has created.
60 void purgeResources();
62 bool isClipInStencil() const {
63 return kStencil_ClipMaskType == fCurrClipMaskType;
65 bool isClipInAlpha() const {
66 return kAlpha_ClipMaskType == fCurrClipMaskType;
69 void invalidateStencilMask() {
70 if (kStencil_ClipMaskType == fCurrClipMaskType) {
71 fCurrClipMaskType = kNone_ClipMaskType;
75 GrContext* getContext() {
76 return fAACache.getContext();
79 void setGpu(GrGpu* gpu);
81 void adjustPathStencilParams(GrStencilSettings* settings);
84 * Informs the helper function adjustStencilParams() about how the stencil
85 * buffer clip is being used.
87 enum StencilClipMode {
88 // Draw to the clip bit of the stencil buffer
89 kModifyClip_StencilClipMode,
90 // Clip against the existing representation of the clip in the high bit
91 // of the stencil buffer.
92 kRespectClip_StencilClipMode,
93 // Neither writing to nor clipping against the clip bit.
94 kIgnoreClip_StencilClipMode,
100 * We may represent the clip as a mask in the stencil buffer or as an alpha
101 * texture. It may be neither because the scissor rect suffices or we
102 * haven't yet examined the clip.
106 kStencil_ClipMaskType,
110 GrClipMaskCache fAACache; // cache for the AA path
112 // Attempts to install a series of coverage effects to implement the clip. Return indicates
113 // whether the element list was successfully converted to effects.
114 bool installClipEffects(const GrReducedClip::ElementList&,
115 GrDrawState::AutoRestoreEffects*,
116 const SkVector& clipOffset,
117 const SkRect* devBounds);
119 // Draws the clip into the stencil buffer
120 bool createStencilClipMask(int32_t elementsGenID,
121 GrReducedClip::InitialState initialState,
122 const GrReducedClip::ElementList& elements,
123 const SkIRect& clipSpaceIBounds,
124 const SkIPoint& clipSpaceToStencilOffset);
125 // Creates an alpha mask of the clip. The mask is a rasterization of elements through the
126 // rect specified by clipSpaceIBounds.
127 GrTexture* createAlphaClipMask(int32_t elementsGenID,
128 GrReducedClip::InitialState initialState,
129 const GrReducedClip::ElementList& elements,
130 const SkIRect& clipSpaceIBounds);
131 // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
132 GrTexture* createSoftwareClipMask(int32_t elementsGenID,
133 GrReducedClip::InitialState initialState,
134 const GrReducedClip::ElementList& elements,
135 const SkIRect& clipSpaceIBounds);
137 // Returns the cached mask texture if it matches the elementsGenID and the clipSpaceIBounds.
138 // Returns NULL if not found.
139 GrTexture* getCachedMaskTexture(int32_t elementsGenID, const SkIRect& clipSpaceIBounds);
142 // Handles allocation (if needed) of a clip alpha-mask texture for both the sw-upload
143 // or gpu-rendered cases.
144 GrTexture* allocMaskTexture(int32_t elementsGenID,
145 const SkIRect& clipSpaceIBounds,
148 bool useSWOnlyPath(const GrReducedClip::ElementList& elements);
150 // Draws a clip element into the target alpha mask. The caller should have already setup the
151 // desired blend operation. Optionally if the caller already selected a path renderer it can
152 // be passed. Otherwise the function will select one if the element is a path.
153 bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL);
155 // Determines whether it is possible to draw the element to both the stencil buffer and the
156 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is
158 bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**);
160 void mergeMask(GrTexture* dstMask,
163 const SkIRect& dstBound,
164 const SkIRect& srcBound);
166 void getTemp(int width, int height, GrAutoScratchTexture* temp);
168 void setupCache(const SkClipStack& clip,
169 const SkIRect& bounds);
172 * Called prior to return control back the GrGpu in setupClipping. It
173 * updates the GrGpu with stencil settings that account stencil-based
176 void setGpuStencil();
179 * Adjusts the stencil settings to account for interaction with stencil
182 void adjustStencilParams(GrStencilSettings* settings,
183 StencilClipMode mode,
186 typedef SkNoncopyable INHERITED;
189 #endif // GrClipMaskManager_DEFINED