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 "GrDrawState.h" 14#include "GrNoncopyable.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 27class GrGpu; 28class GrPathRenderer; 29class GrPathRendererChain; 30class SkPath; 31class GrTexture; 32 33/** 34 * The clip mask creator handles the generation of the clip mask. If anti 35 * aliasing is requested it will (in the future) generate a single channel 36 * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit 37 * mask in the stencil buffer. In the non anti-aliasing case, if the clip 38 * mask can be represented as a rectangle then scissoring is used. In all 39 * cases scissoring is used to bound the range of the clip mask. 40 */ 41class GrClipMaskManager : public GrNoncopyable { 42public: 43 GrClipMaskManager() 44 : fGpu(NULL) 45 , fCurrClipMaskType(kNone_ClipMaskType) { 46 } 47 48 /** 49 * Creates a clip mask if necessary as a stencil buffer or alpha texture 50 * and sets the GrGpu's scissor and stencil state. If the return is false 51 * then the draw can be skipped. 52 */ 53 bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*); 54 55 void releaseResources(); 56 57 bool isClipInStencil() const { 58 return kStencil_ClipMaskType == fCurrClipMaskType; 59 } 60 bool isClipInAlpha() const { 61 return kAlpha_ClipMaskType == fCurrClipMaskType; 62 } 63 64 void invalidateStencilMask() { 65 if (kStencil_ClipMaskType == fCurrClipMaskType) { 66 fCurrClipMaskType = kNone_ClipMaskType; 67 } 68 } 69 70 GrContext* getContext() { 71 return fAACache.getContext(); 72 } 73 74 void setGpu(GrGpu* gpu); 75private: 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(GrReducedClip::InitialState initialState, 107 const GrReducedClip::ElementList& elements, 108 const SkIRect& clipSpaceIBounds, 109 const SkIPoint& clipSpaceToStencilOffset); 110 // Creates an alpha mask of the clip. The mask is a rasterization of elements through the 111 // rect specified by clipSpaceIBounds. 112 GrTexture* createAlphaClipMask(int32_t clipStackGenID, 113 GrReducedClip::InitialState initialState, 114 const GrReducedClip::ElementList& elements, 115 const SkIRect& clipSpaceIBounds); 116 // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 117 GrTexture* createSoftwareClipMask(int32_t clipStackGenID, 118 GrReducedClip::InitialState initialState, 119 const GrReducedClip::ElementList& elements, 120 const SkIRect& clipSpaceIBounds); 121 122 // Gets a texture to use for the clip mask. If true is returned then a cached mask was found 123 // that already contains the rasterization of the clip stack, otherwise an uninitialized texture 124 // is returned. 125 bool getMaskTexture(int32_t clipStackGenID, 126 const SkIRect& clipSpaceIBounds, 127 GrTexture** result); 128 129 bool useSWOnlyPath(const GrReducedClip::ElementList& elements); 130 131 // Draws a clip element into the target alpha mask. The caller should have already setup the 132 // desired blend operation. Optionally if the caller already selected a path renderer it can 133 // be passed. Otherwise the function will select one if the element is a path. 134 bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL); 135 136 // Determines whether it is possible to draw the element to both the stencil buffer and the 137 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 138 // also returned. 139 bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); 140 141 void mergeMask(GrTexture* dstMask, 142 GrTexture* srcMask, 143 SkRegion::Op op, 144 const SkIRect& dstBound, 145 const SkIRect& srcBound); 146 147 void getTemp(int width, int height, GrAutoScratchTexture* temp); 148 149 void setupCache(const SkClipStack& clip, 150 const SkIRect& bounds); 151 152 /** 153 * Called prior to return control back the GrGpu in setupClipping. It 154 * updates the GrGpu with stencil settings that account stencil-based 155 * clipping. 156 */ 157 void setGpuStencil(); 158 159 /** 160 * Adjusts the stencil settings to account for interaction with stencil 161 * clipping. 162 */ 163 void adjustStencilParams(GrStencilSettings* settings, 164 StencilClipMode mode, 165 int stencilBitCnt); 166 167 typedef GrNoncopyable INHERITED; 168}; 169 170#endif // GrClipMaskManager_DEFINED 171