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 "GrPipelineBuilder.h" 11 #include "GrReducedClip.h" 12 #include "GrStencil.h" 13 #include "GrTexture.h" 14 #include "SkClipStack.h" 15 #include "SkDeque.h" 16 #include "SkPath.h" 17 #include "SkRefCnt.h" 18 #include "SkTLList.h" 19 #include "SkTypes.h" 20 21 class GrDrawTarget; 22 class GrPathRenderer; 23 class GrPathRendererChain; 24 class GrResourceProvider; 25 class GrTexture; 26 class SkPath; 27 28 /** 29 * Produced by GrClipMaskManager. It provides a set of modifications to the drawing state that 30 * are used to create the final GrPipeline for a GrBatch. This is a work in progress. It will 31 * eventually encapsulate all mechanisms for modifying the scissor, shaders, and stencil state 32 * to implement clipping. 33 */ 34 class GrAppliedClip : public SkNoncopyable { 35 public: GrAppliedClip()36 GrAppliedClip() {} clipCoverageFragmentProcessor()37 const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; } scissorState()38 const GrScissorState& scissorState() const { return fScissorState; } 39 40 private: 41 SkAutoTUnref<const GrFragmentProcessor> fClipCoverageFP; 42 GrScissorState fScissorState; 43 friend class GrClipMaskManager; 44 45 typedef SkNoncopyable INHERITED; 46 }; 47 48 /** 49 * The clip mask creator handles the generation of the clip mask. If anti 50 * aliasing is requested it will (in the future) generate a single channel 51 * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit 52 * mask in the stencil buffer. In the non anti-aliasing case, if the clip 53 * mask can be represented as a rectangle then scissoring is used. In all 54 * cases scissoring is used to bound the range of the clip mask. 55 */ 56 class GrClipMaskManager : SkNoncopyable { 57 public: 58 GrClipMaskManager(GrDrawTarget* owner, bool debugClipBatchToBounds); 59 60 /** 61 * Creates a clip mask if necessary as a stencil buffer or alpha texture 62 * and sets the GrGpu's scissor and stencil state. If the return is false 63 * then the draw can be skipped. The AutoRestoreEffects is initialized by 64 * the manager when it must install additional effects to implement the 65 * clip. devBounds is optional but can help optimize clipping. 66 */ 67 bool setupClipping(const GrPipelineBuilder&, 68 GrPipelineBuilder::AutoRestoreStencil*, 69 const SkRect* devBounds, 70 GrAppliedClip*); 71 72 void adjustPathStencilParams(const GrStencilAttachment*, GrStencilSettings*); 73 74 private: 75 inline GrContext* getContext(); 76 inline const GrCaps* caps() const; 77 inline GrResourceProvider* resourceProvider(); 78 79 static bool PathNeedsSWRenderer(GrContext* context, 80 bool isStencilDisabled, 81 const GrRenderTarget* rt, 82 const SkMatrix& viewMatrix, 83 const SkClipStack::Element* element, 84 GrPathRenderer** prOut, 85 bool needsStencil); 86 static GrPathRenderer* GetPathRenderer(GrContext* context, 87 GrTexture* texture, 88 const SkMatrix& viewMatrix, 89 const SkClipStack::Element* element); 90 91 /** 92 * Informs the helper function adjustStencilParams() about how the stencil 93 * buffer clip is being used. 94 */ 95 enum StencilClipMode { 96 // Draw to the clip bit of the stencil buffer 97 kModifyClip_StencilClipMode, 98 // Clip against the existing representation of the clip in the high bit 99 // of the stencil buffer. 100 kRespectClip_StencilClipMode, 101 // Neither writing to nor clipping against the clip bit. 102 kIgnoreClip_StencilClipMode, 103 }; 104 105 // Attempts to install a series of coverage effects to implement the clip. Return indicates 106 // whether the element list was successfully converted to processors. *fp may be nullptr even 107 // when the function succeeds because all the elements were ignored. TODO: Make clip reduction 108 // bounds-aware and stop checking bounds in this function. Similarly, we shouldn't need to pass 109 // abortIfAA, but we don't yet know if all the AA elements will be eliminated. 110 bool getAnalyticClipProcessor(const GrReducedClip::ElementList&, 111 bool abortIfAA, 112 SkVector& clipOffset, 113 const SkRect* devBounds, 114 const GrFragmentProcessor** fp); 115 116 // Draws the clip into the stencil buffer 117 bool createStencilClipMask(GrRenderTarget*, 118 int32_t elementsGenID, 119 GrReducedClip::InitialState initialState, 120 const GrReducedClip::ElementList& elements, 121 const SkIRect& clipSpaceIBounds, 122 const SkIPoint& clipSpaceToStencilOffset); 123 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 SkVector& clipToMaskOffset, 130 const SkIRect& clipSpaceIBounds); 131 132 // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 133 GrTexture* createSoftwareClipMask(int32_t elementsGenID, 134 GrReducedClip::InitialState initialState, 135 const GrReducedClip::ElementList& elements, 136 const SkVector& clipToMaskOffset, 137 const SkIRect& clipSpaceIBounds); 138 139 bool useSWOnlyPath(const GrPipelineBuilder&, 140 const GrRenderTarget* rt, 141 const SkVector& clipToMaskOffset, 142 const GrReducedClip::ElementList& elements); 143 144 // Draws a clip element into the target alpha mask. The caller should have already setup the 145 // desired blend operation. Optionally if the caller already selected a path renderer it can 146 // be passed. Otherwise the function will select one if the element is a path. 147 bool drawElement(GrPipelineBuilder*, 148 const SkMatrix& viewMatrix, 149 GrTexture* target, 150 const SkClipStack::Element*, 151 GrPathRenderer* pr = nullptr); 152 153 /** 154 * Called prior to return control back the GrGpu in setupClipping. It updates the 155 * GrPipelineBuilder with stencil settings that account for stencil-based clipping. 156 */ 157 void setPipelineBuilderStencil(const GrPipelineBuilder&, 158 GrPipelineBuilder::AutoRestoreStencil*); 159 160 /** 161 * Adjusts the stencil settings to account for interaction with stencil 162 * clipping. 163 */ 164 void adjustStencilParams(GrStencilSettings* settings, 165 StencilClipMode mode, 166 int stencilBitCnt); 167 168 GrTexture* createCachedMask(int width, int height, const GrUniqueKey& key, bool renderTarget); 169 170 static const int kMaxAnalyticElements = 4; 171 172 GrDrawTarget* fDrawTarget; // This is our owning draw target. 173 StencilClipMode fClipMode; 174 bool fDebugClipBatchToBounds; 175 176 typedef SkNoncopyable INHERITED; 177 }; 178 #endif // GrClipMaskManager_DEFINED 179