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