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 : 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 /** 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. 59 */ 60 void purgeResources(); 61 62 bool isClipInStencil() const { 63 return kStencil_ClipMaskType == fCurrClipMaskType; 64 } 65 bool isClipInAlpha() const { 66 return kAlpha_ClipMaskType == fCurrClipMaskType; 67 } 68 69 void invalidateStencilMask() { 70 if (kStencil_ClipMaskType == fCurrClipMaskType) { 71 fCurrClipMaskType = kNone_ClipMaskType; 72 } 73 } 74 75 GrContext* getContext() { 76 return fAACache.getContext(); 77 } 78 79 void setGpu(GrGpu* gpu); 80 81 void adjustPathStencilParams(GrStencilSettings* settings); 82 private: 83 /** 84 * Informs the helper function adjustStencilParams() about how the stencil 85 * buffer clip is being used. 86 */ 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, 95 }; 96 97 GrGpu* fGpu; 98 99 /** 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. 103 */ 104 enum ClipMaskType { 105 kNone_ClipMaskType, 106 kStencil_ClipMaskType, 107 kAlpha_ClipMaskType, 108 } fCurrClipMaskType; 109 110 GrClipMaskCache fAACache; // cache for the AA path 111 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); 118 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); 136 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); 140 141 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, 146 bool willUpload); 147 148 bool useSWOnlyPath(const GrReducedClip::ElementList& elements); 149 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); 154 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 157 // also returned. 158 bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); 159 160 void mergeMask(GrTexture* dstMask, 161 GrTexture* srcMask, 162 SkRegion::Op op, 163 const SkIRect& dstBound, 164 const SkIRect& srcBound); 165 166 void getTemp(int width, int height, GrAutoScratchTexture* temp); 167 168 void setupCache(const SkClipStack& clip, 169 const SkIRect& bounds); 170 171 /** 172 * Called prior to return control back the GrGpu in setupClipping. It 173 * updates the GrGpu with stencil settings that account stencil-based 174 * clipping. 175 */ 176 void setGpuStencil(); 177 178 /** 179 * Adjusts the stencil settings to account for interaction with stencil 180 * clipping. 181 */ 182 void adjustStencilParams(GrStencilSettings* settings, 183 StencilClipMode mode, 184 int stencilBitCnt); 185 186 typedef SkNoncopyable INHERITED; 187 }; 188 189 #endif // GrClipMaskManager_DEFINED 190