Fix T70229: Show Cache On will cause a lower fps
Use gpu batch drawing for cache content in VSE. Immediate drawing caused significant dorp in framerate. Reviewed By: fclem Differential Revision: https://developer.blender.org/D6835
This commit is contained in:
@@ -338,6 +338,7 @@ void BKE_sequencer_cache_iterate(
|
|||||||
struct Scene *scene,
|
struct Scene *scene,
|
||||||
void *userdata,
|
void *userdata,
|
||||||
bool callback(void *userdata, struct Sequence *seq, int cfra, int cache_type, float cost));
|
bool callback(void *userdata, struct Sequence *seq, int cfra, int cache_type, float cost));
|
||||||
|
size_t BKE_sequencer_cache_get_num_items(struct Scene *scene);
|
||||||
bool BKE_sequencer_cache_is_full(struct Scene *scene);
|
bool BKE_sequencer_cache_is_full(struct Scene *scene);
|
||||||
|
|
||||||
/* **********************************************************************
|
/* **********************************************************************
|
||||||
|
@@ -717,6 +717,20 @@ void BKE_sequencer_cache_put(
|
|||||||
seq_cache_unlock(scene);
|
seq_cache_unlock(scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t BKE_sequencer_cache_get_num_items(struct Scene *scene)
|
||||||
|
{
|
||||||
|
SeqCache *cache = seq_cache_get_from_scene(scene);
|
||||||
|
if (!cache) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq_cache_lock(scene);
|
||||||
|
size_t num_items = BLI_ghash_len(cache->hash);
|
||||||
|
seq_cache_unlock(scene);
|
||||||
|
|
||||||
|
return num_items;
|
||||||
|
}
|
||||||
|
|
||||||
void BKE_sequencer_cache_iterate(
|
void BKE_sequencer_cache_iterate(
|
||||||
struct Scene *scene,
|
struct Scene *scene,
|
||||||
void *userdata,
|
void *userdata,
|
||||||
|
@@ -55,6 +55,7 @@
|
|||||||
#include "GPU_matrix.h"
|
#include "GPU_matrix.h"
|
||||||
#include "GPU_state.h"
|
#include "GPU_state.h"
|
||||||
#include "GPU_framebuffer.h"
|
#include "GPU_framebuffer.h"
|
||||||
|
#include "GPU_vertex_buffer.h"
|
||||||
|
|
||||||
#include "ED_anim_api.h"
|
#include "ED_anim_api.h"
|
||||||
#include "ED_gpencil.h"
|
#include "ED_gpencil.h"
|
||||||
@@ -1795,10 +1796,17 @@ static void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct CacheDrawData {
|
typedef struct CacheDrawData {
|
||||||
const bContext *C;
|
struct View2D *v2d;
|
||||||
uint pos;
|
|
||||||
float stripe_offs;
|
float stripe_offs;
|
||||||
float stripe_ht;
|
float stripe_ht;
|
||||||
|
GPUVertBuf *raw_vbo;
|
||||||
|
GPUVertBuf *preprocessed_vbo;
|
||||||
|
GPUVertBuf *composite_vbo;
|
||||||
|
GPUVertBuf *final_out_vbo;
|
||||||
|
size_t raw_vert_count;
|
||||||
|
size_t preprocessed_vert_count;
|
||||||
|
size_t composite_vert_count;
|
||||||
|
size_t final_out_vert_count;
|
||||||
} CacheDrawData;
|
} CacheDrawData;
|
||||||
|
|
||||||
/* Called as a callback */
|
/* Called as a callback */
|
||||||
@@ -1806,93 +1814,80 @@ static bool draw_cache_view_cb(
|
|||||||
void *userdata, struct Sequence *seq, int nfra, int cache_type, float UNUSED(cost))
|
void *userdata, struct Sequence *seq, int nfra, int cache_type, float UNUSED(cost))
|
||||||
{
|
{
|
||||||
CacheDrawData *drawdata = userdata;
|
CacheDrawData *drawdata = userdata;
|
||||||
const bContext *C = drawdata->C;
|
struct View2D *v2d = drawdata->v2d;
|
||||||
Scene *scene = CTX_data_scene(C);
|
|
||||||
ARegion *ar = CTX_wm_region(C);
|
|
||||||
struct View2D *v2d = &ar->v2d;
|
|
||||||
Editing *ed = scene->ed;
|
|
||||||
uint pos = drawdata->pos;
|
|
||||||
|
|
||||||
if ((ed->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT) == 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float stripe_bot, stripe_top, stripe_offs, stripe_ht;
|
float stripe_bot, stripe_top, stripe_offs, stripe_ht;
|
||||||
float color[4];
|
GPUVertBuf *vbo;
|
||||||
color[3] = 0.4f;
|
size_t *vert_count;
|
||||||
|
|
||||||
switch (cache_type) {
|
switch (cache_type) {
|
||||||
case SEQ_CACHE_STORE_FINAL_OUT:
|
case SEQ_CACHE_STORE_FINAL_OUT:
|
||||||
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT) {
|
stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) - v2d->cur.ymin;
|
||||||
color[0] = 1.0f;
|
stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HANDLE_HEIGHT);
|
||||||
color[1] = 0.4f;
|
stripe_top = stripe_bot + stripe_ht;
|
||||||
color[2] = 0.2f;
|
vbo = drawdata->final_out_vbo;
|
||||||
stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) -
|
vert_count = &drawdata->final_out_vert_count;
|
||||||
v2d->cur.ymin;
|
break;
|
||||||
stripe_bot = UI_view2d_region_to_view_y(v2d, V2D_SCROLL_HANDLE_HEIGHT);
|
|
||||||
stripe_top = stripe_bot + stripe_ht;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SEQ_CACHE_STORE_RAW:
|
case SEQ_CACHE_STORE_RAW:
|
||||||
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_RAW) {
|
stripe_offs = drawdata->stripe_offs;
|
||||||
color[0] = 1.0f;
|
stripe_ht = drawdata->stripe_ht;
|
||||||
color[1] = 0.1f;
|
stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_offs;
|
||||||
color[2] = 0.02f;
|
stripe_top = stripe_bot + stripe_ht;
|
||||||
stripe_offs = drawdata->stripe_offs;
|
vbo = drawdata->raw_vbo;
|
||||||
stripe_ht = drawdata->stripe_ht;
|
vert_count = &drawdata->raw_vert_count;
|
||||||
stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_offs;
|
break;
|
||||||
stripe_top = stripe_bot + stripe_ht;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SEQ_CACHE_STORE_PREPROCESSED:
|
case SEQ_CACHE_STORE_PREPROCESSED:
|
||||||
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED) {
|
stripe_offs = drawdata->stripe_offs;
|
||||||
color[0] = 0.1f;
|
stripe_ht = drawdata->stripe_ht;
|
||||||
color[1] = 0.1f;
|
stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + (stripe_offs + stripe_ht) + stripe_offs;
|
||||||
color[2] = 0.75f;
|
stripe_top = stripe_bot + stripe_ht;
|
||||||
stripe_offs = drawdata->stripe_offs;
|
vbo = drawdata->preprocessed_vbo;
|
||||||
stripe_ht = drawdata->stripe_ht;
|
vert_count = &drawdata->preprocessed_vert_count;
|
||||||
stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + (stripe_offs + stripe_ht) + stripe_offs;
|
break;
|
||||||
stripe_top = stripe_bot + stripe_ht;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
case SEQ_CACHE_STORE_COMPOSITE:
|
case SEQ_CACHE_STORE_COMPOSITE:
|
||||||
if (scene->ed->cache_flag & SEQ_CACHE_VIEW_COMPOSITE) {
|
stripe_offs = drawdata->stripe_offs;
|
||||||
color[0] = 1.0f;
|
stripe_ht = drawdata->stripe_ht;
|
||||||
color[1] = 0.6f;
|
stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_offs;
|
||||||
color[2] = 0.0f;
|
stripe_bot = stripe_top - stripe_ht;
|
||||||
stripe_offs = drawdata->stripe_offs;
|
vbo = drawdata->composite_vbo;
|
||||||
stripe_ht = drawdata->stripe_ht;
|
vert_count = &drawdata->composite_vert_count;
|
||||||
stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_offs;
|
break;
|
||||||
stripe_bot = stripe_top - stripe_ht;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cfra = seq->start + nfra;
|
int cfra = seq->start + nfra;
|
||||||
immUniformColor4f(color[0], color[1], color[2], color[3]);
|
float vert_pos[6][2];
|
||||||
immRectf(pos, cfra, stripe_bot, cfra + 1, stripe_top);
|
copy_v2_fl2(vert_pos[0], cfra, stripe_bot);
|
||||||
|
copy_v2_fl2(vert_pos[1], cfra, stripe_top);
|
||||||
|
copy_v2_fl2(vert_pos[2], cfra + 1, stripe_top);
|
||||||
|
copy_v2_v2(vert_pos[3], vert_pos[2]);
|
||||||
|
copy_v2_v2(vert_pos[4], vert_pos[0]);
|
||||||
|
copy_v2_fl2(vert_pos[5], cfra + 1, stripe_bot);
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
GPU_vertbuf_vert_set(vbo, *vert_count + i, vert_pos[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
*vert_count += 6;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void draw_cache_view_batch(
|
||||||
|
GPUVertBuf *vbo, size_t vert_count, float col_r, float col_g, float col_b, float col_a)
|
||||||
|
{
|
||||||
|
GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_TRIS, vbo, NULL, GPU_BATCH_OWNS_VBO);
|
||||||
|
GPU_vertbuf_data_len_set(vbo, vert_count);
|
||||||
|
GPU_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
|
||||||
|
GPU_batch_uniform_4f(batch, "color", col_r, col_g, col_b, col_a);
|
||||||
|
if (vert_count > 0) {
|
||||||
|
GPU_batch_draw(batch);
|
||||||
|
}
|
||||||
|
GPU_batch_discard(batch);
|
||||||
|
}
|
||||||
|
|
||||||
static void draw_cache_view(const bContext *C)
|
static void draw_cache_view(const bContext *C)
|
||||||
{
|
{
|
||||||
Scene *scene = CTX_data_scene(C);
|
Scene *scene = CTX_data_scene(C);
|
||||||
@@ -1961,15 +1956,45 @@ static void draw_cache_view(const bContext *C)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CacheDrawData userdata;
|
|
||||||
userdata.C = C;
|
|
||||||
userdata.pos = pos;
|
|
||||||
userdata.stripe_offs = stripe_offs;
|
|
||||||
userdata.stripe_ht = stripe_ht;
|
|
||||||
|
|
||||||
BKE_sequencer_cache_iterate(scene, &userdata, draw_cache_view_cb);
|
|
||||||
|
|
||||||
immUnbindProgram();
|
immUnbindProgram();
|
||||||
|
|
||||||
|
size_t cache_num_items = BKE_sequencer_cache_get_num_items(scene);
|
||||||
|
|
||||||
|
if (cache_num_items > 0) {
|
||||||
|
GPUVertFormat format = {0};
|
||||||
|
GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||||
|
|
||||||
|
CacheDrawData userdata;
|
||||||
|
userdata.v2d = v2d;
|
||||||
|
userdata.stripe_offs = stripe_offs;
|
||||||
|
userdata.stripe_ht = stripe_ht;
|
||||||
|
userdata.raw_vert_count = 0;
|
||||||
|
userdata.preprocessed_vert_count = 0;
|
||||||
|
userdata.composite_vert_count = 0;
|
||||||
|
userdata.final_out_vert_count = 0;
|
||||||
|
userdata.raw_vbo = GPU_vertbuf_create_with_format(&format);
|
||||||
|
userdata.preprocessed_vbo = GPU_vertbuf_create_with_format(&format);
|
||||||
|
userdata.composite_vbo = GPU_vertbuf_create_with_format(&format);
|
||||||
|
userdata.final_out_vbo = GPU_vertbuf_create_with_format(&format);
|
||||||
|
|
||||||
|
/* We can not get item count per cache type, so using total item count is safe. */
|
||||||
|
size_t max_vert_count = cache_num_items * 6;
|
||||||
|
GPU_vertbuf_data_alloc(userdata.raw_vbo, max_vert_count);
|
||||||
|
GPU_vertbuf_data_alloc(userdata.preprocessed_vbo, max_vert_count);
|
||||||
|
GPU_vertbuf_data_alloc(userdata.composite_vbo, max_vert_count);
|
||||||
|
GPU_vertbuf_data_alloc(userdata.final_out_vbo, max_vert_count);
|
||||||
|
|
||||||
|
BKE_sequencer_cache_iterate(scene, &userdata, draw_cache_view_cb);
|
||||||
|
|
||||||
|
draw_cache_view_batch(userdata.raw_vbo, userdata.raw_vert_count, 1.0f, 0.1f, 0.02f, 0.4f);
|
||||||
|
draw_cache_view_batch(
|
||||||
|
userdata.preprocessed_vbo, userdata.preprocessed_vert_count, 0.1f, 0.1f, 0.75f, 0.4f);
|
||||||
|
draw_cache_view_batch(
|
||||||
|
userdata.composite_vbo, userdata.composite_vert_count, 1.0f, 0.6f, 0.0f, 0.4f);
|
||||||
|
draw_cache_view_batch(
|
||||||
|
userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f);
|
||||||
|
}
|
||||||
|
|
||||||
GPU_blend(false);
|
GPU_blend(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user