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
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-09-15 14:05:07 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-09-15 14:05:07 +0400
commita73dd3476e7d180d3320afc04d218ce22f2f3bfc (patch)
treea540f5657bc9e8692eb0d3417de71393bad6bece /source/blender/render
parentb93da9b01e163158a830872d29f8bd874f63d54d (diff)
Color Management, Stage 2: Switch color pipeline to use OpenColorIO
Replace old color pipeline which was supporting linear/sRGB color spaces only with OpenColorIO-based pipeline. This introduces two configurable color spaces: - Input color space for images and movie clips. This space is used to convert images/movies from color space in which file is saved to Blender's linear space (for float images, byte images are not internally converted, only input space is stored for such images and used later). This setting could be found in image/clip data block settings. - Display color space which defines space in which particular display is working. This settings could be found in scene's Color Management panel. When render result is being displayed on the screen, apart from converting image to display space, some additional conversions could happen. This conversions are: - View, which defines tone curve applying before display transformation. These are different ways to view the image on the same display device. For example it could be used to emulate film view on sRGB display. - Exposure affects on image exposure before tone map is applied. - Gamma is post-display gamma correction, could be used to match particular display gamma. - RGB curves are user-defined curves which are applying before display transformation, could be used for different purposes. All this settings by default are only applying on render result and does not affect on other images. If some particular image needs to be affected by this transformation, "View as Render" setting of image data block should be set to truth. Movie clips are always affected by all display transformations. This commit also introduces configurable color space in which sequencer is working. This setting could be found in scene's Color Management panel and it should be used if such stuff as grading needs to be done in color space different from sRGB (i.e. when Film view on sRGB display is use, using VD16 space as sequencer's internal space would make grading working in space which is close to the space using for display). Some technical notes: - Image buffer's float buffer is now always in linear space, even if it was created from 16bit byte images. - Space of byte buffer is stored in image buffer's rect_colorspace property. - Profile of image buffer was removed since it's not longer meaningful. - OpenGL and GLSL is supposed to always work in sRGB space. It is possible to support other spaces, but it's quite large project which isn't so much important. - Legacy Color Management option disabled is emulated by using None display. It could have some regressions, but there's no clear way to avoid them. - If OpenColorIO is disabled on build time, it should make blender behaving in the same way as previous release with color management enabled. More details could be found at this page (more details would be added soon): http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Color_Management -- Thanks to Xavier Thomas, Lukas Toene for initial work on OpenColorIO integration and to Brecht van Lommel for some further development and code/ usecase review!
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/include/render_result.h6
-rw-r--r--source/blender/render/intern/source/envmap.c3
-rw-r--r--source/blender/render/intern/source/pipeline.c60
-rw-r--r--source/blender/render/intern/source/render_result.c41
-rw-r--r--source/blender/render/intern/source/render_texture.c21
-rw-r--r--source/blender/render/intern/source/rendercore.c14
-rw-r--r--source/blender/render/intern/source/shadeinput.c9
7 files changed, 93 insertions, 61 deletions
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 303d4094f8e..999fb24ba32 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -47,6 +47,8 @@ struct RenderLayer;
struct RenderResult;
struct Scene;
struct rcti;
+struct ColorManagedDisplaySettings;
+struct ColorManagedViewSettings;
/* New */
@@ -90,7 +92,9 @@ void render_result_rect_from_ibuf(struct RenderResult *rr, struct RenderData *rd
void render_result_rect_fill_zero(struct RenderResult *rr);
void render_result_rect_get_pixels(struct RenderResult *rr, struct RenderData *rd,
- unsigned int *rect, int rectx, int recty);
+ unsigned int *rect, int rectx, int recty,
+ const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
#endif /* __RENDER_RESULT_H__ */
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index 26bd482af69..03eb21dfa23 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -472,9 +472,6 @@ static void render_envmap(Render *re, EnvMap *env)
ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat);
memcpy(ibuf->rect_float, rl->rectf, ibuf->channels * ibuf->x * ibuf->y * sizeof(float));
- if (re->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
-
/* envmap renders without alpha */
alpha = ibuf->rect_float + 3;
for (y = ibuf->x * ibuf->y - 1; y >= 0; y--, alpha += 4)
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 5f110410978..599d91333e6 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -67,6 +67,7 @@
#include "BLI_callbacks.h"
#include "PIL_time.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -333,7 +334,7 @@ void RE_ResultGet32(Render *re, unsigned int *rect)
RenderResult rres;
RE_AcquireResultImage(re, &rres);
- render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty);
+ render_result_rect_get_pixels(&rres, &re->r, rect, re->rectx, re->recty, &re->scene->view_settings, &re->scene->display_settings);
RE_ReleaseResultImage(re);
}
@@ -1434,7 +1435,7 @@ static void do_merge_fullsample(Render *re, bNodeTree *ntree)
ntreeCompositTagRender(re->scene);
ntreeCompositTagAnimated(ntree);
- ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0);
+ ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
}
/* ensure we get either composited result or the active layer */
@@ -1598,7 +1599,7 @@ static void do_render_composite_fields_blur_3d(Render *re)
if (re->r.scemode & R_FULL_SAMPLE)
do_merge_fullsample(re, ntree);
else {
- ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0);
+ ntreeCompositExecTree(ntree, &re->r, 1, G.background == 0, &re->scene->view_settings, &re->scene->display_settings);
}
ntree->stats_draw = NULL;
@@ -1647,7 +1648,7 @@ int RE_seq_render_active(Scene *scene, RenderData *rd)
static void do_render_seq(Render *re)
{
static int recurs_depth = 0;
- struct ImBuf *ibuf;
+ struct ImBuf *ibuf, *out;
RenderResult *rr; /* don't assign re->result here as it might change during give_ibuf_seq */
int cfra = re->r.cfra;
SeqRenderData context;
@@ -1674,7 +1675,11 @@ static void do_render_seq(Render *re)
100);
}
- ibuf = BKE_sequencer_give_ibuf(context, cfra, 0);
+ out = BKE_sequencer_give_ibuf(context, cfra, 0);
+
+ ibuf = IMB_dupImBuf(out);
+ IMB_freeImBuf(out);
+ BKE_sequencer_imbuf_from_sequencer_space(re->scene, ibuf);
recurs_depth--;
@@ -2069,6 +2074,14 @@ void RE_BlenderFrame(Render *re, Main *bmain, Scene *scene, SceneRenderLayer *sr
G.is_rendering = FALSE;
}
+static void colormanage_image_for_write(Scene *scene, ImBuf *ibuf)
+{
+ IMB_display_buffer_to_imbuf_rect(ibuf, &scene->view_settings, &scene->display_settings);
+
+ if (ibuf)
+ imb_freerectfloatImBuf(ibuf);
+}
+
static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovieHandle *mh, const char *name_override)
{
char name[FILE_MAX];
@@ -2081,19 +2094,27 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
/* write movie or image */
if (BKE_imtype_is_movie(scene->r.im_format.imtype)) {
int do_free = FALSE;
- unsigned int *rect32 = (unsigned int *)rres.rect32;
+ ImBuf *ibuf = render_result_rect_to_ibuf(&rres, &scene->r);
+
/* note; the way it gets 32 bits rects is weak... */
- if (rres.rect32 == NULL) {
- rect32 = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect");
- RE_ResultGet32(re, rect32);
+ if (ibuf->rect == NULL) {
+ ibuf->rect = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect");
+ RE_ResultGet32(re, ibuf->rect);
do_free = TRUE;
}
- ok = mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *)rect32,
- rres.rectx, rres.recty, re->reports);
+ colormanage_image_for_write(scene, ibuf);
+
+ ok = mh->append_movie(&re->r, scene->r.sfra, scene->r.cfra, (int *) ibuf->rect,
+ ibuf->x, ibuf->y, re->reports);
if (do_free) {
- MEM_freeN(rect32);
+ MEM_freeN(ibuf->rect);
+ ibuf->rect = NULL;
}
+
+ /* imbuf knows which rects are not part of ibuf */
+ IMB_freeImBuf(ibuf);
+
printf("Append frame %d", scene->r.cfra);
}
else {
@@ -2110,6 +2131,12 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
}
else {
ImBuf *ibuf = render_result_rect_to_ibuf(&rres, &scene->r);
+ int do_colormanagement;
+
+ do_colormanagement = !BKE_imtype_supports_float(scene->r.im_format.imtype);
+
+ if (do_colormanagement)
+ colormanage_image_for_write(scene, ibuf);
ok = BKE_imbuf_write_stamp(scene, camera, ibuf, name, &scene->r.im_format);
@@ -2127,6 +2154,9 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie
name[strlen(name) - 4] = 0;
BKE_add_image_extension(name, R_IMF_IMTYPE_JPEG90);
ibuf->planes = 24;
+
+ colormanage_image_for_write(scene, ibuf);
+
BKE_imbuf_write_stamp(scene, camera, ibuf, name, &imf);
printf("\nSaved: %s", name);
}
@@ -2381,7 +2411,8 @@ void RE_init_threadcount(Render *re)
* x/y offsets are only used on a partial copy when dimensions don't match */
void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char *filename, int x, int y)
{
- ImBuf *ibuf = IMB_loadiffname(filename, IB_rect);
+ /* OCIO_TODO: assume layer was saved in defaule color space */
+ ImBuf *ibuf = IMB_loadiffname(filename, IB_rect, NULL);
if (ibuf && (ibuf->rect || ibuf->rect_float)) {
if (ibuf->x == layer->rectx && ibuf->y == layer->recty) {
@@ -2470,8 +2501,7 @@ int RE_WriteEnvmapResult(struct ReportList *reports, Scene *scene, EnvMap *env,
return 0;
}
- if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
+ IMB_display_buffer_to_imbuf_rect(ibuf, &scene->view_settings, &scene->display_settings);
/* to save, we first get absolute path */
BLI_strncpy(filepath, relpath, sizeof(filepath));
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 2f932b2149e..f11f84c9d3b 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -50,6 +50,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "IMB_colormanagement.h"
#include "intern/openexr/openexr_multi.h"
@@ -1081,16 +1082,12 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
/* float factor for random dither, imbuf takes care of it */
ibuf->dither = rd->dither_intensity;
- /* prepare to gamma correct to sRGB color space */
- if (rd->color_mgt_flag & R_COLOR_MANAGEMENT) {
- /* sequence editor can generate 8bpc render buffers */
- if (ibuf->rect) {
- ibuf->profile = IB_PROFILE_SRGB;
- if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32))
- IMB_float_from_rect(ibuf);
- }
- else {
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
+ /* prepare to gamma correct to sRGB color space
+ * note that sequence editor can generate 8bpc render buffers
+ */
+ if (ibuf->rect) {
+ if (BKE_imtype_valid_depths(rd->im_format.imtype) & (R_IMF_CHAN_DEPTH_12 | R_IMF_CHAN_DEPTH_16 | R_IMF_CHAN_DEPTH_24 | R_IMF_CHAN_DEPTH_32)) {
+ IMB_float_from_rect(ibuf);
}
}
@@ -1106,22 +1103,14 @@ ImBuf *render_result_rect_to_ibuf(RenderResult *rr, RenderData *rd)
return ibuf;
}
-void render_result_rect_from_ibuf(RenderResult *rr, RenderData *rd, ImBuf *ibuf)
+void render_result_rect_from_ibuf(RenderResult *rr, RenderData *UNUSED(rd), ImBuf *ibuf)
{
if (ibuf->rect_float) {
- /* color management: when off ensure rectf is non-lin, since thats what the internal
- * render engine delivers */
- int profile_to = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
- int profile_from = (ibuf->profile == IB_PROFILE_LINEAR_RGB) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
- int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
-
if (!rr->rectf)
rr->rectf = MEM_mallocN(4 * sizeof(float) * rr->rectx * rr->recty, "render_seq rectf");
- IMB_buffer_float_from_float(rr->rectf, ibuf->rect_float,
- 4, profile_to, profile_from, predivide,
- rr->rectx, rr->recty, rr->rectx, rr->rectx);
-
+ memcpy(rr->rectf, ibuf->rect_float, 4 * sizeof(float) * rr->rectx * rr->recty);
+
/* TSK! Since sequence render doesn't free the *rr render result, the old rect32
* can hang around when sequence render has rendered a 32 bits one before */
if (rr->rect32) {
@@ -1153,19 +1142,17 @@ void render_result_rect_fill_zero(RenderResult *rr)
rr->rect32 = MEM_callocN(sizeof(int) * rr->rectx * rr->recty, "render_seq rect");
}
-void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty)
+void render_result_rect_get_pixels(RenderResult *rr, RenderData *rd, unsigned int *rect, int rectx, int recty,
+ const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
{
if (rr->rect32) {
memcpy(rect, rr->rect32, sizeof(int) * rr->rectx * rr->recty);
}
else if (rr->rectf) {
- int profile_from = (rd->color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_SRGB;
int predivide = (rd->color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE);
- int dither = 0;
- IMB_buffer_byte_from_float((unsigned char *)rect, rr->rectf,
- 4, dither, IB_PROFILE_SRGB, profile_from, predivide,
- rr->rectx, rr->recty, rr->rectx, rr->rectx);
+ IMB_display_buffer_transform_apply((unsigned char *) rect, rr->rectf, rr->rectx, rr->recty, 4,
+ view_settings, display_settings, predivide);
}
else
/* else fill with black */
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 4d3b9c2493e..6d22d8991b4 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -50,6 +50,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
#include "BKE_colortools.h"
#include "BKE_image.h"
@@ -1226,8 +1227,8 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex,
ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
- srgb_to_linearrgb_v3_v3(&texres->tr, &texres->tr);
+ if (ibuf && !(ibuf->rect_float))
+ IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace);
}
}
else {
@@ -2379,8 +2380,8 @@ void do_material_tex(ShadeInput *shi, Render *re)
ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && re->r.color_mgt_flag & R_COLOR_MANAGEMENT)
- srgb_to_linearrgb_v3_v3(tcol, tcol);
+ if (ibuf && !(ibuf->rect_float))
+ IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
}
if (mtex->mapto & MAP_COL) {
@@ -2891,8 +2892,8 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
- srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr);
+ if (ibuf && !(ibuf->rect_float))
+ IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
}
fact= texres.tin*mtex->colfac;
@@ -3106,8 +3107,8 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h
ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
- srgb_to_linearrgb_v3_v3(tcol, tcol);
+ if (ibuf && !(ibuf->rect_float))
+ IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace);
}
if (mtex->mapto & WOMAP_HORIZ) {
@@ -3320,8 +3321,8 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser);
/* don't linearize float buffers, assumed to be linear */
- if (ibuf && !(ibuf->rect_float) && R.r.color_mgt_flag & R_COLOR_MANAGEMENT)
- srgb_to_linearrgb_v3_v3(&texres.tr, &texres.tr);
+ if (ibuf && !(ibuf->rect_float))
+ IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace);
}
/* lamp colors were premultiplied with this */
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index c009c7b7394..97a05e6a4c9 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -62,6 +62,7 @@
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
/* local include */
#include "rayintersection.h"
@@ -1993,6 +1994,8 @@ typedef struct BakeShade {
float dxco[3], dyco[3];
short *do_update;
+
+ struct ColorSpace *rect_colorspace;
} BakeShade;
static void bake_set_shade_input(ObjectInstanceRen *obi, VlakRen *vlr, ShadeInput *shi, int quad, int UNUSED(isect), int x, int y, float u, float v)
@@ -2168,8 +2171,12 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua
else {
unsigned char *col= (unsigned char *)(bs->rect + bs->rectx*y + x);
- if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE) && (R.r.color_mgt_flag & R_COLOR_MANAGEMENT)) {
- linearrgb_to_srgb_uchar3(col, shr.combined);
+ if (ELEM(bs->type, RE_BAKE_ALL, RE_BAKE_TEXTURE)) {
+ float rgb[3];
+
+ copy_v3_v3(rgb, shr.combined);
+ IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace);
+ rgb_float_to_uchar(col, rgb);
}
else {
rgb_float_to_uchar(col, shr.combined);
@@ -2503,6 +2510,7 @@ static void shade_tface(BakeShade *bs)
bs->rectx= bs->ibuf->x;
bs->recty= bs->ibuf->y;
bs->rect= bs->ibuf->rect;
+ bs->rect_colorspace= bs->ibuf->rect_colorspace;
bs->rect_float= bs->ibuf->rect_float;
bs->quad= 0;
@@ -2613,8 +2621,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
ima->flag&= ~IMA_USED_FOR_RENDER;
if (ibuf) {
ibuf->userdata = NULL; /* use for masking if needed */
- if (ibuf->rect_float)
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
}
}
diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c
index bbdcfbb5a73..d1d2c66985e 100644
--- a/source/blender/render/intern/source/shadeinput.c
+++ b/source/blender/render/intern/source/shadeinput.c
@@ -1325,7 +1325,14 @@ void shade_input_initialize(ShadeInput *shi, RenderPart *pa, RenderLayer *rl, in
shi->sample = sample;
shi->thread = pa->thread;
shi->do_preview = (R.r.scemode & R_MATNODE_PREVIEW) != 0;
- shi->do_manage = (R.r.color_mgt_flag & R_COLOR_MANAGEMENT);
+
+ /* OCIO_TODO: for now assume color management is always enabled and vertes colors are in sRGB space
+ * probably would be nice to have this things configurable, but for now it should work
+ * also probably this flag could be removed (in separated commit) before the release
+ * since it's not actually meaningful anymore
+ */
+ shi->do_manage = TRUE;
+
shi->lay = rl->lay;
shi->layflag = rl->layflag;
shi->passflag = rl->passflag;