Browse Source

Fix ShaderBuffer cleanup assertion with state cache disabled

rdb 7 years ago
parent
commit
669a655366

+ 3 - 2
panda/src/glstuff/glBufferContext_src.I

@@ -16,8 +16,9 @@
  */
  */
 INLINE CLP(BufferContext)::
 INLINE CLP(BufferContext)::
 CLP(BufferContext)(CLP(GraphicsStateGuardian) *glgsg,
 CLP(BufferContext)(CLP(GraphicsStateGuardian) *glgsg,
-                   PreparedGraphicsObjects *pgo) :
-  BufferContext(&pgo->_sbuffer_residency),
+                   PreparedGraphicsObjects *pgo,
+                   TypedWritableReferenceCount *object) :
+  BufferContext(&pgo->_sbuffer_residency, object),
   AdaptiveLruPage(0),
   AdaptiveLruPage(0),
   _glgsg(glgsg)
   _glgsg(glgsg)
 {
 {

+ 2 - 1
panda/src/glstuff/glBufferContext_src.h

@@ -21,7 +21,8 @@
 class EXPCL_GL CLP(BufferContext) : public BufferContext, public AdaptiveLruPage {
 class EXPCL_GL CLP(BufferContext) : public BufferContext, public AdaptiveLruPage {
 public:
 public:
   INLINE CLP(BufferContext)(CLP(GraphicsStateGuardian) *glgsg,
   INLINE CLP(BufferContext)(CLP(GraphicsStateGuardian) *glgsg,
-                            PreparedGraphicsObjects *pgo);
+                            PreparedGraphicsObjects *pgo,
+                            TypedWritableReferenceCount *object);
   ALLOC_DELETED_CHAIN(CLP(BufferContext));
   ALLOC_DELETED_CHAIN(CLP(BufferContext));
 
 
   virtual void evict_lru();
   virtual void evict_lru();

+ 1 - 1
panda/src/glstuff/glGraphicsBuffer_src.cxx

@@ -1413,7 +1413,7 @@ open_buffer() {
   }
   }
 
 
   if (_rb_context == nullptr) {
   if (_rb_context == nullptr) {
-    _rb_context = new BufferContext(&(glgsg->_renderbuffer_residency));
+    _rb_context = new BufferContext(&(glgsg->_renderbuffer_residency), nullptr);
   }
   }
 
 
 /*
 /*

+ 1 - 1
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -6519,7 +6519,7 @@ prepare_shader_buffer(ShaderBuffer *data) {
   if (_supports_shader_buffers) {
   if (_supports_shader_buffers) {
     PStatGPUTimer timer(this, _prepare_shader_buffer_pcollector);
     PStatGPUTimer timer(this, _prepare_shader_buffer_pcollector);
 
 
-    CLP(BufferContext) *gbc = new CLP(BufferContext)(this, _prepared_objects);
+    CLP(BufferContext) *gbc = new CLP(BufferContext)(this, _prepared_objects, data);
     _glGenBuffers(1, &gbc->_index);
     _glGenBuffers(1, &gbc->_index);
 
 
     if (GLCAT.is_debug() && gl_debug_buffers) {
     if (GLCAT.is_debug() && gl_debug_buffers) {

+ 8 - 0
panda/src/gobj/bufferContext.I

@@ -11,6 +11,14 @@
  * @date 2006-03-16
  * @date 2006-03-16
  */
  */
 
 
+/**
+ * Returns the associated object.
+ */
+INLINE TypedWritableReferenceCount *BufferContext::
+get_object() const {
+  return _object;
+}
+
 /**
 /**
  * Returns the number of bytes previously reported for the data object.  This
  * Returns the number of bytes previously reported for the data object.  This
  * is used to track changes in the data object's allocated size; if it changes
  * is used to track changes in the data object's allocated size; if it changes

+ 2 - 1
panda/src/gobj/bufferContext.cxx

@@ -19,7 +19,8 @@ TypeHandle BufferContext::_type_handle;
  *
  *
  */
  */
 BufferContext::
 BufferContext::
-BufferContext(BufferResidencyTracker *residency) :
+BufferContext(BufferResidencyTracker *residency, TypedWritableReferenceCount *object) :
+  _object(object),
   _residency(residency),
   _residency(residency),
   _residency_state(0),
   _residency_state(0),
   _data_size_bytes(0),
   _data_size_bytes(0),

+ 11 - 1
panda/src/gobj/bufferContext.h

@@ -23,6 +23,7 @@
 #include "bufferResidencyTracker.h"
 #include "bufferResidencyTracker.h"
 
 
 class PreparedGraphicsObjects;
 class PreparedGraphicsObjects;
+class TypedWritableReferenceCount;
 
 
 /**
 /**
  * This is a base class for those kinds of SavedContexts that occupy an
  * This is a base class for those kinds of SavedContexts that occupy an
@@ -36,15 +37,19 @@ class PreparedGraphicsObjects;
  */
  */
 class EXPCL_PANDA_GOBJ BufferContext : public SavedContext, private LinkedListNode {
 class EXPCL_PANDA_GOBJ BufferContext : public SavedContext, private LinkedListNode {
 public:
 public:
-  BufferContext(BufferResidencyTracker *residency);
+  BufferContext(BufferResidencyTracker *residency, TypedWritableReferenceCount *object);
   virtual ~BufferContext();
   virtual ~BufferContext();
 
 
+  INLINE TypedWritableReferenceCount *get_object() const;
+
 PUBLISHED:
 PUBLISHED:
   INLINE size_t get_data_size_bytes() const;
   INLINE size_t get_data_size_bytes() const;
   INLINE UpdateSeq get_modified() const;
   INLINE UpdateSeq get_modified() const;
   INLINE bool get_active() const;
   INLINE bool get_active() const;
   INLINE bool get_resident() const;
   INLINE bool get_resident() const;
 
 
+  MAKE_PROPERTY(object, get_object);
+
   MAKE_PROPERTY(data_size_bytes, get_data_size_bytes);
   MAKE_PROPERTY(data_size_bytes, get_data_size_bytes);
   MAKE_PROPERTY(modified, get_modified);
   MAKE_PROPERTY(modified, get_modified);
   MAKE_PROPERTY(active, get_active);
   MAKE_PROPERTY(active, get_active);
@@ -62,6 +67,11 @@ public:
 private:
 private:
   void set_owning_chain(BufferContextChain *chain);
   void set_owning_chain(BufferContextChain *chain);
 
 
+protected:
+  // This cannot be a PT(), because the object and the GSG both own their
+  // BufferContexts!  That would create a circular reference count.
+  TypedWritableReferenceCount *_object;
+
 private:
 private:
   BufferResidencyTracker *_residency;
   BufferResidencyTracker *_residency;
   int _residency_state;
   int _residency_state;

+ 7 - 8
panda/src/gobj/indexBufferContext.I

@@ -16,9 +16,8 @@
  */
  */
 INLINE IndexBufferContext::
 INLINE IndexBufferContext::
 IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
 IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
-  BufferContext(&pgo->_ibuffer_residency),
-  AdaptiveLruPage(0),
-  _data(data)
+  BufferContext(&pgo->_ibuffer_residency, data),
+  AdaptiveLruPage(0)
 {
 {
 }
 }
 
 
@@ -27,7 +26,7 @@ IndexBufferContext(PreparedGraphicsObjects *pgo, GeomPrimitive *data) :
  */
  */
 INLINE GeomPrimitive *IndexBufferContext::
 INLINE GeomPrimitive *IndexBufferContext::
 get_data() const {
 get_data() const {
-  return _data;
+  return (GeomPrimitive *)_object;
 }
 }
 
 
 /**
 /**
@@ -36,7 +35,7 @@ get_data() const {
  */
  */
 INLINE bool IndexBufferContext::
 INLINE bool IndexBufferContext::
 changed_size(const GeomPrimitivePipelineReader *reader) const {
 changed_size(const GeomPrimitivePipelineReader *reader) const {
-  nassertr(reader->get_object() == _data, false);
+  nassertr(reader->get_object() == get_data(), false);
   return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
   return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
 }
 }
 
 
@@ -46,7 +45,7 @@ changed_size(const GeomPrimitivePipelineReader *reader) const {
  */
  */
 INLINE bool IndexBufferContext::
 INLINE bool IndexBufferContext::
 changed_usage_hint(const GeomPrimitivePipelineReader *reader) const {
 changed_usage_hint(const GeomPrimitivePipelineReader *reader) const {
-  nassertr(reader->get_object() == _data, false);
+  nassertr(reader->get_object() == get_data(), false);
   return _usage_hint != reader->get_usage_hint();
   return _usage_hint != reader->get_usage_hint();
 }
 }
 
 
@@ -56,7 +55,7 @@ changed_usage_hint(const GeomPrimitivePipelineReader *reader) const {
  */
  */
 INLINE bool IndexBufferContext::
 INLINE bool IndexBufferContext::
 was_modified(const GeomPrimitivePipelineReader *reader) const {
 was_modified(const GeomPrimitivePipelineReader *reader) const {
-  nassertr(reader->get_object() == _data, false);
+  nassertr(reader->get_object() == get_data(), false);
   return get_modified() != reader->get_modified();
   return get_modified() != reader->get_modified();
 }
 }
 
 
@@ -76,7 +75,7 @@ update_data_size_bytes(size_t new_data_size_bytes) {
  */
  */
 INLINE void IndexBufferContext::
 INLINE void IndexBufferContext::
 mark_loaded(const GeomPrimitivePipelineReader *reader) {
 mark_loaded(const GeomPrimitivePipelineReader *reader) {
-  nassertv(reader->get_object() == _data);
+  nassertv(reader->get_object() == get_data());
   update_data_size_bytes(reader->get_data_size_bytes());
   update_data_size_bytes(reader->get_data_size_bytes());
   update_modified(reader->get_modified());
   update_modified(reader->get_modified());
   _usage_hint = reader->get_usage_hint();
   _usage_hint = reader->get_usage_hint();

+ 0 - 3
panda/src/gobj/indexBufferContext.h

@@ -50,9 +50,6 @@ public:
   virtual void write(std::ostream &out, int indent_level) const;
   virtual void write(std::ostream &out, int indent_level) const;
 
 
 private:
 private:
-  // This cannot be a PT(GeomPrimitive), because the data and the GSG both own
-  // their IndexBufferContexts!  That would create a circular reference count.
-  GeomPrimitive *_data;
   GeomEnums::UsageHint _usage_hint;
   GeomEnums::UsageHint _usage_hint;
 
 
 public:
 public:

+ 25 - 18
panda/src/gobj/preparedGraphicsObjects.cxx

@@ -270,11 +270,11 @@ void PreparedGraphicsObjects::
 release_texture(TextureContext *tc) {
 release_texture(TextureContext *tc) {
   ReMutexHolder holder(_lock);
   ReMutexHolder holder(_lock);
 
 
-  tc->_texture->clear_prepared(tc->get_view(), this);
+  tc->get_texture()->clear_prepared(tc->get_view(), this);
 
 
   // We have to set the Texture pointer to NULL at this point, since the
   // We have to set the Texture pointer to NULL at this point, since the
   // Texture itself might destruct at any time after it has been released.
   // Texture itself might destruct at any time after it has been released.
-  tc->_texture = nullptr;
+  tc->_object = nullptr;
 
 
   bool removed = (_prepared_textures.erase(tc) != 0);
   bool removed = (_prepared_textures.erase(tc) != 0);
   nassertv(removed);
   nassertv(removed);
@@ -307,8 +307,8 @@ release_all_textures() {
        tci != _prepared_textures.end();
        tci != _prepared_textures.end();
        ++tci) {
        ++tci) {
     TextureContext *tc = (*tci);
     TextureContext *tc = (*tci);
-    tc->_texture->clear_prepared(tc->get_view(), this);
-    tc->_texture = nullptr;
+    tc->get_texture()->clear_prepared(tc->get_view(), this);
+    tc->_object = nullptr;
 
 
     _released_textures.insert(tc);
     _released_textures.insert(tc);
   }
   }
@@ -946,14 +946,14 @@ void PreparedGraphicsObjects::
 release_vertex_buffer(VertexBufferContext *vbc) {
 release_vertex_buffer(VertexBufferContext *vbc) {
   ReMutexHolder holder(_lock);
   ReMutexHolder holder(_lock);
 
 
-  vbc->_data->clear_prepared(this);
+  vbc->get_data()->clear_prepared(this);
 
 
-  size_t data_size_bytes = vbc->_data->get_data_size_bytes();
-  GeomEnums::UsageHint usage_hint = vbc->_data->get_usage_hint();
+  size_t data_size_bytes = vbc->get_data()->get_data_size_bytes();
+  GeomEnums::UsageHint usage_hint = vbc->get_data()->get_usage_hint();
 
 
   // We have to set the Data pointer to NULL at this point, since the Data
   // We have to set the Data pointer to NULL at this point, since the Data
   // itself might destruct at any time after it has been released.
   // itself might destruct at any time after it has been released.
-  vbc->_data = nullptr;
+  vbc->_object = nullptr;
 
 
   bool removed = (_prepared_vertex_buffers.erase(vbc) != 0);
   bool removed = (_prepared_vertex_buffers.erase(vbc) != 0);
   nassertv(removed);
   nassertv(removed);
@@ -985,8 +985,8 @@ release_all_vertex_buffers() {
        vbci != _prepared_vertex_buffers.end();
        vbci != _prepared_vertex_buffers.end();
        ++vbci) {
        ++vbci) {
     VertexBufferContext *vbc = (VertexBufferContext *)(*vbci);
     VertexBufferContext *vbc = (VertexBufferContext *)(*vbci);
-    vbc->_data->clear_prepared(this);
-    vbc->_data = nullptr;
+    vbc->get_data()->clear_prepared(this);
+    vbc->_object = nullptr;
 
 
     _released_vertex_buffers.insert(vbc);
     _released_vertex_buffers.insert(vbc);
   }
   }
@@ -1061,7 +1061,7 @@ prepare_vertex_buffer_now(GeomVertexArrayData *data, GraphicsStateGuardianBase *
                       _vertex_buffer_cache, _vertex_buffer_cache_lru,
                       _vertex_buffer_cache, _vertex_buffer_cache_lru,
                       _vertex_buffer_cache_size);
                       _vertex_buffer_cache_size);
   if (vbc != nullptr) {
   if (vbc != nullptr) {
-    vbc->_data = data;
+    vbc->_object = data;
 
 
   } else {
   } else {
     // Ask the GSG to create a brand new VertexBufferContext.  There might be
     // Ask the GSG to create a brand new VertexBufferContext.  There might be
@@ -1144,14 +1144,14 @@ void PreparedGraphicsObjects::
 release_index_buffer(IndexBufferContext *ibc) {
 release_index_buffer(IndexBufferContext *ibc) {
   ReMutexHolder holder(_lock);
   ReMutexHolder holder(_lock);
 
 
-  ibc->_data->clear_prepared(this);
+  ibc->get_data()->clear_prepared(this);
 
 
-  size_t data_size_bytes = ibc->_data->get_data_size_bytes();
-  GeomEnums::UsageHint usage_hint = ibc->_data->get_usage_hint();
+  size_t data_size_bytes = ibc->get_data()->get_data_size_bytes();
+  GeomEnums::UsageHint usage_hint = ibc->get_data()->get_usage_hint();
 
 
   // We have to set the Data pointer to NULL at this point, since the Data
   // We have to set the Data pointer to NULL at this point, since the Data
   // itself might destruct at any time after it has been released.
   // itself might destruct at any time after it has been released.
-  ibc->_data = nullptr;
+  ibc->_object = nullptr;
 
 
   bool removed = (_prepared_index_buffers.erase(ibc) != 0);
   bool removed = (_prepared_index_buffers.erase(ibc) != 0);
   nassertv(removed);
   nassertv(removed);
@@ -1183,8 +1183,8 @@ release_all_index_buffers() {
        ibci != _prepared_index_buffers.end();
        ibci != _prepared_index_buffers.end();
        ++ibci) {
        ++ibci) {
     IndexBufferContext *ibc = (IndexBufferContext *)(*ibci);
     IndexBufferContext *ibc = (IndexBufferContext *)(*ibci);
-    ibc->_data->clear_prepared(this);
-    ibc->_data = nullptr;
+    ibc->get_data()->clear_prepared(this);
+    ibc->_object = nullptr;
 
 
     _released_index_buffers.insert(ibc);
     _released_index_buffers.insert(ibc);
   }
   }
@@ -1258,7 +1258,7 @@ prepare_index_buffer_now(GeomPrimitive *data, GraphicsStateGuardianBase *gsg) {
                       _index_buffer_cache, _index_buffer_cache_lru,
                       _index_buffer_cache, _index_buffer_cache_lru,
                       _index_buffer_cache_size);
                       _index_buffer_cache_size);
   if (ibc != nullptr) {
   if (ibc != nullptr) {
-    ibc->_data = data;
+    ibc->_object = data;
 
 
   } else {
   } else {
     // Ask the GSG to create a brand new IndexBufferContext.  There might be
     // Ask the GSG to create a brand new IndexBufferContext.  There might be
@@ -1341,6 +1341,13 @@ void PreparedGraphicsObjects::
 release_shader_buffer(BufferContext *bc) {
 release_shader_buffer(BufferContext *bc) {
   ReMutexHolder holder(_lock);
   ReMutexHolder holder(_lock);
 
 
+  ShaderBuffer *buffer = (ShaderBuffer *)bc->_object;
+  buffer->clear_prepared(this);
+
+  // We have to set the ShaderBuffer pointer to NULL at this point, since the
+  // buffer itself might destruct at any time after it has been released.
+  bc->_object = nullptr;
+
   bool removed = (_prepared_shader_buffers.erase(bc) != 0);
   bool removed = (_prepared_shader_buffers.erase(bc) != 0);
   nassertv(removed);
   nassertv(removed);
 
 

+ 25 - 0
panda/src/gobj/shaderBuffer.cxx

@@ -143,6 +143,31 @@ release_all() {
   return num_freed;
   return num_freed;
 }
 }
 
 
+/**
+ * Removes the indicated PreparedGraphicsObjects table from the buffer's
+ * table, without actually releasing the texture.  This is intended to be
+ * called only from PreparedGraphicsObjects::release_shader_buffer(); it
+ * should never be called by user code.
+ */
+void ShaderBuffer::
+clear_prepared(PreparedGraphicsObjects *prepared_objects) {
+  nassertv(_contexts != nullptr);
+
+  Contexts::iterator ci;
+  ci = _contexts->find(prepared_objects);
+  if (ci != _contexts->end()) {
+    _contexts->erase(ci);
+    if (_contexts->empty()) {
+      delete _contexts;
+      _contexts = nullptr;
+    }
+  } else {
+    // If this assertion fails, clear_prepared() was given a prepared_objects
+    // which the data array didn't know about.
+    nassert_raise("unknown PreparedGraphicsObjects");
+  }
+}
+
 /**
 /**
  * Tells the BamReader how to create objects of type ParamValue.
  * Tells the BamReader how to create objects of type ParamValue.
  */
  */

+ 5 - 0
panda/src/gobj/shaderBuffer.h

@@ -57,6 +57,9 @@ PUBLISHED:
   bool release(PreparedGraphicsObjects *prepared_objects);
   bool release(PreparedGraphicsObjects *prepared_objects);
   int release_all();
   int release_all();
 
 
+private:
+  void clear_prepared(PreparedGraphicsObjects *prepared_objects);
+
 private:
 private:
   uint64_t _data_size_bytes;
   uint64_t _data_size_bytes;
   UsageHint _usage_hint;
   UsageHint _usage_hint;
@@ -91,6 +94,8 @@ public:
 
 
 private:
 private:
   static TypeHandle _type_handle;
   static TypeHandle _type_handle;
+
+  friend class PreparedGraphicsObjects;
 };
 };
 
 
 INLINE std::ostream &operator << (std::ostream &out, const ShaderBuffer &m) {
 INLINE std::ostream &operator << (std::ostream &out, const ShaderBuffer &m) {

+ 9 - 10
panda/src/gobj/textureContext.I

@@ -16,9 +16,8 @@
  */
  */
 INLINE TextureContext::
 INLINE TextureContext::
 TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) :
 TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) :
-  BufferContext(&pgo->_texture_residency),
+  BufferContext(&pgo->_texture_residency, tex),
   AdaptiveLruPage(0),
   AdaptiveLruPage(0),
-  _texture(tex),
   _view(view)
   _view(view)
 {
 {
 }
 }
@@ -28,7 +27,7 @@ TextureContext(PreparedGraphicsObjects *pgo, Texture *tex, int view) :
  */
  */
 INLINE Texture *TextureContext::
 INLINE Texture *TextureContext::
 get_texture() const {
 get_texture() const {
-  return _texture;
+  return (Texture *)_object;
 }
 }
 
 
 /**
 /**
@@ -56,7 +55,7 @@ was_modified() const {
  */
  */
 INLINE bool TextureContext::
 INLINE bool TextureContext::
 was_properties_modified() const {
 was_properties_modified() const {
-  return _properties_modified != _texture->get_properties_modified();
+  return _properties_modified != get_texture()->get_properties_modified();
 }
 }
 
 
 /**
 /**
@@ -65,7 +64,7 @@ was_properties_modified() const {
  */
  */
 INLINE bool TextureContext::
 INLINE bool TextureContext::
 was_image_modified() const {
 was_image_modified() const {
-  return _image_modified != _texture->get_image_modified();
+  return _image_modified != get_texture()->get_image_modified();
 }
 }
 
 
 /**
 /**
@@ -74,7 +73,7 @@ was_image_modified() const {
  */
  */
 INLINE bool TextureContext::
 INLINE bool TextureContext::
 was_simple_image_modified() const {
 was_simple_image_modified() const {
-  return _simple_image_modified != _texture->get_simple_image_modified();
+  return _simple_image_modified != get_texture()->get_simple_image_modified();
 }
 }
 
 
 /**
 /**
@@ -121,8 +120,8 @@ update_data_size_bytes(size_t new_data_size_bytes) {
 INLINE void TextureContext::
 INLINE void TextureContext::
 mark_loaded() {
 mark_loaded() {
   // _data_size_bytes = _data->get_texture_size_bytes();
   // _data_size_bytes = _data->get_texture_size_bytes();
-  _properties_modified = _texture->get_properties_modified();
-  _image_modified = _texture->get_image_modified();
+  _properties_modified = get_texture()->get_properties_modified();
+  _image_modified = get_texture()->get_image_modified();
   update_modified(std::max(_properties_modified, _image_modified));
   update_modified(std::max(_properties_modified, _image_modified));
 
 
   // Assume the texture is now resident.
   // Assume the texture is now resident.
@@ -135,8 +134,8 @@ mark_loaded() {
  */
  */
 INLINE void TextureContext::
 INLINE void TextureContext::
 mark_simple_loaded() {
 mark_simple_loaded() {
-  _properties_modified = _texture->get_properties_modified();
-  _simple_image_modified = _texture->get_simple_image_modified();
+  _properties_modified = get_texture()->get_properties_modified();
+  _simple_image_modified = get_texture()->get_simple_image_modified();
   update_modified(std::max(_properties_modified, _simple_image_modified));
   update_modified(std::max(_properties_modified, _simple_image_modified));
 
 
   // The texture's not exactly resident now, but some part of it is.
   // The texture's not exactly resident now, but some part of it is.

+ 0 - 3
panda/src/gobj/textureContext.h

@@ -60,9 +60,6 @@ public:
   virtual void write(std::ostream &out, int indent_level) const;
   virtual void write(std::ostream &out, int indent_level) const;
 
 
 private:
 private:
-  // This cannot be a PT(Texture), because the texture and the GSG both own
-  // their TextureContexts!  That would create a circular reference count.
-  Texture *_texture;
   int _view;
   int _view;
   UpdateSeq _properties_modified;
   UpdateSeq _properties_modified;
   UpdateSeq _image_modified;
   UpdateSeq _image_modified;

+ 7 - 8
panda/src/gobj/vertexBufferContext.I

@@ -16,9 +16,8 @@
  */
  */
 INLINE VertexBufferContext::
 INLINE VertexBufferContext::
 VertexBufferContext(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
 VertexBufferContext(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
-  BufferContext(&pgo->_vbuffer_residency),
-  AdaptiveLruPage(0),
-  _data(data)
+  BufferContext(&pgo->_vbuffer_residency, data),
+  AdaptiveLruPage(0)
 {
 {
 }
 }
 
 
@@ -27,7 +26,7 @@ VertexBufferContext(PreparedGraphicsObjects *pgo, GeomVertexArrayData *data) :
  */
  */
 INLINE GeomVertexArrayData *VertexBufferContext::
 INLINE GeomVertexArrayData *VertexBufferContext::
 get_data() const {
 get_data() const {
-  return _data;
+  return (GeomVertexArrayData *)_object;
 }
 }
 
 
 /**
 /**
@@ -36,7 +35,7 @@ get_data() const {
  */
  */
 INLINE bool VertexBufferContext::
 INLINE bool VertexBufferContext::
 changed_size(const GeomVertexArrayDataHandle *reader) const {
 changed_size(const GeomVertexArrayDataHandle *reader) const {
-  nassertr(reader->get_object() == _data, false);
+  nassertr(reader->get_object() == get_data(), false);
   return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
   return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
 }
 }
 
 
@@ -46,7 +45,7 @@ changed_size(const GeomVertexArrayDataHandle *reader) const {
  */
  */
 INLINE bool VertexBufferContext::
 INLINE bool VertexBufferContext::
 changed_usage_hint(const GeomVertexArrayDataHandle *reader) const {
 changed_usage_hint(const GeomVertexArrayDataHandle *reader) const {
-  nassertr(reader->get_object() == _data, false);
+  nassertr(reader->get_object() == get_data(), false);
   return _usage_hint != reader->get_usage_hint();
   return _usage_hint != reader->get_usage_hint();
 }
 }
 
 
@@ -56,7 +55,7 @@ changed_usage_hint(const GeomVertexArrayDataHandle *reader) const {
  */
  */
 INLINE bool VertexBufferContext::
 INLINE bool VertexBufferContext::
 was_modified(const GeomVertexArrayDataHandle *reader) const {
 was_modified(const GeomVertexArrayDataHandle *reader) const {
-  nassertr(reader->get_object() == _data, false);
+  nassertr(reader->get_object() == get_data(), false);
   return get_modified() != reader->get_modified();
   return get_modified() != reader->get_modified();
 }
 }
 
 
@@ -77,7 +76,7 @@ update_data_size_bytes(size_t new_data_size_bytes) {
  */
  */
 INLINE void VertexBufferContext::
 INLINE void VertexBufferContext::
 mark_loaded(const GeomVertexArrayDataHandle *reader) {
 mark_loaded(const GeomVertexArrayDataHandle *reader) {
-  nassertv(reader->get_object() == _data);
+  nassertv(reader->get_object() == get_data());
   update_data_size_bytes(reader->get_data_size_bytes());
   update_data_size_bytes(reader->get_data_size_bytes());
   update_modified(reader->get_modified());
   update_modified(reader->get_modified());
   _usage_hint = reader->get_usage_hint();
   _usage_hint = reader->get_usage_hint();

+ 0 - 4
panda/src/gobj/vertexBufferContext.h

@@ -51,10 +51,6 @@ public:
   virtual void write(std::ostream &out, int indent_level) const;
   virtual void write(std::ostream &out, int indent_level) const;
 
 
 private:
 private:
-  // This cannot be a PT(GeomVertexArrayData), because the data and the GSG
-  // both own their VertexBufferContexts!  That would create a circular
-  // reference count.
-  GeomVertexArrayData *_data;
   GeomEnums::UsageHint _usage_hint;
   GeomEnums::UsageHint _usage_hint;
 
 
 public:
 public: