VSE timeline, when many (hundreds/thousands) of thumbnails were visible, was very slow to redraw. This PR makes them 3-10x faster to redraw, by stopping doing things that are slow :) Part of #126087 thumbnail improvements task. - No longer do mute semitransparency or corner rounding on the CPU, do it in shader instead. - Stop creating a separate GPU texture for each thumbnail, on every repaint, and drawing each thumbnail as a separate draw call. Instead, put thumbnails into a single texture atlas (using a simple shelf packing algorithm), and draw them in batch, passing data via UBO. The atlas is still re-created every frame, but that does not seem to be a performance issue. Thumbnails are cropped horizontally based on how much of their parts are visible (e.g. a narrow strip on screen), so realistically the atlas size is kinda proportional to screen size, and ends up being just several megabytes of data transfer between CPU -> GPU each frame. On this Sprite Fright edit timeline view (612 visible thumbnails), time taken to repaint the timeline window: - Mac (M1 Max, Metal): 68.1ms -> 4.7ms - Windows (Ryzen 5950X, RTX 3080Ti, OpenGL): 23.7ms -> 6.8ms This also fixes a visual issue with thumbnails, where when strips are very tall, the "rounded corners" that were poked right into the thumbnail bitmap on the CPU were showing up due to actual bitmap being scaled up a lot. Pull Request: https://projects.blender.org/blender/blender/pulls/126972
61 lines
1.7 KiB
C++
61 lines
1.7 KiB
C++
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup sequencer
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
struct bContext;
|
|
struct ImBuf;
|
|
struct rctf;
|
|
struct Sequence;
|
|
struct Scene;
|
|
|
|
#include "BLI_function_ref.hh"
|
|
|
|
#include <string>
|
|
|
|
namespace blender::seq {
|
|
|
|
static constexpr int SEQ_THUMB_SIZE = 256;
|
|
|
|
/**
|
|
* Get a thumbnail image for given strip `seq` at `timeline_frame`.
|
|
*
|
|
* The function can return null if a strip type does not have a thumbnail, a source media file is
|
|
* not found, or the thumbnail has not been loaded yet.
|
|
*
|
|
* A "closest" thumbnail if there is no exact match can also be returned, e.g. for a movie strip
|
|
* the closest frame that has a thumbnail already.
|
|
*
|
|
* When there is no exact match, a request to load a thumbnail will be internally added and
|
|
* processed in the background. */
|
|
ImBuf *thumbnail_cache_get(const bContext *C,
|
|
Scene *scene,
|
|
const Sequence *seq,
|
|
float timeline_frame);
|
|
|
|
/**
|
|
* If total amount of resident thumbnails is too large, try to remove oldest-used ones to
|
|
* keep the cache size in check.
|
|
*/
|
|
void thumbnail_cache_maintain_capacity(Scene *scene);
|
|
|
|
void thumbnail_cache_invalidate_strip(Scene *scene, const Sequence *seq);
|
|
|
|
/**
|
|
* Discard in-flight thumbnail loading requests that are outside of the given view (X coordinate:
|
|
* timeline frames, Y coordinate: channels).
|
|
*/
|
|
void thumbnail_cache_discard_requests_outside(Scene *scene, const rctf &rect);
|
|
|
|
void thumbnail_cache_clear(Scene *scene);
|
|
void thumbnail_cache_destroy(Scene *scene);
|
|
|
|
bool strip_can_have_thumbnail(const Scene *scene, const Sequence *seq);
|
|
|
|
} // namespace blender::seq
|