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