Browse Source

Big perf improvement flattening and munging vertex colors

rdb 10 years ago
parent
commit
0fffcdfc6b

+ 1 - 0
panda/src/gobj/geomVertexColumn.h

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

+ 60 - 11
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

+ 2 - 0
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,