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