1
1

Compare commits

...

1 Commits

Author SHA1 Message Date
e94cd5eeed T94900: Sequence drawing errors on selected platforms.
The VSE only uses an overlay texture to draw to the screen. The
GPUViewport assumes that drivers would clear textures when created, but
they do not on selected platforms. What would lead to drawing from
uncleared memory.

By selecting which layers would contain correct data allows us to use
dummy textures in these cases that would eliminate the drawing
artifacts.
2022-01-26 13:36:52 +01:00
5 changed files with 52 additions and 13 deletions

View File

@@ -2700,6 +2700,7 @@ void draw_timeline_seq(const bContext *C, ARegion *region)
seq_prefetch_wm_notify(C, scene);
GPUViewport *viewport = WM_draw_region_get_viewport(region);
GPU_viewport_default_layers_set(viewport, GPU_VIEWPORT_LAYER_OVERLAY);
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
GPU_depth_test(GPU_DEPTH_NONE);

View File

@@ -40,6 +40,12 @@ extern "C" {
typedef struct GHash GHash;
typedef struct GPUViewport GPUViewport;
typedef enum eGPUViewportLayer {
GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY = 0,
GPU_VIEWPORT_LAYER_COLOR = 1,
GPU_VIEWPORT_LAYER_OVERLAY = 2
} eGPUViewportLayer;
struct DRWData;
struct DefaultFramebufferList;
struct DefaultTextureList;
@@ -49,6 +55,7 @@ GPUViewport *GPU_viewport_create(void);
GPUViewport *GPU_viewport_stereo_create(void);
void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect);
void GPU_viewport_unbind(GPUViewport *viewport);
void GPU_viewport_default_layers_set(GPUViewport *viewport, eGPUViewportLayer active_layer);
/**
* Merge and draw the buffers of \a viewport into the currently active framebuffer, performing
* color transform to display space.
@@ -65,7 +72,7 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
int view,
const rcti *rect,
bool display_colorspace,
bool do_overlay_merge);
eGPUViewportLayer active_layers);
/**
* Must be executed inside Draw-manager OpenGL Context.
*/

View File

@@ -93,6 +93,8 @@ struct GPUViewport {
/* TODO(fclem): the uvimage display use the viewport but do not set any view transform for the
* moment. The end goal would be to let the GPUViewport do the color management. */
bool do_color_management;
/** The default layers to use when drawing to screen. */
eGPUViewportLayer default_layers;
struct GPUViewportBatch batch;
};
@@ -113,6 +115,11 @@ bool GPU_viewport_do_update(GPUViewport *viewport)
return ret;
}
void GPU_viewport_default_layers_set(GPUViewport *viewport, eGPUViewportLayer default_layers)
{
viewport->default_layers = default_layers;
}
GPUViewport *GPU_viewport_create(void)
{
GPUViewport *viewport = MEM_callocN(sizeof(GPUViewport), "GPUViewport");
@@ -403,11 +410,23 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
const rctf *rect_pos,
const rctf *rect_uv,
bool display_colorspace,
bool do_overlay_merge)
eGPUViewportLayer active_layers)
{
GPUTexture *color = viewport->color_render_tx[view];
GPUTexture *color_overlay = viewport->color_overlay_tx[view];
/* When drawing only the overlay it needs to be drawn on top of an empty texture. Some platforms
* do not clear textures when allocating what leads to scrambled parts of the display.
*
* See T94900 for more information. */
const bool do_overlay = ELEM(
active_layers, GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY, GPU_VIEWPORT_LAYER_OVERLAY);
const bool use_dummy_texture = viewport->default_layers == GPU_VIEWPORT_LAYER_OVERLAY;
if (use_dummy_texture) {
static float data[4] = {0.0f, 0.0f, 0.0f, 0.0f};
color = GPU_texture_create_2d(__func__, 1, 1, 0, GPU_RGBA16F, data);
}
bool use_ocio = false;
if (viewport->do_color_management && display_colorspace) {
@@ -424,7 +443,7 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
NULL,
viewport->dither,
false,
do_overlay_merge);
do_overlay);
}
GPUBatch *batch = gpu_viewport_batch_get(viewport, rect_pos, rect_uv);
@@ -433,7 +452,7 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
}
else {
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE);
GPU_batch_uniform_1i(batch, "overlay", do_overlay_merge);
GPU_batch_uniform_1i(batch, "overlay", do_overlay);
GPU_batch_uniform_1i(batch, "display_transform", display_colorspace);
GPU_batch_uniform_1i(batch, "image_texture", 0);
GPU_batch_uniform_1i(batch, "overlays_texture", 1);
@@ -448,13 +467,18 @@ static void gpu_viewport_draw_colormanaged(GPUViewport *viewport,
if (use_ocio) {
IMB_colormanagement_finish_glsl_draw();
}
if (use_dummy_texture) {
GPU_texture_free(color);
color = NULL;
}
}
void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
int view,
const rcti *rect,
bool display_colorspace,
bool do_overlay_merge)
eGPUViewportLayer active_layers)
{
GPUTexture *color = viewport->color_render_tx[view];
@@ -499,12 +523,12 @@ void GPU_viewport_draw_to_screen_ex(GPUViewport *viewport,
}
gpu_viewport_draw_colormanaged(
viewport, view, &pos_rect, &uv_rect, display_colorspace, do_overlay_merge);
viewport, view, &pos_rect, &uv_rect, display_colorspace, active_layers);
}
void GPU_viewport_draw_to_screen(GPUViewport *viewport, int view, const rcti *rect)
{
GPU_viewport_draw_to_screen_ex(viewport, view, rect, true, true);
GPU_viewport_draw_to_screen_ex(viewport, view, rect, true, viewport->default_layers);
}
void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
@@ -533,8 +557,13 @@ void GPU_viewport_unbind_from_offscreen(GPUViewport *viewport,
.ymax = 1.0f,
};
gpu_viewport_draw_colormanaged(
viewport, 0, &pos_rect, &uv_rect, display_colorspace, do_overlay_merge);
gpu_viewport_draw_colormanaged(viewport,
0,
&pos_rect,
&uv_rect,
display_colorspace,
do_overlay_merge ? GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY :
GPU_VIEWPORT_LAYER_COLOR);
/* This one is from the offscreen. Don't free it with the viewport. */
viewport->depth_tx = NULL;

View File

@@ -23,9 +23,7 @@
#pragma once
struct GPUOffScreen;
struct GPUTexture;
struct GPUViewport;
#include "GPU_viewport.h"
#ifdef __cplusplus
extern "C" {

View File

@@ -136,7 +136,11 @@ static void wm_xr_draw_viewport_buffers_to_active_framebuffer(
if (is_upside_down) {
SWAP(int, rect.ymin, rect.ymax);
}
GPU_viewport_draw_to_screen_ex(vp->viewport, 0, &rect, draw_view->expects_srgb_buffer, true);
GPU_viewport_draw_to_screen_ex(vp->viewport,
0,
&rect,
draw_view->expects_srgb_buffer,
GPU_VIEWPORT_LAYER_COLOR_AND_OVERLAY);
}
void wm_xr_draw_view(const GHOST_XrDrawViewInfo *draw_view, void *customdata)