]> git.tdb.fi Git - libs/gl.git/commitdiff
Unbind things if they are deleted while current
authorMikko Rasa <tdb@tdb.fi>
Fri, 26 Sep 2014 15:00:18 +0000 (18:00 +0300)
committerMikko Rasa <tdb@tdb.fi>
Fri, 26 Sep 2014 15:00:18 +0000 (18:00 +0300)
Failing to do so can lead to all sorts of stale-state issues, especially
if a newly created thing happens to get the exact same address as the
just deleted one.

12 files changed:
source/bindable.h
source/buffer.cpp
source/buffer.h
source/light.cpp
source/light.h
source/texenv.cpp
source/texenv.h
source/texgen.cpp
source/texgen.h
source/texture.cpp
source/vertexarray.cpp
source/vertexarray.h

index 8a5821b957cf4dd1569e3e840d6ad2ee8207e5ed..20b6482a9ec92009e555e9cdbe34519e49699787 100644 (file)
@@ -15,6 +15,7 @@ protected:
        static const T *cur_obj;
 
        Bindable() { }
+       ~Bindable() { if(cur_obj==this) T::unbind(); }
 
        static bool set_current(const T *obj)
        {
@@ -39,8 +40,11 @@ A helper class for Bindables that revert to a default object on unbind.
 template<typename T>
 class BindableWithDefault: protected Bindable<T>
 {
+       friend class Bindable<T>;
+
 protected:
        BindableWithDefault() { }
+       ~BindableWithDefault() { if(this==&default_object()) Bindable<T>::set_current(0); }
 
 public:
        static const T *current()
index 9edcf07d6e52ab52e2b9b5f277a0f57b389fcec3..93ef98db60ad32654309945d505726d9255414d0 100644 (file)
@@ -13,6 +13,7 @@ namespace Msp {
 namespace GL {
 
 const Buffer *Buffer::bound[5] = { 0, 0, 0, 0, 0 };
+BufferType buffer_types[] = { ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER, PIXEL_PACK_BUFFER, PIXEL_UNPACK_BUFFER, UNIFORM_BUFFER };
 
 Buffer::Buffer(BufferType t):
        type(t),
@@ -26,6 +27,9 @@ Buffer::Buffer(BufferType t):
 
 Buffer::~Buffer()
 {
+       for(unsigned i=0; i<5; ++i)
+               if(bound[i]==this)
+                       unbind_from(buffer_types[i]);
        glDeleteBuffers(1, &id);
 }
 
@@ -140,6 +144,13 @@ BufferRange::BufferRange(Buffer &b, unsigned o, unsigned s):
                throw out_of_range("BufferRange::BufferRange");
 }
 
+BufferRange::~BufferRange()
+{
+       for(unsigned i=0; i<bound_uniform.size(); ++i)
+               if(bound_uniform[i]==this)
+                       unbind_from(UNIFORM_BUFFER, i);
+}
+
 void BufferRange::data(const void *d)
 {
        buffer.sub_data(offset, size, d);
index e43536e238da3f50b66fc875f499aeb4d0b90286..e254bcc70ca76a2f6cf7701cdff71faaeb8627d0 100644 (file)
@@ -121,6 +121,7 @@ private:
 
 public:
        BufferRange(Buffer &, unsigned, unsigned);
+       ~BufferRange();
 
        void data(const void *);
 
index 11f4826cd74748acde5b1bfba24d8efd32ea3203..968bffdf74894723bc620666bd56865b366637eb 100644 (file)
@@ -24,6 +24,12 @@ Light::Light():
        attenuation[2] = 0;
 }
 
+Light::~Light()
+{
+       while(LightUnit *unit = LightUnit::find_unit(this))
+               unbind_from(unit->get_index());
+}
+
 void Light::update_parameter(int mask, int index) const
 {
        if(index<0)
index 77542a54f7404b3a346ff8ec5de3cb1399ee6ffc..fa5bf28752b00a2a7e4735b8c0096d319c12b7af 100644 (file)
@@ -35,6 +35,7 @@ private:
 
 public:
        Light();
+       ~Light();
 
 private:
        void update_parameter(int, int = -1) const;
index 51adf9fb4aee45f1aa40e93effbad084e3c3b4d4..c8af55f85febad1b22c5560efb0c7f688fca405e 100644 (file)
@@ -9,6 +9,15 @@ TexEnv::TexEnv():
        color(0, 0, 0, 0)
 { }
 
+TexEnv::~TexEnv()
+{
+       if(this!=&default_object())
+       {
+               while(TexUnit *unit = TexUnit::find_unit(this))
+                       unbind_from(unit->get_index());
+       }
+}
+
 const TexEnv &TexEnv::default_object()
 {
        static TexEnv obj;
index 61f700854b50030e43297b96310aa106622a36fb..c422331aadd8f95285a842d9322fde6241bce16a 100644 (file)
@@ -31,6 +31,7 @@ private:
 
 public:
        TexEnv();
+       ~TexEnv();
 
        static const TexEnv &default_object();
 
index eb6179d08ef680e8732e544d7692533cec649a90..0114b2b73e2af6cbb177fc7aaeb5bb8613489f60 100644 (file)
@@ -12,6 +12,11 @@ TexGen::TexGen():
        mode(EYE_LINEAR)
 { }
 
+TexGen::~TexGen()
+{
+       // TODO unbind
+}
+
 void TexGen::set_mode(TexGenMode m)
 {
        mode = m;
index c69df6386fceb0036eb99e8ebfa6ddf5280d6cce..5858efb4e39e86814489e597280ebe6cb97736cc 100644 (file)
@@ -31,6 +31,7 @@ private:
 
 public:
        TexGen();
+       ~TexGen();
 
        void set_mode(TexGenMode);
        void set_plane(const Vector4 &);
index aec1bc92da90b9b84f8882991f9b6bf4a24d84c2..0fa65eadaed0f7b31508c6e9e4fa55a2d6ba4cfe 100644 (file)
@@ -65,6 +65,9 @@ Texture::Texture(GLenum t, ResourceManager *m):
 
 Texture::~Texture()
 {
+       while(TexUnit *unit = TexUnit::find_unit(this))
+               unbind_from(unit->get_index());
+
        if(id)
                glDeleteTextures(1, &id);
 }
index 3848109973c9dca9c8c49c830ebfa10e0285c6e9..042f58c758b41ac48af3fccd52dcb7ec5f75440b 100644 (file)
@@ -18,13 +18,10 @@ VertexArray::VertexArray(const VertexFormat &f)
 
 VertexArray::~VertexArray()
 {
+       /* Unbind accesses the current VertexArray, so a call from ~Bindable would
+       try to access destroyed data. */
        if(current()==this)
-       {
-               /* We must deactivate arrays here, or apply() would try to access deleted
-               data on the next invocation. */
-               set_current(0);
-               apply_arrays(0, &arrays, 0, 0);
-       }
+               unbind();
 }
 
 void VertexArray::reset(const VertexFormat &f)
@@ -103,7 +100,7 @@ unsigned VertexArray::get_data_size() const
        return data.size()*sizeof(float);
 }
 
-void VertexArray::apply() const
+void VertexArray::bind() const
 {
        if(format.empty())
                throw invalid_operation("VertexArray::apply");
@@ -210,6 +207,13 @@ void VertexArray::apply_arrays(const vector<Array> *arrays, const vector<Array>
                glClientActiveTexture(GL_TEXTURE0);
 }
 
+void VertexArray::unbind()
+{
+       const VertexArray *old = current();
+       if(set_current(0))
+               apply_arrays(0, &old->arrays, 0, 0);
+}
+
 
 VertexArray::Array::Array():
        component(0),
index 0223a1f4434df584cc16dd59a0a659f23d2f1409..9fa55b7117c32fdc2901c74215223b6616f9fa53 100644 (file)
@@ -68,9 +68,12 @@ public:
        const std::vector<float> &get_data() const { return data; }
        const float *operator[](unsigned i) const { return &data[0]+i*stride; }
 
-       void apply() const;
+       void bind() const;
+       void apply() const { bind(); }
 private:
        static void apply_arrays(const std::vector<Array> *, const std::vector<Array> *, const float *, unsigned);
+public:
+       static void unbind();
 };
 
 } // namespace GL