Add utility functions for reference counting.

Bug 26851951

Change-Id: I5494d61927eb4c1faff320aa7cd6cebe81800f29
Reviewed-on: https://swiftshader-review.googlesource.com/4712
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/OpenGL/common/Image.cpp b/src/OpenGL/common/Image.cpp
index e4a1c87..73a8656 100644
--- a/src/OpenGL/common/Image.cpp
+++ b/src/OpenGL/common/Image.cpp
@@ -1165,6 +1165,11 @@
 		release();
 	}
 
+	bool Image::isChildOf(const egl::Texture *parent) const
+	{
+		return parentTexture == parent;
+	}
+
 	void Image::loadImageData(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const UnpackInfo& unpackInfo, const void *input)
 	{
 		GLsizei inputPitch = ComputePitch((unpackInfo.rowLength == 0) ? width : unpackInfo.rowLength, format, type, unpackInfo.alignment);
diff --git a/src/OpenGL/common/Image.hpp b/src/OpenGL/common/Image.hpp
index 609a8c4..a019133 100644
--- a/src/OpenGL/common/Image.hpp
+++ b/src/OpenGL/common/Image.hpp
@@ -148,7 +148,8 @@
 

 	void addRef() override;

 	void release() override;

-	virtual void unbind(const Texture *parent);   // Break parent ownership and release

+	void unbind(const Texture *parent);   // Break parent ownership and release

+	bool isChildOf(const Texture *parent) const;

 

 	virtual void destroyShared()   // Release a shared image

 	{

diff --git a/src/OpenGL/common/Object.cpp b/src/OpenGL/common/Object.cpp
index c846d62..3808dff 100644
--- a/src/OpenGL/common/Object.cpp
+++ b/src/OpenGL/common/Object.cpp
@@ -49,17 +49,28 @@
 
 void Object::release()
 {
+	if(dereference() == 0)
+	{
+		delete this;
+	}
+}
+
+int Object::dereference()
+{
     ASSERT(referenceCount > 0);
 
     if(referenceCount > 0)
 	{
-		sw::atomicDecrement(&referenceCount);
+		return sw::atomicDecrement(&referenceCount);
 	}
 
-	if(referenceCount == 0)
-	{
-		delete this;
-	}
+	return 0;
+}
+
+void Object::destroy()
+{
+	referenceCount = 0;
+	delete this;
 }
 
 NamedObject::NamedObject(GLuint name) : name(name)
diff --git a/src/OpenGL/common/Object.hpp b/src/OpenGL/common/Object.hpp
index baa188d..b54d589 100644
--- a/src/OpenGL/common/Object.hpp
+++ b/src/OpenGL/common/Object.hpp
@@ -29,12 +29,21 @@
 {
 public:
     Object();
-    virtual ~Object();
 
     virtual void addRef();
 	virtual void release();
 
-private:
+	inline bool hasSingleReference() const
+	{
+		return referenceCount == 1;
+	}
+
+protected:
+    virtual ~Object();
+
+	int dereference();
+	void destroy();
+
     volatile int referenceCount;
 
 #ifndef NDEBUG
diff --git a/src/OpenGL/libEGL/Texture.hpp b/src/OpenGL/libEGL/Texture.hpp
index 6d6e22b..89f40bf 100644
--- a/src/OpenGL/libEGL/Texture.hpp
+++ b/src/OpenGL/libEGL/Texture.hpp
@@ -13,7 +13,8 @@
 class Texture : public gl::NamedObject

 {

 public:

-	Texture(GLuint name) : NamedObject(name) {};

+	Texture(GLuint name) : NamedObject(name) {}

+

 	virtual void releaseTexImage() = 0;

 	virtual sw::Resource *getResource() const = 0;

 };

diff --git a/src/OpenGL/libGLES_CM/Texture.h b/src/OpenGL/libGLES_CM/Texture.h
index 575126f..75b483b 100644
--- a/src/OpenGL/libGLES_CM/Texture.h
+++ b/src/OpenGL/libGLES_CM/Texture.h
@@ -49,8 +49,6 @@
 public:

     explicit Texture(GLuint name);

 

-    virtual ~Texture();

-

 	sw::Resource *getResource() const;

 

 	virtual void addProxyRef(const Renderbuffer *proxy) = 0;

@@ -99,6 +97,8 @@
     virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

 

 protected:

+	virtual ~Texture();

+

     void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

     void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, egl::Image *image);

     void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);

@@ -127,10 +127,8 @@
 public:

     explicit Texture2D(GLuint name);

 

-    virtual ~Texture2D();

-

-	void addProxyRef(const Renderbuffer *proxy);

-    void releaseProxy(const Renderbuffer *proxy);

+	void addProxyRef(const Renderbuffer *proxy) override;

+    void releaseProxy(const Renderbuffer *proxy) override;

 

     virtual GLenum getTarget() const;

 

@@ -166,6 +164,8 @@
     egl::Image *getImage(unsigned int level);

 

 protected:

+	virtual ~Texture2D();

+

 	bool isMipmapComplete() const;

 

 	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

@@ -186,9 +186,10 @@
 public:

     explicit TextureExternal(GLuint name);

 

-    virtual ~TextureExternal();

-

     virtual GLenum getTarget() const;

+

+protected:

+	virtual ~TextureExternal();

 };

 }

 

diff --git a/src/OpenGL/libGLESv2/Texture.h b/src/OpenGL/libGLESv2/Texture.h
index 7f0519a..30dc822 100644
--- a/src/OpenGL/libGLESv2/Texture.h
+++ b/src/OpenGL/libGLESv2/Texture.h
@@ -54,8 +54,6 @@
 public:

     explicit Texture(GLuint name);

 

-    virtual ~Texture();

-

 	virtual sw::Resource *getResource() const;

 

 	virtual void addProxyRef(const Renderbuffer *proxy) = 0;

@@ -120,6 +118,8 @@
 	virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0;

 

 protected:

+	virtual ~Texture();

+

     void setImage(GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);

     void subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const egl::Image::UnpackInfo& unpackInfo, const void *pixels, egl::Image *image);

     void setCompressedImage(GLsizei imageSize, const void *pixels, egl::Image *image);

@@ -155,10 +155,8 @@
 public:

     explicit Texture2D(GLuint name);

 

-    virtual ~Texture2D();

-

-	void addProxyRef(const Renderbuffer *proxy);

-    void releaseProxy(const Renderbuffer *proxy);

+	void addProxyRef(const Renderbuffer *proxy) override;

+    void releaseProxy(const Renderbuffer *proxy) override;

 

     virtual GLenum getTarget() const;

 

@@ -193,12 +191,14 @@
     egl::Image *getImage(unsigned int level);

 

 protected:

+	virtual ~Texture2D();

+

 	bool isMipmapComplete() const;

 

 	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-    

+

     egl::Surface *mSurface;

-    

+

 	// 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

@@ -213,13 +213,11 @@
 public:

     explicit TextureCubeMap(GLuint name);

 

-    virtual ~TextureCubeMap();

-

-	void addProxyRef(const Renderbuffer *proxy);

-    void releaseProxy(const Renderbuffer *proxy);

+	void addProxyRef(const Renderbuffer *proxy) override;

+    void releaseProxy(const Renderbuffer *proxy) override;

 

     virtual GLenum getTarget() const;

-    

+

     virtual GLsizei getWidth(GLenum target, GLint level) const;

     virtual GLsizei getHeight(GLenum target, GLint level) const;

     virtual GLenum getFormat(GLenum target, GLint level) const;

@@ -248,6 +246,9 @@
 

 	egl::Image *getImage(int face, unsigned int level);

 

+protected:

+	virtual ~TextureCubeMap();

+

 private:

 	bool isCubeComplete() const;

 	bool isMipmapCubeComplete() const;

@@ -256,7 +257,7 @@
 	egl::Image *getImage(GLenum face, unsigned int level);

 

 	egl::Image *image[6][IMPLEMENTATION_MAX_TEXTURE_LEVELS];

-	

+

 	// 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

@@ -271,10 +272,8 @@
 public:

 	explicit Texture3D(GLuint name);

 

-	virtual ~Texture3D();

-

-	void addProxyRef(const Renderbuffer *proxy);

-	void releaseProxy(const Renderbuffer *proxy);

+	void addProxyRef(const Renderbuffer *proxy) override;

+    void releaseProxy(const Renderbuffer *proxy) override;

 

 	virtual GLenum getTarget() const;

 

@@ -310,6 +309,8 @@
 	egl::Image *getImage(unsigned int level);

 

 protected:

+	virtual ~Texture3D();

+

 	bool isMipmapComplete() const;

 

 	egl::Image *image[IMPLEMENTATION_MAX_TEXTURE_LEVELS];

@@ -330,10 +331,11 @@
 public:

 	explicit Texture2DArray(GLuint name);

 

-	virtual ~Texture2DArray();

-

 	virtual GLenum getTarget() const;

 	virtual void generateMipmaps();

+

+protected:

+	virtual ~Texture2DArray();

 };

 

 class TextureExternal : public Texture2D

@@ -341,9 +343,10 @@
 public:

     explicit TextureExternal(GLuint name);

 

-    virtual ~TextureExternal();

-

     virtual GLenum getTarget() const;

+

+protected:

+	virtual ~TextureExternal();

 };

 }