/* * Copyright 2011 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "GrGpuResource.h" #include "GrResourceCache.h" #include "GrGpu.h" #include "GrGpuResourcePriv.h" static inline GrResourceCache* get_resource_cache(GrGpu* gpu) { SkASSERT(gpu); SkASSERT(gpu->getContext()); SkASSERT(gpu->getContext()->getResourceCache()); return gpu->getContext()->getResourceCache(); } GrGpuResource::GrGpuResource(GrGpu* gpu, LifeCycle lifeCycle) : fGpu(gpu) , fGpuMemorySize(kInvalidGpuMemorySize) , fLifeCycle(lifeCycle) , fUniqueID(CreateUniqueID()) { SkDEBUGCODE(fCacheArrayIndex = -1); } void GrGpuResource::registerWithCache() { get_resource_cache(fGpu)->resourceAccess().insertResource(this); } GrGpuResource::~GrGpuResource() { // The cache should have released or destroyed this resource. SkASSERT(this->wasDestroyed()); } void GrGpuResource::release() { SkASSERT(fGpu); this->onRelease(); get_resource_cache(fGpu)->resourceAccess().removeResource(this); fGpu = NULL; fGpuMemorySize = 0; } void GrGpuResource::abandon() { SkASSERT(fGpu); this->onAbandon(); get_resource_cache(fGpu)->resourceAccess().removeResource(this); fGpu = NULL; fGpuMemorySize = 0; } const SkData* GrGpuResource::setCustomData(const SkData* data) { SkSafeRef(data); fData.reset(data); return data; } const GrContext* GrGpuResource::getContext() const { if (fGpu) { return fGpu->getContext(); } else { return NULL; } } GrContext* GrGpuResource::getContext() { if (fGpu) { return fGpu->getContext(); } else { return NULL; } } void GrGpuResource::didChangeGpuMemorySize() const { if (this->wasDestroyed()) { return; } size_t oldSize = fGpuMemorySize; SkASSERT(kInvalidGpuMemorySize != oldSize); fGpuMemorySize = kInvalidGpuMemorySize; get_resource_cache(fGpu)->resourceAccess().didChangeGpuMemorySize(this, oldSize); } void GrGpuResource::removeUniqueKey() { SkASSERT(fUniqueKey.isValid()); get_resource_cache(fGpu)->resourceAccess().removeUniqueKey(this); } void GrGpuResource::setUniqueKey(const GrUniqueKey& key) { SkASSERT(this->internalHasRef()); SkASSERT(key.isValid()); // Wrapped and uncached resources can never have a unique key. if (!this->resourcePriv().isBudgeted()) { return; } if (this->wasDestroyed()) { return; } get_resource_cache(fGpu)->resourceAccess().changeUniqueKey(this, key); } void GrGpuResource::notifyIsPurgeable() const { if (this->wasDestroyed()) { // We've already been removed from the cache. Goodbye cruel world! SkDELETE(this); } else { GrGpuResource* mutableThis = const_cast(this); get_resource_cache(fGpu)->resourceAccess().notifyPurgeable(mutableThis); } } void GrGpuResource::setScratchKey(const GrScratchKey& scratchKey) { SkASSERT(!fScratchKey.isValid()); SkASSERT(scratchKey.isValid()); // Wrapped resources can never have a scratch key. if (this->isWrapped()) { return; } fScratchKey = scratchKey; } void GrGpuResource::removeScratchKey() { if (!this->wasDestroyed() && fScratchKey.isValid()) { get_resource_cache(fGpu)->resourceAccess().willRemoveScratchKey(this); fScratchKey.reset(); } } void GrGpuResource::makeBudgeted() { if (GrGpuResource::kUncached_LifeCycle == fLifeCycle) { fLifeCycle = kCached_LifeCycle; get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this); } } void GrGpuResource::makeUnbudgeted() { if (GrGpuResource::kCached_LifeCycle == fLifeCycle && !fUniqueKey.isValid()) { fLifeCycle = kUncached_LifeCycle; get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this); } } uint32_t GrGpuResource::CreateUniqueID() { static int32_t gUniqueID = SK_InvalidUniqueID; uint32_t id; do { id = static_cast(sk_atomic_inc(&gUniqueID) + 1); } while (id == SK_InvalidUniqueID); return id; }