[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