open_toontown_panda3d/panda/src/gobj/vertexDataBuffer.cxx

175 lines
6.1 KiB
C++

// Filename: vertexDataBuffer.cxx
// Created by: drose (14May07)
//
////////////////////////////////////////////////////////////////////
//
// 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 "vertexDataBuffer.h"
#include "pStatTimer.h"
TypeHandle VertexDataBuffer::_type_handle;
////////////////////////////////////////////////////////////////////
// Function: VertexDataBuffer::Copy Assignment Operator
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
void VertexDataBuffer::
operator = (const VertexDataBuffer &copy) {
MutexHolder holder(_lock);
MutexHolder holder2(copy._lock);
if (_resident_data != (unsigned char *)NULL) {
nassertv(_size != 0);
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_size);
free(_resident_data);
_resident_data = NULL;
}
if (copy._resident_data != (unsigned char *)NULL) {
nassertv(copy._size != 0);
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)copy._size);
_resident_data = (unsigned char *)malloc(copy._size);
memcpy(_resident_data, copy._resident_data, copy._size);
}
_size = copy._size;
_block = copy._block;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBuffer::do_clean_realloc
// Access: Private
// Description: Changes the size of the buffer, preserving its data
// (except for any data beyond the new end of the
// buffer, if the buffer is being reduced). If the
// buffer is expanded, the new data is uninitialized.
//
// Assumes the lock is already held.
////////////////////////////////////////////////////////////////////
void VertexDataBuffer::
do_clean_realloc(size_t size) {
if (size != _size) {
if (size == 0) {
do_unclean_realloc(size);
return;
}
// Page in if we're currently paged out.
if (_size != 0 && _resident_data == (unsigned char *)NULL) {
do_page_in();
}
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)size - (int)_size);
if (_size == 0) {
nassertv(_resident_data == (unsigned char *)NULL);
_resident_data = (unsigned char *)malloc(size);
} else {
nassertv(_resident_data != (unsigned char *)NULL);
_resident_data = (unsigned char *)realloc(_resident_data, size);
}
nassertv(_resident_data != (unsigned char *)NULL);
_size = size;
}
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBuffer::do_unclean_realloc
// Access: Private
// Description: Changes the size of the buffer, without regard to
// preserving its data. The buffer may contain random
// data after this call.
//
// Assumes the lock is already held.
////////////////////////////////////////////////////////////////////
void VertexDataBuffer::
do_unclean_realloc(size_t size) {
if (size != _size || _resident_data == (unsigned char *)NULL) {
// If we're paged out, discard the page.
_block = NULL;
if (_resident_data != (unsigned char *)NULL) {
nassertv(_size != 0);
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_size);
free(_resident_data);
_resident_data = NULL;
_size = 0;
}
if (size != 0) {
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)size);
nassertv(_resident_data == (unsigned char *)NULL);
_resident_data = (unsigned char *)malloc(size);
}
_size = size;
}
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBuffer::do_page_out
// Access: Private
// Description: Moves the buffer out of independent memory and puts
// it on a page in the indicated book. The buffer may
// still be directly accessible as long as its page
// remains resident. Any subsequent attempt to rewrite
// the buffer will implicitly move it off of the page
// and back into independent memory.
//
// Assumes the lock is already held.
////////////////////////////////////////////////////////////////////
void VertexDataBuffer::
do_page_out(VertexDataBook &book) {
if (_block != (VertexDataBlock *)NULL || _size == 0) {
// We're already paged out.
return;
}
nassertv(_resident_data != (unsigned char *)NULL);
_block = book.alloc(_size);
nassertv(_block != (VertexDataBlock *)NULL);
unsigned char *pointer = _block->get_pointer(true);
nassertv(pointer != (unsigned char *)NULL);
memcpy(pointer, _resident_data, _size);
get_class_type().dec_memory_usage(TypeHandle::MC_array, (int)_size);
free(_resident_data);
_resident_data = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: VertexDataBuffer::do_page_in
// Access: Private
// Description: Moves the buffer off of its current page and into
// independent memory. If the page is not already
// resident, it is forced resident first.
//
// Assumes the lock is already held.
////////////////////////////////////////////////////////////////////
void VertexDataBuffer::
do_page_in() {
if (_resident_data != (unsigned char *)NULL || _size == 0) {
// We're already paged in.
return;
}
nassertv(_block != (VertexDataBlock *)NULL);
get_class_type().inc_memory_usage(TypeHandle::MC_array, (int)_size);
_resident_data = (unsigned char *)malloc(_size);
nassertv(_resident_data != (unsigned char *)NULL);
memcpy(_resident_data, _block->get_pointer(true), _size);
}