blob: 43eded6bb11bed26175634aa68086580bb879716 [file] [log] [blame]
/*
* 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 GrGpuResourceCacheAccess_DEFINED
#define GrGpuResourceCacheAccess_DEFINED
#include "src/gpu/GrGpuResource.h"
#include "src/gpu/GrGpuResourcePriv.h"
namespace skiatest {
class Reporter;
} // namespace skiatest
/**
* This class allows GrResourceCache increased privileged access to GrGpuResource objects.
*/
class GrGpuResource::CacheAccess {
private:
/** The cache is allowed to go from no refs to 1 ref. */
void ref() { fResource->addInitialRef(); }
/**
* Is the resource currently cached as scratch? This means it is cached, has a valid scratch
* key, and does not have a unique key.
*/
bool isScratch() const {
return !fResource->getUniqueKey().isValid() && fResource->fScratchKey.isValid() &&
GrBudgetedType::kBudgeted == fResource->resourcePriv().budgetedType();
}
bool isUsableAsScratch() const {
return this->isScratch() && !fResource->internalHasRef();
}
/**
* Called by the cache to delete the resource under normal circumstances.
*/
void release() {
fResource->release();
if (!fResource->hasRef() && fResource->hasNoCommandBufferUsages()) {
delete fResource;
}
}
/**
* Called by the cache to delete the resource when the backend 3D context is no longer valid.
*/
void abandon() {
fResource->abandon();
if (!fResource->hasRef() && fResource->hasNoCommandBufferUsages()) {
delete fResource;
}
}
/** Called by the cache to assign a new unique key. */
void setUniqueKey(const GrUniqueKey& key) { fResource->fUniqueKey = key; }
/** Is the resource ref'ed */
bool hasRef() const { return fResource->hasRef(); }
bool hasRefOrCommandBufferUsage() const {
return this->hasRef() || !fResource->hasNoCommandBufferUsages();
}
/** Called by the cache to make the unique key invalid. */
void removeUniqueKey() { fResource->fUniqueKey.reset(); }
uint32_t timestamp() const { return fResource->fTimestamp; }
void setTimestamp(uint32_t ts) { fResource->fTimestamp = ts; }
void setTimeWhenResourceBecomePurgeable() {
SkASSERT(fResource->isPurgeable());
fResource->fTimeWhenBecamePurgeable = GrStdSteadyClock::now();
}
/**
* Called by the cache to determine whether this resource should be purged based on the length
* of time it has been available for purging.
*/
GrStdSteadyClock::time_point timeWhenResourceBecamePurgeable() {
SkASSERT(fResource->isPurgeable());
return fResource->fTimeWhenBecamePurgeable;
}
int* accessCacheIndex() const { return &fResource->fCacheArrayIndex; }
CacheAccess(GrGpuResource* resource) : fResource(resource) {}
CacheAccess(const CacheAccess& that) : fResource(that.fResource) {}
CacheAccess& operator=(const CacheAccess&) = delete;
// No taking addresses of this type.
const CacheAccess* operator&() const = delete;
CacheAccess* operator&() = delete;
GrGpuResource* fResource;
friend class GrGpuResource; // to construct/copy this type.
friend class GrResourceCache; // to use this type
friend void test_unbudgeted_to_scratch(skiatest::Reporter* reporter); // for unit testing
};
inline GrGpuResource::CacheAccess GrGpuResource::cacheAccess() { return CacheAccess(this); }
inline const GrGpuResource::CacheAccess GrGpuResource::cacheAccess() const { // NOLINT(readability-const-return-type)
return CacheAccess(const_cast<GrGpuResource*>(this));
}
#endif