[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