VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
/* SPDX-FileCopyrightText: 2021-2024 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2021-10-06 04:16:50 +02:00
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
|
* \ingroup spseq
|
|
|
|
|
*/
|
|
|
|
|
|
2023-11-16 11:41:55 +01:00
|
|
|
#include "BKE_context.hh"
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
#include "BLI_array.hh"
|
|
|
|
|
|
2024-01-18 22:50:23 +02:00
|
|
|
#include "IMB_imbuf.hh"
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
#include "DNA_sequence_types.h"
|
|
|
|
|
#include "DNA_space_types.h"
|
2025-02-11 16:59:42 +01:00
|
|
|
#include "DNA_userdef_types.h"
|
2021-10-06 04:16:50 +02:00
|
|
|
|
2025-01-26 20:08:00 +01:00
|
|
|
#include "GPU_batch.hh"
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
#include "GPU_batch_presets.hh"
|
|
|
|
|
#include "GPU_matrix.hh"
|
|
|
|
|
#include "GPU_shader_shared.hh"
|
|
|
|
|
#include "GPU_texture.hh"
|
2025-01-26 20:08:00 +01:00
|
|
|
#include "GPU_uniform_buffer.hh"
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
|
|
|
|
|
#include "IMB_colormanagement.hh"
|
2021-10-06 04:16:50 +02:00
|
|
|
|
2023-11-02 01:05:06 +01:00
|
|
|
#include "SEQ_render.hh"
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
#include "SEQ_thumbnail_cache.hh"
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
#include "WM_api.hh"
|
|
|
|
|
|
|
|
|
|
#include "sequencer_intern.hh"
|
|
|
|
|
#include "sequencer_strips_batch.hh"
|
2024-08-29 17:16:41 +10:00
|
|
|
|
2025-03-06 06:22:14 +01:00
|
|
|
namespace blender::ed::vse {
|
2024-06-04 20:05:35 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
/* Information for one thumbnail picture in the timeline. Note that a single
|
|
|
|
|
* strip could have multiple thumbnails. */
|
|
|
|
|
struct SeqThumbInfo {
|
|
|
|
|
ImBuf *ibuf;
|
|
|
|
|
/* Strip coordinates in timeline space (X: frames, Y: channels). */
|
|
|
|
|
float left_handle, right_handle, bottom, top;
|
|
|
|
|
/* Thumbnail coordinates in timeline space. */
|
|
|
|
|
float x1, x2, y1, y2;
|
|
|
|
|
/* Horizontal cropping of thumbnail image, in pixels. Often a thumbnail
|
|
|
|
|
* does not have to be cropped, in which case these are 0 and ibuf->x-1. */
|
|
|
|
|
float cropx_min, cropx_max;
|
|
|
|
|
bool is_muted;
|
|
|
|
|
};
|
|
|
|
|
|
2025-01-07 14:09:45 +01:00
|
|
|
static float thumb_calc_first_timeline_frame(const Strip *strip,
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
float left_handle,
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
float frame_step,
|
|
|
|
|
const rctf *view_area)
|
2021-10-06 04:16:50 +02:00
|
|
|
{
|
2025-01-07 14:09:45 +01:00
|
|
|
int first_drawable_frame = max_iii(left_handle, strip->start, view_area->xmin);
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
/* First frame should correspond to handle position. */
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
if (first_drawable_frame == left_handle) {
|
|
|
|
|
return left_handle;
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
}
|
2021-10-06 04:16:50 +02:00
|
|
|
|
2025-01-07 14:09:45 +01:00
|
|
|
float aligned_frame_offset = int((first_drawable_frame - strip->start) / frame_step) *
|
|
|
|
|
frame_step;
|
|
|
|
|
return strip->start + aligned_frame_offset;
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
2025-01-07 14:09:45 +01:00
|
|
|
static float thumb_calc_next_timeline_frame(const Strip *strip,
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
float left_handle,
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
float last_frame,
|
|
|
|
|
float frame_step)
|
2021-10-06 04:16:50 +02:00
|
|
|
{
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
float next_frame = last_frame + frame_step;
|
2021-10-06 04:16:50 +02:00
|
|
|
|
2025-01-07 14:09:45 +01:00
|
|
|
/* If handle position was displayed, align next frame with `strip->start`. */
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
if (last_frame == left_handle) {
|
2025-01-07 14:09:45 +01:00
|
|
|
next_frame = strip->start + (int((last_frame - strip->start) / frame_step) + 1) * frame_step;
|
2022-04-25 01:21:21 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
return next_frame;
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
2025-01-07 16:03:11 +01:00
|
|
|
static void strip_get_thumb_image_dimensions(const Strip *strip,
|
|
|
|
|
float pixelx,
|
|
|
|
|
float pixely,
|
|
|
|
|
float *r_thumb_width,
|
|
|
|
|
float thumb_height,
|
|
|
|
|
float *r_image_width,
|
|
|
|
|
float *r_image_height)
|
2021-10-06 04:16:50 +02:00
|
|
|
{
|
2025-01-07 14:09:45 +01:00
|
|
|
float image_width = strip->data->stripdata->orig_width;
|
|
|
|
|
float image_height = strip->data->stripdata->orig_height;
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
/* Fix the dimensions to be max SEQ_THUMB_SIZE for x or y. */
|
2023-06-14 18:36:17 +02:00
|
|
|
float aspect_ratio = image_width / image_height;
|
2021-10-06 04:16:50 +02:00
|
|
|
if (image_width > image_height) {
|
2025-03-06 13:04:39 +01:00
|
|
|
image_width = seq::THUMB_SIZE;
|
2021-10-06 04:16:50 +02:00
|
|
|
image_height = round_fl_to_int(image_width / aspect_ratio);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2025-03-06 13:04:39 +01:00
|
|
|
image_height = seq::THUMB_SIZE;
|
2021-10-06 04:16:50 +02:00
|
|
|
image_width = round_fl_to_int(image_height * aspect_ratio);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Calculate thumb dimensions. */
|
2023-06-14 18:36:17 +02:00
|
|
|
aspect_ratio = image_width / image_height;
|
2021-10-06 04:16:50 +02:00
|
|
|
float thumb_h_px = thumb_height / pixely;
|
|
|
|
|
float thumb_width = aspect_ratio * thumb_h_px * pixelx;
|
|
|
|
|
|
|
|
|
|
*r_thumb_width = thumb_width;
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
*r_image_width = image_width;
|
|
|
|
|
*r_image_height = image_height;
|
2024-06-04 20:05:35 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
static void get_seq_strip_thumbnails(const View2D *v2d,
|
|
|
|
|
const bContext *C,
|
|
|
|
|
Scene *scene,
|
|
|
|
|
const StripDrawContext &strip,
|
|
|
|
|
float pixelx,
|
|
|
|
|
float pixely,
|
|
|
|
|
bool is_muted,
|
|
|
|
|
Vector<SeqThumbInfo> &r_thumbs)
|
2024-06-04 20:05:35 +02:00
|
|
|
{
|
2025-01-07 14:09:45 +01:00
|
|
|
if (!seq::strip_can_have_thumbnail(scene, strip.strip)) {
|
2024-06-04 20:05:35 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
/* No thumbnails is height of the strip is too small. */
|
|
|
|
|
const float thumb_height = strip.strip_content_top - strip.bottom;
|
|
|
|
|
if (thumb_height / pixely <= 20 * UI_SCALE_FAC) {
|
2022-06-23 17:49:26 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-06-12 12:42:59 +02:00
|
|
|
float thumb_width, image_width, image_height;
|
2025-01-07 16:03:11 +01:00
|
|
|
strip_get_thumb_image_dimensions(
|
2025-01-07 14:09:45 +01:00
|
|
|
strip.strip, pixelx, pixely, &thumb_width, thumb_height, &image_width, &image_height);
|
2024-06-12 12:42:59 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
const float crop_x_multiplier = 1.0f / pixelx / (thumb_height / image_height / pixely);
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
float upper_thumb_bound = min_ff(strip.right_handle, strip.content_end);
|
2025-01-07 16:10:36 +01:00
|
|
|
if (strip.strip->type == STRIP_TYPE_IMAGE) {
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
upper_thumb_bound = strip.right_handle;
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
float timeline_frame = thumb_calc_first_timeline_frame(
|
2025-01-07 14:09:45 +01:00
|
|
|
strip.strip, strip.left_handle, thumb_width, &v2d->cur);
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
/* Start going over the strip length. */
|
2022-04-25 01:21:21 +02:00
|
|
|
while (timeline_frame < upper_thumb_bound) {
|
2024-04-24 12:37:38 +02:00
|
|
|
float thumb_x_end = timeline_frame + thumb_width;
|
2024-06-12 12:42:59 +02:00
|
|
|
bool clipped = false;
|
2021-10-06 04:16:50 +02:00
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
/* Reached end of view, no more thumbnails needed. */
|
2022-04-25 01:21:21 +02:00
|
|
|
if (timeline_frame > v2d->cur.xmax) {
|
2021-10-06 04:16:50 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */
|
2024-06-12 12:42:59 +02:00
|
|
|
float cut_off = 0.0f;
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
if (strip.left_handle > timeline_frame && strip.left_handle < thumb_x_end) {
|
|
|
|
|
cut_off = strip.left_handle - timeline_frame;
|
2021-10-06 04:16:50 +02:00
|
|
|
clipped = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Clip if full thumbnail cannot be displayed. */
|
2024-06-12 12:42:59 +02:00
|
|
|
if (thumb_x_end > upper_thumb_bound) {
|
2021-10-06 04:16:50 +02:00
|
|
|
thumb_x_end = upper_thumb_bound;
|
|
|
|
|
clipped = true;
|
|
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
float cropx_min = cut_off * crop_x_multiplier;
|
|
|
|
|
float cropx_max = (thumb_x_end - timeline_frame) * crop_x_multiplier;
|
|
|
|
|
if (cropx_max < 1.0f) {
|
2024-04-24 12:37:38 +02:00
|
|
|
break;
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster and more consistent thumbnails
Implementing part of design outlined in #126087.
- VSE thumbnail cache has a new implementation, hopefully simpler
and easier to understand.
- Instead of cache key being a VSE strip, frame index, plus
complicated logic for cache items linking etc.,
- The cache is keyed by media file path (if multiple strips
use the same input file, they will share cache entries), frame
index within media file, and any extra data (e.g. steam index
for multi-steam videos)
- Much reduced cache flickering and strange/weird thumbnail choices.
- Likewise, thumbnails no longer disappear-and-reload on operations
like Undo, dragging new video strip into timeline, or F12 render.
- Thumbnails now load faster.
- Images use dedicated/faster thumbnail loading routines when a
format can do that (e.g. JPG and EXR can).
- Movies reuse ffmpeg decoding context for neighboring strips
that use the same file (as often happens when cutting footage)
- Thumbnail requests are processed on several threads now too.
Images and more detail in PR.
Pull Request: https://projects.blender.org/blender/blender/pulls/126405
2024-08-29 08:27:12 +02:00
|
|
|
/* Get the thumbnail image. */
|
2025-01-07 14:09:45 +01:00
|
|
|
ImBuf *ibuf = seq::thumbnail_cache_get(C, scene, strip.strip, timeline_frame);
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
if (ibuf == nullptr) {
|
|
|
|
|
break;
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
SeqThumbInfo thumb = {};
|
|
|
|
|
thumb.ibuf = ibuf;
|
|
|
|
|
thumb.cropx_min = 0;
|
|
|
|
|
thumb.cropx_max = ibuf->x - 1;
|
|
|
|
|
if (clipped) {
|
|
|
|
|
thumb.cropx_min = clamp_f(cropx_min, 0, ibuf->x - 1);
|
|
|
|
|
thumb.cropx_max = clamp_f(cropx_max - 1 * 0, 0, ibuf->x - 1);
|
|
|
|
|
}
|
|
|
|
|
thumb.left_handle = strip.left_handle;
|
|
|
|
|
thumb.right_handle = strip.right_handle;
|
|
|
|
|
thumb.is_muted = is_muted;
|
|
|
|
|
thumb.bottom = strip.bottom;
|
|
|
|
|
thumb.top = strip.top;
|
|
|
|
|
thumb.x1 = timeline_frame + cut_off;
|
|
|
|
|
thumb.x2 = thumb_x_end;
|
|
|
|
|
thumb.y1 = strip.bottom;
|
|
|
|
|
thumb.y2 = strip.strip_content_top;
|
|
|
|
|
r_thumbs.append(thumb);
|
|
|
|
|
|
|
|
|
|
timeline_frame = thumb_calc_next_timeline_frame(
|
2025-01-07 14:09:45 +01:00
|
|
|
strip.strip, strip.left_handle, timeline_frame, thumb_width);
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ThumbsDrawBatch {
|
2025-03-06 06:22:14 +01:00
|
|
|
StripsDrawBatch &strips_batch_;
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
Array<SeqStripThumbData> thumbs_;
|
|
|
|
|
GPUUniformBuf *ubo_thumbs_ = nullptr;
|
|
|
|
|
GPUShader *shader_ = nullptr;
|
|
|
|
|
gpu::Batch *batch_ = nullptr;
|
|
|
|
|
GPUTexture *atlas_ = nullptr;
|
|
|
|
|
int binding_context_ = 0;
|
|
|
|
|
int binding_thumbs_ = 0;
|
|
|
|
|
int binding_image_ = 0;
|
|
|
|
|
int thumbs_count_ = 0;
|
|
|
|
|
|
2025-03-06 06:22:14 +01:00
|
|
|
ThumbsDrawBatch(StripsDrawBatch &strips_batch, GPUTexture *atlas)
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
: strips_batch_(strips_batch), thumbs_(GPU_SEQ_STRIP_DRAW_DATA_LEN), atlas_(atlas)
|
|
|
|
|
{
|
|
|
|
|
shader_ = GPU_shader_get_builtin_shader(GPU_SHADER_SEQUENCER_THUMBS);
|
|
|
|
|
binding_thumbs_ = GPU_shader_get_ubo_binding(shader_, "thumb_data");
|
|
|
|
|
binding_context_ = GPU_shader_get_ubo_binding(shader_, "context_data");
|
|
|
|
|
binding_image_ = GPU_shader_get_sampler_binding(shader_, "image");
|
|
|
|
|
|
|
|
|
|
ubo_thumbs_ = GPU_uniformbuf_create(sizeof(SeqStripThumbData) * GPU_SEQ_STRIP_DRAW_DATA_LEN);
|
|
|
|
|
|
|
|
|
|
batch_ = GPU_batch_preset_quad();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ThumbsDrawBatch()
|
|
|
|
|
{
|
|
|
|
|
flush_batch();
|
|
|
|
|
GPU_uniformbuf_unbind(ubo_thumbs_);
|
|
|
|
|
GPU_uniformbuf_free(ubo_thumbs_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void add_thumb(
|
|
|
|
|
const SeqThumbInfo &info, float width, const rcti &rect, int tex_width, int tex_height)
|
|
|
|
|
{
|
|
|
|
|
if (thumbs_count_ == GPU_SEQ_STRIP_DRAW_DATA_LEN) {
|
|
|
|
|
flush_batch();
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
SeqStripThumbData &res = thumbs_[thumbs_count_];
|
|
|
|
|
thumbs_count_++;
|
|
|
|
|
|
|
|
|
|
res.left = strips_batch_.pos_to_pixel_space_x(info.left_handle);
|
|
|
|
|
res.right = strips_batch_.pos_to_pixel_space_x(info.right_handle);
|
|
|
|
|
res.bottom = strips_batch_.pos_to_pixel_space_y(info.bottom);
|
|
|
|
|
res.top = strips_batch_.pos_to_pixel_space_y(info.top);
|
|
|
|
|
res.tint_color = float4(1.0f, 1.0f, 1.0f, info.is_muted ? 0.47f : 1.0f);
|
|
|
|
|
res.x1 = strips_batch_.pos_to_pixel_space_x(info.x1);
|
|
|
|
|
res.x2 = strips_batch_.pos_to_pixel_space_x(info.x2);
|
|
|
|
|
res.y1 = strips_batch_.pos_to_pixel_space_y(info.y1);
|
|
|
|
|
res.y2 = strips_batch_.pos_to_pixel_space_y(info.y2);
|
|
|
|
|
res.u1 = float(rect.xmin) / float(tex_width);
|
|
|
|
|
res.u2 = float(rect.xmin + width) / float(tex_width);
|
|
|
|
|
res.v1 = float(rect.ymin) / float(tex_height);
|
|
|
|
|
res.v2 = float(rect.ymax) / float(tex_height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void flush_batch()
|
|
|
|
|
{
|
|
|
|
|
if (thumbs_count_ == 0) {
|
|
|
|
|
return;
|
2024-06-04 20:05:35 +02:00
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
GPU_uniformbuf_update(ubo_thumbs_, thumbs_.data());
|
|
|
|
|
|
|
|
|
|
GPU_shader_bind(shader_);
|
|
|
|
|
GPU_uniformbuf_bind(ubo_thumbs_, binding_thumbs_);
|
|
|
|
|
GPU_uniformbuf_bind(strips_batch_.get_ubo_context(), binding_context_);
|
|
|
|
|
GPU_texture_bind(atlas_, binding_image_);
|
|
|
|
|
|
|
|
|
|
GPU_batch_set_shader(batch_, shader_);
|
|
|
|
|
GPU_batch_draw_instance_range(batch_, 0, thumbs_count_);
|
|
|
|
|
thumbs_count_ = 0;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void draw_strip_thumbnails(TimelineDrawContext *ctx,
|
2025-03-06 06:22:14 +01:00
|
|
|
StripsDrawBatch &strips_batch,
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
const Vector<StripDrawContext> &strips)
|
|
|
|
|
{
|
|
|
|
|
/* Nothing to do if we're not showing thumbnails overall. */
|
|
|
|
|
if ((ctx->sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
|
|
|
|
(ctx->sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_THUMBNAILS) == 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Gather information for all thumbnails. */
|
|
|
|
|
Vector<SeqThumbInfo> thumbs;
|
|
|
|
|
for (const StripDrawContext &strip : strips) {
|
|
|
|
|
get_seq_strip_thumbnails(
|
2024-09-24 11:40:35 +02:00
|
|
|
ctx->v2d, ctx->C, ctx->scene, strip, ctx->pixelx, ctx->pixely, strip.is_muted, thumbs);
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
}
|
|
|
|
|
if (thumbs.is_empty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ColorManagedViewSettings *view_settings;
|
|
|
|
|
ColorManagedDisplaySettings *display_settings;
|
|
|
|
|
IMB_colormanagement_display_settings_from_ctx(ctx->C, &view_settings, &display_settings);
|
|
|
|
|
|
|
|
|
|
/* Arrange thumbnail images into a texture atlas, using a simple
|
|
|
|
|
* "add to current row until end, then start a new row". Thumbnail
|
|
|
|
|
* images are most often same height (but varying width due to horizontal
|
|
|
|
|
* cropping), so this simple algorithm works well enough. */
|
|
|
|
|
constexpr int ATLAS_WIDTH = 4096;
|
|
|
|
|
constexpr int ATLAS_MAX_HEIGHT = 4096;
|
|
|
|
|
int cur_row_x = 0;
|
|
|
|
|
int cur_row_y = 0;
|
|
|
|
|
int cur_row_height = 0;
|
|
|
|
|
Vector<rcti> rects;
|
|
|
|
|
rects.reserve(thumbs.size());
|
|
|
|
|
for (const SeqThumbInfo &info : thumbs) {
|
|
|
|
|
int cropx_min = int(info.cropx_min);
|
|
|
|
|
int cropx_max = int(math::ceil(info.cropx_max));
|
|
|
|
|
int width = cropx_max - cropx_min + 1;
|
|
|
|
|
int height = info.ibuf->y;
|
|
|
|
|
cur_row_height = math::max(cur_row_height, height);
|
|
|
|
|
|
|
|
|
|
/* If this thumb would not fit onto current row, start a new row. */
|
|
|
|
|
if (cur_row_x + width > ATLAS_WIDTH) {
|
|
|
|
|
cur_row_y += cur_row_height + 1; /* +1 empty pixel for bilinear filter. */
|
|
|
|
|
cur_row_height = height;
|
|
|
|
|
cur_row_x = 0;
|
|
|
|
|
if (cur_row_y > ATLAS_MAX_HEIGHT) {
|
|
|
|
|
break;
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
/* Record our rect. */
|
|
|
|
|
rcti rect{cur_row_x, cur_row_x + width, cur_row_y, cur_row_y + height};
|
|
|
|
|
rects.append(rect);
|
|
|
|
|
|
|
|
|
|
/* Advance to next item inside row. */
|
|
|
|
|
cur_row_x += width + 1; /* +1 empty pixel for bilinear filter. */
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
VSE: Faster timeline thumbnail drawing
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
2024-09-03 08:25:15 +02:00
|
|
|
|
|
|
|
|
/* Create the atlas GPU texture. */
|
|
|
|
|
const int tex_width = ATLAS_WIDTH;
|
|
|
|
|
const int tex_height = cur_row_y + cur_row_height;
|
|
|
|
|
Array<uchar> tex_data(tex_width * tex_height * 4, 0);
|
|
|
|
|
for (int64_t i = 0; i < rects.size(); i++) {
|
|
|
|
|
/* Copy one thumbnail into atlas. */
|
|
|
|
|
const rcti &rect = rects[i];
|
|
|
|
|
SeqThumbInfo &info = thumbs[i];
|
|
|
|
|
|
|
|
|
|
void *cache_handle = nullptr;
|
|
|
|
|
uchar *display_buffer = IMB_display_buffer_acquire(
|
|
|
|
|
info.ibuf, view_settings, display_settings, &cache_handle);
|
|
|
|
|
if (display_buffer != nullptr && info.ibuf != nullptr) {
|
|
|
|
|
int cropx_min = int(info.cropx_min);
|
|
|
|
|
int cropx_max = int(math::ceil(info.cropx_max));
|
|
|
|
|
int width = cropx_max - cropx_min + 1;
|
|
|
|
|
int height = info.ibuf->y;
|
|
|
|
|
const uchar *src = display_buffer + cropx_min * 4;
|
|
|
|
|
uchar *dst = &tex_data[(rect.ymin * ATLAS_WIDTH + rect.xmin) * 4];
|
|
|
|
|
for (int y = 0; y < height; y++) {
|
|
|
|
|
memcpy(dst, src, width * 4);
|
|
|
|
|
src += info.ibuf->x * 4;
|
|
|
|
|
dst += ATLAS_WIDTH * 4;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
IMB_display_buffer_release(cache_handle);
|
|
|
|
|
|
|
|
|
|
/* Release thumb image reference. */
|
|
|
|
|
IMB_freeImBuf(info.ibuf);
|
|
|
|
|
info.ibuf = nullptr;
|
|
|
|
|
}
|
|
|
|
|
GPUTexture *atlas = GPU_texture_create_2d(
|
|
|
|
|
"thumb_atlas", tex_width, tex_height, 1, GPU_RGBA8, GPU_TEXTURE_USAGE_SHADER_READ, nullptr);
|
|
|
|
|
GPU_texture_update(atlas, GPU_DATA_UBYTE, tex_data.data());
|
|
|
|
|
GPU_texture_filter_mode(atlas, true);
|
|
|
|
|
GPU_texture_extend_mode(atlas, GPU_SAMPLER_EXTEND_MODE_CLAMP_TO_BORDER);
|
|
|
|
|
|
|
|
|
|
/* Draw all thumbnails. */
|
|
|
|
|
GPU_matrix_push_projection();
|
|
|
|
|
wmOrtho2_region_pixelspace(ctx->region);
|
|
|
|
|
|
|
|
|
|
ThumbsDrawBatch batch(strips_batch, atlas);
|
|
|
|
|
for (int64_t i = 0; i < rects.size(); i++) {
|
|
|
|
|
const rcti &rect = rects[i];
|
|
|
|
|
const SeqThumbInfo &info = thumbs[i];
|
|
|
|
|
batch.add_thumb(info, info.cropx_max - info.cropx_min + 1, rect, tex_width, tex_height);
|
|
|
|
|
}
|
|
|
|
|
batch.flush_batch();
|
|
|
|
|
|
|
|
|
|
GPU_matrix_pop_projection();
|
|
|
|
|
|
|
|
|
|
GPU_texture_unbind(atlas);
|
|
|
|
|
GPU_texture_free(atlas);
|
2021-10-06 04:16:50 +02:00
|
|
|
}
|
2025-03-06 06:22:14 +01:00
|
|
|
|
|
|
|
|
} // namespace blender::ed::vse
|