1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrClipMaskCache.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,235 @@ 1.4 +/* 1.5 + * Copyright 2012 Google Inc. 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#ifndef GrClipMaskCache_DEFINED 1.12 +#define GrClipMaskCache_DEFINED 1.13 + 1.14 +#include "GrContext.h" 1.15 +#include "SkClipStack.h" 1.16 +#include "SkTypes.h" 1.17 + 1.18 +class GrTexture; 1.19 + 1.20 +/** 1.21 + * The stencil buffer stores the last clip path - providing a single entry 1.22 + * "cache". This class provides similar functionality for AA clip paths 1.23 + */ 1.24 +class GrClipMaskCache : public SkNoncopyable { 1.25 +public: 1.26 + GrClipMaskCache(); 1.27 + 1.28 + ~GrClipMaskCache() { 1.29 + 1.30 + while (!fStack.empty()) { 1.31 + GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back(); 1.32 + temp->~GrClipStackFrame(); 1.33 + fStack.pop_back(); 1.34 + } 1.35 + } 1.36 + 1.37 + bool canReuse(int32_t clipGenID, const SkIRect& bounds) { 1.38 + 1.39 + SkASSERT(clipGenID != SkClipStack::kWideOpenGenID); 1.40 + SkASSERT(clipGenID != SkClipStack::kEmptyGenID); 1.41 + 1.42 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.43 + 1.44 + // We could reuse the mask if bounds is a subset of last bounds. We'd have to communicate 1.45 + // an offset to the caller. 1.46 + if (back->fLastMask.texture() && 1.47 + back->fLastBound == bounds && 1.48 + back->fLastClipGenID == clipGenID) { 1.49 + return true; 1.50 + } 1.51 + 1.52 + return false; 1.53 + } 1.54 + 1.55 + void reset() { 1.56 + if (fStack.empty()) { 1.57 +// SkASSERT(false); 1.58 + return; 1.59 + } 1.60 + 1.61 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.62 + 1.63 + back->reset(); 1.64 + } 1.65 + 1.66 + /** 1.67 + * After a "push" the clip state is entirely open. Currently, the 1.68 + * entire clip stack will be re-rendered into a new clip mask. 1.69 + * TODO: can we take advantage of the nested nature of the clips to 1.70 + * reduce the mask creation cost? 1.71 + */ 1.72 + void push(); 1.73 + 1.74 + void pop() { 1.75 + //SkASSERT(!fStack.empty()); 1.76 + 1.77 + if (!fStack.empty()) { 1.78 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.79 + 1.80 + back->~GrClipStackFrame(); 1.81 + fStack.pop_back(); 1.82 + } 1.83 + } 1.84 + 1.85 + int32_t getLastClipGenID() const { 1.86 + 1.87 + if (fStack.empty()) { 1.88 + return SkClipStack::kInvalidGenID; 1.89 + } 1.90 + 1.91 + return ((GrClipStackFrame*) fStack.back())->fLastClipGenID; 1.92 + } 1.93 + 1.94 + GrTexture* getLastMask() { 1.95 + 1.96 + if (fStack.empty()) { 1.97 + SkASSERT(false); 1.98 + return NULL; 1.99 + } 1.100 + 1.101 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.102 + 1.103 + return back->fLastMask.texture(); 1.104 + } 1.105 + 1.106 + const GrTexture* getLastMask() const { 1.107 + 1.108 + if (fStack.empty()) { 1.109 + SkASSERT(false); 1.110 + return NULL; 1.111 + } 1.112 + 1.113 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.114 + 1.115 + return back->fLastMask.texture(); 1.116 + } 1.117 + 1.118 + void acquireMask(int32_t clipGenID, 1.119 + const GrTextureDesc& desc, 1.120 + const SkIRect& bound) { 1.121 + 1.122 + if (fStack.empty()) { 1.123 + SkASSERT(false); 1.124 + return; 1.125 + } 1.126 + 1.127 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.128 + 1.129 + back->acquireMask(fContext, clipGenID, desc, bound); 1.130 + } 1.131 + 1.132 + int getLastMaskWidth() const { 1.133 + 1.134 + if (fStack.empty()) { 1.135 + SkASSERT(false); 1.136 + return -1; 1.137 + } 1.138 + 1.139 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.140 + 1.141 + if (NULL == back->fLastMask.texture()) { 1.142 + return -1; 1.143 + } 1.144 + 1.145 + return back->fLastMask.texture()->width(); 1.146 + } 1.147 + 1.148 + int getLastMaskHeight() const { 1.149 + 1.150 + if (fStack.empty()) { 1.151 + SkASSERT(false); 1.152 + return -1; 1.153 + } 1.154 + 1.155 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.156 + 1.157 + if (NULL == back->fLastMask.texture()) { 1.158 + return -1; 1.159 + } 1.160 + 1.161 + return back->fLastMask.texture()->height(); 1.162 + } 1.163 + 1.164 + void getLastBound(SkIRect* bound) const { 1.165 + 1.166 + if (fStack.empty()) { 1.167 + SkASSERT(false); 1.168 + bound->setEmpty(); 1.169 + return; 1.170 + } 1.171 + 1.172 + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); 1.173 + 1.174 + *bound = back->fLastBound; 1.175 + } 1.176 + 1.177 + void setContext(GrContext* context) { 1.178 + fContext = context; 1.179 + } 1.180 + 1.181 + GrContext* getContext() { 1.182 + return fContext; 1.183 + } 1.184 + 1.185 + void releaseResources() { 1.186 + 1.187 + SkDeque::F2BIter iter(fStack); 1.188 + for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next(); 1.189 + frame != NULL; 1.190 + frame = (GrClipStackFrame*) iter.next()) { 1.191 + frame->reset(); 1.192 + } 1.193 + } 1.194 + 1.195 +private: 1.196 + struct GrClipStackFrame { 1.197 + 1.198 + GrClipStackFrame() { 1.199 + this->reset(); 1.200 + } 1.201 + 1.202 + void acquireMask(GrContext* context, 1.203 + int32_t clipGenID, 1.204 + const GrTextureDesc& desc, 1.205 + const SkIRect& bound) { 1.206 + 1.207 + fLastClipGenID = clipGenID; 1.208 + 1.209 + fLastMask.set(context, desc); 1.210 + 1.211 + fLastBound = bound; 1.212 + } 1.213 + 1.214 + void reset () { 1.215 + fLastClipGenID = SkClipStack::kInvalidGenID; 1.216 + 1.217 + GrTextureDesc desc; 1.218 + 1.219 + fLastMask.set(NULL, desc); 1.220 + fLastBound.setEmpty(); 1.221 + } 1.222 + 1.223 + int32_t fLastClipGenID; 1.224 + // The mask's width & height values are used by GrClipMaskManager to correctly scale the 1.225 + // texture coords for the geometry drawn with this mask. 1.226 + GrAutoScratchTexture fLastMask; 1.227 + // fLastBound stores the bounding box of the clip mask in clip-stack space. This rect is 1.228 + // used by GrClipMaskManager to position a rect and compute texture coords for the mask. 1.229 + SkIRect fLastBound; 1.230 + }; 1.231 + 1.232 + GrContext* fContext; 1.233 + SkDeque fStack; 1.234 + 1.235 + typedef SkNoncopyable INHERITED; 1.236 +}; 1.237 + 1.238 +#endif // GrClipMaskCache_DEFINED