[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58027] branches/soc-2013-paint/source/ blender/editors/sculpt_paint/paint_image.c: Fix redo not working on image painting since the last few changes for

Antony Riakiotakis kalast at gmail.com
Sat Jul 6 01:02:58 CEST 2013


Revision: 58027
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58027
Author:   psy-fi
Date:     2013-07-05 23:02:57 +0000 (Fri, 05 Jul 2013)
Log Message:
-----------
Fix redo not working on image painting since the last few changes for
drag dot and anchored support. This gave a nice opportunity to add the
last optimization for runtime restoration of tiles, comparing by
pointers instead of ID and file names.

Modified Paths:
--------------
    branches/soc-2013-paint/source/blender/editors/sculpt_paint/paint_image.c

Modified: branches/soc-2013-paint/source/blender/editors/sculpt_paint/paint_image.c
===================================================================
--- branches/soc-2013-paint/source/blender/editors/sculpt_paint/paint_image.c	2013-07-05 22:07:39 UTC (rev 58026)
+++ branches/soc-2013-paint/source/blender/editors/sculpt_paint/paint_image.c	2013-07-05 23:02:57 UTC (rev 58027)
@@ -117,6 +117,7 @@
 
 	int x, y;
 
+	Image *ima;
 	short source, use_float;
 	char gen_type;
 	bool valid;
@@ -138,21 +139,19 @@
 }
 
 /* UNDO */
+typedef enum {
+	COPY = 0,
+	RESTORE = 1,
+	RESTORE_COPY = 2
+} CopyMode;
 
-static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, int restore)
+static void undo_copy_tile(UndoImageTile *tile, ImBuf *tmpibuf, ImBuf *ibuf, CopyMode mode)
 {
-	if (restore) {
-		/* swap to the tmpbuf for easy copying */
-		if (ibuf->rect_float) {
-			SWAP(float *, tmpibuf->rect_float, tile->rect.fp);
-		}
-		else {
-			SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint);
-		}
+	if (mode == COPY) {
+		/* copy or swap contents of tile->rect and region in ibuf->rect */
+		IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE,
+		            tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
 
-		IMB_rectcpy(ibuf, tmpibuf, tile->x * IMAPAINT_TILE_SIZE,
-		            tile->y * IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
-
 		if (ibuf->rect_float) {
 			SWAP(float *, tmpibuf->rect_float, tile->rect.fp);
 		}
@@ -161,16 +160,28 @@
 		}
 	}
 	else {
-		/* copy or swap contents of tile->rect and region in ibuf->rect */
-		IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE,
-		            tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
-
+		if (mode == RESTORE_COPY)
+			IMB_rectcpy(tmpibuf, ibuf, 0, 0, tile->x * IMAPAINT_TILE_SIZE,
+		                tile->y * IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
+		/* swap to the tmpbuf for easy copying */
 		if (ibuf->rect_float) {
 			SWAP(float *, tmpibuf->rect_float, tile->rect.fp);
 		}
 		else {
 			SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint);
 		}
+
+		IMB_rectcpy(ibuf, tmpibuf, tile->x * IMAPAINT_TILE_SIZE,
+		            tile->y * IMAPAINT_TILE_SIZE, 0, 0, IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE);
+
+		if (mode == RESTORE) {
+			if (ibuf->rect_float) {
+				SWAP(float *, tmpibuf->rect_float, tile->rect.fp);
+			}
+			else {
+				SWAP(unsigned int *, tmpibuf->rect, tile->rect.uint);
+			}
+		}
 	}
 }
 
@@ -241,8 +252,9 @@
 	tile->source = ima->source;
 	tile->use_float = use_float;
 	tile->valid = true;
+	tile->ima = ima;
 
-	undo_copy_tile(tile, *tmpibuf, ibuf, 0);
+	undo_copy_tile(tile, *tmpibuf, ibuf, COPY);
 	undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize);
 
 	BLI_addtail(lb, tile);
@@ -254,7 +266,6 @@
 {
 	ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
 	UndoImageTile *tile;
-
 	for (tile = lb->first; tile; tile = tile->next) {
 		if (tile->mask) {
 			MEM_freeN(tile->mask);
@@ -263,6 +274,33 @@
 	}
 }
 
+static void image_undo_restore_runtime(ListBase *lb)
+{
+	ImBuf *ibuf, *tmpibuf;
+	UndoImageTile *tile;
+
+	tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32,
+	                         IB_rectfloat | IB_rect);
+
+	for (tile = lb->first; tile; tile = tile->next) {
+		Image *ima = tile->ima;
+		ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
+
+		undo_copy_tile(tile, tmpibuf, ibuf, RESTORE);
+
+		GPU_free_image(ima); /* force OpenGL reload (maybe partial update will operate better?) */
+		if (ibuf->rect_float)
+			ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */
+		if (ibuf->mipmap[0])
+			ibuf->userflags |= IB_MIPMAP_INVALID;  /* force mipmap recreatiom */
+		ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+		BKE_image_release_ibuf(ima, ibuf, NULL);
+	}
+
+	IMB_freeImBuf(tmpibuf);
+}
+
 void image_undo_restore(bContext *C, ListBase *lb)
 {
 	Main *bmain = CTX_data_main(C);
@@ -314,7 +352,7 @@
 			continue;
 		}
 
-		undo_copy_tile(tile, tmpibuf, ibuf, 1);
+		undo_copy_tile(tile, tmpibuf, ibuf, RESTORE_COPY);
 
 		GPU_free_image(ima); /* force OpenGL reload */
 		if (ibuf->rect_float)
@@ -341,15 +379,26 @@
 {
 	ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
 	UndoImageTile *tile;
+	int deallocsize = 0;
+	int allocsize = IMAPAINT_TILE_SIZE * IMAPAINT_TILE_SIZE * 4;
 
 	/* first dispose of invalid tiles (may happen due to drag dot for instance) */
-	for (tile = lb->first; tile; tile = tile->next) {
+	for (tile = lb->first; tile;) {
 		if (!tile->valid) {
+			UndoImageTile *tmp_tile = tile->next;
+			deallocsize += allocsize * ((tile->use_float) ? sizeof(float) : sizeof(char));
 			MEM_freeN(tile->rect.pt);
 			BLI_freelinkN (lb, tile);
+			tile = tmp_tile;
 		}
+		else {
+			tile = tile->next;
+		}
 	}
 
+	/* don't forget to remove the size of deallocated tiles */
+	undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, -deallocsize);
+
 	undo_paint_push_end(UNDO_PAINT_IMAGE);
 }
 
@@ -563,10 +612,10 @@
 }
 
 /* restore painting image to previous state. Used for anchored and drag-dot style brushes*/
-static void paint_stroke_restore(bContext *C)
+static void paint_stroke_restore(void)
 {
 	ListBase *lb = undo_paint_push_get_list(UNDO_PAINT_IMAGE);
-	image_undo_restore(C, lb);
+	image_undo_restore_runtime(lb);
 	image_undo_invalidate();
 }
 
@@ -596,7 +645,7 @@
 	BKE_brush_size_set(scene, brush, max_ff(1.0f, size));
 
 	if ((brush->flag & BRUSH_RESTORE_MESH) || (brush->flag & BRUSH_ANCHORED)) {
-		paint_stroke_restore(C);
+		paint_stroke_restore();
 	}
 
 	if (pop->mode == PAINT_MODE_3D_PROJECT) {




More information about the Bf-blender-cvs mailing list