Add GrResourceCache2.
Currently it just replaces GrGpu as the owner of the linked list of resources. Committed: https://skia.googlesource.com/skia/+/94ce9ac8624dbb45656b8f5c992fad9c9ff3ee5f R=mtklein@google.com, robertphillips@google.com Author: bsalomon@google.com Review URL: https://codereview.chromium.org/481443002
This commit is contained in:
parent
78fc1dbed0
commit
c8dc1f74b6
@ -114,6 +114,8 @@
|
|||||||
'<(skia_src_path)/gpu/GrReducedClip.h',
|
'<(skia_src_path)/gpu/GrReducedClip.h',
|
||||||
'<(skia_src_path)/gpu/GrResourceCache.cpp',
|
'<(skia_src_path)/gpu/GrResourceCache.cpp',
|
||||||
'<(skia_src_path)/gpu/GrResourceCache.h',
|
'<(skia_src_path)/gpu/GrResourceCache.h',
|
||||||
|
'<(skia_src_path)/gpu/GrResourceCache2.cpp',
|
||||||
|
'<(skia_src_path)/gpu/GrResourceCache2.h',
|
||||||
'<(skia_src_path)/gpu/GrStencil.cpp',
|
'<(skia_src_path)/gpu/GrStencil.cpp',
|
||||||
'<(skia_src_path)/gpu/GrStencil.h',
|
'<(skia_src_path)/gpu/GrStencil.h',
|
||||||
'<(skia_src_path)/gpu/GrStencilAndCoverPathRenderer.cpp',
|
'<(skia_src_path)/gpu/GrStencilAndCoverPathRenderer.cpp',
|
||||||
|
@ -35,6 +35,7 @@ class GrPath;
|
|||||||
class GrPathRenderer;
|
class GrPathRenderer;
|
||||||
class GrResourceEntry;
|
class GrResourceEntry;
|
||||||
class GrResourceCache;
|
class GrResourceCache;
|
||||||
|
class GrResourceCache2;
|
||||||
class GrStencilBuffer;
|
class GrStencilBuffer;
|
||||||
class GrTestTarget;
|
class GrTestTarget;
|
||||||
class GrTextContext;
|
class GrTextContext;
|
||||||
@ -926,6 +927,7 @@ public:
|
|||||||
GrDrawTarget* getTextTarget();
|
GrDrawTarget* getTextTarget();
|
||||||
const GrIndexBuffer* getQuadIndexBuffer() const;
|
const GrIndexBuffer* getQuadIndexBuffer() const;
|
||||||
GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
|
GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; }
|
||||||
|
GrResourceCache2* getResourceCache2() { return fResourceCache2; }
|
||||||
|
|
||||||
// Called by tests that draw directly to the context via GrDrawTarget
|
// Called by tests that draw directly to the context via GrDrawTarget
|
||||||
void getTestTarget(GrTestTarget*);
|
void getTestTarget(GrTestTarget*);
|
||||||
@ -973,6 +975,7 @@ private:
|
|||||||
GrDrawState* fDrawState;
|
GrDrawState* fDrawState;
|
||||||
|
|
||||||
GrResourceCache* fResourceCache;
|
GrResourceCache* fResourceCache;
|
||||||
|
GrResourceCache2* fResourceCache2;
|
||||||
GrFontCache* fFontCache;
|
GrFontCache* fFontCache;
|
||||||
SkAutoTDelete<GrLayerCache> fLayerCache;
|
SkAutoTDelete<GrLayerCache> fLayerCache;
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "SkTInternalLList.h"
|
#include "SkTInternalLList.h"
|
||||||
|
|
||||||
class GrResourceCacheEntry;
|
class GrResourceCacheEntry;
|
||||||
|
class GrResourceCache2;
|
||||||
class GrGpu;
|
class GrGpu;
|
||||||
class GrContext;
|
class GrContext;
|
||||||
|
|
||||||
@ -118,12 +119,13 @@ private:
|
|||||||
|
|
||||||
static uint32_t CreateUniqueID();
|
static uint32_t CreateUniqueID();
|
||||||
|
|
||||||
// We're in an internal doubly linked list
|
// We're in an internal doubly linked list owned by GrResourceCache2
|
||||||
SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuResource);
|
SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrGpuResource);
|
||||||
|
|
||||||
GrGpu* fGpu; // not reffed. The GrGpu can be deleted while there
|
// This is not ref'ed but abandon() or release() will be called before the GrGpu object
|
||||||
// are still live GrGpuResources. It will call
|
// is destroyed. Those calls set will this to NULL.
|
||||||
// release() on all such objects in its destructor.
|
GrGpu* fGpu;
|
||||||
|
|
||||||
enum Flags {
|
enum Flags {
|
||||||
/**
|
/**
|
||||||
* This object wraps a GPU object given to us by the user.
|
* This object wraps a GPU object given to us by the user.
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
// We could reuse the mask if bounds is a subset of last bounds. We'd have to communicate
|
// We could reuse the mask if bounds is a subset of last bounds. We'd have to communicate
|
||||||
// an offset to the caller.
|
// an offset to the caller.
|
||||||
if (back->fLastMask.texture() &&
|
if (back->fLastMask.texture() &&
|
||||||
|
!back->fLastMask.texture()->wasDestroyed() &&
|
||||||
back->fLastBound == bounds &&
|
back->fLastBound == bounds &&
|
||||||
back->fLastClipGenID == clipGenID) {
|
back->fLastClipGenID == clipGenID) {
|
||||||
return true;
|
return true;
|
||||||
@ -179,8 +180,8 @@ public:
|
|||||||
return fContext;
|
return fContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
void releaseResources() {
|
// TODO: Remove this when we hold cache keys instead of refs to textures.
|
||||||
|
void purgeResources() {
|
||||||
SkDeque::F2BIter iter(fStack);
|
SkDeque::F2BIter iter(fStack);
|
||||||
for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next();
|
for (GrClipStackFrame* frame = (GrClipStackFrame*) iter.next();
|
||||||
frame != NULL;
|
frame != NULL;
|
||||||
@ -219,7 +220,8 @@ private:
|
|||||||
|
|
||||||
int32_t fLastClipGenID;
|
int32_t fLastClipGenID;
|
||||||
// The mask's width & height values are used by GrClipMaskManager to correctly scale the
|
// The mask's width & height values are used by GrClipMaskManager to correctly scale the
|
||||||
// texture coords for the geometry drawn with this mask.
|
// texture coords for the geometry drawn with this mask. TODO: This should be a cache key
|
||||||
|
// and not a hard ref to a texture.
|
||||||
GrAutoScratchTexture fLastMask;
|
GrAutoScratchTexture fLastMask;
|
||||||
// fLastBound stores the bounding box of the clip mask in clip-stack space. This rect is
|
// fLastBound stores the bounding box of the clip mask in clip-stack space. This rect is
|
||||||
// used by GrClipMaskManager to position a rect and compute texture coords for the mask.
|
// used by GrClipMaskManager to position a rect and compute texture coords for the mask.
|
||||||
|
@ -1112,8 +1112,8 @@ GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void GrClipMaskManager::releaseResources() {
|
void GrClipMaskManager::purgeResources() {
|
||||||
fAACache.releaseResources();
|
fAACache.purgeResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrClipMaskManager::setGpu(GrGpu* gpu) {
|
void GrClipMaskManager::setGpu(GrGpu* gpu) {
|
||||||
|
@ -53,7 +53,11 @@ public:
|
|||||||
bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*,
|
bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*,
|
||||||
const SkRect* devBounds);
|
const SkRect* devBounds);
|
||||||
|
|
||||||
void releaseResources();
|
/**
|
||||||
|
* Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
|
||||||
|
* which will allow ResourceCache2 to automatically purge anything this class has created.
|
||||||
|
*/
|
||||||
|
void purgeResources();
|
||||||
|
|
||||||
bool isClipInStencil() const {
|
bool isClipInStencil() const {
|
||||||
return kStencil_ClipMaskType == fCurrClipMaskType;
|
return kStencil_ClipMaskType == fCurrClipMaskType;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#include "GrPathRenderer.h"
|
#include "GrPathRenderer.h"
|
||||||
#include "GrPathUtils.h"
|
#include "GrPathUtils.h"
|
||||||
#include "GrResourceCache.h"
|
#include "GrResourceCache.h"
|
||||||
|
#include "GrResourceCache2.h"
|
||||||
#include "GrSoftwarePathRenderer.h"
|
#include "GrSoftwarePathRenderer.h"
|
||||||
#include "GrStencilBuffer.h"
|
#include "GrStencilBuffer.h"
|
||||||
#include "GrStencilAndCoverTextContext.h"
|
#include "GrStencilAndCoverTextContext.h"
|
||||||
@ -108,6 +109,7 @@ GrContext::GrContext(const Options& opts) : fOptions(opts) {
|
|||||||
fPathRendererChain = NULL;
|
fPathRendererChain = NULL;
|
||||||
fSoftwarePathRenderer = NULL;
|
fSoftwarePathRenderer = NULL;
|
||||||
fResourceCache = NULL;
|
fResourceCache = NULL;
|
||||||
|
fResourceCache2 = NULL;
|
||||||
fFontCache = NULL;
|
fFontCache = NULL;
|
||||||
fDrawBuffer = NULL;
|
fDrawBuffer = NULL;
|
||||||
fDrawBufferVBAllocPool = NULL;
|
fDrawBufferVBAllocPool = NULL;
|
||||||
@ -133,6 +135,7 @@ bool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
|
|||||||
fResourceCache = SkNEW_ARGS(GrResourceCache, (MAX_RESOURCE_CACHE_COUNT,
|
fResourceCache = SkNEW_ARGS(GrResourceCache, (MAX_RESOURCE_CACHE_COUNT,
|
||||||
MAX_RESOURCE_CACHE_BYTES));
|
MAX_RESOURCE_CACHE_BYTES));
|
||||||
fResourceCache->setOverbudgetCallback(OverbudgetCB, this);
|
fResourceCache->setOverbudgetCallback(OverbudgetCB, this);
|
||||||
|
fResourceCache2 = SkNEW(GrResourceCache2);
|
||||||
|
|
||||||
fFontCache = SkNEW_ARGS(GrFontCache, (fGpu));
|
fFontCache = SkNEW_ARGS(GrFontCache, (fGpu));
|
||||||
|
|
||||||
@ -161,10 +164,8 @@ GrContext::~GrContext() {
|
|||||||
(*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
|
(*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since the gpu can hold scratch textures, give it a chance to let go
|
delete fResourceCache2;
|
||||||
// of them before freeing the texture cache
|
fResourceCache2 = NULL;
|
||||||
fGpu->purgeResources();
|
|
||||||
|
|
||||||
delete fResourceCache;
|
delete fResourceCache;
|
||||||
fResourceCache = NULL;
|
fResourceCache = NULL;
|
||||||
delete fFontCache;
|
delete fFontCache;
|
||||||
@ -184,7 +185,9 @@ GrContext::~GrContext() {
|
|||||||
void GrContext::abandonContext() {
|
void GrContext::abandonContext() {
|
||||||
// abandon first to so destructors
|
// abandon first to so destructors
|
||||||
// don't try to free the resources in the API.
|
// don't try to free the resources in the API.
|
||||||
fGpu->abandonResources();
|
fResourceCache2->abandonAll();
|
||||||
|
|
||||||
|
fGpu->contextAbandonded();
|
||||||
|
|
||||||
// a path renderer may be holding onto resources that
|
// a path renderer may be holding onto resources that
|
||||||
// are now unusable
|
// are now unusable
|
||||||
@ -207,7 +210,6 @@ void GrContext::abandonContext() {
|
|||||||
|
|
||||||
fFontCache->freeAll();
|
fFontCache->freeAll();
|
||||||
fLayerCache->freeAll();
|
fLayerCache->freeAll();
|
||||||
fGpu->markContextDirty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrContext::resetContext(uint32_t state) {
|
void GrContext::resetContext(uint32_t state) {
|
||||||
@ -218,6 +220,9 @@ void GrContext::freeGpuResources() {
|
|||||||
this->flush();
|
this->flush();
|
||||||
|
|
||||||
fGpu->purgeResources();
|
fGpu->purgeResources();
|
||||||
|
if (NULL != fDrawBuffer) {
|
||||||
|
fDrawBuffer->purgeResources();
|
||||||
|
}
|
||||||
|
|
||||||
fAARectRenderer->reset();
|
fAARectRenderer->reset();
|
||||||
fOvalRenderer->reset();
|
fOvalRenderer->reset();
|
||||||
@ -540,6 +545,15 @@ void GrContext::addExistingTextureToCache(GrTexture* texture) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GrContext::unlockScratchTexture(GrTexture* texture) {
|
void GrContext::unlockScratchTexture(GrTexture* texture) {
|
||||||
|
if (texture->wasDestroyed()) {
|
||||||
|
if (texture->getCacheEntry()->key().isScratch()) {
|
||||||
|
// This texture was detached from the cache but the cache still had a ref to it but
|
||||||
|
// not a pointer to it.
|
||||||
|
texture->unref();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ASSERT_OWNED_RESOURCE(texture);
|
ASSERT_OWNED_RESOURCE(texture);
|
||||||
SkASSERT(NULL != texture->getCacheEntry());
|
SkASSERT(NULL != texture->getCacheEntry());
|
||||||
|
|
||||||
|
@ -50,18 +50,6 @@ GrGpu::GrGpu(GrContext* context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GrGpu::~GrGpu() {
|
GrGpu::~GrGpu() {
|
||||||
this->releaseResources();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGpu::abandonResources() {
|
|
||||||
|
|
||||||
fClipMaskManager.releaseResources();
|
|
||||||
|
|
||||||
while (NULL != fObjectList.head()) {
|
|
||||||
fObjectList.head()->abandon();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed());
|
|
||||||
SkSafeSetNull(fQuadIndexBuffer);
|
SkSafeSetNull(fQuadIndexBuffer);
|
||||||
delete fVertexPool;
|
delete fVertexPool;
|
||||||
fVertexPool = NULL;
|
fVertexPool = NULL;
|
||||||
@ -69,42 +57,7 @@ void GrGpu::abandonResources() {
|
|||||||
fIndexPool = NULL;
|
fIndexPool = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrGpu::releaseResources() {
|
void GrGpu::contextAbandonded() {}
|
||||||
|
|
||||||
fClipMaskManager.releaseResources();
|
|
||||||
|
|
||||||
while (NULL != fObjectList.head()) {
|
|
||||||
fObjectList.head()->release();
|
|
||||||
}
|
|
||||||
|
|
||||||
SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed());
|
|
||||||
SkSafeSetNull(fQuadIndexBuffer);
|
|
||||||
delete fVertexPool;
|
|
||||||
fVertexPool = NULL;
|
|
||||||
delete fIndexPool;
|
|
||||||
fIndexPool = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGpu::insertObject(GrGpuResource* object) {
|
|
||||||
SkASSERT(NULL != object);
|
|
||||||
SkASSERT(this == object->getGpu());
|
|
||||||
|
|
||||||
fObjectList.addToHead(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GrGpu::removeObject(GrGpuResource* object) {
|
|
||||||
SkASSERT(NULL != object);
|
|
||||||
SkASSERT(this == object->getGpu());
|
|
||||||
|
|
||||||
fObjectList.remove(object);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void GrGpu::unimpl(const char msg[]) {
|
|
||||||
#ifdef SK_DEBUG
|
|
||||||
GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -318,7 +271,8 @@ static inline void fill_indices(uint16_t* indices, int quadCount) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
|
const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
|
||||||
if (NULL == fQuadIndexBuffer) {
|
if (NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()) {
|
||||||
|
SkSafeUnref(fQuadIndexBuffer);
|
||||||
static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS;
|
static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS;
|
||||||
GrGpu* me = const_cast<GrGpu*>(this);
|
GrGpu* me = const_cast<GrGpu*>(this);
|
||||||
fQuadIndexBuffer = me->createIndexBuffer(SIZE, false);
|
fQuadIndexBuffer = me->createIndexBuffer(SIZE, false);
|
||||||
|
@ -59,6 +59,12 @@ public:
|
|||||||
return fPathRendering.get();
|
return fPathRendering.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Called by GrContext when the underlying backend context has been destroyed.
|
||||||
|
// GrGpu should use this to ensure that no backend API calls will be made from
|
||||||
|
// here onward, including in its destructor. Subclasses should call
|
||||||
|
// INHERITED::contextAbandonded() if they override this.
|
||||||
|
virtual void contextAbandonded();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The GrGpu object normally assumes that no outsider is setting state
|
* The GrGpu object normally assumes that no outsider is setting state
|
||||||
* within the underlying 3D API's context/device/whatever. This call informs
|
* within the underlying 3D API's context/device/whatever. This call informs
|
||||||
@ -253,30 +259,6 @@ public:
|
|||||||
GrPixelConfig config, const void* buffer,
|
GrPixelConfig config, const void* buffer,
|
||||||
size_t rowBytes);
|
size_t rowBytes);
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to tell GrGpu that all GrGpuResources have been lost and should
|
|
||||||
* be abandoned. Overrides must call INHERITED::abandonResources().
|
|
||||||
*/
|
|
||||||
virtual void abandonResources();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called to tell GrGpu to release all GrGpuResources. Overrides must call
|
|
||||||
* INHERITED::releaseResources().
|
|
||||||
*/
|
|
||||||
void releaseResources();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add object to list of objects. Should only be called by GrGpuResource.
|
|
||||||
* @param resource the resource to add.
|
|
||||||
*/
|
|
||||||
void insertObject(GrGpuResource* object);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove object from list of objects. Should only be called by GrGpuResource.
|
|
||||||
* @param resource the resource to remove.
|
|
||||||
*/
|
|
||||||
void removeObject(GrGpuResource* object);
|
|
||||||
|
|
||||||
// GrDrawTarget overrides
|
// GrDrawTarget overrides
|
||||||
virtual void clear(const SkIRect* rect,
|
virtual void clear(const SkIRect* rect,
|
||||||
GrColor color,
|
GrColor color,
|
||||||
@ -286,7 +268,7 @@ public:
|
|||||||
virtual void purgeResources() SK_OVERRIDE {
|
virtual void purgeResources() SK_OVERRIDE {
|
||||||
// The clip mask manager can rebuild all its clip masks so just
|
// The clip mask manager can rebuild all its clip masks so just
|
||||||
// get rid of them all.
|
// get rid of them all.
|
||||||
fClipMaskManager.releaseResources();
|
fClipMaskManager.purgeResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
// After the client interacts directly with the 3D context state the GrGpu
|
// After the client interacts directly with the 3D context state the GrGpu
|
||||||
@ -523,7 +505,6 @@ private:
|
|||||||
enum {
|
enum {
|
||||||
kPreallocGeomPoolStateStackCnt = 4,
|
kPreallocGeomPoolStateStackCnt = 4,
|
||||||
};
|
};
|
||||||
typedef SkTInternalLList<GrGpuResource> ObjectList;
|
|
||||||
SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true> fGeomPoolStateStack;
|
SkSTArray<kPreallocGeomPoolStateStackCnt, GeometryPoolState, true> fGeomPoolStateStack;
|
||||||
ResetTimestamp fResetTimestamp;
|
ResetTimestamp fResetTimestamp;
|
||||||
uint32_t fResetBits;
|
uint32_t fResetBits;
|
||||||
@ -534,9 +515,6 @@ private:
|
|||||||
int fIndexPoolUseCnt;
|
int fIndexPoolUseCnt;
|
||||||
// these are mutable so they can be created on-demand
|
// these are mutable so they can be created on-demand
|
||||||
mutable GrIndexBuffer* fQuadIndexBuffer;
|
mutable GrIndexBuffer* fQuadIndexBuffer;
|
||||||
// Used to abandon/release all resources created by this GrGpu. TODO: Move this
|
|
||||||
// functionality to GrResourceCache.
|
|
||||||
ObjectList fObjectList;
|
|
||||||
|
|
||||||
typedef GrDrawTarget INHERITED;
|
typedef GrDrawTarget INHERITED;
|
||||||
};
|
};
|
||||||
|
@ -8,19 +8,27 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "GrGpuResource.h"
|
#include "GrGpuResource.h"
|
||||||
|
#include "GrResourceCache2.h"
|
||||||
#include "GrGpu.h"
|
#include "GrGpu.h"
|
||||||
|
|
||||||
|
static inline GrResourceCache2* get_resource_cache2(GrGpu* gpu) {
|
||||||
|
SkASSERT(NULL != gpu);
|
||||||
|
SkASSERT(NULL != gpu->getContext());
|
||||||
|
SkASSERT(NULL != gpu->getContext()->getResourceCache2());
|
||||||
|
return gpu->getContext()->getResourceCache2();
|
||||||
|
}
|
||||||
|
|
||||||
GrGpuResource::GrGpuResource(GrGpu* gpu, bool isWrapped)
|
GrGpuResource::GrGpuResource(GrGpu* gpu, bool isWrapped)
|
||||||
: fRefCnt(1)
|
: fGpu(gpu)
|
||||||
|
, fRefCnt(1)
|
||||||
, fCacheEntry(NULL)
|
, fCacheEntry(NULL)
|
||||||
, fUniqueID(CreateUniqueID()) {
|
, fUniqueID(CreateUniqueID()) {
|
||||||
fGpu = gpu;
|
|
||||||
if (isWrapped) {
|
if (isWrapped) {
|
||||||
fFlags = kWrapped_FlagBit;
|
fFlags = kWrapped_FlagBit;
|
||||||
} else {
|
} else {
|
||||||
fFlags = 0;
|
fFlags = 0;
|
||||||
}
|
}
|
||||||
fGpu->insertObject(this);
|
get_resource_cache2(fGpu)->insertResource(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrGpuResource::~GrGpuResource() {
|
GrGpuResource::~GrGpuResource() {
|
||||||
@ -32,7 +40,7 @@ GrGpuResource::~GrGpuResource() {
|
|||||||
void GrGpuResource::release() {
|
void GrGpuResource::release() {
|
||||||
if (NULL != fGpu) {
|
if (NULL != fGpu) {
|
||||||
this->onRelease();
|
this->onRelease();
|
||||||
fGpu->removeObject(this);
|
get_resource_cache2(fGpu)->removeResource(this);
|
||||||
fGpu = NULL;
|
fGpu = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -40,7 +48,7 @@ void GrGpuResource::release() {
|
|||||||
void GrGpuResource::abandon() {
|
void GrGpuResource::abandon() {
|
||||||
if (NULL != fGpu) {
|
if (NULL != fGpu) {
|
||||||
this->onAbandon();
|
this->onAbandon();
|
||||||
fGpu->removeObject(this);
|
get_resource_cache2(fGpu)->removeResource(this);
|
||||||
fGpu = NULL;
|
fGpu = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ void GrLayerCache::freeAll() {
|
|||||||
fAtlas.free();
|
fAtlas.free();
|
||||||
// GrLayerCache always assumes an atlas exists so recreate it. The atlas
|
// GrLayerCache always assumes an atlas exists so recreate it. The atlas
|
||||||
// lazily allocates a replacement texture so reallocating a new
|
// lazily allocates a replacement texture so reallocating a new
|
||||||
// atlas here won't disrupt a GrContext::contextDestroyed or freeGpuResources.
|
// atlas here won't disrupt a GrContext::abandonContext or freeGpuResources.
|
||||||
// TODO: Make GrLayerCache lazily allocate the atlas manager?
|
// TODO: Make GrLayerCache lazily allocate the atlas manager?
|
||||||
this->initAtlas();
|
this->initAtlas();
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ void GrResourceCache::makeExclusive(GrResourceCacheEntry* entry) {
|
|||||||
void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) {
|
void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) {
|
||||||
// If the resource went invalid while it was detached then purge it
|
// If the resource went invalid while it was detached then purge it
|
||||||
// This can happen when a 3D context was lost,
|
// This can happen when a 3D context was lost,
|
||||||
// the client called GrContext::contextDestroyed() to notify Gr,
|
// the client called GrContext::abandonContext() to notify Gr,
|
||||||
// and then later an SkGpuDevice's destructor releases its backing
|
// and then later an SkGpuDevice's destructor releases its backing
|
||||||
// texture (which was invalidated at contextDestroyed time).
|
// texture (which was invalidated at contextDestroyed time).
|
||||||
// TODO: Safely delete the GrResourceCacheEntry as well.
|
// TODO: Safely delete the GrResourceCacheEntry as well.
|
||||||
|
47
src/gpu/GrResourceCache2.cpp
Normal file
47
src/gpu/GrResourceCache2.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "GrResourceCache2.h"
|
||||||
|
#include "GrGpuResource.h"
|
||||||
|
|
||||||
|
GrResourceCache2::~GrResourceCache2() {
|
||||||
|
this->releaseAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrResourceCache2::insertResource(GrGpuResource* resource) {
|
||||||
|
SkASSERT(NULL != resource);
|
||||||
|
SkASSERT(!resource->wasDestroyed());
|
||||||
|
fResources.addToHead(resource);
|
||||||
|
++fCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrResourceCache2::removeResource(GrGpuResource* resource) {
|
||||||
|
fResources.remove(resource);
|
||||||
|
--fCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrResourceCache2::abandonAll() {
|
||||||
|
while (GrGpuResource* head = fResources.head()) {
|
||||||
|
SkASSERT(!head->wasDestroyed());
|
||||||
|
head->abandon();
|
||||||
|
// abandon should have already removed this from the list.
|
||||||
|
SkASSERT(head != fResources.head());
|
||||||
|
}
|
||||||
|
SkASSERT(!fCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrResourceCache2::releaseAll() {
|
||||||
|
while (GrGpuResource* head = fResources.head()) {
|
||||||
|
SkASSERT(!head->wasDestroyed());
|
||||||
|
head->release();
|
||||||
|
// release should have already removed this from the list.
|
||||||
|
SkASSERT(head != fResources.head());
|
||||||
|
}
|
||||||
|
SkASSERT(!fCount);
|
||||||
|
}
|
40
src/gpu/GrResourceCache2.h
Normal file
40
src/gpu/GrResourceCache2.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc.
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a BSD-style license that can be
|
||||||
|
* found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GrResourceCache2_DEFINED
|
||||||
|
#define GrResourceCache2_DEFINED
|
||||||
|
|
||||||
|
#include "GrTypes.h"
|
||||||
|
#include "SkTInternalLList.h"
|
||||||
|
|
||||||
|
class GrGpuResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eventual replacement for GrResourceCache. Currently it simply holds a list
|
||||||
|
* of all GrGpuResource objects for a GrContext. It is used to invalidate all
|
||||||
|
* the resources when necessary.
|
||||||
|
*/
|
||||||
|
class GrResourceCache2 {
|
||||||
|
public:
|
||||||
|
GrResourceCache2() : fCount(0) {};
|
||||||
|
~GrResourceCache2();
|
||||||
|
|
||||||
|
void insertResource(GrGpuResource* resource);
|
||||||
|
|
||||||
|
void removeResource(GrGpuResource* resource);
|
||||||
|
|
||||||
|
void abandonAll();
|
||||||
|
|
||||||
|
void releaseAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int fCount;
|
||||||
|
SkTInternalLList<GrGpuResource> fResources;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -164,9 +164,15 @@ GrGpuGL::~GrGpuGL() {
|
|||||||
|
|
||||||
// This must be called by before the GrDrawTarget destructor
|
// This must be called by before the GrDrawTarget destructor
|
||||||
this->releaseGeometry();
|
this->releaseGeometry();
|
||||||
// This subclass must do this before the base class destructor runs
|
}
|
||||||
// since we will unref the GrGLInterface.
|
|
||||||
this->releaseResources();
|
void GrGpuGL::contextAbandonded() {
|
||||||
|
INHERITED::contextAbandonded();
|
||||||
|
fProgramCache->abandon();
|
||||||
|
fHWProgramID = 0;
|
||||||
|
if (this->glCaps().pathRenderingSupport()) {
|
||||||
|
this->glPathRendering()->abandonGpuResources();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -30,6 +30,8 @@ public:
|
|||||||
GrGpuGL(const GrGLContext& ctx, GrContext* context);
|
GrGpuGL(const GrGLContext& ctx, GrContext* context);
|
||||||
virtual ~GrGpuGL();
|
virtual ~GrGpuGL();
|
||||||
|
|
||||||
|
virtual void contextAbandonded() SK_OVERRIDE;
|
||||||
|
|
||||||
const GrGLContext& glContext() const { return fGLContext; }
|
const GrGLContext& glContext() const { return fGLContext; }
|
||||||
|
|
||||||
const GrGLInterface* glInterface() const { return fGLContext.interface(); }
|
const GrGLInterface* glInterface() const { return fGLContext.interface(); }
|
||||||
@ -75,8 +77,6 @@ public:
|
|||||||
|
|
||||||
virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
|
virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
|
||||||
|
|
||||||
virtual void abandonResources() SK_OVERRIDE;
|
|
||||||
|
|
||||||
// These functions should be used to bind GL objects. They track the GL state and skip redundant
|
// These functions should be used to bind GL objects. They track the GL state and skip redundant
|
||||||
// bindings. Making the equivalent glBind calls directly will confuse the state tracking.
|
// bindings. Making the equivalent glBind calls directly will confuse the state tracking.
|
||||||
void bindVertexArray(GrGLuint id) {
|
void bindVertexArray(GrGLuint id) {
|
||||||
|
@ -199,17 +199,6 @@ GrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
|
|||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void GrGpuGL::abandonResources(){
|
|
||||||
INHERITED::abandonResources();
|
|
||||||
fProgramCache->abandon();
|
|
||||||
fHWProgramID = 0;
|
|
||||||
if (this->glCaps().pathRenderingSupport()) {
|
|
||||||
this->glPathRendering()->abandonGpuResources();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
|
#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
|
||||||
|
|
||||||
bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
|
bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
|
||||||
|
Loading…
Reference in New Issue
Block a user