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 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 // Returns the cached mask texture if it matches the elementsGenID and the clipSpaceIBounds. 134 // Returns NULL if not found. 135 GrTexture* getCachedMaskTexture(int32_t elementsGenID, const SkIRect& clipSpaceIBounds); 136 137 138 // Handles allocation (if needed) of a clip alpha-mask texture for both the sw-upload 139 // or gpu-rendered cases. 140 GrTexture* allocMaskTexture(int32_t elementsGenID, 141 const SkIRect& clipSpaceIBounds, 142 bool willUpload); 143 144 bool useSWOnlyPath(const GrReducedClip::ElementList& elements); 145 146 // Draws a clip element into the target alpha mask. The caller should have already setup the 147 // desired blend operation. Optionally if the caller already selected a path renderer it can 148 // be passed. Otherwise the function will select one if the element is a path. 149 bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL); 150 151 // Determines whether it is possible to draw the element to both the stencil buffer and the 152 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 153 // also returned. 154 bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); 155 156 void mergeMask(GrTexture* dstMask, 157 GrTexture* srcMask, 158 SkRegion::Op op, 159 const SkIRect& dstBound, 160 const SkIRect& srcBound); 161 162 void getTemp(int width, int height, GrAutoScratchTexture* temp); 163 164 void setupCache(const SkClipStack& clip, 165 const SkIRect& bounds); 166 167 /** 168 * Called prior to return control back the GrGpu in setupClipping. It 169 * updates the GrGpu with stencil settings that account stencil-based 170 * clipping. 171 */ 172 void setGpuStencil(); 173 174 /** 175 * Adjusts the stencil settings to account for interaction with stencil 176 * clipping. 177 */ 178 void adjustStencilParams(GrStencilSettings* settings, 179 StencilClipMode mode, 180 int stencilBitCnt); 181 182 typedef SkNoncopyable INHERITED; 183 }; 184 185 #endif // GrClipMaskManager_DEFINED 186