From 0fffcdfc6b4e37b00ea53b86d814813c7a8806b8 Mon Sep 17 00:00:00 2001 From: rdb Date: Thu, 12 Nov 2015 23:28:58 +0100 Subject: [PATCH] Big perf improvement flattening and munging vertex colors --- panda/src/gobj/geomVertexColumn.h | 1 + panda/src/gobj/geomVertexData.cxx | 71 ++++++++++++++++++++++++++----- panda/src/gobj/geomVertexData.h | 2 + 3 files changed, 63 insertions(+), 11 deletions(-) diff --git a/panda/src/gobj/geomVertexColumn.h b/panda/src/gobj/geomVertexColumn.h index 8fab9952aa..cd6f8b6efa 100644 --- a/panda/src/gobj/geomVertexColumn.h +++ b/panda/src/gobj/geomVertexColumn.h @@ -433,6 +433,7 @@ private: }; friend class GeomVertexArrayFormat; + friend class GeomVertexData; friend class GeomVertexReader; friend class GeomVertexWriter; }; diff --git a/panda/src/gobj/geomVertexData.cxx b/panda/src/gobj/geomVertexData.cxx index 1ac95c98c3..5715ec3953 100644 --- a/panda/src/gobj/geomVertexData.cxx +++ b/panda/src/gobj/geomVertexData.cxx @@ -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 diff --git a/panda/src/gobj/geomVertexData.h b/panda/src/gobj/geomVertexData.h index de1b3d23d1..08fbdcc4cc 100644 --- a/panda/src/gobj/geomVertexData.h +++ b/panda/src/gobj/geomVertexData.h @@ -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,