mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
gobj: improve performance of GeomPrimitive::make_nonindexed()
It now no longer has to create two GeomVertexArrayDataHandle objects for every vertex it visits.
This commit is contained in:
parent
8a0f438156
commit
301957c591
@ -538,15 +538,26 @@ offset_vertices(int offset, int begin_row, int end_row) {
|
||||
void GeomPrimitive::
|
||||
make_nonindexed(GeomVertexData *dest, const GeomVertexData *source) {
|
||||
Thread *current_thread = Thread::get_current_thread();
|
||||
int num_vertices = get_num_vertices();
|
||||
int dest_start = dest->get_num_rows();
|
||||
int strip_cut_index = get_strip_cut_index();
|
||||
|
||||
dest->set_num_rows(dest_start + num_vertices);
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
int v = get_vertex(i);
|
||||
nassertd(v != strip_cut_index) continue;
|
||||
dest->copy_row_from(dest_start + i, source, v, current_thread);
|
||||
int num_vertices, dest_start;
|
||||
{
|
||||
GeomPrimitivePipelineReader reader(this, current_thread);
|
||||
num_vertices = reader.get_num_vertices();
|
||||
int strip_cut_index = reader.get_strip_cut_index();
|
||||
|
||||
GeomVertexDataPipelineWriter data_writer(dest, false, current_thread);
|
||||
data_writer.check_array_writers();
|
||||
dest_start = data_writer.get_num_rows();
|
||||
data_writer.set_num_rows(dest_start + num_vertices);
|
||||
|
||||
GeomVertexDataPipelineReader data_reader(source, current_thread);
|
||||
data_reader.check_array_readers();
|
||||
|
||||
for (int i = 0; i < num_vertices; ++i) {
|
||||
int v = reader.get_vertex(i);
|
||||
nassertd(v != strip_cut_index) continue;
|
||||
data_writer.copy_row_from(dest_start + i, data_reader, v);
|
||||
}
|
||||
}
|
||||
|
||||
set_nonindexed_vertices(dest_start, num_vertices);
|
||||
|
@ -686,32 +686,13 @@ copy_from(const GeomVertexData *source, bool keep_data_objects,
|
||||
void GeomVertexData::
|
||||
copy_row_from(int dest_row, const GeomVertexData *source,
|
||||
int source_row, Thread *current_thread) {
|
||||
const GeomVertexFormat *source_format = source->get_format();
|
||||
const GeomVertexFormat *dest_format = get_format();
|
||||
nassertv(source_format == dest_format);
|
||||
nassertv(source_row >= 0 && source_row < source->get_num_rows());
|
||||
|
||||
if (dest_row >= get_num_rows()) {
|
||||
// Implicitly add enough rows to get to the indicated row.
|
||||
set_num_rows(dest_row + 1);
|
||||
}
|
||||
GeomVertexDataPipelineReader reader(source, current_thread);
|
||||
reader.check_array_readers();
|
||||
|
||||
int num_arrays = source_format->get_num_arrays();
|
||||
|
||||
for (int i = 0; i < num_arrays; ++i) {
|
||||
PT(GeomVertexArrayDataHandle) dest_handle = modify_array_handle(i);
|
||||
unsigned char *dest_array_data = dest_handle->get_write_pointer();
|
||||
|
||||
CPT(GeomVertexArrayDataHandle) source_array_handle = source->get_array_handle(i);
|
||||
const unsigned char *source_array_data = source_array_handle->get_read_pointer(true);
|
||||
|
||||
const GeomVertexArrayFormat *array_format = source_format->get_array(i);
|
||||
int stride = array_format->get_stride();
|
||||
|
||||
memcpy(dest_array_data + stride * dest_row,
|
||||
source_array_data + stride * source_row,
|
||||
stride);
|
||||
}
|
||||
GeomVertexDataPipelineWriter writer(this, true, current_thread);
|
||||
writer.check_array_writers();
|
||||
writer.copy_row_from(dest_row, reader, source_row);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2601,6 +2582,45 @@ set_array(size_t i, const GeomVertexArrayData *array) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copies a single row of the data from the other array into the indicated row
|
||||
* of this array. In this case, the source format must exactly match the
|
||||
* destination format.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
void GeomVertexDataPipelineWriter::
|
||||
copy_row_from(int dest_row, const GeomVertexDataPipelineReader &source,
|
||||
int source_row) {
|
||||
const GeomVertexFormat *source_format = source.get_format();
|
||||
const GeomVertexFormat *dest_format = get_format();
|
||||
nassertv(source_format == dest_format);
|
||||
nassertv(source_row >= 0 && source_row < source.get_num_rows());
|
||||
nassertv(_got_array_writers);
|
||||
|
||||
if (dest_row >= get_num_rows()) {
|
||||
// Implicitly add enough rows to get to the indicated row.
|
||||
set_num_rows(dest_row + 1);
|
||||
}
|
||||
|
||||
size_t num_arrays = source_format->get_num_arrays();
|
||||
for (size_t i = 0; i < num_arrays; ++i) {
|
||||
GeomVertexArrayDataHandle *dest_handle = get_array_writer(i);
|
||||
unsigned char *dest_array_data = dest_handle->get_write_pointer();
|
||||
|
||||
const GeomVertexArrayDataHandle *source_array_handle = source.get_array_reader(i);
|
||||
const unsigned char *source_array_data = source_array_handle->get_read_pointer(true);
|
||||
|
||||
const GeomVertexArrayFormat *array_format = source_format->get_array(i);
|
||||
int stride = array_format->get_stride();
|
||||
|
||||
memcpy(dest_array_data + stride * dest_row,
|
||||
source_array_data + stride * source_row,
|
||||
stride);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -526,6 +526,9 @@ public:
|
||||
bool unclean_set_num_rows(int n);
|
||||
bool reserve_num_rows(int n);
|
||||
|
||||
void copy_row_from(int dest_row, const GeomVertexDataPipelineReader &source,
|
||||
int source_row);
|
||||
|
||||
private:
|
||||
void make_array_writers();
|
||||
void delete_array_writers();
|
||||
|
Loading…
x
Reference in New Issue
Block a user