[Bf-blender-cvs] [8cde671] master: Sequencer: Speedup gaussian blur effect

Sergey Sharybin noreply at git.blender.org
Thu Jan 21 20:13:32 CET 2016


Commit: 8cde671f8bd221bc29a117de09946599c343fcd8
Author: Sergey Sharybin
Date:   Fri Jan 22 00:11:37 2016 +0500
Branches: master
https://developer.blender.org/rB8cde671f8bd221bc29a117de09946599c343fcd8

Sequencer: Speedup gaussian blur effect

Apply X and Y blur as separate step, this reduces number of accumulations
required and makes effect more realtime.

Another quick thing for the Nieve project.

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

M	source/blender/blenkernel/intern/seqeffects.c

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

diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 777d599..d87da66 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2667,36 +2667,81 @@ static float *make_gaussian_blur_kernel(float rad, int size)
 	return gausstab;
 }
 
-static void do_gaussian_blur_effect_byte(Sequence *seq,
-                                         int start_line,
-                                         int x, int y,
-                                         int frame_width, int frame_height,
-                                         unsigned char *rect,
-                                         unsigned char *out)
+static void do_gaussian_blur_effect_byte_x(Sequence *seq,
+                                           int start_line,
+                                           int x, int y,
+                                           int frame_width,
+                                           int UNUSED(frame_height),
+                                           unsigned char *rect,
+                                           unsigned char *out)
 {
 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
 	GaussianBlurVars *data = seq->effectdata;
 	const int size_x = (int) (data->size_x + 0.5f);
-	const int size_y = (int) (data->size_y + 0.5f);
 	int i, j;
 
 	/* Make gaussian weight tabke. */
-	float *gausstab_x, *gausstab_y;
+	float *gausstab_x;
 	gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
-	if (data->size_x == data->size_y) {
-		gausstab_y = gausstab_x;
-	}
-	else {
-		gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
+
+	for (i = 0; i < y; ++i) {
+		for (j = 0; j < x; ++j) {
+			int out_index = INDEX(j, i);
+			float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+			float accum_weight = 0.0f;
+
+			for (int current_x = j - size_x;
+			     current_x <= j + size_x;
+			     ++current_x)
+			{
+				if (current_x < 0 || current_x >= frame_width) {
+					/* Out of bounds. */
+					continue;
+				}
+				int index = INDEX(current_x, i + start_line);
+				float weight = gausstab_x[current_x - j + size_x];
+				accum[0] += rect[index] * weight;
+				accum[1] += rect[index + 1] * weight;
+				accum[2] += rect[index + 2] * weight;
+				accum[3] += rect[index + 3] * weight;
+				accum_weight += weight;
+			}
+
+			float inv_accum_weight = 1.0f / accum_weight;
+			out[out_index + 0] = accum[0] * inv_accum_weight;
+			out[out_index + 1] = accum[1] * inv_accum_weight;
+			out[out_index + 2] = accum[2] * inv_accum_weight;
+			out[out_index + 3] = accum[3] * inv_accum_weight;
+		}
 	}
 
+	MEM_freeN(gausstab_x);
+#undef INDEX
+}
+
+static void do_gaussian_blur_effect_byte_y(Sequence *seq,
+                                           int start_line,
+                                           int x, int y,
+                                           int UNUSED(frame_width),
+                                           int frame_height,
+                                           unsigned char *rect,
+                                           unsigned char *out)
+{
+#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
+	GaussianBlurVars *data = seq->effectdata;
+	const int size_y = (int) (data->size_y + 0.5f);
+	int i, j;
+
+	/* Make gaussian weight tabke. */
+	float *gausstab_y;
+	gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
+
 	for (i = 0; i < y; ++i) {
 		for (j = 0; j < x; ++j) {
 			int out_index = INDEX(j, i);
-			int current_x, current_y;
 			float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 			float accum_weight = 0.0f;
-			for (current_y = i - size_y;
+			for (int current_y = i - size_y;
 			     current_y <= i + size_y;
 			     ++current_y)
 			{
@@ -2706,144 +2751,127 @@ static void do_gaussian_blur_effect_byte(Sequence *seq,
 					/* Out of bounds. */
 					continue;
 				}
+				int index = INDEX(j, current_y + start_line);
+				float weight = gausstab_y[current_y - i + size_y];
+				accum[0] += rect[index] * weight;
+				accum[1] += rect[index + 1] * weight;
+				accum[2] += rect[index + 2] * weight;
+				accum[3] += rect[index + 3] * weight;
+				accum_weight += weight;
+			}
+			float inv_accum_weight = 1.0f / accum_weight;
+			out[out_index + 0] = accum[0] * inv_accum_weight;
+			out[out_index + 1] = accum[1] * inv_accum_weight;
+			out[out_index + 2] = accum[2] * inv_accum_weight;
+			out[out_index + 3] = accum[3] * inv_accum_weight;
+		}
+	}
 
-				for (current_x = j - size_x;
-				     current_x <= j + size_x;
-				     ++current_x)
-				{
-					float weight;
-					int index = INDEX(current_x, current_y + start_line);
-					if (current_x < 0 || current_x >= frame_width) {
-						/* Out of bounds. */
-						continue;
-					}
-					BLI_assert(index >= 0);
-					BLI_assert(index < frame_width * frame_height * 4);
-
-					if (size_x != 0 && size_y != 0) {
-						weight = gausstab_x[current_x - j + size_x] *
-							gausstab_y[current_y - i + size_y];
-					}
-					else if (size_x == 0) {
-						weight = gausstab_y[current_y - i + size_y];
-					}
-					else {
-						weight = gausstab_x[current_x - j + size_x];
-					}
-					accum[0] += rect[index] * weight;
-					accum[1] += rect[index + 1] * weight;
-					accum[2] += rect[index + 2] * weight;
-					accum[3] += rect[index + 3] * weight;
-					accum_weight += weight;
+	MEM_freeN(gausstab_y);
+#undef INDEX
+}
+
+static void do_gaussian_blur_effect_float_x(Sequence *seq,
+                                            int start_line,
+                                            int x, int y,
+                                            int frame_width,
+                                            int UNUSED(frame_height),
+                                            float *rect,
+                                            float *out)
+{
+#define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
+	GaussianBlurVars *data = seq->effectdata;
+	const int size_x = (int) (data->size_x + 0.5f);
+	int i, j;
+
+	/* Make gaussian weight tabke. */
+	float *gausstab_x;
+	gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
+
+	for (i = 0; i < y; ++i) {
+		for (j = 0; j < x; ++j) {
+			int out_index = INDEX(j, i);
+			float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+			float accum_weight = 0.0f;
+			for (int current_x = j - size_x;
+			     current_x <= j + size_x;
+			     ++current_x)
+			{
+				if (current_x < 0 || current_x >= frame_width) {
+					/* Out of bounds. */
+					continue;
 				}
+				int index = INDEX(current_x, i + start_line);
+				float weight = gausstab_x[current_x - j + size_x];
+				madd_v4_v4fl(accum, &rect[index], weight);
+				accum_weight += weight;
 			}
-			out[out_index + 0] = accum[0] / accum_weight;
-			out[out_index + 1] = accum[1] / accum_weight;
-			out[out_index + 2] = accum[2] / accum_weight;
-			out[out_index + 3] = accum[3] / accum_weight;
+			mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight);
 		}
 	}
 
 	MEM_freeN(gausstab_x);
-	if (gausstab_x != gausstab_y) {
-		MEM_freeN(gausstab_y);
-	}
 #undef INDEX
 }
 
-static void do_gaussian_blur_effect_float(Sequence *seq,
-                                          int start_line,
-                                          int x, int y,
-                                          int frame_width, int frame_height,
-                                          float *rect,
-                                          float *out)
+static void do_gaussian_blur_effect_float_y(Sequence *seq,
+                                            int start_line,
+                                            int x, int y,
+                                            int UNUSED(frame_width),
+                                            int frame_height,
+                                            float *rect,
+                                            float *out)
 {
 #define INDEX(_x, _y) (((_y) * (x) + (_x)) * 4)
 	GaussianBlurVars *data = seq->effectdata;
-	const int size_x = (int) (data->size_x + 0.5f);
 	const int size_y = (int) (data->size_y + 0.5f);
 	int i, j;
 
 	/* Make gaussian weight tabke. */
-	float *gausstab_x, *gausstab_y;
-	gausstab_x = make_gaussian_blur_kernel(data->size_x, size_x);
-	if (data->size_x == data->size_y) {
-		gausstab_y = gausstab_x;
-	}
-	else {
-		gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
-	}
+	float *gausstab_y;
+	gausstab_y = make_gaussian_blur_kernel(data->size_y, size_y);
 
 	for (i = 0; i < y; ++i) {
 		for (j = 0; j < x; ++j) {
 			int out_index = INDEX(j, i);
-			int current_x, current_y;
 			float accum[4] = {0.0f, 0.0f, 0.0f, 0.0f};
 			float accum_weight = 0.0f;
-			for (current_y = i - size_y;
+			for (int current_y = i - size_y;
 			     current_y <= i + size_y;
 			     ++current_y)
 			{
-				float weight;
 				if (current_y < -start_line ||
 				    current_y + start_line >= frame_height)
 				{
 					/* Out of bounds. */
 					continue;
 				}
-
-				for (current_x = j - size_x;
-				     current_x <= j + size_x;
-				     ++current_x)
-				{
-					int index = INDEX(current_x, current_y + start_line);
-					if (current_x < 0 || current_x >= frame_width) {
-						/* Out of bounds. */
-						continue;
-					}
-
-					if (size_x != 0 && size_y != 0) {
-						weight = gausstab_x[current_x - j + size_x] *
-							gausstab_y[current_y - i + size_y];
-					}
-					else if (size_x == 0) {
-						weight = gausstab_y[current_y - i + size_y];
-					}
-					else {
-						weight = gausstab_x[current_x - j + size_x];
-					}
-					madd_v4_v4fl(accum, &rect[index], weight);
-					accum_weight += weight;
-				}
+				int index = INDEX(j, current_y + start_line);
+				float weight = gausstab_y[current_y - i + size_y];
+				madd_v4_v4fl(accum, &rect[index], weight);
+				accum_weight += weight;
 			}
 			mul_v4_v4fl(&out[out_index], accum, 1.0f / accum_weight);
 		}
 	}
 
-	MEM_freeN(gausstab_x);
-	if (gausstab_x != gausstab_y) {
-		MEM_freeN(gausstab_y);
-	}
+	MEM_freeN(gausstab_y);
 #undef INDEX
 }
 
-static void do_gaussian_blur_effect(const SeqRenderData *context,
-                                    Sequence *seq,
-                                    float UNUSED(cfra),
-                                    float UNUSED(facf0),
-                                    float UNUSED(facf

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list