Encapsulate GPUObject in a safer way

This commit is contained in:
Atlante45 2016-01-13 12:15:57 -08:00
parent e41c49b19f
commit 8da027c56f
10 changed files with 34 additions and 124 deletions

View file

@ -97,68 +97,16 @@ public:
TransformCamera getEyeCamera(int eye, const StereoState& stereo) const; TransformCamera getEyeCamera(int eye, const StereoState& stereo) const;
}; };
template< typename T >
static void setGPUObject(const Buffer& buffer, T* object) { template<typename T>
buffer.setGPUObject(object); static void setGPUObject(const GPUObjectWrapper& wrapper, T* object) {
wrapper.setGPUObject(object);
} }
template< typename T > template<typename T>
static T* getGPUObject(const Buffer& buffer) { static T* getGPUObject(const GPUObjectWrapper& wrapper) {
return reinterpret_cast<T*>(buffer.getGPUObject()); return reinterpret_cast<T*>(wrapper.getGPUObject());
} }
template< typename T >
static void setGPUObject(const Texture& texture, T* object) {
texture.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Texture& texture) {
return reinterpret_cast<T*>(texture.getGPUObject());
}
template< typename T >
static void setGPUObject(const Shader& shader, T* object) {
shader.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Shader& shader) {
return reinterpret_cast<T*>(shader.getGPUObject());
}
template< typename T >
static void setGPUObject(const Pipeline& pipeline, T* object) {
pipeline.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Pipeline& pipeline) {
return reinterpret_cast<T*>(pipeline.getGPUObject());
}
template< typename T >
static void setGPUObject(const State& state, T* object) {
state.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const State& state) {
return reinterpret_cast<T*>(state.getGPUObject());
}
template< typename T >
static void setGPUObject(const Framebuffer& framebuffer, T* object) {
framebuffer.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Framebuffer& framebuffer) {
return reinterpret_cast<T*>(framebuffer.getGPUObject());
}
template< typename T >
static void setGPUObject(const Query& query, T* object) {
query.setGPUObject(object);
}
template< typename T >
static T* getGPUObject(const Query& query) {
return reinterpret_cast<T*>(query.getGPUObject());
}
protected: protected:
StereoState _stereo; StereoState _stereo;

View file

@ -16,10 +16,25 @@
namespace gpu { namespace gpu {
class Backend;
class GPUObject { class GPUObject {
public: public:
GPUObject() {} virtual ~GPUObject() = default;
virtual ~GPUObject() {} };
class GPUObjectWrapper {
public:
virtual ~GPUObjectWrapper() { delete _gpuObject; }
private:
// This shouldn't be used by anything else than the Backend class with the proper casting.
// TODO: Consider using std::unique_ptr to get rid of dtor and ensure correct destruction of GPU objects
mutable GPUObject* _gpuObject { nullptr };
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef int Stamp; typedef int Stamp;

View file

@ -64,7 +64,7 @@ protected:
typedef std::shared_ptr<Swapchain> SwapchainPointer; typedef std::shared_ptr<Swapchain> SwapchainPointer;
class Framebuffer { class Framebuffer : public GPUObjectWrapper {
public: public:
enum BufferMask { enum BufferMask {
BUFFER_COLOR0 = 1, BUFFER_COLOR0 = 1,
@ -153,12 +153,6 @@ protected:
// Non exposed // Non exposed
Framebuffer(const Framebuffer& framebuffer) = delete; Framebuffer(const Framebuffer& framebuffer) = delete;
Framebuffer() {} Framebuffer() {}
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef std::shared_ptr<Framebuffer> FramebufferPointer; typedef std::shared_ptr<Framebuffer> FramebufferPointer;

View file

@ -20,7 +20,7 @@
namespace gpu { namespace gpu {
class Pipeline { class Pipeline : public GPUObjectWrapper {
public: public:
using Pointer = std::shared_ptr< Pipeline >; using Pointer = std::shared_ptr< Pipeline >;
@ -38,12 +38,6 @@ protected:
Pipeline(); Pipeline();
Pipeline(const Pipeline& pipeline); // deep copy of the sysmem shader Pipeline(const Pipeline& pipeline); // deep copy of the sysmem shader
Pipeline& operator=(const Pipeline& pipeline); // deep copy of the sysmem texture Pipeline& operator=(const Pipeline& pipeline); // deep copy of the sysmem texture
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = nullptr;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef Pipeline::Pointer PipelinePointer; typedef Pipeline::Pointer PipelinePointer;

View file

@ -19,7 +19,7 @@
namespace gpu { namespace gpu {
class Query { class Query : public GPUObjectWrapper {
public: public:
Query(); Query();
~Query(); ~Query();
@ -27,14 +27,6 @@ namespace gpu {
uint32 queryResult; uint32 queryResult;
double getElapsedTime(); double getElapsedTime();
protected:
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef std::shared_ptr<Query> QueryPointer; typedef std::shared_ptr<Query> QueryPointer;

View file

@ -170,20 +170,17 @@ Resource::Size Resource::Sysmem::append(Size size, const Byte* bytes) {
Buffer::Buffer() : Buffer::Buffer() :
Resource(), Resource(),
_sysmem(new Sysmem()), _sysmem(new Sysmem()) {
_gpuObject(NULL) {
} }
Buffer::Buffer(Size size, const Byte* bytes) : Buffer::Buffer(Size size, const Byte* bytes) :
Resource(), Resource(),
_sysmem(new Sysmem(size, bytes)), _sysmem(new Sysmem(size, bytes)) {
_gpuObject(NULL) {
} }
Buffer::Buffer(const Buffer& buf) : Buffer::Buffer(const Buffer& buf) :
Resource(), Resource(),
_sysmem(new Sysmem(buf.getSysmem())), _sysmem(new Sysmem(buf.getSysmem())) {
_gpuObject(NULL) {
} }
Buffer& Buffer::operator=(const Buffer& buf) { Buffer& Buffer::operator=(const Buffer& buf) {
@ -196,10 +193,6 @@ Buffer::~Buffer() {
delete _sysmem; delete _sysmem;
_sysmem = NULL; _sysmem = NULL;
} }
if (_gpuObject) {
delete _gpuObject;
_gpuObject = NULL;
}
} }
Buffer::Size Buffer::resize(Size size) { Buffer::Size Buffer::resize(Size size) {

View file

@ -108,7 +108,7 @@ protected:
}; };
class Buffer : public Resource { class Buffer : public Resource, public GPUObjectWrapper {
public: public:
Buffer(); Buffer();
@ -156,13 +156,6 @@ public:
protected: protected:
Sysmem* _sysmem = NULL; Sysmem* _sysmem = NULL;
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef std::shared_ptr<Buffer> BufferPointer; typedef std::shared_ptr<Buffer> BufferPointer;

View file

@ -20,7 +20,7 @@
namespace gpu { namespace gpu {
class Shader { class Shader : public GPUObjectWrapper {
public: public:
typedef std::shared_ptr< Shader > Pointer; typedef std::shared_ptr< Shader > Pointer;
@ -178,12 +178,6 @@ protected:
// The type of the shader, the master key // The type of the shader, the master key
Type _type; Type _type;
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef Shader::Pointer ShaderPointer; typedef Shader::Pointer ShaderPointer;

View file

@ -36,7 +36,7 @@ namespace gpu {
class GPUObject; class GPUObject;
class State { class State : public GPUObjectWrapper {
public: public:
State(); State();
virtual ~State(); virtual ~State();
@ -392,12 +392,6 @@ protected:
Data _values; Data _values;
Signature _signature{0}; Signature _signature{0};
Stamp _stamp{0}; Stamp _stamp{0};
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = nullptr;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef std::shared_ptr< State > StatePointer; typedef std::shared_ptr< State > StatePointer;

View file

@ -136,7 +136,7 @@ protected:
Desc _desc; Desc _desc;
}; };
class Texture : public Resource { class Texture : public Resource, public GPUObjectWrapper {
public: public:
class Pixels { class Pixels {
@ -386,13 +386,6 @@ protected:
static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler); static Texture* create(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices, const Sampler& sampler);
Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices); Size resize(Type type, const Element& texelFormat, uint16 width, uint16 height, uint16 depth, uint16 numSamples, uint16 numSlices);
// This shouldn't be used by anything else than the Backend class with the proper casting.
mutable GPUObject* _gpuObject = NULL;
void setGPUObject(GPUObject* gpuObject) const { _gpuObject = gpuObject; }
GPUObject* getGPUObject() const { return _gpuObject; }
friend class Backend;
}; };
typedef std::shared_ptr<Texture> TexturePointer; typedef std::shared_ptr<Texture> TexturePointer;