Fix #131552: Backdrop has a wrong size of 256x256
The compositor backdrop in certain files always have a size of 256x256 regardless of the actual size of the viewer image. That's because the compositor writes its result to a different image buffer than the one the image engine reads its image buffer from. And the image engine assumes a default size of 256x256. The reason is a bit involved. For non multi-view images, the image module uses the special cache index value of IMA_NO_INDEX for the compositor backdrop, which works fine if the image was detected as a non multi-view image in the first place. However, this detection fails because the compositor may still write multi-view images even for non multi-view renders. In particular, before the compositor writes its viewer image, it ensures correct views by calling BKE_image_ensure_viewer_views, which first checks if we need to recreate the views of the viewer image if they don't match the render views. And in the case of non multi-view image, that check fails in one case. Functions like BKE_image_is_multiview checks if a single unnamed view exists in the image, unnamed being the keyword here. The root issue is that BKE_image_ensure_viewer_views only checks that a single view exists, while it should also check that it is unnamed. Which happens when the user enabled multi-view, added only one view, then disabled multi-view again. To fix this, we add a check for the name of the view in case of non multi-view images. And additionally pull the view matching code into its own documented utility function for clarity. Pull Request: https://projects.blender.org/blender/blender/pulls/132348
This commit is contained in:
@@ -2813,33 +2813,58 @@ static void image_viewer_create_views(const RenderData *rd, Image *ima)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns true if the views of the given image match the actives views in the given render data.
|
||||
* Returns false otherwise to indicate that the image views should be recreated to make them match
|
||||
* the render data. */
|
||||
static bool image_views_match_render_views(const Image *image, const RenderData *render_data)
|
||||
{
|
||||
/* The number of views in the image do not match the number of active views in the render
|
||||
* data. */
|
||||
const int number_of_active_views = BKE_scene_multiview_num_views_get(render_data);
|
||||
if (BLI_listbase_count(&image->views) != number_of_active_views) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the render data is not multi-view, then a single unnamed view should exist in the image,
|
||||
* otherwise, the views don't match. We don't have to check that a single view exist, since this
|
||||
* is handled by the check above for the number of views. */
|
||||
if (!(render_data->scemode & R_MULTIVIEW)) {
|
||||
const ImageView *image_view = static_cast<ImageView *>(image->views.first);
|
||||
/* If the view is unnamed, the views match, otherwise, they don't. */
|
||||
return image_view->name[0] == '\0';
|
||||
}
|
||||
|
||||
/* The render data is multi-view, so we need to check that for every view in the image, a
|
||||
* corresponding active render view with the same name exists, noting that they may not
|
||||
* necessarily be in the same order. */
|
||||
LISTBASE_FOREACH (ImageView *, image_view, &image->views) {
|
||||
SceneRenderView *scene_render_view = static_cast<SceneRenderView *>(
|
||||
BLI_findstring(&render_data->views, image_view->name, offsetof(SceneRenderView, name)));
|
||||
/* A render view doesn't exist for that image view with the same name, so the views don't
|
||||
* match. */
|
||||
if (!scene_render_view) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* A render view exists for that image view with the same name, but it is disabled, so the
|
||||
* views don't match. */
|
||||
if (!BKE_scene_multiview_is_render_view_active(render_data, scene_render_view)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void BKE_image_ensure_viewer_views(const RenderData *rd, Image *ima, ImageUser *iuser)
|
||||
{
|
||||
bool do_reset;
|
||||
const bool is_multiview = (rd->scemode & R_MULTIVIEW) != 0;
|
||||
|
||||
BLI_thread_lock(LOCK_DRAW_IMAGE);
|
||||
|
||||
if (!BKE_scene_multiview_is_stereo3d(rd)) {
|
||||
iuser->flag &= ~IMA_SHOW_STEREO;
|
||||
}
|
||||
|
||||
/* see if all scene render views are in the image view list */
|
||||
do_reset = (BKE_scene_multiview_num_views_get(rd) != BLI_listbase_count(&ima->views));
|
||||
|
||||
/* multiview also needs to be sure all the views are synced */
|
||||
if (is_multiview && !do_reset) {
|
||||
LISTBASE_FOREACH (ImageView *, iv, &ima->views) {
|
||||
SceneRenderView *srv = static_cast<SceneRenderView *>(
|
||||
BLI_findstring(&rd->views, iv->name, offsetof(SceneRenderView, name)));
|
||||
if ((srv == nullptr) || (BKE_scene_multiview_is_render_view_active(rd, srv) == false)) {
|
||||
do_reset = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (do_reset) {
|
||||
if (!image_views_match_render_views(ima, rd)) {
|
||||
BLI_mutex_lock(static_cast<ThreadMutex *>(ima->runtime.cache_mutex));
|
||||
|
||||
image_free_cached_frames(ima);
|
||||
|
||||
Reference in New Issue
Block a user