First pass at memory-managed vertices. Might break threaded code.
This commit is contained in:
parent
ad4aa44a6b
commit
b943c36fae
|
|
@ -43,6 +43,7 @@
|
|||
#include "objectDeletor.h"
|
||||
#include "bamCache.h"
|
||||
#include "cullableObject.h"
|
||||
#include "geomVertexArrayData.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
|
|
@ -75,6 +76,12 @@ PStatCollector GraphicsEngine::_cyclers_pcollector("PipelineCyclers");
|
|||
PStatCollector GraphicsEngine::_dirty_cyclers_pcollector("Dirty PipelineCyclers");
|
||||
PStatCollector GraphicsEngine::_delete_pcollector("App:Delete");
|
||||
|
||||
|
||||
PStatCollector GraphicsEngine::_sw_sprites_pcollector("SW Sprites");
|
||||
PStatCollector GraphicsEngine::_vertex_data_resident_pcollector("Vertex Data:Resident");
|
||||
PStatCollector GraphicsEngine::_vertex_data_compressed_pcollector("Vertex Data:Compressed");
|
||||
PStatCollector GraphicsEngine::_vertex_data_disk_pcollector("Vertex Data:Disk");
|
||||
|
||||
// These are counted independently by the collision system; we
|
||||
// redefine them here so we can reset them at each frame.
|
||||
PStatCollector GraphicsEngine::_cnode_volume_pcollector("Collision Volumes:CollisionNode");
|
||||
|
|
@ -95,7 +102,6 @@ PStatCollector GraphicsEngine::_volume_inv_sphere_pcollector("Collision Volumes:
|
|||
PStatCollector GraphicsEngine::_test_inv_sphere_pcollector("Collision Tests:CollisionInvSphere");
|
||||
PStatCollector GraphicsEngine::_volume_geom_pcollector("Collision Volumes:CollisionGeom");
|
||||
PStatCollector GraphicsEngine::_test_geom_pcollector("Collision Tests:CollisionGeom");
|
||||
PStatCollector GraphicsEngine::_sw_sprites_pcollector("SW Sprites");
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GraphicsEngine::Constructor
|
||||
|
|
@ -672,6 +678,8 @@ render_frame() {
|
|||
PStatTimer timer(_delete_pcollector, current_thread);
|
||||
deletor->flush();
|
||||
}
|
||||
|
||||
GeomVertexArrayData::lru_epoch();
|
||||
|
||||
GeomCacheManager::flush_level();
|
||||
CullTraverser::flush_level();
|
||||
|
|
@ -714,6 +722,11 @@ render_frame() {
|
|||
_render_states_unused_pcollector.set_level(RenderState::get_num_unused_states());
|
||||
}
|
||||
|
||||
_sw_sprites_pcollector.clear_level();
|
||||
_vertex_data_resident_pcollector.set_level(GeomVertexArrayData::get_global_lru(GeomVertexArrayData::RC_resident)->get_total_size());
|
||||
_vertex_data_compressed_pcollector.set_level(GeomVertexArrayData::get_global_lru(GeomVertexArrayData::RC_compressed)->get_total_size());
|
||||
_vertex_data_disk_pcollector.set_level(GeomVertexArrayData::get_global_lru(GeomVertexArrayData::RC_disk)->get_total_size());
|
||||
|
||||
_cnode_volume_pcollector.clear_level();
|
||||
_gnode_volume_pcollector.clear_level();
|
||||
_geom_volume_pcollector.clear_level();
|
||||
|
|
@ -732,7 +745,6 @@ render_frame() {
|
|||
_test_inv_sphere_pcollector.clear_level();
|
||||
_volume_geom_pcollector.clear_level();
|
||||
_test_geom_pcollector.clear_level();
|
||||
_sw_sprites_pcollector.clear_level();
|
||||
|
||||
#endif // DO_PSTATS
|
||||
|
||||
|
|
|
|||
|
|
@ -359,6 +359,11 @@ private:
|
|||
static PStatCollector _dirty_cyclers_pcollector;
|
||||
static PStatCollector _delete_pcollector;
|
||||
|
||||
static PStatCollector _sw_sprites_pcollector;
|
||||
static PStatCollector _vertex_data_resident_pcollector;
|
||||
static PStatCollector _vertex_data_compressed_pcollector;
|
||||
static PStatCollector _vertex_data_disk_pcollector;
|
||||
|
||||
static PStatCollector _cnode_volume_pcollector;
|
||||
static PStatCollector _gnode_volume_pcollector;
|
||||
static PStatCollector _geom_volume_pcollector;
|
||||
|
|
@ -377,7 +382,6 @@ private:
|
|||
static PStatCollector _test_inv_sphere_pcollector;
|
||||
static PStatCollector _volume_geom_pcollector;
|
||||
static PStatCollector _test_geom_pcollector;
|
||||
static PStatCollector _sw_sprites_pcollector;
|
||||
|
||||
friend class WindowRenderer;
|
||||
friend class GraphicsOutput;
|
||||
|
|
|
|||
|
|
@ -305,7 +305,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXGraphicsStateGuardian8::
|
||||
apply_vertex_buffer(VertexBufferContext *vbc,
|
||||
const GeomVertexArrayDataPipelineReader *reader) {
|
||||
const GeomVertexArrayDataHandle *reader) {
|
||||
DXVertexBufferContext8 *dvbc = DCAST(DXVertexBufferContext8, vbc);
|
||||
|
||||
if (dvbc->_vbuffer == NULL) {
|
||||
|
|
@ -807,7 +807,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
const GeomVertexFormat *format = _data_reader->get_format();
|
||||
|
||||
// The munger should have put the FVF data in the first array.
|
||||
const GeomVertexArrayDataPipelineReader *data = _data_reader->get_array_reader(0);
|
||||
const GeomVertexArrayDataHandle *data = _data_reader->get_array_reader(0);
|
||||
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, false);
|
||||
|
|
@ -930,9 +930,9 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
|||
(D3DPT_TRIANGLELIST,
|
||||
min_vertex, max_vertex,
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
reader->get_pointer(),
|
||||
index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -949,7 +949,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
|||
draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -990,8 +990,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
(D3DPT_TRIANGLESTRIP,
|
||||
min_vertex, max_vertex,
|
||||
reader->get_num_vertices() - 2,
|
||||
reader->get_data(), index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
reader->get_pointer(), index_type,
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1008,7 +1008,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
reader->get_num_vertices() - 2,
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -1050,9 +1050,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Indexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
const unsigned char *vertices = reader->get_pointer();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1087,7 +1087,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Nonindexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1150,9 +1150,9 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
const unsigned char *vertices = reader->get_pointer();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1187,7 +1187,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1238,9 +1238,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader) {
|
|||
(D3DPT_LINELIST,
|
||||
min_vertex, max_vertex,
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
reader->get_pointer(),
|
||||
index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1256,7 +1256,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) {
|
|||
draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -1299,7 +1299,7 @@ draw_points(const GeomPrimitivePipelineReader *reader) {
|
|||
draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public:
|
|||
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
||||
void apply_vertex_buffer(VertexBufferContext *vbc,
|
||||
const GeomVertexArrayDataPipelineReader *reader);
|
||||
const GeomVertexArrayDataHandle *reader);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ upload_data(const GeomPrimitivePipelineReader *reader) {
|
|||
}
|
||||
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
|
||||
memcpy(local_pointer, reader->get_data(), data_size);
|
||||
memcpy(local_pointer, reader->get_pointer(), data_size);
|
||||
|
||||
_ibuffer->Unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ DXVertexBufferContext8::
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXVertexBufferContext8::
|
||||
create_vbuffer(DXScreenData &scrn,
|
||||
const GeomVertexArrayDataPipelineReader *reader) {
|
||||
const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(reader->get_object() == get_data());
|
||||
Thread *current_thread = reader->get_current_thread();
|
||||
|
||||
|
|
@ -232,7 +232,7 @@ create_vbuffer(DXScreenData &scrn,
|
|||
// DirectX.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXVertexBufferContext8::
|
||||
upload_data(const GeomVertexArrayDataPipelineReader *reader) {
|
||||
upload_data(const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(reader->get_object() == get_data());
|
||||
nassertv(_vbuffer != NULL);
|
||||
Thread *current_thread = reader->get_current_thread();
|
||||
|
|
@ -257,7 +257,7 @@ upload_data(const GeomVertexArrayDataPipelineReader *reader) {
|
|||
}
|
||||
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
|
||||
memcpy(local_pointer, reader->get_data(), data_size);
|
||||
memcpy(local_pointer, reader->get_pointer(), data_size);
|
||||
|
||||
_vbuffer->Unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ public:
|
|||
virtual ~DXVertexBufferContext8();
|
||||
|
||||
void create_vbuffer(DXScreenData &scrn,
|
||||
const GeomVertexArrayDataPipelineReader *reader);
|
||||
void upload_data(const GeomVertexArrayDataPipelineReader *reader);
|
||||
const GeomVertexArrayDataHandle *reader);
|
||||
void upload_data(const GeomVertexArrayDataHandle *reader);
|
||||
|
||||
IDirect3DVertexBuffer8 *_vbuffer;
|
||||
int _fvf;
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
|
|||
void DXGraphicsStateGuardian9::
|
||||
apply_vertex_buffer(VertexBufferContext *vbc,
|
||||
CLP(ShaderContext) *shader_context,
|
||||
const GeomVertexArrayDataPipelineReader *reader) {
|
||||
const GeomVertexArrayDataHandle *reader) {
|
||||
DXVertexBufferContext9 *dvbc = DCAST(DXVertexBufferContext9, vbc);
|
||||
|
||||
DBG_SH3 dxgsg9_cat.debug ( ) << "apply_vertex_buffer\n"; DBG_E
|
||||
|
|
@ -1186,7 +1186,7 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
|
|||
_vertex_array_shader_context = _current_shader_context;
|
||||
|
||||
const GeomVertexFormat *format = _data_reader->get_format ( );
|
||||
const GeomVertexArrayDataPipelineReader *data;
|
||||
const GeomVertexArrayDataHandle *data;
|
||||
int number_of_arrays = _data_reader -> get_num_arrays ( );
|
||||
|
||||
if (_current_shader_context && number_of_arrays > 1) {
|
||||
|
|
@ -1422,9 +1422,9 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
|||
(D3DPT_TRIANGLELIST,
|
||||
min_vertex, max_vertex,
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
reader->get_pointer(),
|
||||
index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1446,7 +1446,7 @@ draw_triangles(const GeomPrimitivePipelineReader *reader) {
|
|||
draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -1497,8 +1497,8 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
(D3DPT_TRIANGLESTRIP,
|
||||
min_vertex, max_vertex,
|
||||
reader->get_num_vertices() - 2,
|
||||
reader->get_data(), index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
reader->get_pointer(), index_type,
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1518,7 +1518,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
reader->get_num_vertices() - 2,
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -1561,9 +1561,9 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Indexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
const unsigned char *vertices = reader->get_pointer();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1598,7 +1598,7 @@ draw_tristrips(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Nonindexed, client arrays, individual triangle strips.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1664,9 +1664,9 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Indexed, client arrays.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
CPTA_uchar vertices = reader->get_data();
|
||||
const unsigned char *vertices = reader->get_pointer();
|
||||
D3DFORMAT index_type = get_index_type(reader->get_index_type());
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1701,7 +1701,7 @@ draw_trifans(const GeomPrimitivePipelineReader *reader) {
|
|||
|
||||
} else {
|
||||
// Nonindexed, client arrays.
|
||||
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
|
||||
const unsigned char *array_data = _data_reader->get_array_reader(0)->get_pointer();
|
||||
int stride = _data_reader->get_format()->get_array(0)->get_stride();
|
||||
|
||||
unsigned int start = 0;
|
||||
|
|
@ -1753,9 +1753,9 @@ draw_lines(const GeomPrimitivePipelineReader *reader) {
|
|||
(D3DPT_LINELIST,
|
||||
min_vertex, max_vertex,
|
||||
reader->get_num_primitives(),
|
||||
reader->get_data(),
|
||||
reader->get_pointer(),
|
||||
index_type,
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
} else {
|
||||
|
|
@ -1771,7 +1771,7 @@ draw_lines(const GeomPrimitivePipelineReader *reader) {
|
|||
draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -1814,7 +1814,7 @@ draw_points(const GeomPrimitivePipelineReader *reader) {
|
|||
draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
|
||||
reader->get_first_vertex(),
|
||||
reader->get_num_vertices(),
|
||||
_data_reader->get_array_reader(0)->get_data(),
|
||||
_data_reader->get_array_reader(0)->get_pointer(),
|
||||
_data_reader->get_format()->get_array(0)->get_stride());
|
||||
}
|
||||
}
|
||||
|
|
@ -2220,11 +2220,11 @@ bool vertex_buffer_page_in_function (LruPage *lru_page)
|
|||
|
||||
// allocate vertex buffer
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
GeomVertexArrayDataPipelineReader reader(vertex_buffer->get_data(), current_thread);
|
||||
vertex_buffer -> allocate_vbuffer (*(gsg->_screen), &reader);
|
||||
CPT(GeomVertexArrayDataHandle) reader = vertex_buffer->get_data()->get_handle(current_thread);
|
||||
vertex_buffer -> allocate_vbuffer (*(gsg->_screen), reader);
|
||||
|
||||
// update vertex buffer
|
||||
vertex_buffer -> upload_data(&reader);
|
||||
vertex_buffer -> upload_data(reader);
|
||||
vertex_buffer -> set_resident(true);
|
||||
|
||||
if (DEBUG_LRU && dxgsg9_cat.is_debug())
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public:
|
|||
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
||||
void apply_vertex_buffer(VertexBufferContext *vbc, CLP(ShaderContext) *shader_context,
|
||||
const GeomVertexArrayDataPipelineReader *reader);
|
||||
const GeomVertexArrayDataHandle *reader);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
|
||||
|
|
|
|||
|
|
@ -237,7 +237,7 @@ upload_data(const GeomPrimitivePipelineReader *reader) {
|
|||
}
|
||||
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
|
||||
memcpy(local_pointer, reader->get_data(), data_size);
|
||||
memcpy(local_pointer, reader->get_pointer(), data_size);
|
||||
|
||||
_ibuffer->Unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -459,7 +459,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
|
|||
{
|
||||
if (_vertex_element_array == 0) {
|
||||
bool error;
|
||||
const GeomVertexArrayDataPipelineReader *array_reader;
|
||||
const GeomVertexArrayDataHandle *array_reader;
|
||||
Geom::NumericType numeric_type;
|
||||
int start, stride, num_values;
|
||||
int nvarying = _expansion->_var_spec.size();
|
||||
|
|
|
|||
|
|
@ -341,7 +341,7 @@ free_vbuffer(void) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXVertexBufferContext9::
|
||||
allocate_vbuffer(DXScreenData &scrn,
|
||||
const GeomVertexArrayDataPipelineReader *reader) {
|
||||
const GeomVertexArrayDataHandle *reader) {
|
||||
|
||||
int data_size;
|
||||
HRESULT hr;
|
||||
|
|
@ -393,7 +393,7 @@ allocate_vbuffer(DXScreenData &scrn,
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void DXVertexBufferContext9::
|
||||
create_vbuffer(DXScreenData &scrn,
|
||||
const GeomVertexArrayDataPipelineReader *reader) {
|
||||
const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(reader->get_object() == get_data());
|
||||
Thread *current_thread = reader->get_current_thread();
|
||||
|
||||
|
|
@ -442,7 +442,7 @@ create_vbuffer(DXScreenData &scrn,
|
|||
// DirectX.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void DXVertexBufferContext9::
|
||||
upload_data(const GeomVertexArrayDataPipelineReader *reader) {
|
||||
upload_data(const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(reader->get_object() == get_data());
|
||||
nassertv(_vbuffer != NULL);
|
||||
Thread *current_thread = reader->get_current_thread();
|
||||
|
|
@ -473,7 +473,7 @@ upload_data(const GeomVertexArrayDataPipelineReader *reader) {
|
|||
}
|
||||
|
||||
GraphicsStateGuardian::_data_transferred_pcollector.add_level(data_size);
|
||||
memcpy(local_pointer, reader->get_data(), data_size);
|
||||
memcpy(local_pointer, reader->get_pointer(), data_size);
|
||||
|
||||
_vbuffer->Unlock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,9 +34,9 @@ public:
|
|||
virtual ~DXVertexBufferContext9();
|
||||
|
||||
void free_vbuffer();
|
||||
void allocate_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataPipelineReader *reader);
|
||||
void create_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataPipelineReader *reader);
|
||||
void upload_data(const GeomVertexArrayDataPipelineReader *reader);
|
||||
void allocate_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader);
|
||||
void create_vbuffer(DXScreenData &scrn, const GeomVertexArrayDataHandle *reader);
|
||||
void upload_data(const GeomVertexArrayDataHandle *reader);
|
||||
|
||||
IDirect3DVertexBuffer9 *_vbuffer;
|
||||
int _fvf;
|
||||
|
|
|
|||
|
|
@ -1782,7 +1782,7 @@ update_standard_vertex_arrays() {
|
|||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
// We may use vertex arrays or buffers to render primitives.
|
||||
const GeomVertexArrayDataPipelineReader *array_reader;
|
||||
const GeomVertexArrayDataHandle *array_reader;
|
||||
int num_values;
|
||||
Geom::NumericType numeric_type;
|
||||
int start;
|
||||
|
|
@ -2697,7 +2697,7 @@ prepare_vertex_buffer(GeomVertexArrayData *data) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void CLP(GraphicsStateGuardian)::
|
||||
apply_vertex_buffer(VertexBufferContext *vbc,
|
||||
const GeomVertexArrayDataPipelineReader *reader) {
|
||||
const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(_supports_buffers);
|
||||
nassertv(reader->get_modified() != UpdateSeq::initial());
|
||||
|
||||
|
|
@ -2724,12 +2724,12 @@ apply_vertex_buffer(VertexBufferContext *vbc,
|
|||
if (num_bytes != 0) {
|
||||
if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) {
|
||||
_glBufferData(GL_ARRAY_BUFFER, num_bytes,
|
||||
reader->get_data(),
|
||||
reader->get_pointer(),
|
||||
get_usage(reader->get_usage_hint()));
|
||||
|
||||
} else {
|
||||
_glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes,
|
||||
reader->get_data());
|
||||
reader->get_pointer());
|
||||
}
|
||||
_data_transferred_pcollector.add_level(num_bytes);
|
||||
}
|
||||
|
|
@ -2795,10 +2795,10 @@ release_vertex_buffer(VertexBufferContext *vbc) {
|
|||
// in client memory, that is, the data array passed in.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
const unsigned char *CLP(GraphicsStateGuardian)::
|
||||
setup_array_data(const GeomVertexArrayDataPipelineReader *array_reader) {
|
||||
setup_array_data(const GeomVertexArrayDataHandle *array_reader) {
|
||||
if (!_supports_buffers) {
|
||||
// No support for buffer objects; always render from client.
|
||||
return array_reader->get_data();
|
||||
return array_reader->get_pointer();
|
||||
}
|
||||
if (!vertex_buffers || _geom_display_list != 0 ||
|
||||
array_reader->get_usage_hint() == Geom::UH_client) {
|
||||
|
|
@ -2812,12 +2812,12 @@ setup_array_data(const GeomVertexArrayDataPipelineReader *array_reader) {
|
|||
_glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
_current_vbuffer_index = 0;
|
||||
}
|
||||
return array_reader->get_data();
|
||||
return array_reader->get_pointer();
|
||||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_data());
|
||||
nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_pointer());
|
||||
apply_vertex_buffer(vbc, array_reader);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer object.
|
||||
|
|
@ -2884,6 +2884,7 @@ apply_index_buffer(IndexBufferContext *ibc,
|
|||
|
||||
if (gibc->was_modified(reader)) {
|
||||
PStatTimer timer(_load_index_buffer_pcollector, reader->get_current_thread());
|
||||
|
||||
int num_bytes = reader->get_data_size_bytes();
|
||||
if (GLCAT.is_spam()) {
|
||||
GLCAT.spam()
|
||||
|
|
@ -2893,12 +2894,12 @@ apply_index_buffer(IndexBufferContext *ibc,
|
|||
if (num_bytes != 0) {
|
||||
if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) {
|
||||
_glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes,
|
||||
reader->get_data(),
|
||||
reader->get_pointer(),
|
||||
get_usage(reader->get_usage_hint()));
|
||||
|
||||
} else {
|
||||
_glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
|
||||
reader->get_data());
|
||||
reader->get_pointer());
|
||||
}
|
||||
_data_transferred_pcollector.add_level(num_bytes);
|
||||
}
|
||||
|
|
@ -2966,7 +2967,7 @@ const unsigned char *CLP(GraphicsStateGuardian)::
|
|||
setup_primitive(const GeomPrimitivePipelineReader *reader) {
|
||||
if (!_supports_buffers) {
|
||||
// No support for buffer objects; always render from client.
|
||||
return reader->get_data();
|
||||
return reader->get_pointer();
|
||||
}
|
||||
if (!vertex_buffers || _geom_display_list != 0 ||
|
||||
reader->get_usage_hint() == Geom::UH_client) {
|
||||
|
|
@ -2980,12 +2981,12 @@ setup_primitive(const GeomPrimitivePipelineReader *reader) {
|
|||
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
_current_ibuffer_index = 0;
|
||||
}
|
||||
return reader->get_data();
|
||||
return reader->get_pointer();
|
||||
}
|
||||
|
||||
// Prepare the buffer object and bind it.
|
||||
IndexBufferContext *ibc = ((GeomPrimitive *)reader->get_object())->prepare_now(get_prepared_objects(), this);
|
||||
nassertr(ibc != (IndexBufferContext *)NULL, reader->get_data());
|
||||
nassertr(ibc != (IndexBufferContext *)NULL, reader->get_pointer());
|
||||
apply_index_buffer(ibc, reader);
|
||||
|
||||
// NULL is the OpenGL convention for the first byte of the buffer object.
|
||||
|
|
|
|||
|
|
@ -131,9 +131,9 @@ public:
|
|||
|
||||
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
|
||||
void apply_vertex_buffer(VertexBufferContext *vbc,
|
||||
const GeomVertexArrayDataPipelineReader *reader);
|
||||
const GeomVertexArrayDataHandle *reader);
|
||||
virtual void release_vertex_buffer(VertexBufferContext *vbc);
|
||||
const unsigned char *setup_array_data(const GeomVertexArrayDataPipelineReader *data);
|
||||
const unsigned char *setup_array_data(const GeomVertexArrayDataHandle *data);
|
||||
|
||||
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
|
||||
void apply_index_buffer(IndexBufferContext *ibc,
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) {
|
|||
} else
|
||||
#endif // SUPPORT_IMMEDIATE_MODE
|
||||
{
|
||||
const GeomVertexArrayDataPipelineReader *array_reader;
|
||||
const GeomVertexArrayDataHandle *array_reader;
|
||||
Geom::NumericType numeric_type;
|
||||
int start, stride, num_values;
|
||||
int nvarying = _expansion->_var_spec.size();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
savedContext.I savedContext.h \
|
||||
shaderContext.h shaderContext.I \
|
||||
shaderExpansion.h shaderExpansion.I \
|
||||
simpleLru.h simpleLru.I \
|
||||
sliderTable.I sliderTable.h \
|
||||
texture.I texture.h \
|
||||
textureContext.I textureContext.h \
|
||||
|
|
@ -106,6 +107,7 @@
|
|||
savedContext.cxx \
|
||||
shaderContext.cxx \
|
||||
shaderExpansion.cxx \
|
||||
simpleLru.cxx \
|
||||
sliderTable.cxx \
|
||||
texture.cxx textureContext.cxx texturePool.cxx \
|
||||
texturePoolFilter.cxx \
|
||||
|
|
@ -162,6 +164,7 @@
|
|||
savedContext.I savedContext.h \
|
||||
shaderContext.h shaderContext.I \
|
||||
shaderExpansion.h shaderExpansion.I \
|
||||
simpleLru.h simpleLru.I \
|
||||
sliderTable.I sliderTable.h \
|
||||
texture.I texture.h \
|
||||
textureContext.I textureContext.h \
|
||||
|
|
|
|||
|
|
@ -287,8 +287,7 @@ ConfigureFn(config_gobj) {
|
|||
GeomTrifans::init_type();
|
||||
GeomTristrips::init_type();
|
||||
GeomVertexArrayData::init_type();
|
||||
GeomVertexArrayDataPipelineReader::init_type();
|
||||
GeomVertexArrayDataPipelineWriter::init_type();
|
||||
GeomVertexArrayDataHandle::init_type();
|
||||
GeomVertexArrayFormat::init_type();
|
||||
GeomVertexData::init_type();
|
||||
GeomVertexDataPipelineReader::init_type();
|
||||
|
|
|
|||
|
|
@ -223,6 +223,10 @@ offset_vertices(const GeomVertexData *data, int offset) {
|
|||
|
||||
#ifndef NDEBUG
|
||||
if (!prim->check_valid(data)) {
|
||||
gobj_cat.warning()
|
||||
<< *prim << " is invalid for " << *data << ":\n";
|
||||
prim->write(gobj_cat.warning(false), 4);
|
||||
|
||||
all_is_valid = false;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -210,6 +210,17 @@ PUBLISHED:
|
|||
AT_hardware, // Hardware-accelerated animation on the graphics card.
|
||||
};
|
||||
|
||||
// These are used to indicate the current residency state of vertex
|
||||
// data, which may or may not have been temporarily evicted to
|
||||
// satisfy memory requirements.
|
||||
enum RamClass {
|
||||
RC_resident,
|
||||
RC_compressed,
|
||||
RC_disk,
|
||||
|
||||
RC_end_of_list, // list marker; do not use
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
EXPCL_PANDA ostream &operator << (ostream &out, GeomEnums::NumericType numeric_type);
|
||||
|
|
|
|||
|
|
@ -303,18 +303,6 @@ get_index_stride() const {
|
|||
return reader.get_index_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_data
|
||||
// Access: Public
|
||||
// Description: A convenience function to return the actual data of
|
||||
// the index array.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar GeomPrimitive::
|
||||
get_data() const {
|
||||
nassertr(is_indexed(), CPTA_uchar());
|
||||
return get_vertices()->get_data();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitive::get_ends
|
||||
// Access: Public
|
||||
|
|
@ -486,8 +474,7 @@ GeomPrimitivePipelineReader(const GeomPrimitive *object,
|
|||
_cdata->ref();
|
||||
#endif // DO_PIPELINING
|
||||
if (!_cdata->_vertices.is_null()) {
|
||||
_vertices_reader =
|
||||
new GeomVertexArrayDataPipelineReader(_cdata->_vertices.get_read_pointer(), _current_thread);
|
||||
_vertices_reader = _cdata->_vertices.get_read_pointer()->get_handle();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -518,9 +505,6 @@ operator = (const GeomPrimitivePipelineReader &) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomPrimitivePipelineReader::
|
||||
~GeomPrimitivePipelineReader() {
|
||||
if (_vertices_reader != (GeomVertexArrayDataPipelineReader *)NULL) {
|
||||
delete _vertices_reader;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#endif // _DEBUG
|
||||
|
|
@ -671,19 +655,19 @@ get_index_stride() const {
|
|||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayDataPipelineReader *GeomPrimitivePipelineReader::
|
||||
INLINE const GeomVertexArrayDataHandle *GeomPrimitivePipelineReader::
|
||||
get_vertices_reader() const {
|
||||
return _vertices_reader;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomPrimitivePipelineReader::get_data
|
||||
// Function: GeomPrimitivePipelineReader::get_pointer
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar GeomPrimitivePipelineReader::
|
||||
get_data() const {
|
||||
return _vertices_reader->get_data();
|
||||
INLINE const unsigned char *GeomPrimitivePipelineReader::
|
||||
get_pointer() const {
|
||||
return _vertices_reader->get_pointer();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -1314,7 +1314,8 @@ calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
|
|||
}
|
||||
} else {
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
reader.set_row(index.get_data1i());
|
||||
int ii = index.get_data1i();
|
||||
reader.set_row(ii);
|
||||
const LVecBase3f &vertex = reader.get_data3f();
|
||||
|
||||
if (found_any) {
|
||||
|
|
|
|||
|
|
@ -158,7 +158,6 @@ public:
|
|||
void set_nonindexed_vertices(int first_vertex, int num_vertices);
|
||||
|
||||
INLINE int get_index_stride() const;
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
|
||||
INLINE CPTA_int get_ends() const;
|
||||
PTA_int modify_ends();
|
||||
|
|
@ -346,8 +345,8 @@ public:
|
|||
INLINE UpdateSeq get_modified() const;
|
||||
bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
|
||||
INLINE int get_index_stride() const;
|
||||
INLINE const GeomVertexArrayDataPipelineReader *get_vertices_reader() const;
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
INLINE const GeomVertexArrayDataHandle *get_vertices_reader() const;
|
||||
INLINE const unsigned char *get_pointer() const;
|
||||
INLINE CPTA_int get_ends() const;
|
||||
INLINE CPT(GeomVertexArrayData) get_mins() const;
|
||||
INLINE CPT(GeomVertexArrayData) get_maxs() const;
|
||||
|
|
@ -357,7 +356,7 @@ private:
|
|||
Thread *_current_thread;
|
||||
const GeomPrimitive::CData *_cdata;
|
||||
|
||||
GeomVertexArrayDataPipelineReader *_vertices_reader;
|
||||
CPT(GeomVertexArrayDataHandle) _vertices_reader;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ has_column(const InternalName *name) const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayData::
|
||||
get_num_rows() const {
|
||||
GeomVertexArrayDataPipelineReader reader(this, Thread::get_current_thread());
|
||||
return reader.get_num_rows();
|
||||
return get_handle()->get_num_rows();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -90,8 +89,7 @@ get_num_rows() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexArrayData::
|
||||
set_num_rows(int n) {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread());
|
||||
return writer.set_num_rows(n);
|
||||
return modify_handle()->set_num_rows(n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -109,8 +107,7 @@ set_num_rows(int n) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool GeomVertexArrayData::
|
||||
unclean_set_num_rows(int n) {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread());
|
||||
return writer.unclean_set_num_rows(n);
|
||||
return modify_handle()->unclean_set_num_rows(n);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -121,7 +118,7 @@ unclean_set_num_rows(int n) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayData::
|
||||
clear_rows() {
|
||||
set_data(PTA_uchar(GeomVertexArrayData::get_class_type()));
|
||||
return modify_handle()->clear_rows();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -132,7 +129,7 @@ clear_rows() {
|
|||
INLINE int GeomVertexArrayData::
|
||||
get_data_size_bytes() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_data.size();
|
||||
return cdata->_data_full_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -149,49 +146,71 @@ get_modified() const {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::get_data
|
||||
// Function: GeomVertexArrayData::get_handle
|
||||
// Access: Published
|
||||
// Description: Returns a const pointer to the actual vertex data,
|
||||
// for application code to directly examine (but not
|
||||
// modify).
|
||||
// Description: Returns an object that can be used to read the actual
|
||||
// data bytes stored in the array. Calling this method
|
||||
// locks the data, and will block any other threads
|
||||
// attempting to read or write the data, until the
|
||||
// returned object destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar GeomVertexArrayData::
|
||||
get_data() const {
|
||||
CDReader cdata(_cycler);
|
||||
return cdata->_data;
|
||||
INLINE CPT(GeomVertexArrayDataHandle) GeomVertexArrayData::
|
||||
get_handle(Thread *current_thread) const {
|
||||
return new GeomVertexArrayDataHandle(this, current_thread,
|
||||
_cycler.read_unlocked(current_thread),
|
||||
false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::modify_data
|
||||
// Function: GeomVertexArrayData::modify_handle
|
||||
// Access: Published
|
||||
// Description: Returns a modifiable pointer to the actual vertex
|
||||
// array, so that application code may directly
|
||||
// manipulate it. Use with caution.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
// Description: Returns an object that can be used to read or write
|
||||
// the actual data bytes stored in the array. Calling
|
||||
// this method locks the data, and will block any other
|
||||
// threads attempting to read or write the data, until
|
||||
// the returned object destructs.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PTA_uchar GeomVertexArrayData::
|
||||
modify_data() {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread());
|
||||
return writer.modify_data();
|
||||
INLINE PT(GeomVertexArrayDataHandle) GeomVertexArrayData::
|
||||
modify_handle(Thread *current_thread) {
|
||||
return new GeomVertexArrayDataHandle(this, current_thread,
|
||||
_cycler.write_upstream(true, current_thread),
|
||||
true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_data
|
||||
// Function: GeomVertexArrayData::get_ram_class
|
||||
// Access: Published
|
||||
// Description: Replaces the vertex data array with a completely new
|
||||
// array.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
// have recently made in an upstream thread.
|
||||
// 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 GeomVertexArrayData::RamClass GeomVertexArrayData::
|
||||
get_ram_class() const {
|
||||
return _ram_class;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::get_global_lru
|
||||
// Access: Published, Static
|
||||
// Description: Returns a pointer to the global LRU object that
|
||||
// manages the GeomVertexArrayData's with the indicated
|
||||
// RamClass.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleLru *GeomVertexArrayData::
|
||||
get_global_lru(RamClass rclass) {
|
||||
nassertr(rclass >= 0 && rclass < RC_end_of_list, NULL);
|
||||
return &_global_lru[rclass];
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::set_ram_class
|
||||
// Access: Private
|
||||
// Description: Puts the data in a new ram class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayData::
|
||||
set_data(CPTA_uchar array) {
|
||||
GeomVertexArrayDataPipelineWriter writer(this, true, Thread::get_current_thread());
|
||||
writer.set_data(array);
|
||||
set_ram_class(RamClass rclass) {
|
||||
_ram_class = rclass;
|
||||
mark_used_lru(&_global_lru[rclass]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -202,9 +221,9 @@ set_data(CPTA_uchar array) {
|
|||
INLINE GeomVertexArrayData::CData::
|
||||
CData() :
|
||||
_usage_hint(UH_unspecified),
|
||||
_data(GeomVertexArrayData::get_class_type())
|
||||
_data(GeomVertexArrayData::get_class_type()),
|
||||
_data_full_size(0)
|
||||
{
|
||||
_data.node_ref();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -215,24 +234,41 @@ CData() :
|
|||
INLINE GeomVertexArrayData::CData::
|
||||
CData(const GeomVertexArrayData::CData ©) :
|
||||
_usage_hint(copy._usage_hint),
|
||||
_data(copy._data),
|
||||
_data(GeomVertexArrayData::get_class_type()),
|
||||
_data_full_size(copy._data_full_size),
|
||||
_modified(copy._modified)
|
||||
{
|
||||
_data.node_ref();
|
||||
_data.v() = copy._data.v();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::Constructor
|
||||
// Function: GeomVertexArrayData::CData::Copy Assignment
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineBase::
|
||||
GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
|
||||
Thread *current_thread,
|
||||
GeomVertexArrayData::CData *cdata) :
|
||||
_object(object),
|
||||
INLINE void GeomVertexArrayData::CData::
|
||||
operator = (const GeomVertexArrayData::CData ©) {
|
||||
_usage_hint = copy._usage_hint;
|
||||
_modified = copy._modified;
|
||||
_data.v() = copy._data.v();
|
||||
_data_full_size = copy._data_full_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataHandle::
|
||||
GeomVertexArrayDataHandle(const GeomVertexArrayData *object,
|
||||
Thread *current_thread,
|
||||
const GeomVertexArrayData::CData *cdata,
|
||||
bool writable) :
|
||||
_holder(((GeomVertexArrayData::CData *)cdata)->_rw_lock),
|
||||
_object((GeomVertexArrayData *)object),
|
||||
_current_thread(current_thread),
|
||||
_cdata(cdata)
|
||||
_cdata((GeomVertexArrayData::CData *)cdata),
|
||||
_writable(writable)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
|
|
@ -243,16 +279,42 @@ GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::Destructor
|
||||
// Function: GeomVertexArrayDataHandle::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataHandle::
|
||||
GeomVertexArrayDataHandle(const GeomVertexArrayDataHandle ©) :
|
||||
_holder(copy._cdata->_rw_lock)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayDataHandle::
|
||||
operator = (const GeomVertexArrayDataHandle &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineBase::
|
||||
~GeomVertexArrayDataPipelineBase() {
|
||||
INLINE GeomVertexArrayDataHandle::
|
||||
~GeomVertexArrayDataHandle() {
|
||||
#ifdef _DEBUG
|
||||
nassertv(_object->test_ref_count_nonzero());
|
||||
#endif // _DEBUG
|
||||
|
||||
if (_writable) {
|
||||
_object->_cycler.release_write(_cdata);
|
||||
}
|
||||
|
||||
#ifdef DO_PIPELINING
|
||||
unref_delete((CycleData *)_cdata);
|
||||
#endif // DO_PIPELINING
|
||||
|
|
@ -264,184 +326,134 @@ INLINE GeomVertexArrayDataPipelineBase::
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_current_thread
|
||||
// Function: GeomVertexArrayDataHandle::get_current_thread
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE Thread *GeomVertexArrayDataPipelineBase::
|
||||
INLINE Thread *GeomVertexArrayDataHandle::
|
||||
get_current_thread() const {
|
||||
return _current_thread;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_array_format
|
||||
// Function: GeomVertexArrayDataHandle::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomVertexArrayDataHandle::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayData *GeomVertexArrayDataHandle::
|
||||
get_object() {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::get_pointer
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the beginning of the actual data
|
||||
// stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const unsigned char *GeomVertexArrayDataHandle::
|
||||
get_pointer() const {
|
||||
check_resident();
|
||||
return _cdata->_data.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::get_pointer
|
||||
// Access: Public
|
||||
// Description: Returns a pointer to the beginning of the actual data
|
||||
// stream.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned char *GeomVertexArrayDataHandle::
|
||||
get_pointer() {
|
||||
nassertr(_writable, NULL);
|
||||
check_resident();
|
||||
return _cdata->_data.p();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::get_array_format
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayFormat *GeomVertexArrayDataPipelineBase::
|
||||
INLINE const GeomVertexArrayFormat *GeomVertexArrayDataHandle::
|
||||
get_array_format() const {
|
||||
return _object->_array_format;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_usage_hint
|
||||
// Function: GeomVertexArrayDataHandle::get_usage_hint
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineBase::UsageHint GeomVertexArrayDataPipelineBase::
|
||||
INLINE GeomVertexArrayDataHandle::UsageHint GeomVertexArrayDataHandle::
|
||||
get_usage_hint() const {
|
||||
return _cdata->_usage_hint;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_data
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE CPTA_uchar GeomVertexArrayDataPipelineBase::
|
||||
get_data() const {
|
||||
return _cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_num_rows
|
||||
// Function: GeomVertexArrayDataHandle::get_num_rows
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayDataPipelineBase::
|
||||
INLINE int GeomVertexArrayDataHandle::
|
||||
get_num_rows() const {
|
||||
return get_data_size_bytes() / _object->_array_format->get_stride();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_data_size_bytes
|
||||
// Function: GeomVertexArrayDataHandle::clear_rows
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE int GeomVertexArrayDataPipelineBase::
|
||||
get_data_size_bytes() const {
|
||||
return _cdata->_data.size();
|
||||
INLINE void GeomVertexArrayDataHandle::
|
||||
clear_rows() {
|
||||
set_num_rows(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineBase::get_modified
|
||||
// Access: Public
|
||||
// Function: GeomVertexArrayDataHandle::get_data_size_bytes
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomVertexArrayDataPipelineBase::
|
||||
INLINE int GeomVertexArrayDataHandle::
|
||||
get_data_size_bytes() const {
|
||||
return _cdata->_data_full_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataHandle::get_modified
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE UpdateSeq GeomVertexArrayDataHandle::
|
||||
get_modified() const {
|
||||
return _cdata->_modified;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
// Function: GeomVertexArrayDataHandle::check_resident
|
||||
// Access: Published
|
||||
// Description: Forces the vertex data into system RAM, if it is not
|
||||
// already there; also, marks it recently-used.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineReader::
|
||||
GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object,
|
||||
Thread *current_thread) :
|
||||
GeomVertexArrayDataPipelineBase((GeomVertexArrayData *)object,
|
||||
current_thread,
|
||||
(GeomVertexArrayData::CData *)object->_cycler.read_unlocked(current_thread))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineReader::
|
||||
GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader ©) :
|
||||
GeomVertexArrayDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayDataPipelineReader::
|
||||
operator = (const GeomVertexArrayDataPipelineReader &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineReader::
|
||||
~GeomVertexArrayDataPipelineReader() {
|
||||
// _object->_cycler.release_read(_cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineReader::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayData *GeomVertexArrayDataPipelineReader::
|
||||
get_object() const {
|
||||
return _object;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Constructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter::
|
||||
GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, bool force_to_0,
|
||||
Thread *current_thread) :
|
||||
GeomVertexArrayDataPipelineBase(object, current_thread,
|
||||
object->_cycler.write_upstream(force_to_0, current_thread))
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Copy Constructor
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter::
|
||||
GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter ©) :
|
||||
GeomVertexArrayDataPipelineBase(copy)
|
||||
{
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Copy Assignment Operator
|
||||
// Access: Private
|
||||
// Description: Don't attempt to copy these objects.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexArrayDataPipelineWriter::
|
||||
operator = (const GeomVertexArrayDataPipelineWriter &) {
|
||||
nassertv(false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::Destructor
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter::
|
||||
~GeomVertexArrayDataPipelineWriter() {
|
||||
_object->_cycler.release_write(_cdata);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::get_object
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayData *GeomVertexArrayDataPipelineWriter::
|
||||
get_object() const {
|
||||
return _object;
|
||||
void GeomVertexArrayDataHandle::
|
||||
check_resident() const {
|
||||
if (_object->get_ram_class() != RC_resident) {
|
||||
_object->make_resident();
|
||||
} else {
|
||||
_object->mark_used_lru();
|
||||
}
|
||||
nassertv(_cdata->_data.size() == _cdata->_data_full_size);
|
||||
}
|
||||
|
||||
INLINE ostream &
|
||||
|
|
|
|||
|
|
@ -23,11 +23,55 @@
|
|||
#include "bamReader.h"
|
||||
#include "bamWriter.h"
|
||||
#include "pset.h"
|
||||
#include "config_gobj.h"
|
||||
#include "pStatTimer.h"
|
||||
|
||||
#ifdef HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#endif
|
||||
|
||||
ConfigVariableInt max_ram_vertex_data
|
||||
("max-ram-vertex-data", 0,
|
||||
PRC_DESC("Specifies the maximum number of bytes of all vertex data "
|
||||
"that is allowed to remain resident in system RAM at one time. "
|
||||
"If more than this number of bytes of vertices are created, "
|
||||
"the least-recently-used ones will be temporarily compressed in "
|
||||
"system RAM until they are needed. Set it to 0 for no limit."));
|
||||
|
||||
ConfigVariableInt max_compressed_vertex_data
|
||||
("max-compressed-vertex-data", 0,
|
||||
PRC_DESC("Specifies the maximum number of bytes of all vertex data "
|
||||
"that is allowed to remain compressed in system RAM at one time. "
|
||||
"If more than this number of bytes of vertices are created, "
|
||||
"the least-recently-used ones will be temporarily flushed to "
|
||||
"disk until they are needed. Set it to 0 for no limit."));
|
||||
|
||||
// We make this a static constant rather than a dynamic variable,
|
||||
// since we can't tolerate this value changing at runtime.
|
||||
static const size_t min_vertex_data_compress_size =
|
||||
ConfigVariableInt
|
||||
("min-vertex-data-compress-size", 64,
|
||||
PRC_DESC("This is the minimum number of bytes that we deem worthy of "
|
||||
"passing through zlib to compress, when a vertex buffer is "
|
||||
"evicted from resident state and compressed for long-term "
|
||||
"storage. Buffers smaller than this are assumed to be likely to "
|
||||
"have minimal compression gains (or even end up larger)."));
|
||||
|
||||
|
||||
|
||||
SimpleLru GeomVertexArrayData::_global_lru[RC_end_of_list] = {
|
||||
SimpleLru(max_ram_vertex_data),
|
||||
SimpleLru(max_compressed_vertex_data),
|
||||
SimpleLru(0)
|
||||
};
|
||||
|
||||
PStatCollector GeomVertexArrayData::_vdata_compress_pcollector("*:Vertex Data:Compress");
|
||||
PStatCollector GeomVertexArrayData::_vdata_decompress_pcollector("*:Vertex Data:Decompress");
|
||||
|
||||
|
||||
TypeHandle GeomVertexArrayData::_type_handle;
|
||||
TypeHandle GeomVertexArrayData::CData::_type_handle;
|
||||
TypeHandle GeomVertexArrayDataPipelineReader::_type_handle;
|
||||
TypeHandle GeomVertexArrayDataPipelineWriter::_type_handle;
|
||||
TypeHandle GeomVertexArrayDataHandle::_type_handle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::Default Constructor
|
||||
|
|
@ -36,8 +80,11 @@ TypeHandle GeomVertexArrayDataPipelineWriter::_type_handle;
|
|||
// reading from the bam file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
GeomVertexArrayData::
|
||||
GeomVertexArrayData() {
|
||||
GeomVertexArrayData() : SimpleLruPage(0) {
|
||||
_endian_reversed = false;
|
||||
_ram_class = RC_resident;
|
||||
|
||||
// Can't put it in the LRU until it has been read in and made valid.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -47,6 +94,7 @@ GeomVertexArrayData() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
PT(CopyOnWriteObject) GeomVertexArrayData::
|
||||
make_cow_copy() {
|
||||
make_resident();
|
||||
return new GeomVertexArrayData(*this);
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +106,7 @@ make_cow_copy() {
|
|||
GeomVertexArrayData::
|
||||
GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
|
||||
GeomVertexArrayData::UsageHint usage_hint) :
|
||||
SimpleLruPage(0),
|
||||
_array_format(array_format)
|
||||
{
|
||||
OPEN_ITERATE_ALL_STAGES(_cycler) {
|
||||
|
|
@ -67,6 +116,10 @@ GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
|
|||
CLOSE_ITERATE_ALL_STAGES(_cycler);
|
||||
|
||||
_endian_reversed = false;
|
||||
|
||||
_ram_class = RC_resident;
|
||||
mark_used_lru(&_global_lru[RC_resident]);
|
||||
|
||||
nassertv(_array_format->is_registered());
|
||||
}
|
||||
|
||||
|
|
@ -78,10 +131,15 @@ GeomVertexArrayData(const GeomVertexArrayFormat *array_format,
|
|||
GeomVertexArrayData::
|
||||
GeomVertexArrayData(const GeomVertexArrayData ©) :
|
||||
CopyOnWriteObject(copy),
|
||||
SimpleLruPage(copy),
|
||||
_array_format(copy._array_format),
|
||||
_cycler(copy._cycler)
|
||||
{
|
||||
_endian_reversed = false;
|
||||
|
||||
_ram_class = copy._ram_class;
|
||||
mark_used_lru(&_global_lru[_ram_class]);
|
||||
|
||||
nassertv(_array_format->is_registered());
|
||||
}
|
||||
|
||||
|
|
@ -96,6 +154,7 @@ GeomVertexArrayData(const GeomVertexArrayData ©) :
|
|||
void GeomVertexArrayData::
|
||||
operator = (const GeomVertexArrayData ©) {
|
||||
CopyOnWriteObject::operator = (copy);
|
||||
SimpleLruPage::operator = (copy);
|
||||
_array_format = copy._array_format;
|
||||
_cycler = copy._cycler;
|
||||
|
||||
|
|
@ -272,6 +331,155 @@ release_all() {
|
|||
return num_freed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::lru_epoch
|
||||
// Access: Published, Static
|
||||
// Description: Marks that an epoch has passed in each LRU. Asks the
|
||||
// LRU's to consider whether they should perform
|
||||
// evictions.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
lru_epoch() {
|
||||
for (int i = 0; i < (int)RC_end_of_list; ++i) {
|
||||
get_global_lru((RamClass)i)->consider_evict();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::make_resident
|
||||
// Access: Published
|
||||
// Description: Moves the vertex data to fully resident status by
|
||||
// expanding it or reading it from disk as necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
make_resident() {
|
||||
// TODO: make this work with pipelining properly.
|
||||
if (_ram_class == RC_compressed) {
|
||||
CDWriter cdata(_cycler, true);
|
||||
#ifdef HAVE_ZLIB
|
||||
if (cdata->_data_full_size > min_vertex_data_compress_size) {
|
||||
PStatTimer timer(_vdata_decompress_pcollector);
|
||||
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Expanding " << *this << " from " << cdata->_data.size()
|
||||
<< " to " << cdata->_data_full_size << "\n";
|
||||
}
|
||||
PTA_uchar new_data = PTA_uchar::empty_array(cdata->_data_full_size, get_class_type());
|
||||
uLongf dest_len = cdata->_data_full_size;
|
||||
int result = uncompress(new_data.p(), &dest_len,
|
||||
cdata->_data.p(), cdata->_data.size());
|
||||
if (result != Z_OK) {
|
||||
gobj_cat.error()
|
||||
<< "Couldn't expand: zlib error " << result << "\n";
|
||||
}
|
||||
nassertv(dest_len == new_data.size());
|
||||
cdata->_data = new_data;
|
||||
}
|
||||
#endif
|
||||
set_lru_size(cdata->_data.size());
|
||||
}
|
||||
|
||||
set_ram_class(RC_resident);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::make_compressed
|
||||
// Access: Published
|
||||
// Description: Moves the vertex data to compressed status by
|
||||
// compressing it or reading it from disk as necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
make_compressed() {
|
||||
// TODO: make this work with pipelining properly.
|
||||
if (_ram_class == RC_resident) {
|
||||
|
||||
CDWriter cdata(_cycler, true);
|
||||
#ifdef HAVE_ZLIB
|
||||
if (cdata->_data_full_size > min_vertex_data_compress_size) {
|
||||
PStatTimer timer(_vdata_compress_pcollector);
|
||||
|
||||
// According to the zlib manual, we need to provide this much
|
||||
// buffer to the compress algorithm: 0.1% bigger plus twelve
|
||||
// bytes.
|
||||
uLongf buffer_size = cdata->_data_full_size + ((cdata->_data_full_size + 999) / 1000) + 12;
|
||||
Bytef *buffer = new Bytef[buffer_size];
|
||||
|
||||
int result = compress(buffer, &buffer_size,
|
||||
cdata->_data.p(), cdata->_data_full_size);
|
||||
if (result != Z_OK) {
|
||||
gobj_cat.error()
|
||||
<< "Couldn't compress: zlib error " << result << "\n";
|
||||
}
|
||||
|
||||
PTA_uchar new_data = PTA_uchar::empty_array(buffer_size, get_class_type());
|
||||
memcpy(new_data.p(), buffer, buffer_size);
|
||||
delete[] buffer;
|
||||
|
||||
cdata->_data = new_data;
|
||||
if (gobj_cat.is_debug()) {
|
||||
gobj_cat.debug()
|
||||
<< "Compressed " << *this << " from " << cdata->_data_full_size
|
||||
<< " to " << cdata->_data.size() << "\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
set_ram_class(RC_compressed);
|
||||
set_lru_size(cdata->_data.size());
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::make_disk
|
||||
// Access: Published
|
||||
// Description: Moves the vertex data to disk status by
|
||||
// writing it to disk as necessary.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
make_disk() {
|
||||
// TODO: make this work with pipelining properly.
|
||||
if (_ram_class == RC_compressed) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::evict_lru
|
||||
// Access: Public, Virtual
|
||||
// Description: Evicts the page from the LRU. Called internally when
|
||||
// the LRU determines that it is full. May also be
|
||||
// called externally when necessary to explicitly evict
|
||||
// the page.
|
||||
//
|
||||
// It is legal for this method to either evict the page
|
||||
// as requested, do nothing (in which case the eviction
|
||||
// will be requested again at the next epoch), or
|
||||
// requeue itself on the tail of the queue (in which
|
||||
// case the eviction will be requested again much
|
||||
// later).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
evict_lru() {
|
||||
nassertv(get_lru() == get_global_lru(_ram_class));
|
||||
|
||||
switch (_ram_class) {
|
||||
case RC_resident:
|
||||
make_compressed();
|
||||
break;
|
||||
|
||||
case RC_compressed:
|
||||
make_disk();
|
||||
break;
|
||||
|
||||
case RC_disk:
|
||||
gobj_cat.warning()
|
||||
<< "Cannot evict array data from disk.\n";
|
||||
break;
|
||||
|
||||
case RC_end_of_list:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayData::clear_prepared
|
||||
// Access: Private
|
||||
|
|
@ -359,6 +567,7 @@ register_with_read_factory() {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayData::
|
||||
write_datagram(BamWriter *manager, Datagram &dg) {
|
||||
make_resident();
|
||||
CopyOnWriteObject::write_datagram(manager, dg);
|
||||
|
||||
manager->write_pointer(dg, _array_format);
|
||||
|
|
@ -465,6 +674,8 @@ finalize(BamReader *manager) {
|
|||
|
||||
// Now is also the time to node_ref the data.
|
||||
cdata->_data.node_ref();
|
||||
|
||||
set_ram_class(RC_resident);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -510,7 +721,6 @@ fillin(DatagramIterator &scan, BamReader *manager) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
GeomVertexArrayData::CData::
|
||||
~CData() {
|
||||
_data.node_unref();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -548,47 +758,41 @@ fillin(DatagramIterator &scan, BamReader *manager, void *extra_data) {
|
|||
GeomVertexArrayData *array_data = (GeomVertexArrayData *)extra_data;
|
||||
_usage_hint = (UsageHint)scan.get_uint8();
|
||||
READ_PTA(manager, scan, array_data->read_raw_data, _data);
|
||||
_data_full_size = _data.size();
|
||||
array_data->set_lru_size(_data_full_size);
|
||||
|
||||
_modified = Geom::get_next_modified();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::set_num_rows
|
||||
// Function: GeomVertexArrayDataHandle::set_num_rows
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexArrayDataPipelineWriter::
|
||||
bool GeomVertexArrayDataHandle::
|
||||
set_num_rows(int n) {
|
||||
nassertr(_writable, false);
|
||||
check_resident();
|
||||
|
||||
int stride = _object->_array_format->get_stride();
|
||||
int delta = n - (_cdata->_data.size() / stride);
|
||||
|
||||
if (delta != 0) {
|
||||
if (_cdata->_data.get_node_ref_count() > 1) {
|
||||
// Copy-on-write: the data is already reffed somewhere else,
|
||||
// so we're just going to make a copy.
|
||||
PTA_uchar new_data(GeomVertexArrayData::get_class_type());
|
||||
new_data.reserve(n * stride);
|
||||
new_data.insert(new_data.end(), n * stride, 0);
|
||||
memcpy(new_data, _cdata->_data,
|
||||
min((size_t)(n * stride), _cdata->_data.size()));
|
||||
_cdata->_data.node_unref();
|
||||
_cdata->_data = new_data;
|
||||
_cdata->_data.node_ref();
|
||||
if (delta > 0) {
|
||||
_cdata->_data.insert(_cdata->_data.end(), delta * stride, 0);
|
||||
|
||||
} else {
|
||||
// We've got the only reference to the data, so we can change
|
||||
// it directly.
|
||||
if (delta > 0) {
|
||||
_cdata->_data.insert(_cdata->_data.end(), delta * stride, 0);
|
||||
|
||||
} else {
|
||||
_cdata->_data.erase(_cdata->_data.begin() + n * stride,
|
||||
_cdata->_data.end());
|
||||
}
|
||||
_cdata->_data.erase(_cdata->_data.begin() + n * stride,
|
||||
_cdata->_data.end());
|
||||
}
|
||||
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
_cdata->_data_full_size = _cdata->_data.size();
|
||||
|
||||
if (get_current_thread()->get_pipeline_stage() == 0) {
|
||||
_object->set_ram_class(RC_resident);
|
||||
_object->set_lru_size(_cdata->_data_full_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -596,24 +800,30 @@ set_num_rows(int n) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::unclean_set_num_rows
|
||||
// Function: GeomVertexArrayDataHandle::unclean_set_num_rows
|
||||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexArrayDataPipelineWriter::
|
||||
bool GeomVertexArrayDataHandle::
|
||||
unclean_set_num_rows(int n) {
|
||||
nassertr(_writable, false);
|
||||
check_resident();
|
||||
|
||||
int stride = _object->_array_format->get_stride();
|
||||
int delta = n - (_cdata->_data.size() / stride);
|
||||
|
||||
if (delta != 0) {
|
||||
// Just make a new array. No reason to keep the old one around.
|
||||
PTA_uchar new_data = PTA_uchar::empty_array(n * stride, GeomVertexArrayData::get_class_type());
|
||||
//_cdata->_data = GeomVertexArrayData::Data('\0', n * stride, GeomVertexArrayData::get_class_type());
|
||||
_cdata->_data = PTA_uchar::empty_array(n * stride, GeomVertexArrayData::get_class_type());
|
||||
|
||||
_cdata->_data.node_unref();
|
||||
_cdata->_data = new_data;
|
||||
_cdata->_data.node_ref();
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
_cdata->_data_full_size = _cdata->_data.size();
|
||||
|
||||
if (get_current_thread()->get_pipeline_stage() == 0) {
|
||||
_object->set_ram_class(RC_resident);
|
||||
_object->set_lru_size(_cdata->_data_full_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -621,37 +831,66 @@ unclean_set_num_rows(int n) {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::modify_data
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Function: GeomVertexArrayDataHandle::copy_data_from
|
||||
// Access: Public
|
||||
// Description: Copies the entire data array from the other object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
PTA_uchar GeomVertexArrayDataPipelineWriter::
|
||||
modify_data() {
|
||||
// Perform copy-on-write: if the *node* reference count on the
|
||||
// vertex data is greater than 1, assume some other
|
||||
// GeomVertexArrayData has the same pointer, so make a copy of it
|
||||
// first.
|
||||
if (_cdata->_data.get_node_ref_count() > 1) {
|
||||
PTA_uchar orig_data = _cdata->_data;
|
||||
_cdata->_data.node_unref();
|
||||
_cdata->_data = PTA_uchar(GeomVertexArrayData::get_class_type());
|
||||
_cdata->_data.v() = orig_data.v();
|
||||
_cdata->_data.node_ref();
|
||||
void GeomVertexArrayDataHandle::
|
||||
copy_data_from(const GeomVertexArrayDataHandle *other) {
|
||||
nassertv(_writable);
|
||||
check_resident();
|
||||
other->check_resident();
|
||||
|
||||
_cdata->_data.v() = other->_cdata->_data.v();
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
_cdata->_data_full_size = _cdata->_data.size();
|
||||
|
||||
if (get_current_thread()->get_pipeline_stage() == 0) {
|
||||
_object->set_ram_class(RC_resident);
|
||||
_object->set_lru_size(_cdata->_data_full_size);
|
||||
}
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
|
||||
return _cdata->_data;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: GeomVertexArrayDataPipelineWriter::set_data
|
||||
// Access: Published
|
||||
// Description:
|
||||
// Function: GeomVertexArrayDataHandle::copy_subdata_from
|
||||
// Access: Public
|
||||
// Description: Copies a portion of the data array from the other
|
||||
// object into a portion of the data array of this
|
||||
// object. If to_size != from_size, the size of this
|
||||
// data array is adjusted accordingly.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void GeomVertexArrayDataPipelineWriter::
|
||||
set_data(CPTA_uchar array) {
|
||||
_cdata->_data.node_unref();
|
||||
_cdata->_data = (PTA_uchar &)array;
|
||||
_cdata->_data.node_ref();
|
||||
void GeomVertexArrayDataHandle::
|
||||
copy_subdata_from(size_t to_start, size_t to_size,
|
||||
const GeomVertexArrayDataHandle *other,
|
||||
size_t from_start, size_t from_size) {
|
||||
nassertv(_writable);
|
||||
check_resident();
|
||||
other->check_resident();
|
||||
|
||||
pvector<unsigned char> &to_v = _cdata->_data.v();
|
||||
to_start = min(to_start, to_v.size());
|
||||
to_size = min(to_size, to_v.size() - to_start);
|
||||
|
||||
from_start = min(from_start, other->_cdata->_data.size());
|
||||
from_size = min(from_size, other->_cdata->_data.size() - from_start);
|
||||
|
||||
if (from_size < to_size) {
|
||||
// Reduce the array.
|
||||
to_v.erase(to_v.begin() + to_start + from_size, to_v.begin() + to_start + to_size);
|
||||
|
||||
} else if (to_size < from_size) {
|
||||
// Expand the array.
|
||||
to_v.insert(to_v.begin() + to_start + to_size, from_size - to_size, char());
|
||||
}
|
||||
|
||||
// Now copy the data.
|
||||
memcpy(&to_v[0] + to_start, other->get_pointer() + from_start, from_size);
|
||||
_cdata->_modified = Geom::get_next_modified();
|
||||
_cdata->_data_full_size = _cdata->_data.size();
|
||||
|
||||
if (get_current_thread()->get_pipeline_stage() == 0) {
|
||||
_object->set_ram_class(RC_resident);
|
||||
_object->set_lru_size(_cdata->_data_full_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,11 +33,15 @@
|
|||
#include "pipelineCycler.h"
|
||||
#include "pStatCollector.h"
|
||||
#include "pmap.h"
|
||||
#include "reMutex.h"
|
||||
#include "simpleLru.h"
|
||||
|
||||
class PreparedGraphicsObjects;
|
||||
class VertexBufferContext;
|
||||
class GraphicsStateGuardianBase;
|
||||
|
||||
class GeomVertexArrayDataHandle;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayData
|
||||
// Description : This is the data for one array of a GeomVertexData
|
||||
|
|
@ -57,7 +61,7 @@ class GraphicsStateGuardianBase;
|
|||
// GeomVertexReader/Writer/Rewriter for high-level tools
|
||||
// to manipulate the actual vertex data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayData : public CopyOnWriteObject, public GeomEnums {
|
||||
class EXPCL_PANDA GeomVertexArrayData : public CopyOnWriteObject, public SimpleLruPage, public GeomEnums {
|
||||
private:
|
||||
GeomVertexArrayData();
|
||||
|
||||
|
|
@ -90,9 +94,8 @@ PUBLISHED:
|
|||
void output(ostream &out) const;
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
INLINE PTA_uchar modify_data();
|
||||
INLINE void set_data(CPTA_uchar data);
|
||||
INLINE CPT(GeomVertexArrayDataHandle) get_handle(Thread *current_thread = Thread::get_current_thread()) const;
|
||||
INLINE PT(GeomVertexArrayDataHandle) modify_handle(Thread *current_thread = Thread::get_current_thread());
|
||||
|
||||
void prepare(PreparedGraphicsObjects *prepared_objects);
|
||||
bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
|
||||
|
|
@ -102,10 +105,25 @@ PUBLISHED:
|
|||
bool release(PreparedGraphicsObjects *prepared_objects);
|
||||
int release_all();
|
||||
|
||||
INLINE RamClass get_ram_class() const;
|
||||
|
||||
INLINE static SimpleLru *get_global_lru(RamClass rclass);
|
||||
static void lru_epoch();
|
||||
|
||||
void make_resident();
|
||||
void make_compressed();
|
||||
void make_disk();
|
||||
|
||||
public:
|
||||
virtual void evict_lru();
|
||||
|
||||
private:
|
||||
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
|
||||
PTA_uchar reverse_data_endianness(const PTA_uchar &data);
|
||||
|
||||
INLINE void set_ram_class(RamClass rclass);
|
||||
|
||||
|
||||
CPT(GeomVertexArrayFormat) _array_format;
|
||||
|
||||
// A GeomVertexArrayData keeps a list (actually, a map) of all the
|
||||
|
|
@ -120,11 +138,17 @@ private:
|
|||
// to indicate the data must be endian-reversed in finalize().
|
||||
bool _endian_reversed;
|
||||
|
||||
RamClass _ram_class;
|
||||
|
||||
typedef pvector<unsigned char> Data;
|
||||
|
||||
// This is the data that must be cycled between pipeline stages.
|
||||
class EXPCL_PANDA CData : public CycleData {
|
||||
public:
|
||||
INLINE CData();
|
||||
INLINE CData(const CData ©);
|
||||
INLINE void operator = (const CData ©);
|
||||
|
||||
virtual ~CData();
|
||||
ALLOC_DELETED_CHAIN(CData);
|
||||
virtual CycleData *make_copy() const;
|
||||
|
|
@ -138,7 +162,12 @@ private:
|
|||
|
||||
UsageHint _usage_hint;
|
||||
PTA_uchar _data;
|
||||
size_t _data_full_size;
|
||||
UpdateSeq _modified;
|
||||
|
||||
// This implements read-write locking. Anyone who gets the data for
|
||||
// reading or writing will hold this mutex during the lock.
|
||||
ReMutex _rw_lock;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
|
|
@ -160,6 +189,11 @@ private:
|
|||
typedef CycleDataStageReader<CData> CDStageReader;
|
||||
typedef CycleDataStageWriter<CData> CDStageWriter;
|
||||
|
||||
static SimpleLru _global_lru[RC_end_of_list];
|
||||
|
||||
static PStatCollector _vdata_compress_pcollector;
|
||||
static PStatCollector _vdata_decompress_pcollector;
|
||||
|
||||
public:
|
||||
static void register_with_read_factory();
|
||||
virtual void write_datagram(BamWriter *manager, Datagram &dg);
|
||||
|
|
@ -194,104 +228,92 @@ private:
|
|||
friend class GeomCacheManager;
|
||||
friend class GeomVertexData;
|
||||
friend class PreparedGraphicsObjects;
|
||||
friend class GeomVertexArrayDataPipelineBase;
|
||||
friend class GeomVertexArrayDataPipelineReader;
|
||||
friend class GeomVertexArrayDataPipelineWriter;
|
||||
friend class GeomVertexArrayDataHandle;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayDataPipelineBase
|
||||
// Description : The common code from
|
||||
// Class : GeomVertexArrayDataHandle
|
||||
// Description : This data object is returned by
|
||||
// GeomVertexArrayData::get_handle() or modify_handle().
|
||||
// As long as it exists, the data is locked; when the
|
||||
// last of these destructs, the data is unlocked.
|
||||
//
|
||||
// Only one thread at a time may lock the data; other
|
||||
// threads attempting to lock the data will block. A
|
||||
// given thread may simultaneously lock the data
|
||||
// multiple times.
|
||||
//
|
||||
// This class serves in lieu of a pair of
|
||||
// GeomVertexArrayDataPipelineReader and
|
||||
// GeomVertexArrayDataPipelineWriter.
|
||||
// GeomVertexArrayDataPipelineWriter classes
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayDataPipelineBase : public GeomEnums {
|
||||
protected:
|
||||
INLINE GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
|
||||
Thread *current_thread,
|
||||
GeomVertexArrayData::CData *cdata);
|
||||
class EXPCL_PANDA GeomVertexArrayDataHandle : public ReferenceCount, public GeomEnums {
|
||||
private:
|
||||
INLINE GeomVertexArrayDataHandle(const GeomVertexArrayData *object,
|
||||
Thread *current_thread,
|
||||
const GeomVertexArrayData::CData *_cdata,
|
||||
bool writable);
|
||||
INLINE GeomVertexArrayDataHandle(const GeomVertexArrayDataHandle &);
|
||||
INLINE void operator = (const GeomVertexArrayDataHandle &);
|
||||
|
||||
PUBLISHED:
|
||||
INLINE ~GeomVertexArrayDataHandle();
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexArrayDataPipelineBase();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexArrayDataHandle);
|
||||
|
||||
INLINE Thread *get_current_thread() const;
|
||||
INLINE const GeomVertexArrayData *get_object() const;
|
||||
INLINE GeomVertexArrayData *get_object();
|
||||
|
||||
INLINE const unsigned char *get_pointer() const;
|
||||
INLINE unsigned char *get_pointer();
|
||||
|
||||
PUBLISHED:
|
||||
INLINE const GeomVertexArrayFormat *get_array_format() const;
|
||||
|
||||
INLINE UsageHint get_usage_hint() const;
|
||||
INLINE CPTA_uchar get_data() const;
|
||||
|
||||
INLINE int get_num_rows() const;
|
||||
bool set_num_rows(int n);
|
||||
bool unclean_set_num_rows(int n);
|
||||
INLINE void clear_rows();
|
||||
|
||||
INLINE int get_data_size_bytes() const;
|
||||
INLINE UpdateSeq get_modified() const;
|
||||
|
||||
protected:
|
||||
void copy_data_from(const GeomVertexArrayDataHandle *other);
|
||||
void copy_subdata_from(size_t to_start, size_t to_size,
|
||||
const GeomVertexArrayDataHandle *other,
|
||||
size_t from_start, size_t from_size);
|
||||
|
||||
/*
|
||||
INLINE string get_data() const;
|
||||
void set_data(const string &data);
|
||||
INLINE string get_subdata(size_t start, size_t size) const;
|
||||
void set_subdata(size_t start, size_t size, const string &data);
|
||||
*/
|
||||
|
||||
INLINE void check_resident() const;
|
||||
|
||||
private:
|
||||
ReMutexHolder _holder;
|
||||
PT(GeomVertexArrayData) _object;
|
||||
Thread *_current_thread;
|
||||
GeomVertexArrayData::CData *_cdata;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayDataPipelineReader
|
||||
// Description : Encapsulates the data from a GeomVertexArrayData,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayDataPipelineReader : public GeomVertexArrayDataPipelineBase {
|
||||
public:
|
||||
INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object, Thread *current_thread);
|
||||
private:
|
||||
INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader ©);
|
||||
INLINE void operator = (const GeomVertexArrayDataPipelineReader ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexArrayDataPipelineReader();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineReader);
|
||||
|
||||
INLINE const GeomVertexArrayData *get_object() const;
|
||||
bool _writable;
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "GeomVertexArrayDataPipelineReader");
|
||||
register_type(_type_handle, "GeomVertexArrayDataHandle");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : GeomVertexArrayDataPipelineWriter
|
||||
// Description : Encapsulates the data from a GeomVertexArrayData,
|
||||
// pre-fetched for one stage of the pipeline.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA GeomVertexArrayDataPipelineWriter : public GeomVertexArrayDataPipelineBase {
|
||||
public:
|
||||
INLINE GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, bool force_to_0, Thread *current_thread);
|
||||
private:
|
||||
INLINE GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter ©);
|
||||
INLINE void operator = (const GeomVertexArrayDataPipelineWriter ©);
|
||||
|
||||
public:
|
||||
INLINE ~GeomVertexArrayDataPipelineWriter();
|
||||
ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineWriter);
|
||||
|
||||
bool set_num_rows(int n);
|
||||
bool unclean_set_num_rows(int n);
|
||||
|
||||
INLINE GeomVertexArrayData *get_object() const;
|
||||
PTA_uchar modify_data();
|
||||
void set_data(CPTA_uchar data);
|
||||
|
||||
public:
|
||||
static TypeHandle get_class_type() {
|
||||
return _type_handle;
|
||||
}
|
||||
static void init_type() {
|
||||
register_type(_type_handle, "GeomVertexArrayDataPipelineWriter");
|
||||
}
|
||||
|
||||
private:
|
||||
static TypeHandle _type_handle;
|
||||
friend class GeomVertexArrayData;
|
||||
};
|
||||
|
||||
INLINE ostream &operator << (ostream &out, const GeomVertexArrayData &obj);
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ check_array_readers() const {
|
|||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const GeomVertexArrayDataPipelineReader *GeomVertexDataPipelineReader::
|
||||
INLINE const GeomVertexArrayDataHandle *GeomVertexDataPipelineReader::
|
||||
get_array_reader(int i) const {
|
||||
nassertr(_got_array_readers, NULL);
|
||||
nassertr(i >= 0 && i < (int)_array_readers.size(), NULL);
|
||||
|
|
@ -846,7 +846,7 @@ check_array_writers() const {
|
|||
// Access: Public
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE GeomVertexArrayDataPipelineWriter *GeomVertexDataPipelineWriter::
|
||||
INLINE GeomVertexArrayDataHandle *GeomVertexDataPipelineWriter::
|
||||
get_array_writer(int i) const {
|
||||
nassertr(_got_array_writers, NULL);
|
||||
nassertr(i >= 0 && i < (int)_array_writers.size(), NULL);
|
||||
|
|
|
|||
|
|
@ -426,10 +426,10 @@ set_slider_table(const SliderTable *table) {
|
|||
// more of the arrays can be copied without the need to
|
||||
// apply any conversion operation. If it is true, the
|
||||
// original GeomVertexArrayData objects in this object
|
||||
// are retained, but their data arrays are copied
|
||||
// pointerwise from the source; if it is false, then the
|
||||
// GeomVertexArrayData objects themselves are copied
|
||||
// pointerwise from the source.
|
||||
// are retained, and their data arrays are copied
|
||||
// byte-by-byte from the source; if it is false, then the
|
||||
// GeomVertexArrayData objects are copied pointerwise
|
||||
// from the source.
|
||||
//
|
||||
// Don't call this in a downstream thread unless you
|
||||
// don't mind it blowing away other changes you might
|
||||
|
|
@ -465,13 +465,10 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
// Great! Just use the same data for this one.
|
||||
if (keep_data_objects) {
|
||||
// Copy the data, but keep the same GeomVertexArrayData object.
|
||||
|
||||
// Maybe it even has the same data pointer already. If so,
|
||||
// avoid flipping the modified flag.
|
||||
CPTA_uchar source_data = source->get_array(source_i)->get_data();
|
||||
if (get_array(dest_i)->get_data() != source_data) {
|
||||
modify_array(dest_i)->set_data(source_data);
|
||||
}
|
||||
|
||||
PT(GeomVertexArrayData) dest_data = modify_array(dest_i);
|
||||
CPT(GeomVertexArrayData) source_data = source->get_array(source_i);
|
||||
dest_data->modify_handle()->copy_data_from(source_data->get_handle());
|
||||
} else {
|
||||
// Copy the GeomVertexArrayData object.
|
||||
if (get_array(dest_i) != source->get_array(source_i)) {
|
||||
|
|
@ -491,7 +488,8 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
// Now go back through and copy any data that's left over.
|
||||
for (source_i = 0; source_i < num_arrays; ++source_i) {
|
||||
CPT(GeomVertexArrayData) array_obj = source->get_array(source_i);
|
||||
CPTA_uchar array_data = array_obj->get_data();
|
||||
CPT(GeomVertexArrayDataHandle) array_handle = array_obj->get_handle();
|
||||
const unsigned char *array_data = array_handle->get_pointer();
|
||||
const GeomVertexArrayFormat *source_array_format = source_format->get_array(source_i);
|
||||
int num_columns = source_array_format->get_num_columns();
|
||||
for (int di = 0; di < num_columns; ++di) {
|
||||
|
|
@ -509,7 +507,8 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
if (dest_column->is_bytewise_equivalent(*source_column)) {
|
||||
// We can do a quick bytewise copy.
|
||||
PT(GeomVertexArrayData) dest_array_obj = modify_array(dest_i);
|
||||
PTA_uchar dest_array_data = dest_array_obj->modify_data();
|
||||
PT(GeomVertexArrayDataHandle) dest_handle = dest_array_obj->modify_handle();
|
||||
unsigned char *dest_array_data = dest_handle->get_pointer();
|
||||
|
||||
bytewise_copy(dest_array_data + dest_column->get_start(),
|
||||
dest_array_format->get_stride(),
|
||||
|
|
@ -520,7 +519,8 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
source_column->is_uint8_rgba()) {
|
||||
// A common special case: OpenGL color to DirectX color.
|
||||
PT(GeomVertexArrayData) dest_array_obj = modify_array(dest_i);
|
||||
PTA_uchar dest_array_data = dest_array_obj->modify_data();
|
||||
PT(GeomVertexArrayDataHandle) dest_handle = dest_array_obj->modify_handle();
|
||||
unsigned char *dest_array_data = dest_handle->get_pointer();
|
||||
|
||||
uint8_rgba_to_packed_argb
|
||||
(dest_array_data + dest_column->get_start(),
|
||||
|
|
@ -533,7 +533,8 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
|||
// Another common special case: DirectX color to OpenGL
|
||||
// color.
|
||||
PT(GeomVertexArrayData) dest_array_obj = modify_array(dest_i);
|
||||
PTA_uchar dest_array_data = dest_array_obj->modify_data();
|
||||
PT(GeomVertexArrayDataHandle) dest_handle = dest_array_obj->modify_handle();
|
||||
unsigned char *dest_array_data = dest_handle->get_pointer();
|
||||
|
||||
packed_argb_to_uint8_rgba
|
||||
(dest_array_data + dest_column->get_start(),
|
||||
|
|
@ -654,10 +655,12 @@ copy_row_from(int dest_row, const GeomVertexData *source,
|
|||
|
||||
for (int i = 0; i < num_arrays; ++i) {
|
||||
PT(GeomVertexArrayData) dest_array_obj = modify_array(i);
|
||||
PTA_uchar dest_array_data = dest_array_obj->modify_data();
|
||||
PT(GeomVertexArrayDataHandle) dest_handle = dest_array_obj->modify_handle();
|
||||
unsigned char *dest_array_data = dest_handle->get_pointer();
|
||||
|
||||
CPT(GeomVertexArrayData) source_array_obj = source->get_array(i);
|
||||
CPTA_uchar source_array_data = source_array_obj->get_data();
|
||||
CPT(GeomVertexArrayDataHandle) source_array_handle = source_array_obj->get_handle();
|
||||
const unsigned char *source_array_data = source_array_handle->get_pointer();
|
||||
|
||||
const GeomVertexArrayFormat *array_format = source_format->get_array(i);
|
||||
int stride = array_format->get_stride();
|
||||
|
|
@ -948,6 +951,7 @@ animate_vertices(Thread *current_thread) const {
|
|||
CDWriter cdataw(((GeomVertexData *)this)->_cycler, cdata, false);
|
||||
cdataw->_animated_vertices_modified = modified;
|
||||
((GeomVertexData *)this)->update_animated_vertices(cdataw, current_thread);
|
||||
|
||||
return cdataw->_animated_vertices;
|
||||
}
|
||||
|
||||
|
|
@ -1270,7 +1274,7 @@ update_animated_vertices(GeomVertexData::CData *cdata, Thread *current_thread) {
|
|||
if (slider_value != 0.0f) {
|
||||
CPT(InternalName) base_name = orig_format->get_morph_base(mi);
|
||||
CPT(InternalName) delta_name = orig_format->get_morph_delta(mi);
|
||||
|
||||
|
||||
GeomVertexRewriter data(new_data, base_name);
|
||||
GeomVertexReader delta(this, delta_name);
|
||||
int num_subranges = rows.get_num_subranges();
|
||||
|
|
@ -1714,7 +1718,7 @@ get_num_rows() const {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_array_info(const InternalName *name,
|
||||
const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
|
|
@ -1738,7 +1742,7 @@ get_array_info(const InternalName *name,
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_vertex_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
|
|
@ -1763,7 +1767,7 @@ get_vertex_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_normal_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
get_normal_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
nassertr(_got_array_readers, false);
|
||||
|
|
@ -1787,7 +1791,7 @@ get_normal_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
|||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexDataPipelineReader::
|
||||
get_color_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
get_color_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values,
|
||||
GeomVertexDataPipelineReader::NumericType &numeric_type,
|
||||
int &start, int &stride) const {
|
||||
|
|
@ -1818,7 +1822,8 @@ make_array_readers() {
|
|||
_array_readers.reserve(_cdata->_arrays.size());
|
||||
GeomVertexData::Arrays::const_iterator ai;
|
||||
for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
|
||||
_array_readers.push_back(new GeomVertexArrayDataPipelineReader((*ai).get_read_pointer(), _current_thread));
|
||||
CPT(GeomVertexArrayData) array_obj = (*ai).get_read_pointer();
|
||||
_array_readers.push_back(array_obj->get_handle(_current_thread));
|
||||
}
|
||||
|
||||
_got_array_readers = true;
|
||||
|
|
@ -1833,10 +1838,6 @@ void GeomVertexDataPipelineReader::
|
|||
delete_array_readers() {
|
||||
nassertv(_got_array_readers);
|
||||
|
||||
ArrayReaders::iterator ri;
|
||||
for (ri = _array_readers.begin(); ri != _array_readers.end(); ++ri) {
|
||||
delete (*ri);
|
||||
}
|
||||
_array_readers.clear();
|
||||
_got_array_readers = false;
|
||||
}
|
||||
|
|
@ -1888,15 +1889,15 @@ set_num_rows(int n) {
|
|||
}
|
||||
|
||||
if (color_array >= 0 && orig_color_rows < n) {
|
||||
// We have just added some rows, fill the "color" column with
|
||||
// We have just added some rows; fill the "color" column with
|
||||
// (1, 1, 1, 1), for the programmer's convenience.
|
||||
GeomVertexArrayDataPipelineWriter *array_writer = _array_writers[color_array];
|
||||
GeomVertexArrayDataHandle *array_writer = _array_writers[color_array];
|
||||
const GeomVertexArrayFormat *array_format = array_writer->get_array_format();
|
||||
const GeomVertexColumn *column =
|
||||
array_format->get_column(InternalName::get_color());
|
||||
int stride = array_format->get_stride();
|
||||
unsigned char *start =
|
||||
array_writer->modify_data() + column->get_start();
|
||||
array_writer->get_pointer() + column->get_start();
|
||||
unsigned char *stop = start + array_writer->get_data_size_bytes();
|
||||
unsigned char *pointer = start + stride * orig_color_rows;
|
||||
int num_values = column->get_num_values();
|
||||
|
|
@ -1999,8 +2000,7 @@ set_array(int i, const GeomVertexArrayData *array) {
|
|||
_cdata->_animated_vertices_modified = UpdateSeq();
|
||||
|
||||
if (_got_array_writers) {
|
||||
delete _array_writers[i];
|
||||
_array_writers[i] = new GeomVertexArrayDataPipelineWriter(_cdata->_arrays[i].get_write_pointer(), _force_to_0, _current_thread);
|
||||
_array_writers[i] = _cdata->_arrays[i].get_write_pointer()->modify_handle(_current_thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2017,7 +2017,7 @@ make_array_writers() {
|
|||
GeomVertexData::Arrays::iterator ai;
|
||||
for (ai = _cdata->_arrays.begin(); ai != _cdata->_arrays.end(); ++ai) {
|
||||
PT(GeomVertexArrayData) array_obj = (*ai).get_write_pointer();
|
||||
_array_writers.push_back(new GeomVertexArrayDataPipelineWriter(array_obj, _force_to_0, _current_thread));
|
||||
_array_writers.push_back(array_obj->modify_handle(_current_thread));
|
||||
}
|
||||
|
||||
_object->clear_cache_stage();
|
||||
|
|
@ -2036,10 +2036,6 @@ void GeomVertexDataPipelineWriter::
|
|||
delete_array_writers() {
|
||||
nassertv(_got_array_writers);
|
||||
|
||||
ArrayWriters::iterator ri;
|
||||
for (ri = _array_writers.begin(); ri != _array_writers.end(); ++ri) {
|
||||
delete (*ri);
|
||||
}
|
||||
_array_writers.clear();
|
||||
_got_array_writers = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -409,27 +409,27 @@ public:
|
|||
INLINE const GeomVertexData *get_object() const;
|
||||
|
||||
INLINE void check_array_readers() const;
|
||||
INLINE const GeomVertexArrayDataPipelineReader *get_array_reader(int i) const;
|
||||
INLINE const GeomVertexArrayDataHandle *get_array_reader(int i) const;
|
||||
int get_num_rows() const;
|
||||
|
||||
bool get_array_info(const InternalName *name,
|
||||
const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_vertex() const;
|
||||
INLINE bool is_vertex_transformed() const;
|
||||
bool get_vertex_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
bool get_vertex_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_normal() const;
|
||||
bool get_normal_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
bool get_normal_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
INLINE bool has_color() const;
|
||||
bool get_color_info(const GeomVertexArrayDataPipelineReader *&array_reader,
|
||||
bool get_color_info(const GeomVertexArrayDataHandle *&array_reader,
|
||||
int &num_values, NumericType &numeric_type,
|
||||
int &start, int &stride) const;
|
||||
|
||||
|
|
@ -438,7 +438,7 @@ private:
|
|||
void delete_array_readers();
|
||||
|
||||
bool _got_array_readers;
|
||||
typedef pvector<GeomVertexArrayDataPipelineReader *> ArrayReaders;
|
||||
typedef pvector<CPT(GeomVertexArrayDataHandle) > ArrayReaders;
|
||||
ArrayReaders _array_readers;
|
||||
|
||||
public:
|
||||
|
|
@ -473,7 +473,7 @@ public:
|
|||
INLINE GeomVertexData *get_object() const;
|
||||
|
||||
INLINE void check_array_writers() const;
|
||||
INLINE GeomVertexArrayDataPipelineWriter *get_array_writer(int i) const;
|
||||
INLINE GeomVertexArrayDataHandle *get_array_writer(int i) const;
|
||||
|
||||
PT(GeomVertexArrayData) modify_array(int i);
|
||||
void set_array(int i, const GeomVertexArrayData *array);
|
||||
|
|
@ -488,7 +488,7 @@ private:
|
|||
|
||||
bool _force_to_0;
|
||||
bool _got_array_writers;
|
||||
typedef pvector<GeomVertexArrayDataPipelineWriter *> ArrayWriters;
|
||||
typedef pvector<PT(GeomVertexArrayDataHandle) > ArrayWriters;
|
||||
ArrayWriters _array_writers;
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -575,9 +575,10 @@ write_with_data(ostream &out, int indent_level,
|
|||
indent(out, indent_level)
|
||||
<< data->get_num_rows() << " rows.\n";
|
||||
for (size_t i = 0; i < _arrays.size(); i++) {
|
||||
CPTA_uchar array_data = data->get_array(i)->get_data();
|
||||
CPT(GeomVertexArrayDataHandle) handle = data->get_array(i)->get_handle();
|
||||
const unsigned char *array_data = handle->get_pointer();
|
||||
indent(out, indent_level)
|
||||
<< "Array " << i << " (" << (void *)array_data.p() << ", "
|
||||
<< "Array " << i << " (" << (void *)array_data << ", "
|
||||
<< *_arrays[i] << "):\n";
|
||||
_arrays[i]->write_with_data(out, indent_level + 2, data->get_array(i));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ GeomVertexReader(const GeomVertexReader ©) :
|
|||
_current_thread(copy._current_thread),
|
||||
_packer(copy._packer),
|
||||
_stride(copy._stride),
|
||||
_data(copy._data),
|
||||
_handle(copy._handle),
|
||||
_pointer_begin(copy._pointer_begin),
|
||||
_pointer_end(copy._pointer_end),
|
||||
_pointer(copy._pointer),
|
||||
|
|
@ -168,7 +168,7 @@ operator = (const GeomVertexReader ©) {
|
|||
_current_thread = copy._current_thread;
|
||||
_packer = copy._packer;
|
||||
_stride = copy._stride;
|
||||
_data = copy._data;
|
||||
_handle = copy._handle;
|
||||
_pointer_begin = copy._pointer_begin;
|
||||
_pointer_end = copy._pointer_end;
|
||||
_pointer = copy._pointer;
|
||||
|
|
@ -242,9 +242,7 @@ set_column(int column) {
|
|||
&reader);
|
||||
}
|
||||
if (_array_data != (const GeomVertexArrayData *)NULL) {
|
||||
GeomVertexArrayDataPipelineReader reader(_array_data, _current_thread);
|
||||
return set_array_column(reader.get_array_format()->get_column(column),
|
||||
&reader);
|
||||
return set_array_column(_array_data->get_array_format()->get_column(column));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -291,9 +289,7 @@ set_column(const InternalName *name) {
|
|||
&reader);
|
||||
}
|
||||
if (_array_data != (const GeomVertexArrayData *)NULL) {
|
||||
GeomVertexArrayDataPipelineReader reader(_array_data, _current_thread);
|
||||
return set_array_column(reader.get_array_format()->get_column(name),
|
||||
&reader);
|
||||
return set_array_column(_array_data->get_array_format()->get_column(name));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
@ -511,10 +507,9 @@ get_packer() const {
|
|||
// and sets the internal pointer to the indicated row.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexReader::
|
||||
set_pointer(int row, const GeomVertexArrayDataPipelineReader *array_reader) {
|
||||
_data = array_reader->get_data();
|
||||
_pointer_begin = _data;
|
||||
_pointer_end = _pointer_begin + array_reader->get_data_size_bytes();
|
||||
set_pointer(int row) {
|
||||
_pointer_begin = _handle->get_pointer();
|
||||
_pointer_end = _pointer_begin + _handle->get_data_size_bytes();
|
||||
quick_set_pointer(row);
|
||||
}
|
||||
|
||||
|
|
@ -529,21 +524,16 @@ INLINE void GeomVertexReader::
|
|||
quick_set_pointer(int row) {
|
||||
nassertv(has_column());
|
||||
|
||||
#if defined(_DEBUG) && !defined(HAVE_THREADS)
|
||||
// Make sure we still have the same pointer as stored the array. We
|
||||
// only perform this test in debug mode, because it is expensive,
|
||||
// and only in single-threaded mode, because in threaded mode
|
||||
// another thread might have reallocated the other pointer outside
|
||||
// of our control anyway.
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertv(_pointer_begin == array_data->get_data());
|
||||
} else {
|
||||
nassertv(_pointer_begin == _array_data->get_data());
|
||||
}
|
||||
#if defined(_DEBUG)
|
||||
// Make sure we still have the same pointer as stored in the array.
|
||||
nassertv(_pointer_begin == _handle->get_pointer());
|
||||
#endif
|
||||
|
||||
_pointer = _pointer_begin + _packer->_column->get_start() + _stride * row;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
nassertv(_pointer_begin == _pointer_end || _pointer < _pointer_end);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -554,14 +544,11 @@ quick_set_pointer(int row) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE const unsigned char *GeomVertexReader::
|
||||
inc_pointer() {
|
||||
#ifdef _DEBUG
|
||||
#if defined(_DEBUG)
|
||||
nassertr(_pointer < _pointer_end, empty_buffer);
|
||||
if (_vertex_data != (const GeomVertexData *)NULL){
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
|
||||
} else {
|
||||
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
|
||||
}
|
||||
// Make sure we still have the same pointer as stored in the array.
|
||||
nassertr(_pointer_begin == _handle->get_pointer(), empty_buffer);
|
||||
nassertr(_pointer < _pointer_begin + _handle->get_data_size_bytes(), empty_buffer);
|
||||
#endif
|
||||
|
||||
const unsigned char *orig_pointer = _pointer;
|
||||
|
|
|
|||
|
|
@ -57,8 +57,7 @@ set_column(int array, const GeomVertexColumn *column) {
|
|||
return set_vertex_column(array, column, &reader);
|
||||
}
|
||||
if (_array_data != (const GeomVertexArrayData *)NULL) {
|
||||
GeomVertexArrayDataPipelineReader reader(_array_data, _current_thread);
|
||||
return set_array_column(column, &reader);
|
||||
return set_array_column(column);
|
||||
}
|
||||
|
||||
// No data is associated with the Reader.
|
||||
|
|
@ -121,12 +120,11 @@ set_vertex_column(int array, const GeomVertexColumn *column,
|
|||
#endif
|
||||
|
||||
_array = array;
|
||||
const GeomVertexArrayDataPipelineReader *array_reader =
|
||||
data_reader->get_array_reader(_array);
|
||||
_stride = array_reader->get_array_format()->get_stride();
|
||||
_handle = data_reader->get_array_reader(_array);
|
||||
_stride = _handle->get_array_format()->get_stride();
|
||||
|
||||
_packer = column->_packer;
|
||||
set_pointer(_start_row, array_reader);
|
||||
set_pointer(_start_row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -139,18 +137,18 @@ set_vertex_column(int array, const GeomVertexColumn *column,
|
|||
// GeomVertexArrayData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexReader::
|
||||
set_array_column(const GeomVertexColumn *column,
|
||||
const GeomVertexArrayDataPipelineReader *array_reader) {
|
||||
set_array_column(const GeomVertexColumn *column) {
|
||||
if (column == (const GeomVertexColumn *)NULL) {
|
||||
return set_column(0, NULL);
|
||||
}
|
||||
|
||||
nassertr(_array_data != (const GeomVertexArrayData *)NULL, false);
|
||||
|
||||
_stride = array_reader->get_array_format()->get_stride();
|
||||
_handle = _array_data->get_handle();
|
||||
_stride = _handle->get_array_format()->get_stride();
|
||||
|
||||
_packer = column->_packer;
|
||||
set_pointer(_start_row, array_reader);
|
||||
set_pointer(_start_row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,15 +120,13 @@ protected:
|
|||
private:
|
||||
void initialize();
|
||||
|
||||
INLINE void set_pointer(int row,
|
||||
const GeomVertexArrayDataPipelineReader *array_reader);
|
||||
INLINE void set_pointer(int row);
|
||||
INLINE void quick_set_pointer(int row);
|
||||
INLINE const unsigned char *inc_pointer();
|
||||
|
||||
bool set_vertex_column(int array, const GeomVertexColumn *column,
|
||||
const GeomVertexDataPipelineReader *data_reader);
|
||||
bool set_array_column(const GeomVertexColumn *column,
|
||||
const GeomVertexArrayDataPipelineReader *array_reader);
|
||||
bool set_array_column(const GeomVertexColumn *column);
|
||||
|
||||
// It is important that we only store *one* of the following two
|
||||
// pointers. If we are storing a GeomVertexData/array index, we
|
||||
|
|
@ -143,7 +141,7 @@ private:
|
|||
GeomVertexColumn::Packer *_packer;
|
||||
int _stride;
|
||||
|
||||
CPTA_uchar _data;
|
||||
CPT(GeomVertexArrayDataHandle) _handle;
|
||||
const unsigned char *_pointer_begin;
|
||||
const unsigned char *_pointer_end;
|
||||
const unsigned char *_pointer;
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ GeomVertexWriter(const GeomVertexWriter ©) :
|
|||
_current_thread(copy._current_thread),
|
||||
_packer(copy._packer),
|
||||
_stride(copy._stride),
|
||||
_data(copy._data),
|
||||
_handle(copy._handle),
|
||||
_pointer_begin(copy._pointer_begin),
|
||||
_pointer_end(copy._pointer_end),
|
||||
_pointer(copy._pointer),
|
||||
|
|
@ -166,7 +166,7 @@ operator = (const GeomVertexWriter ©) {
|
|||
_current_thread = copy._current_thread;
|
||||
_packer = copy._packer;
|
||||
_stride = copy._stride;
|
||||
_data = copy._data;
|
||||
_handle = copy._handle;
|
||||
_pointer_begin = copy._pointer_begin;
|
||||
_pointer_end = copy._pointer_end;
|
||||
_pointer = copy._pointer;
|
||||
|
|
@ -240,9 +240,7 @@ set_column(int column) {
|
|||
&writer);
|
||||
}
|
||||
if (_array_data != (GeomVertexArrayData *)NULL) {
|
||||
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
|
||||
return set_array_column(writer.get_array_format()->get_column(column),
|
||||
&writer);
|
||||
return set_array_column(_array_data->get_array_format()->get_column(column));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -289,9 +287,7 @@ set_column(const InternalName *name) {
|
|||
&writer);
|
||||
}
|
||||
if (_array_data != (GeomVertexArrayData *)NULL) {
|
||||
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
|
||||
return set_array_column(writer.get_array_format()->get_column(name),
|
||||
&writer);
|
||||
return set_array_column(_array_data->get_array_format()->get_column(name));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -814,10 +810,9 @@ get_packer() const {
|
|||
// and sets the internal pointer to the indicated row.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void GeomVertexWriter::
|
||||
set_pointer(int row, GeomVertexArrayDataPipelineWriter *array_writer) {
|
||||
_data = array_writer->modify_data();
|
||||
_pointer_begin = _data;
|
||||
_pointer_end = _pointer_begin + array_writer->get_data_size_bytes();
|
||||
set_pointer(int row) {
|
||||
_pointer_begin = _handle->get_pointer();
|
||||
_pointer_end = _pointer_begin + _handle->get_data_size_bytes();
|
||||
quick_set_pointer(row);
|
||||
}
|
||||
|
||||
|
|
@ -832,21 +827,16 @@ INLINE void GeomVertexWriter::
|
|||
quick_set_pointer(int row) {
|
||||
nassertv(has_column());
|
||||
|
||||
#if defined(_DEBUG) && !defined(HAVE_THREADS)
|
||||
// Make sure we still have the same pointer as stored the array. We
|
||||
// only perform this test in debug mode, because it is expensive,
|
||||
// and only in single-threaded mode, because in threaded mode
|
||||
// another thread might have reallocated the other pointer outside
|
||||
// of our control anyway.
|
||||
if (_vertex_data != (const GeomVertexData *)NULL) {
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertv(_pointer_begin == array_data->get_data());
|
||||
} else {
|
||||
nassertv(_pointer_begin == _array_data->get_data());
|
||||
}
|
||||
#if defined(_DEBUG)
|
||||
// Make sure we still have the same pointer as stored in the array.
|
||||
nassertv(_pointer_begin == _handle->get_pointer());
|
||||
#endif
|
||||
|
||||
_pointer = _pointer_begin + _packer->_column->get_start() + _stride * row;
|
||||
|
||||
#if defined(_DEBUG)
|
||||
nassertv(_pointer_begin == _pointer_end || _pointer <= _pointer_end);
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -857,14 +847,11 @@ quick_set_pointer(int row) {
|
|||
////////////////////////////////////////////////////////////////////
|
||||
INLINE unsigned char *GeomVertexWriter::
|
||||
inc_pointer() {
|
||||
#ifdef _DEBUG
|
||||
#if defined(_DEBUG)
|
||||
nassertr(_pointer < _pointer_end, empty_buffer);
|
||||
if (_vertex_data != (GeomVertexData *)NULL){
|
||||
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
|
||||
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
|
||||
} else {
|
||||
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
|
||||
}
|
||||
// Make sure we still have the same pointer as stored in the array.
|
||||
nassertr(_pointer_begin == _handle->get_pointer(), empty_buffer);
|
||||
nassertr(_pointer < _pointer_begin + _handle->get_data_size_bytes(), empty_buffer);
|
||||
#endif
|
||||
|
||||
unsigned char *orig_pointer = _pointer;
|
||||
|
|
@ -885,16 +872,23 @@ inc_add_pointer() {
|
|||
if (_pointer >= _pointer_end) {
|
||||
// Reset the data pointer.
|
||||
int write_row = get_write_row();
|
||||
|
||||
if (_vertex_data != (GeomVertexData *)NULL) {
|
||||
// If we have a whole GeomVertexData, we must set the length of
|
||||
// all its arrays at once.
|
||||
GeomVertexDataPipelineWriter writer(_vertex_data, true, _current_thread);
|
||||
writer.check_array_writers();
|
||||
writer.set_num_rows(max(write_row + 1, writer.get_num_rows()));
|
||||
set_pointer(write_row, writer.get_array_writer(_array));
|
||||
_handle = writer.get_array_writer(_array);
|
||||
|
||||
} else {
|
||||
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
|
||||
writer.set_num_rows(max(write_row + 1, writer.get_num_rows()));
|
||||
set_pointer(write_row, &writer);
|
||||
// Otherwise, we can get away with modifying only the one array
|
||||
// we're using.
|
||||
_handle->set_num_rows(max(write_row + 1, _handle->get_num_rows()));
|
||||
}
|
||||
|
||||
set_pointer(write_row);
|
||||
}
|
||||
return inc_pointer();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,8 +62,7 @@ set_column(int array, const GeomVertexColumn *column) {
|
|||
return set_vertex_column(array, column, &writer);
|
||||
}
|
||||
if (_array_data != (GeomVertexArrayData *)NULL) {
|
||||
GeomVertexArrayDataPipelineWriter writer(_array_data, true, _current_thread);
|
||||
return set_array_column(column, &writer);
|
||||
return set_array_column(column);
|
||||
}
|
||||
|
||||
// No data is associated with the Writer.
|
||||
|
|
@ -126,12 +125,11 @@ set_vertex_column(int array, const GeomVertexColumn *column,
|
|||
#endif
|
||||
|
||||
_array = array;
|
||||
GeomVertexArrayDataPipelineWriter *array_writer =
|
||||
data_writer->get_array_writer(_array);
|
||||
_stride = array_writer->get_array_format()->get_stride();
|
||||
_handle = data_writer->get_array_writer(_array);
|
||||
_stride = _handle->get_array_format()->get_stride();
|
||||
|
||||
_packer = column->_packer;
|
||||
set_pointer(_start_row, array_writer);
|
||||
set_pointer(_start_row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -144,18 +142,18 @@ set_vertex_column(int array, const GeomVertexColumn *column,
|
|||
// GeomVertexArrayData.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool GeomVertexWriter::
|
||||
set_array_column(const GeomVertexColumn *column,
|
||||
GeomVertexArrayDataPipelineWriter *array_writer) {
|
||||
set_array_column(const GeomVertexColumn *column) {
|
||||
if (column == (const GeomVertexColumn *)NULL) {
|
||||
return set_column(0, NULL);
|
||||
}
|
||||
|
||||
nassertr(_array_data != (GeomVertexArrayData *)NULL, false);
|
||||
|
||||
_stride = array_writer->get_array_format()->get_stride();
|
||||
_handle = _array_data->modify_handle();
|
||||
_stride = _handle->get_array_format()->get_stride();
|
||||
|
||||
_packer = column->_packer;
|
||||
set_pointer(_start_row, array_writer);
|
||||
set_pointer(_start_row);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -157,16 +157,14 @@ private:
|
|||
|
||||
void initialize();
|
||||
|
||||
INLINE void set_pointer(int row,
|
||||
GeomVertexArrayDataPipelineWriter *array_writer);
|
||||
INLINE void set_pointer(int row);
|
||||
INLINE void quick_set_pointer(int row);
|
||||
INLINE unsigned char *inc_pointer();
|
||||
INLINE unsigned char *inc_add_pointer();
|
||||
|
||||
bool set_vertex_column(int array, const GeomVertexColumn *column,
|
||||
GeomVertexDataPipelineWriter *data_writer);
|
||||
bool set_array_column(const GeomVertexColumn *column,
|
||||
GeomVertexArrayDataPipelineWriter *array_writer);
|
||||
bool set_array_column(const GeomVertexColumn *column);
|
||||
|
||||
// It is important that we only store *one* of the following two
|
||||
// pointers. If we are storing a GeomVertexData/array index, we
|
||||
|
|
@ -181,7 +179,7 @@ private:
|
|||
GeomVertexColumn::Packer *_packer;
|
||||
int _stride;
|
||||
|
||||
PTA_uchar _data;
|
||||
PT(GeomVertexArrayDataHandle) _handle;
|
||||
unsigned char *_pointer_begin;
|
||||
unsigned char *_pointer_end;
|
||||
unsigned char *_pointer;
|
||||
|
|
|
|||
|
|
@ -1,25 +1,28 @@
|
|||
#include "bufferContext.cxx"
|
||||
#include "bufferContextChain.cxx"
|
||||
#include "bufferResidencyTracker.cxx"
|
||||
#include "config_gobj.cxx"
|
||||
#include "geom.cxx"
|
||||
#include "geomContext.cxx"
|
||||
#include "geomEnums.cxx"
|
||||
#include "geomMunger.cxx"
|
||||
#include "geomPrimitive.cxx"
|
||||
#include "geomTriangles.cxx"
|
||||
#include "geomTristrips.cxx"
|
||||
#include "geomTrifans.cxx"
|
||||
#include "geomLines.cxx"
|
||||
#include "geomLinestrips.cxx"
|
||||
#include "geomPoints.cxx"
|
||||
#include "geomVertexArrayData.cxx"
|
||||
#include "geomVertexArrayFormat.cxx"
|
||||
#include "geomCacheEntry.cxx"
|
||||
#include "geomCacheManager.cxx"
|
||||
#include "geomContext.cxx"
|
||||
#include "geomEnums.cxx"
|
||||
#include "geomLines.cxx"
|
||||
#include "geomLinestrips.cxx"
|
||||
#include "geomMunger.cxx"
|
||||
#include "geomPoints.cxx"
|
||||
#include "geomPrimitive.cxx"
|
||||
#include "geomTriangles.cxx"
|
||||
#include "geomTrifans.cxx"
|
||||
#include "geomTristrips.cxx"
|
||||
#include "geomVertexAnimationSpec.cxx"
|
||||
#include "geomVertexData.cxx"
|
||||
#include "geomVertexArrayData.cxx"
|
||||
#include "geomVertexArrayFormat.cxx"
|
||||
#include "geomVertexColumn.cxx"
|
||||
#include "geomVertexData.cxx"
|
||||
#include "geomVertexFormat.cxx"
|
||||
#include "geomVertexReader.cxx"
|
||||
#include "geomVertexRewriter.cxx"
|
||||
#include "geomVertexWriter.cxx"
|
||||
#include "indexBufferContext.cxx"
|
||||
#include "internalName.cxx"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,3 @@
|
|||
#include "config_gobj.cxx"
|
||||
#include "indexBufferContext.cxx"
|
||||
#include "internalName.cxx"
|
||||
#include "lens.cxx"
|
||||
#include "material.cxx"
|
||||
#include "materialPool.cxx"
|
||||
|
|
@ -11,14 +8,15 @@
|
|||
#include "preparedGraphicsObjects.cxx"
|
||||
#include "queryContext.cxx"
|
||||
#include "savedContext.cxx"
|
||||
#include "shaderContext.cxx"
|
||||
#include "shaderExpansion.cxx"
|
||||
#include "simpleLru.cxx"
|
||||
#include "sliderTable.cxx"
|
||||
#include "texture.cxx"
|
||||
#include "textureContext.cxx"
|
||||
#include "texturePool.cxx"
|
||||
#include "texturePoolFilter.cxx"
|
||||
#include "textureStage.cxx"
|
||||
#include "shaderExpansion.cxx"
|
||||
#include "shaderContext.cxx"
|
||||
#include "transformBlend.cxx"
|
||||
#include "transformBlendTable.cxx"
|
||||
#include "transformTable.cxx"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,203 @@
|
|||
// Filename: simpleLru.I
|
||||
// Created by: drose (11May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::Constructor
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SimpleLru::
|
||||
SimpleLru(size_t max_size) : LinkedListNode(true) {
|
||||
_total_size = 0;
|
||||
_max_size = max_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::get_total_size
|
||||
// Access: Published
|
||||
// Description: Returns the total size of all objects currently
|
||||
// active on the LRU.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleLru::
|
||||
get_total_size() const {
|
||||
return _total_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::get_max_size
|
||||
// Access: Published
|
||||
// Description: Returns the max size of all objects that are allowed
|
||||
// to be active on the LRU.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleLru::
|
||||
get_max_size() const {
|
||||
return _max_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::set_max_size
|
||||
// Access: Published
|
||||
// Description: Changes the max size of all objects that are allowed
|
||||
// to be active on the LRU.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLru::
|
||||
set_max_size(size_t max_size) {
|
||||
_max_size = max_size;
|
||||
consider_evict();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::consider_evict
|
||||
// Access: Published
|
||||
// Description: Evicts a sequence of objects if the queue is full.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLru::
|
||||
consider_evict() {
|
||||
if (_max_size != 0 && _total_size > _max_size) {
|
||||
do_evict();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleLruPage::
|
||||
SimpleLruPage(size_t lru_size) :
|
||||
_lru(NULL),
|
||||
_lru_size(lru_size)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::Copy Constructor
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleLruPage::
|
||||
SimpleLruPage(const SimpleLruPage ©) :
|
||||
_lru(NULL),
|
||||
_lru_size(copy._lru_size)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::Copy Assignment Operator
|
||||
// Access: Protected
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLruPage::
|
||||
operator = (const SimpleLruPage ©) {
|
||||
set_lru_size(copy.get_lru_size());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::enqueue_lru
|
||||
// Access: Published
|
||||
// Description: Returns the LRU that manages this page, or NULL if it
|
||||
// is not currently managed by any LRU.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE SimpleLru *SimpleLruPage::
|
||||
get_lru() const {
|
||||
return _lru;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::enqueue_lru
|
||||
// Access: Published
|
||||
// Description: Adds the page to the tail of the SimpleLru. When it
|
||||
// reaches the head, it will be the next to be evicted.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLruPage::
|
||||
enqueue_lru(SimpleLru *lru) {
|
||||
dequeue_lru();
|
||||
_lru = lru;
|
||||
_lru->_total_size += _lru_size;
|
||||
insert_before(_lru);
|
||||
|
||||
// Let's not automatically evict pages; instead, we'll evict only on
|
||||
// an explicit epoch test.
|
||||
// _lru->consider_evict();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::dequeue_lru
|
||||
// Access: Published
|
||||
// Description: Removes the page from its SimpleLru.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLruPage::
|
||||
dequeue_lru() {
|
||||
if (_lru != (SimpleLru *)NULL) {
|
||||
remove_from_list();
|
||||
_lru->_total_size -= _lru_size;
|
||||
_lru = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::mark_used_lru
|
||||
// Access: Published
|
||||
// Description: To be called when the page is used; this will move it
|
||||
// to the tail of the SimpleLru queue it is already on.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLruPage::
|
||||
mark_used_lru() {
|
||||
if (_lru != (SimpleLru *)NULL) {
|
||||
mark_used_lru(_lru);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::mark_used_lru
|
||||
// Access: Published
|
||||
// Description: To be called when the page is used; this will move it
|
||||
// to the tail of the specified SimpleLru queue.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLruPage::
|
||||
mark_used_lru(SimpleLru *lru) {
|
||||
dequeue_lru();
|
||||
enqueue_lru(lru);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::get_lru_size
|
||||
// Access: Published
|
||||
// Description: Returns the size of this page as reported to the LRU,
|
||||
// presumably in bytes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE size_t SimpleLruPage::
|
||||
get_lru_size() const {
|
||||
return _lru_size;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::set_lru_size
|
||||
// Access: Published
|
||||
// Description: Specifies the size of this page, presumably in bytes,
|
||||
// although any units is possible.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void SimpleLruPage::
|
||||
set_lru_size(size_t lru_size) {
|
||||
if (_lru != (SimpleLru *)NULL) {
|
||||
_lru->_total_size -= _lru_size;
|
||||
_lru->_total_size += lru_size;
|
||||
}
|
||||
_lru_size = lru_size;
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
// Filename: simpleLru.cxx
|
||||
// Created by: drose (11May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "simpleLru.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::Destructor
|
||||
// Access: Protected, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SimpleLru::
|
||||
~SimpleLru() {
|
||||
#ifndef NDEBUG
|
||||
// We're shutting down. Force-remove everything remaining, but
|
||||
// don't explicitly evict it (that would force vertex buffers to
|
||||
// write themselves to disk unnecessarily).
|
||||
while (_next != (LinkedListNode *)NULL) {
|
||||
((SimpleLruPage *)_next)->_lru = NULL;
|
||||
((SimpleLruPage *)_next)->remove_from_list();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLru::do_evict
|
||||
// Access: Private
|
||||
// Description: Evicts pages until the LRU is within tolerance.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SimpleLru::
|
||||
do_evict() {
|
||||
// Store the current end of the list. If pages re-enqueue
|
||||
// themselves during this traversal, we don't want to visit them
|
||||
// twice.
|
||||
SimpleLruPage *end = (SimpleLruPage *)_prev;
|
||||
|
||||
// Now walk through the list.
|
||||
SimpleLruPage *node = (SimpleLruPage *)_next;
|
||||
while (_total_size > _max_size) {
|
||||
SimpleLruPage *next = (SimpleLruPage *)node->_next;
|
||||
|
||||
node->evict_lru();
|
||||
if (node == end) {
|
||||
// If we reach the original tail of the list, stop.
|
||||
return;
|
||||
}
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::Destructor
|
||||
// Access: Published, Virtual
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
SimpleLruPage::
|
||||
~SimpleLruPage() {
|
||||
if (_lru != NULL) {
|
||||
dequeue_lru();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: SimpleLruPage::evict_lru
|
||||
// Access: Published, Virtual
|
||||
// Description: Evicts the page from the LRU. Called internally when
|
||||
// the LRU determines that it is full. May also be
|
||||
// called externally when necessary to explicitly evict
|
||||
// the page.
|
||||
//
|
||||
// It is legal for this method to either evict the page
|
||||
// as requested, do nothing (in which case the eviction
|
||||
// will be requested again at the next epoch), or
|
||||
// requeue itself on the tail of the queue (in which
|
||||
// case the eviction will be requested again much
|
||||
// later).
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void SimpleLruPage::
|
||||
evict_lru() {
|
||||
dequeue_lru();
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
// Filename: simpleLru.h
|
||||
// Created by: drose (11May07)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 .
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SIMPLELRU_H
|
||||
#define SIMPLELRU_H
|
||||
|
||||
#include "pandabase.h"
|
||||
#include "linkedListNode.h"
|
||||
|
||||
class SimpleLruPage;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SimpleLru
|
||||
// Description : An implementation of a very simple LRU algorithm.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA SimpleLru : public LinkedListNode {
|
||||
PUBLISHED:
|
||||
INLINE SimpleLru(size_t max_size);
|
||||
~SimpleLru();
|
||||
|
||||
INLINE size_t get_total_size() const;
|
||||
INLINE size_t get_max_size() const;
|
||||
INLINE void set_max_size(size_t max_size);
|
||||
|
||||
INLINE void consider_evict();
|
||||
|
||||
private:
|
||||
void do_evict();
|
||||
|
||||
size_t _total_size;
|
||||
size_t _max_size;
|
||||
|
||||
friend class SimpleLruPage;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : SimpleLruPage
|
||||
// Description : One atomic piece that may be managed by a SimpleLru
|
||||
// chain. To use this class, inherit from it and
|
||||
// override evict_lru().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class EXPCL_PANDA SimpleLruPage : public LinkedListNode {
|
||||
PUBLISHED:
|
||||
INLINE SimpleLruPage(size_t lru_size);
|
||||
INLINE SimpleLruPage(const SimpleLruPage ©);
|
||||
INLINE void operator = (const SimpleLruPage ©);
|
||||
|
||||
virtual ~SimpleLruPage();
|
||||
|
||||
INLINE SimpleLru *get_lru() const;
|
||||
|
||||
INLINE void enqueue_lru(SimpleLru *lru);
|
||||
INLINE void dequeue_lru();
|
||||
|
||||
INLINE void mark_used_lru();
|
||||
INLINE void mark_used_lru(SimpleLru *lru);
|
||||
|
||||
INLINE size_t get_lru_size() const;
|
||||
INLINE void set_lru_size(size_t lru_size);
|
||||
|
||||
virtual void evict_lru();
|
||||
|
||||
private:
|
||||
SimpleLru *_lru;
|
||||
|
||||
size_t _lru_size;
|
||||
|
||||
friend class SimpleLru;
|
||||
};
|
||||
|
||||
#include "simpleLru.I"
|
||||
|
||||
#endif
|
||||
|
|
@ -47,7 +47,7 @@ get_data() const {
|
|||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
changed_size(const GeomVertexArrayDataPipelineReader *reader) const {
|
||||
changed_size(const GeomVertexArrayDataHandle *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
return get_data_size_bytes() != (size_t)reader->get_data_size_bytes();
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ changed_size(const GeomVertexArrayDataPipelineReader *reader) const {
|
|||
// since the last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
changed_usage_hint(const GeomVertexArrayDataPipelineReader *reader) const {
|
||||
changed_usage_hint(const GeomVertexArrayDataHandle *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
return _usage_hint != reader->get_usage_hint();
|
||||
}
|
||||
|
|
@ -71,7 +71,7 @@ changed_usage_hint(const GeomVertexArrayDataPipelineReader *reader) const {
|
|||
// last time mark_loaded() was called.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE bool VertexBufferContext::
|
||||
was_modified(const GeomVertexArrayDataPipelineReader *reader) const {
|
||||
was_modified(const GeomVertexArrayDataHandle *reader) const {
|
||||
nassertr(reader->get_object() == _data, false);
|
||||
return get_modified() != reader->get_modified();
|
||||
}
|
||||
|
|
@ -84,7 +84,7 @@ was_modified(const GeomVertexArrayDataPipelineReader *reader) const {
|
|||
// internal flags for changed_size() and modified().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void VertexBufferContext::
|
||||
mark_loaded(const GeomVertexArrayDataPipelineReader *reader) {
|
||||
mark_loaded(const GeomVertexArrayDataHandle *reader) {
|
||||
nassertv(reader->get_object() == _data);
|
||||
update_data_size_bytes(reader->get_data_size_bytes());
|
||||
update_modified(reader->get_modified());
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ public:
|
|||
PUBLISHED:
|
||||
INLINE GeomVertexArrayData *get_data() const;
|
||||
|
||||
INLINE bool changed_size(const GeomVertexArrayDataPipelineReader *reader) const;
|
||||
INLINE bool changed_usage_hint(const GeomVertexArrayDataPipelineReader *reader) const;
|
||||
INLINE bool was_modified(const GeomVertexArrayDataPipelineReader *reader) const;
|
||||
INLINE bool changed_size(const GeomVertexArrayDataHandle *reader) const;
|
||||
INLINE bool changed_usage_hint(const GeomVertexArrayDataHandle *reader) const;
|
||||
INLINE bool was_modified(const GeomVertexArrayDataHandle *reader) const;
|
||||
|
||||
public:
|
||||
INLINE void mark_loaded(const GeomVertexArrayDataPipelineReader *reader);
|
||||
INLINE void mark_loaded(const GeomVertexArrayDataHandle *reader);
|
||||
|
||||
private:
|
||||
// This cannot be a PT(GeomVertexArrayData), because the data and
|
||||
|
|
|
|||
|
|
@ -484,15 +484,16 @@ collect_vertex_data(Geom *geom, int collect_bits) {
|
|||
new_data->set_num_rows(new_num_vertices);
|
||||
|
||||
for (int i = 0; i < vdata->get_num_arrays(); ++i) {
|
||||
GeomVertexArrayData *new_array = new_data->modify_array(i);
|
||||
const GeomVertexArrayData *old_array = vdata->get_array(i);
|
||||
PT(GeomVertexArrayData) new_array = new_data->modify_array(i);
|
||||
CPT(GeomVertexArrayData) old_array = vdata->get_array(i);
|
||||
int stride = format->get_array(i)->get_stride();
|
||||
int start_byte = offset * stride;
|
||||
int copy_bytes = old_array->get_data_size_bytes();
|
||||
nassertr(start_byte + copy_bytes == new_array->get_data_size_bytes(), 0);
|
||||
|
||||
memcpy(new_array->modify_data() + start_byte,
|
||||
old_array->get_data(), copy_bytes);
|
||||
new_array->modify_handle()->copy_subdata_from
|
||||
(start_byte, copy_bytes,
|
||||
old_array->get_handle(), 0, copy_bytes);
|
||||
}
|
||||
|
||||
// Also, copy the animation data (if any). This means combining
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ flatten(PandaNode *root, int combine_siblings_bits) {
|
|||
// Now visit each of the children in turn.
|
||||
int num_children = cr.get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
PandaNode *child_node = cr.get_child(i);
|
||||
PT(PandaNode) child_node = cr.get_child(i);
|
||||
num_pass_nodes += r_flatten(root, child_node, combine_siblings_bits);
|
||||
}
|
||||
|
||||
|
|
@ -271,7 +271,7 @@ r_flatten(PandaNode *grandparent_node, PandaNode *parent_node,
|
|||
PandaNode::Children cr = parent_node->get_children();
|
||||
int num_children = cr.get_num_children();
|
||||
for (int i = 0; i < num_children; i++) {
|
||||
PandaNode *child_node = cr.get_child(i);
|
||||
PT(PandaNode) child_node = cr.get_child(i);
|
||||
num_nodes += r_flatten(parent_node, child_node, combine_siblings_bits);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ main_tick() {
|
|||
|
||||
size_t total_usage = 0;
|
||||
int i;
|
||||
for (int i = 0; i < num_typehandles; ++i) {
|
||||
for (i = 0; i < num_typehandles; ++i) {
|
||||
TypeHandle type = type_reg->get_typehandle(i);
|
||||
for (int mi = 0; mi < (int)TypeHandle::MC_limit; ++mi) {
|
||||
TypeHandle::MemoryClass mc = (TypeHandle::MemoryClass)mi;
|
||||
|
|
@ -245,7 +245,7 @@ main_tick() {
|
|||
}
|
||||
size_t other_usage = total_usage;
|
||||
|
||||
for (int i = 0; i < num_typehandles; ++i) {
|
||||
for (i = 0; i < num_typehandles; ++i) {
|
||||
TypeHandle type = type_reg->get_typehandle(i);
|
||||
for (int mi = 0; mi < (int)TypeHandle::MC_limit; ++mi) {
|
||||
TypeHandle::MemoryClass mc = (TypeHandle::MemoryClass)mi;
|
||||
|
|
|
|||
|
|
@ -199,6 +199,10 @@ static LevelCollectorProperties level_properties[] = {
|
|||
{ 1, "Main memory", { 0.5, 1.0, 0.5 }, "MB", 64, 1048576 },
|
||||
{ 1, "Main memory:C++", { 0.2, 0.2, 1.0 } },
|
||||
{ 1, "Main memory:Interpreter", { 0.8, 0.2, 0.5 } },
|
||||
{ 1, "Vertex Data", { 1.0, 0.4, 0.0 }, "MB", 64, 1048576 },
|
||||
{ 1, "Vertex Data:Disk", { 0.6, 0.9, 0.1 } },
|
||||
{ 1, "Vertex Data:Compressed", { 0.5, 0.1, 0.4 } },
|
||||
{ 1, "Vertex Data:Resident", { 0.9, 0.1, 0.7 } },
|
||||
{ 1, "TransformStates", { 1.0, 0.5, 0.5 }, "", 5000 },
|
||||
{ 1, "TransformStates:On nodes", { 0.2, 0.8, 1.0 } },
|
||||
{ 1, "TransformStates:Cached", { 1.0, 0.0, 0.2 } },
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ get_write_pointer() {
|
|||
if (_object == (CopyOnWriteObject *)NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (_object->get_ref_count() > 1) {
|
||||
if (_object->get_cache_ref_count() > 1) {
|
||||
PT(CopyOnWriteObject) new_object = _object->make_cow_copy();
|
||||
cache_unref_delete(_object);
|
||||
_object = new_object;
|
||||
|
|
|
|||
Loading…
Reference in New Issue