Made clip mask cache use Scratch Texture system
http://codereview.appspot.com/6210044/ git-svn-id: http://skia.googlecode.com/svn/trunk@3920 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
18c464b460
commit
f105b10926
@ -853,6 +853,7 @@ public:
|
|||||||
GrContext::kApprox_ScratchTexMatch) {
|
GrContext::kApprox_ScratchTexMatch) {
|
||||||
if (NULL != fContext) {
|
if (NULL != fContext) {
|
||||||
fContext->unlockTexture(fEntry);
|
fContext->unlockTexture(fEntry);
|
||||||
|
fEntry.reset();
|
||||||
}
|
}
|
||||||
fContext = context;
|
fContext = context;
|
||||||
if (NULL != fContext) {
|
if (NULL != fContext) {
|
||||||
|
@ -338,7 +338,6 @@ bool GrClipMaskManager::drawClipShape(GrGpu* gpu,
|
|||||||
|
|
||||||
void GrClipMaskManager::drawTexture(GrGpu* gpu,
|
void GrClipMaskManager::drawTexture(GrGpu* gpu,
|
||||||
GrTexture* target,
|
GrTexture* target,
|
||||||
const GrRect& rect,
|
|
||||||
GrTexture* texture) {
|
GrTexture* texture) {
|
||||||
GrDrawState* drawState = gpu->drawState();
|
GrDrawState* drawState = gpu->drawState();
|
||||||
GrAssert(NULL != drawState);
|
GrAssert(NULL != drawState);
|
||||||
@ -354,6 +353,9 @@ void GrClipMaskManager::drawTexture(GrGpu* gpu,
|
|||||||
GrSamplerState::kNearest_Filter,
|
GrSamplerState::kNearest_Filter,
|
||||||
sampleM);
|
sampleM);
|
||||||
|
|
||||||
|
GrRect rect = GrRect::MakeWH(SkIntToScalar(target->width()),
|
||||||
|
SkIntToScalar(target->height()));
|
||||||
|
|
||||||
gpu->drawSimpleRect(rect, NULL, 1 << 0);
|
gpu->drawSimpleRect(rect, NULL, 1 << 0);
|
||||||
|
|
||||||
drawState->setTexture(0, NULL);
|
drawState->setTexture(0, NULL);
|
||||||
@ -372,10 +374,13 @@ void clear(GrGpu* gpu,
|
|||||||
gpu->clear(NULL, color);
|
gpu->clear(NULL, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// get a texture to act as a temporary buffer for AA clip boolean operations
|
// get a texture to act as a temporary buffer for AA clip boolean operations
|
||||||
// TODO: given the expense of createTexture we may want to just cache this too
|
// TODO: given the expense of createTexture we may want to just cache this too
|
||||||
void get_temp(GrGpu *gpu, const GrRect& bounds, GrTexture** temp) {
|
void GrClipMaskManager::getTemp(const GrRect& bounds,
|
||||||
if (NULL != *temp) {
|
GrAutoScratchTexture* temp) {
|
||||||
|
if (NULL != temp->texture()) {
|
||||||
// we've already allocated the temp texture
|
// we've already allocated the temp texture
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -388,39 +393,27 @@ void get_temp(GrGpu *gpu, const GrRect& bounds, GrTexture** temp) {
|
|||||||
0 // samples
|
0 // samples
|
||||||
};
|
};
|
||||||
|
|
||||||
*temp = gpu->createTexture(desc, NULL, 0);
|
temp->set(fAACache.getContext(), desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GrClipMaskManager::setupCache(const GrClip& clipIn,
|
||||||
|
const GrRect& bounds) {
|
||||||
|
// Since we are setting up the cache we know the last lookup was a miss
|
||||||
|
// Free up the currently cached mask so it can be reused
|
||||||
|
fAACache.reset();
|
||||||
|
|
||||||
|
const GrTextureDesc desc = {
|
||||||
|
kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit,
|
||||||
|
SkScalarCeilToInt(bounds.width()),
|
||||||
|
SkScalarCeilToInt(bounds.height()),
|
||||||
|
kAlpha_8_GrPixelConfig,
|
||||||
|
0 // samples
|
||||||
|
};
|
||||||
|
|
||||||
|
fAACache.acquireMask(clipIn, desc, bounds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrClipMaskManager::getAccum(GrGpu* gpu,
|
|
||||||
const GrRect& bounds,
|
|
||||||
GrTexture** accum) {
|
|
||||||
GrAssert(NULL == *accum);
|
|
||||||
|
|
||||||
// since we are getting an accumulator we know our cache is shot. See
|
|
||||||
// if we can reuse the texture stored in the cache
|
|
||||||
if (fAACache.getLastMaskWidth() >= bounds.width() &&
|
|
||||||
fAACache.getLastMaskHeight() >= bounds.height()) {
|
|
||||||
// we can just reuse the existing texture
|
|
||||||
*accum = fAACache.detachLastMask();
|
|
||||||
fAACache.reset();
|
|
||||||
} else {
|
|
||||||
const GrTextureDesc desc = {
|
|
||||||
kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit,
|
|
||||||
SkScalarCeilToInt(bounds.width()),
|
|
||||||
SkScalarCeilToInt(bounds.height()),
|
|
||||||
kAlpha_8_GrPixelConfig,
|
|
||||||
0 // samples
|
|
||||||
};
|
|
||||||
|
|
||||||
*accum = gpu->createTexture(desc, NULL, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
GrAssert(1 == (*accum)->getRefCnt());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// Shared preamble between gpu and SW-only AA clip mask creation paths.
|
// Shared preamble between gpu and SW-only AA clip mask creation paths.
|
||||||
// Handles caching, determination of clip mask bound & allocation (if needed)
|
// Handles caching, determination of clip mask bound & allocation (if needed)
|
||||||
@ -429,8 +422,7 @@ void GrClipMaskManager::getAccum(GrGpu* gpu,
|
|||||||
bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
|
bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
|
||||||
const GrClip& clipIn,
|
const GrClip& clipIn,
|
||||||
GrTexture** result,
|
GrTexture** result,
|
||||||
GrRect *resultBounds,
|
GrRect *resultBounds) {
|
||||||
GrTexture** maskStorage) {
|
|
||||||
GrDrawState* origDrawState = gpu->drawState();
|
GrDrawState* origDrawState = gpu->drawState();
|
||||||
GrAssert(origDrawState->isClipState());
|
GrAssert(origDrawState->isClipState());
|
||||||
|
|
||||||
@ -441,7 +433,6 @@ bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
|
|||||||
rtRect.setLTRB(0, 0,
|
rtRect.setLTRB(0, 0,
|
||||||
GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
|
GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
|
||||||
|
|
||||||
|
|
||||||
// unlike the stencil path the alpha path is not bound to the size of the
|
// unlike the stencil path the alpha path is not bound to the size of the
|
||||||
// render target - determine the minimum size required for the mask
|
// render target - determine the minimum size required for the mask
|
||||||
GrRect bounds;
|
GrRect bounds;
|
||||||
@ -477,7 +468,8 @@ bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->getAccum(gpu, bounds, maskStorage);
|
this->setupCache(clipIn, bounds);
|
||||||
|
|
||||||
*resultBounds = bounds;
|
*resultBounds = bounds;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -489,19 +481,17 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
|
|||||||
GrTexture** result,
|
GrTexture** result,
|
||||||
GrRect *resultBounds) {
|
GrRect *resultBounds) {
|
||||||
|
|
||||||
GrTexture* accum = NULL;
|
if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) {
|
||||||
if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds, &accum)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrTexture* accum = fAACache.getLastMask();
|
||||||
if (NULL == accum) {
|
if (NULL == accum) {
|
||||||
fClipMaskInAlpha = false;
|
fClipMaskInAlpha = false;
|
||||||
|
fAACache.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrRect newRTBounds;
|
|
||||||
newRTBounds.setLTRB(0, 0, resultBounds->width(), resultBounds->height());
|
|
||||||
|
|
||||||
GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit);
|
GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit);
|
||||||
GrDrawState* drawState = gpu->drawState();
|
GrDrawState* drawState = gpu->drawState();
|
||||||
|
|
||||||
@ -528,7 +518,7 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
|
|||||||
|
|
||||||
clear(gpu, accum, clearToInside ? 0xffffffff : 0x00000000);
|
clear(gpu, accum, clearToInside ? 0xffffffff : 0x00000000);
|
||||||
|
|
||||||
GrTexture* temp = NULL;
|
GrAutoScratchTexture temp;
|
||||||
|
|
||||||
// walk through each clip element and perform its set op
|
// walk through each clip element and perform its set op
|
||||||
for (int c = start; c < count; ++c) {
|
for (int c = start; c < count; ++c) {
|
||||||
@ -555,18 +545,18 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_temp(gpu, *resultBounds, &temp);
|
getTemp(*resultBounds, &temp);
|
||||||
if (NULL == temp) {
|
if (NULL == temp.texture()) {
|
||||||
fClipMaskInAlpha = false;
|
fClipMaskInAlpha = false;
|
||||||
SkSafeUnref(accum);
|
fAACache.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the temp target & draw into it
|
// clear the temp target & draw into it
|
||||||
clear(gpu, temp, 0x00000000);
|
clear(gpu, temp.texture(), 0x00000000);
|
||||||
|
|
||||||
setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
|
setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
|
||||||
this->drawClipShape(gpu, temp, clipIn, c);
|
this->drawClipShape(gpu, temp.texture(), clipIn, c);
|
||||||
|
|
||||||
// TODO: rather than adding these two translations here
|
// TODO: rather than adding these two translations here
|
||||||
// compute the bounding box needed to render the texture
|
// compute the bounding box needed to render the texture
|
||||||
@ -582,7 +572,7 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
|
|||||||
// Now draw into the accumulator using the real operation
|
// Now draw into the accumulator using the real operation
|
||||||
// and the temp buffer as a texture
|
// and the temp buffer as a texture
|
||||||
setup_boolean_blendcoeffs(drawState, op);
|
setup_boolean_blendcoeffs(drawState, op);
|
||||||
this->drawTexture(gpu, accum, newRTBounds, temp);
|
this->drawTexture(gpu, accum, temp.texture());
|
||||||
|
|
||||||
if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) {
|
if (0 != resultBounds->fTop || 0 != resultBounds->fLeft) {
|
||||||
GrMatrix m;
|
GrMatrix m;
|
||||||
@ -600,10 +590,7 @@ bool GrClipMaskManager::createAlphaClipMask(GrGpu* gpu,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fAACache.set(clipIn, accum, *resultBounds);
|
|
||||||
*result = accum;
|
*result = accum;
|
||||||
SkSafeUnref(accum); // fAACache still has a ref to accum
|
|
||||||
SkSafeUnref(temp);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -784,13 +771,14 @@ bool GrClipMaskManager::createSoftwareClipMask(GrGpu* gpu,
|
|||||||
GrTexture** result,
|
GrTexture** result,
|
||||||
GrRect *resultBounds) {
|
GrRect *resultBounds) {
|
||||||
|
|
||||||
GrTexture* accum = NULL;
|
if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds)) {
|
||||||
if (this->clipMaskPreamble(gpu, clipIn, result, resultBounds, &accum)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrTexture* accum = fAACache.getLastMask();
|
||||||
if (NULL == accum) {
|
if (NULL == accum) {
|
||||||
fClipMaskInAlpha = false;
|
fClipMaskInAlpha = false;
|
||||||
|
fAACache.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,9 +807,7 @@ bool GrClipMaskManager::createSoftwareClipMask(GrGpu* gpu,
|
|||||||
// TODO: need to get pixels out of SkRasterClip & into the texture!
|
// TODO: need to get pixels out of SkRasterClip & into the texture!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fAACache.set(clipIn, accum, *resultBounds);
|
|
||||||
*result = accum;
|
*result = accum;
|
||||||
SkSafeUnref(accum); // fAACache still has a ref to accum
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -841,7 +827,8 @@ GrPathRenderer* GrClipMaskManager::getClipPathRenderer(GrGpu* gpu,
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void GrClipMaskManager::freeResources() {
|
void GrClipMaskManager::releaseResources() {
|
||||||
// in case path renderer has any GrResources, start from scratch
|
// in case path renderer has any GrResources, start from scratch
|
||||||
GrSafeSetNull(fPathRendererChain);
|
GrSafeSetNull(fPathRendererChain);
|
||||||
|
fAACache.releaseResources();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include "SkRefCnt.h"
|
#include "SkRefCnt.h"
|
||||||
#include "GrTexture.h"
|
#include "GrTexture.h"
|
||||||
#include "SkDeque.h"
|
#include "SkDeque.h"
|
||||||
|
#include "GrContext.h"
|
||||||
|
|
||||||
class GrGpu;
|
class GrGpu;
|
||||||
class GrPathRenderer;
|
class GrPathRenderer;
|
||||||
@ -44,7 +45,8 @@ struct ScissoringSettings {
|
|||||||
class GrClipMaskCache : public GrNoncopyable {
|
class GrClipMaskCache : public GrNoncopyable {
|
||||||
public:
|
public:
|
||||||
GrClipMaskCache()
|
GrClipMaskCache()
|
||||||
: fStack(sizeof(GrClipStackFrame)) {
|
: fContext(NULL)
|
||||||
|
, fStack(sizeof(GrClipStackFrame)) {
|
||||||
// We need an initial frame to capture the clip state prior to
|
// We need an initial frame to capture the clip state prior to
|
||||||
// any pushes
|
// any pushes
|
||||||
new (fStack.push_back()) GrClipStackFrame();
|
new (fStack.push_back()) GrClipStackFrame();
|
||||||
@ -68,9 +70,9 @@ public:
|
|||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
||||||
|
|
||||||
if (back->fLastMask &&
|
if (back->fLastMask.texture() &&
|
||||||
back->fLastMask->width() >= width &&
|
back->fLastMask.texture()->width() >= width &&
|
||||||
back->fLastMask->height() >= height &&
|
back->fLastMask.texture()->height() >= height &&
|
||||||
clip == back->fLastClip) {
|
clip == back->fLastClip) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -78,21 +80,6 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set(const GrClip& clip, GrTexture* mask, const GrRect& bound) {
|
|
||||||
|
|
||||||
if (fStack.empty()) {
|
|
||||||
GrAssert(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
|
||||||
|
|
||||||
back->fLastClip = clip;
|
|
||||||
SkSafeRef(mask);
|
|
||||||
back->fLastMask.reset(mask);
|
|
||||||
back->fLastBound = bound;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
if (fStack.empty()) {
|
if (fStack.empty()) {
|
||||||
GrAssert(false);
|
GrAssert(false);
|
||||||
@ -147,7 +134,7 @@ public:
|
|||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
||||||
|
|
||||||
return back->fLastMask.get();
|
return back->fLastMask.texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
const GrTexture* getLastMask() const {
|
const GrTexture* getLastMask() const {
|
||||||
@ -159,19 +146,21 @@ public:
|
|||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
||||||
|
|
||||||
return back->fLastMask.get();
|
return back->fLastMask.texture();
|
||||||
}
|
}
|
||||||
|
|
||||||
GrTexture* detachLastMask() {
|
void acquireMask(const GrClip& clip,
|
||||||
|
const GrTextureDesc& desc,
|
||||||
|
const GrRect& bound) {
|
||||||
|
|
||||||
if (fStack.empty()) {
|
if (fStack.empty()) {
|
||||||
GrAssert(false);
|
GrAssert(false);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
||||||
|
|
||||||
return back->fLastMask.detach();
|
back->acquireMask(fContext, clip, desc, bound);
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLastMaskWidth() const {
|
int getLastMaskWidth() const {
|
||||||
@ -183,11 +172,11 @@ public:
|
|||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
||||||
|
|
||||||
if (NULL == back->fLastMask.get()) {
|
if (NULL == back->fLastMask.texture()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return back->fLastMask.get()->width();
|
return back->fLastMask.texture()->width();
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLastMaskHeight() const {
|
int getLastMaskHeight() const {
|
||||||
@ -199,11 +188,11 @@ public:
|
|||||||
|
|
||||||
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
GrClipStackFrame* back = (GrClipStackFrame*) fStack.back();
|
||||||
|
|
||||||
if (NULL == back->fLastMask.get()) {
|
if (NULL == back->fLastMask.texture()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return back->fLastMask.get()->height();
|
return back->fLastMask.texture()->height();
|
||||||
}
|
}
|
||||||
|
|
||||||
void getLastBound(GrRect* bound) const {
|
void getLastBound(GrRect* bound) const {
|
||||||
@ -219,6 +208,24 @@ public:
|
|||||||
*bound = back->fLastBound;
|
*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:
|
protected:
|
||||||
private:
|
private:
|
||||||
struct GrClipStackFrame {
|
struct GrClipStackFrame {
|
||||||
@ -227,22 +234,39 @@ private:
|
|||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void acquireMask(GrContext* context,
|
||||||
|
const GrClip& clip,
|
||||||
|
const GrTextureDesc& desc,
|
||||||
|
const GrRect& bound) {
|
||||||
|
|
||||||
|
fLastClip = clip;
|
||||||
|
|
||||||
|
fLastMask.set(context, desc);
|
||||||
|
|
||||||
|
fLastBound = bound;
|
||||||
|
}
|
||||||
|
|
||||||
void reset () {
|
void reset () {
|
||||||
fLastClip.setEmpty();
|
fLastClip.setEmpty();
|
||||||
fLastMask.reset(NULL);
|
|
||||||
|
const GrTextureDesc desc = { kNone_GrTextureFlags, 0, 0,
|
||||||
|
kUnknown_GrPixelConfig, 0 };
|
||||||
|
|
||||||
|
fLastMask.set(NULL, desc);
|
||||||
fLastBound.setEmpty();
|
fLastBound.setEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
GrClip fLastClip;
|
GrClip fLastClip;
|
||||||
// The mask's width & height values are used in setupDrawStateAAClip to
|
// The mask's width & height values are used in setupDrawStateAAClip to
|
||||||
// correctly scale the uvs for geometry drawn with this mask
|
// correctly scale the uvs for geometry drawn with this mask
|
||||||
SkAutoTUnref<GrTexture> fLastMask;
|
GrAutoScratchTexture fLastMask;
|
||||||
// fLastBound stores the bounding box of the clip mask in canvas
|
// fLastBound stores the bounding box of the clip mask in canvas
|
||||||
// space. The left and top fields are used to offset the uvs for
|
// space. The left and top fields are used to offset the uvs for
|
||||||
// geometry drawn with this mask (in setupDrawStateAAClip)
|
// geometry drawn with this mask (in setupDrawStateAAClip)
|
||||||
GrRect fLastBound;
|
GrRect fLastBound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
GrContext* fContext;
|
||||||
SkDeque fStack;
|
SkDeque fStack;
|
||||||
|
|
||||||
typedef GrNoncopyable INHERITED;
|
typedef GrNoncopyable INHERITED;
|
||||||
@ -268,7 +292,7 @@ public:
|
|||||||
const GrClip& clip,
|
const GrClip& clip,
|
||||||
ScissoringSettings* scissorSettings);
|
ScissoringSettings* scissorSettings);
|
||||||
|
|
||||||
void freeResources();
|
void releaseResources();
|
||||||
|
|
||||||
bool isClipInStencil() const { return fClipMaskInStencil; }
|
bool isClipInStencil() const { return fClipMaskInStencil; }
|
||||||
bool isClipInAlpha() const { return fClipMaskInAlpha; }
|
bool isClipInAlpha() const { return fClipMaskInAlpha; }
|
||||||
@ -277,6 +301,10 @@ public:
|
|||||||
fClipMaskInStencil = false;
|
fClipMaskInStencil = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setContext(GrContext* context) {
|
||||||
|
fAACache.setContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
private:
|
private:
|
||||||
bool fClipMaskInStencil; // is the clip mask in the stencil buffer?
|
bool fClipMaskInStencil; // is the clip mask in the stencil buffer?
|
||||||
@ -302,8 +330,7 @@ private:
|
|||||||
bool clipMaskPreamble(GrGpu* gpu,
|
bool clipMaskPreamble(GrGpu* gpu,
|
||||||
const GrClip& clipIn,
|
const GrClip& clipIn,
|
||||||
GrTexture** result,
|
GrTexture** result,
|
||||||
GrRect *resultBounds,
|
GrRect *resultBounds);
|
||||||
GrTexture** maskStorage);
|
|
||||||
|
|
||||||
bool drawPath(GrGpu* gpu,
|
bool drawPath(GrGpu* gpu,
|
||||||
const SkPath& path,
|
const SkPath& path,
|
||||||
@ -317,10 +344,12 @@ private:
|
|||||||
|
|
||||||
void drawTexture(GrGpu* gpu,
|
void drawTexture(GrGpu* gpu,
|
||||||
GrTexture* target,
|
GrTexture* target,
|
||||||
const GrRect& rect,
|
|
||||||
GrTexture* texture);
|
GrTexture* texture);
|
||||||
|
|
||||||
void getAccum(GrGpu* gpu, const GrRect& bounds, GrTexture** accum);
|
void getTemp(const GrRect& bounds, GrAutoScratchTexture* temp);
|
||||||
|
|
||||||
|
void setupCache(const GrClip& clip,
|
||||||
|
const GrRect& bounds);
|
||||||
|
|
||||||
// determines the path renderer used to draw a clip path element.
|
// determines the path renderer used to draw a clip path element.
|
||||||
GrPathRenderer* getClipPathRenderer(GrGpu* gpu,
|
GrPathRenderer* getClipPathRenderer(GrGpu* gpu,
|
||||||
|
@ -66,6 +66,8 @@ GrGpu::~GrGpu() {
|
|||||||
|
|
||||||
void GrGpu::abandonResources() {
|
void GrGpu::abandonResources() {
|
||||||
|
|
||||||
|
fClipMaskManager.releaseResources();
|
||||||
|
|
||||||
while (NULL != fResourceHead) {
|
while (NULL != fResourceHead) {
|
||||||
fResourceHead->abandon();
|
fResourceHead->abandon();
|
||||||
}
|
}
|
||||||
@ -79,12 +81,12 @@ void GrGpu::abandonResources() {
|
|||||||
fVertexPool = NULL;
|
fVertexPool = NULL;
|
||||||
delete fIndexPool;
|
delete fIndexPool;
|
||||||
fIndexPool = NULL;
|
fIndexPool = NULL;
|
||||||
|
|
||||||
fClipMaskManager.freeResources();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpu::releaseResources() {
|
void GrGpu::releaseResources() {
|
||||||
|
|
||||||
|
fClipMaskManager.releaseResources();
|
||||||
|
|
||||||
while (NULL != fResourceHead) {
|
while (NULL != fResourceHead) {
|
||||||
fResourceHead->release();
|
fResourceHead->release();
|
||||||
}
|
}
|
||||||
@ -98,8 +100,6 @@ void GrGpu::releaseResources() {
|
|||||||
fVertexPool = NULL;
|
fVertexPool = NULL;
|
||||||
delete fIndexPool;
|
delete fIndexPool;
|
||||||
fIndexPool = NULL;
|
fIndexPool = NULL;
|
||||||
|
|
||||||
fClipMaskManager.freeResources();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpu::insertResource(GrResource* resource) {
|
void GrGpu::insertResource(GrResource* resource) {
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
void setContext(GrContext* context) {
|
void setContext(GrContext* context) {
|
||||||
GrAssert(NULL == fContext);
|
GrAssert(NULL == fContext);
|
||||||
fContext = context;
|
fContext = context;
|
||||||
|
fClipMaskManager.setContext(context);
|
||||||
}
|
}
|
||||||
GrContext* getContext() { return fContext; }
|
GrContext* getContext() { return fContext; }
|
||||||
const GrContext* getContext() const { return fContext; }
|
const GrContext* getContext() const { return fContext; }
|
||||||
|
@ -61,6 +61,8 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
|||||||
|
|
||||||
GrClipMaskCache cache;
|
GrClipMaskCache cache;
|
||||||
|
|
||||||
|
cache.setContext(context);
|
||||||
|
|
||||||
GrClip emptyClip;
|
GrClip emptyClip;
|
||||||
emptyClip.setEmpty();
|
emptyClip.setEmpty();
|
||||||
|
|
||||||
@ -77,25 +79,32 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
|||||||
GrClip clip1;
|
GrClip clip1;
|
||||||
clip1.setFromRect(bound1);
|
clip1.setFromRect(bound1);
|
||||||
|
|
||||||
SkAutoTUnref<GrTexture> texture(createTexture(context));
|
const GrTextureDesc desc = {
|
||||||
REPORTER_ASSERT(reporter, texture.get());
|
kRenderTarget_GrTextureFlagBit,
|
||||||
|
X_SIZE,
|
||||||
|
Y_SIZE,
|
||||||
|
kSkia8888_PM_GrPixelConfig,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
if (NULL == texture.get()) {
|
cache.acquireMask(clip1, desc, bound1);
|
||||||
|
|
||||||
|
GrTexture* texture1 = cache.getLastMask();
|
||||||
|
REPORTER_ASSERT(reporter, texture1);
|
||||||
|
if (NULL == texture1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.set(clip1, texture.get(), bound1);
|
|
||||||
|
|
||||||
// check that the set took
|
// check that the set took
|
||||||
check_state(reporter, cache, clip1, texture.get(), bound1);
|
check_state(reporter, cache, clip1, texture1, bound1);
|
||||||
REPORTER_ASSERT(reporter, 2 == texture.get()->getRefCnt());
|
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||||
|
|
||||||
// push the state
|
// push the state
|
||||||
cache.push();
|
cache.push();
|
||||||
|
|
||||||
// verify that the pushed state is initially empty
|
// verify that the pushed state is initially empty
|
||||||
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
||||||
REPORTER_ASSERT(reporter, 2 == texture.get()->getRefCnt());
|
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||||
|
|
||||||
// modify the new state
|
// modify the new state
|
||||||
GrRect bound2;
|
GrRect bound2;
|
||||||
@ -105,11 +114,18 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
|||||||
clip2.setEmpty();
|
clip2.setEmpty();
|
||||||
clip2.setFromRect(bound2);
|
clip2.setFromRect(bound2);
|
||||||
|
|
||||||
cache.set(clip2, texture.get(), bound2);
|
cache.acquireMask(clip2, desc, bound2);
|
||||||
|
|
||||||
|
GrTexture* texture2 = cache.getLastMask();
|
||||||
|
REPORTER_ASSERT(reporter, texture2);
|
||||||
|
if (NULL == texture2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// check that the changes took
|
// check that the changes took
|
||||||
check_state(reporter, cache, clip2, texture.get(), bound2);
|
check_state(reporter, cache, clip2, texture2, bound2);
|
||||||
REPORTER_ASSERT(reporter, 3 == texture.get()->getRefCnt());
|
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||||
|
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||||
|
|
||||||
// check to make sure canReuse works
|
// check to make sure canReuse works
|
||||||
REPORTER_ASSERT(reporter, cache.canReuse(clip2, 10, 10));
|
REPORTER_ASSERT(reporter, cache.canReuse(clip2, 10, 10));
|
||||||
@ -119,15 +135,17 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
|||||||
cache.pop();
|
cache.pop();
|
||||||
|
|
||||||
// verify that the old state is restored
|
// verify that the old state is restored
|
||||||
check_state(reporter, cache, clip1, texture.get(), bound1);
|
check_state(reporter, cache, clip1, texture1, bound1);
|
||||||
REPORTER_ASSERT(reporter, 2 == texture.get()->getRefCnt());
|
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||||
|
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||||
|
|
||||||
// manually clear the state
|
// manually clear the state
|
||||||
cache.reset();
|
cache.reset();
|
||||||
|
|
||||||
// verify it is now empty
|
// verify it is now empty
|
||||||
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
||||||
REPORTER_ASSERT(reporter, 1 == texture.get()->getRefCnt());
|
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||||
|
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||||
|
|
||||||
// pop again - so there is no state
|
// pop again - so there is no state
|
||||||
cache.pop();
|
cache.pop();
|
||||||
@ -137,7 +155,8 @@ static void test_cache(skiatest::Reporter* reporter, GrContext* context) {
|
|||||||
// only do in release since it generates asserts in debug
|
// only do in release since it generates asserts in debug
|
||||||
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
check_state(reporter, cache, emptyClip, NULL, emptyBound);
|
||||||
#endif
|
#endif
|
||||||
REPORTER_ASSERT(reporter, 1 == texture.get()->getRefCnt());
|
REPORTER_ASSERT(reporter, 1 == texture1->getRefCnt());
|
||||||
|
REPORTER_ASSERT(reporter, 1 == texture2->getRefCnt());
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user