Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-10-09 19:57:32 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-10-09 19:57:32 +0400
commit6e1fe4ddd9209aa1b5bc562d92f82a6bfb743513 (patch)
treef81ee4356da9246609b4e25202f2aa13d3a14abd /source
parentd917bdb095573161522194449fc22f6809e5b5b2 (diff)
Implementation of curve mapping in GLSL
The title says it all, now having curve mapping enabled in color management settings wouldn't force fallback from GLSL to CPU based color space conversion.
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/render/render_internal.c2
-rw-r--r--source/blender/editors/screen/glutil.c9
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h9
-rw-r--r--source/blender/imbuf/intern/colormanagement.c119
-rw-r--r--source/blender/makesrna/intern/rna_render.c4
5 files changed, 106 insertions, 37 deletions
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 39d6f836815..df8d5ec4e84 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1152,7 +1152,7 @@ void render_view3d_draw(RenderEngine *engine, const bContext *C)
/* Try using GLSL display transform. */
if (force_fallback == false) {
- if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, true, false)) {
+ if (IMB_colormanagement_setup_glsl_draw(&scene->view_settings, &scene->display_settings, true)) {
glEnable(GL_BLEND);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glaDrawPixelsTex(rres.xof, rres.yof, rres.rectx, rres.recty, GL_RGBA, GL_FLOAT,
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 70e5aab6628..b70b06f2aa4 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -1091,18 +1091,15 @@ void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter,
if (ibuf->rect_float) {
if (ibuf->float_colorspace) {
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- ibuf->float_colorspace,
- true, false);
+ ibuf->float_colorspace, true);
}
else {
- ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings,
- true, false);
+ ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, true);
}
}
else {
ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- ibuf->rect_colorspace,
- false, false);
+ ibuf->rect_colorspace, false);
}
if (ok) {
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 64a2bbb72d9..8af86389db3 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -174,19 +174,16 @@ void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processo
/* ** OpenGL drawing routines using GLSL for color space transform ** */
/* Test if GLSL drawing is supported for combination of graphics card and this configuration */
-bool IMB_colormanagement_support_glsl_draw(const struct ColorManagedViewSettings *view_settings,
- bool skip_curves);
+bool IMB_colormanagement_support_glsl_draw(const struct ColorManagedViewSettings *view_settings);
/* Configures GLSL shader for conversion from scene linear to display space */
bool IMB_colormanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings,
- bool predivide,
- bool skip_curves);
+ bool predivide);
/* Same as above, but display space conversion happens from a specified space */
bool IMB_colormanagement_setup_glsl_draw_from_space(const struct ColorManagedViewSettings *view_settings,
const struct ColorManagedDisplaySettings *display_settings,
struct ColorSpace *colorspace,
- bool predivide,
- bool skip_curves);
+ bool predivide);
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, bool predivide);
/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 61051464c7f..cf9cc0c2e6f 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -119,6 +119,11 @@ static struct global_glsl_state {
char input[MAX_COLORSPACE_NAME];
float exposure, gamma;
+ CurveMapping *curve_mapping, *orig_curve_mapping;
+ bool use_curve_mapping;
+ int curve_mapping_timestamp;
+ OCIO_CurveMappingSettings curve_mapping_settings;
+
/* Container for GLSL state needed for OCIO module. */
struct OCIO_GLSLDrawState *ocio_glsl_state;
struct OCIO_GLSLDrawState *transform_ocio_glsl_state;
@@ -663,6 +668,12 @@ void colormanagement_exit(void)
if (global_glsl_state.processor)
OCIO_processorRelease(global_glsl_state.processor);
+ if (global_glsl_state.curve_mapping)
+ curvemapping_free(global_glsl_state.curve_mapping);
+
+ if (global_glsl_state.curve_mapping_settings.lut)
+ MEM_freeN(global_glsl_state.curve_mapping_settings.lut);
+
if (global_glsl_state.ocio_glsl_state)
OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
@@ -2937,16 +2948,61 @@ static bool check_glsl_display_processor_changed(const ColorManagedViewSettings
STREQ(global_glsl_state.input, from_colorspace));
}
+static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
+ OCIO_CurveMappingSettings *curve_mapping_settings)
+{
+ int i;
+
+ curvemapping_initialize(curve_mapping);
+ curvemapping_premultiply(curve_mapping, false);
+ curvemapping_table_RGBA(curve_mapping,
+ &curve_mapping_settings->lut,
+ &curve_mapping_settings->lut_size);
+
+ for (i = 0; i < 4; i++) {
+ CurveMap *cuma = curve_mapping->cm + i;
+ curve_mapping_settings->use_extend_extrapolate[i] = (cuma->flag & CUMA_EXTEND_EXTRAPOLATE) != 0;
+ curve_mapping_settings->range[i] = cuma->range;
+ curve_mapping_settings->mintable[i] = cuma->mintable;
+ curve_mapping_settings->ext_in_x[i] = cuma->ext_in[0];
+ curve_mapping_settings->ext_in_y[i] = cuma->ext_in[1];
+ curve_mapping_settings->ext_out_x[i] = cuma->ext_out[0];
+ curve_mapping_settings->ext_out_y[i] = cuma->ext_out[1];
+ curve_mapping_settings->first_x[i] = cuma->table[0].x;
+ curve_mapping_settings->first_y[i] = cuma->table[0].y;
+ curve_mapping_settings->last_x[i] = cuma->table[CM_TABLE].x;
+ curve_mapping_settings->last_y[i] = cuma->table[CM_TABLE].y;
+ }
+
+ copy_v3_v3(curve_mapping_settings->black, curve_mapping->black);
+ copy_v3_v3(curve_mapping_settings->bwmul, curve_mapping->bwmul);
+
+ curve_mapping_settings->cache_id = (size_t) curve_mapping;
+}
+
static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
const char *from_colorspace)
{
+ bool use_curve_mapping = (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) != 0;
+ bool need_update = false;
+
+ need_update = global_glsl_state.processor == NULL ||
+ check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace) ||
+ use_curve_mapping != global_glsl_state.use_curve_mapping;
+
+ if (use_curve_mapping && need_update == false) {
+ need_update |= view_settings->curve_mapping->changed_timestamp != global_glsl_state.curve_mapping_timestamp ||
+ view_settings->curve_mapping != global_glsl_state.orig_curve_mapping;
+ }
+
/* Update state if there's no processor yet or
* processor settings has been changed.
*/
- if (global_glsl_state.processor == NULL ||
- check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace))
- {
+ if (need_update) {
+ OCIO_CurveMappingSettings *curve_mapping_settings = &global_glsl_state.curve_mapping_settings;
+ CurveMapping *new_curve_mapping = NULL;
+
/* Store settings of processor for further comparison. */
BLI_strncpy(global_glsl_state.look, view_settings->look, MAX_COLORSPACE_NAME);
BLI_strncpy(global_glsl_state.view, view_settings->view_transform, MAX_COLORSPACE_NAME);
@@ -2955,6 +3011,35 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
global_glsl_state.exposure = view_settings->exposure;
global_glsl_state.gamma = view_settings->gamma;
+ /* We're using curve mapping's address as a acache ID,
+ * so we need to make sure re-allocation gives new address here.
+ * We do this by allocating new curve mapping before freeing ol one.
+ */
+ if (use_curve_mapping) {
+ new_curve_mapping = curvemapping_copy(view_settings->curve_mapping);
+ }
+
+ if (global_glsl_state.curve_mapping) {
+ curvemapping_free(global_glsl_state.curve_mapping);
+ MEM_freeN(curve_mapping_settings->lut);
+ global_glsl_state.curve_mapping = NULL;
+ curve_mapping_settings->lut = NULL;
+ }
+
+ /* Fill in OCIO's curve mapping settings. */
+ if (use_curve_mapping) {
+ curve_mapping_to_ocio_settings(new_curve_mapping, &global_glsl_state.curve_mapping_settings);
+
+ global_glsl_state.curve_mapping = new_curve_mapping;
+ global_glsl_state.curve_mapping_timestamp = view_settings->curve_mapping->changed_timestamp;
+ global_glsl_state.orig_curve_mapping = view_settings->curve_mapping;
+ global_glsl_state.use_curve_mapping = true;
+ }
+ else {
+ global_glsl_state.orig_curve_mapping = NULL;
+ global_glsl_state.use_curve_mapping = false;
+ }
+
/* Free old processor, if any. */
if (global_glsl_state.processor)
OCIO_processorRelease(global_glsl_state.processor);
@@ -2970,14 +3055,8 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
}
}
-bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *view_settings,
- bool skip_curves)
+bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *UNUSED(view_settings))
{
- /* curves not supported yet */
- if (!skip_curves)
- if (view_settings && (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES))
- return 0;
-
return OCIO_supportGLSLDraw();
}
@@ -2996,8 +3075,7 @@ bool IMB_colormanagement_support_glsl_draw(const ColorManagedViewSettings *view_
*/
bool IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- struct ColorSpace *from_colorspace, bool predivide,
- bool skip_curves)
+ struct ColorSpace *from_colorspace, bool predivide)
{
ColorManagedViewSettings default_view_settings;
const ColorManagedViewSettings *applied_view_settings;
@@ -3014,25 +3092,22 @@ bool IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettin
applied_view_settings = &default_view_settings;
}
- /* RGB curves mapping is not supported on GPU yet. */
- if (!skip_curves)
- if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES)
- return false;
-
/* Make sure OCIO processor is up-to-date. */
update_glsl_display_processor(applied_view_settings, display_settings,
from_colorspace ? from_colorspace->name : global_role_scene_linear);
- return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor, predivide);
+ return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor,
+ global_glsl_state.use_curve_mapping ? &global_glsl_state.curve_mapping_settings : NULL,
+ predivide);
}
/* Configures GLSL shader for conversion from scene linear to display space */
bool IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings,
- bool predivide, bool skip_curves)
+ bool predivide)
{
return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
- NULL, predivide, skip_curves);
+ NULL, predivide);
}
/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
@@ -3043,7 +3118,7 @@ bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C
IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings);
- return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide, false);
+ return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide);
}
/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
@@ -3082,7 +3157,7 @@ bool IMB_colormanagement_setup_transform_from_role_glsl(int role, bool predivide
processor = colorspace_to_scene_linear_processor(colorspace);
- return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor, predivide);
+ return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor, NULL, predivide);
}
/* Finish GLSL-based color space conversion */
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 5b809a51705..7ebbcf7b39b 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -66,14 +66,14 @@ static void engine_tag_update(RenderEngine *engine)
static int engine_support_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
{
- return IMB_colormanagement_support_glsl_draw(&scene->view_settings, true);
+ return IMB_colormanagement_support_glsl_draw(&scene->view_settings);
}
static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
{
IMB_colormanagement_setup_glsl_draw(&scene->view_settings,
&scene->display_settings,
- false, true);
+ false);
}
static void engine_unbind_display_space_shader(RenderEngine *UNUSED(engine))