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