... by avoiding the walk through the entire chain every time it is
called. It's not necessary to add up all the sizes either, since we can
just get the end of the last Bufferable.
void Bufferable::update_buffer_data() const
{
void Bufferable::update_buffer_data() const
{
- const Bufferable *first = this;
- for(; first->prev_in_buffer; first=first->prev_in_buffer) ;
-
- unsigned total_size = 0;
- for(const Bufferable *b=first; b; b=b->next_in_buffer)
- total_size += b->get_data_size();
-
- if(total_size!=buffer->get_size())
+ if(buffer_offset+get_data_size()>=buffer->get_size())
- buffer->data(total_size, 0);
- // Resizing the buffer invalidates its contents.
- for(const Bufferable *b=first; b; b=b->next_in_buffer)
- b->dirty = true;
+ const Bufferable *last = this;
+ for(; last->next_in_buffer; last=last->next_in_buffer) ;
+
+ unsigned total_size = last->buffer_offset+last->get_data_size();
+
+ if(total_size>buffer->get_size())
+ {
+ buffer->data(total_size, 0);
+ /* Resizing the buffer invalidates its contents. Non-dirty data may
+ be in use, so reupload it. */
+ for(const Bufferable *b=last; b; b=b->prev_in_buffer)
+ if(!b->dirty)
+ b->upload_data();
+ }