GrClipMaskManager.h revision 8059eb9f6e24ed609393fbda4ad71edea03ac258
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 "GrDrawState.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 23class GrClipTarget; 24class GrPathRenderer; 25class GrPathRendererChain; 26class GrTexture; 27class 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 */ 36class GrClipMaskManager : SkNoncopyable { 37public: 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(GrDrawState*, 52 GrDrawState::AutoRestoreEffects*, 53 GrDrawState::AutoRestoreStencil*, 54 GrScissorState*, 55 const GrClipData* clipDataIn, 56 const SkRect* devBounds); 57 58 /** 59 * Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs 60 * which will allow ResourceCache2 to automatically purge anything this class has created. 61 */ 62 void purgeResources(); 63 64 bool isClipInStencil() const { 65 return kStencil_ClipMaskType == fCurrClipMaskType; 66 } 67 68 bool isClipInAlpha() const { 69 return kAlpha_ClipMaskType == fCurrClipMaskType; 70 } 71 72 GrContext* getContext() { 73 return fAACache.getContext(); 74 } 75 76 void setClipTarget(GrClipTarget*); 77 78 void adjustPathStencilParams(const GrStencilBuffer*, GrStencilSettings*); 79 80private: 81 /** 82 * Informs the helper function adjustStencilParams() about how the stencil 83 * buffer clip is being used. 84 */ 85 enum StencilClipMode { 86 // Draw to the clip bit of the stencil buffer 87 kModifyClip_StencilClipMode, 88 // Clip against the existing representation of the clip in the high bit 89 // of the stencil buffer. 90 kRespectClip_StencilClipMode, 91 // Neither writing to nor clipping against the clip bit. 92 kIgnoreClip_StencilClipMode, 93 }; 94 95 // Attempts to install a series of coverage effects to implement the clip. Return indicates 96 // whether the element list was successfully converted to effects. 97 bool installClipEffects(GrDrawState*, 98 GrDrawState::AutoRestoreEffects*, 99 const GrReducedClip::ElementList&, 100 const SkVector& clipOffset, 101 const SkRect* devBounds); 102 103 // Draws the clip into the stencil buffer 104 bool createStencilClipMask(GrRenderTarget*, 105 int32_t elementsGenID, 106 GrReducedClip::InitialState initialState, 107 const GrReducedClip::ElementList& elements, 108 const SkIRect& clipSpaceIBounds, 109 const SkIPoint& clipSpaceToStencilOffset); 110 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 SkVector& clipToMaskOffset, 117 const SkIRect& clipSpaceIBounds); 118 119 // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 120 GrTexture* createSoftwareClipMask(int32_t elementsGenID, 121 GrReducedClip::InitialState initialState, 122 const GrReducedClip::ElementList& elements, 123 const SkVector& clipToMaskOffset, 124 const SkIRect& clipSpaceIBounds); 125 126 // Returns the cached mask texture if it matches the elementsGenID and the clipSpaceIBounds. 127 // Returns NULL if not found. 128 GrTexture* getCachedMaskTexture(int32_t elementsGenID, const SkIRect& clipSpaceIBounds); 129 130 // Handles allocation (if needed) of a clip alpha-mask texture for both the sw-upload 131 // or gpu-rendered cases. 132 GrTexture* allocMaskTexture(int32_t elementsGenID, 133 const SkIRect& clipSpaceIBounds, 134 bool willUpload); 135 136 bool useSWOnlyPath(const GrDrawState*, 137 const SkVector& clipToMaskOffset, 138 const GrReducedClip::ElementList& elements); 139 140 // Draws a clip element into the target alpha mask. The caller should have already setup the 141 // desired blend operation. Optionally if the caller already selected a path renderer it can 142 // be passed. Otherwise the function will select one if the element is a path. 143 bool drawElement(GrDrawState*, 144 const SkMatrix& viewMatrix, 145 GrTexture* target, 146 const SkClipStack::Element*, 147 GrPathRenderer* pr = NULL); 148 149 // Determines whether it is possible to draw the element to both the stencil buffer and the 150 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 151 // also returned. 152 bool canStencilAndDrawElement(GrDrawState*, 153 GrTexture* target, 154 GrPathRenderer**, 155 const SkClipStack::Element*); 156 157 void mergeMask(GrDrawState*, 158 GrTexture* dstMask, 159 GrTexture* srcMask, 160 SkRegion::Op op, 161 const SkIRect& dstBound, 162 const SkIRect& srcBound); 163 164 GrTexture* createTempMask(int width, int height); 165 166 void setupCache(const SkClipStack& clip, 167 const SkIRect& bounds); 168 /** 169 * Called prior to return control back the GrGpu in setupClipping. It 170 * updates the GrGpu with stencil settings that account stencil-based 171 * clipping. 172 */ 173 void setDrawStateStencil(GrDrawState*, GrDrawState::AutoRestoreStencil*); 174 175 /** 176 * Adjusts the stencil settings to account for interaction with stencil 177 * clipping. 178 */ 179 void adjustStencilParams(GrStencilSettings* settings, 180 StencilClipMode mode, 181 int stencilBitCnt); 182 183 /** 184 * We may represent the clip as a mask in the stencil buffer or as an alpha 185 * texture. It may be neither because the scissor rect suffices or we 186 * haven't yet examined the clip. 187 */ 188 enum ClipMaskType { 189 kNone_ClipMaskType, 190 kStencil_ClipMaskType, 191 kAlpha_ClipMaskType, 192 } fCurrClipMaskType; 193 194 GrClipMaskCache fAACache; // cache for the AA path 195 GrClipTarget* fClipTarget; 196 StencilClipMode fClipMode; 197 198 typedef SkNoncopyable INHERITED; 199}; 200#endif // GrClipMaskManager_DEFINED 201