Changes the pointer from textures to their renderbuffer proxies to non-refcounted (2/2)

TRAC #19335 Issue=271 Instead, the texture maintains an internal refcount which causes the pointer to behave kind of like a "weak" shared pointer-- its reference won't prevent the renderbuffer from being deleted, but if the renderbuffer's refcount drops to zero, the texture should set its pointer to the renderbuffer to null so that a new one can be created at the next getRenderbuffer call. Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/trunk@948 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 0dc8a5ee
#define MAJOR_VERSION 1
#define MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 946
#define BUILD_REVISION 948
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -915,9 +915,9 @@ void Display::sync(bool block)
freeEventQuery(query);
if (isDeviceLostError(result))
{
notifyDeviceLost();
if (isDeviceLostError(result))
{
notifyDeviceLost();
}
}
......
......@@ -22,6 +22,17 @@ RenderbufferInterface::RenderbufferInterface()
{
}
// The default case for classes inherited from RenderbufferInterface is not to
// need to do anything upon the reference count to the parent Renderbuffer incrementing
// or decrementing.
void RenderbufferInterface::addProxyRef(const Renderbuffer *proxy)
{
}
void RenderbufferInterface::releaseProxy(const Renderbuffer *proxy)
{
}
GLuint RenderbufferInterface::getRedSize() const
{
return dx2es::GetRedSize(getD3DFormat());
......@@ -62,6 +73,18 @@ RenderbufferTexture::~RenderbufferTexture()
mTexture.set(NULL);
}
// Textures need to maintain their own reference count for references via
// Renderbuffers acting as proxies. Here, we notify the texture of a reference.
void RenderbufferTexture::addProxyRef(const Renderbuffer *proxy)
{
mTexture->addProxyRef(proxy);
}
void RenderbufferTexture::releaseProxy(const Renderbuffer *proxy)
{
mTexture->releaseProxy(proxy);
}
IDirect3DSurface9 *RenderbufferTexture::getRenderTarget()
{
return mTexture->getRenderTarget(mTarget);
......@@ -113,6 +136,22 @@ Renderbuffer::~Renderbuffer()
delete mInstance;
}
// The RenderbufferInterface contained in this Renderbuffer may need to maintain
// its own reference count, so we pass it on here.
void Renderbuffer::addRef() const
{
mInstance->addProxyRef(this);
RefCountObject::addRef();
}
void Renderbuffer::release() const
{
mInstance->releaseProxy(this);
RefCountObject::release();
}
IDirect3DSurface9 *Renderbuffer::getRenderTarget()
{
return mInstance->getRenderTarget();
......
......@@ -22,6 +22,7 @@
namespace gl
{
class Texture;
class Renderbuffer;
class Colorbuffer;
class DepthStencilbuffer;
......@@ -32,6 +33,9 @@ class RenderbufferInterface
virtual ~RenderbufferInterface() {};
virtual void addProxyRef(const Renderbuffer *proxy);
virtual void releaseProxy(const Renderbuffer *proxy);
virtual IDirect3DSurface9 *getRenderTarget() = 0;
virtual IDirect3DSurface9 *getDepthStencil() = 0;
......@@ -61,6 +65,9 @@ class RenderbufferTexture : public RenderbufferInterface
virtual ~RenderbufferTexture();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
IDirect3DSurface9 *getRenderTarget();
IDirect3DSurface9 *getDepthStencil();
......@@ -128,6 +135,13 @@ class Renderbuffer : public RefCountObject
virtual ~Renderbuffer();
// These functions from RefCountObject are overloaded here because
// Textures need to maintain their own count of references to them via
// Renderbuffers/RenderbufferTextures. These functions invoke those
// reference counting functions on the RenderbufferInterface.
void addRef() const;
void release() const;
IDirect3DSurface9 *getRenderTarget();
IDirect3DSurface9 *getDepthStencil();
......
......@@ -1722,11 +1722,13 @@ Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexStorage = NULL;
mSurface = NULL;
mColorbufferProxy = NULL;
mProxyRefs = 0;
}
Texture2D::~Texture2D()
{
mColorbufferProxy.set(NULL);
mColorbufferProxy = NULL;
delete mTexStorage;
mTexStorage = NULL;
......@@ -1738,6 +1740,23 @@ Texture2D::~Texture2D()
}
}
// We need to maintain a count of references to renderbuffers acting as
// proxies for this texture, so that we do not attempt to use a pointer
// to a renderbuffer proxy which has been deleted.
void Texture2D::addProxyRef(const Renderbuffer *proxy)
{
mProxyRefs++;
}
void Texture2D::releaseProxy(const Renderbuffer *proxy)
{
if (mProxyRefs > 0)
mProxyRefs--;
if (mProxyRefs == 0)
mColorbufferProxy = NULL;
}
GLenum Texture2D::getTarget() const
{
return GL_TEXTURE_2D;
......@@ -2294,12 +2313,12 @@ Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
return error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
}
if (mColorbufferProxy.get() == NULL)
if (mColorbufferProxy == NULL)
{
mColorbufferProxy.set(new Renderbuffer(id(), new RenderbufferTexture(this, target)));
mColorbufferProxy = new Renderbuffer(id(), new RenderbufferTexture(this, target));
}
return mColorbufferProxy.get();
return mColorbufferProxy;
}
IDirect3DSurface9 *Texture2D::getRenderTarget(GLenum target)
......@@ -2383,19 +2402,53 @@ unsigned int TextureStorageCubeMap::getRenderTargetSerial(GLenum target) const
TextureCubeMap::TextureCubeMap(GLuint id) : Texture(id)
{
mTexStorage = NULL;
for (int i = 0; i < 6; i++)
{
mFaceProxies[i] = NULL;
mFaceProxyRefs[i] = 0;
}
}
TextureCubeMap::~TextureCubeMap()
{
for (int i = 0; i < 6; i++)
{
mFaceProxies[i].set(NULL);
mFaceProxies[i] = NULL;
}
delete mTexStorage;
mTexStorage = NULL;
}
// We need to maintain a count of references to renderbuffers acting as
// proxies for this texture, so that the texture is not deleted while
// proxy references still exist. If the reference count drops to zero,
// we set our proxy pointer NULL, so that a new attempt at referencing
// will cause recreation.
void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)
{
for (int i = 0; i < 6; i++)
{
if (mFaceProxies[i] == proxy)
mFaceProxyRefs[i]++;
}
}
void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)
{
for (int i = 0; i < 6; i++)
{
if (mFaceProxies[i] == proxy)
{
if (mFaceProxyRefs[i] > 0)
mFaceProxyRefs[i]--;
if (mFaceProxyRefs[i] == 0)
mFaceProxies[i] = NULL;
}
}
}
GLenum TextureCubeMap::getTarget() const
{
return GL_TEXTURE_CUBE_MAP;
......@@ -2995,12 +3048,12 @@ Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
unsigned int face = faceIndex(target);
if (mFaceProxies[face].get() == NULL)
if (mFaceProxies[face] == NULL)
{
mFaceProxies[face].set(new Renderbuffer(id(), new RenderbufferTexture(this, target)));
mFaceProxies[face] = new Renderbuffer(id(), new RenderbufferTexture(this, target));
}
return mFaceProxies[face].get();
return mFaceProxies[face];
}
IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
......
......@@ -173,6 +173,9 @@ class Texture : public RefCountObject
virtual ~Texture();
virtual void addProxyRef(const Renderbuffer *proxy) = 0;
virtual void releaseProxy(const Renderbuffer *proxy) = 0;
virtual GLenum getTarget() const = 0;
bool setMinFilter(GLenum filter);
......@@ -278,6 +281,9 @@ class Texture2D : public Texture
~Texture2D();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
virtual GLenum getTarget() const;
virtual GLsizei getWidth(GLint level) const;
......@@ -323,7 +329,13 @@ class Texture2D : public Texture
TextureStorage2D *mTexStorage;
egl::Surface *mSurface;
BindingPointer<Renderbuffer> mColorbufferProxy;
// A specific internal reference count is kept for colorbuffer proxy references,
// because, as the renderbuffer acting as proxy will maintain a binding pointer
// back to this texture, there would be a circular reference if we used a binding
// pointer here. This reference count will cause the pointer to be set to NULL if
// the count drops to zero, but will not cause deletion of the Renderbuffer.
Renderbuffer *mColorbufferProxy;
unsigned int mProxyRefs;
};
class TextureStorageCubeMap : public TextureStorage
......@@ -352,6 +364,9 @@ class TextureCubeMap : public Texture
~TextureCubeMap();
void addProxyRef(const Renderbuffer *proxy);
void releaseProxy(const Renderbuffer *proxy);
virtual GLenum getTarget() const;
virtual GLsizei getWidth(GLint level) const;
......@@ -405,7 +420,13 @@ class TextureCubeMap : public Texture
TextureStorageCubeMap *mTexStorage;
BindingPointer<Renderbuffer> mFaceProxies[6];
// A specific internal reference count is kept for colorbuffer proxy references,
// because, as the renderbuffer acting as proxy will maintain a binding pointer
// back to this texture, there would be a circular reference if we used a binding
// pointer here. This reference count will cause the pointer to be set to NULL if
// the count drops to zero, but will not cause deletion of the Renderbuffer.
Renderbuffer *mFaceProxies[6];
unsigned int *mFaceProxyRefs[6];
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment