[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56823] trunk/blender/source/blender: Attempt to fix #35057 and #35372: slow texture painting performance.

Brecht Van Lommel brechtvanlommel at pandora.be
Wed May 15 16:37:05 CEST 2013


Revision: 56823
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56823
Author:   blendix
Date:     2013-05-15 14:37:05 +0000 (Wed, 15 May 2013)
Log Message:
-----------
Attempt to fix #35057 and #35372: slow texture painting performance.

After the paint refactoring for 2.67, the OpenGL texture was getting updated for
every stroke point, rather than once for every redraw. With a small brush radius
and low spacing the number of stroke points can be quite large, which might have
a big performance impact depending on the graphics card / drivers.

Also for 2D image paint, avoid redrawing the button panels and properties editor
during painting.

There is another possible cause for slowdowns with 3D texture painting which was
not fixed. Projection painting is creating and destroying threads for every stroke
point. Depending on the CPU/OS there might be a lot of overhead in doing that if
the brush size is small.

Modified Paths:
--------------
    trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_intern.h
    trunk/blender/source/blender/editors/sculpt_paint/paint_stroke.c
    trunk/blender/source/blender/editors/sculpt_paint/paint_vertex.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
    trunk/blender/source/blender/editors/space_buttons/space_buttons.c
    trunk/blender/source/blender/editors/space_image/space_image.c
    trunk/blender/source/blender/windowmanager/WM_types.h

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2013-05-15 14:37:01 UTC (rev 56822)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image.c	2013-05-15 14:37:05 UTC (rev 56823)
@@ -478,22 +478,6 @@
 }
 
 
-static void paint_redraw(const bContext *C, PaintOperation *pop, int final)
-{
-	if (pop->mode == PAINT_MODE_2D) {
-		paint_2d_redraw(C, pop->custom_paint, final);
-	}
-	else {
-		if (final) {
-			/* compositor listener deals with updating */
-			WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, NULL);
-		}
-		else {
-			ED_region_tag_redraw(CTX_wm_region(C));
-		}
-	}
-}
-
 static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const wmEvent *event)
 {
 	Scene *scene = CTX_data_scene(C);
@@ -547,7 +531,7 @@
 
 	float mouse[2];
 	float pressure;
-	int redraw, eraser;
+	int eraser;
 
 	RNA_float_get_array(itemptr, "mouse", mouse);
 	pressure = RNA_float_get(itemptr, "pressure");
@@ -559,10 +543,10 @@
 		BKE_brush_size_set(scene, brush, max_ff(1.0f, startsize * pressure));
 
 	if (pop->mode == PAINT_MODE_3D_PROJECT) {
-		redraw = paint_proj_stroke(C, pop->custom_paint, pop->prevmouse, mouse);
+		paint_proj_stroke(C, pop->custom_paint, pop->prevmouse, mouse);
 	}
 	else {
-		redraw = paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser);
+		paint_2d_stroke(pop->custom_paint, pop->prevmouse, mouse, eraser);
 	}
 
 	pop->prevmouse[0] = mouse[0];
@@ -571,11 +555,18 @@
 	/* restore brush values */
 	BKE_brush_alpha_set(scene, brush, startalpha);
 	BKE_brush_size_set(scene, brush, startsize);
+}
 
+static void paint_stroke_redraw(const bContext *C, struct PaintStroke *stroke, bool final)
+{
+	PaintOperation *pop = paint_stroke_mode_data(stroke);
 
-	if (redraw)
-		paint_redraw(C, pop, 0);
-
+	if (pop->mode == PAINT_MODE_3D_PROJECT) {
+		paint_proj_redraw(C, pop->custom_paint, final);
+	}
+	else {
+		paint_2d_redraw(C, pop->custom_paint, final);
+	}
 }
 
 static void paint_stroke_done(const bContext *C, struct PaintStroke *stroke)
@@ -584,8 +575,6 @@
 	ToolSettings *settings = scene->toolsettings;
 	PaintOperation *pop = paint_stroke_mode_data(stroke);
 
-	paint_redraw(C, pop, 1);
-
 	settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
 
 	if (pop->mode == PAINT_MODE_3D_PROJECT) {
@@ -629,6 +618,7 @@
 
 	stroke = op->customdata = paint_stroke_new(C, NULL, paint_stroke_test_start,
 	                                  paint_stroke_update_step,
+	                                  paint_stroke_redraw,
 	                                  paint_stroke_done, event->type);
 	paint_stroke_set_mode_data(stroke, pop);
 	/* add modal handler */

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c	2013-05-15 14:37:01 UTC (rev 56822)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_2d.c	2013-05-15 14:37:05 UTC (rev 56823)
@@ -153,6 +153,8 @@
 	int faceindex;
 	float uv[2];
 	int do_facesel;
+
+	bool need_redraw;
 } ImagePaintState;
 
 
@@ -1016,17 +1018,16 @@
 		image_undo_remove_masks();
 }
 
-int paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser)
+void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser)
 {
 	float newuv[2], olduv[2];
-	int redraw = 0;
 	ImagePaintState *s = ps;
 	BrushPainter *painter = s->painter;
 	ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
 	const bool is_data = (ibuf && ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA);
 
 	if (!ibuf)
-		return 0;
+		return;
 
 	s->blend = s->brush->blend;
 	if (eraser)
@@ -1064,19 +1065,10 @@
 
 	brush_painter_2d_refresh_cache(s, painter, newuv);
 
-	if (paint_2d_op(s, painter->cache.ibuf, painter->cache.mask, olduv, newuv)) {
-		imapaint_image_update(s->sima, s->image, ibuf, false);
-		BKE_image_release_ibuf(s->image, ibuf, NULL);
-		redraw |= 1;
-	}
-	else {
-		BKE_image_release_ibuf(s->image, ibuf, NULL);
-	}
+	if (paint_2d_op(s, painter->cache.ibuf, painter->cache.mask, olduv, newuv))
+		s->need_redraw = true;
 
-	if (redraw)
-		imapaint_clear_partial_redraw();
-
-	return redraw;
+	BKE_image_release_ibuf(s->image, ibuf, NULL);
 }
 
 void *paint_2d_new_stroke(bContext *C, wmOperator *op)
@@ -1116,10 +1108,24 @@
 	return s;
 }
 
-void paint_2d_redraw(const bContext *C, void *ps, int final)
+void paint_2d_redraw(const bContext *C, void *ps, bool final)
 {
 	ImagePaintState *s = ps;
 
+	if (s->need_redraw) {
+		ImBuf *ibuf = BKE_image_acquire_ibuf(s->image, s->sima ? &s->sima->iuser : NULL, NULL);
+
+		imapaint_image_update(s->sima, s->image, ibuf, false);
+		imapaint_clear_partial_redraw();
+
+		BKE_image_release_ibuf(s->image, ibuf, NULL);
+
+		s->need_redraw = false;
+	}
+	else if (!final) {
+		return;
+	}
+
 	if (final) {
 		if (s->image && !(s->sima && s->sima->lock))
 			GPU_free_image(s->image);
@@ -1131,7 +1137,7 @@
 		if (!s->sima || !s->sima->lock)
 			ED_region_tag_redraw(CTX_wm_region(C));
 		else
-			WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, s->image);
+			WM_event_add_notifier(C, NC_IMAGE | NA_PAINTING, s->image);
 	}
 }
 

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c	2013-05-15 14:37:01 UTC (rev 56822)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_image_proj.c	2013-05-15 14:37:05 UTC (rev 56823)
@@ -264,12 +264,14 @@
 	Image *reproject_image;
 	ImBuf *reproject_ibuf;
 
-
 	/* threads */
 	int thread_tot;
 	int bucketMin[2];
 	int bucketMax[2];
 	int context_bucket_x, context_bucket_y; /* must lock threads while accessing these */
+
+	/* redraw */
+	bool need_redraw;
 } ProjPaintState;
 
 typedef union pixelPointer {
@@ -4044,10 +4046,10 @@
 }
 
 
-int paint_proj_stroke(bContext *C, void *pps, const float prev_pos[2], const float pos[2])
+void paint_proj_stroke(bContext *C, void *pps, const float prev_pos[2], const float pos[2])
 {
 	ProjPaintState *ps = pps;
-	int a, redraw;
+	int a;
 
 	/* clone gets special treatment here to avoid going through image initialization */
 	if (ps->tool == PAINT_TOOL_CLONE && ps->mode == BRUSH_STROKE_INVERT) {
@@ -4059,22 +4061,21 @@
 		view3d_operator_needs_opengl(C);
 
 		if (!ED_view3d_autodist(scene, ps->ar, v3d, mval_i, cursor, false))
-			return 0;
+			return;
 
 		ED_region_tag_redraw(ps->ar);
 
-		return 0;
+		return;
 	}
 
-	for (a = 0; a < ps->image_tot; a++)
-		partial_redraw_array_init(ps->projImages[a].partRedrawRect);
+	/* continue adding to existing partial redraw rects until redraw */
+	if (!ps->need_redraw) {
+		for (a = 0; a < ps->image_tot; a++)
+			partial_redraw_array_init(ps->projImages[a].partRedrawRect);
+	}
 
-	redraw = project_paint_op(ps, prev_pos, pos) ? 1 : 0;
-
-	if (project_image_refresh_tagged(ps))
-		return redraw;
-
-	return 0;
+	if (project_paint_op(ps, prev_pos, pos))
+		ps->need_redraw = true;
 }
 
 
@@ -4195,6 +4196,28 @@
 	return ps;
 }
 
+void paint_proj_redraw(const bContext *C, void *pps, bool final)
+{
+	ProjPaintState *ps = pps;
+
+	if (ps->need_redraw) {
+		project_image_refresh_tagged(ps);
+
+		ps->need_redraw = false;
+	}
+	else if (!final) {
+		return;
+	}
+
+	if (final) {
+		/* compositor listener deals with updating */
+		WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, NULL);
+	}
+	else {
+		ED_region_tag_redraw(CTX_wm_region(C));
+	}
+}
+
 void paint_proj_stroke_done(void *pps)
 {
 	ProjPaintState *ps = pps;

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_intern.h
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_intern.h	2013-05-15 14:37:01 UTC (rev 56822)
+++ trunk/blender/source/blender/editors/sculpt_paint/paint_intern.h	2013-05-15 14:37:05 UTC (rev 56823)
@@ -60,11 +60,13 @@
 typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]);
 typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]);
 typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr);
+typedef void (*StrokeRedraw)(const struct bContext *C, struct PaintStroke *stroke, bool final);
 typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke);
 
 struct PaintStroke *paint_stroke_new(struct bContext *C,
                                      StrokeGetLocation get_location, StrokeTestStart test_start,
-                                     StrokeUpdateStep update_step, StrokeDone done, int event_type);
+                                     StrokeUpdateStep update_step, StrokeRedraw redraw,
+                                     StrokeDone done, int event_type);
 void paint_stroke_data_free(struct wmOperator *op);
 
 bool paint_space_stroke_enabled(struct Brush *br, enum PaintMode mode);
@@ -139,11 +141,12 @@
 void imapaint_region_tiles(struct ImBuf *ibuf, int x, int y, int w, int h, int *tx, int *ty, int *tw, int *th);
 int get_imapaint_zoom(struct bContext *C, float *zoomx, float *zoomy);
 void *paint_2d_new_stroke(struct bContext *, struct wmOperator *);
-void paint_2d_redraw(const bContext *C, void *ps, int final);
+void paint_2d_redraw(const bContext *C, void *ps, bool final);
 void paint_2d_stroke_done(void *ps);
-int paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser);
+void paint_2d_stroke(void *ps, const float prev_mval[2], const float mval[2], int eraser);
 void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const float mouse[2], int mode);
-int paint_proj_stroke(struct bContext *C, void *ps, const float prevmval_i[2], const float mval_i[2]);
+void paint_proj_stroke(struct bContext *C, void *ps, const float prevmval_i[2], const float mval_i[2]);
+void paint_proj_redraw(const bContext *C, void *pps, bool final);
 void paint_proj_stroke_done(void *ps);
 void paint_brush_init_tex(struct Brush *brush);
 void paint_brush_exit_tex(struct Brush *brush);

Modified: trunk/blender/source/blender/editors/sculpt_paint/paint_stroke.c
===================================================================
--- trunk/blender/source/blender/editors/sculpt_paint/paint_stroke.c	2013-05-15 14:37:01 UTC (rev 56822)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list