Commit 6c6a7514 authored by Ell's avatar Ell

app: some cleanup in gimppaintcore-loops

In gimp_paint_core_loops_process(), initialize the iterator with
sufficient room for the number of iterators used by the algorithm
hierarchy, instead of a fixed number.

Add an additional 'rect' parameter to the init_step() and
process_rows() algorithm member functions, which receives the area
of the currently-processed chunk, to be used instead of the
iterator's ROI member.  This allows us to pass a NULL iterator to
hierarchies that don't use an iterator, and avoid the stack-
allocated iterator hack we used in this case (and which became even
more problematic with the new iterator API).
parent 6fca9959
...@@ -278,7 +278,8 @@ struct AlgorithmBase ...@@ -278,7 +278,8 @@ struct AlgorithmBase
* *
* 'params' is the same parameter struct passed to the constructor. 'state' * 'params' is the same parameter struct passed to the constructor. 'state'
* is the state object. 'iter' is the iterator; each distinct state object * is the state object. 'iter' is the iterator; each distinct state object
* uses a distinct iterator. 'roi' is the full region to be processed. * uses a distinct iterator; if the algorithm hierarchy doesn't use any
* iterator, 'iter' may be NULL. 'roi' is the full region to be processed.
* 'area' is the subregion to be processed by the current state object. * 'area' is the subregion to be processed by the current state object.
* *
* An algorithm that overrides this function should call the 'init()' * An algorithm that overrides this function should call the 'init()'
...@@ -298,7 +299,8 @@ struct AlgorithmBase ...@@ -298,7 +299,8 @@ struct AlgorithmBase
* 'gegl_buffer_iterator_next()' call, and should perform any necessary * 'gegl_buffer_iterator_next()' call, and should perform any necessary
* initialization required before processing the current chunk. * initialization required before processing the current chunk.
* *
* The parameters are the same as for 'init()'. * The parameters are the same as for 'init()', with the addition of 'rect',
* which is the area of the current chunk.
* *
* An algorithm that overrides this function should call the 'init_step()' * An algorithm that overrides this function should call the 'init_step()'
* function of its base class first, using the same arguments. * function of its base class first, using the same arguments.
...@@ -309,15 +311,16 @@ struct AlgorithmBase ...@@ -309,15 +311,16 @@ struct AlgorithmBase
State<Derived> *state, State<Derived> *state,
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area) const const GeglRectangle *area,
const GeglRectangle *rect) const
{ {
} }
/* The 'process_row()' function is called for each row in the current chunk, /* The 'process_row()' function is called for each row in the current chunk,
* and should perform the actual processing. * and should perform the actual processing.
* *
* The parameters are the same as for 'init()', with the addition of 'y', * The parameters are the same as for 'init_step()', with the addition of
* which is the current row. * 'y', which is the current row.
* *
* An algorithm that overrides this function should call the 'process_row()' * An algorithm that overrides this function should call the 'process_row()'
* function of its base class first, using the same arguments. * function of its base class first, using the same arguments.
...@@ -329,6 +332,7 @@ struct AlgorithmBase ...@@ -329,6 +332,7 @@ struct AlgorithmBase
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area, const GeglRectangle *area,
const GeglRectangle *rect,
gint y) const gint y) const
{ {
} }
...@@ -636,9 +640,10 @@ struct CombinePaintMaskToCanvasMaskToPaintBufAlpha : ...@@ -636,9 +640,10 @@ struct CombinePaintMaskToCanvasMaskToPaintBufAlpha :
State<Derived> *state, State<Derived> *state,
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area) const const GeglRectangle *area,
const GeglRectangle *rect) const
{ {
base_type::init_step (params, state, iter, roi, area); base_type::init_step (params, state, iter, roi, area, rect);
state->canvas_pixel = state->canvas_pixel =
(gfloat *) iter->items[base_type::canvas_buffer_iterator].data; (gfloat *) iter->items[base_type::canvas_buffer_iterator].data;
...@@ -651,19 +656,20 @@ struct CombinePaintMaskToCanvasMaskToPaintBufAlpha : ...@@ -651,19 +656,20 @@ struct CombinePaintMaskToCanvasMaskToPaintBufAlpha :
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area, const GeglRectangle *area,
const GeglRectangle *rect,
gint y) const gint y) const
{ {
base_type::process_row (params, state, iter, roi, area, y); base_type::process_row (params, state, iter, roi, area, rect, y);
gint mask_offset = (y - roi->y) * this->mask_stride + gint mask_offset = (y - roi->y) * this->mask_stride +
(iter->items[0].roi.x - roi->x); (rect->x - roi->x);
const mask_type *mask_pixel = &this->mask_data[mask_offset]; const mask_type *mask_pixel = &this->mask_data[mask_offset];
gint paint_offset = (y - roi->y) * this->paint_stride + gint paint_offset = (y - roi->y) * this->paint_stride +
(iter->items[0].roi.x - roi->x) * 4; (rect->x - roi->x) * 4;
gfloat *paint_pixel = &this->paint_data[paint_offset]; gfloat *paint_pixel = &this->paint_data[paint_offset];
gint x; gint x;
for (x = 0; x < iter->items[0].roi.width; x++) for (x = 0; x < rect->width; x++)
{ {
if (base_type::stipple) if (base_type::stipple)
{ {
...@@ -733,9 +739,10 @@ struct CombinePaintMaskToCanvasMask : ...@@ -733,9 +739,10 @@ struct CombinePaintMaskToCanvasMask :
State<Derived> *state, State<Derived> *state,
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area) const const GeglRectangle *area,
const GeglRectangle *rect) const
{ {
base_type::init_step (params, state, iter, roi, area); base_type::init_step (params, state, iter, roi, area, rect);
state->canvas_pixel = state->canvas_pixel =
(gfloat *) iter->items[base_type::canvas_buffer_iterator].data; (gfloat *) iter->items[base_type::canvas_buffer_iterator].data;
...@@ -748,16 +755,17 @@ struct CombinePaintMaskToCanvasMask : ...@@ -748,16 +755,17 @@ struct CombinePaintMaskToCanvasMask :
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area, const GeglRectangle *area,
const GeglRectangle *rect,
gint y) const gint y) const
{ {
base_type::process_row (params, state, iter, roi, area, y); base_type::process_row (params, state, iter, roi, area, rect, y);
gint mask_offset = (y - roi->y) * this->mask_stride + gint mask_offset = (y - roi->y) * this->mask_stride +
(iter->items[0].roi.x - roi->x); (rect->x - roi->x);
const mask_type *mask_pixel = &this->mask_data[mask_offset]; const mask_type *mask_pixel = &this->mask_data[mask_offset];
gint x; gint x;
for (x = 0; x < iter->items[0].roi.width; x++) for (x = 0; x < rect->width; x++)
{ {
if (base_type::stipple) if (base_type::stipple)
{ {
...@@ -821,9 +829,10 @@ struct CanvasBufferToPaintBufAlpha : CanvasBufferIterator<Base, ...@@ -821,9 +829,10 @@ struct CanvasBufferToPaintBufAlpha : CanvasBufferIterator<Base,
State<Derived> *state, State<Derived> *state,
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area) const const GeglRectangle *area,
const GeglRectangle *rect) const
{ {
base_type::init_step (params, state, iter, roi, area); base_type::init_step (params, state, iter, roi, area, rect);
state->canvas_pixel = state->canvas_pixel =
(const gfloat *) iter->items[base_type::canvas_buffer_iterator].data; (const gfloat *) iter->items[base_type::canvas_buffer_iterator].data;
...@@ -836,18 +845,19 @@ struct CanvasBufferToPaintBufAlpha : CanvasBufferIterator<Base, ...@@ -836,18 +845,19 @@ struct CanvasBufferToPaintBufAlpha : CanvasBufferIterator<Base,
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area, const GeglRectangle *area,
const GeglRectangle *rect,
gint y) const gint y) const
{ {
base_type::process_row (params, state, iter, roi, area, y); base_type::process_row (params, state, iter, roi, area, rect, y);
/* Copy the canvas buffer in rect to the paint buffer's alpha channel */ /* Copy the canvas buffer in rect to the paint buffer's alpha channel */
gint paint_offset = (y - roi->y) * this->paint_stride + gint paint_offset = (y - roi->y) * this->paint_stride +
(iter->items[0].roi.x - roi->x) * 4; (rect->x - roi->x) * 4;
gfloat *paint_pixel = &this->paint_data[paint_offset]; gfloat *paint_pixel = &this->paint_data[paint_offset];
gint x; gint x;
for (x = 0; x < iter->items[0].roi.width; x++) for (x = 0; x < rect->width; x++)
{ {
paint_pixel[3] *= *state->canvas_pixel; paint_pixel[3] *= *state->canvas_pixel;
...@@ -902,19 +912,20 @@ struct PaintMaskToPaintBuffer : Base ...@@ -902,19 +912,20 @@ struct PaintMaskToPaintBuffer : Base
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area, const GeglRectangle *area,
const GeglRectangle *rect,
gint y) const gint y) const
{ {
Base::process_row (params, state, iter, roi, area, y); Base::process_row (params, state, iter, roi, area, rect, y);
gint paint_offset = (y - roi->y) * this->paint_stride + gint paint_offset = (y - roi->y) * this->paint_stride +
(iter->items[0].roi.x - roi->x) * 4; (rect->x - roi->x) * 4;
gfloat *paint_pixel = &this->paint_data[paint_offset]; gfloat *paint_pixel = &this->paint_data[paint_offset];
gint mask_offset = (y - roi->y) * this->mask_stride + gint mask_offset = (y - roi->y) * this->mask_stride +
(iter->items[0].roi.x - roi->x); (rect->x - roi->x);
const mask_type *mask_pixel = &this->mask_data[mask_offset]; const mask_type *mask_pixel = &this->mask_data[mask_offset];
gint x; gint x;
for (x = 0; x < iter->items[0].roi.width; x++) for (x = 0; x < rect->width; x++)
{ {
paint_pixel[3] *= value_to_float (*mask_pixel) * params->paint_opacity; paint_pixel[3] *= value_to_float (*mask_pixel) * params->paint_opacity;
...@@ -1020,23 +1031,24 @@ struct DoLayerBlend : Base ...@@ -1020,23 +1031,24 @@ struct DoLayerBlend : Base
State<Derived> *state, State<Derived> *state,
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area) const const GeglRectangle *area,
const GeglRectangle *rect) const
{ {
Base::init_step (params, state, iter, roi, area); Base::init_step (params, state, iter, roi, area, rect);
state->out_pixel = (gfloat *) iter->items[iterator_base + 0].data; state->out_pixel = (gfloat *) iter->items[iterator_base + 0].data;
state->in_pixel = (gfloat *) iter->items[iterator_base + 1].data; state->in_pixel = (gfloat *) iter->items[iterator_base + 1].data;
state->mask_pixel = NULL; state->mask_pixel = NULL;
state->paint_pixel = this->paint_data + state->paint_pixel = this->paint_data +
(iter->items[0].roi.y - roi->y) * this->paint_stride + (rect->y - roi->y) * this->paint_stride +
(iter->items[0].roi.x - roi->x) * 4; (rect->x - roi->x) * 4;
if (params->mask_buffer) if (params->mask_buffer)
state->mask_pixel = (gfloat *) iter->items[iterator_base + 2].data; state->mask_pixel = (gfloat *) iter->items[iterator_base + 2].data;
state->process_roi.x = iter->items[0].roi.x; state->process_roi.x = rect->x;
state->process_roi.width = iter->items[0].roi.width; state->process_roi.width = rect->width;
state->process_roi.height = 1; state->process_roi.height = 1;
} }
...@@ -1047,9 +1059,10 @@ struct DoLayerBlend : Base ...@@ -1047,9 +1059,10 @@ struct DoLayerBlend : Base
GeglBufferIterator *iter, GeglBufferIterator *iter,
const GeglRectangle *roi, const GeglRectangle *roi,
const GeglRectangle *area, const GeglRectangle *area,
const GeglRectangle *rect,
gint y) const gint y) const
{ {
Base::process_row (params, state, iter, roi, area, y); Base::process_row (params, state, iter, roi, area, rect, y);
state->process_roi.y = y; state->process_roi.y = y;
...@@ -1058,14 +1071,14 @@ struct DoLayerBlend : Base ...@@ -1058,14 +1071,14 @@ struct DoLayerBlend : Base
state->paint_pixel, state->paint_pixel,
state->mask_pixel, state->mask_pixel,
state->out_pixel, state->out_pixel,
iter->items[0].roi.width, rect->width,
&state->process_roi, &state->process_roi,
0); 0);
state->in_pixel += iter->items[0].roi.width * 4; state->in_pixel += rect->width * 4;
state->out_pixel += iter->items[0].roi.width * 4; state->out_pixel += rect->width * 4;
if (params->mask_buffer) if (params->mask_buffer)
state->mask_pixel += iter->items[0].roi.width; state->mask_pixel += rect->width;
state->paint_pixel += this->paint_stride; state->paint_pixel += this->paint_stride;
} }
}; };
...@@ -1130,36 +1143,34 @@ gimp_paint_core_loops_process (const GimpPaintCoreLoopsParams *params, ...@@ -1130,36 +1143,34 @@ gimp_paint_core_loops_process (const GimpPaintCoreLoopsParams *params,
{ {
GeglBufferIterator *iter; GeglBufferIterator *iter;
iter = gegl_buffer_iterator_empty_new (4); iter = gegl_buffer_iterator_empty_new (Algorithm::n_iterators);
algorithm.init (params, &state, iter, &roi, area); algorithm.init (params, &state, iter, &roi, area);
while (gegl_buffer_iterator_next (iter)) while (gegl_buffer_iterator_next (iter))
{ {
algorithm.init_step (params, &state, iter, &roi, area); const GeglRectangle *rect = &iter->items[0].roi;
for (y = 0; y < iter->items[0].roi.height; y++) algorithm.init_step (params, &state, iter, &roi, area, rect);
for (y = 0; y < rect->height; y++)
{ {
algorithm.process_row (params, &state, algorithm.process_row (params, &state,
iter, &roi, area, iter, &roi, area, rect,
iter->items[0].roi.y + y); rect->y + y);
} }
} }
} }
else else
{ {
GeglBufferIterator iter[2]; algorithm.init (params, &state, NULL, &roi, area);
algorithm.init_step (params, &state, NULL, &roi, area, area);
iter[0].items[0].roi = *area;
algorithm.init (params, &state, &iter[0], &roi, area);
algorithm.init_step (params, &state, &iter[0], &roi, area);
for (y = 0; y < iter[0].items[0].roi.height; y++) for (y = 0; y < area->height; y++)
{ {
algorithm.process_row (params, &state, algorithm.process_row (params, &state,
&iter[0], &roi, area, NULL, &roi, area, area,
iter[0].items[0].roi.y + y); area->y + y);
} }
} }
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment