[Bf-blender-cvs] [5b99b47] opensubdiv-modifier: OpenSubdiv: Avoid per-evaluation heap memory allocation

Sergey Sharybin noreply at git.blender.org
Sat Jul 11 20:02:12 CEST 2015


Commit: 5b99b47e6fd662978868783bdc35d5fb6df4b2de
Author: Sergey Sharybin
Date:   Fri Jul 10 12:27:03 2015 +0200
Branches: opensubdiv-modifier
https://developer.blender.org/rB5b99b47e6fd662978868783bdc35d5fb6df4b2de

OpenSubdiv: Avoid per-evaluation heap memory allocation

===================================================================

M	intern/opensubdiv/opensubdiv_evaluator_capi.cc

===================================================================

diff --git a/intern/opensubdiv/opensubdiv_evaluator_capi.cc b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
index 0447910..a4be717 100644
--- a/intern/opensubdiv/opensubdiv_evaluator_capi.cc
+++ b/intern/opensubdiv/opensubdiv_evaluator_capi.cc
@@ -53,6 +53,10 @@ using OpenSubdiv::Far::TopologyRefiner;
 
 namespace {
 
+/* Helper class to wrap numerous of patch coords into a buffer.
+ * Used to pass coordinates to the CPU evaluator. Other evaluators
+ * are not supported.
+ */
 class PatchCoordBuffer : public std::vector<PatchCoord> {
 public:
 	static PatchCoordBuffer *Create(int size)
@@ -76,6 +80,10 @@ public:
 	}
 };
 
+/* Helper class to wrap single of patch coord into a buffer.
+ * Used to pass coordinates to the CPU evaluator. Other evaluators
+ * are not supported.
+ */
 class SinglePatchCoordBuffer {
 public:
 	SinglePatchCoordBuffer() {
@@ -102,6 +110,32 @@ protected:
 	PatchCoord patch_coord_;
 };
 
+/* Helper class which is aimed to be used in cases when buffer
+ * is small enough and better to be allocated in stack rather
+ * than in heap.
+ *
+ * TODO(sergey): Check if bare arrays could be sued by CPU evalautor.
+ */
+template <int element_size, int num_verts>
+class StackAllocatedBuffer {
+public:
+	static PatchCoordBuffer *Create(int size)
+	{
+		StackAllocatedBuffer<element_size, num_verts> *buffer =
+		        new StackAllocatedBuffer<element_size, num_verts>();
+		return buffer;
+	}
+	float *BindCpuBuffer() {
+		return &data_[0];
+	}
+	int GetNumVertices() {
+		return num_verts;
+	}
+	/* TODO(sergey): Support UpdateData(). */
+protected:
+	float data_[element_size * num_verts];
+};
+
 /* Non-volatile evaluator which can't be used from threads but capable of
  * evaluating multiple patch coords at once.
  */
@@ -391,8 +425,7 @@ public:
 
 	void EvalPatchCoord(PatchCoord& patch_coord, float P[3])
 	{
-		/* TODO(sergey): Avoid per-evaluation heap allocation. */
-		EVAL_VERTEX_BUFFER *vertex_data = EVAL_VERTEX_BUFFER::Create(6, 1, device_context_);
+		StackAllocatedBuffer<6, 1> vertex_data;
 		BufferDescriptor vertex_desc(0, 3, 6);
 		SinglePatchCoordBuffer patch_coord_buffer(patch_coord);
 		const EVALUATOR *eval_instance =
@@ -401,13 +434,12 @@ public:
 		                                                 vertex_desc,
 		                                                 device_context_);
 		EVALUATOR::EvalPatches(src_data_, src_desc_,
-		                       vertex_data, vertex_desc,
+		                       &vertex_data, vertex_desc,
 		                       patch_coord_buffer.GetNumVertices(),
 		                       &patch_coord_buffer,
 		                       patch_table_, eval_instance, device_context_);
-		float *refined_verts = vertex_data->BindCpuBuffer();
+		float *refined_verts = vertex_data.BindCpuBuffer();
 		memcpy(P, refined_verts, sizeof(float) * 3);
-		delete vertex_data;
 	}
 
 	void EvalPatchesWithDerivatives(PatchCoord& patch_coord,
@@ -415,9 +447,7 @@ public:
 	                                float dPdu[3],
 	                                float dPdv[3])
 	{
-		/* TODO(sergey): Avoid per-evaluation heap allocation. */
-		EVAL_VERTEX_BUFFER *vertex_data = EVAL_VERTEX_BUFFER::Create(6, 1, device_context_),
-		                   *derivatives = EVAL_VERTEX_BUFFER::Create(6, 1, device_context_);
+		StackAllocatedBuffer<6, 1> vertex_data, derivatives;
 		BufferDescriptor vertex_desc(0, 3, 6),
 		                 du_desc(0, 3, 6),
 		                 dv_desc(3, 3, 6);
@@ -430,16 +460,16 @@ public:
 		                                                 dv_desc,
 		                                                 device_context_);
 		EVALUATOR::EvalPatches(src_data_, src_desc_,
-		                       vertex_data, vertex_desc,
-		                       derivatives, du_desc,
-		                       derivatives, dv_desc,
+		                       &vertex_data, vertex_desc,
+		                       &derivatives, du_desc,
+		                       &derivatives, dv_desc,
 		                       patch_coord_buffer.GetNumVertices(),
 		                       &patch_coord_buffer,
 		                       patch_table_, eval_instance, device_context_);
-		float *refined_verts = vertex_data->BindCpuBuffer();
+		float *refined_verts = vertex_data.BindCpuBuffer();
 		memcpy(P, refined_verts, sizeof(float) * 3);
 		if (dPdu != NULL || dPdv != NULL) {
-			float *refined_drivatives = derivatives->BindCpuBuffer();
+			float *refined_drivatives = derivatives.BindCpuBuffer();
 			if (dPdu) {
 				memcpy(dPdu, refined_drivatives, sizeof(float) * 3);
 			}
@@ -447,8 +477,6 @@ public:
 				memcpy(dPdv, refined_drivatives + 3, sizeof(float) * 3);
 			}
 		}
-		delete vertex_data;
-		delete derivatives;
 	}
 private:
 	SRC_VERTEX_BUFFER *src_data_;
@@ -599,12 +627,12 @@ void openSubdiv_evaluateLimit(OpenSubdiv_EvaluatorDescr *evaluator_descr,
 	        evaluator_descr->patch_map->FindPatch(osd_face_index, face_u, face_v);
 	PatchCoord patch_coord(*handle, face_u, face_v);
 	if (dPdu != NULL || dPdv != NULL) {
-		evaluator_descr->eval_output->EvalPatchCoord(patch_coord, P);
-	}
-	else {
 		evaluator_descr->eval_output->EvalPatchesWithDerivatives(patch_coord,
 		                                                         P,
 		                                                         dPdu,
 		                                                         dPdv);
 	}
+	else {
+		evaluator_descr->eval_output->EvalPatchCoord(patch_coord, P);
+	}
 }




More information about the Bf-blender-cvs mailing list