Delete GL tex ID when last of GrGLTexture or GrGLRenderTarget that reference it is destroyed
git-svn-id: http://skia.googlecode.com/svn/trunk@915 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
a7f84e150c
commit
1da0746fa1
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -25,6 +25,26 @@
|
||||
class GrGpuGL;
|
||||
class GrGLTexture;
|
||||
|
||||
/**
|
||||
* A ref counted tex id that deletes the texture in its destructor.
|
||||
*/
|
||||
class GrGLTexID : public GrRefCnt {
|
||||
public:
|
||||
GrGLTexID(GLuint texID) : fTexID(texID) {}
|
||||
|
||||
virtual ~GrGLTexID() {
|
||||
if (0 != fTexID) {
|
||||
GR_GL(DeleteTextures(1, &fTexID));
|
||||
}
|
||||
}
|
||||
|
||||
void abandon() { fTexID = 0; }
|
||||
GLuint id() const { return fTexID; }
|
||||
|
||||
private:
|
||||
GLuint fTexID;
|
||||
};
|
||||
|
||||
class GrGLRenderTarget : public GrRenderTarget {
|
||||
public:
|
||||
virtual ~GrGLRenderTarget();
|
||||
@ -49,6 +69,7 @@ protected:
|
||||
};
|
||||
|
||||
GrGLRenderTarget(const GLRenderTargetIDs& ids,
|
||||
GrGLTexID* texID,
|
||||
GLuint stencilBits,
|
||||
const GrGLIRect& fViewport,
|
||||
GrGLTexture* texture,
|
||||
@ -76,6 +97,9 @@ private:
|
||||
// we want the rendering to be at top left (GL has origin in bottom left)
|
||||
GrGLIRect fViewport;
|
||||
|
||||
// non-NULL if this RT was created by Gr with an associated GrGLTexture.
|
||||
GrGLTexID* fTexIDObj;
|
||||
|
||||
friend class GrGpuGL;
|
||||
friend class GrGLTexture;
|
||||
|
||||
@ -120,9 +144,8 @@ public:
|
||||
|
||||
// overloads of GrTexture
|
||||
virtual void abandon();
|
||||
virtual bool isRenderTarget() const;
|
||||
virtual GrRenderTarget* asRenderTarget();
|
||||
virtual void removeRenderTarget();
|
||||
virtual void releaseRenderTarget();
|
||||
virtual void uploadTextureData(uint32_t x,
|
||||
uint32_t y,
|
||||
uint32_t width,
|
||||
@ -132,7 +155,7 @@ public:
|
||||
|
||||
const TexParams& getTexParams() const { return fTexParams; }
|
||||
void setTexParams(const TexParams& texParams) { fTexParams = texParams; }
|
||||
GLuint textureID() const { return fTextureID; }
|
||||
GLuint textureID() const { return fTexIDObj->id(); }
|
||||
|
||||
GLenum uploadFormat() const { return fUploadFormat; }
|
||||
GLenum uploadByteCount() const { return fUploadByteCount; }
|
||||
@ -174,7 +197,7 @@ public:
|
||||
|
||||
private:
|
||||
TexParams fTexParams;
|
||||
GLuint fTextureID;
|
||||
GrGLTexID* fTexIDObj;
|
||||
GLenum fUploadFormat;
|
||||
GLenum fUploadByteCount;
|
||||
GLenum fUploadType;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -156,6 +156,11 @@ public:
|
||||
* will be embedded in a power of two texture. The extra width and height
|
||||
* is filled as though srcData were rendered clamped into the texture.
|
||||
*
|
||||
* If kRenderTarget_TextureFlag is specified the GrRenderTarget is
|
||||
* accessible via GrTexture::asRenderTarget(). The texture will hold a ref
|
||||
* on the render target until its releaseRenderTarget() is called or it is
|
||||
* destroyed.
|
||||
*
|
||||
* @param desc describes the texture to be created.
|
||||
* @param srcData texel data to load texture. Begins with full-size
|
||||
* palette data for paletted textures. Contains width*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -134,11 +134,6 @@ private:
|
||||
void pushClip();
|
||||
|
||||
GrTAllocator<Draw> fDraws;
|
||||
// HACK: We currently do not hold refs on RTs in the saved draw states.
|
||||
// The reason is that in the GL implementation when a GrTexture is destroyed
|
||||
// that has an associated RT the RT is destroyed regardless of its ref count.
|
||||
// We need a third object that holds the shared GL ids and persists until
|
||||
// both reach ref count 0. (skia issue 122)
|
||||
GrTAllocator<SavedDrawState> fStates;
|
||||
|
||||
GrTAllocator<GrClip> fClips;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -160,32 +160,21 @@ public:
|
||||
*/
|
||||
virtual void abandon() = 0;
|
||||
|
||||
/**
|
||||
* Queries whether the texture was created as a render target.
|
||||
*
|
||||
* Use asRenderTarget() to use the texture as a render target if this
|
||||
* returns true.
|
||||
*
|
||||
* @return true if the texture was created as a render target.
|
||||
*/
|
||||
virtual bool isRenderTarget() const = 0;
|
||||
|
||||
/**
|
||||
* Retrieves the render target underlying this texture that can be passed to
|
||||
* GrGpu::setRenderTarget().
|
||||
*
|
||||
* If isRenderTarget() is false then the returned handle is undefined.
|
||||
*
|
||||
* @return handle to render target or undefined if the texture is not a
|
||||
* render target
|
||||
*/
|
||||
virtual GrRenderTarget* asRenderTarget() = 0;
|
||||
|
||||
/**
|
||||
* Removes the "rendertargetness" from a texture. This may or may not
|
||||
* actually do anything with the underlying 3D API.
|
||||
* Removes the reference on the associated GrRenderTarget held by this
|
||||
* texture. Afterwards asRenderTarget() will return NULL. The
|
||||
* GrRenderTarget survives the release if another ref is held on it.
|
||||
*/
|
||||
virtual void removeRenderTarget() = 0;
|
||||
virtual void releaseRenderTarget() = 0;
|
||||
|
||||
/**
|
||||
* Return the native ID or handle to the texture, depending on the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -172,7 +172,7 @@ GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key,
|
||||
0, 4);
|
||||
entry = fTextureCache->createAndLock(*key, texture);
|
||||
}
|
||||
texture->removeRenderTarget();
|
||||
texture->releaseRenderTarget();
|
||||
} else {
|
||||
// TODO: Our CPU stretch doesn't filter. But we create separate
|
||||
// stretched textures when the sampler state is either filtered or
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -19,6 +19,7 @@
|
||||
#include "GrGpuGL.h"
|
||||
|
||||
GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
|
||||
GrGLTexID* texID,
|
||||
GLuint stencilBits,
|
||||
const GrGLIRect& viewport,
|
||||
GrGLTexture* texture,
|
||||
@ -34,6 +35,8 @@ GrGLRenderTarget::GrGLRenderTarget(const GLRenderTargetIDs& ids,
|
||||
fNeedsResolve = false;
|
||||
fViewport = viewport;
|
||||
fOwnIDs = ids.fOwnIDs;
|
||||
fTexIDObj = texID;
|
||||
GrSafeRef(fTexIDObj);
|
||||
}
|
||||
|
||||
GrGLRenderTarget::~GrGLRenderTarget() {
|
||||
@ -52,6 +55,7 @@ GrGLRenderTarget::~GrGLRenderTarget() {
|
||||
GR_GLEXT(fGL->extensions(), DeleteRenderbuffers(1, &fMSColorRenderbufferID));
|
||||
}
|
||||
}
|
||||
GrSafeUnref(fTexIDObj);
|
||||
}
|
||||
|
||||
void GrGLRenderTarget::abandon() {
|
||||
@ -59,6 +63,9 @@ void GrGLRenderTarget::abandon() {
|
||||
fTexFBOID = 0;
|
||||
fStencilRenderbufferID = 0;
|
||||
fMSColorRenderbufferID = 0;
|
||||
if (NULL != fTexIDObj) {
|
||||
fTexIDObj->abandon();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -84,7 +91,7 @@ GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
|
||||
textureDesc.fFormat) {
|
||||
|
||||
fTexParams = initialTexParams;
|
||||
fTextureID = textureDesc.fTextureID;
|
||||
fTexIDObj = new GrGLTexID(textureDesc.fTextureID);
|
||||
fUploadFormat = textureDesc.fUploadFormat;
|
||||
fUploadByteCount = textureDesc.fUploadByteCount;
|
||||
fUploadType = textureDesc.fUploadType;
|
||||
@ -108,43 +115,32 @@ GrGLTexture::GrGLTexture(const GLTextureDesc& textureDesc,
|
||||
vp.fHeight = textureDesc.fContentHeight;
|
||||
vp.fBottom = textureDesc.fAllocHeight - textureDesc.fContentHeight;
|
||||
|
||||
fRenderTarget = new GrGLRenderTarget(rtIDs, textureDesc.fStencilBits,
|
||||
fRenderTarget = new GrGLRenderTarget(rtIDs, fTexIDObj,
|
||||
textureDesc.fStencilBits,
|
||||
vp, this, gl);
|
||||
}
|
||||
}
|
||||
|
||||
GrGLTexture::~GrGLTexture() {
|
||||
// make sure we haven't been abandoned
|
||||
if (fTextureID) {
|
||||
fGpuGL->notifyTextureDelete(this);
|
||||
GR_GL(DeleteTextures(1, &fTextureID));
|
||||
}
|
||||
delete fRenderTarget;
|
||||
fGpuGL->notifyTextureDelete(this);
|
||||
fTexIDObj->unref();
|
||||
GrSafeUnref(fRenderTarget);
|
||||
}
|
||||
|
||||
void GrGLTexture::abandon() {
|
||||
fTextureID = 0;
|
||||
fTexIDObj->abandon();
|
||||
if (NULL != fRenderTarget) {
|
||||
fRenderTarget->abandon();
|
||||
}
|
||||
}
|
||||
|
||||
bool GrGLTexture::isRenderTarget() const {
|
||||
return NULL != fRenderTarget;
|
||||
}
|
||||
|
||||
GrRenderTarget* GrGLTexture::asRenderTarget() {
|
||||
return (GrRenderTarget*)fRenderTarget;
|
||||
}
|
||||
|
||||
void GrGLTexture::removeRenderTarget() {
|
||||
GrAssert(NULL != fRenderTarget);
|
||||
if (NULL != fRenderTarget) {
|
||||
// must do this notify before the delete
|
||||
fGpuGL->notifyTextureRemoveRenderTarget(this);
|
||||
delete fRenderTarget;
|
||||
fRenderTarget = NULL;
|
||||
}
|
||||
void GrGLTexture::releaseRenderTarget() {
|
||||
GrSafeUnref(fRenderTarget);
|
||||
fRenderTarget = NULL;
|
||||
}
|
||||
|
||||
void GrGLTexture::uploadTextureData(uint32_t x,
|
||||
@ -162,7 +158,7 @@ void GrGLTexture::uploadTextureData(uint32_t x,
|
||||
// If we need to update textures that are created upside down
|
||||
// then we have to modify this code to flip the srcData
|
||||
GrAssert(kTopDown_Orientation == fOrientation);
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, fTextureID));
|
||||
GR_GL(BindTexture(GL_TEXTURE_2D, fTexIDObj->id()));
|
||||
GR_GL(PixelStorei(GL_UNPACK_ALIGNMENT, fUploadByteCount));
|
||||
GR_GL(TexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height,
|
||||
fUploadFormat, fUploadType, srcData));
|
||||
@ -170,7 +166,7 @@ void GrGLTexture::uploadTextureData(uint32_t x,
|
||||
}
|
||||
|
||||
intptr_t GrGLTexture::getTextureHandle() {
|
||||
return fTextureID;
|
||||
return fTexIDObj->id();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -510,7 +510,7 @@ GrRenderTarget* GrGpuGL::createPlatformRenderTargetHelper(
|
||||
rtIDs.fRTFBOID = (GLuint)platformRenderTarget;
|
||||
rtIDs.fTexFBOID = (GLuint)platformRenderTarget;
|
||||
|
||||
return new GrGLRenderTarget(rtIDs, stencilBits, viewport, NULL, this);
|
||||
return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
|
||||
}
|
||||
|
||||
GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
|
||||
@ -529,7 +529,7 @@ GrRenderTarget* GrGpuGL::createRenderTargetFrom3DApiStateHelper() {
|
||||
|
||||
rtIDs.fOwnIDs = false;
|
||||
|
||||
return new GrGLRenderTarget(rtIDs, stencilBits, viewport, NULL, this);
|
||||
return new GrGLRenderTarget(rtIDs, NULL, stencilBits, viewport, NULL, this);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -1694,11 +1694,6 @@ void GrGpuGL::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
|
||||
|
||||
void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
|
||||
GrAssert(NULL != renderTarget);
|
||||
|
||||
// if the bound FBO is destroyed we can't rely on the implicit bind to 0
|
||||
// a) we want the default RT which may not be FBO 0
|
||||
// b) we set more state than just FBO based on the RT
|
||||
// So trash the HW state to force an RT flush next time
|
||||
if (fCurrDrawState.fRenderTarget == renderTarget) {
|
||||
fCurrDrawState.fRenderTarget = NULL;
|
||||
}
|
||||
@ -1719,13 +1714,6 @@ void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
|
||||
}
|
||||
}
|
||||
|
||||
void GrGpuGL::notifyTextureRemoveRenderTarget(GrGLTexture* texture) {
|
||||
GrAssert(NULL != texture->asRenderTarget());
|
||||
|
||||
// if there is a pending resolve, perform it.
|
||||
resolveTextureRenderTarget(texture);
|
||||
}
|
||||
|
||||
bool GrGpuGL::canBeTexture(GrTexture::PixelConfig config,
|
||||
GLenum* internalFormat,
|
||||
GLenum* format,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -151,7 +151,6 @@ private:
|
||||
void notifyIndexBufferDelete(const GrGLIndexBuffer* buffer);
|
||||
void notifyTextureDelete(GrGLTexture* texture);
|
||||
void notifyRenderTargetDelete(GrRenderTarget* renderTarget);
|
||||
void notifyTextureRemoveRenderTarget(GrGLTexture* texture);
|
||||
|
||||
void setSpareTextureUnit();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -291,12 +291,11 @@ void GrInOrderDrawBuffer::reset() {
|
||||
GrAssert(!fReservedGeometry.fLocked);
|
||||
uint32_t numStates = fStates.count();
|
||||
for (uint32_t i = 0; i < numStates; ++i) {
|
||||
const DrState& dstate = this->accessSavedDrawState(fStates[i]);
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrTexture* tex = this->accessSavedDrawState(fStates[i]).fTextures[s];
|
||||
if (NULL != tex) {
|
||||
tex->unref();
|
||||
}
|
||||
GrSafeUnref(dstate.fTextures[s]);
|
||||
}
|
||||
GrSafeUnref(dstate.fRenderTarget);
|
||||
}
|
||||
int numDraws = fDraws.count();
|
||||
for (int d = 0; d < numDraws; ++d) {
|
||||
@ -499,6 +498,7 @@ void GrInOrderDrawBuffer::pushState() {
|
||||
for (int s = 0; s < kNumStages; ++s) {
|
||||
GrSafeRef(fCurrDrawState.fTextures[s]);
|
||||
}
|
||||
GrSafeRef(fCurrDrawState.fRenderTarget);
|
||||
this->saveCurrentDrawState(&fStates.push_back());
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2010 Google Inc.
|
||||
Copyright 2011 Google Inc.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@ -142,7 +142,7 @@ SkGpuDevice::SkGpuDevice(GrContext* context,
|
||||
&fTexture, true);
|
||||
if (fCache) {
|
||||
SkASSERT(NULL != fTexture);
|
||||
SkASSERT(fTexture->isRenderTarget());
|
||||
SkASSERT(NULL != fTexture->asRenderTarget());
|
||||
}
|
||||
#else
|
||||
const GrGpu::TextureDesc desc = {
|
||||
|
Loading…
Reference in New Issue
Block a user