OLD | NEW |
| (Empty) |
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 | |
8 #ifndef GrClipMaskCache_DEFINED | |
9 #define GrClipMaskCache_DEFINED | |
10 | |
11 #include "GrResourceProvider.h" | |
12 #include "SkClipStack.h" | |
13 #include "SkTypes.h" | |
14 | |
15 class GrTexture; | |
16 | |
17 /** | |
18 * The stencil buffer stores the last clip path - providing a single entry | |
19 * "cache". This class provides similar functionality for AA clip paths | |
20 */ | |
21 class GrClipMaskCache : SkNoncopyable { | |
22 public: | |
23 GrClipMaskCache(GrResourceProvider*); | |
24 | |
25 ~GrClipMaskCache() { | |
26 while (!fStack.empty()) { | |
27 GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back(); | |
28 temp->~GrClipStackFrame(); | |
29 fStack.pop_back(); | |
30 } | |
31 } | |
32 | |
33 bool canReuse(int32_t clipGenID, const SkIRect& bounds) { | |
34 | |
35 SkASSERT(clipGenID != SkClipStack::kWideOpenGenID); | |
36 SkASSERT(clipGenID != SkClipStack::kEmptyGenID); | |
37 | |
38 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
39 | |
40 // We could reuse the mask if bounds is a subset of last bounds. We'd ha
ve to communicate | |
41 // an offset to the caller. | |
42 if (back->fLastMask && | |
43 !back->fLastMask->wasDestroyed() && | |
44 back->fLastBound == bounds && | |
45 back->fLastClipGenID == clipGenID) { | |
46 return true; | |
47 } | |
48 | |
49 return false; | |
50 } | |
51 | |
52 void reset() { | |
53 if (fStack.empty()) { | |
54 // SkASSERT(false); | |
55 return; | |
56 } | |
57 | |
58 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
59 | |
60 back->reset(); | |
61 } | |
62 | |
63 /** | |
64 * After a "push" the clip state is entirely open. Currently, the | |
65 * entire clip stack will be re-rendered into a new clip mask. | |
66 * TODO: can we take advantage of the nested nature of the clips to | |
67 * reduce the mask creation cost? | |
68 */ | |
69 void push(); | |
70 | |
71 void pop() { | |
72 //SkASSERT(!fStack.empty()); | |
73 | |
74 if (!fStack.empty()) { | |
75 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
76 | |
77 back->~GrClipStackFrame(); | |
78 fStack.pop_back(); | |
79 } | |
80 } | |
81 | |
82 int32_t getLastClipGenID() const { | |
83 | |
84 if (fStack.empty()) { | |
85 return SkClipStack::kInvalidGenID; | |
86 } | |
87 | |
88 return ((GrClipStackFrame*) fStack.back())->fLastClipGenID; | |
89 } | |
90 | |
91 GrTexture* getLastMask() { | |
92 | |
93 if (fStack.empty()) { | |
94 SkASSERT(false); | |
95 return nullptr; | |
96 } | |
97 | |
98 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
99 | |
100 return back->fLastMask; | |
101 } | |
102 | |
103 const GrTexture* getLastMask() const { | |
104 | |
105 if (fStack.empty()) { | |
106 SkASSERT(false); | |
107 return nullptr; | |
108 } | |
109 | |
110 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
111 | |
112 return back->fLastMask; | |
113 } | |
114 | |
115 void acquireMask(int32_t clipGenID, | |
116 const GrSurfaceDesc& desc, | |
117 const SkIRect& bound) { | |
118 | |
119 if (fStack.empty()) { | |
120 SkASSERT(false); | |
121 return; | |
122 } | |
123 | |
124 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
125 | |
126 back->acquireMask(fResourceProvider, clipGenID, desc, bound); | |
127 } | |
128 | |
129 int getLastMaskWidth() const { | |
130 | |
131 if (fStack.empty()) { | |
132 SkASSERT(false); | |
133 return -1; | |
134 } | |
135 | |
136 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
137 | |
138 if (nullptr == back->fLastMask) { | |
139 return -1; | |
140 } | |
141 | |
142 return back->fLastMask->width(); | |
143 } | |
144 | |
145 int getLastMaskHeight() const { | |
146 | |
147 if (fStack.empty()) { | |
148 SkASSERT(false); | |
149 return -1; | |
150 } | |
151 | |
152 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
153 | |
154 if (nullptr == back->fLastMask) { | |
155 return -1; | |
156 } | |
157 | |
158 return back->fLastMask->height(); | |
159 } | |
160 | |
161 void getLastBound(SkIRect* bound) const { | |
162 | |
163 if (fStack.empty()) { | |
164 SkASSERT(false); | |
165 bound->setEmpty(); | |
166 return; | |
167 } | |
168 | |
169 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); | |
170 | |
171 *bound = back->fLastBound; | |
172 } | |
173 | |
174 // TODO: Remove this when we hold cache keys instead of refs to textures. | |
175 void purgeResources() { | |
176 SkDeque::F2BIter iter(fStack); | |
177 for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next(); | |
178 frame != nullptr; | |
179 frame = (GrClipStackFrame*) iter.next()) { | |
180 frame->reset(); | |
181 } | |
182 } | |
183 | |
184 private: | |
185 struct GrClipStackFrame { | |
186 | |
187 GrClipStackFrame() { | |
188 this->reset(); | |
189 } | |
190 | |
191 void acquireMask(GrResourceProvider* resourceProvider, | |
192 int32_t clipGenID, | |
193 const GrSurfaceDesc& desc, | |
194 const SkIRect& bound) { | |
195 | |
196 fLastClipGenID = clipGenID; | |
197 | |
198 // TODO: Determine if we really need the NoPendingIO flag anymore. | |
199 // (http://skbug.com/4156) | |
200 static const uint32_t kFlags = GrResourceProvider::kNoPendingIO_Flag
; | |
201 fLastMask.reset(resourceProvider->createApproxTexture(desc, kFlags))
; | |
202 | |
203 fLastBound = bound; | |
204 } | |
205 | |
206 void reset () { | |
207 fLastClipGenID = SkClipStack::kInvalidGenID; | |
208 | |
209 GrSurfaceDesc desc; | |
210 | |
211 fLastMask.reset(nullptr); | |
212 fLastBound.setEmpty(); | |
213 } | |
214 | |
215 int32_t fLastClipGenID; | |
216 // The mask's width & height values are used by GrClipMaskManager to cor
rectly scale the | |
217 // texture coords for the geometry drawn with this mask. TODO: This shou
ld be a cache key | |
218 // and not a hard ref to a texture. | |
219 SkAutoTUnref<GrTexture> fLastMask; | |
220 // fLastBound stores the bounding box of the clip mask in clip-stack spa
ce. This rect is | |
221 // used by GrClipMaskManager to position a rect and compute texture coor
ds for the mask. | |
222 SkIRect fLastBound; | |
223 }; | |
224 | |
225 SkDeque fStack; | |
226 GrResourceProvider* fResourceProvider; | |
227 | |
228 typedef SkNoncopyable INHERITED; | |
229 }; | |
230 | |
231 #endif // GrClipMaskCache_DEFINED | |
OLD | NEW |