panda3d/panda/src/gobj/vertexDataBook.cxx
2007-06-07 21:47:37 +00:00

186 lines
6.1 KiB
C++

// Filename: vertexDataBook.cxx
// Created by: drose (16May07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "vertexDataBook.h"
#include "reMutexHolder.h"
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
VertexDataBook::
VertexDataBook(size_t block_size) : _block_size(block_size) {
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
VertexDataBook::
~VertexDataBook() {
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::count_total_page_size
// Access: Published
// Description: Returns the total size of all bytes owned by all
// pages owned by this book.
////////////////////////////////////////////////////////////////////
size_t VertexDataBook::
count_total_page_size() const {
MutexHolder holder(_lock);
size_t total = 0;
Pages::const_iterator pi;
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
total += (*pi)->get_max_size();
}
return total;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::count_total_page_size
// Access: Published
// Description: Returns the total size of all bytes owned by all
// pages owned by this book that have the indicated ram
// class.
////////////////////////////////////////////////////////////////////
size_t VertexDataBook::
count_total_page_size(VertexDataPage::RamClass ram_class) const {
MutexHolder holder(_lock);
size_t total = 0;
Pages::const_iterator pi;
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
if ((*pi)->get_ram_class() == ram_class) {
total += (*pi)->get_max_size();
}
}
return total;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::count_allocated_size
// Access: Published
// Description: Returns the total size of all bytes allocated within
// pages owned by this book.
////////////////////////////////////////////////////////////////////
size_t VertexDataBook::
count_allocated_size() const {
MutexHolder holder(_lock);
size_t total = 0;
Pages::const_iterator pi;
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
total += (*pi)->get_total_size();
}
return total;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::count_allocated_size
// Access: Published
// Description: Returns the total size of all bytes allocated within
// pages owned by this book that have the indicated ram
// class.
////////////////////////////////////////////////////////////////////
size_t VertexDataBook::
count_allocated_size(VertexDataPage::RamClass ram_class) const {
MutexHolder holder(_lock);
size_t total = 0;
Pages::const_iterator pi;
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
if ((*pi)->get_ram_class() == ram_class) {
total += (*pi)->get_total_size();
}
}
return total;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::save_to_disk
// Access: Published
// Description: Writes all pages to disk immediately, just in case
// they get evicted later. It makes sense to make this
// call just before taking down a loading screen, to
// minimize chugs from saving pages inadvertently later.
////////////////////////////////////////////////////////////////////
void VertexDataBook::
save_to_disk() {
MutexHolder holder(_lock);
Pages::iterator pi;
for (pi = _pages.begin(); pi != _pages.end(); ++pi) {
(*pi)->save_to_disk();
}
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBook::do_alloc
// Access: Private
// Description: Allocates and returns a new VertexDataBuffer of the
// requested size.
//
// Assumes the lock is already held.
////////////////////////////////////////////////////////////////////
VertexDataBlock *VertexDataBook::
do_alloc(size_t size) {
// Look for an empty page of the appropriate size. The _pages set
// is sorted so that the pages with the smallest available blocks
// are at the front.
// Create a dummy page to use to search the set.
VertexDataPage size_page(size);
Pages::iterator pi = _pages.lower_bound(&size_page);
// Now we can start from the first element of the set that is
// possibly large enough to contain this block, and work up from
// there.
while (pi != _pages.end()) {
Pages::iterator pnext = pi;
++pnext;
VertexDataPage *page = (*pi);
// Allocating a block may change the page's available contiguous
// size, and thereby change its position in the set, invalidating
// the iterator pi. This is why we've already computed pnext.
VertexDataBlock *block = page->do_alloc(size);
if (block != (VertexDataBlock *)NULL) {
// This page worked.
return block;
}
// Try the next page.
pi = pnext;
}
// No page was good enough. Create a new page. Make it at least
// large enough to hold this requested block.
VertexDataPage *page = create_new_page(size);
_pages.insert(page);
VertexDataBlock *block = page->do_alloc(size);
return block;
}