1321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 2321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com/* 3321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * Copyright 2012 Google Inc. 4321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * 5321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 6321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * found in the LICENSE file. 7321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com */ 8321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 9321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com#ifndef GrClipMaskManager_DEFINED 10321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com#define GrClipMaskManager_DEFINED 11321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 127d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com#include "GrContext.h" 13860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com#include "GrDrawState.h" 147d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com#include "GrNoncopyable.h" 15e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com#include "GrReducedClip.h" 167d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com#include "GrStencil.h" 17bb3e02c86c0bc10ad2f064718166c19809fac440robertphillips@google.com#include "GrTexture.h" 187d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com 199304429af7b3825b5a9fb334e43c92ae1ba9d71arobertphillips@google.com#include "SkClipStack.h" 2087c46428e6d8465f9b18467a66737c17e71d36e0robertphillips@google.com#include "SkDeque.h" 217d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com#include "SkPath.h" 227d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com#include "SkRefCnt.h" 237830e470d00cdeb468ebf34525bc9f3f0c731014bsalomon@google.com#include "SkTLList.h" 24321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 25a0564cc3856261df813ebca2ad9576be26757cd4robertphillips@google.com#include "GrClipMaskCache.h" 26a0564cc3856261df813ebca2ad9576be26757cd4robertphillips@google.com 27321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.comclass GrGpu; 28321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.comclass GrPathRenderer; 29321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.comclass GrPathRendererChain; 30321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.comclass SkPath; 31fcf86a350bf9d8cdaff79d69bc8f3fecd019817brobertphillips@google.comclass GrTexture; 32321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 33321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com/** 34dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com * The clip mask creator handles the generation of the clip mask. If anti 35dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com * aliasing is requested it will (in the future) generate a single channel 36dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit 37321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * mask in the stencil buffer. In the non anti-aliasing case, if the clip 38321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * mask can be represented as a rectangle then scissoring is used. In all 39321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com * cases scissoring is used to bound the range of the clip mask. 40321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com */ 41a8fa01146ef11553878b7c23e273fd56aa764b33robertphillips@google.comclass GrClipMaskManager : public GrNoncopyable { 42321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.compublic: 43e804ec6a43335d919240f01097132f9a454b8b3brobertphillips@google.com GrClipMaskManager() 44e804ec6a43335d919240f01097132f9a454b8b3brobertphillips@google.com : fGpu(NULL) 450c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com , fCurrClipMaskType(kNone_ClipMaskType) { 46321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com } 47321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 4885d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com /** 4985d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * Creates a clip mask if necessary as a stencil buffer or alpha texture 5085d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * and sets the GrGpu's scissor and stencil state. If the return is false 5185d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * then the draw can be skipped. 5285d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com */ 53860912a0affd82bc6b30ad9006658df856ca1d17bsalomon@google.com bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*); 54321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 550fe76ba222e76bf6610aa99f7f605d25da059cd3robertphillips@google.com void releaseResources(); 56321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 570c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com bool isClipInStencil() const { 580c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com return kStencil_ClipMaskType == fCurrClipMaskType; 590c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com } 600c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com bool isClipInAlpha() const { 610c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com return kAlpha_ClipMaskType == fCurrClipMaskType; 620c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com } 63321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 640c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com void invalidateStencilMask() { 650c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com if (kStencil_ClipMaskType == fCurrClipMaskType) { 660c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com fCurrClipMaskType = kNone_ClipMaskType; 670c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com } 68321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com } 69321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 70a21adf42a7140b5420b400e1b03cbebb92b357f1robertphillips@google.com GrContext* getContext() { 71a21adf42a7140b5420b400e1b03cbebb92b357f1robertphillips@google.com return fAACache.getContext(); 72a21adf42a7140b5420b400e1b03cbebb92b357f1robertphillips@google.com } 73a21adf42a7140b5420b400e1b03cbebb92b357f1robertphillips@google.com 740ad5bd91fd7dc876326ee0832ca8f7947dc1cc24bsalomon@google.com void setGpu(GrGpu* gpu); 7585d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.comprivate: 767d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com /** 777d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com * Informs the helper function adjustStencilParams() about how the stencil 787d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com * buffer clip is being used. 797d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com */ 807d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com enum StencilClipMode { 817d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com // Draw to the clip bit of the stencil buffer 827d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com kModifyClip_StencilClipMode, 837d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com // Clip against the existing representation of the clip in the high bit 847d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com // of the stencil buffer. 857d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com kRespectClip_StencilClipMode, 867d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com // Neither writing to nor clipping against the clip bit. 877d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com kIgnoreClip_StencilClipMode, 887d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com }; 897d9fe5f786cc56c653bbcc99ea2a632d3b920f80bsalomon@google.com 9062310c0ce7ef008e106b483e568fcfa03fb04e66bsalomon@google.com GrGpu* fGpu; 910c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com 920c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com /** 930c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com * We may represent the clip as a mask in the stencil buffer or as an alpha 940c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com * texture. It may be neither because the scissor rect suffices or we 950c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com * haven't yet examined the clip. 960c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com */ 970c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com enum ClipMaskType { 980c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com kNone_ClipMaskType, 990c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com kStencil_ClipMaskType, 1000c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com kAlpha_ClipMaskType, 1010c4165f59a09574d521de66abeb3cc3101b04bd6bsalomon@google.com } fCurrClipMaskType; 102dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com 103a8fa01146ef11553878b7c23e273fd56aa764b33robertphillips@google.com GrClipMaskCache fAACache; // cache for the AA path 104321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 105e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com // Draws the clip into the stencil buffer 106e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com bool createStencilClipMask(GrReducedClip::InitialState initialState, 107e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const GrReducedClip::ElementList& elements, 108e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const SkIRect& clipSpaceIBounds, 109e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const SkIPoint& clipSpaceToStencilOffset); 110e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com // Creates an alpha mask of the clip. The mask is a rasterization of elements through the 111e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com // rect specified by clipSpaceIBounds. 112e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com GrTexture* createAlphaClipMask(int32_t clipStackGenID, 113e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com GrReducedClip::InitialState initialState, 114e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const GrReducedClip::ElementList& elements, 115e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const SkIRect& clipSpaceIBounds); 116e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com // Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture. 117e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com GrTexture* createSoftwareClipMask(int32_t clipStackGenID, 118e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com GrReducedClip::InitialState initialState, 119e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const GrReducedClip::ElementList& elements, 120e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const SkIRect& clipSpaceIBounds); 121e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com 122f4e6e352876ae31b68064b03bfadef08d29912acskia.committer@gmail.com // Gets a texture to use for the clip mask. If true is returned then a cached mask was found 123e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com // that already contains the rasterization of the clip stack, otherwise an uninitialized texture 124e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com // is returned. 125e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com bool getMaskTexture(int32_t clipStackGenID, 126e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com const SkIRect& clipSpaceIBounds, 127e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com GrTexture** result); 128e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com 129e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com bool useSWOnlyPath(const GrReducedClip::ElementList& elements); 130e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com 131bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com // Draws a clip element into the target alpha mask. The caller should have already setup the 132bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com // desired blend operation. Optionally if the caller already selected a path renderer it can 133bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com // be passed. Otherwise the function will select one if the element is a path. 134bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL); 135bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com 136bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com // Determines whether it is possible to draw the element to both the stencil buffer and the 137bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 138bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com // also returned. 139bf2c6afceebb56969edeedda8114b172165a2982bsalomon@google.com bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**); 140fcf86a350bf9d8cdaff79d69bc8f3fecd019817brobertphillips@google.com 141746496832ab4c5f603dbb7efa12a68f3b08bed8dbsalomon@google.com void mergeMask(GrTexture* dstMask, 142746496832ab4c5f603dbb7efa12a68f3b08bed8dbsalomon@google.com GrTexture* srcMask, 143746496832ab4c5f603dbb7efa12a68f3b08bed8dbsalomon@google.com SkRegion::Op op, 144a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkIRect& dstBound, 145a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkIRect& srcBound); 146321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 147e6aa2fce1b318c69ecf03324d19f93168e86feb6bsalomon@google.com void getTemp(int width, int height, GrAutoScratchTexture* temp); 1480fe76ba222e76bf6610aa99f7f605d25da059cd3robertphillips@google.com 149dfb3e3c0faadabc131ac1532e29ca71667328513rmistry@google.com void setupCache(const SkClipStack& clip, 150a8cbc57c2d74f8024d149370377bd7dcbd8d204ccommit-bot@chromium.org const SkIRect& bounds); 151bb3e02c86c0bc10ad2f064718166c19809fac440robertphillips@google.com 15285d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com /** 15385d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * Called prior to return control back the GrGpu in setupClipping. It 15485d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * updates the GrGpu with stencil settings that account stencil-based 15585d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * clipping. 15685d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com */ 15785d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com void setGpuStencil(); 15885d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com 15985d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com /** 16085d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * Adjusts the stencil settings to account for interaction with stencil 16185d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com * clipping. 16285d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com */ 16385d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com void adjustStencilParams(GrStencilSettings* settings, 16485d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com StencilClipMode mode, 16585d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com int stencilBitCnt); 16685d47bf8e929c8eca60ce0fc5bda1f64481d5ef1bsalomon@google.com 167a8fa01146ef11553878b7c23e273fd56aa764b33robertphillips@google.com typedef GrNoncopyable INHERITED; 168321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com}; 169321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com 170321f62ca78984b4e78d0f2c014af46327cf7331crobertphillips@google.com#endif // GrClipMaskManager_DEFINED 171