Implemented delayed partial rect update for image buffers
authorSergey Sharybin <sergey.vfx@gmail.com>
Mon, 11 Feb 2013 13:24:35 +0000 (13:24 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Mon, 11 Feb 2013 13:24:35 +0000 (13:24 +0000)
Used by image painting mode, so every brush step would mark area
if affected on, but actual color space conversion would happen
later when actually displaying image.

Implemented as a rcti stored in ImBuf which is getting merged with
partial rect passed to IMB_partial_display_buffer_update_delayed.

This makes painting as fast as it currently possible and finally
solves #33935: Texture painting slow down with mouse, but not with tablet

source/blender/editors/sculpt_paint/paint_image.c
source/blender/imbuf/IMB_colormanagement.h
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/intern/colormanagement.c

index a1b3941..b9b3b1d 100644 (file)
@@ -140,7 +140,7 @@ BLI_INLINE unsigned char f_to_char(const float val)
 #define IMAPAINT_TILE_SIZE          (1 << IMAPAINT_TILE_BITS)
 #define IMAPAINT_TILE_NUMBER(size)  (((size) + IMAPAINT_TILE_SIZE - 1) >> IMAPAINT_TILE_BITS)
 
-static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
+static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint);
 
 
 typedef struct ImagePaintState {
@@ -3656,7 +3656,7 @@ static int project_image_refresh_tagged(ProjPaintState *ps)
                                pr = &(projIma->partRedrawRect[i]);
                                if (pr->x2 != -1) { /* TODO - use 'enabled' ? */
                                        imapaintpartial = *pr;
-                                       imapaint_image_update(NULL, NULL, projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
+                                       imapaint_image_update(NULL, projIma->ima, projIma->ibuf, 1); /*last 1 is for texpaint*/
                                        redraw = 1;
                                }
                        }
@@ -4417,16 +4417,13 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w,
                IMB_freeImBuf(tmpibuf);
 }
 
-static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
+static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint)
 {
-       if (scene) {
-               IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect, ibuf->x, 0, 0,
-                                                 &scene->view_settings, &scene->display_settings,
-                                                 imapaintpartial.x1, imapaintpartial.y1,
-                                                 imapaintpartial.x2, imapaintpartial.y2, FALSE);
-       }
-       else {
-               ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+       if (imapaintpartial.x1 != imapaintpartial.x2 &&
+           imapaintpartial.y1 != imapaintpartial.y2)
+       {
+               IMB_partial_display_buffer_update_delayed(ibuf, imapaintpartial.x1, imapaintpartial.y1,
+                                                         imapaintpartial.x2, imapaintpartial.y2);
        }
        
        if (ibuf->mipmap[0])
@@ -4790,7 +4787,7 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter,
         */
        if (BKE_brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, is_data == FALSE)) {
                if (update)
-                       imapaint_image_update(s->scene, s->sima, image, ibuf, texpaint);
+                       imapaint_image_update(s->sima, image, ibuf, texpaint);
                BKE_image_release_ibuf(image, ibuf, NULL);
                return 1;
        }
index 1e33f8d..a05f0d5 100644 (file)
@@ -133,6 +133,8 @@ void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_b
                                        int xmin, int ymin, int xmax, int ymax,
                                        int update_orig_byte_buffer);
 
+void IMB_partial_display_buffer_update_delayed(struct ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax);
+
 /* ** Pixel processor functions ** */
 struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const struct ColorManagedViewSettings *view_settings,
                                                                        const struct ColorManagedDisplaySettings *display_settings);
index e30f161..dde8d4d 100644 (file)
@@ -28,6 +28,8 @@
 #ifndef __IMB_IMBUF_TYPES_H__
 #define __IMB_IMBUF_TYPES_H__
 
+#include "DNA_vec_types.h"  /* for rcti */
+
 /**
  * \file IMB_imbuf_types.h
  * \ingroup imbuf
@@ -132,6 +134,7 @@ typedef struct ImBuf {
        unsigned int *display_buffer_flags;          /* array of per-display display buffers dirty flags */
        struct ColormanageCache *colormanage_cache;  /* cache used by color management */
        int colormanage_flag;
+       rcti invalid_rect;
 
        /* information for compressed textures */
        struct DDSData dds_data;
index a516812..ff297d7 100644 (file)
@@ -57,6 +57,7 @@
 #include "BLI_path_util.h"
 #include "BLI_string.h"
 #include "BLI_threads.h"
+#include "BLI_rect.h"
 
 #include "BKE_colortools.h"
 #include "BKE_context.h"
@@ -1823,6 +1824,18 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet
                colormanage_view_settings_to_cache(&cache_view_settings, applied_view_settings);
                colormanage_display_settings_to_cache(&cache_display_settings, display_settings);
 
+               if (ibuf->invalid_rect.xmin != ibuf->invalid_rect.xmax) {
+                       if ((ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) == 0) {
+                               IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect,
+                                                                 ibuf->x, 0, 0, applied_view_settings, display_settings,
+                                                                 ibuf->invalid_rect.xmin, ibuf->invalid_rect.ymin,
+                                                                 ibuf->invalid_rect.xmax, ibuf->invalid_rect.ymax,
+                                                                 FALSE);
+                       }
+
+                       BLI_rcti_init(&ibuf->invalid_rect, 0, 0, 0, 0);
+               }
+
                BLI_lock_thread(LOCK_COLORMANAGE);
 
                /* ensure color management bit fields exists */
@@ -2488,6 +2501,18 @@ void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer,
        }
 }
 
+void IMB_partial_display_buffer_update_delayed(ImBuf *ibuf, int xmin, int ymin, int xmax, int ymax)
+{
+       if (ibuf->invalid_rect.xmin == ibuf->invalid_rect.xmax) {
+               BLI_rcti_init(&ibuf->invalid_rect, xmin, xmax, ymin, ymax);
+       }
+       else {
+               rcti rect;
+               BLI_rcti_init(&rect, xmin, xmax, ymin, ymax);
+               BLI_rcti_union(&ibuf->invalid_rect, &rect);
+       }
+}
+
 /*********************** Pixel processor functions *************************/
 
 ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManagedViewSettings *view_settings,