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
This commit is contained in:
Sergey Sharybin 2013-02-11 13:24:35 +00:00
parent 30a18589e2
commit 7fcc1ac48b
4 changed files with 39 additions and 12 deletions

@ -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;
}

@ -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);

@ -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;

@ -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,