2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #ifndef GrClipMaskCache_DEFINED
9 #define GrClipMaskCache_DEFINED
11 #include "GrContext.h"
12 #include "SkClipStack.h"
18 * The stencil buffer stores the last clip path - providing a single entry
19 * "cache". This class provides similar functionality for AA clip paths
21 class GrClipMaskCache : SkNoncopyable {
27 while (!fStack.empty()) {
28 GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back();
29 temp->~GrClipStackFrame();
34 bool canReuse(int32_t clipGenID, const SkIRect& bounds) {
36 SkASSERT(clipGenID != SkClipStack::kWideOpenGenID);
37 SkASSERT(clipGenID != SkClipStack::kEmptyGenID);
39 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
41 // We could reuse the mask if bounds is a subset of last bounds. We'd have to communicate
42 // an offset to the caller.
43 if (back->fLastMask &&
44 !back->fLastMask->wasDestroyed() &&
45 back->fLastBound == bounds &&
46 back->fLastClipGenID == clipGenID) {
59 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
65 * After a "push" the clip state is entirely open. Currently, the
66 * entire clip stack will be re-rendered into a new clip mask.
67 * TODO: can we take advantage of the nested nature of the clips to
68 * reduce the mask creation cost?
73 //SkASSERT(!fStack.empty());
75 if (!fStack.empty()) {
76 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
78 back->~GrClipStackFrame();
83 int32_t getLastClipGenID() const {
86 return SkClipStack::kInvalidGenID;
89 return ((GrClipStackFrame*) fStack.back())->fLastClipGenID;
92 GrTexture* getLastMask() {
99 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
101 return back->fLastMask;
104 const GrTexture* getLastMask() const {
106 if (fStack.empty()) {
111 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
113 return back->fLastMask;
116 void acquireMask(int32_t clipGenID,
117 const GrSurfaceDesc& desc,
118 const SkIRect& bound) {
120 if (fStack.empty()) {
125 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
127 back->acquireMask(fContext, clipGenID, desc, bound);
130 int getLastMaskWidth() const {
132 if (fStack.empty()) {
137 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
139 if (NULL == back->fLastMask) {
143 return back->fLastMask->width();
146 int getLastMaskHeight() const {
148 if (fStack.empty()) {
153 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
155 if (NULL == back->fLastMask) {
159 return back->fLastMask->height();
162 void getLastBound(SkIRect* bound) const {
164 if (fStack.empty()) {
170 GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
172 *bound = back->fLastBound;
175 void setContext(GrContext* context) {
179 GrContext* getContext() {
183 // TODO: Remove this when we hold cache keys instead of refs to textures.
184 void purgeResources() {
185 SkDeque::F2BIter iter(fStack);
186 for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next();
188 frame = (GrClipStackFrame*) iter.next()) {
194 struct GrClipStackFrame {
200 void acquireMask(GrContext* context,
202 const GrSurfaceDesc& desc,
203 const SkIRect& bound) {
205 fLastClipGenID = clipGenID;
207 // HACK: set the last param to true to indicate that this request is at
208 // flush time and therefore we require a scratch texture with no pending IO operations.
209 fLastMask.reset(context->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch,
216 fLastClipGenID = SkClipStack::kInvalidGenID;
220 fLastMask.reset(NULL);
221 fLastBound.setEmpty();
224 int32_t fLastClipGenID;
225 // The mask's width & height values are used by GrClipMaskManager to correctly scale the
226 // texture coords for the geometry drawn with this mask. TODO: This should be a cache key
227 // and not a hard ref to a texture.
228 SkAutoTUnref<GrTexture> fLastMask;
229 // fLastBound stores the bounding box of the clip mask in clip-stack space. This rect is
230 // used by GrClipMaskManager to position a rect and compute texture coords for the mask.
237 typedef SkNoncopyable INHERITED;
240 #endif // GrClipMaskCache_DEFINED