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 : public SkNoncopyable { 40 public: GrClipMaskManager()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. 50 */ 51 bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*); 52 53 void releaseResources(); 54 isClipInStencil()55 bool isClipInStencil() const { 56 return kStencil_ClipMaskType == fCurrClipMaskType; 57 } isClipInAlpha()58 bool isClipInAlpha() const { 59 return kAlpha_ClipMaskType == fCurrClipMaskType; 60 } 61 invalidateStencilMask()62 void invalidateStencilMask() { 63 if (kStencil_ClipMaskType == fCurrClipMaskType) { 64 fCurrClipMaskType = kNone_ClipMaskType; 65 } 66 } 67 getContext()68 GrContext* getContext() { 69 return fAACache.getContext(); 70 } 71 72 void setGpu(GrGpu* gpu); 73 74 void adjustPathStencilParams(GrStencilSettings* settings); 75 private: 76 /** 77 * Informs the helper function adjustStencilParams() about how the stencil 78 * buffer clip is being used. 79 */ 80 enum StencilClipMode { 81 // Draw to the clip bit of the stencil buffer 82 kModifyClip_StencilClipMode, 83 // Clip against the existing representation of the clip in the high bit 84 // of the stencil buffer. 85 kRespectClip_StencilClipMode, 86 // Neither writing to nor clipping against the clip bit. 87 kIgnoreClip_StencilClipMode, 88 }; 89 90 GrGpu* fGpu; 91 92 /** 93 * We may represent the clip as a mask in the stencil buffer or as an alpha 94 * texture. It may be neither because the scissor rect suffices or we 95 * haven't yet examined the clip. 96 */ 97 enum ClipMaskType { 98 kNone_ClipMaskType, 99 kStencil_ClipMaskType, 100 kAlpha_ClipMaskType, 101 } fCurrClipMaskType; 102 103 GrClipMaskCache fAACache; // cache for the AA path 104 105 // Draws the clip into the stencil buffer 106 bool createStencilClipMask(int32_t elementsGenID, 107 GrReducedClip::InitialState initialState, 108 const GrReducedClip::ElementList& elements, 109 const SkIRect& clipSpaceIBounds, 110 const SkIPoint& clipSpaceToStencilOffset); 111 // Creates an alpha mask of the clip. The mask is a rasterization of elements through the 112 // rect specified by clipSpaceIBounds. 113 GrTexture* createAlphaClipMask(int32_t elementsGenID, 114 GrReducedClip::InitialState initialState, 115 const GrReducedClip::ElementList& elements, 116 const SkIRect& clipSpaceIBounds); 117 // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 118 GrTexture* createSoftwareClipMask(int32_t elementsGenID, 119 GrReducedClip::InitialState initialState, 120 const GrReducedClip::ElementList& elements, 121 const SkIRect& clipSpaceIBounds); 122 123 // Gets a texture to use for the clip mask. If true is returned then a cached mask was found 124 // that already contains the rasterization of the clip stack, otherwise an uninitialized texture 125 // is returned. 'willUpload' is set when the alpha mask needs to be uploaded from the CPU. 126 bool getMaskTexture(int32_t elementsGenID, 127 const SkIRect& clipSpaceIBounds, 128 GrTexture** result, 129 bool willUpload); 130 131 bool useSWOnlyPath(const GrReducedClip::ElementList& elements); 132 133 // Draws a clip element into the target alpha mask. The caller should have already setup the 134 // desired blend operation. Optionally if the caller already selected a path renderer it can 135 // be passed. Otherwise the function will select one if the element is a path. 136 bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL); 137 138 // Determines whether it is possible to draw the element to both the stencil buffer and the 139 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 140 // also returned. 141 bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); 142 143 void mergeMask(GrTexture* dstMask, 144 GrTexture* srcMask, 145 SkRegion::Op op, 146 const SkIRect& dstBound, 147 const SkIRect& srcBound); 148 149 void getTemp(int width, int height, GrAutoScratchTexture* temp); 150 151 void setupCache(const SkClipStack& clip, 152 const SkIRect& bounds); 153 154 /** 155 * Called prior to return control back the GrGpu in setupClipping. It 156 * updates the GrGpu with stencil settings that account stencil-based 157 * clipping. 158 */ 159 void setGpuStencil(); 160 161 /** 162 * Adjusts the stencil settings to account for interaction with stencil 163 * clipping. 164 */ 165 void adjustStencilParams(GrStencilSettings* settings, 166 StencilClipMode mode, 167 int stencilBitCnt); 168 169 typedef SkNoncopyable INHERITED; 170 }; 171 172 #endif // GrClipMaskManager_DEFINED 173