Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-05-06 12:48:07 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-05-06 12:49:09 +0300
commitef0c02cb4dbd5f74fd0cb7c7ef119e4ca1936249 (patch)
tree1000d42908297b93b1f767209438bc88ef3f5f18 /source/blender/editors/sculpt_paint
parent204f55c189d7e7a7b7808b6730a285326e7ac38a (diff)
Speedup of regular 2D painting
Yet another commit which makes painting aware of multi-threaded systems.
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c112
1 files changed, 83 insertions, 29 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 59b50e28ce7..080bd5b73c7 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -42,6 +42,7 @@
#include "BLI_math_color_blend.h"
#include "BLI_stack.h"
#include "BLI_bitmap.h"
+#include "BLI_task.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
@@ -1019,6 +1020,64 @@ static void paint_2d_convert_brushco(ImBuf *ibufb, const float pos[2], int ipos[
ipos[1] = (int)floorf((pos[1] - ibufb->y / 2));
}
+static void paint_2d_do_making_brush(ImagePaintState *s,
+ ImagePaintRegion *region,
+ unsigned short *curveb,
+ unsigned short *texmaskb,
+ ImBuf *frombuf,
+ float mask_max,
+ short blend,
+ int tilex, int tiley,
+ int tilew, int tileh)
+{
+ ImBuf tmpbuf;
+ IMB_initImBuf(&tmpbuf, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, 0);
+
+ for (int ty = tiley; ty <= tileh; ty++) {
+ for (int tx = tilex; tx <= tilew; tx++) {
+ /* retrieve original pixels + mask from undo buffer */
+ unsigned short *mask;
+ int origx = region->destx - tx * IMAPAINT_TILE_SIZE;
+ int origy = region->desty - ty * IMAPAINT_TILE_SIZE;
+
+ if (s->canvas->rect_float)
+ tmpbuf.rect_float = image_undo_find_tile(s->image, s->canvas, tx, ty, &mask, false);
+ else
+ tmpbuf.rect = image_undo_find_tile(s->image, s->canvas, tx, ty, &mask, false);
+
+ IMB_rectblend(s->canvas, &tmpbuf, frombuf, mask,
+ curveb, texmaskb, mask_max,
+ region->destx, region->desty,
+ origx, origy,
+ region->srcx, region->srcy,
+ region->width, region->height,
+ blend, ((s->brush->flag & BRUSH_ACCUMULATE) != 0));
+ }
+ }
+}
+
+typedef struct Paint2DForeachData {
+ ImagePaintState *s;
+ ImagePaintRegion *region;
+ unsigned short *curveb;
+ unsigned short *texmaskb;
+ ImBuf *frombuf;
+ float mask_max;
+ short blend;
+ int tilex;
+ int tilew;
+} Paint2DForeachData;
+
+static void paint_2d_op_foreach_do(void *data_v, const int iter)
+{
+ Paint2DForeachData *data = (Paint2DForeachData *)data_v;
+ paint_2d_do_making_brush(data->s, data->region, data->curveb,
+ data->texmaskb, data->frombuf, data->mask_max,
+ data->blend,
+ data->tilex, iter,
+ data->tilew, iter);
+}
+
static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsigned short *texmaskb, const float lastpos[2], const float pos[2])
{
ImagePaintState *s = ((ImagePaintState *)state);
@@ -1072,45 +1131,40 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
if (s->do_masking) {
/* masking, find original pixels tiles from undo buffer to composite over */
- int tilex, tiley, tilew, tileh, tx, ty;
- ImBuf *tmpbuf;
+ int tilex, tiley, tilew, tileh;
imapaint_region_tiles(s->canvas, region[a].destx, region[a].desty,
region[a].width, region[a].height,
&tilex, &tiley, &tilew, &tileh);
- tmpbuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, 0);
-
- for (ty = tiley; ty <= tileh; ty++) {
- for (tx = tilex; tx <= tilew; tx++) {
- /* retrieve original pixels + mask from undo buffer */
- unsigned short *mask;
- int origx = region[a].destx - tx * IMAPAINT_TILE_SIZE;
- int origy = region[a].desty - ty * IMAPAINT_TILE_SIZE;
-
- if (s->canvas->rect_float)
- tmpbuf->rect_float = image_undo_find_tile(s->image, s->canvas, tx, ty, &mask, false);
- else
- tmpbuf->rect = image_undo_find_tile(s->image, s->canvas, tx, ty, &mask, false);
-
- IMB_rectblend(s->canvas, tmpbuf, frombuf, mask,
- curveb, texmaskb, mask_max,
- region[a].destx, region[a].desty,
- origx, origy,
- region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, blend, ((s->brush->flag & BRUSH_ACCUMULATE) != 0));
- }
+ if (tiley == tileh) {
+ paint_2d_do_making_brush(s, &region[a], curveb, texmaskb, frombuf,
+ mask_max, blend, tilex, tiley, tilew, tileh);
}
+ else {
+ Paint2DForeachData data;
+ data.s = s;
+ data.region = &region[a];
+ data.curveb = curveb;
+ data.texmaskb = texmaskb;
+ data.frombuf = frombuf;
+ data.mask_max = mask_max;
+ data.blend = blend;
+ data.tilex = tilex;
+ data.tilew = tilew;
+ BLI_task_parallel_range(tiley, tileh + 1, &data,
+ paint_2d_op_foreach_do,
+ true);
- IMB_freeImBuf(tmpbuf);
+ }
}
else {
/* no masking, composite brush directly onto canvas */
- IMB_rectblend(s->canvas, s->canvas, frombuf, NULL, curveb, texmaskb, mask_max,
- region[a].destx, region[a].desty,
- region[a].destx, region[a].desty,
- region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, blend, false);
+ IMB_rectblend_threaded(s->canvas, s->canvas, frombuf, NULL, curveb, texmaskb, mask_max,
+ region[a].destx, region[a].desty,
+ region[a].destx, region[a].desty,
+ region[a].srcx, region[a].srcy,
+ region[a].width, region[a].height, blend, false);
}
}