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 "GrClipMaskCache.h" 11 #include "GrContext.h" 12 #include "GrPipelineBuilder.h" 13 #include "GrReducedClip.h" 14 #include "GrStencil.h" 15 #include "GrTexture.h" 16 #include "SkClipStack.h" 17 #include "SkDeque.h" 18 #include "SkPath.h" 19 #include "SkRefCnt.h" 20 #include "SkTLList.h" 21 #include "SkTypes.h" 22 23 class GrClipTarget; 24 class GrPathRenderer; 25 class GrPathRendererChain; 26 class GrTexture; 27 class SkPath; 28 /** 29 * The clip mask creator handles the generation of the clip mask. If anti 30 * aliasing is requested it will (in the future) generate a single channel 31 * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit 32 * mask in the stencil buffer. In the non anti-aliasing case, if the clip 33 * mask can be represented as a rectangle then scissoring is used. In all 34 * cases scissoring is used to bound the range of the clip mask. 35 */ 36 class GrClipMaskManager : SkNoncopyable { 37 public: GrClipMaskManager()38 GrClipMaskManager() 39 : fCurrClipMaskType(kNone_ClipMaskType) 40 , fClipTarget(NULL) 41 , fClipMode(kIgnoreClip_StencilClipMode) { 42 } 43 44 /** 45 * Creates a clip mask if necessary as a stencil buffer or alpha texture 46 * and sets the GrGpu's scissor and stencil state. If the return is false 47 * then the draw can be skipped. The AutoRestoreEffects is initialized by 48 * the manager when it must install additional effects to implement the 49 * clip. devBounds is optional but can help optimize clipping. 50 */ 51 bool setupClipping(GrPipelineBuilder*, 52 GrPipelineBuilder::AutoRestoreFragmentProcessors*, 53 GrPipelineBuilder::AutoRestoreStencil*, 54 GrScissorState*, 55 const SkRect* devBounds); 56 57 /** 58 * Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs 59 * which will allow Resourcecache to automatically purge anything this class has created. 60 */ 61 void purgeResources(); 62 isClipInStencil()63 bool isClipInStencil() const { 64 return kStencil_ClipMaskType == fCurrClipMaskType; 65 } 66 isClipInAlpha()67 bool isClipInAlpha() const { 68 return kAlpha_ClipMaskType == fCurrClipMaskType; 69 } 70 getContext()71 GrContext* getContext() { 72 return fAACache.getContext(); 73 } 74 75 void setClipTarget(GrClipTarget*); 76 77 void adjustPathStencilParams(const GrStencilAttachment*, GrStencilSettings*); 78 79 private: 80 /** 81 * Informs the helper function adjustStencilParams() about how the stencil 82 * buffer clip is being used. 83 */ 84 enum StencilClipMode { 85 // Draw to the clip bit of the stencil buffer 86 kModifyClip_StencilClipMode, 87 // Clip against the existing representation of the clip in the high bit 88 // of the stencil buffer. 89 kRespectClip_StencilClipMode, 90 // Neither writing to nor clipping against the clip bit. 91 kIgnoreClip_StencilClipMode, 92 }; 93 94 // Attempts to install a series of coverage effects to implement the clip. Return indicates 95 // whether the element list was successfully converted to effects. 96 bool installClipEffects(GrPipelineBuilder*, 97 GrPipelineBuilder::AutoRestoreFragmentProcessors*, 98 const GrReducedClip::ElementList&, 99 const SkVector& clipOffset, 100 const SkRect* devBounds); 101 102 // Draws the clip into the stencil buffer 103 bool createStencilClipMask(GrRenderTarget*, 104 int32_t elementsGenID, 105 GrReducedClip::InitialState initialState, 106 const GrReducedClip::ElementList& elements, 107 const SkIRect& clipSpaceIBounds, 108 const SkIPoint& clipSpaceToStencilOffset); 109 110 // Creates an alpha mask of the clip. The mask is a rasterization of elements through the 111 // rect specified by clipSpaceIBounds. 112 GrTexture* createAlphaClipMask(int32_t elementsGenID, 113 GrReducedClip::InitialState initialState, 114 const GrReducedClip::ElementList& elements, 115 const SkVector& clipToMaskOffset, 116 const SkIRect& clipSpaceIBounds); 117 118 // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 119 GrTexture* createSoftwareClipMask(int32_t elementsGenID, 120 GrReducedClip::InitialState initialState, 121 const GrReducedClip::ElementList& elements, 122 const SkVector& clipToMaskOffset, 123 const SkIRect& clipSpaceIBounds); 124 125 // Returns the cached mask texture if it matches the elementsGenID and the clipSpaceIBounds. 126 // Returns NULL if not found. 127 GrTexture* getCachedMaskTexture(int32_t elementsGenID, const SkIRect& clipSpaceIBounds); 128 129 // Handles allocation (if needed) of a clip alpha-mask texture for both the sw-upload 130 // or gpu-rendered cases. 131 GrTexture* allocMaskTexture(int32_t elementsGenID, 132 const SkIRect& clipSpaceIBounds, 133 bool willUpload); 134 135 bool useSWOnlyPath(const GrPipelineBuilder*, 136 const SkVector& clipToMaskOffset, 137 const GrReducedClip::ElementList& elements); 138 139 // Draws a clip element into the target alpha mask. The caller should have already setup the 140 // desired blend operation. Optionally if the caller already selected a path renderer it can 141 // be passed. Otherwise the function will select one if the element is a path. 142 bool drawElement(GrPipelineBuilder*, 143 const SkMatrix& viewMatrix, 144 GrTexture* target, 145 const SkClipStack::Element*, 146 GrPathRenderer* pr = 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(GrPipelineBuilder*, 152 GrTexture* target, 153 GrPathRenderer**, 154 const SkClipStack::Element*); 155 156 void mergeMask(GrPipelineBuilder*, 157 GrTexture* dstMask, 158 GrTexture* srcMask, 159 SkRegion::Op op, 160 const SkIRect& dstBound, 161 const SkIRect& srcBound); 162 163 GrTexture* createTempMask(int width, int height); 164 165 void setupCache(const SkClipStack& clip, 166 const SkIRect& bounds); 167 /** 168 * Called prior to return control back the GrGpu in setupClipping. It updates the 169 * GrPipelineBuilder with stencil settings that account for stencil-based clipping. 170 */ 171 void setPipelineBuilderStencil(GrPipelineBuilder*, GrPipelineBuilder::AutoRestoreStencil*); 172 173 /** 174 * Adjusts the stencil settings to account for interaction with stencil 175 * clipping. 176 */ 177 void adjustStencilParams(GrStencilSettings* settings, 178 StencilClipMode mode, 179 int stencilBitCnt); 180 181 /** 182 * We may represent the clip as a mask in the stencil buffer or as an alpha 183 * texture. It may be neither because the scissor rect suffices or we 184 * haven't yet examined the clip. 185 */ 186 enum ClipMaskType { 187 kNone_ClipMaskType, 188 kStencil_ClipMaskType, 189 kAlpha_ClipMaskType, 190 } fCurrClipMaskType; 191 192 GrClipMaskCache fAACache; // cache for the AA path 193 GrClipTarget* fClipTarget; 194 StencilClipMode fClipMode; 195 196 typedef SkNoncopyable INHERITED; 197 }; 198 #endif // GrClipMaskManager_DEFINED 199