diff options
Diffstat (limited to 'source/blender/editors/render')
-rw-r--r-- | source/blender/editors/render/render_internal.c | 30 | ||||
-rw-r--r-- | source/blender/editors/render/render_opengl.c | 90 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 46 |
3 files changed, 108 insertions, 58 deletions
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index b236b555850..c08ea2b6429 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -61,6 +61,7 @@ #include "ED_object.h" #include "RE_pipeline.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -78,8 +79,8 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat { float *rectf = NULL; int ymin, ymax, xmin, xmax; - int rymin, rxmin, predivide, profile_from; - unsigned char *rectc; + int rymin, rxmin; + /* unsigned char *rectc; */ /* UNUSED */ /* if renrect argument, we only refresh scanlines */ if (renrect) { @@ -123,8 +124,14 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat if (rr->rectf) rectf = rr->rectf; else { - if (rr->rect32) + if (rr->rect32) { + /* special case, currently only happens with sequencer rendering, + * which updates the whole frame, so we can only mark display buffer + * as invalid here (sergey) + */ + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; return; + } else { if (rr->renlay == NULL || rr->renlay->rectf == NULL) return; rectf = rr->renlay->rectf; @@ -136,20 +143,11 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat imb_addrectImBuf(ibuf); rectf += 4 * (rr->rectx * ymin + xmin); - rectc = (unsigned char *)(ibuf->rect + ibuf->x * rymin + rxmin); - - if (scene && (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)) { - profile_from = IB_PROFILE_LINEAR_RGB; - predivide = (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE); - } - else { - profile_from = IB_PROFILE_SRGB; - predivide = 0; - } + /* rectc = (unsigned char *)(ibuf->rect + ibuf->x * rymin + rxmin); */ /* UNUSED */ - IMB_buffer_byte_from_float(rectc, rectf, - 4, ibuf->dither, IB_PROFILE_SRGB, profile_from, predivide, - xmax, ymax, ibuf->x, rr->rectx); + IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin, + &scene->view_settings, &scene->display_settings, + rxmin, rymin, rxmin + xmax, rymin + ymax); } /* ****************************** render invoking ***************** */ diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 55df1caf3eb..d9618e89b68 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -63,6 +63,7 @@ #include "RE_pipeline.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" +#include "IMB_colormanagement.h" #include "RNA_access.h" #include "RNA_define.h" @@ -143,22 +144,30 @@ static void screen_opengl_render_apply(OGLRender *oglrender) ibuf = BKE_sequencer_give_ibuf(context, CFRA, chanshown); if (ibuf) { + ImBuf *linear_ibuf; + BLI_assert((oglrender->sizex == ibuf->x) && (oglrender->sizey == ibuf->y)); - if (ibuf->rect_float == NULL) { - /* internally sequencer working in sRGB space and stores both bytes and float - * buffers in sRGB space, but if byte->float onversion doesn't happen in sequencer - * (e.g. when adding image sequence/movie into sequencer) there'll be only - * byte buffer and profile will still indicate sRGB->linear space conversion is needed - * here we're ensure there'll be no conversion happen and float buffer would store - * linear frame (sergey) */ - ibuf->profile = IB_PROFILE_NONE; - IMB_float_from_rect(ibuf); + linear_ibuf = IMB_dupImBuf(ibuf); + IMB_freeImBuf(ibuf); + + if (linear_ibuf->rect_float == NULL) { + /* internally sequencer working in display space and stores both bytes and float buffers in that space. + * It is possible that byte->float onversion didn't happen in sequencer (e.g. when adding image sequence/movie + * into sequencer) there'll be only byte buffer. Create float buffer from existing byte buffer, making it linear + */ + + IMB_float_from_rect(linear_ibuf); + } + else { + /* ensure float buffer is in linear space, not in display space */ + BKE_sequencer_imbuf_from_sequencer_space(scene, linear_ibuf); } - memcpy(rr->rectf, ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey); - IMB_freeImBuf(ibuf); + memcpy(rr->rectf, linear_ibuf->rect_float, sizeof(float) * 4 * oglrender->sizex * oglrender->sizey); + + IMB_freeImBuf(linear_ibuf); } } else if (view_context) { @@ -181,7 +190,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } if ((scene->r.mode & R_OSA) == 0) { - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, rr->rectf); } else { @@ -195,7 +204,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) BLI_jitter_init(jit_ofs[0], scene->r.osa); /* first sample buffer, also initializes 'rv3d->persmat' */ - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat, TRUE, FALSE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_buffer); /* skip the first sample */ @@ -205,7 +214,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) (jit_ofs[j][0] * 2.0f) / sizex, (jit_ofs[j][1] * 2.0f) / sizey); - ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE); + ED_view3d_draw_offscreen(scene, v3d, ar, sizex, sizey, NULL, winmat_jitter, TRUE, FALSE); GPU_offscreen_read_pixels(oglrender->ofs, GL_FLOAT, accum_tmp); add_vn_vn(accum_buffer, accum_tmp, sizex * sizey * sizeof(float)); } @@ -221,7 +230,7 @@ static void screen_opengl_render_apply(OGLRender *oglrender) else { /* shouldnt suddenly give errors mid-render but possible */ char err_out[256] = "unknown"; - ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, TRUE, err_out); + ImBuf *ibuf_view = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, oglrender->sizex, oglrender->sizey, IB_rectfloat, OB_SOLID, TRUE, FALSE, err_out); camera = scene->camera; if (ibuf_view) { @@ -233,27 +242,27 @@ static void screen_opengl_render_apply(OGLRender *oglrender) } } - /* rr->rectf is now filled with image data */ - - if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) - BKE_stamp_buf(scene, camera, NULL, rr->rectf, rr->rectx, rr->recty, 4); - /* note on color management: * * OpenGL renders into sRGB colors, but render buffers are expected to be - * linear if color management is enabled. So we convert to linear here, so - * the conversion back to bytes using the color management flag can make it - * sRGB again, and so that e.g. openexr saving also saves the correct linear - * float buffer. */ + * linear So we convert to linear here, so the conversion back to bytes can make it + * sRGB (or other display space) again, and so that e.g. openexr saving also saves the + * correct linear float buffer. + */ - if (oglrender->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) { - int predivide = 0; /* no alpha */ + if (!oglrender->is_sequencer) { + /* sequencer has got tricker ocnversion happened above */ IMB_buffer_float_from_float(rr->rectf, rr->rectf, - 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, predivide, + 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, FALSE, oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex); } + /* rr->rectf is now filled with image data */ + + if ((scene->r.stamp & R_STAMP_ALL) && (scene->r.stamp & R_STAMP_DRAW)) + BKE_stamp_buf(scene, camera, NULL, rr->rectf, rr->rectx, rr->recty, 4); + RE_ReleaseResult(oglrender->re); /* update byte from float buffer */ @@ -536,12 +545,28 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) ibuf = BKE_image_acquire_ibuf(oglrender->ima, &oglrender->iuser, &lock); if (ibuf) { + int needs_free = FALSE; + + if (is_movie || !BKE_imtype_supports_float(scene->r.im_format.imtype)) { + ImBuf *colormanage_ibuf = IMB_dupImBuf(ibuf); + + IMB_display_buffer_to_imbuf_rect(colormanage_ibuf, &scene->view_settings, &scene->display_settings); + imb_freerectfloatImBuf(colormanage_ibuf); + + // IMB_freeImBuf(ibuf); /* owned by the image */ + ibuf = colormanage_ibuf; + needs_free = TRUE; + } + /* color -> grayscale */ /* editing directly would alter the render view */ if (scene->r.im_format.planes == R_IMF_PLANES_BW) { - ImBuf *ibuf_bw = IMB_dupImBuf(ibuf); + ImBuf *ibuf_bw = IMB_dupImBuf(ibuf); IMB_color_to_bw(ibuf_bw); - // IMB_freeImBuf(ibuf); /* owned by the image */ + + if (needs_free) + IMB_freeImBuf(ibuf); + ibuf = ibuf_bw; } else { @@ -551,6 +576,13 @@ static int screen_opengl_render_anim_step(bContext *C, wmOperator *op) ibuf_cpy->rect = ibuf->rect; ibuf_cpy->rect_float = ibuf->rect_float; ibuf_cpy->zbuf_float = ibuf->zbuf_float; + + if (needs_free) { + ibuf_cpy->mall = ibuf->mall; + ibuf->mall = 0; + IMB_freeImBuf(ibuf); + } + ibuf = ibuf_cpy; } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 068a7aaa50a..6b6018e51d2 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -64,6 +64,7 @@ #include "BKE_brush.h" #include "BKE_context.h" +#include "BKE_colortools.h" #include "BKE_depsgraph.h" #include "BKE_global.h" #include "BKE_idprop.h" @@ -75,11 +76,13 @@ #include "BKE_material.h" #include "BKE_node.h" #include "BKE_object.h" +#include "BKE_scene.h" #include "BKE_texture.h" #include "BKE_world.h" #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" +#include "IMB_colormanagement.h" #include "BIF_gl.h" #include "BIF_glutil.h" @@ -115,7 +118,8 @@ ImBuf *get_brush_icon(Brush *brush) BLI_strncpy(path, brush->icon_filepath, sizeof(brush->icon_filepath)); BLI_path_abs(path, G.main->name); - brush->icon_imbuf = IMB_loadiffname(path, flags); + /* use default colorspaces for brushes */ + brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); // otherwise lets try to find it in other directories if (!(brush->icon_imbuf)) { @@ -123,8 +127,10 @@ ImBuf *get_brush_icon(Brush *brush) BLI_make_file_string(G.main->name, path, folder, brush->icon_filepath); - if (path[0]) - brush->icon_imbuf = IMB_loadiffname(path, flags); + if (path[0]) { + /* use fefault color spaces */ + brush->icon_imbuf = IMB_loadiffname(path, flags, NULL); + } } if (brush->icon_imbuf) @@ -254,6 +260,10 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre } sce->r.color_mgt_flag = scene->r.color_mgt_flag; + BKE_color_managed_display_settings_copy(&sce->display_settings, &scene->display_settings); + + BKE_color_managed_view_settings_free(&sce->view_settings); + BKE_color_managed_view_settings_copy(&sce->view_settings, &scene->view_settings); /* prevent overhead for small renders and icons (32) */ if (id && sp->sizex < 40) @@ -263,7 +273,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre /* exception: don't color manage texture previews or icons */ if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) - sce->r.color_mgt_flag &= ~R_COLOR_MANAGEMENT; + BKE_scene_disable_color_management(sce); if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO) sce->r.alphamode = R_ALPHAPREMUL; @@ -475,13 +485,13 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int char name[32]; int do_gamma_correct = FALSE, do_predivide = FALSE; int offx = 0; - int newx = BLI_RCT_SIZE_X(rect); - int newy = BLI_RCT_SIZE_Y(rect); + int newx = BLI_rcti_size_x(rect); + int newy = BLI_rcti_size_y(rect); if (id && GS(id->name) != ID_TE) { /* exception: don't color manage texture previews - show the raw values */ if (sce) { - do_gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT; + do_gamma_correct = TRUE; do_predivide = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE; } } @@ -514,15 +524,25 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int /* temporary conversion to byte for drawing */ float fx = rect->xmin + offx; float fy = rect->ymin; - int profile_from = (do_gamma_correct) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB; int dither = 0; unsigned char *rect_byte; rect_byte = MEM_mallocN(rres.rectx * rres.recty * sizeof(int), "ed_preview_draw_rect"); - IMB_buffer_byte_from_float(rect_byte, rres.rectf, - 4, dither, IB_PROFILE_SRGB, profile_from, do_predivide, - rres.rectx, rres.recty, rres.rectx, rres.rectx); + if (do_gamma_correct) { + IMB_display_buffer_transform_apply(rect_byte, rres.rectf, rres.rectx, rres.recty, 4, + &sce->view_settings, &sce->display_settings, do_predivide); + + } + else { + /* OCIO_TODO: currently seems an exception for textures (came fro mlegacish time), + * but is it indeed expected behavior, or textures should be + * color managed as well? + */ + IMB_buffer_byte_from_float(rect_byte, rres.rectf, + 4, dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, do_predivide, + rres.rectx, rres.recty, rres.rectx, rres.rectx); + } glaDrawPixelsSafe(fx, fy, rres.rectx, rres.recty, rres.rectx, GL_RGBA, GL_UNSIGNED_BYTE, rect_byte); @@ -549,8 +569,8 @@ void ED_preview_draw(const bContext *C, void *idp, void *parentp, void *slotp, r SpaceButs *sbuts = sa->spacedata.first; rcti newrect; int ok; - int newx = BLI_RCT_SIZE_X(rect); - int newy = BLI_RCT_SIZE_Y(rect); + int newx = BLI_rcti_size_x(rect); + int newy = BLI_rcti_size_y(rect); newrect.xmin = rect->xmin; newrect.xmax = rect->xmin; |