Fix T84398: Multiview images show only one view.

The `image_get_gpu_texture` didn't use the iuser->view_index but
recalculated the requested view again. This lead to inconsistent
behavior when switching between multi view textures or stereo textures.

This has been fixed by ensuring that the `iuser->view_index` is always
used.

An Image has only place to store 2 view textures. This is done for
right/left eye compositing. A multi view texture can have more views.
This would lead to reading and writing to unallocated space.

When a multiview texture is requested that is larger than 1. It will
always be cached as being the first eye. The `gpu_view` of the Image is
also used as a cache key to check this.
This commit is contained in:
Jeroen Bakker 2021-01-25 11:17:03 +01:00
parent 02404ded80
commit ebaa3fcedd
Notes: blender-bot 2023-02-14 08:10:06 +01:00
Referenced by commit a5b996df88, Fix T92608: Image Editor does not display stereo images
Referenced by commit 5aa3167e48, Fix T90772: Image Editor not sampling color from the the currently
Referenced by issue #90772, Image Editor not sampling color from the the currently selected pass
Referenced by issue #84398, Multiview images show only one view
3 changed files with 16 additions and 7 deletions

View File

@ -271,6 +271,7 @@ static GPUTexture **get_image_gpu_texture_ptr(Image *ima,
{
const bool in_range = (textarget >= 0) && (textarget < TEXTARGET_COUNT);
BLI_assert(in_range);
BLI_assert(multiview_eye == 0 || multiview_eye == 1);
if (in_range) {
return &(ima->gputexture[textarget][multiview_eye]);
@ -310,9 +311,17 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
* the current `pass` and `layer` should be 0. */
short requested_pass = iuser ? iuser->pass : 0;
short requested_layer = iuser ? iuser->layer : 0;
if (ima->gpu_pass != requested_pass || ima->gpu_layer != requested_layer) {
short requested_view = iuser ? iuser->multi_index : 0;
/* There is room for 2 multiview textures. When a higher number is requested we should always
* target the first view slot. This is fine as multi view images aren't used together. */
if (requested_view < 2) {
requested_view = 0;
}
if (ima->gpu_pass != requested_pass || ima->gpu_layer != requested_layer ||
ima->gpu_view != requested_view) {
ima->gpu_pass = requested_pass;
ima->gpu_layer = requested_layer;
ima->gpu_view = requested_view;
ima->gpuflag |= IMA_GPU_REFRESH;
}
@ -345,9 +354,10 @@ static GPUTexture *image_get_gpu_texture(Image *ima,
BKE_image_tag_time(ima);
/* Test if we already have a texture. */
const int current_view = iuser ? ((iuser->flag & IMA_SHOW_STEREO) != 0 ? iuser->multiview_eye :
iuser->view) :
0;
int current_view = iuser ? iuser->multi_index : 0;
if (current_view >= 2) {
current_view = 0;
}
GPUTexture **tex = get_image_gpu_texture_ptr(ima, textarget, current_view);
if (*tex) {
return *tex;

View File

@ -110,9 +110,7 @@ static void space_image_gpu_texture_get(Image *image,
/* update multiindex and pass for the current eye */
BKE_image_multilayer_index(image->rr, &sima->iuser);
}
else {
BKE_image_multiview_index(image, &sima->iuser);
}
BKE_image_multiview_index(image, &sima->iuser);
if (ibuf) {
if (sima->flag & SI_SHOW_ZBUF && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1))) {

View File

@ -157,6 +157,7 @@ typedef struct Image {
short gpuflag;
short gpu_pass;
short gpu_layer;
short gpu_view;
char _pad2[6];
/** Deprecated. */