open_toontown_panda3d/panda/src/gobj/vertexDataPage.I

274 lines
10 KiB
Plaintext

// Filename: vertexDataPage.I
// Created by: drose (04Jun07)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) Carnegie Mellon University. All rights reserved.
//
// All use of this software is subject to the terms of the revised BSD
// license. You should have received a copy of this license along
// with this source code in a file named "LICENSE."
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_ram_class
// Access: Published
// Description: Returns the current ram class of the array. If this
// is other than RC_resident, the array data is not
// resident in memory.
////////////////////////////////////////////////////////////////////
INLINE VertexDataPage::RamClass VertexDataPage::
get_ram_class() const {
MutexHolder holder(_lock);
return _ram_class;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_pending_ram_class
// Access: Published
// Description: Returns the pending ram class of the array. If this
// is different from get_ram_class(), this page has been
// queued to be processed by the thread. Eventually the
// page will be set to this ram class.
////////////////////////////////////////////////////////////////////
INLINE VertexDataPage::RamClass VertexDataPage::
get_pending_ram_class() const {
MutexHolder holder(_lock);
return _pending_ram_class;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::request_resident
// Access: Published
// Description: Ensures that the page will become resident soon.
// Future calls to get_page_data() will eventually
// return non-NULL.
////////////////////////////////////////////////////////////////////
INLINE void VertexDataPage::
request_resident() {
MutexHolder holder(_lock);
if (_ram_class != RC_resident) {
request_ram_class(RC_resident);
}
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::alloc
// Access: Published
// Description: Allocates a new block. Returns NULL if a block of the
// requested size cannot be allocated.
//
// To free the allocated block, call block->free(), or
// simply delete the block pointer.
////////////////////////////////////////////////////////////////////
INLINE VertexDataBlock *VertexDataPage::
alloc(size_t size) {
MutexHolder holder(_lock);
return do_alloc(size);
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_first_block
// Access: Published
// Description: Returns a pointer to the first allocated block, or
// NULL if there are no allocated blocks.
////////////////////////////////////////////////////////////////////
INLINE VertexDataBlock *VertexDataPage::
get_first_block() const {
MutexHolder holder(_lock);
return (VertexDataBlock *)SimpleAllocator::get_first_block();
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_book
// Access: Published
// Description: Returns a pointer to the book that owns this page.
////////////////////////////////////////////////////////////////////
INLINE VertexDataBook *VertexDataPage::
get_book() const {
return _book;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_global_lru
// Access: Published, Static
// Description: Returns a pointer to the global LRU object that
// manages the VertexDataPage's with the indicated
// RamClass.
////////////////////////////////////////////////////////////////////
INLINE SimpleLru *VertexDataPage::
get_global_lru(RamClass rclass) {
nassertr(rclass >= 0 && rclass < RC_end_of_list, NULL);
return _global_lru[rclass];
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_pending_lru
// Access: Published, Static
// Description: Returns a pointer to the global LRU object that
// manages the VertexDataPage's that are pending
// processing by the thread.
////////////////////////////////////////////////////////////////////
INLINE SimpleLru *VertexDataPage::
get_pending_lru() {
return &_pending_lru;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_save_file
// Access: Published, Static
// Description: Returns the global VertexDataSaveFile that will be
// used to save vertex data buffers to disk when
// necessary.
////////////////////////////////////////////////////////////////////
INLINE VertexDataSaveFile *VertexDataPage::
get_save_file() {
if (_save_file == (VertexDataSaveFile *)NULL) {
make_save_file();
}
return _save_file;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::save_to_disk
// Access: Published
// Description: Writes the page to disk, but does not evict it from
// memory or affect its LRU status. If it gets evicted
// later without having been modified, it will not need
// to write itself to disk again.
////////////////////////////////////////////////////////////////////
INLINE bool VertexDataPage::
save_to_disk() {
MutexHolder holder(_lock);
return do_save_to_disk();
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_num_threads
// Access: Published, Static
// Description: Returns the number of threads that have been spawned
// to service vertex paging requests, or 0 if no threads
// have been spawned (which may mean either that all
// paging requests will be handled by the main thread,
// or simply that no paging requests have yet been
// issued).
////////////////////////////////////////////////////////////////////
INLINE int VertexDataPage::
get_num_threads() {
MutexHolder holder(_tlock);
if (_thread_mgr == (PageThreadManager *)NULL) {
return 0;
}
return _thread_mgr->get_num_threads();
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_num_pending_reads
// Access: Published, Static
// Description: Returns the number of read requests that are waiting
// to be serviced by a thread.
////////////////////////////////////////////////////////////////////
INLINE int VertexDataPage::
get_num_pending_reads() {
MutexHolder holder(_tlock);
if (_thread_mgr == (PageThreadManager *)NULL) {
return 0;
}
return _thread_mgr->get_num_pending_reads();
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_num_pending_writes
// Access: Published, Static
// Description: Returns the number of write requests that are waiting
// to be serviced by a thread.
////////////////////////////////////////////////////////////////////
INLINE int VertexDataPage::
get_num_pending_writes() {
MutexHolder holder(_tlock);
if (_thread_mgr == (PageThreadManager *)NULL) {
return 0;
}
return _thread_mgr->get_num_pending_writes();
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::get_page_data
// Access: Public
// Description: Returns a pointer to the page's data area, or NULL if
// the page is not currently resident. If the page is
// not currently resident, this will implicitly request
// it to become resident soon.
//
// If force is true, this method will never return NULL,
// but may block until the page is available.
////////////////////////////////////////////////////////////////////
INLINE unsigned char *VertexDataPage::
get_page_data(bool force) {
MutexHolder holder(_lock);
if (_ram_class != RC_resident || _pending_ram_class != RC_resident) {
if (force) {
make_resident_now();
} else {
request_ram_class(RC_resident);
if (_ram_class != RC_resident) {
return NULL;
}
}
}
mark_used_lru();
nassertr(_size == _uncompressed_size, _page_data);
return _page_data;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::operator
// Access: Public
// Description: This comparison method is used to order pages within
// a book.
////////////////////////////////////////////////////////////////////
INLINE bool VertexDataPage::
operator < (const VertexDataPage &other) const {
// We sort pages so that the pages with the smallest number of
// available contiguous bytes come up first. We store our best
// estimate of continguous bytes here.
if (_book_size != other._book_size) {
return _book_size < other._book_size;
}
// For pages of equal size, we sort based on pointers, to make it
// easy to quickly find a specific page.
return this < &other;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::set_ram_class
// Access: Private
// Description: Puts the data in a new ram class. Assumes the page
// lock is already held.
////////////////////////////////////////////////////////////////////
INLINE void VertexDataPage::
set_ram_class(RamClass rclass) {
_ram_class = rclass;
mark_used_lru(_global_lru[rclass]);
// Changing the ram class might make our effective available space 0
// and thereby change the placement within the book.
adjust_book_size();
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataPage::round_up
// Access: Private
// Description: Round page_size up to the next multiple of
// _block_size.
////////////////////////////////////////////////////////////////////
INLINE size_t VertexDataPage::
round_up(size_t page_size) const {
return ((page_size + _block_size - 1) / _block_size) * _block_size;
}