GrClipMaskManager.h revision c377baf406996aed18d82d328029c82dbc3b8dda
1f71323e297a928af368937089d3ed71239786f86Andreas Huber
2f71323e297a928af368937089d3ed71239786f86Andreas Huber/*
3f71323e297a928af368937089d3ed71239786f86Andreas Huber * Copyright 2012 Google Inc.
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *
5f71323e297a928af368937089d3ed71239786f86Andreas Huber * Use of this source code is governed by a BSD-style license that can be
6f71323e297a928af368937089d3ed71239786f86Andreas Huber * found in the LICENSE file.
7f71323e297a928af368937089d3ed71239786f86Andreas Huber */
8f71323e297a928af368937089d3ed71239786f86Andreas Huber
9f71323e297a928af368937089d3ed71239786f86Andreas Huber#ifndef GrClipMaskManager_DEFINED
10f71323e297a928af368937089d3ed71239786f86Andreas Huber#define GrClipMaskManager_DEFINED
11f71323e297a928af368937089d3ed71239786f86Andreas Huber
12f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "GrClip.h"
13f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "GrContext.h"
14f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "GrNoncopyable.h"
15f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "GrRect.h"
16f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "GrStencil.h"
17f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "GrTexture.h"
18f71323e297a928af368937089d3ed71239786f86Andreas Huber
19f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "SkDeque.h"
20f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "SkPath.h"
21f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "SkRefCnt.h"
22f71323e297a928af368937089d3ed71239786f86Andreas Huber
23f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrGpu;
24f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrPathRenderer;
25f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrPathRendererChain;
26f71323e297a928af368937089d3ed71239786f86Andreas Huberclass SkPath;
27f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrTexture;
28f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrDrawState;
29f71323e297a928af368937089d3ed71239786f86Andreas Huber
30f71323e297a928af368937089d3ed71239786f86Andreas Huber/**
31f71323e297a928af368937089d3ed71239786f86Andreas Huber * The stencil buffer stores the last clip path - providing a single entry
32f71323e297a928af368937089d3ed71239786f86Andreas Huber * "cache". This class provides similar functionality for AA clip paths
33f71323e297a928af368937089d3ed71239786f86Andreas Huber */
34f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrClipMaskCache : public GrNoncopyable {
35f71323e297a928af368937089d3ed71239786f86Andreas Huberpublic:
36f71323e297a928af368937089d3ed71239786f86Andreas Huber    GrClipMaskCache()
371b362b15af34006e6a11974088a46d42b903418eJohann    : fContext(NULL)
38f71323e297a928af368937089d3ed71239786f86Andreas Huber    , fStack(sizeof(GrClipStackFrame)) {
39f71323e297a928af368937089d3ed71239786f86Andreas Huber        // We need an initial frame to capture the clip state prior to
40f71323e297a928af368937089d3ed71239786f86Andreas Huber        // any pushes
41f71323e297a928af368937089d3ed71239786f86Andreas Huber        SkNEW_PLACEMENT(fStack.push_back(), GrClipStackFrame);
421b362b15af34006e6a11974088a46d42b903418eJohann    }
43f71323e297a928af368937089d3ed71239786f86Andreas Huber
44f71323e297a928af368937089d3ed71239786f86Andreas Huber    ~GrClipMaskCache() {
45f71323e297a928af368937089d3ed71239786f86Andreas Huber
46f71323e297a928af368937089d3ed71239786f86Andreas Huber        while (!fStack.empty()) {
47f71323e297a928af368937089d3ed71239786f86Andreas Huber            GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back();
48f71323e297a928af368937089d3ed71239786f86Andreas Huber            temp->~GrClipStackFrame();
49f71323e297a928af368937089d3ed71239786f86Andreas Huber            fStack.pop_back();
50f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
51f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
52538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
53f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool canReuse(const GrClip& clip, int width, int height) {
54538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
55f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (fStack.empty()) {
56f71323e297a928af368937089d3ed71239786f86Andreas Huber            GrAssert(false);
57f71323e297a928af368937089d3ed71239786f86Andreas Huber            return false;
58f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
59f71323e297a928af368937089d3ed71239786f86Andreas Huber
60f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
61f71323e297a928af368937089d3ed71239786f86Andreas Huber
62f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (back->fLastMask.texture() &&
63f71323e297a928af368937089d3ed71239786f86Andreas Huber            back->fLastMask.texture()->width() >= width &&
64f71323e297a928af368937089d3ed71239786f86Andreas Huber            back->fLastMask.texture()->height() >= height &&
65f71323e297a928af368937089d3ed71239786f86Andreas Huber            clip == back->fLastClip) {
66f71323e297a928af368937089d3ed71239786f86Andreas Huber            return true;
67f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
68f71323e297a928af368937089d3ed71239786f86Andreas Huber
69f71323e297a928af368937089d3ed71239786f86Andreas Huber        return false;
70f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
71f71323e297a928af368937089d3ed71239786f86Andreas Huber
72f71323e297a928af368937089d3ed71239786f86Andreas Huber    void reset() {
731b362b15af34006e6a11974088a46d42b903418eJohann        if (fStack.empty()) {
74538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber//            GrAssert(false);
75f71323e297a928af368937089d3ed71239786f86Andreas Huber            return;
76538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
77f71323e297a928af368937089d3ed71239786f86Andreas Huber
78538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
79f71323e297a928af368937089d3ed71239786f86Andreas Huber
80538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        back->reset();
81538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
82538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
83538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /**
84538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber     * After a "push" the clip state is entirely open. Currently, the
85538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber     * entire clip stack will be re-rendered into a new clip mask.
86538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber     * TODO: can we take advantage of the nested nature of the clips to
87538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber     * reduce the mask creation cost?
88538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber     */
89538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    void push() {
90538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        SkNEW_PLACEMENT(fStack.push_back(), GrClipStackFrame);
91f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
92f71323e297a928af368937089d3ed71239786f86Andreas Huber
93f71323e297a928af368937089d3ed71239786f86Andreas Huber    void pop() {
94538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        //GrAssert(!fStack.empty());
95538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
96538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (!fStack.empty()) {
97538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
98538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
99538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            back->~GrClipStackFrame();
100538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fStack.pop_back();
101538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
102538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
103f71323e297a928af368937089d3ed71239786f86Andreas Huber
104f71323e297a928af368937089d3ed71239786f86Andreas Huber    void getLastClip(GrClip* clip) const {
1051b362b15af34006e6a11974088a46d42b903418eJohann
106f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (fStack.empty()) {
107f71323e297a928af368937089d3ed71239786f86Andreas Huber            GrAssert(false);
108f71323e297a928af368937089d3ed71239786f86Andreas Huber            clip->setEmpty();
109f71323e297a928af368937089d3ed71239786f86Andreas Huber            return;
110f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
1111b362b15af34006e6a11974088a46d42b903418eJohann
112f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
113f71323e297a928af368937089d3ed71239786f86Andreas Huber
114f71323e297a928af368937089d3ed71239786f86Andreas Huber        *clip = back->fLastClip;
115f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
116f71323e297a928af368937089d3ed71239786f86Andreas Huber
117f71323e297a928af368937089d3ed71239786f86Andreas Huber    GrTexture* getLastMask() {
118f71323e297a928af368937089d3ed71239786f86Andreas Huber
119f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (fStack.empty()) {
120538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            GrAssert(false);
121538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            return NULL;
122f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
123f71323e297a928af368937089d3ed71239786f86Andreas Huber
124f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
125f71323e297a928af368937089d3ed71239786f86Andreas Huber
126f71323e297a928af368937089d3ed71239786f86Andreas Huber        return back->fLastMask.texture();
127f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
128f71323e297a928af368937089d3ed71239786f86Andreas Huber
129f71323e297a928af368937089d3ed71239786f86Andreas Huber    const GrTexture* getLastMask() const {
130f71323e297a928af368937089d3ed71239786f86Andreas Huber
131538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (fStack.empty()) {
1321b362b15af34006e6a11974088a46d42b903418eJohann            GrAssert(false);
133538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            return NULL;
134f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
135538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
136f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
137538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
138538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        return back->fLastMask.texture();
139538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
140538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
141538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    void acquireMask(const GrClip& clip,
142538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                     const GrTextureDesc& desc,
143538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                     const GrIRect& bound) {
144538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
145538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (fStack.empty()) {
146538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            GrAssert(false);
147f71323e297a928af368937089d3ed71239786f86Andreas Huber            return;
148f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
149f71323e297a928af368937089d3ed71239786f86Andreas Huber
150538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
151538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
152538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        back->acquireMask(fContext, clip, desc, bound);
153538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
154538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
155538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    int getLastMaskWidth() const {
156538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
157538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        if (fStack.empty()) {
158f71323e297a928af368937089d3ed71239786f86Andreas Huber            GrAssert(false);
159f71323e297a928af368937089d3ed71239786f86Andreas Huber            return -1;
160f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
1611b362b15af34006e6a11974088a46d42b903418eJohann
162f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
163f71323e297a928af368937089d3ed71239786f86Andreas Huber
164f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (NULL == back->fLastMask.texture()) {
165f71323e297a928af368937089d3ed71239786f86Andreas Huber            return -1;
166f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
1671b362b15af34006e6a11974088a46d42b903418eJohann
168f71323e297a928af368937089d3ed71239786f86Andreas Huber        return back->fLastMask.texture()->width();
169f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
170f71323e297a928af368937089d3ed71239786f86Andreas Huber
171f71323e297a928af368937089d3ed71239786f86Andreas Huber    int getLastMaskHeight() const {
172f71323e297a928af368937089d3ed71239786f86Andreas Huber
173f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (fStack.empty()) {
174f71323e297a928af368937089d3ed71239786f86Andreas Huber            GrAssert(false);
175f71323e297a928af368937089d3ed71239786f86Andreas Huber            return -1;
176f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
177f71323e297a928af368937089d3ed71239786f86Andreas Huber
178f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
179f71323e297a928af368937089d3ed71239786f86Andreas Huber
1801b362b15af34006e6a11974088a46d42b903418eJohann        if (NULL == back->fLastMask.texture()) {
181f71323e297a928af368937089d3ed71239786f86Andreas Huber            return -1;
182f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
183f71323e297a928af368937089d3ed71239786f86Andreas Huber
184f71323e297a928af368937089d3ed71239786f86Andreas Huber        return back->fLastMask.texture()->height();
1851b362b15af34006e6a11974088a46d42b903418eJohann    }
186f71323e297a928af368937089d3ed71239786f86Andreas Huber
187f71323e297a928af368937089d3ed71239786f86Andreas Huber    void getLastBound(GrIRect* bound) const {
188f71323e297a928af368937089d3ed71239786f86Andreas Huber
189f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (fStack.empty()) {
190f71323e297a928af368937089d3ed71239786f86Andreas Huber            GrAssert(false);
191538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            bound->setEmpty();
192f71323e297a928af368937089d3ed71239786f86Andreas Huber            return;
193f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
194f71323e297a928af368937089d3ed71239786f86Andreas Huber
195538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
196f71323e297a928af368937089d3ed71239786f86Andreas Huber
197f71323e297a928af368937089d3ed71239786f86Andreas Huber        *bound = back->fLastBound;
198538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
199f71323e297a928af368937089d3ed71239786f86Andreas Huber
200538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    void setContext(GrContext* context) {
201f71323e297a928af368937089d3ed71239786f86Andreas Huber        fContext = context;
202f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
203f71323e297a928af368937089d3ed71239786f86Andreas Huber
204f71323e297a928af368937089d3ed71239786f86Andreas Huber    GrContext* getContext() {
205f71323e297a928af368937089d3ed71239786f86Andreas Huber        return fContext;
206538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
207538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
208538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    void releaseResources() {
209f71323e297a928af368937089d3ed71239786f86Andreas Huber
2101b362b15af34006e6a11974088a46d42b903418eJohann        SkDeque::F2BIter iter(fStack);
211538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next();
212f71323e297a928af368937089d3ed71239786f86Andreas Huber                frame != NULL;
213538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                frame = (GrClipStackFrame*) iter.next()) {
214f71323e297a928af368937089d3ed71239786f86Andreas Huber            frame->reset();
215538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
216f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
217538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
218538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberprotected:
219538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huberprivate:
220538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    struct GrClipStackFrame {
221538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
222538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        GrClipStackFrame() {
223538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            reset();
224538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
225538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
226538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        void acquireMask(GrContext* context,
227538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                         const GrClip& clip,
228538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                         const GrTextureDesc& desc,
229538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                         const GrIRect& bound) {
230538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
231538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fLastClip = clip;
232538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
233538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fLastMask.set(context, desc);
234538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
235538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fLastBound = bound;
236538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
237538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
238538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        void reset () {
239538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fLastClip.setEmpty();
240538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
241538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            GrTextureDesc desc;
242538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
243538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fLastMask.set(NULL, desc);
244538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber            fLastBound.setEmpty();
245538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        }
246538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
247538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        GrClip                  fLastClip;
248538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // The mask's width & height values are used in setupDrawStateAAClip to
249f71323e297a928af368937089d3ed71239786f86Andreas Huber        // correctly scale the uvs for geometry drawn with this mask
250f71323e297a928af368937089d3ed71239786f86Andreas Huber        GrAutoScratchTexture    fLastMask;
251538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // fLastBound stores the bounding box of the clip mask in canvas
252f71323e297a928af368937089d3ed71239786f86Andreas Huber        // space. The left and top fields are used to offset the uvs for
253538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        // geometry drawn with this mask (in setupDrawStateAAClip)
254538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber        GrIRect                 fLastBound;
255538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    };
256538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
257538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    GrContext*   fContext;
258538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    SkDeque      fStack;
259538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
260538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    typedef GrNoncopyable INHERITED;
261538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber};
262f71323e297a928af368937089d3ed71239786f86Andreas Huber
263f71323e297a928af368937089d3ed71239786f86Andreas Huber/**
264f71323e297a928af368937089d3ed71239786f86Andreas Huber * The clip mask creator handles the generation of the clip mask. If anti
265538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber * aliasing is requested it will (in the future) generate a single channel
266f71323e297a928af368937089d3ed71239786f86Andreas Huber * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit
2671b362b15af34006e6a11974088a46d42b903418eJohann * mask in the stencil buffer. In the non anti-aliasing case, if the clip
268f71323e297a928af368937089d3ed71239786f86Andreas Huber * mask can be represented as a rectangle then scissoring is used. In all
269f71323e297a928af368937089d3ed71239786f86Andreas Huber * cases scissoring is used to bound the range of the clip mask.
270f71323e297a928af368937089d3ed71239786f86Andreas Huber */
271f71323e297a928af368937089d3ed71239786f86Andreas Huberclass GrClipMaskManager : public GrNoncopyable {
272f71323e297a928af368937089d3ed71239786f86Andreas Huberpublic:
2731b362b15af34006e6a11974088a46d42b903418eJohann    GrClipMaskManager(GrGpu* gpu)
274f71323e297a928af368937089d3ed71239786f86Andreas Huber        : fGpu(gpu)
275f71323e297a928af368937089d3ed71239786f86Andreas Huber        , fCurrClipMaskType(kNone_ClipMaskType) {
276f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
277f71323e297a928af368937089d3ed71239786f86Andreas Huber
278f71323e297a928af368937089d3ed71239786f86Andreas Huber    /**
279f71323e297a928af368937089d3ed71239786f86Andreas Huber     * Creates a clip mask if necessary as a stencil buffer or alpha texture
280f71323e297a928af368937089d3ed71239786f86Andreas Huber     * and sets the GrGpu's scissor and stencil state. If the return is false
281f71323e297a928af368937089d3ed71239786f86Andreas Huber     * then the draw can be skipped.
282f71323e297a928af368937089d3ed71239786f86Andreas Huber     */
283f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool setupClipping(const GrClip& clip);
284f71323e297a928af368937089d3ed71239786f86Andreas Huber
285f71323e297a928af368937089d3ed71239786f86Andreas Huber    void releaseResources();
286f71323e297a928af368937089d3ed71239786f86Andreas Huber
2871b362b15af34006e6a11974088a46d42b903418eJohann    bool isClipInStencil() const {
288f71323e297a928af368937089d3ed71239786f86Andreas Huber        return kStencil_ClipMaskType == fCurrClipMaskType;
289f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
290f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool isClipInAlpha() const {
291f71323e297a928af368937089d3ed71239786f86Andreas Huber        return kAlpha_ClipMaskType == fCurrClipMaskType;
2921b362b15af34006e6a11974088a46d42b903418eJohann    }
293f71323e297a928af368937089d3ed71239786f86Andreas Huber
294f71323e297a928af368937089d3ed71239786f86Andreas Huber    void invalidateStencilMask() {
295f71323e297a928af368937089d3ed71239786f86Andreas Huber        if (kStencil_ClipMaskType == fCurrClipMaskType) {
296f71323e297a928af368937089d3ed71239786f86Andreas Huber            fCurrClipMaskType = kNone_ClipMaskType;
297f71323e297a928af368937089d3ed71239786f86Andreas Huber        }
298f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
299f71323e297a928af368937089d3ed71239786f86Andreas Huber
300f71323e297a928af368937089d3ed71239786f86Andreas Huber    void setContext(GrContext* context) {
301f71323e297a928af368937089d3ed71239786f86Andreas Huber        fAACache.setContext(context);
302538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    }
303f71323e297a928af368937089d3ed71239786f86Andreas Huber
304538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    GrContext* getContext() {
305f71323e297a928af368937089d3ed71239786f86Andreas Huber        return fAACache.getContext();
306f71323e297a928af368937089d3ed71239786f86Andreas Huber    }
3071b362b15af34006e6a11974088a46d42b903418eJohann
308f71323e297a928af368937089d3ed71239786f86Andreas Huberprivate:
309f71323e297a928af368937089d3ed71239786f86Andreas Huber    /**
310f71323e297a928af368937089d3ed71239786f86Andreas Huber     * Informs the helper function adjustStencilParams() about how the stencil
311f71323e297a928af368937089d3ed71239786f86Andreas Huber     * buffer clip is being used.
312f71323e297a928af368937089d3ed71239786f86Andreas Huber     */
313f71323e297a928af368937089d3ed71239786f86Andreas Huber    enum StencilClipMode {
314f71323e297a928af368937089d3ed71239786f86Andreas Huber        // Draw to the clip bit of the stencil buffer
315f71323e297a928af368937089d3ed71239786f86Andreas Huber        kModifyClip_StencilClipMode,
316f71323e297a928af368937089d3ed71239786f86Andreas Huber        // Clip against the existing representation of the clip in the high bit
317f71323e297a928af368937089d3ed71239786f86Andreas Huber        // of the stencil buffer.
318f71323e297a928af368937089d3ed71239786f86Andreas Huber        kRespectClip_StencilClipMode,
319f71323e297a928af368937089d3ed71239786f86Andreas Huber        // Neither writing to nor clipping against the clip bit.
320f71323e297a928af368937089d3ed71239786f86Andreas Huber        kIgnoreClip_StencilClipMode,
3211b362b15af34006e6a11974088a46d42b903418eJohann    };
322f71323e297a928af368937089d3ed71239786f86Andreas Huber
323f71323e297a928af368937089d3ed71239786f86Andreas Huber    GrGpu* fGpu;
324f71323e297a928af368937089d3ed71239786f86Andreas Huber
325538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    /**
326f71323e297a928af368937089d3ed71239786f86Andreas Huber     * We may represent the clip as a mask in the stencil buffer or as an alpha
327f71323e297a928af368937089d3ed71239786f86Andreas Huber     * texture. It may be neither because the scissor rect suffices or we
328538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber     * haven't yet examined the clip.
329f71323e297a928af368937089d3ed71239786f86Andreas Huber     */
330538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber    enum ClipMaskType {
331f71323e297a928af368937089d3ed71239786f86Andreas Huber        kNone_ClipMaskType,
332f71323e297a928af368937089d3ed71239786f86Andreas Huber        kStencil_ClipMaskType,
333f71323e297a928af368937089d3ed71239786f86Andreas Huber        kAlpha_ClipMaskType,
334f71323e297a928af368937089d3ed71239786f86Andreas Huber    } fCurrClipMaskType;
335f71323e297a928af368937089d3ed71239786f86Andreas Huber
336f71323e297a928af368937089d3ed71239786f86Andreas Huber    GrClipMaskCache fAACache;       // cache for the AA path
337f71323e297a928af368937089d3ed71239786f86Andreas Huber
338f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool createStencilClipMask(const GrClip& clip,
339f71323e297a928af368937089d3ed71239786f86Andreas Huber                               const GrIRect& bounds);
340f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool createAlphaClipMask(const GrClip& clipIn,
341f71323e297a928af368937089d3ed71239786f86Andreas Huber                             GrTexture** result,
342f71323e297a928af368937089d3ed71239786f86Andreas Huber                             GrIRect *resultBounds);
343f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool createSoftwareClipMask(const GrClip& clipIn,
344f71323e297a928af368937089d3ed71239786f86Andreas Huber                                GrTexture** result,
345f71323e297a928af368937089d3ed71239786f86Andreas Huber                                GrIRect *resultBounds);
346f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool clipMaskPreamble(const GrClip& clipIn,
347f71323e297a928af368937089d3ed71239786f86Andreas Huber                          GrTexture** result,
348f71323e297a928af368937089d3ed71239786f86Andreas Huber                          GrIRect *resultBounds);
3491b362b15af34006e6a11974088a46d42b903418eJohann
350f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool useSWOnlyPath(const GrClip& clipIn);
351f71323e297a928af368937089d3ed71239786f86Andreas Huber
352f71323e297a928af368937089d3ed71239786f86Andreas Huber    bool drawClipShape(GrTexture* target,
353f71323e297a928af368937089d3ed71239786f86Andreas Huber                       const GrClip& clipIn,
354f71323e297a928af368937089d3ed71239786f86Andreas Huber                       int index,
355ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang                       const GrIRect& resultBounds);
356f71323e297a928af368937089d3ed71239786f86Andreas Huber
357f71323e297a928af368937089d3ed71239786f86Andreas Huber    void drawTexture(GrTexture* target,
358f71323e297a928af368937089d3ed71239786f86Andreas Huber                     GrTexture* texture);
359f71323e297a928af368937089d3ed71239786f86Andreas Huber
3601b362b15af34006e6a11974088a46d42b903418eJohann    void getTemp(const GrIRect& bounds, GrAutoScratchTexture* temp);
361f71323e297a928af368937089d3ed71239786f86Andreas Huber
362f71323e297a928af368937089d3ed71239786f86Andreas Huber    void setupCache(const GrClip& clip,
363538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                    const GrIRect& bounds);
364538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber
365f71323e297a928af368937089d3ed71239786f86Andreas Huber    /**
366f71323e297a928af368937089d3ed71239786f86Andreas Huber     * Called prior to return control back the GrGpu in setupClipping. It
367f71323e297a928af368937089d3ed71239786f86Andreas Huber     * updates the GrGpu with stencil settings that account stencil-based
368f71323e297a928af368937089d3ed71239786f86Andreas Huber     * clipping.
369f71323e297a928af368937089d3ed71239786f86Andreas Huber     */
370f71323e297a928af368937089d3ed71239786f86Andreas Huber    void setGpuStencil();
371f71323e297a928af368937089d3ed71239786f86Andreas Huber
372f71323e297a928af368937089d3ed71239786f86Andreas Huber    /**
3731b362b15af34006e6a11974088a46d42b903418eJohann     * Adjusts the stencil settings to account for interaction with stencil
374f71323e297a928af368937089d3ed71239786f86Andreas Huber     * clipping.
375f71323e297a928af368937089d3ed71239786f86Andreas Huber     */
376f71323e297a928af368937089d3ed71239786f86Andreas Huber    void adjustStencilParams(GrStencilSettings* settings,
377538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                             StencilClipMode mode,
378538f6170b788de7408b06efc6613dc98579aa6a6Andreas Huber                             int stencilBitCnt);
379f71323e297a928af368937089d3ed71239786f86Andreas Huber
380f71323e297a928af368937089d3ed71239786f86Andreas Huber    typedef GrNoncopyable INHERITED;
381f71323e297a928af368937089d3ed71239786f86Andreas Huber};
382f71323e297a928af368937089d3ed71239786f86Andreas Huber
383f71323e297a928af368937089d3ed71239786f86Andreas Huber#endif // GrClipMaskManager_DEFINED
384f71323e297a928af368937089d3ed71239786f86Andreas Huber