Reduce overhead when sampling texture images for brushes. The tests can
be cached and reused.
This commit is contained in:
@@ -634,15 +634,9 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br,
|
|||||||
rgba[2] = intensity;
|
rgba[2] = intensity;
|
||||||
rgba[3] = 1.0f;
|
rgba[3] = 1.0f;
|
||||||
}
|
}
|
||||||
else {
|
/* For consistency, sampling always returns color in linear space */
|
||||||
if (br->mtex.tex->type == TEX_IMAGE && br->mtex.tex->ima) {
|
else if (ups->do_linear_conversion) {
|
||||||
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(br->mtex.tex->ima, &br->mtex.tex->iuser, pool);
|
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, ups->colorspace);
|
||||||
/* For consistency, sampling always returns color in linear space */
|
|
||||||
if (tex_ibuf && tex_ibuf->rect_float == NULL) {
|
|
||||||
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, tex_ibuf->rect_colorspace);
|
|
||||||
}
|
|
||||||
BKE_image_pool_release_ibuf(br->mtex.tex->ima, tex_ibuf, pool);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return intensity;
|
return intensity;
|
||||||
|
|||||||
@@ -162,7 +162,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
|
|||||||
if (refresh) {
|
if (refresh) {
|
||||||
struct ImagePool *pool = NULL;
|
struct ImagePool *pool = NULL;
|
||||||
bool convert_to_linear = false;
|
bool convert_to_linear = false;
|
||||||
ImBuf *tex_ibuf;
|
struct ColorSpace *colorspace;
|
||||||
/* stencil is rotated later */
|
/* stencil is rotated later */
|
||||||
const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
|
const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
|
||||||
-mtex->rot : 0;
|
-mtex->rot : 0;
|
||||||
@@ -223,10 +223,11 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
|
if (mtex->tex->type == TEX_IMAGE && mtex->tex->ima) {
|
||||||
tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
|
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(mtex->tex->ima, &mtex->tex->iuser, pool);
|
||||||
/* For consistency, sampling always returns color in linear space */
|
/* For consistency, sampling always returns color in linear space */
|
||||||
if (tex_ibuf && tex_ibuf->rect_float == NULL) {
|
if (tex_ibuf && tex_ibuf->rect_float == NULL) {
|
||||||
convert_to_linear = true;
|
convert_to_linear = true;
|
||||||
|
colorspace = tex_ibuf->rect_colorspace;
|
||||||
}
|
}
|
||||||
BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
|
BKE_image_pool_release_ibuf(mtex->tex->ima, tex_ibuf, pool);
|
||||||
}
|
}
|
||||||
@@ -270,7 +271,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool prima
|
|||||||
if (col) {
|
if (col) {
|
||||||
float rgba[4];
|
float rgba[4];
|
||||||
|
|
||||||
paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_num, convert_to_linear, tex_ibuf);
|
paint_get_tex_pixel_col(mtex, x, y, rgba, pool, thread_num, convert_to_linear, colorspace);
|
||||||
|
|
||||||
buffer[index * 4] = rgba[0] * 255;
|
buffer[index * 4] = rgba[0] * 255;
|
||||||
buffer[index * 4 + 1] = rgba[1] * 255;
|
buffer[index * 4 + 1] = rgba[1] * 255;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ struct bContext;
|
|||||||
struct bglMats;
|
struct bglMats;
|
||||||
struct Brush;
|
struct Brush;
|
||||||
struct ImagePool;
|
struct ImagePool;
|
||||||
struct ImBuf;
|
struct ColorSpace;
|
||||||
struct ListBase;
|
struct ListBase;
|
||||||
struct Mesh;
|
struct Mesh;
|
||||||
struct MTex;
|
struct MTex;
|
||||||
@@ -200,7 +200,7 @@ void paint_calc_redraw_planes(float planes[4][4],
|
|||||||
|
|
||||||
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
|
float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius);
|
||||||
float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
|
float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool, int thread);
|
||||||
void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert, struct ImBuf *ibuf);
|
void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert, struct ColorSpace *colorspace);
|
||||||
|
|
||||||
void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y);
|
void paint_sample_color(const struct bContext *C, struct ARegion *ar, int x, int y);
|
||||||
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
|
void BRUSH_OT_curve_preset(struct wmOperatorType *ot);
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "BKE_paint.h"
|
#include "BKE_paint.h"
|
||||||
#include "BKE_brush.h"
|
#include "BKE_brush.h"
|
||||||
#include "BKE_colortools.h"
|
#include "BKE_colortools.h"
|
||||||
|
#include "BKE_image.h"
|
||||||
|
|
||||||
#include "WM_api.h"
|
#include "WM_api.h"
|
||||||
#include "WM_types.h"
|
#include "WM_types.h"
|
||||||
@@ -57,6 +58,8 @@
|
|||||||
#include "ED_screen.h"
|
#include "ED_screen.h"
|
||||||
#include "ED_view3d.h"
|
#include "ED_view3d.h"
|
||||||
|
|
||||||
|
#include "IMB_imbuf_types.h"
|
||||||
|
|
||||||
#include "paint_intern.h"
|
#include "paint_intern.h"
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
@@ -172,6 +175,18 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode,
|
|||||||
copy_v2_v2(ups->tex_mouse, mouse);
|
copy_v2_v2(ups->tex_mouse, mouse);
|
||||||
copy_v2_v2(ups->mask_tex_mouse, mouse);
|
copy_v2_v2(ups->mask_tex_mouse, mouse);
|
||||||
stroke->cached_size_pressure = pressure;
|
stroke->cached_size_pressure = pressure;
|
||||||
|
|
||||||
|
/* check here if color sampling the main brush should do color conversion. This is done here
|
||||||
|
* to avoid locking up to get the image buffer during sampling */
|
||||||
|
if (brush->mtex.tex && brush->mtex.tex->type == TEX_IMAGE && brush->mtex.tex->ima) {
|
||||||
|
ImBuf *tex_ibuf = BKE_image_pool_acquire_ibuf(brush->mtex.tex->ima, &brush->mtex.tex->iuser, NULL);
|
||||||
|
if (tex_ibuf && tex_ibuf->rect_float == NULL) {
|
||||||
|
ups->do_linear_conversion = true;
|
||||||
|
ups->colorspace = tex_ibuf->rect_colorspace;
|
||||||
|
}
|
||||||
|
BKE_image_pool_release_ibuf(brush->mtex.tex->ima, tex_ibuf, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
stroke->brush_init = true;
|
stroke->brush_init = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool,
|
|||||||
return intensity;
|
return intensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert_to_linear, ImBuf *ibuf)
|
void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool, int thread, bool convert_to_linear, struct ColorSpace *colorspace)
|
||||||
{
|
{
|
||||||
float co[3] = {u, v, 0.0f};
|
float co[3] = {u, v, 0.0f};
|
||||||
int hasrgb;
|
int hasrgb;
|
||||||
@@ -195,7 +195,7 @@ void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (convert_to_linear)
|
if (convert_to_linear)
|
||||||
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, ibuf->rect_colorspace);
|
IMB_colormanagement_colorspace_to_scene_linear_v3(rgba, colorspace);
|
||||||
|
|
||||||
linearrgb_to_srgb_v3_v3(rgba, rgba);
|
linearrgb_to_srgb_v3_v3(rgba, rgba);
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ struct Editing;
|
|||||||
struct SceneStats;
|
struct SceneStats;
|
||||||
struct bGPdata;
|
struct bGPdata;
|
||||||
struct MovieClip;
|
struct MovieClip;
|
||||||
|
struct ColorSpace;
|
||||||
|
|
||||||
/* ************************************************************* */
|
/* ************************************************************* */
|
||||||
/* Scene Data */
|
/* Scene Data */
|
||||||
@@ -932,7 +933,9 @@ typedef struct UnifiedPaintSettings {
|
|||||||
|
|
||||||
float brush_rotation;
|
float brush_rotation;
|
||||||
|
|
||||||
// all this below is used to communicate with the cursor drawing routine
|
/*********************************************************************************
|
||||||
|
* all data below are used to communicate with cursor drawing and tex sampling *
|
||||||
|
*********************************************************************************/
|
||||||
int draw_anchored;
|
int draw_anchored;
|
||||||
int anchored_size;
|
int anchored_size;
|
||||||
float anchored_initial_mouse[2];
|
float anchored_initial_mouse[2];
|
||||||
@@ -949,9 +952,14 @@ typedef struct UnifiedPaintSettings {
|
|||||||
/* position of mouse, used to sample the mask texture */
|
/* position of mouse, used to sample the mask texture */
|
||||||
float mask_tex_mouse[2];
|
float mask_tex_mouse[2];
|
||||||
|
|
||||||
|
/* ColorSpace cache to avoid locking up during sampling */
|
||||||
|
int do_linear_conversion;
|
||||||
|
struct ColorSpace *colorspace;
|
||||||
|
|
||||||
/* radius of brush, premultiplied with pressure.
|
/* radius of brush, premultiplied with pressure.
|
||||||
* In case of anchored brushes contains that radius */
|
* In case of anchored brushes contains that radius */
|
||||||
float pixel_radius;
|
float pixel_radius;
|
||||||
|
int pad2;
|
||||||
} UnifiedPaintSettings;
|
} UnifiedPaintSettings;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
Reference in New Issue
Block a user