diff options
-rw-r--r-- | gyp/gpu.gypi | 2 | ||||
-rw-r--r-- | src/gpu/GrClipMaskCache.cpp | 22 | ||||
-rw-r--r-- | src/gpu/GrClipMaskCache.h | 242 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 12 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.h | 227 |
5 files changed, 268 insertions, 237 deletions
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index af8bfe7b18..806acafe87 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -66,6 +66,8 @@ '<(skia_src_path)/gpu/GrDrawTarget.cpp', '<(skia_src_path)/gpu/GrDrawTarget.h', '<(skia_src_path)/gpu/GrGeometryBuffer.h', + '<(skia_src_path)/gpu/GrClipMaskCache.h', + '<(skia_src_path)/gpu/GrClipMaskCache.cpp', '<(skia_src_path)/gpu/GrClipMaskManager.h', '<(skia_src_path)/gpu/GrClipMaskManager.cpp', '<(skia_src_path)/gpu/GrGpu.cpp', diff --git a/src/gpu/GrClipMaskCache.cpp b/src/gpu/GrClipMaskCache.cpp new file mode 100644 index 0000000000..b7cfb65087 --- /dev/null +++ b/src/gpu/GrClipMaskCache.cpp @@ -0,0 +1,22 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrClipMaskCache.h" + +GrClipMaskCache::GrClipMaskCache() + : fContext(NULL) + , fStack(sizeof(GrClipStackFrame)) { + // We need an initial frame to capture the clip state prior to + // any pushes + SkNEW_PLACEMENT(fStack.push_back(), GrClipStackFrame); +} + +void GrClipMaskCache::push() { + SkNEW_PLACEMENT(fStack.push_back(), GrClipStackFrame); +} + diff --git a/src/gpu/GrClipMaskCache.h b/src/gpu/GrClipMaskCache.h new file mode 100644 index 0000000000..f1152cc6be --- /dev/null +++ b/src/gpu/GrClipMaskCache.h @@ -0,0 +1,242 @@ +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef GrClipMaskCache_DEFINED +#define GrClipMaskCache_DEFINED + +#include "GrContext.h" +#include "GrNoncopyable.h" +#include "SkClipStack.h" + +class GrTexture; + +/** + * The stencil buffer stores the last clip path - providing a single entry + * "cache". This class provides similar functionality for AA clip paths + */ +class GrClipMaskCache : public GrNoncopyable { +public: + GrClipMaskCache(); + + ~GrClipMaskCache() { + + while (!fStack.empty()) { + GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back(); + temp->~GrClipStackFrame(); + fStack.pop_back(); + } + } + + bool canReuse(const SkClipStack& clip, int width, int height) { + + if (fStack.empty()) { + GrAssert(false); + return false; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + if (back->fLastMask.texture() && + back->fLastMask.texture()->width() >= width && + back->fLastMask.texture()->height() >= height && + clip == back->fLastClip) { + return true; + } + + return false; + } + + void reset() { + if (fStack.empty()) { +// GrAssert(false); + return; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + back->reset(); + } + + /** + * After a "push" the clip state is entirely open. Currently, the + * entire clip stack will be re-rendered into a new clip mask. + * TODO: can we take advantage of the nested nature of the clips to + * reduce the mask creation cost? + */ + void push(); + + void pop() { + //GrAssert(!fStack.empty()); + + if (!fStack.empty()) { + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + back->~GrClipStackFrame(); + fStack.pop_back(); + } + } + + void getLastClip(SkClipStack* clip) const { + + if (fStack.empty()) { + GrAssert(false); + clip->reset(); + return; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + *clip = back->fLastClip; + } + + GrTexture* getLastMask() { + + if (fStack.empty()) { + GrAssert(false); + return NULL; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + return back->fLastMask.texture(); + } + + const GrTexture* getLastMask() const { + + if (fStack.empty()) { + GrAssert(false); + return NULL; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + return back->fLastMask.texture(); + } + + void acquireMask(const SkClipStack& clip, + const GrTextureDesc& desc, + const GrIRect& bound) { + + if (fStack.empty()) { + GrAssert(false); + return; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + back->acquireMask(fContext, clip, desc, bound); + } + + int getLastMaskWidth() const { + + if (fStack.empty()) { + GrAssert(false); + return -1; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + if (NULL == back->fLastMask.texture()) { + return -1; + } + + return back->fLastMask.texture()->width(); + } + + int getLastMaskHeight() const { + + if (fStack.empty()) { + GrAssert(false); + return -1; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + if (NULL == back->fLastMask.texture()) { + return -1; + } + + return back->fLastMask.texture()->height(); + } + + void getLastBound(GrIRect* bound) const { + + if (fStack.empty()) { + GrAssert(false); + bound->setEmpty(); + return; + } + + GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); + + *bound = back->fLastBound; + } + + void setContext(GrContext* context) { + fContext = context; + } + + GrContext* getContext() { + return fContext; + } + + void releaseResources() { + + SkDeque::F2BIter iter(fStack); + for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next(); + frame != NULL; + frame = (GrClipStackFrame*) iter.next()) { + frame->reset(); + } + } + +protected: +private: + struct GrClipStackFrame { + + GrClipStackFrame() { + reset(); + } + + void acquireMask(GrContext* context, + const SkClipStack& clip, + const GrTextureDesc& desc, + const GrIRect& bound) { + + fLastClip = clip; + + fLastMask.set(context, desc); + + fLastBound = bound; + } + + void reset () { + fLastClip.reset(); + + GrTextureDesc desc; + + fLastMask.set(NULL, desc); + fLastBound.setEmpty(); + } + + SkClipStack fLastClip; + // The mask's width & height values are used in setupDrawStateAAClip to + // correctly scale the uvs for geometry drawn with this mask + GrAutoScratchTexture fLastMask; + // fLastBound stores the bounding box of the clip mask in canvas + // space. The left and top fields are used to offset the uvs for + // geometry drawn with this mask (in setupDrawStateAAClip) + GrIRect fLastBound; + }; + + GrContext* fContext; + SkDeque fStack; + + typedef GrNoncopyable INHERITED; +}; + +#endif // GrClipMaskCache_DEFINED diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 4968c0bdfb..d80868d31e 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -23,18 +23,6 @@ GR_DEFINE_RESOURCE_CACHE_DOMAIN(GrClipMaskManager, GetAlphaMaskDomain) //#define GR_AA_CLIP 1 //#define GR_SW_CLIP 1 -GrClipMaskCache::GrClipMaskCache() - : fContext(NULL) - , fStack(sizeof(GrClipStackFrame)) { - // We need an initial frame to capture the clip state prior to - // any pushes - SkNEW_PLACEMENT(fStack.push_back(), GrClipStackFrame); -} - -void GrClipMaskCache::push() { - SkNEW_PLACEMENT(fStack.push_back(), GrClipStackFrame); -} - //////////////////////////////////////////////////////////////////////////////// namespace { // set up the draw state to enable the aa clipping mask. Besides setting up the diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index fe56ded5fa..d23a525e7a 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -20,6 +20,8 @@ #include "SkPath.h" #include "SkRefCnt.h" +#include "GrClipMaskCache.h" + class GrGpu; class GrPathRenderer; class GrPathRendererChain; @@ -28,231 +30,6 @@ class GrTexture; class GrDrawState; /** - * The stencil buffer stores the last clip path - providing a single entry - * "cache". This class provides similar functionality for AA clip paths - */ -class GrClipMaskCache : public GrNoncopyable { -public: - GrClipMaskCache(); - - ~GrClipMaskCache() { - - while (!fStack.empty()) { - GrClipStackFrame* temp = (GrClipStackFrame*) fStack.back(); - temp->~GrClipStackFrame(); - fStack.pop_back(); - } - } - - bool canReuse(const SkClipStack& clip, int width, int height) { - - if (fStack.empty()) { - GrAssert(false); - return false; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - if (back->fLastMask.texture() && - back->fLastMask.texture()->width() >= width && - back->fLastMask.texture()->height() >= height && - clip == back->fLastClip) { - return true; - } - - return false; - } - - void reset() { - if (fStack.empty()) { -// GrAssert(false); - return; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - back->reset(); - } - - /** - * After a "push" the clip state is entirely open. Currently, the - * entire clip stack will be re-rendered into a new clip mask. - * TODO: can we take advantage of the nested nature of the clips to - * reduce the mask creation cost? - */ - void push(); - - void pop() { - //GrAssert(!fStack.empty()); - - if (!fStack.empty()) { - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - back->~GrClipStackFrame(); - fStack.pop_back(); - } - } - - void getLastClip(SkClipStack* clip) const { - - if (fStack.empty()) { - GrAssert(false); - clip->reset(); - return; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - *clip = back->fLastClip; - } - - GrTexture* getLastMask() { - - if (fStack.empty()) { - GrAssert(false); - return NULL; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - return back->fLastMask.texture(); - } - - const GrTexture* getLastMask() const { - - if (fStack.empty()) { - GrAssert(false); - return NULL; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - return back->fLastMask.texture(); - } - - void acquireMask(const SkClipStack& clip, - const GrTextureDesc& desc, - const GrIRect& bound) { - - if (fStack.empty()) { - GrAssert(false); - return; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - back->acquireMask(fContext, clip, desc, bound); - } - - int getLastMaskWidth() const { - - if (fStack.empty()) { - GrAssert(false); - return -1; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - if (NULL == back->fLastMask.texture()) { - return -1; - } - - return back->fLastMask.texture()->width(); - } - - int getLastMaskHeight() const { - - if (fStack.empty()) { - GrAssert(false); - return -1; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - if (NULL == back->fLastMask.texture()) { - return -1; - } - - return back->fLastMask.texture()->height(); - } - - void getLastBound(GrIRect* bound) const { - - if (fStack.empty()) { - GrAssert(false); - bound->setEmpty(); - return; - } - - GrClipStackFrame* back = (GrClipStackFrame*) fStack.back(); - - *bound = back->fLastBound; - } - - void setContext(GrContext* context) { - fContext = context; - } - - GrContext* getContext() { - return fContext; - } - - void releaseResources() { - - SkDeque::F2BIter iter(fStack); - for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next(); - frame != NULL; - frame = (GrClipStackFrame*) iter.next()) { - frame->reset(); - } - } - -protected: -private: - struct GrClipStackFrame { - - GrClipStackFrame() { - reset(); - } - - void acquireMask(GrContext* context, - const SkClipStack& clip, - const GrTextureDesc& desc, - const GrIRect& bound) { - - fLastClip = clip; - - fLastMask.set(context, desc); - - fLastBound = bound; - } - - void reset () { - fLastClip.reset(); - - GrTextureDesc desc; - - fLastMask.set(NULL, desc); - fLastBound.setEmpty(); - } - - SkClipStack fLastClip; - // The mask's width & height values are used in setupDrawStateAAClip to - // correctly scale the uvs for geometry drawn with this mask - GrAutoScratchTexture fLastMask; - // fLastBound stores the bounding box of the clip mask in canvas - // space. The left and top fields are used to offset the uvs for - // geometry drawn with this mask (in setupDrawStateAAClip) - GrIRect fLastBound; - }; - - GrContext* fContext; - SkDeque fStack; - - typedef GrNoncopyable INHERITED; -}; - -/** * The clip mask creator handles the generation of the clip mask. If anti * aliasing is requested it will (in the future) generate a single channel * (8bit) mask. If no anti aliasing is requested it will generate a 1-bit |