gfx/skia/trunk/src/gpu/GrClipMaskCache.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial