1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrClipMaskManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,182 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrClipMaskManager_DEFINED 1.12 +#define GrClipMaskManager_DEFINED 1.13 + 1.14 +#include "GrClipMaskCache.h" 1.15 +#include "GrContext.h" 1.16 +#include "GrDrawState.h" 1.17 +#include "GrReducedClip.h" 1.18 +#include "GrStencil.h" 1.19 +#include "GrTexture.h" 1.20 + 1.21 +#include "SkClipStack.h" 1.22 +#include "SkDeque.h" 1.23 +#include "SkPath.h" 1.24 +#include "SkRefCnt.h" 1.25 +#include "SkTLList.h" 1.26 +#include "SkTypes.h" 1.27 + 1.28 +class GrGpu; 1.29 +class GrPathRenderer; 1.30 +class GrPathRendererChain; 1.31 +class GrTexture; 1.32 +class SkPath; 1.33 + 1.34 +/** 1.35 + * The clip mask creator handles the generation of the clip mask. If anti 1.36 + * aliasing is requested it will (in the future) generate a single channel 1.37 + * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit 1.38 + * mask in the stencil buffer. In the non anti-aliasing case, if the clip 1.39 + * mask can be represented as a rectangle then scissoring is used. In all 1.40 + * cases scissoring is used to bound the range of the clip mask. 1.41 + */ 1.42 +class GrClipMaskManager : public SkNoncopyable { 1.43 +public: 1.44 + GrClipMaskManager() 1.45 + : fGpu(NULL) 1.46 + , fCurrClipMaskType(kNone_ClipMaskType) { 1.47 + } 1.48 + 1.49 + /** 1.50 + * Creates a clip mask if necessary as a stencil buffer or alpha texture 1.51 + * and sets the GrGpu's scissor and stencil state. If the return is false 1.52 + * then the draw can be skipped. The AutoRestoreEffects is initialized by 1.53 + * the manager when it must install additional effects to implement the 1.54 + * clip. devBounds is optional but can help optimize clipping. 1.55 + */ 1.56 + bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*, 1.57 + const SkRect* devBounds); 1.58 + 1.59 + void releaseResources(); 1.60 + 1.61 + bool isClipInStencil() const { 1.62 + return kStencil_ClipMaskType == fCurrClipMaskType; 1.63 + } 1.64 + bool isClipInAlpha() const { 1.65 + return kAlpha_ClipMaskType == fCurrClipMaskType; 1.66 + } 1.67 + 1.68 + void invalidateStencilMask() { 1.69 + if (kStencil_ClipMaskType == fCurrClipMaskType) { 1.70 + fCurrClipMaskType = kNone_ClipMaskType; 1.71 + } 1.72 + } 1.73 + 1.74 + GrContext* getContext() { 1.75 + return fAACache.getContext(); 1.76 + } 1.77 + 1.78 + void setGpu(GrGpu* gpu); 1.79 + 1.80 + void adjustPathStencilParams(GrStencilSettings* settings); 1.81 +private: 1.82 + /** 1.83 + * Informs the helper function adjustStencilParams() about how the stencil 1.84 + * buffer clip is being used. 1.85 + */ 1.86 + enum StencilClipMode { 1.87 + // Draw to the clip bit of the stencil buffer 1.88 + kModifyClip_StencilClipMode, 1.89 + // Clip against the existing representation of the clip in the high bit 1.90 + // of the stencil buffer. 1.91 + kRespectClip_StencilClipMode, 1.92 + // Neither writing to nor clipping against the clip bit. 1.93 + kIgnoreClip_StencilClipMode, 1.94 + }; 1.95 + 1.96 + GrGpu* fGpu; 1.97 + 1.98 + /** 1.99 + * We may represent the clip as a mask in the stencil buffer or as an alpha 1.100 + * texture. It may be neither because the scissor rect suffices or we 1.101 + * haven't yet examined the clip. 1.102 + */ 1.103 + enum ClipMaskType { 1.104 + kNone_ClipMaskType, 1.105 + kStencil_ClipMaskType, 1.106 + kAlpha_ClipMaskType, 1.107 + } fCurrClipMaskType; 1.108 + 1.109 + GrClipMaskCache fAACache; // cache for the AA path 1.110 + 1.111 + // Attempts to install a series of coverage effects to implement the clip. Return indicates 1.112 + // whether the element list was successfully converted to effects. 1.113 + bool installClipEffects(const GrReducedClip::ElementList&, 1.114 + GrDrawState::AutoRestoreEffects*, 1.115 + const SkVector& clipOffset, 1.116 + const SkRect* devBounds); 1.117 + 1.118 + // Draws the clip into the stencil buffer 1.119 + bool createStencilClipMask(int32_t elementsGenID, 1.120 + GrReducedClip::InitialState initialState, 1.121 + const GrReducedClip::ElementList& elements, 1.122 + const SkIRect& clipSpaceIBounds, 1.123 + const SkIPoint& clipSpaceToStencilOffset); 1.124 + // Creates an alpha mask of the clip. The mask is a rasterization of elements through the 1.125 + // rect specified by clipSpaceIBounds. 1.126 + GrTexture* createAlphaClipMask(int32_t elementsGenID, 1.127 + GrReducedClip::InitialState initialState, 1.128 + const GrReducedClip::ElementList& elements, 1.129 + const SkIRect& clipSpaceIBounds); 1.130 + // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 1.131 + GrTexture* createSoftwareClipMask(int32_t elementsGenID, 1.132 + GrReducedClip::InitialState initialState, 1.133 + const GrReducedClip::ElementList& elements, 1.134 + const SkIRect& clipSpaceIBounds); 1.135 + 1.136 + // Gets a texture to use for the clip mask. If true is returned then a cached mask was found 1.137 + // that already contains the rasterization of the clip stack, otherwise an uninitialized texture 1.138 + // is returned. 'willUpload' is set when the alpha mask needs to be uploaded from the CPU. 1.139 + bool getMaskTexture(int32_t elementsGenID, 1.140 + const SkIRect& clipSpaceIBounds, 1.141 + GrTexture** result, 1.142 + bool willUpload); 1.143 + 1.144 + bool useSWOnlyPath(const GrReducedClip::ElementList& elements); 1.145 + 1.146 + // Draws a clip element into the target alpha mask. The caller should have already setup the 1.147 + // desired blend operation. Optionally if the caller already selected a path renderer it can 1.148 + // be passed. Otherwise the function will select one if the element is a path. 1.149 + bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL); 1.150 + 1.151 + // Determines whether it is possible to draw the element to both the stencil buffer and the 1.152 + // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 1.153 + // also returned. 1.154 + bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); 1.155 + 1.156 + void mergeMask(GrTexture* dstMask, 1.157 + GrTexture* srcMask, 1.158 + SkRegion::Op op, 1.159 + const SkIRect& dstBound, 1.160 + const SkIRect& srcBound); 1.161 + 1.162 + void getTemp(int width, int height, GrAutoScratchTexture* temp); 1.163 + 1.164 + void setupCache(const SkClipStack& clip, 1.165 + const SkIRect& bounds); 1.166 + 1.167 + /** 1.168 + * Called prior to return control back the GrGpu in setupClipping. It 1.169 + * updates the GrGpu with stencil settings that account stencil-based 1.170 + * clipping. 1.171 + */ 1.172 + void setGpuStencil(); 1.173 + 1.174 + /** 1.175 + * Adjusts the stencil settings to account for interaction with stencil 1.176 + * clipping. 1.177 + */ 1.178 + void adjustStencilParams(GrStencilSettings* settings, 1.179 + StencilClipMode mode, 1.180 + int stencilBitCnt); 1.181 + 1.182 + typedef SkNoncopyable INHERITED; 1.183 +}; 1.184 + 1.185 +#endif // GrClipMaskManager_DEFINED