[gimp/gimp-attributes-wip: 141/148] app: increasing paint stroke speed
- From: Hartmut Kuhse <hartmutkuhse src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-attributes-wip: 141/148] app: increasing paint stroke speed
- Date: Sat, 7 Feb 2015 13:21:53 +0000 (UTC)
commit e5569c653e42122ea63db193856b1777383339ed
Author: Hartmut Kuhse <hk_priv gmx de>
Date: Fri Jan 30 21:45:33 2015 +0100
app: increasing paint stroke speed
app/paint/gimppaintcore-loops.c | 353 +++++++++++++++++++++++++++++++++++++++
app/paint/gimppaintcore-loops.h | 18 ++
app/paint/gimppaintcore.c | 81 ++++++----
3 files changed, 420 insertions(+), 32 deletions(-)
---
diff --git a/app/paint/gimppaintcore-loops.c b/app/paint/gimppaintcore-loops.c
index a9c0dcb..a2266d1 100644
--- a/app/paint/gimppaintcore-loops.c
+++ b/app/paint/gimppaintcore-loops.c
@@ -27,6 +27,356 @@
#include "operations/gimplayermodefunctions.h"
void
+combine_paint_canvas_buffer (const GimpTempBuf *paint_mask,
+ GimpTempBuf *paint_buf,
+ GeglBuffer *src_buffer,
+ GeglBuffer *dst_buffer,
+ GeglBuffer *mask_buffer,
+ gint mask_x_offset,
+ gint mask_y_offset,
+ GeglBuffer *canvas_buffer,
+ gint x_offset,
+ gint y_offset,
+ gfloat opacity,
+ gboolean stipple,
+ gint p_mask_x_offset,
+ gint p_mask_y_offset,
+ gboolean linear_mode,
+ GimpLayerModeEffects paint_mode)
+{
+ GeglRectangle roi;
+ GeglBufferIterator *iter;
+ GeglRectangle mask_roi;
+ GeglRectangle process_roi;
+ const Babl *iterator_format;
+
+ const gint mask_stride = gimp_temp_buf_get_width (paint_mask);
+ const gint mask_start_offset = mask_y_offset * mask_stride + mask_x_offset;
+ const Babl *mask_format = gimp_temp_buf_get_format (paint_mask);
+
+ const guint paint_stride = gimp_temp_buf_get_width (paint_buf);
+ gfloat *paint_data = (gfloat *) gimp_temp_buf_get_data (paint_buf);
+
+ const guint blend_stride = gimp_temp_buf_get_width (paint_buf);
+ gfloat *blend_data = (gfloat *) gimp_temp_buf_get_data (paint_buf);
+
+ GimpLayerModeFunction apply_func = get_layer_mode_function (paint_mode);
+
+ if (linear_mode)
+ iterator_format = babl_format ("RGBA float");
+ else
+ iterator_format = babl_format ("R'G'B'A float");
+
+ roi.x = x_offset;
+ roi.y = y_offset;
+ roi.width = gimp_temp_buf_get_width (paint_mask) - mask_x_offset;
+ roi.height = gimp_temp_buf_get_height (paint_mask) - mask_y_offset;
+
+ mask_roi.x = roi.x + p_mask_x_offset;
+ mask_roi.y = roi.y + p_mask_y_offset;
+ mask_roi.width = roi.width;
+ mask_roi.height = roi.height;
+
+ g_return_if_fail (gimp_temp_buf_get_format (paint_buf) == iterator_format);
+
+// g_print ("combine_paint_mask_to_canvas_mask: %d, %d, %d, %d\n", roi.x, roi.y, roi.width, roi.height);
+ iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0,
+ babl_format ("Y float"),
+ GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);
+
+ gegl_buffer_iterator_add (iter, dst_buffer, &roi, 0,
+ iterator_format,
+ GEGL_ACCESS_WRITE, GEGL_ABYSS_NONE);
+
+ gegl_buffer_iterator_add (iter, src_buffer, &roi, 0,
+ iterator_format,
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+
+ if (mask_buffer)
+ {
+ gegl_buffer_iterator_add (iter, mask_buffer, &mask_roi, 0,
+ babl_format ("Y float"),
+ GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
+ }
+
+ if (paint_mask != NULL)
+ {
+ if (stipple)
+ {
+ if (mask_format == babl_format ("Y u8"))
+ {
+ const guint8 *mask_data = (const guint8 *) gimp_temp_buf_get_data (paint_mask);
+ mask_data += mask_start_offset;
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ gfloat *out_pixel = (gfloat *)iter->data[0];
+ int iy, ix;
+ gfloat *bout_pixel = (gfloat *)iter->data[1];
+ gfloat *bin_pixel = (gfloat *)iter->data[2];
+ gfloat *bmask_pixel = NULL;
+ gfloat *bpaint_pixel = blend_data + ((iter->roi[0].y - roi.y) * blend_stride +
iter->roi[0].x - roi.x) * 4;
+
+ if (mask_buffer)
+ bmask_pixel = (gfloat *)iter->data[3];
+
+ process_roi.x = iter->roi[1].x;
+ process_roi.width = iter->roi[1].width;
+ process_roi.height = 1;
+
+
+ for (iy = 0; iy < iter->roi[0].height; iy++)
+ {
+ int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
+ const guint8 *mask_pixel = &mask_data[mask_offset];
+ int paint_offset = (iy + iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x -
roi.x;
+ float *paint_pixel = &paint_data[paint_offset * 4];
+
+ for (ix = 0; ix < iter->roi[0].width; ix++)
+ {
+ out_pixel[0] += (1.0 - out_pixel[0]) * (*mask_pixel / 255.0f) * opacity;
+ paint_pixel[3] *= *out_pixel;
+
+ paint_pixel += 4;
+ mask_pixel += 1;
+ out_pixel += 1;
+ }
+ {
+ process_roi.y = iter->roi[1].y + iy;
+
+ (*apply_func) (bin_pixel,
+ bpaint_pixel,
+ bmask_pixel,
+ bout_pixel,
+ opacity,
+ iter->roi[1].width,
+ &process_roi,
+ 0);
+
+ bin_pixel += iter->roi[1].width * 4;
+ bout_pixel += iter->roi[1].width * 4;
+ if (mask_buffer)
+ bmask_pixel += iter->roi[1].width;
+ bpaint_pixel += blend_stride * 4;
+ }
+
+ }
+ }
+ }
+ else if (mask_format == babl_format ("Y float"))
+ {
+ const gfloat *mask_data = (const gfloat *) gimp_temp_buf_get_data (paint_mask);
+ mask_data += mask_start_offset;
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ gfloat *out_pixel = (gfloat *)iter->data[0];
+ int iy, ix;
+ gfloat *bout_pixel = (gfloat *)iter->data[1];
+ gfloat *bin_pixel = (gfloat *)iter->data[2];
+ gfloat *bmask_pixel = NULL;
+ gfloat *bpaint_pixel = blend_data + ((iter->roi[0].y - roi.y) * blend_stride +
iter->roi[0].x - roi.x) * 4;
+
+ if (mask_buffer)
+ bmask_pixel = (gfloat *)iter->data[3];
+
+ process_roi.x = iter->roi[1].x;
+ process_roi.width = iter->roi[1].width;
+ process_roi.height = 1;
+
+
+ for (iy = 0; iy < iter->roi[0].height; iy++)
+ {
+ int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x -
roi.x;
+ int paint_offset = (iy + iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x -
roi.x;
+ const gfloat *mask_pixel = &mask_data[mask_offset];
+ float *paint_pixel = &paint_data[paint_offset * 4];
+
+ for (ix = 0; ix < iter->roi[0].width; ix++)
+ {
+ out_pixel[0] += (1.0 - out_pixel[0]) * (*mask_pixel) * opacity;
+ paint_pixel[3] *= *out_pixel;
+
+ paint_pixel += 4;
+ mask_pixel += 1;
+ out_pixel += 1;
+ }
+ {
+ process_roi.y = iter->roi[1].y + iy;
+
+ (*apply_func) (bin_pixel,
+ bpaint_pixel,
+ bmask_pixel,
+ bout_pixel,
+ opacity,
+ iter->roi[1].width,
+ &process_roi,
+ 0);
+
+ bin_pixel += iter->roi[1].width * 4;
+ bout_pixel += iter->roi[1].width * 4;
+ if (mask_buffer)
+ bmask_pixel += iter->roi[1].width;
+ bpaint_pixel += blend_stride * 4;
+ }
+ }
+ }
+ }
+ else
+ {
+ g_warning("Mask format not supported: %s", babl_get_name (mask_format));
+ }
+ }
+ else
+ {
+ if (mask_format == babl_format ("Y u8"))
+ {
+ const guint8 *mask_data = (const guint8 *) gimp_temp_buf_get_data (paint_mask);
+ mask_data += mask_start_offset;
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ gfloat *out_pixel = (gfloat *)iter->data[0];
+ int iy, ix;
+ gfloat *bout_pixel = (gfloat *)iter->data[1];
+ gfloat *bin_pixel = (gfloat *)iter->data[2];
+ gfloat *bmask_pixel = NULL;
+ gfloat *bpaint_pixel = blend_data + ((iter->roi[0].y - roi.y) * blend_stride +
iter->roi[0].x - roi.x) * 4;
+
+ if (mask_buffer)
+ bmask_pixel = (gfloat *)iter->data[3];
+
+ process_roi.x = iter->roi[1].x;
+ process_roi.width = iter->roi[1].width;
+ process_roi.height = 1;
+
+ for (iy = 0; iy < iter->roi[0].height; iy++)
+ {
+ int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
+ const guint8 *mask_pixel = &mask_data[mask_offset];
+ int paint_offset = (iy + iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x -
roi.x;
+ float *paint_pixel = &paint_data[paint_offset * 4];
+
+ for (ix = 0; ix < iter->roi[0].width; ix++)
+ {
+ if (opacity > out_pixel[0])
+ out_pixel[0] += (opacity - out_pixel[0]) * (*mask_pixel / 255.0f) * opacity;
+
+ paint_pixel[3] *= *out_pixel;
+
+ paint_pixel += 4;
+ mask_pixel += 1;
+ out_pixel += 1;
+ }
+ {
+ process_roi.y = iter->roi[1].y + iy;
+
+ (*apply_func) (bin_pixel,
+ bpaint_pixel,
+ bmask_pixel,
+ bout_pixel,
+ opacity,
+ iter->roi[1].width,
+ &process_roi,
+ 0);
+
+ bin_pixel += iter->roi[1].width * 4;
+ bout_pixel += iter->roi[1].width * 4;
+ if (mask_buffer)
+ bmask_pixel += iter->roi[1].width;
+ bpaint_pixel += blend_stride * 4;
+ }
+ }
+ }
+ }
+ else if (mask_format == babl_format ("Y float"))
+ {
+ const gfloat *mask_data = (const gfloat *) gimp_temp_buf_get_data (paint_mask);
+ mask_data += mask_start_offset;
+
+ while (gegl_buffer_iterator_next (iter))
+ {
+ gfloat *out_pixel = (gfloat *)iter->data[0];
+ int iy, ix;
+ gfloat *bout_pixel = (gfloat *)iter->data[1];
+ gfloat *bin_pixel = (gfloat *)iter->data[2];
+ gfloat *bmask_pixel = NULL;
+ gfloat *bpaint_pixel = blend_data + ((iter->roi[0].y - roi.y) * blend_stride +
iter->roi[0].x - roi.x) * 4;
+
+ if (mask_buffer)
+ bmask_pixel = (gfloat *)iter->data[3];
+
+ process_roi.x = iter->roi[1].x;
+ process_roi.width = iter->roi[1].width;
+ process_roi.height = 1;
+
+
+ for (iy = 0; iy < iter->roi[0].height; iy++)
+ {
+ int mask_offset = (iy + iter->roi[0].y - roi.y) * mask_stride + iter->roi[0].x - roi.x;
+ const gfloat *mask_pixel = &mask_data[mask_offset];
+ int paint_offset = (iy + iter->roi[0].y - roi.y) * paint_stride + iter->roi[0].x -
roi.x;
+ float *paint_pixel = &paint_data[paint_offset * 4];
+
+ for (ix = 0; ix < iter->roi[0].width; ix++)
+ {
+ if (opacity > out_pixel[0])
+ out_pixel[0] += (opacity - out_pixel[0]) * (*mask_pixel) * opacity;
+
+ paint_pixel[3] *= *out_pixel;
+
+ paint_pixel += 4;
+ mask_pixel += 1;
+ out_pixel += 1;
+ }
+ {
+ process_roi.y = iter->roi[1].y + iy;
+
+ (*apply_func) (bin_pixel,
+ bpaint_pixel,
+ bmask_pixel,
+ bout_pixel,
+ opacity,
+ iter->roi[1].width,
+ &process_roi,
+ 0);
+
+ bin_pixel += iter->roi[1].width * 4;
+ bout_pixel += iter->roi[1].width * 4;
+ if (mask_buffer)
+ bmask_pixel += iter->roi[1].width;
+ bpaint_pixel += blend_stride * 4;
+ }
+ }
+ }
+ }
+ else
+ {
+ g_warning("Mask format not supported: %s", babl_get_name (mask_format));
+ }
+ }
+ }
+ else
+ {
+ canvas_buffer_to_paint_buf_alpha (paint_buf,
+ canvas_buffer,
+ x_offset,
+ y_offset);
+ do_layer_blend (src_buffer,
+ dst_buffer,
+ paint_buf,
+ mask_buffer,
+ opacity,
+ x_offset,
+ y_offset,
+ mask_x_offset,
+ mask_y_offset,
+ linear_mode,
+ paint_mode);
+ }
+}
+
+void
combine_paint_mask_to_canvas_mask (const GimpTempBuf *paint_mask,
gint mask_x_offset,
gint mask_y_offset,
@@ -48,6 +398,7 @@ combine_paint_mask_to_canvas_mask (const GimpTempBuf *paint_mask,
roi.width = gimp_temp_buf_get_width (paint_mask) - mask_x_offset;
roi.height = gimp_temp_buf_get_height (paint_mask) - mask_y_offset;
+// g_print ("combine_paint_mask_to_canvas_mask: %d, %d, %d, %d\n", roi.x, roi.y, roi.width, roi.height);
iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0,
babl_format ("Y float"),
GEGL_ACCESS_READWRITE, GEGL_ABYSS_NONE);
@@ -188,6 +539,8 @@ canvas_buffer_to_paint_buf_alpha (GimpTempBuf *paint_buf,
roi.width = gimp_temp_buf_get_width (paint_buf);
roi.height = gimp_temp_buf_get_height (paint_buf);
+// g_print ("canvas_buffer_to_paint_buf_alpha: %d, %d, %d, %d\n", roi.x, roi.y, roi.width, roi.height);
+
iter = gegl_buffer_iterator_new (canvas_buffer, &roi, 0,
babl_format ("Y float"),
GEGL_ACCESS_READ, GEGL_ABYSS_NONE);
diff --git a/app/paint/gimppaintcore-loops.h b/app/paint/gimppaintcore-loops.h
index e8ceafa..154ce55 100644
--- a/app/paint/gimppaintcore-loops.h
+++ b/app/paint/gimppaintcore-loops.h
@@ -15,6 +15,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+void
+combine_paint_canvas_buffer (const GimpTempBuf *paint_mask,
+ GimpTempBuf *paint_buf,
+ GeglBuffer *src_buffer,
+ GeglBuffer *dst_buffer,
+ GeglBuffer *mask_buffer,
+ gint mask_x_offset,
+ gint mask_y_offset,
+ GeglBuffer *canvas_buffer,
+ gint x_offset,
+ gint y_offset,
+ gfloat opacity,
+ gboolean stipple,
+ gint p_mask_x_offset,
+ gint p_mask_y_offset,
+ gboolean linear_mode,
+ GimpLayerModeEffects paint_mode);
+
void combine_paint_mask_to_canvas_mask (const GimpTempBuf *paint_mask,
gint mask_x_offset,
gint mask_y_offset,
diff --git a/app/paint/gimppaintcore.c b/app/paint/gimppaintcore.c
index 87e1258..07ebebe 100644
--- a/app/paint/gimppaintcore.c
+++ b/app/paint/gimppaintcore.c
@@ -900,27 +900,44 @@ gimp_paint_core_paste (GimpPaintCore *core,
/* This step is skipped by the ink tool, which writes
* directly to canvas_buffer
*/
- if (paint_mask != NULL)
- {
- /* Mix paint mask and canvas_buffer */
- combine_paint_mask_to_canvas_mask (paint_mask,
- paint_mask_offset_x,
- paint_mask_offset_y,
- core->canvas_buffer,
- core->paint_buffer_x,
- core->paint_buffer_y,
- paint_opacity,
- GIMP_IS_AIRBRUSH (core));
- }
-
- /* Write canvas_buffer to paint_buf */
- canvas_buffer_to_paint_buf_alpha (paint_buf,
- core->canvas_buffer,
- core->paint_buffer_x,
- core->paint_buffer_y);
-
- /* undo buf -> paint_buf -> dest_buffer */
src_buffer = core->undo_buffer;
+ combine_paint_canvas_buffer (paint_mask,
+ paint_buf,
+ src_buffer,
+ dest_buffer,
+ core->mask_buffer,
+ paint_mask_offset_x,
+ paint_mask_offset_y,
+ core->canvas_buffer,
+ core->paint_buffer_x,
+ core->paint_buffer_y,
+ paint_opacity,
+ GIMP_IS_AIRBRUSH (core),
+ core->mask_x_offset,
+ core->mask_y_offset,
+ core->linear_mode,
+ paint_mode);
+// if (paint_mask != NULL)
+// {
+// /* Mix paint mask and canvas_buffer */
+// combine_paint_mask_to_canvas_mask (paint_mask,
+// paint_mask_offset_x,
+// paint_mask_offset_y,
+// core->canvas_buffer,
+// core->paint_buffer_x,
+// core->paint_buffer_y,
+// paint_opacity,
+// GIMP_IS_AIRBRUSH (core));
+// }
+//
+// /* Write canvas_buffer to paint_buf */
+// canvas_buffer_to_paint_buf_alpha (paint_buf,
+// core->canvas_buffer,
+// core->paint_buffer_x,
+// core->paint_buffer_y);
+//
+ /* undo buf -> paint_buf -> dest_buffer */
+// src_buffer = core->undo_buffer;
}
else
{
@@ -935,19 +952,19 @@ gimp_paint_core_paste (GimpPaintCore *core,
/* dest_buffer -> paint_buf -> dest_buffer */
src_buffer = dest_buffer;
- }
- do_layer_blend (src_buffer,
- dest_buffer,
- paint_buf,
- core->mask_buffer,
- image_opacity,
- core->paint_buffer_x,
- core->paint_buffer_y,
- core->mask_x_offset,
- core->mask_y_offset,
- core->linear_mode,
- paint_mode);
+ do_layer_blend (src_buffer,
+ dest_buffer,
+ paint_buf,
+ core->mask_buffer,
+ image_opacity,
+ core->paint_buffer_x,
+ core->paint_buffer_y,
+ core->mask_x_offset,
+ core->mask_y_offset,
+ core->linear_mode,
+ paint_mode);
+ }
if (core->comp_buffer)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]