From 7fcc1ac48b405f8f6ef0ab7b7cd3dba1f5c6b24d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 11 Feb 2013 13:24:35 +0000 Subject: [PATCH] Implemented delayed partial rect update for image buffers 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 --- .../editors/sculpt_paint/paint_image.c | 21 +++++++--------- source/blender/imbuf/IMB_colormanagement.h | 2 ++ source/blender/imbuf/IMB_imbuf_types.h | 3 +++ source/blender/imbuf/intern/colormanagement.c | 25 +++++++++++++++++++ 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index a1b3941dd7a..b9b3b1da762 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -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; } diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index 1e33f8da363..a05f0d5b3e6 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -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); diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index e30f1618c81..dde8d4d4ab7 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -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; diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index a516812eb53..ff297d70cc3 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -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,