Fix T81751: Use GLSL for better anim player performance
Originally colorspace of float images was converted using CPU. GLSL will render images much faster. Originally image was converted to `global_role_default_byte` space, disregarding view transform and also display device, which now is possible to specify. These parameters could be set via commandline to settings used in Blender, however if they are to be set by users, these needs to be sanitized. Right now defaults are assumed for device given for `COLOR_ROLE_DEFAULT_BYTE`. This should produce same behavior as implemented before. Together with D11167 animation player performance should be much better. This code was mostly copy-pasted from sequencer. Reviewed By: sergey Differential Revision: https://developer.blender.org/D11178
This commit is contained in:
parent
7b9c865afc
commit
fd3e44492e
Notes:
blender-bot
2023-07-18 14:11:06 +02:00
Referenced by commit5ec6bcd474
, Fix PlayAnim X/Y flipping Referenced by issue #88194, Animation player displays washed out colors Referenced by issue #81751, Poor playback performance with large float images in the animation-player Referenced by issue #110204, Animation Player draws non-uniformly scaled when resizing window Referenced by pull request #110206, Fix #110204: Anim Player draws non-uniformly scaled when resizing window Referenced by commitc275f4219f
, Fix #110204: Anim Player draws non-uniformly scaled when resizing window
|
@ -47,9 +47,11 @@
|
|||
#include "BLI_fileops.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_rect.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
|
@ -138,6 +140,9 @@ typedef struct PlayState {
|
|||
|
||||
bool need_frame_update;
|
||||
int frame_cursor_x;
|
||||
|
||||
ColorManagedViewSettings view_settings;
|
||||
ColorManagedDisplaySettings display_settings;
|
||||
} PlayState;
|
||||
|
||||
/* for debugging */
|
||||
|
@ -288,6 +293,144 @@ static int pupdate_time(void)
|
|||
return (ptottime < 0);
|
||||
}
|
||||
|
||||
static void *ocio_transform_ibuf(PlayState *ps,
|
||||
ImBuf *ibuf,
|
||||
bool *r_glsl_used,
|
||||
eGPUTextureFormat *r_format,
|
||||
eGPUDataFormat *r_data,
|
||||
void **r_buffer_cache_handle)
|
||||
{
|
||||
void *display_buffer;
|
||||
bool force_fallback = false;
|
||||
*r_glsl_used = false;
|
||||
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
|
||||
force_fallback |= (ibuf->dither != 0.0f);
|
||||
|
||||
/* Default */
|
||||
*r_format = GPU_RGBA8;
|
||||
*r_data = GPU_DATA_UBYTE;
|
||||
|
||||
/* Fallback to CPU based color space conversion. */
|
||||
if (force_fallback) {
|
||||
*r_glsl_used = false;
|
||||
display_buffer = NULL;
|
||||
}
|
||||
else if (ibuf->rect_float) {
|
||||
display_buffer = ibuf->rect_float;
|
||||
|
||||
*r_data = GPU_DATA_FLOAT;
|
||||
if (ibuf->channels == 4) {
|
||||
*r_format = GPU_RGBA16F;
|
||||
}
|
||||
else if (ibuf->channels == 3) {
|
||||
/* Alpha is implicitly 1. */
|
||||
*r_format = GPU_RGB16F;
|
||||
}
|
||||
|
||||
if (ibuf->float_colorspace) {
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space(&ps->view_settings,
|
||||
&ps->display_settings,
|
||||
ibuf->float_colorspace,
|
||||
ibuf->dither,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
else {
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw(
|
||||
&ps->view_settings, &ps->display_settings, ibuf->dither, false);
|
||||
}
|
||||
}
|
||||
else if (ibuf->rect) {
|
||||
display_buffer = ibuf->rect;
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space(&ps->view_settings,
|
||||
&ps->display_settings,
|
||||
ibuf->float_colorspace,
|
||||
ibuf->dither,
|
||||
false,
|
||||
false);
|
||||
}
|
||||
else {
|
||||
display_buffer = NULL;
|
||||
}
|
||||
|
||||
/* There is data to be displayed, but GLSL is not initialized
|
||||
* properly, in this case we fallback to CPU-based display transform. */
|
||||
if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
|
||||
display_buffer = IMB_display_buffer_acquire(
|
||||
ibuf, &ps->view_settings, &ps->display_settings, r_buffer_cache_handle);
|
||||
*r_format = GPU_RGBA8;
|
||||
*r_data = GPU_DATA_UBYTE;
|
||||
}
|
||||
|
||||
return display_buffer;
|
||||
}
|
||||
|
||||
static void draw_display_buffer(PlayState *ps, ImBuf *ibuf)
|
||||
{
|
||||
void *display_buffer;
|
||||
|
||||
/* Format needs to be created prior to any #immBindShader call.
|
||||
* Do it here because OCIO binds its own shader. */
|
||||
eGPUTextureFormat format;
|
||||
eGPUDataFormat data;
|
||||
bool glsl_used = false;
|
||||
GPUVertFormat *imm_format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
uint texCoord = GPU_vertformat_attr_add(
|
||||
imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
void *buffer_cache_handle = NULL;
|
||||
display_buffer = ocio_transform_ibuf(ps, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
|
||||
|
||||
GPUTexture *texture = GPU_texture_create_2d("display_buf", ibuf->x, ibuf->y, 1, format, NULL);
|
||||
GPU_texture_update(texture, data, display_buffer);
|
||||
GPU_texture_filter_mode(texture, false);
|
||||
|
||||
GPU_texture_bind(texture, 0);
|
||||
|
||||
if (!glsl_used) {
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
|
||||
immUniformColor3f(1.0f, 1.0f, 1.0f);
|
||||
immUniform1i("image", 0);
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 4);
|
||||
|
||||
rctf preview;
|
||||
rctf canvas;
|
||||
|
||||
BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
BLI_rctf_init(&preview, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmin, canvas.ymin);
|
||||
immVertex2f(pos, preview.xmin, preview.ymin);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmin, canvas.ymax);
|
||||
immVertex2f(pos, preview.xmin, preview.ymax);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmax, canvas.ymax);
|
||||
immVertex2f(pos, preview.xmax, preview.ymax);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmax, canvas.ymin);
|
||||
immVertex2f(pos, preview.xmax, preview.ymin);
|
||||
|
||||
immEnd();
|
||||
|
||||
GPU_texture_unbind(texture);
|
||||
GPU_texture_free(texture);
|
||||
|
||||
if (!glsl_used) {
|
||||
immUnbindProgram();
|
||||
}
|
||||
else {
|
||||
IMB_colormanagement_finish_glsl_draw();
|
||||
}
|
||||
|
||||
if (buffer_cache_handle) {
|
||||
IMB_display_buffer_release(buffer_cache_handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void playanim_toscreen(
|
||||
PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
|
||||
{
|
||||
|
@ -295,13 +438,6 @@ static void playanim_toscreen(
|
|||
printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>");
|
||||
return;
|
||||
}
|
||||
if (ibuf->rect == NULL && ibuf->rect_float) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
imb_freerectfloatImBuf(ibuf);
|
||||
}
|
||||
if (ibuf->rect == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
|
||||
|
||||
|
@ -331,19 +467,7 @@ static void playanim_toscreen(
|
|||
8);
|
||||
}
|
||||
|
||||
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
|
||||
|
||||
immDrawPixelsTex(&state,
|
||||
offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
|
||||
offs_y + (ps->draw_flip[1] ? span_y : 0.0f),
|
||||
ibuf->x,
|
||||
ibuf->y,
|
||||
GPU_RGBA8,
|
||||
false,
|
||||
ibuf->rect,
|
||||
((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x),
|
||||
((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y),
|
||||
NULL);
|
||||
draw_display_buffer(ps, ibuf);
|
||||
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
|
@ -1178,6 +1302,10 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
|
|||
|
||||
ps.fontid = -1;
|
||||
|
||||
STRNCPY(ps.display_settings.display_device,
|
||||
IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE));
|
||||
IMB_colormanagement_init_default_view_settings(&ps.view_settings, &ps.display_settings);
|
||||
|
||||
while (argc > 1) {
|
||||
if (argv[1][0] == '-') {
|
||||
switch (argv[1][1]) {
|
||||
|
|
Loading…
Reference in New Issue