Big perf improvement flattening and munging vertex colors

This commit is contained in:
rdb 2015-11-12 23:28:58 +01:00
parent 36722ebe70
commit 0fffcdfc6b
3 changed files with 63 additions and 11 deletions

View File

@ -433,6 +433,7 @@ private:
};
friend class GeomVertexArrayFormat;
friend class GeomVertexData;
friend class GeomVertexReader;
friend class GeomVertexWriter;
};

View File

@ -976,11 +976,7 @@ set_color(const LColor &color) const {
}
PT(GeomVertexData) new_data = new GeomVertexData(*this);
GeomVertexWriter to(new_data, InternalName::get_color());
while (!to.is_at_end()) {
to.set_data4(color);
}
do_set_color(new_data, color);
return new_data;
}
@ -1008,12 +1004,7 @@ set_color(const LColor &color, int num_components,
PT(GeomVertexData) new_data = replace_column
(InternalName::get_color(), num_components, numeric_type, contents);
// Now go through and set the new color value.
GeomVertexWriter to(new_data, InternalName::get_color());
while (!to.is_at_end()) {
to.set_data4(color);
}
do_set_color(new_data, color);
return new_data;
}
@ -1196,6 +1187,64 @@ transform_vertices(const LMatrix4 &mat, int begin_row, int end_row) {
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::do_set_color
// Access: Private, Static
// Description: Fills in the color column of the given vertex data
// object with a constant color. Assumes that there
// is already a color column present.
////////////////////////////////////////////////////////////////////
void GeomVertexData::
do_set_color(GeomVertexData *vdata, const LColor &color) {
// This function is used relatively often (by the SceneGraphReducer,
// when flattening colors, and by the munger, when munging colors),
// so I've written out a version that avoids the performance overhead
// of the packer and GeomVertexWriter.
const GeomVertexFormat *format = vdata->get_format();
const GeomVertexColumn *column;
int array_index;
if (!format->get_array_info(InternalName::get_color(), array_index, column)) {
nassertv(false);
}
size_t stride = format->get_array(array_index)->get_stride();
GeomVertexColumn::Packer *packer = column->_packer;
nassertv(packer != NULL);
// Pack into a buffer, which we will then copy.
unsigned char buffer[32];
size_t bufsize = column->get_total_bytes();
#ifdef STDFLOAT_DOUBLE
packer->set_data4d(buffer, color);
#else
packer->set_data4f(buffer, color);
#endif
PT(GeomVertexArrayDataHandle) handle =
vdata->modify_array(array_index)->modify_handle();
unsigned char *write_ptr = handle->get_write_pointer();
unsigned char *end_ptr = write_ptr + handle->get_data_size_bytes();
write_ptr += column->get_start();
if (bufsize == 4) {
// Most common case.
while (write_ptr < end_ptr) {
write_ptr[0] = buffer[0];
write_ptr[1] = buffer[1];
write_ptr[2] = buffer[2];
write_ptr[3] = buffer[3];
write_ptr += stride;
}
} else {
while (write_ptr < end_ptr) {
memcpy(write_ptr, buffer, bufsize);
write_ptr += stride;
}
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::bytewise_copy
// Access: Private, Static

View File

@ -182,6 +182,8 @@ public:
static INLINE float unpack_ufloat_c(PN_uint32 data);
private:
static void do_set_color(GeomVertexData *vdata, const LColor &color);
static void bytewise_copy(unsigned char *to, int to_stride,
const unsigned char *from, int from_stride,
const GeomVertexColumn *from_type,