Refactor to separate backend object lifecycle and GpuResource budget decision

Refactor GrGpuResource to contain two different pieces of state:
 a) instance is budgeted or not budgeted
 b) instance references wrapped backend objects or not

The "object lifecycle" was also attached to backend object
handles (ids), which made the code a bit unclear. Backend objects
would be associated with GrGpuResource::LifeCycle, even though
GrGpuResource::LifeCycle refers to the GpuResource, and individual
backend objects in one GpuResource might be governed with different
"lifecycle".

Mark the budgeted/not budgeted with SkBudgeted::kYes, SkBudgeted::kNo.
This was previously GrGpuResource::kCached_LifeCycle,
GrGpuResource::kUncached_LifeCycle.

Mark the "references wrapped object" with boolean. This was previously
GrGpuResource::kBorrowed_LifeCycle,
GrGpuResource::kAdopted_LifeCycle for GrGpuResource.

Associate the backend object ownership status with
GrBackendObjectOwnership for the backend object handles.

The resource type leaf constuctors, such has GrGLTexture or
GrGLTextureRenderTarget take "budgeted" parameter. This parameter
is passed to GrGpuResource::registerWithCache().

The resource type intermediary constructors, such as GrGLTexture
constructors for class GrGLTextureRenderTarget do not take "budgeted"
parameters, intermediary construtors do not call registerWithCache.

Removes the need for tagging GrGpuResource -derived subclass
constructors with "Derived" parameter.

Makes instances that wrap backend objects be registered with
a new function GrGpuResource::registerWithCacheWrapped().

Removes "budgeted" parameter from classes such as StencilAttahment, as
they are always cached and never wrap any external backend objects.

Removes the use of concept "external" from the member function names.
The API refers to the objects as "wrapped", so make all related
functions use the term consistently.

No change in functionality. Resources referencing wrapped objects are
always inserted to the cache with budget decision kNo.

BUG=594928
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1862043002

Review URL: https://codereview.chromium.org/1862043002
This commit is contained in:
kkinnunen 2016-04-22 01:48:29 -07:00 committed by Commit bot
parent cb61a6452f
commit 2e6055b3ea
47 changed files with 446 additions and 439 deletions

View File

@ -23,8 +23,8 @@ enum {
class BenchResource : public GrGpuResource {
public:
BenchResource (GrGpu* gpu)
: INHERITED(gpu, kCached_LifeCycle) {
this->registerWithCache();
: INHERITED(gpu) {
this->registerWithCache(SkBudgeted::kYes);
}
static void ComputeKey(int i, int keyData32Count, GrUniqueKey* key) {

View File

@ -110,22 +110,24 @@ public:
protected:
GrBuffer(GrGpu* gpu, size_t gpuMemorySize, GrBufferType intendedType,
GrAccessPattern accessPattern, bool cpuBacked)
: INHERITED(gpu, kCached_LifeCycle),
: INHERITED(gpu),
fMapPtr(nullptr),
fGpuMemorySize(gpuMemorySize), // TODO: Zero for cpu backed buffers?
fAccessPattern(accessPattern),
fCPUBacked(cpuBacked) {
fCPUBacked(cpuBacked),
fIntendedType(intendedType) {
}
void computeScratchKey(GrScratchKey* key) const override {
if (!fCPUBacked && SkIsPow2(fGpuMemorySize) && kDynamic_GrAccessPattern == fAccessPattern) {
GrScratchKey key;
ComputeScratchKeyForDynamicBuffer(fGpuMemorySize, intendedType, &key);
this->setScratchKey(key);
ComputeScratchKeyForDynamicBuffer(fGpuMemorySize, fIntendedType, key);
}
}
void* fMapPtr;
private:
virtual size_t onGpuMemorySize() const { return fGpuMemorySize; }
size_t onGpuMemorySize() const override { return fGpuMemorySize; }
virtual void onMap() = 0;
virtual void onUnmap() = 0;
@ -134,7 +136,7 @@ private:
size_t fGpuMemorySize;
GrAccessPattern fAccessPattern;
bool fCPUBacked;
GrBufferType fIntendedType;
typedef GrGpuResource INHERITED;
};

View File

@ -140,34 +140,6 @@ private:
class SK_API GrGpuResource : public GrIORef<GrGpuResource> {
public:
enum LifeCycle {
/**
* The resource is cached and owned by Skia. Resources with this status may be kept alive
* by the cache as either scratch or unique resources even when there are no refs to them.
* The cache may release them whenever there are no refs.
*/
kCached_LifeCycle,
/**
* The resource is uncached. As soon as there are no more refs to it, it is released. Under
* the hood the cache may opaquely recycle it as a cached resource.
*/
kUncached_LifeCycle,
/**
* Similar to uncached, but Skia does not manage the lifetime of the underlying backend
* 3D API object(s). The client is responsible for freeing those. Used to inject client-
* created GPU resources into Skia (e.g. to render to a client-created texture).
*/
kBorrowed_LifeCycle,
/**
* An external resource with ownership transfered into Skia. Skia will free the resource.
*/
kAdopted_LifeCycle,
};
/**
* Tests whether a object has been abandoned or released. All objects will
* be in this state after their creating GrContext is destroyed or has
@ -261,11 +233,16 @@ public:
virtual void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
protected:
// This must be called by every GrGpuObject. It should be called once the object is fully
// initialized (i.e. not in a base class constructor).
void registerWithCache();
// This must be called by every non-wrapped GrGpuObject. It should be called once the object is
// fully initialized (i.e. only from the constructors of the final class).
void registerWithCache(SkBudgeted);
GrGpuResource(GrGpu*, LifeCycle);
// This must be called by every GrGpuObject that references any wrapped backend objects. It
// should be called once the object is fully initialized (i.e. only from the constructors of the
// final class).
void registerWithCacheWrapped();
GrGpuResource(GrGpu*);
virtual ~GrGpuResource();
GrGpu* getGpu() const { return fGpu; }
@ -277,25 +254,12 @@ protected:
backend API calls should be made. */
virtual void onAbandon() { }
bool shouldFreeResources() const { return fLifeCycle != kBorrowed_LifeCycle; }
bool isExternal() const {
return GrGpuResource::kAdopted_LifeCycle == fLifeCycle ||
GrGpuResource::kBorrowed_LifeCycle == fLifeCycle;
}
/**
* This entry point should be called whenever gpuMemorySize() should report a different size.
* The cache will call gpuMemorySize() to update the current size of the resource.
*/
void didChangeGpuMemorySize() const;
/**
* Optionally called by the GrGpuResource subclass if the resource can be used as scratch.
* By default resources are not usable as scratch. This should only be called once.
**/
void setScratchKey(const GrScratchKey& scratchKey);
/**
* Allows subclasses to add additional backing information to the SkTraceMemoryDump. Called by
* onMemoryDump. The default implementation adds no backing information.
@ -303,6 +267,14 @@ protected:
virtual void setMemoryBacking(SkTraceMemoryDump*, const SkString&) const {}
private:
/**
* Called by the registerWithCache if the resource is available to be used as scratch.
* Resource subclasses should override this if the instances should be recycled as scratch
* resources and populate the scratchKey with the key.
* By default resources are not recycled as scratch.
**/
virtual void computeScratchKey(GrScratchKey*) const { };
/**
* Frees the object in the underlying 3D API. Called by CacheAccess.
*/
@ -341,7 +313,8 @@ private:
GrGpu* fGpu;
mutable size_t fGpuMemorySize;
LifeCycle fLifeCycle;
SkBudgeted fBudgeted;
bool fRefsWrappedObjects;
const uint32_t fUniqueID;
SkAutoTUnref<const SkData> fData;

View File

@ -156,9 +156,9 @@ public:
GrDrawTarget* getLastDrawTarget() { return fLastDrawTarget; }
protected:
GrRenderTarget(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc,
GrRenderTarget(GrGpu* gpu, const GrSurfaceDesc& desc,
SampleConfig sampleConfig, GrStencilAttachment* stencil = nullptr)
: INHERITED(gpu, lifeCycle, desc)
: INHERITED(gpu, desc)
, fStencilAttachment(stencil)
, fSampleConfig(sampleConfig)
, fLastDrawTarget(nullptr) {

View File

@ -146,8 +146,8 @@ protected:
// Provides access to methods that should be public within Skia code.
friend class GrSurfacePriv;
GrSurface(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc)
: INHERITED(gpu, lifeCycle)
GrSurface(GrGpu* gpu, const GrSurfaceDesc& desc)
: INHERITED(gpu)
, fDesc(desc)
, fReleaseProc(NULL)
, fReleaseCtx(NULL)

View File

@ -46,11 +46,12 @@ public:
inline const GrTexturePriv texturePriv() const;
protected:
GrTexture(GrGpu*, LifeCycle, const GrSurfaceDesc&, GrSLType, bool wasMipMapDataProvided);
GrTexture(GrGpu*, const GrSurfaceDesc&, GrSLType, bool wasMipMapDataProvided);
void validateDesc() const;
private:
void computeScratchKey(GrScratchKey*) const override;
size_t onGpuMemorySize() const override;
void dirtyMipMaps(bool mipMapsDirty);

View File

@ -464,4 +464,14 @@ enum GrAccessPattern {
#define GrCapsDebugf(caps, ...)
#endif
/**
* Specifies if the holder owns the backend, OpenGL or Vulkan, object.
*/
enum class GrBackendObjectOwnership : bool {
/** Holder does not destroy the backend object. */
kBorrowed = false,
/** Holder destroys the backend object. */
kOwned = true
};
#endif

View File

@ -150,9 +150,6 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budget
desc.fOrigin = resolve_origin(desc.fOrigin, isRT);
GrTexture* tex = nullptr;
GrGpuResource::LifeCycle lifeCycle = SkBudgeted::kYes == budgeted ?
GrGpuResource::kCached_LifeCycle :
GrGpuResource::kUncached_LifeCycle;
if (GrPixelConfigIsCompressed(desc.fConfig)) {
// We shouldn't be rendering into this
@ -165,10 +162,10 @@ GrTexture* GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budget
}
this->handleDirtyContext();
tex = this->onCreateCompressedTexture(desc, lifeCycle, texels);
tex = this->onCreateCompressedTexture(desc, budgeted, texels);
} else {
this->handleDirtyContext();
tex = this->onCreateTexture(desc, lifeCycle, texels);
tex = this->onCreateTexture(desc, budgeted, texels);
}
if (tex) {
if (!caps->reuseScratchTextures() && !isRT) {

View File

@ -529,10 +529,10 @@ private:
// Texture size and sample size will have already been validated in base class before
// onCreateTexture/CompressedTexture are called.
virtual GrTexture* onCreateTexture(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) = 0;
virtual GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) = 0;
virtual GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) = 0;

View File

@ -19,15 +19,26 @@ static inline GrResourceCache* get_resource_cache(GrGpu* gpu) {
return gpu->getContext()->getResourceCache();
}
GrGpuResource::GrGpuResource(GrGpu* gpu, LifeCycle lifeCycle)
GrGpuResource::GrGpuResource(GrGpu* gpu)
: fGpu(gpu)
, fGpuMemorySize(kInvalidGpuMemorySize)
, fLifeCycle(lifeCycle)
, fBudgeted(SkBudgeted::kNo)
, fRefsWrappedObjects(false)
, fUniqueID(CreateUniqueID()) {
SkDEBUGCODE(fCacheArrayIndex = -1);
}
void GrGpuResource::registerWithCache() {
void GrGpuResource::registerWithCache(SkBudgeted budgeted) {
SkASSERT(fBudgeted == SkBudgeted::kNo);
fBudgeted = budgeted;
this->computeScratchKey(&fScratchKey);
get_resource_cache(fGpu)->resourceAccess().insertResource(this);
}
void GrGpuResource::registerWithCacheWrapped() {
SkASSERT(fBudgeted == SkBudgeted::kNo);
// Currently resources referencing wrapped objects are not budgeted.
fRefsWrappedObjects = true;
get_resource_cache(fGpu)->resourceAccess().insertResource(this);
}
@ -164,16 +175,6 @@ bool GrGpuResource::notifyRefCountIsZero() const {
return false;
}
void GrGpuResource::setScratchKey(const GrScratchKey& scratchKey) {
SkASSERT(!fScratchKey.isValid());
SkASSERT(scratchKey.isValid());
// Wrapped resources can never have a scratch key.
if (this->resourcePriv().isExternal()) {
return;
}
fScratchKey = scratchKey;
}
void GrGpuResource::removeScratchKey() {
if (!this->wasDestroyed() && fScratchKey.isValid()) {
get_resource_cache(fGpu)->resourceAccess().willRemoveScratchKey(this);
@ -182,16 +183,18 @@ void GrGpuResource::removeScratchKey() {
}
void GrGpuResource::makeBudgeted() {
if (!this->wasDestroyed() && GrGpuResource::kUncached_LifeCycle == fLifeCycle) {
fLifeCycle = kCached_LifeCycle;
if (!this->wasDestroyed() && SkBudgeted::kNo == fBudgeted) {
// Currently resources referencing wrapped objects are not budgeted.
SkASSERT(!fRefsWrappedObjects);
fBudgeted = SkBudgeted::kYes;
get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this);
}
}
void GrGpuResource::makeUnbudgeted() {
if (!this->wasDestroyed() && GrGpuResource::kCached_LifeCycle == fLifeCycle &&
if (!this->wasDestroyed() && SkBudgeted::kYes == fBudgeted &&
!fUniqueKey.isValid()) {
fLifeCycle = kUncached_LifeCycle;
fBudgeted = SkBudgeted::kNo;
get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this);
}
}

View File

@ -29,18 +29,6 @@ private:
SkBudgeted::kYes == fResource->resourcePriv().isBudgeted();
}
/**
* Is the resource object wrapping an externally allocated GPU resource that Skia has not taken
* ownership of.
*/
bool isBorrowed() const { return GrGpuResource::kBorrowed_LifeCycle == fResource->fLifeCycle; }
/**
* Is the resource object wrapping an externally allocated GPU resource that Skia has taken
* ownership of.
*/
bool isAdopted() const { return GrGpuResource::kAdopted_LifeCycle == fResource->fLifeCycle; }
/**
* Called by the cache to delete the resource under normal circumstances.
*/

View File

@ -44,7 +44,7 @@ public:
* Does the resource count against the resource budget?
*/
SkBudgeted isBudgeted() const {
bool ret = GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle;
bool ret = SkBudgeted::kYes == fResource->fBudgeted;
SkASSERT(ret || !fResource->getUniqueKey().isValid());
return SkBudgeted(ret);
}
@ -52,7 +52,7 @@ public:
/**
* Is the resource object wrapping an externally allocated GPU resource?
*/
bool isExternal() const { return fResource->isExternal(); }
bool refsWrappedObjects() const { return fResource->fRefsWrappedObjects; }
/**
* If this resource can be used as a scratch resource this returns a valid scratch key.

View File

@ -20,7 +20,7 @@ public:
* Initialize to a path with a fixed stroke. Stroke must not be hairline.
*/
GrPath(GrGpu* gpu, const SkPath& skPath, const GrStrokeInfo& stroke)
: INHERITED(gpu, kCached_LifeCycle)
: INHERITED(gpu)
, fBounds(SkRect::MakeEmpty())
, fFillType(GrPathRendering::kWinding_FillType)
#ifdef SK_DEBUG

View File

@ -10,7 +10,7 @@
GrPathRange::GrPathRange(GrGpu* gpu,
PathGenerator* pathGenerator)
: INHERITED(gpu, kCached_LifeCycle),
: INHERITED(gpu),
fPathGenerator(SkRef(pathGenerator)),
fNumPaths(fPathGenerator->getNumPaths()) {
const int numGroups = (fNumPaths + kPathsPerGroup - 1) / kPathsPerGroup;
@ -20,7 +20,7 @@ GrPathRange::GrPathRange(GrGpu* gpu,
GrPathRange::GrPathRange(GrGpu* gpu,
int numPaths)
: INHERITED(gpu, kCached_LifeCycle),
: INHERITED(gpu),
fNumPaths(numPaths) {
}

View File

@ -146,7 +146,7 @@ void GrResourceCache::insertResource(GrGpuResource* resource) {
#endif
}
if (resource->resourcePriv().getScratchKey().isValid()) {
SkASSERT(!resource->resourcePriv().isExternal());
SkASSERT(!resource->resourcePriv().refsWrappedObjects());
fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource);
}
@ -376,7 +376,7 @@ void GrResourceCache::notifyCntReachedZero(GrGpuResource* resource, uint32_t fla
if (SkBudgeted::kNo == resource->resourcePriv().isBudgeted()) {
// Check whether this resource could still be used as a scratch resource.
if (!resource->resourcePriv().isExternal() &&
if (!resource->resourcePriv().refsWrappedObjects() &&
resource->resourcePriv().getScratchKey().isValid()) {
// We won't purge an existing resource to make room for this one.
if (fBudgetedCount < fMaxCount &&
@ -661,19 +661,19 @@ void GrResourceCache::validate() const {
SkASSERT(!resource->getUniqueKey().isValid());
++fScratch;
SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getScratchKey()));
SkASSERT(!resource->resourcePriv().isExternal());
SkASSERT(!resource->resourcePriv().refsWrappedObjects());
} else if (resource->resourcePriv().getScratchKey().isValid()) {
SkASSERT(SkBudgeted::kNo == resource->resourcePriv().isBudgeted() ||
resource->getUniqueKey().isValid());
++fCouldBeScratch;
SkASSERT(fScratchMap->countForKey(resource->resourcePriv().getScratchKey()));
SkASSERT(!resource->resourcePriv().isExternal());
SkASSERT(!resource->resourcePriv().refsWrappedObjects());
}
const GrUniqueKey& uniqueKey = resource->getUniqueKey();
if (uniqueKey.isValid()) {
++fContent;
SkASSERT(fUniqueHash->find(uniqueKey) == resource);
SkASSERT(!resource->resourcePriv().isExternal());
SkASSERT(!resource->resourcePriv().refsWrappedObjects());
SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted());
}

View File

@ -188,9 +188,7 @@ public:
int fNumNonPurgeable;
int fScratch;
int fExternal;
int fBorrowed;
int fAdopted;
int fWrapped;
size_t fUnbudgetedSize;
Stats() { this->reset(); }
@ -200,9 +198,7 @@ public:
fNumPurgeable = 0;
fNumNonPurgeable = 0;
fScratch = 0;
fExternal = 0;
fBorrowed = 0;
fAdopted = 0;
fWrapped = 0;
fUnbudgetedSize = 0;
}
@ -210,14 +206,8 @@ public:
if (resource->cacheAccess().isScratch()) {
++fScratch;
}
if (resource->resourcePriv().isExternal()) {
++fExternal;
}
if (resource->cacheAccess().isBorrowed()) {
++fBorrowed;
}
if (resource->cacheAccess().isAdopted()) {
++fAdopted;
if (resource->resourcePriv().refsWrappedObjects()) {
++fWrapped;
}
if (SkBudgeted::kNo == resource->resourcePriv().isBudgeted()) {
fUnbudgetedSize += resource->gpuMemorySize();

View File

@ -52,9 +52,9 @@ public:
GrUniqueKey* key);
protected:
GrStencilAttachment(GrGpu* gpu, LifeCycle lifeCycle, int width, int height, int bits,
GrStencilAttachment(GrGpu* gpu, int width, int height, int bits,
int sampleCnt)
: GrGpuResource(gpu, lifeCycle)
: GrGpuResource(gpu)
, fWidth(width)
, fHeight(height)
, fBits(bits)

View File

@ -86,16 +86,10 @@ GrSurfaceOrigin resolve_origin(const GrSurfaceDesc& desc) {
}
//////////////////////////////////////////////////////////////////////////////
GrTexture::GrTexture(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc,
GrSLType samplerType, bool wasMipMapDataProvided)
: INHERITED(gpu, lifeCycle, desc)
GrTexture::GrTexture(GrGpu* gpu, const GrSurfaceDesc& desc, GrSLType samplerType,
bool wasMipMapDataProvided)
: INHERITED(gpu, desc)
, fSamplerType(samplerType) {
if (!this->isExternal() && !GrPixelConfigIsCompressed(desc.fConfig)) {
GrScratchKey key;
GrTexturePriv::ComputeScratchKey(desc, &key);
this->setScratchKey(key);
}
if (wasMipMapDataProvided) {
fMipMapsStatus = kValid_MipMapsStatus;
fMaxMipMapLevel = SkMipMap::ComputeLevelCount(fDesc.fWidth, fDesc.fHeight);
@ -105,6 +99,12 @@ GrTexture::GrTexture(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc,
}
}
void GrTexture::computeScratchKey(GrScratchKey* key) const {
if (!GrPixelConfigIsCompressed(fDesc.fConfig)) {
GrTexturePriv::ComputeScratchKey(fDesc, key);
}
}
void GrTexturePriv::ComputeScratchKey(const GrSurfaceDesc& desc, GrScratchKey* key) {
static const GrScratchKey::ResourceType kType = GrScratchKey::GenerateResourceType();

View File

@ -128,7 +128,7 @@ GrGLBuffer::GrGLBuffer(GrGLGpu* gpu, size_t size, GrBufferType intendedType,
}
}
VALIDATE();
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
inline GrGLGpu* GrGLBuffer::glGpu() const {

View File

@ -649,13 +649,10 @@ GrTexture* GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
return nullptr;
}
switch (ownership) {
case kAdopt_GrWrapOwnership:
idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
break;
case kBorrow_GrWrapOwnership:
idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
break;
if (kAdopt_GrWrapOwnership == ownership) {
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
} else {
idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed;
}
surfDesc.fFlags = (GrSurfaceFlags) desc.fFlags;
@ -676,13 +673,12 @@ GrTexture* GrGLGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
GrGLTexture* texture = nullptr;
if (renderTarget) {
GrGLRenderTarget::IDDesc rtIDDesc;
if (!this->createRenderTargetObjects(surfDesc, GrGpuResource::kUncached_LifeCycle,
idDesc.fInfo, &rtIDDesc)) {
if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) {
return nullptr;
}
texture = new GrGLTextureRenderTarget(this, surfDesc, idDesc, rtIDDesc);
texture = GrGLTextureRenderTarget::CreateWrapped(this, surfDesc, idDesc, rtIDDesc);
} else {
texture = new GrGLTexture(this, surfDesc, idDesc);
texture = GrGLTexture::CreateWrapped(this, surfDesc, idDesc);
}
if (nullptr == texture) {
return nullptr;
@ -697,13 +693,10 @@ GrRenderTarget* GrGLGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
idDesc.fRTFBOID = static_cast<GrGLuint>(wrapDesc.fRenderTargetHandle);
idDesc.fMSColorRenderbufferID = 0;
idDesc.fTexFBOID = GrGLRenderTarget::kUnresolvableFBOID;
switch (ownership) {
case kAdopt_GrWrapOwnership:
idDesc.fLifeCycle = GrGpuResource::kAdopted_LifeCycle;
break;
case kBorrow_GrWrapOwnership:
idDesc.fLifeCycle = GrGpuResource::kBorrowed_LifeCycle;
break;
if (kAdopt_GrWrapOwnership == ownership) {
idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
} else {
idDesc.fRTFBOOwnership = GrBackendObjectOwnership::kBorrowed;
}
idDesc.fSampleConfig = GrRenderTarget::kUnified_SampleConfig;
@ -765,8 +758,7 @@ GrRenderTarget* GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTextu
}
GrGLRenderTarget::IDDesc rtIDDesc;
if (!this->createRenderTargetObjects(surfDesc, GrGpuResource::kUncached_LifeCycle,
texInfo, &rtIDDesc)) {
if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) {
return nullptr;
}
return GrGLRenderTarget::CreateWrapped(this, surfDesc, rtIDDesc, 0);
@ -1487,13 +1479,12 @@ static bool renderbuffer_storage_msaa(const GrGLContext& ctx,
}
bool GrGLGpu::createRenderTargetObjects(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrGLTextureInfo& texInfo,
GrGLRenderTarget::IDDesc* idDesc) {
idDesc->fMSColorRenderbufferID = 0;
idDesc->fRTFBOID = 0;
idDesc->fRTFBOOwnership = GrBackendObjectOwnership::kOwned;
idDesc->fTexFBOID = 0;
idDesc->fLifeCycle = lifeCycle;
idDesc->fSampleConfig = (GrGLCaps::kMixedSamples_MSFBOType == this->glCaps().msFBOType() &&
desc.fSampleCnt > 0) ? GrRenderTarget::kStencil_SampleConfig :
GrRenderTarget::kUnified_SampleConfig;
@ -1605,12 +1596,11 @@ static size_t as_size_t(int x) {
}
#endif
static GrGLTexture::IDDesc generate_gl_texture(const GrGLInterface* interface,
GrGpuResource::LifeCycle lifeCycle) {
static GrGLTexture::IDDesc generate_gl_texture(const GrGLInterface* interface) {
GrGLTexture::IDDesc idDesc;
idDesc.fInfo.fID = 0;
GR_GL_CALL(interface, GenTextures(1, &idDesc.fInfo.fID));
idDesc.fLifeCycle = lifeCycle;
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
// When we create the texture, we only
// create GL_TEXTURE_2D at the moment.
// External clients can do something different.
@ -1645,7 +1635,7 @@ static void set_initial_texture_params(const GrGLInterface* interface,
}
GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) {
// We fail if the MSAA was requested and is not available.
if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt) {
@ -1656,7 +1646,7 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
GrGLTexture::IDDesc idDesc;
idDesc.fLifeCycle = lifeCycle;
idDesc.fOwnership = GrBackendObjectOwnership::kOwned;
GrGLTexture::TexParams initialTexParams;
if (!this->createTextureImpl(desc, &idDesc.fInfo, renderTarget, &initialTexParams, texels)) {
return return_null_texture();
@ -1668,17 +1658,17 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
GL_CALL(BindTexture(idDesc.fInfo.fTarget, 0));
GrGLRenderTarget::IDDesc rtIDDesc;
if (!this->createRenderTargetObjects(desc, lifeCycle, idDesc.fInfo, &rtIDDesc)) {
if (!this->createRenderTargetObjects(desc, idDesc.fInfo, &rtIDDesc)) {
GL_CALL(DeleteTextures(1, &idDesc.fInfo.fID));
return return_null_texture();
}
tex = new GrGLTextureRenderTarget(this, desc, idDesc, rtIDDesc);
tex = new GrGLTextureRenderTarget(this, budgeted, desc, idDesc, rtIDDesc);
} else {
bool wasMipMapDataProvided = false;
if (texels.count() > 1) {
wasMipMapDataProvided = true;
}
tex = new GrGLTexture(this, desc, idDesc, wasMipMapDataProvided);
tex = new GrGLTexture(this, budgeted, desc, idDesc, wasMipMapDataProvided);
}
tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
#ifdef TRACE_TEXTURE_CREATION
@ -1689,14 +1679,14 @@ GrTexture* GrGLGpu::onCreateTexture(const GrSurfaceDesc& desc,
}
GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) {
// Make sure that we're not flipping Y.
if (kBottomLeft_GrSurfaceOrigin == desc.fOrigin) {
return return_null_texture();
}
GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface(), lifeCycle);
GrGLTexture::IDDesc idDesc = generate_gl_texture(this->glInterface());
if (!idDesc.fInfo.fID) {
return return_null_texture();
}
@ -1713,7 +1703,7 @@ GrTexture* GrGLGpu::onCreateCompressedTexture(const GrSurfaceDesc& desc,
}
GrGLTexture* tex;
tex = new GrGLTexture(this, desc, idDesc);
tex = new GrGLTexture(this, budgeted, desc, idDesc);
tex->setCachedTexParams(initialTexParams, this->getResetTimestamp());
#ifdef TRACE_TEXTURE_CREATION
SkDebugf("--- new compressed texture [%d] size=(%d %d) config=%d\n",

View File

@ -126,10 +126,10 @@ private:
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override;
GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
GrTexture* onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) override;
GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) override;
GrBuffer* onCreateBuffer(size_t size, GrBufferType intendedType, GrAccessPattern,
@ -347,8 +347,8 @@ private:
int left = 0, int top = 0,
int width = -1, int height = -1);
bool createRenderTargetObjects(const GrSurfaceDesc&, GrGpuResource::LifeCycle lifeCycle,
const GrGLTextureInfo& texInfo, GrGLRenderTarget::IDDesc*);
bool createRenderTargetObjects(const GrSurfaceDesc&, const GrGLTextureInfo& texInfo,
GrGLRenderTarget::IDDesc*);
enum TempFBOTarget {
kSrc_TempFBOTarget,

View File

@ -330,11 +330,11 @@ GrGLPath::GrGLPath(GrGLGpu* gpu, const SkPath& origSkPath, const GrStrokeInfo& o
}
}
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
void GrGLPath::onRelease() {
if (0 != fPathID && this->shouldFreeResources()) {
if (0 != fPathID) {
static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fPathID, 1);
fPathID = 0;
}

View File

@ -16,7 +16,7 @@ GrGLPathRange::GrGLPathRange(GrGLGpu* gpu, PathGenerator* pathGenerator, const G
fBasePathID(gpu->glPathRendering()->genPaths(this->getNumPaths())),
fGpuMemorySize(0) {
this->init();
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
GrGLPathRange::GrGLPathRange(GrGLGpu* gpu,
@ -29,7 +29,7 @@ GrGLPathRange::GrGLPathRange(GrGLGpu* gpu,
fBasePathID(basePathID),
fGpuMemorySize(gpuMemorySize) {
this->init();
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
void GrGLPathRange::init() {
@ -101,7 +101,7 @@ void GrGLPathRange::onInitPath(int index, const SkPath& origSkPath) const {
void GrGLPathRange::onRelease() {
SkASSERT(this->getGpu());
if (0 != fBasePathID && this->shouldFreeResources()) {
if (0 != fBasePathID) {
static_cast<GrGLGpu*>(this->getGpu())->glPathRendering()->deletePaths(fBasePathID,
this->getNumPaths());
fBasePathID = 0;

View File

@ -7,29 +7,31 @@
#include "GrGLRenderTarget.h"
#include "GrRenderTargetPriv.h"
#include "GrGLGpu.h"
#include "GrGLUtil.h"
#include "GrGpuResourcePriv.h"
#include "GrRenderTargetPriv.h"
#include "SkTraceMemoryDump.h"
#define GPUGL static_cast<GrGLGpu*>(this->getGpu())
#define GL_CALL(X) GR_GL_CALL(GPUGL->glInterface(), X)
// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
// Constructor for wrapped render targets.
GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const IDDesc& idDesc,
GrGLStencilAttachment* stencil)
: GrSurface(gpu, idDesc.fLifeCycle, desc)
, INHERITED(gpu, idDesc.fLifeCycle, desc, idDesc.fSampleConfig, stencil) {
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, idDesc.fSampleConfig, stencil) {
this->init(desc, idDesc);
this->registerWithCache();
this->registerWithCacheWrapped();
}
GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
Derived)
: GrSurface(gpu, idDesc.fLifeCycle, desc)
, INHERITED(gpu, idDesc.fLifeCycle, desc, idDesc.fSampleConfig) {
GrGLRenderTarget::GrGLRenderTarget(GrGLGpu* gpu, const GrSurfaceDesc& desc,
const IDDesc& idDesc)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, idDesc.fSampleConfig) {
this->init(desc, idDesc);
}
@ -37,7 +39,7 @@ void GrGLRenderTarget::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
fRTFBOID = idDesc.fRTFBOID;
fTexFBOID = idDesc.fTexFBOID;
fMSColorRenderbufferID = idDesc.fMSColorRenderbufferID;
fRTLifecycle = idDesc.fLifeCycle;
fRTFBOOwnership = idDesc.fRTFBOOwnership;
fViewport.fLeft = 0;
fViewport.fBottom = 0;
@ -127,7 +129,7 @@ bool GrGLRenderTarget::completeStencilAttachment() {
}
void GrGLRenderTarget::onRelease() {
if (kBorrowed_LifeCycle != fRTLifecycle) {
if (GrBackendObjectOwnership::kBorrowed != fRTFBOOwnership) {
if (fTexFBOID) {
GL_CALL(DeleteFramebuffers(1, &fTexFBOID));
}
@ -156,6 +158,13 @@ GrGLGpu* GrGLRenderTarget::getGLGpu() const {
return static_cast<GrGLGpu*>(this->getGpu());
}
bool GrGLRenderTarget::canAttemptStencilAttachment() const {
// When we have not created the FBO ID we do not attempt to modify its attachments.
// Direct GrGLRenderTarget instances are always created with CreateWrapped.
SkASSERT(this->resourcePriv().refsWrappedObjects());
return false;
}
void GrGLRenderTarget::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const {
// Don't log the backing texture's contribution to the memory size. This will be handled by the
// texture object.

View File

@ -24,9 +24,9 @@ public:
struct IDDesc {
GrGLuint fRTFBOID;
GrBackendObjectOwnership fRTFBOOwnership;
GrGLuint fTexFBOID;
GrGLuint fMSColorRenderbufferID;
GrGpuResource::LifeCycle fLifeCycle;
GrRenderTarget::SampleConfig fSampleConfig;
};
@ -61,21 +61,15 @@ public:
GrBackendObject getRenderTargetHandle() const override { return fRTFBOID; }
/** When we don't own the FBO ID we don't attempt to modify its attachments. */
bool canAttemptStencilAttachment() const override {
return kCached_LifeCycle == fRTLifecycle || kUncached_LifeCycle == fRTLifecycle;
}
bool canAttemptStencilAttachment() const override;
// GrGLRenderTarget overrides dumpMemoryStatistics so it can log its texture and renderbuffer
// components seperately.
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
protected:
// The public constructor registers this object with the cache. However, only the most derived
// class should register with the cache. This constructor does not do the registration and
// rather moves that burden onto the derived class.
enum Derived { kDerived };
GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived);
// Constructor for subclasses.
GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&);
void init(const GrSurfaceDesc&, const IDDesc&);
@ -86,8 +80,7 @@ protected:
size_t onGpuMemorySize() const override;
private:
// This ctor is used only for creating wrapped render targets and is only called for the static
// create function CreateWrapped(...).
// Constructor for instances wrapping backend objects.
GrGLRenderTarget(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, GrGLStencilAttachment*);
GrGLGpu* getGLGpu() const;
@ -103,9 +96,7 @@ private:
GrGLuint fTexFBOID;
GrGLuint fMSColorRenderbufferID;
// We track this separately from GrGpuResource because this may be both a texture and a render
// target, and the texture may be wrapped while the render target is not.
LifeCycle fRTLifecycle;
GrBackendObjectOwnership fRTFBOOwnership;
// when we switch to this render target we want to set the viewport to
// only render to content area (as opposed to the whole allocation) and

View File

@ -19,7 +19,7 @@ size_t GrGLStencilAttachment::onGpuMemorySize() const {
}
void GrGLStencilAttachment::onRelease() {
if (0 != fRenderbufferID && this->shouldFreeResources()) {
if (0 != fRenderbufferID) {
GrGLGpu* gpuGL = (GrGLGpu*) this->getGpu();
const GrGLInterface* gl = gpuGL->glInterface();
GR_GL_CALL(gl, DeleteRenderbuffers(1, &fRenderbufferID));

View File

@ -24,20 +24,19 @@ public:
};
struct IDDesc {
IDDesc() : fRenderbufferID(0), fLifeCycle(kCached_LifeCycle) {}
IDDesc() : fRenderbufferID(0) {}
GrGLuint fRenderbufferID;
GrGpuResource::LifeCycle fLifeCycle;
};
GrGLStencilAttachment(GrGpu* gpu,
const IDDesc& idDesc,
int width, int height,
int sampleCnt,
const Format& format)
: GrStencilAttachment(gpu, idDesc.fLifeCycle, width, height, format.fStencilBits, sampleCnt)
const IDDesc& idDesc,
int width, int height,
int sampleCnt,
const Format& format)
: GrStencilAttachment(gpu, width, height, format.fStencilBits, sampleCnt)
, fFormat(format)
, fRenderbufferID(idDesc.fRenderbufferID) {
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
GrGLuint renderbufferID() const {

View File

@ -26,24 +26,33 @@ inline static GrSLType sampler_type(const GrGLTexture::IDDesc& idDesc, const GrG
}
// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc)
: GrSurface(gpu, idDesc.fLifeCycle, desc)
, INHERITED(gpu, idDesc.fLifeCycle, desc, sampler_type(idDesc, gpu), false) {
GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
const IDDesc& idDesc)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, gpu), false) {
this->init(desc, idDesc);
this->registerWithCache();
this->registerWithCache(budgeted);
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc,
GrGLTexture::GrGLTexture(GrGLGpu* gpu, SkBudgeted budgeted, const GrSurfaceDesc& desc,
const IDDesc& idDesc,
bool wasMipMapDataProvided)
: GrSurface(gpu, idDesc.fLifeCycle, desc)
, INHERITED(gpu, idDesc.fLifeCycle, desc, sampler_type(idDesc, gpu), wasMipMapDataProvided) {
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, gpu), wasMipMapDataProvided) {
this->init(desc, idDesc);
this->registerWithCache();
this->registerWithCache(budgeted);
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc, Derived)
: GrSurface(gpu, idDesc.fLifeCycle, desc)
, INHERITED(gpu, idDesc.fLifeCycle, desc, sampler_type(idDesc, gpu), false) {
GrGLTexture::GrGLTexture(GrGLGpu* gpu, Wrapped, const GrSurfaceDesc& desc, const IDDesc& idDesc)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, gpu), false) {
this->init(desc, idDesc);
this->registerWithCacheWrapped();
}
GrGLTexture::GrGLTexture(GrGLGpu* gpu, const GrSurfaceDesc& desc, const IDDesc& idDesc)
: GrSurface(gpu, desc)
, INHERITED(gpu, desc, sampler_type(idDesc, gpu), false) {
this->init(desc, idDesc);
}
@ -52,12 +61,12 @@ void GrGLTexture::init(const GrSurfaceDesc& desc, const IDDesc& idDesc) {
fTexParams.invalidate();
fTexParamsTimestamp = GrGpu::kExpiredTimestamp;
fInfo = idDesc.fInfo;
fTextureIDLifecycle = idDesc.fLifeCycle;
fTextureIDOwnership = idDesc.fOwnership;
}
void GrGLTexture::onRelease() {
if (fInfo.fID) {
if (GrGpuResource::kBorrowed_LifeCycle != fTextureIDLifecycle) {
if (GrBackendObjectOwnership::kBorrowed != fTextureIDOwnership) {
GL_CALL(DeleteTextures(1, &fInfo.fID));
}
fInfo.fID = 0;
@ -86,3 +95,9 @@ void GrGLTexture::setMemoryBacking(SkTraceMemoryDump* traceMemoryDump,
traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture",
texture_id.c_str());
}
GrGLTexture* GrGLTexture::CreateWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
const IDDesc& idDesc) {
return new GrGLTexture(gpu, kWrapped, desc, idDesc);
}

View File

@ -16,7 +16,6 @@
class GrGLGpu;
class GrGLTexture : public GrTexture {
public:
struct TexParams {
GrGLenum fMinFilter;
@ -31,11 +30,11 @@ public:
struct IDDesc {
GrGLTextureInfo fInfo;
GrGpuResource::LifeCycle fLifeCycle;
GrBackendObjectOwnership fOwnership;
};
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&);
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, bool wasMipMapDataProvided);
GrGLTexture(GrGLGpu*, SkBudgeted, const GrSurfaceDesc&, const IDDesc&);
GrGLTexture(GrGLGpu*, SkBudgeted, const GrSurfaceDesc&, const IDDesc&,
bool wasMipMapDataProvided);
GrBackendObject getTextureHandle() const override;
@ -57,12 +56,14 @@ public:
GrGLenum target() const { return fInfo.fTarget; }
static GrGLTexture* CreateWrapped(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&);
protected:
// The public constructor registers this object with the cache. However, only the most derived
// class should register with the cache. This constructor does not do the registration and
// rather moves that burden onto the derived class.
enum Derived { kDerived };
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&, Derived);
// Constructor for subclasses.
GrGLTexture(GrGLGpu*, const GrSurfaceDesc&, const IDDesc&);
enum Wrapped { kWrapped };
// Constructor for instances wrapping backend objects.
GrGLTexture(GrGLGpu*, Wrapped, const GrSurfaceDesc&, const IDDesc&);
void init(const GrSurfaceDesc&, const IDDesc&);
@ -77,10 +78,7 @@ private:
// Holds the texture target and ID. A pointer to this may be shared to external clients for
// direct interaction with the GL object.
GrGLTextureInfo fInfo;
// We track this separately from GrGpuResource because this may be both a texture and a render
// target, and the texture may be wrapped while the render target is not.
LifeCycle fTextureIDLifecycle;
GrBackendObjectOwnership fTextureIDOwnership;
typedef GrTexture INHERITED;
};

View File

@ -37,3 +37,16 @@ void GrGLTextureRenderTarget::dumpMemoryStatistics(
traceMemoryDump->setMemoryBacking(dumpName.c_str(), "gl_texture",
texture_id.c_str());
}
bool GrGLTextureRenderTarget::canAttemptStencilAttachment() const {
// The RT FBO of GrGLTextureRenderTarget is never created from a
// wrapped FBO.
return true;
}
GrGLTextureRenderTarget* GrGLTextureRenderTarget::CreateWrapped(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
const GrGLRenderTarget::IDDesc& rtIDDesc) {
return new GrGLTextureRenderTarget(gpu, desc, texIDDesc, rtIDDesc);
}

View File

@ -26,17 +26,23 @@ public:
// We're virtually derived from GrSurface (via both GrGLTexture and GrGLRenderTarget) so its
// constructor must be explicitly called.
GrGLTextureRenderTarget(GrGLGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
const GrGLRenderTarget::IDDesc& rtIDDesc)
: GrSurface(gpu, texIDDesc.fLifeCycle, desc)
, GrGLTexture(gpu, desc, texIDDesc, GrGLTexture::kDerived)
, GrGLRenderTarget(gpu, desc, rtIDDesc, GrGLRenderTarget::kDerived) {
this->registerWithCache();
: GrSurface(gpu, desc)
, GrGLTexture(gpu, desc, texIDDesc)
, GrGLRenderTarget(gpu, desc, rtIDDesc) {
this->registerWithCache(budgeted);
}
bool canAttemptStencilAttachment() const override;
void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const override;
static GrGLTextureRenderTarget* CreateWrapped(GrGLGpu* gpu, const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
const GrGLRenderTarget::IDDesc& rtIDDesc);
protected:
void onAbandon() override {
GrGLRenderTarget::onAbandon();
@ -49,6 +55,17 @@ protected:
}
private:
// Constructor for instances wrapping backend objects.
GrGLTextureRenderTarget(GrGLGpu* gpu,
const GrSurfaceDesc& desc,
const GrGLTexture::IDDesc& texIDDesc,
const GrGLRenderTarget::IDDesc& rtIDDesc)
: GrSurface(gpu, desc)
, GrGLTexture(gpu, desc, texIDDesc)
, GrGLRenderTarget(gpu, desc, rtIDDesc) {
this->registerWithCacheWrapped();
}
// GrGLRenderTarget accounts for the texture's memory and any MSAA renderbuffer's memory.
size_t onGpuMemorySize() const override {
return GrGLRenderTarget::onGpuMemorySize();

View File

@ -438,7 +438,7 @@ bool GrVkGpu::uploadTexData(GrVkTexture* tex,
}
////////////////////////////////////////////////////////////////////////////////
GrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
GrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) {
bool renderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
@ -493,10 +493,10 @@ GrTexture* GrVkGpu::onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::Li
GrVkTexture* tex;
if (renderTarget) {
tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, desc, lifeCycle,
tex = GrVkTextureRenderTarget::CreateNewTextureRenderTarget(this, budgeted, desc,
imageDesc);
} else {
tex = GrVkTexture::CreateNewTexture(this, desc, lifeCycle, imageDesc);
tex = GrVkTexture::CreateNewTexture(this, budgeted, desc, imageDesc);
}
if (!tex) {
@ -548,10 +548,6 @@ GrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
return nullptr;
}
GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership)
? GrGpuResource::kAdopted_LifeCycle
: GrGpuResource::kBorrowed_LifeCycle;
GrSurfaceDesc surfDesc;
// next line relies on GrBackendTextureDesc's flags matching GrTexture's
surfDesc.fFlags = (GrSurfaceFlags)desc.fFlags;
@ -567,11 +563,10 @@ GrTexture* GrVkGpu::onWrapBackendTexture(const GrBackendTextureDesc& desc,
GrVkTexture* texture = nullptr;
if (renderTarget) {
texture = GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(this, surfDesc,
lifeCycle, format,
ownership, format,
info);
} else {
texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, lifeCycle, format,
info);
texture = GrVkTexture::CreateWrappedTexture(this, surfDesc, ownership, format, info);
}
if (!texture) {
return nullptr;
@ -590,10 +585,6 @@ GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
return nullptr;
}
GrGpuResource::LifeCycle lifeCycle = (kAdopt_GrWrapOwnership == ownership)
? GrGpuResource::kAdopted_LifeCycle
: GrGpuResource::kBorrowed_LifeCycle;
GrSurfaceDesc desc;
desc.fConfig = wrapDesc.fConfig;
desc.fFlags = kCheckAllocation_GrSurfaceFlag;
@ -604,7 +595,7 @@ GrRenderTarget* GrVkGpu::onWrapBackendRenderTarget(const GrBackendRenderTargetDe
desc.fOrigin = resolve_origin(wrapDesc.fOrigin);
GrVkRenderTarget* tgt = GrVkRenderTarget::CreateWrappedRenderTarget(this, desc,
lifeCycle,
ownership,
info);
if (tgt && wrapDesc.fStencilBits) {
if (!createStencilAttachmentForRenderTarget(tgt, desc.fWidth, desc.fHeight)) {
@ -652,7 +643,6 @@ GrStencilAttachment* GrVkGpu::createStencilAttachmentForRenderTarget(const GrRen
const GrVkCaps::StencilFormat& sFmt = this->vkCaps().preferedStencilFormat();
GrVkStencilAttachment* stencil(GrVkStencilAttachment::Create(this,
GrGpuResource::kCached_LifeCycle,
width,
height,
samples,

View File

@ -117,10 +117,10 @@ private:
void onResetContext(uint32_t resetBits) override {}
GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle,
GrTexture* onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const SkTArray<GrMipLevel>&) override;
GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle,
GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, SkBudgeted,
const SkTArray<GrMipLevel>&) override { return NULL; }
GrTexture* onWrapBackendTexture(const GrBackendTextureDesc&, GrWrapOwnership) override;

View File

@ -13,7 +13,7 @@ GrVkIndexBuffer::GrVkIndexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
: INHERITED(gpu, desc.fSizeInBytes, kIndex_GrBufferType,
desc.fDynamic ? kDynamic_GrAccessPattern : kStatic_GrAccessPattern, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
GrVkIndexBuffer* GrVkIndexBuffer::Create(GrVkGpu* gpu, size_t size, bool dynamic) {

View File

@ -22,16 +22,16 @@
// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImage::Resource* msaaResource,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView)
: GrSurface(gpu, lifeCycle, desc)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
// for the moment we only support 1:1 color to stencil
, GrRenderTarget(gpu, lifeCycle, desc, kUnified_SampleConfig)
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImageResource(msaaResource)
@ -41,7 +41,7 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
// The plus 1 is to account for the resolve texture.
fColorValuesPerPixel = desc.fSampleCnt + 1; // TODO: this still correct?
this->createFramebuffer(gpu);
this->registerWithCache();
this->registerWithCache(budgeted);
msaaResource->ref();
}
@ -49,16 +49,14 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
// constructor must be explicitly called.
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImage::Resource* msaaResource,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
Derived)
: GrSurface(gpu, lifeCycle, desc)
const GrVkImageView* resolveAttachmentView)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
// for the moment we only support 1:1 color to stencil
, GrRenderTarget(gpu, lifeCycle, desc, kUnified_SampleConfig)
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImageResource(msaaResource)
@ -74,13 +72,13 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* colorAttachmentView)
: GrSurface(gpu, lifeCycle, desc)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, GrRenderTarget(gpu, lifeCycle, desc, kUnified_SampleConfig)
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImageResource(nullptr)
@ -89,20 +87,18 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
SkASSERT(!desc.fSampleCnt);
fColorValuesPerPixel = 1;
this->createFramebuffer(gpu);
this->registerWithCache();
this->registerWithCache(budgeted);
}
// We're virtually derived from GrSurface (via GrRenderTarget) so its
// constructor must be explicitly called.
GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* colorAttachmentView,
Derived)
: GrSurface(gpu, lifeCycle, desc)
const GrVkImageView* colorAttachmentView)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, GrRenderTarget(gpu, lifeCycle, desc, kUnified_SampleConfig)
, GrRenderTarget(gpu, desc, kUnified_SampleConfig)
, fFramebuffer(nullptr)
, fColorAttachmentView(colorAttachmentView)
, fMSAAImageResource(nullptr)
@ -115,8 +111,8 @@ GrVkRenderTarget::GrVkRenderTarget(GrVkGpu* gpu,
GrVkRenderTarget*
GrVkRenderTarget::Create(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource) {
VkFormat pixelFormat;
GrPixelConfigToVkFormat(desc.fConfig, &pixelFormat);
@ -172,11 +168,11 @@ GrVkRenderTarget::Create(GrVkGpu* gpu,
GrVkRenderTarget* texRT;
if (msaaResource) {
texRT = new GrVkRenderTarget(gpu, desc, lifeCycle, imageResource, msaaResource,
texRT = new GrVkRenderTarget(gpu, budgeted, desc, imageResource, msaaResource,
colorAttachmentView, resolveAttachmentView);
msaaResource->unref(gpu);
} else {
texRT = new GrVkRenderTarget(gpu, desc, lifeCycle, imageResource,
texRT = new GrVkRenderTarget(gpu, budgeted, desc, imageResource,
colorAttachmentView);
}
@ -185,8 +181,8 @@ GrVkRenderTarget::Create(GrVkGpu* gpu,
GrVkRenderTarget*
GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::ImageDesc& imageDesc) {
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
@ -195,7 +191,7 @@ GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu,
return nullptr;
}
GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, desc, lifeCycle, imageResource);
GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, budgeted, desc, imageResource);
// Create() will increment the refCount of the image resource if it succeeds
imageResource->unref(gpu);
return rt;
@ -204,18 +200,18 @@ GrVkRenderTarget::CreateNewRenderTarget(GrVkGpu* gpu,
GrVkRenderTarget*
GrVkRenderTarget::CreateWrappedRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
GrWrapOwnership ownership,
const GrVkTextureInfo* info) {
SkASSERT(info);
// We can wrap a rendertarget without its allocation, as long as we don't take ownership
SkASSERT(VK_NULL_HANDLE != info->fImage);
SkASSERT(VK_NULL_HANDLE != info->fAlloc || kAdopted_LifeCycle != lifeCycle);
SkASSERT(VK_NULL_HANDLE != info->fAlloc || kAdopt_GrWrapOwnership != ownership);
GrVkImage::Resource::Flags flags = (VK_IMAGE_TILING_LINEAR == info->fImageTiling)
? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
const GrVkImage::Resource* imageResource;
if (kBorrowed_LifeCycle == lifeCycle) {
if (kBorrow_GrWrapOwnership == ownership) {
imageResource = new GrVkImage::BorrowedResource(info->fImage,
info->fAlloc,
flags,
@ -227,7 +223,7 @@ GrVkRenderTarget::CreateWrappedRenderTarget(GrVkGpu* gpu,
return nullptr;
}
GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, desc, lifeCycle, imageResource);
GrVkRenderTarget* rt = GrVkRenderTarget::Create(gpu, SkBudgeted::kNo, desc, imageResource);
if (rt) {
rt->fCurrentLayout = info->fImageLayout;
}
@ -367,12 +363,7 @@ void GrVkRenderTarget::abandonInternalObjects() {
void GrVkRenderTarget::onRelease() {
this->releaseInternalObjects();
if (this->shouldFreeResources()) {
this->releaseImage(this->getVkGpu());
} else {
this->abandonImage();
}
this->releaseImage(this->getVkGpu());
GrRenderTarget::onRelease();
}

View File

@ -30,12 +30,11 @@ struct GrVkTextureInfo;
class GrVkRenderTarget: public GrRenderTarget, public virtual GrVkImage {
public:
static GrVkRenderTarget* CreateNewRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
static GrVkRenderTarget* CreateNewRenderTarget(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&,
const GrVkImage::ImageDesc&);
static GrVkRenderTarget* CreateWrappedRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
GrWrapOwnership,
const GrVkTextureInfo*);
~GrVkRenderTarget() override;
@ -67,11 +66,9 @@ public:
void addResources(GrVkCommandBuffer& commandBuffer) const;
protected:
enum Derived { kDerived };
GrVkRenderTarget(GrVkGpu* gpu,
SkBudgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImage::Resource* msaaImageResource,
const GrVkImageView* colorAttachmentView,
@ -79,28 +76,23 @@ protected:
GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImage::Resource* msaaImageResource,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView,
Derived);
const GrVkImageView* resolveAttachmentView);
GrVkRenderTarget(GrVkGpu* gpu,
SkBudgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* colorAttachmentView);
GrVkRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* colorAttachmentView,
Derived);
const GrVkImageView* colorAttachmentView);
static GrVkRenderTarget* Create(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
static GrVkRenderTarget* Create(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&,
const GrVkImage::Resource* imageResource);
GrVkGpu* getVkGpu() const;

View File

@ -14,22 +14,20 @@
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
GrVkStencilAttachment::GrVkStencilAttachment(GrVkGpu* gpu,
GrGpuResource::LifeCycle lifeCycle,
const Format& format,
const GrVkImage::ImageDesc& desc,
const GrVkImage::Resource* imageResource,
const GrVkImageView* stencilView)
: GrStencilAttachment(gpu, lifeCycle, desc.fWidth, desc.fHeight,
: GrStencilAttachment(gpu, desc.fWidth, desc.fHeight,
format.fStencilBits, desc.fSamples)
, GrVkImage(imageResource)
, fFormat(format)
, fStencilView(stencilView) {
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
stencilView->ref();
}
GrVkStencilAttachment* GrVkStencilAttachment::Create(GrVkGpu* gpu,
GrGpuResource::LifeCycle lifeCycle,
int width,
int height,
int sampleCnt,
@ -59,7 +57,7 @@ GrVkStencilAttachment* GrVkStencilAttachment::Create(GrVkGpu* gpu,
return nullptr;
}
GrVkStencilAttachment* stencil = new GrVkStencilAttachment(gpu, lifeCycle, format, imageDesc,
GrVkStencilAttachment* stencil = new GrVkStencilAttachment(gpu, format, imageDesc,
imageResource, imageView);
imageResource->unref(gpu);
imageView->unref(gpu);

View File

@ -24,8 +24,7 @@ public:
bool fPacked;
};
static GrVkStencilAttachment* Create(GrVkGpu* gpu, GrGpuResource::LifeCycle lifeCycle,
int width, int height,
static GrVkStencilAttachment* Create(GrVkGpu* gpu, int width, int height,
int sampleCnt, const Format& format);
~GrVkStencilAttachment() override;
@ -43,7 +42,6 @@ private:
size_t onGpuMemorySize() const override;
GrVkStencilAttachment(GrVkGpu* gpu,
GrGpuResource::LifeCycle lifeCycle,
const Format& format,
const GrVkImage::ImageDesc&,
const GrVkImage::Resource*,

View File

@ -16,35 +16,47 @@
// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrVkTexture::GrVkTexture(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* view)
: GrSurface(gpu, lifeCycle, desc)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, INHERITED(gpu, lifeCycle, desc, kSampler2D_GrSLType,
, INHERITED(gpu, desc, kSampler2D_GrSLType,
false) // false because we don't upload MIP data in Vk yet
, fTextureView(view) {
this->registerWithCache();
this->registerWithCache(budgeted);
}
GrVkTexture::GrVkTexture(GrVkGpu* gpu,
Wrapped,
const GrSurfaceDesc& desc,
const GrVkImage::Resource* imageResource,
const GrVkImageView* view)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, INHERITED(gpu, desc, kSampler2D_GrSLType,
false) // false because we don't upload MIP data in Vk yet
, fTextureView(view) {
this->registerWithCacheWrapped();
}
// Because this class is virtually derived from GrSurface we must explicitly call its constructor.
GrVkTexture::GrVkTexture(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* view,
Derived)
: GrSurface(gpu, lifeCycle, desc)
const GrVkImageView* view)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, INHERITED(gpu, lifeCycle, desc, kSampler2D_GrSLType,
, INHERITED(gpu, desc, kSampler2D_GrSLType,
false) // false because we don't upload MIP data in Vk yet
, fTextureView(view) {}
template<typename ResourceType>
GrVkTexture* GrVkTexture::Create(GrVkGpu* gpu,
ResourceType type,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
VkFormat format,
const GrVkImage::Resource* imageResource) {
VkImage image = imageResource->fImage;
@ -54,11 +66,11 @@ GrVkTexture* GrVkTexture::Create(GrVkGpu* gpu,
return nullptr;
}
return new GrVkTexture(gpu, desc, lifeCycle, imageResource, imageView);
return new GrVkTexture(gpu, type, desc, imageResource, imageView);
}
GrVkTexture* GrVkTexture::CreateNewTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
GrVkTexture* GrVkTexture::CreateNewTexture(GrVkGpu* gpu, SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImage::ImageDesc& imageDesc) {
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
@ -67,15 +79,16 @@ GrVkTexture* GrVkTexture::CreateNewTexture(GrVkGpu* gpu, const GrSurfaceDesc& de
return nullptr;
}
GrVkTexture* texture = Create(gpu, desc, lifeCycle, imageDesc.fFormat, imageResource);
GrVkTexture* texture = Create(gpu, budgeted, desc, imageDesc.fFormat, imageResource);
// Create() will increment the refCount of the image resource if it succeeds
imageResource->unref(gpu);
return texture;
}
GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu, const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrWrapOwnership ownership,
VkFormat format,
const GrVkTextureInfo* info) {
SkASSERT(info);
@ -86,7 +99,7 @@ GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu, const GrSurfaceDesc
? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
const GrVkImage::Resource* imageResource;
if (kBorrowed_LifeCycle == lifeCycle) {
if (kBorrow_GrWrapOwnership == ownership) {
imageResource = new GrVkImage::BorrowedResource(info->fImage,
info->fAlloc,
flags,
@ -98,7 +111,7 @@ GrVkTexture* GrVkTexture::CreateWrappedTexture(GrVkGpu* gpu, const GrSurfaceDesc
return nullptr;
}
GrVkTexture* texture = Create(gpu, desc, lifeCycle, format, imageResource);
GrVkTexture* texture = Create(gpu, kWrapped, desc, format, imageResource);
if (texture) {
texture->fCurrentLayout = info->fImageLayout;
}
@ -120,11 +133,7 @@ void GrVkTexture::onRelease() {
fTextureView = nullptr;
}
if (this->shouldFreeResources()) {
this->releaseImage(this->getVkGpu());
} else {
this->abandonImage();
}
this->releaseImage(this->getVkGpu());
INHERITED::onRelease();
}

View File

@ -18,12 +18,11 @@ struct GrVkTextureInfo;
class GrVkTexture : public GrTexture, public virtual GrVkImage {
public:
static GrVkTexture* CreateNewTexture(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
static GrVkTexture* CreateNewTexture(GrVkGpu*, SkBudgeted budgeted, const GrSurfaceDesc&,
const GrVkImage::ImageDesc&);
static GrVkTexture* CreateWrappedTexture(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
GrWrapOwnership,
VkFormat, const GrVkTextureInfo*);
~GrVkTexture() override;
@ -35,16 +34,11 @@ public:
const GrVkImageView* textureView() const { return fTextureView; }
protected:
enum Derived { kDerived };
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, GrGpuResource::LifeCycle,
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&,
const GrVkImage::Resource*, const GrVkImageView* imageView);
GrVkTexture(GrVkGpu*, const GrSurfaceDesc&, GrGpuResource::LifeCycle,
const GrVkImage::Resource*, const GrVkImageView* imageView, Derived);
static GrVkTexture* Create(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle, VkFormat,
template<typename ResourceType>
static GrVkTexture* Create(GrVkGpu*, ResourceType, const GrSurfaceDesc&, VkFormat,
const GrVkImage::Resource* texImpl);
GrVkGpu* getVkGpu() const;
@ -53,6 +47,13 @@ protected:
void onRelease() override;
private:
enum Wrapped { kWrapped };
GrVkTexture(GrVkGpu*, SkBudgeted, const GrSurfaceDesc&,
const GrVkImage::Resource*, const GrVkImageView* imageView);
GrVkTexture(GrVkGpu*, Wrapped, const GrSurfaceDesc&,
const GrVkImage::Resource*, const GrVkImageView* imageView);
const GrVkImageView* fTextureView;
typedef GrTexture INHERITED;

View File

@ -16,13 +16,12 @@
#define VK_CALL(GPU, X) GR_VK_CALL(GPU->vkInterface(), X)
GrVkTextureRenderTarget*
GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
VkFormat format,
const GrVkImage::Resource* imageResource) {
template<typename ResourceType>
GrVkTextureRenderTarget* GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
ResourceType resourceType,
const GrSurfaceDesc& desc,
VkFormat format,
const GrVkImage::Resource* imageResource) {
VkImage image = imageResource->fImage;
// Create the texture ImageView
const GrVkImageView* imageView = GrVkImageView::Create(gpu, image, format,
@ -99,16 +98,15 @@ GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
return nullptr;
}
}
GrVkTextureRenderTarget* texRT;
if (msaaImageResource) {
texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
texRT = new GrVkTextureRenderTarget(gpu, resourceType, desc,
imageResource, imageView, msaaImageResource,
colorAttachmentView,
resolveAttachmentView);
msaaImageResource->unref(gpu);
} else {
texRT = new GrVkTextureRenderTarget(gpu, desc, lifeCycle,
texRT = new GrVkTextureRenderTarget(gpu, resourceType, desc,
imageResource, imageView,
colorAttachmentView);
}
@ -117,9 +115,9 @@ GrVkTextureRenderTarget::Create(GrVkGpu* gpu,
GrVkTextureRenderTarget*
GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::ImageDesc& imageDesc) {
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
const GrVkImage::ImageDesc& imageDesc) {
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
SkASSERT(imageDesc.fUsageFlags & VK_IMAGE_USAGE_SAMPLED_BIT);
@ -129,8 +127,8 @@ GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
return nullptr;
}
GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
imageDesc.fFormat, imageRsrc);
GrVkTextureRenderTarget* trt = Create(gpu, budgeted, desc, imageDesc.fFormat,
imageRsrc);
// Create() will increment the refCount of the image resource if it succeeds
imageRsrc->unref(gpu);
@ -140,7 +138,7 @@ GrVkTextureRenderTarget::CreateNewTextureRenderTarget(GrVkGpu* gpu,
GrVkTextureRenderTarget*
GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
GrWrapOwnership ownership,
VkFormat format,
const GrVkTextureInfo* info) {
SkASSERT(info);
@ -151,7 +149,7 @@ GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
? Resource::kLinearTiling_Flag : Resource::kNo_Flags;
const GrVkImage::Resource* imageResource;
if (kBorrowed_LifeCycle == lifeCycle) {
if (kBorrow_GrWrapOwnership == ownership) {
imageResource = new GrVkImage::BorrowedResource(info->fImage,
info->fAlloc,
flags,
@ -162,9 +160,7 @@ GrVkTextureRenderTarget::CreateWrappedTextureRenderTarget(GrVkGpu* gpu,
if (!imageResource) {
return nullptr;
}
GrVkTextureRenderTarget* trt = GrVkTextureRenderTarget::Create(gpu, desc, lifeCycle,
format, imageResource);
GrVkTextureRenderTarget* trt = Create(gpu, kWrapped, desc, format, imageResource);
if (trt) {
trt->fCurrentLayout = info->fImageLayout;
}

View File

@ -24,13 +24,13 @@ struct GrVkTextureInfo;
class GrVkTextureRenderTarget: public GrVkTexture, public GrVkRenderTarget {
public:
static GrVkTextureRenderTarget* CreateNewTextureRenderTarget(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
static GrVkTextureRenderTarget* CreateNewTextureRenderTarget(GrVkGpu*, SkBudgeted,
const GrSurfaceDesc&,
const GrVkImage::ImageDesc&);
static GrVkTextureRenderTarget* CreateWrappedTextureRenderTarget(GrVkGpu*,
const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
GrWrapOwnership,
VkFormat,
const GrVkTextureInfo*);
@ -47,38 +47,68 @@ protected:
private:
GrVkTextureRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* texView,
const GrVkImage::Resource* msaaResource,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView)
: GrSurface(gpu, lifeCycle, desc)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, GrVkTexture(gpu, desc, lifeCycle, imageResource, texView, GrVkTexture::kDerived)
, GrVkRenderTarget(gpu, desc, lifeCycle, imageResource, msaaResource, colorAttachmentView,
resolveAttachmentView, GrVkRenderTarget::kDerived) {
this->registerWithCache();
, GrVkTexture(gpu, desc, imageResource, texView)
, GrVkRenderTarget(gpu, desc, imageResource, msaaResource, colorAttachmentView,
resolveAttachmentView) {
this->registerWithCache(budgeted);
}
GrVkTextureRenderTarget(GrVkGpu* gpu,
SkBudgeted budgeted,
const GrSurfaceDesc& desc,
GrGpuResource::LifeCycle lifeCycle,
const GrVkImage::Resource* imageResource,
const GrVkImageView* texView,
const GrVkImageView* colorAttachmentView)
: GrSurface(gpu, lifeCycle, desc)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, GrVkTexture(gpu, desc, lifeCycle, imageResource, texView, GrVkTexture::kDerived)
, GrVkRenderTarget(gpu, desc, lifeCycle, imageResource, colorAttachmentView,
GrVkRenderTarget::kDerived) {
this->registerWithCache();
, GrVkTexture(gpu, desc, imageResource, texView)
, GrVkRenderTarget(gpu, desc, imageResource, colorAttachmentView) {
this->registerWithCache(budgeted);
}
enum Wrapped { kWrapped };
GrVkTextureRenderTarget(GrVkGpu* gpu,
Wrapped,
const GrSurfaceDesc& desc,
const GrVkImage::Resource* imageResource,
const GrVkImageView* texView,
const GrVkImage::Resource* msaaResource,
const GrVkImageView* colorAttachmentView,
const GrVkImageView* resolveAttachmentView)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, GrVkTexture(gpu, desc, imageResource, texView)
, GrVkRenderTarget(gpu, desc, imageResource, msaaResource, colorAttachmentView,
resolveAttachmentView) {
this->registerWithCacheWrapped();
}
static GrVkTextureRenderTarget* Create(GrVkGpu*, const GrSurfaceDesc&,
GrGpuResource::LifeCycle,
VkFormat format,
GrVkTextureRenderTarget(GrVkGpu* gpu,
Wrapped,
const GrSurfaceDesc& desc,
const GrVkImage::Resource* imageResource,
const GrVkImageView* texView,
const GrVkImageView* colorAttachmentView)
: GrSurface(gpu, desc)
, GrVkImage(imageResource)
, GrVkTexture(gpu, desc, imageResource, texView)
, GrVkRenderTarget(gpu, desc, imageResource, colorAttachmentView) {
this->registerWithCacheWrapped();
}
template <typename ResourceType>
static GrVkTextureRenderTarget* Create(GrVkGpu*,
ResourceType,
const GrSurfaceDesc&,
VkFormat,
const GrVkImage::Resource* imageResource);
// GrGLRenderTarget accounts for the texture's memory and any MSAA renderbuffer's memory.

View File

@ -36,7 +36,7 @@ GrVkTransferBuffer::GrVkTransferBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& des
kXferCpuToGpu_GrBufferType : kXferGpuToCpu_GrBufferType,
kStream_GrAccessPattern, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
void GrVkTransferBuffer::onRelease() {

View File

@ -13,7 +13,7 @@ GrVkVertexBuffer::GrVkVertexBuffer(GrVkGpu* gpu, const GrVkBuffer::Desc& desc,
: INHERITED(gpu, desc.fSizeInBytes, kVertex_GrBufferType,
desc.fDynamic ? kDynamic_GrAccessPattern : kStatic_GrAccessPattern, false)
, GrVkBuffer(desc, bufferResource) {
this->registerWithCache();
this->registerWithCache(SkBudgeted::kYes);
}
GrVkVertexBuffer* GrVkVertexBuffer::Create(GrVkGpu* gpu, size_t size, bool dynamic) {

View File

@ -85,7 +85,7 @@ sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted, ForceCopyM
// If the original render target is a buffer originally created by the client, then we don't
// want to ever retarget the SkSurface at another buffer we create. Force a copy now to avoid
// copy-on-write.
if (kYes_ForceCopyMode == forceCopyMode || !tex || rt->resourcePriv().isExternal()) {
if (kYes_ForceCopyMode == forceCopyMode || !tex || rt->resourcePriv().refsWrappedObjects()) {
GrSurfaceDesc desc = fDevice->accessRenderTarget()->desc();
GrContext* ctx = fDevice->context();
desc.fFlags = desc.fFlags & ~kRenderTarget_GrSurfaceFlag;

View File

@ -249,35 +249,22 @@ public:
* For example, textures have width, height, ... */
enum SimulatedProperty { kA_SimulatedProperty, kB_SimulatedProperty };
TestResource(GrGpu* gpu, size_t size, GrGpuResource::LifeCycle lifeCycle)
: INHERITED(gpu, lifeCycle)
TestResource(GrGpu* gpu, SkBudgeted budgeted = SkBudgeted::kYes, size_t size = kDefaultSize)
: INHERITED(gpu)
, fToDelete(nullptr)
, fSize(size)
, fProperty(kA_SimulatedProperty) {
, fProperty(kA_SimulatedProperty)
, fIsScratch(false) {
++fNumAlive;
this->registerWithCache();
this->registerWithCache(budgeted);
}
TestResource(GrGpu* gpu, GrGpuResource::LifeCycle lifeCycle)
: INHERITED(gpu, lifeCycle)
, fToDelete(nullptr)
, fSize(kDefaultSize)
, fProperty(kA_SimulatedProperty) {
++fNumAlive;
this->registerWithCache();
static TestResource* CreateScratch(GrGpu* gpu, SkBudgeted budgeted,
SimulatedProperty property) {
return new TestResource(gpu, budgeted, property, kScratchConstructor);
}
TestResource(GrGpu* gpu)
: INHERITED(gpu, kCached_LifeCycle)
, fToDelete(nullptr)
, fSize(kDefaultSize)
, fProperty(kA_SimulatedProperty) {
++fNumAlive;
this->registerWithCache();
}
static TestResource* CreateScratch(GrGpu* gpu, SimulatedProperty property, bool cached = true) {
return new TestResource(gpu, property, cached, kScratchConstructor);
static TestResource* CreateWrapped(GrGpu* gpu, size_t size = kDefaultSize) {
return new TestResource(gpu, size);
}
~TestResource() {
@ -307,20 +294,34 @@ public:
static size_t ExpectedScratchKeySize() {
return sizeof(uint32_t) * (kScratchKeyFieldCnt + GrScratchKey::kMetaDataCnt);
}
private:
static const int kScratchKeyFieldCnt = 6;
TestResource(GrGpu* gpu, SimulatedProperty property, bool cached, ScratchConstructor)
: INHERITED(gpu, cached ? kCached_LifeCycle : kUncached_LifeCycle)
TestResource(GrGpu* gpu, SkBudgeted budgeted, SimulatedProperty property, ScratchConstructor)
: INHERITED(gpu)
, fToDelete(nullptr)
, fSize(kDefaultSize)
, fProperty(property) {
GrScratchKey scratchKey;
ComputeScratchKey(fProperty, &scratchKey);
this->setScratchKey(scratchKey);
, fProperty(property)
, fIsScratch(true) {
++fNumAlive;
this->registerWithCache();
this->registerWithCache(budgeted);
}
// Constructor for simulating resources that wrap backend objects.
TestResource(GrGpu* gpu, size_t size)
: INHERITED(gpu)
, fToDelete(nullptr)
, fSize(size)
, fProperty(kA_SimulatedProperty)
, fIsScratch(false) {
++fNumAlive;
this->registerWithCacheWrapped();
}
void computeScratchKey(GrScratchKey* key) const override {
if (fIsScratch) {
ComputeScratchKey(fProperty, key);
}
}
size_t onGpuMemorySize() const override { return fSize; }
@ -329,6 +330,7 @@ private:
size_t fSize;
static int fNumAlive;
SimulatedProperty fProperty;
bool fIsScratch;
typedef GrGpuResource INHERITED;
};
int TestResource::fNumAlive = 0;
@ -418,15 +420,15 @@ static void test_budgeting(skiatest::Reporter* reporter) {
// Create a scratch, a unique, and a wrapped resource
TestResource* scratch =
TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes, TestResource::kB_SimulatedProperty);
scratch->setSize(10);
TestResource* unique = new TestResource(context->getGpu());
unique->setSize(11);
unique->resourcePriv().setUniqueKey(uniqueKey);
TestResource* wrapped = new TestResource(context->getGpu(), GrGpuResource::kBorrowed_LifeCycle);
TestResource* wrapped = TestResource::CreateWrapped(context->getGpu());
wrapped->setSize(12);
TestResource* unbudgeted =
new TestResource(context->getGpu(), GrGpuResource::kUncached_LifeCycle);
new TestResource(context->getGpu(), SkBudgeted::kNo);
unbudgeted->setSize(13);
// Make sure we can't add a unique key to the wrapped resource
@ -461,7 +463,7 @@ static void test_budgeting(skiatest::Reporter* reporter) {
unbudgeted->gpuMemorySize() == cache->getResourceBytes());
// Now try freeing the budgeted resources first
wrapped = new TestResource(context->getGpu(), GrGpuResource::kBorrowed_LifeCycle);
wrapped = TestResource::CreateWrapped(context->getGpu());
scratch->setSize(12);
unique->unref();
cache->purgeAllUnlocked();
@ -506,7 +508,9 @@ static void test_unbudgeted(skiatest::Reporter* reporter) {
TestResource* unbudgeted;
// A large uncached or wrapped resource shouldn't evict anything.
scratch = TestResource::CreateScratch(context->getGpu(), TestResource::kB_SimulatedProperty);
scratch = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
scratch->setSize(10);
scratch->unref();
REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
@ -524,7 +528,7 @@ static void test_unbudgeted(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
size_t large = 2 * cache->getResourceBytes();
unbudgeted = new TestResource(context->getGpu(), large, GrGpuResource::kUncached_LifeCycle);
unbudgeted = new TestResource(context->getGpu(), SkBudgeted::kNo, large);
REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
@ -536,7 +540,7 @@ static void test_unbudgeted(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
REPORTER_ASSERT(reporter, 21 == cache->getBudgetedResourceBytes());
wrapped = new TestResource(context->getGpu(), large, GrGpuResource::kBorrowed_LifeCycle);
wrapped = TestResource::CreateWrapped(context->getGpu(), large);
REPORTER_ASSERT(reporter, 3 == cache->getResourceCount());
REPORTER_ASSERT(reporter, 21 + large == cache->getResourceBytes());
REPORTER_ASSERT(reporter, 2 == cache->getBudgetedResourceCount());
@ -563,7 +567,8 @@ void test_unbudgeted_to_scratch(skiatest::Reporter* reporter);
GrResourceCache* cache = mock.cache();
TestResource* resource =
TestResource::CreateScratch(context->getGpu(), TestResource::kA_SimulatedProperty, false);
TestResource::CreateScratch(context->getGpu(), SkBudgeted::kNo,
TestResource::kA_SimulatedProperty);
GrScratchKey key;
TestResource::ComputeScratchKey(TestResource::kA_SimulatedProperty, &key);
@ -623,8 +628,10 @@ static void test_duplicate_scratch_key(skiatest::Reporter* reporter) {
// Create two resources that have the same scratch key.
TestResource* a = TestResource::CreateScratch(context->getGpu(),
SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
TestResource* b = TestResource::CreateScratch(context->getGpu(),
SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
a->setSize(11);
b->setSize(12);
@ -667,9 +674,9 @@ static void test_remove_scratch_key(skiatest::Reporter* reporter) {
GrResourceCache* cache = mock.cache();
// Create two resources that have the same scratch key.
TestResource* a = TestResource::CreateScratch(context->getGpu(),
TestResource* a = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
TestResource* b = TestResource::CreateScratch(context->getGpu(),
TestResource* b = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
a->unref();
b->unref();
@ -726,9 +733,9 @@ static void test_scratch_key_consistency(skiatest::Reporter* reporter) {
GrResourceCache* cache = mock.cache();
// Create two resources that have the same scratch key.
TestResource* a = TestResource::CreateScratch(context->getGpu(),
TestResource* a = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
TestResource* b = TestResource::CreateScratch(context->getGpu(),
TestResource* b = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes,
TestResource::kB_SimulatedProperty);
a->unref();
b->unref();
@ -888,7 +895,7 @@ static void test_purge_invalidated(skiatest::Reporter* reporter) {
// Add three resources to the cache. Only c is usable as scratch.
TestResource* a = new TestResource(context->getGpu());
TestResource* b = new TestResource(context->getGpu());
TestResource* c = TestResource::CreateScratch(context->getGpu(),
TestResource* c = TestResource::CreateScratch(context->getGpu(), SkBudgeted::kYes,
TestResource::kA_SimulatedProperty);
a->resourcePriv().setUniqueKey(key1);
b->resourcePriv().setUniqueKey(key2);

View File

@ -222,10 +222,9 @@ void GrResourceCache::dumpStats(SkString* out) const {
out->appendf("Budget: %d items %d bytes\n", fMaxCount, (int)fMaxBytes);
out->appendf("\t\tEntry Count: current %d"
" (%d budgeted, %d external(%d borrowed, %d adopted), %d locked, %d scratch %.2g%% full), high %d\n",
stats.fTotal, fBudgetedCount, stats.fExternal, stats.fBorrowed,
stats.fAdopted, stats.fNumNonPurgeable, stats.fScratch, countUtilization,
fHighWaterCount);
" (%d budgeted, %d wrapped, %d locked, %d scratch %.2g%% full), high %d\n",
stats.fTotal, fBudgetedCount, stats.fWrapped, stats.fNumNonPurgeable,
stats.fScratch, countUtilization, fHighWaterCount);
out->appendf("\t\tEntry Bytes: current %d (budgeted %d, %.2g%% full, %d unbudgeted) high %d\n",
SkToInt(fBytes), SkToInt(fBudgetedBytes), byteUtilization,
SkToInt(stats.fUnbudgetedSize), SkToInt(fHighWaterBytes));
@ -323,12 +322,12 @@ private:
void xferBarrier(GrRenderTarget*, GrXferBarrierType) override {}
GrTexture* onCreateTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle lifeCycle,
GrTexture* onCreateTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) override {
return nullptr;
}
GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, GrGpuResource::LifeCycle,
GrTexture* onCreateCompressedTexture(const GrSurfaceDesc& desc, SkBudgeted budgeted,
const SkTArray<GrMipLevel>& texels) override {
return nullptr;
}