Blender V4.5
sequencer_preview_draw.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cmath>
11#include <cstring>
12
13#include "BLF_api.hh"
14
15#include "BLI_index_range.hh"
16#include "BLI_math_matrix.hh"
18#include "BLI_math_rotation.h"
20#include "BLI_rect.h"
21#include "BLI_string.h"
22#include "BLI_utildefines.h"
23#include "BLI_vector.hh"
24
25#include "DNA_scene_types.h"
26#include "DNA_screen_types.h"
27#include "DNA_sequence_types.h"
28#include "DNA_space_types.h"
29#include "DNA_view2d_types.h"
30
31#include "BKE_context.hh"
32#include "BKE_global.hh"
33#include "BKE_scene.hh"
34#include "BKE_screen.hh"
35
37#include "IMB_imbuf.hh"
38#include "IMB_imbuf_types.hh"
39
40#include "GPU_framebuffer.hh"
41#include "GPU_immediate.hh"
42#include "GPU_immediate_util.hh"
43#include "GPU_matrix.hh"
44#include "GPU_primitive.hh"
45#include "GPU_state.hh"
46#include "GPU_viewport.hh"
47
48#include "ED_gpencil_legacy.hh"
49#include "ED_screen.hh"
50#include "ED_sequencer.hh"
51#include "ED_space_api.hh"
52#include "ED_util.hh"
53#include "ED_view3d.hh"
54
55#include "BIF_glutil.hh"
56
57#include "SEQ_channels.hh"
58#include "SEQ_effects.hh"
59#include "SEQ_iterator.hh"
60#include "SEQ_prefetch.hh"
61#include "SEQ_proxy.hh"
62#include "SEQ_render.hh"
63#include "SEQ_select.hh"
64#include "SEQ_sequencer.hh"
65#include "SEQ_time.hh"
66#include "SEQ_transform.hh"
67
68#include "UI_interface.hh"
69#include "UI_resources.hh"
70#include "UI_view2d.hh"
71
72#include "WM_api.hh"
73#include "WM_types.hh"
74
75#include "sequencer_intern.hh"
77#include "sequencer_scopes.hh"
78
79namespace blender::ed::vse {
80static Strip *special_seq_update = nullptr;
81
83{
84 special_seq_update = strip;
85}
86
91
92void special_preview_set(bContext *C, const int mval[2])
93{
94 Scene *scene = CTX_data_scene(C);
95 ARegion *region = CTX_wm_region(C);
96 Strip *strip = strip_under_mouse_get(scene, &region->v2d, mval);
97 if (strip != nullptr && strip->type != STRIP_TYPE_SOUND_RAM) {
99 }
100}
101
106
107ImBuf *sequencer_ibuf_get(const bContext *C, const int timeline_frame, const char *viewname)
108{
109 Main *bmain = CTX_data_main(C);
110 ARegion *region = CTX_wm_region(C);
112 Scene *scene = CTX_data_scene(C);
113 SpaceSeq *sseq = CTX_wm_space_seq(C);
114 bScreen *screen = CTX_wm_screen(C);
115
116 seq::RenderData context = {nullptr};
117 ImBuf *ibuf;
118 int rectx, recty;
119 double render_size;
120 short is_break = G.is_break;
121
122 if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
123 return nullptr;
124 }
125
126 if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
127 render_size = scene->r.size / 100.0;
128 }
129 else {
130 render_size = seq::rendersize_to_scale_factor(sseq->render_size);
131 }
132
133 rectx = roundf(render_size * scene->r.xsch);
134 recty = roundf(render_size * scene->r.ysch);
135
137 bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
138 context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
139 context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
140 context.is_playing = screen->animtimer != nullptr;
141 context.is_scrubbing = screen->scrubbing;
142
143 /* Sequencer could start rendering, in this case we need to be sure it wouldn't be
144 * canceled by Escape pressed somewhere in the past. */
145 G.is_break = false;
146
148 GPUFrameBuffer *fb = GPU_framebuffer_active_get();
149 if (viewport) {
150 /* Unbind viewport to release the DRW context. */
151 GPU_viewport_unbind(viewport);
152 }
153 else {
154 /* Rendering can change OGL context. Save & Restore frame-buffer. */
156 }
157
158 if (special_preview_get()) {
159 ibuf = seq::render_give_ibuf_direct(&context, timeline_frame, special_preview_get());
160 }
161 else {
162 ibuf = seq::render_give_ibuf(&context, timeline_frame, sseq->chanshown);
163 }
164
165 if (viewport) {
166 /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
167 * viewport. */
168 int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
169 GPU_viewport_bind(viewport, view, &region->winrct);
170 }
171 else if (fb) {
173 }
174
175 /* Restore state so real rendering would be canceled if needed. */
176 G.is_break = is_break;
177
178 return ibuf;
179}
180
182 const ColorManagedDisplaySettings &display_settings,
183 const ImBuf &ibuf,
184 ImBuf *(*make_scope_fn)(const ImBuf *ibuf))
185{
186 ImBuf *display_ibuf = IMB_dupImBuf(&ibuf);
187 ImBuf *scope;
188
189 IMB_colormanagement_imbuf_make_display_space(display_ibuf, &view_settings, &display_settings);
190
191 scope = make_scope_fn(display_ibuf);
192
193 IMB_freeImBuf(display_ibuf);
194
195 return scope;
196}
197
198static void sequencer_display_size(const RenderData &render_data, float r_viewrect[2])
199{
200 r_viewrect[0] = float(render_data.xsch);
201 r_viewrect[1] = float(render_data.ysch);
202
203 r_viewrect[0] *= render_data.xasp / render_data.yasp;
204}
205
207{
208 /* Draw grease-pencil (image aligned). */
210
211 /* Orthographic at pixel level. */
213
214 /* Draw grease-pencil (screen aligned). */
216}
217
222 const View2D &v2d,
223 const Scene *scene)
224{
225 const float x1 = v2d.tot.xmin;
226 const float y1 = v2d.tot.ymin;
227 const float x2 = v2d.tot.xmax;
228 const float y2 = v2d.tot.ymax;
229
230 GPU_line_width(1.0f);
231
232 /* Draw border. */
233 const uint shdr_pos = GPU_vertformat_attr_add(
235
237
238 float viewport_size[4];
239 GPU_viewport_size_get_f(viewport_size);
240 immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
241
243 immUniform1i("colors_len", 0); /* Simple dashes. */
244 immUniform1f("dash_width", 6.0f);
245 immUniform1f("udash_factor", 0.5f);
246
247 imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
248
249 /* Draw safety border. */
252 rctf rect;
253 rect.xmin = x1;
254 rect.xmax = x2;
255 rect.ymin = y1;
256 rect.ymax = y2;
257 UI_draw_safe_areas(shdr_pos, &rect, scene->safe_areas.title, scene->safe_areas.action);
258
260
262 shdr_pos, &rect, scene->safe_areas.title_center, scene->safe_areas.action_center);
263 }
264 }
265
267}
268
269#if 0
270void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
271{
272 /* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
273 * For now just disable drawing since the strip frame will likely be offset. */
274
275 // if (sc->mode == SC_MODE_MASKEDIT)
276 if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
277 Mask *mask = SEQ_active_mask_get(scene);
278
279 if (mask) {
280 int width, height;
281 float aspx = 1.0f, aspy = 1.0f;
282 // ED_mask_get_size(C, &width, &height);
283
284 // Scene *scene = CTX_data_scene(C);
285 BKE_render_resolution(&scene->r, false, &width, &height);
286
288 region,
289 0,
290 0,
291 0, /* TODO */
292 width,
293 height,
294 aspx,
295 aspy,
296 false,
297 true,
298 nullptr,
299 C);
300 }
301 }
302}
303#endif
304
305/* Force redraw, when prefetching and using cache view. */
306static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
307{
308 if (seq::prefetch_need_redraw(C, scene)) {
310 }
311}
312
313static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
314{
315 if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
316 /* Stop all running jobs, except screen one. Currently previews frustrate Render.
317 * Need to make so sequencers rendering doesn't conflict with compositor. */
319
320 /* In case of final rendering used for preview, kill all previews,
321 * otherwise threading conflict will happen in rendering module. */
323 }
324}
325
330
331/* Semantic utility to get a rectangle with positions that correspond to a full frame drawn in the
332 * preview region. */
334{
335 return region.v2d.tot;
336}
337
338/* Semantic utility to generate rectangle with UV coordinates that cover an entire 0 .. 1
339 * rectangle. */
341{
342 rctf texture_coord;
343 BLI_rctf_init(&texture_coord, 0.0f, 1.0f, 0.0f, 1.0f);
344 return texture_coord;
345}
346
347/* Get rectangle positions within preview region that are to be used to draw reference frame.
348 *
349 * If the frame overlay is set to RECTANGLE this function returns coordinates of the rectangle
350 * where partial reference frame is to be drawn.
351 *
352 * If the frame overlay is set to REFERENCE this function returns full-frame rectangle, same as
353 * preview_get_full_position().
354 *
355 * If the frame overlay is set to REFERENCE or is disabled the return value is valid but
356 * corresponds to an undefined state.
357 */
358static rctf preview_get_reference_position(const SpaceSeq &space_sequencer,
359 const Editing &editing,
360 const ARegion &region)
361{
362 const View2D &v2d = region.v2d;
363
364 BLI_assert(ELEM(space_sequencer.overlay_frame_type,
367
368 if (space_sequencer.overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT) {
369 rctf position;
370 const float xmin = v2d.tot.xmin;
371 const float ymin = v2d.tot.ymin;
372
373 const float width = BLI_rctf_size_x(&v2d.tot);
374 const float height = BLI_rctf_size_y(&v2d.tot);
375
376 position.xmax = xmin + width * editing.overlay_frame_rect.xmax;
377 position.xmin = xmin + width * editing.overlay_frame_rect.xmin;
378 position.ymax = ymin + height * editing.overlay_frame_rect.ymax;
379 position.ymin = ymin + height * editing.overlay_frame_rect.ymin;
380
381 return position;
382 }
383
384 return v2d.tot;
385}
386
387/* Return rectangle with UV coordinates that are to be used to draw reference frame.
388 *
389 * If the frame overlay is set to rectangle the return value contains vUV coordinates of the
390 * rectangle within the reference frame.
391 *
392 * If the frame overlay is set to REFERENCE this function returns full-frame UV rectangle, same as
393 * preview_get_full_texture_coord().
394 *
395 * If the frame overlay is set to REFERENCE or is disabled the return value is valid but
396 * corresponds to an undefined state.
397 */
399 const Editing &editing)
400{
401 if (space_sequencer.overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT) {
402 return editing.overlay_frame_rect;
403 }
404
405 rctf texture_coord;
406 BLI_rctf_init(&texture_coord, 0.0f, 1.0f, 0.0f, 1.0f);
407
408 return texture_coord;
409}
410
411static void draw_histogram(ARegion &region,
412 const ScopeHistogram &hist,
413 SeqQuadsBatch &quads,
414 const rctf &area)
415{
416 if (hist.data.is_empty()) {
417 return;
418 }
419
420 /* Grid lines and labels. */
421 uchar col_grid[4] = {128, 128, 128, 128};
422 float grid_x_0 = area.xmin;
423 float grid_x_1 = area.xmax;
424 /* Float histograms show more than 0..1 range horizontally. */
425 if (hist.is_float_hist()) {
428 grid_x_0 = area.xmin + (area.xmax - area.xmin) * ratio_0;
429 grid_x_1 = area.xmin + (area.xmax - area.xmin) * ratio_1;
430 }
431
432 View2D &v2d = region.v2d;
433 float text_scale_x, text_scale_y;
434 UI_view2d_scale_get_inverse(&v2d, &text_scale_x, &text_scale_y);
435
436 for (int line = 0; line <= 4; line++) {
437 float val = float(line) / 4;
438 float x = grid_x_0 + (grid_x_1 - grid_x_0) * val;
439 quads.add_line(x, area.ymin, x, area.ymax, col_grid);
440
441 /* Label. */
442 char buf[10];
443 const size_t buf_len = SNPRINTF_RLEN(buf, "%.2f", val);
444
445 float text_width, text_height;
446 BLF_width_and_height(BLF_default(), buf, buf_len, &text_width, &text_height);
447 text_width *= text_scale_x;
448 text_height *= text_scale_y;
450 &v2d, x - text_width / 2, area.ymax - text_height * 1.3f, buf, buf_len, col_grid);
451 }
452
453 /* Border. */
454 uchar col_border[4] = {64, 64, 64, 128};
455 quads.add_wire_quad(area.xmin, area.ymin, area.xmax, area.ymax, col_border);
456
457 /* Histogram area & line for each R/G/B channels, additively blended. */
458 quads.draw();
460 for (int ch = 0; ch < 3; ++ch) {
461 if (hist.max_value[ch] == 0) {
462 continue;
463 }
464 uchar col_line[4] = {32, 32, 32, 255};
465 uchar col_area[4] = {64, 64, 64, 128};
466 col_line[ch] = 224;
467 col_area[ch] = 224;
468 float y_scale = (area.ymax - area.ymin) / hist.max_value[ch] * 0.95f;
469 float x_scale = (area.xmax - area.xmin) / hist.data.size();
470 float yb = area.ymin;
471 for (int bin = 0; bin < hist.data.size() - 1; bin++) {
472 float x0 = area.xmin + (bin + 0.5f) * x_scale;
473 float x1 = area.xmin + (bin + 1.5f) * x_scale;
474
475 float y0 = area.ymin + hist.data[bin][ch] * y_scale;
476 float y1 = area.ymin + hist.data[bin + 1][ch] * y_scale;
477 quads.add_quad(x0, yb, x0, y0, x1, yb, x1, y1, col_area);
478 quads.add_line(x0, y0, x1, y1, col_line);
479 }
480 }
481 quads.draw();
483
485}
486
488{
489 float y, u, v;
490 rgb_to_yuv(rgb.x, rgb.y, rgb.z, &y, &u, &v, BLI_YUV_ITU_BT709);
491 /* Scale to +-0.5 range. */
494 return blender::float2(u, v);
495}
496
497static void draw_waveform_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
498{
499 /* Horizontal lines at 10%, 70%, 90%. */
500 const float lines[3] = {0.1f, 0.7f, 0.9f};
501 uchar col_grid[4] = {160, 64, 64, 128};
502 const float x0 = area.xmin;
503 const float x1 = area.xmax;
504
505 for (int i = 0; i < 3; i++) {
506 const float y = area.ymin + (area.ymax - area.ymin) * lines[i];
507 char buf[10];
508 SNPRINTF(buf, "%.1f", lines[i]);
509 quads.add_line(x0, y, x1, y, col_grid);
510 UI_view2d_text_cache_add(&region->v2d, x0 + 8, y + 8, buf, strlen(buf), col_grid);
511 }
512 /* Border. */
513 uchar col_border[4] = {64, 64, 64, 128};
514 quads.add_wire_quad(x0, area.ymin, x1, area.ymax, col_border);
515
516 quads.draw();
518}
519
520static void draw_vectorscope_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
521{
522 const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
523
524 const float w = BLI_rctf_size_x(&area);
525 const float h = BLI_rctf_size_y(&area);
526 const float2 center{BLI_rctf_cent_x(&area), BLI_rctf_cent_y(&area)};
527 const float radius = ((w < h) ? w : h) * 0.5f;
528
529 /* Precalculate circle points/colors. */
530 constexpr int circle_delta = 6;
531 constexpr int num_circle_points = 360 / circle_delta;
532 float2 circle_pos[num_circle_points];
533 float3 circle_col[num_circle_points];
534 for (int i = 0; i < num_circle_points; i++) {
535 float a = DEG2RADF(i * circle_delta);
536 float x = cosf(a);
537 float y = sinf(a);
538 circle_pos[i] = float2(x, y);
539 float u = x / SeqScopes::VECSCOPE_U_SCALE;
541
542 float3 col;
543 yuv_to_rgb(0.5f, u, v, &col.x, &col.y, &col.z, BLI_YUV_ITU_BT709);
544 circle_col[i] = col;
545 }
546
547 /* Draw colored background and outer ring, additively blended
548 * since vectorscope image is already drawn. */
550
551 constexpr float alpha_f = 0.8f;
552 constexpr uchar alpha_b = uchar(alpha_f * 255.0f);
553 const uchar4 col_center(50, 50, 50, alpha_b);
554
555 uchar4 col1(0, 0, 0, alpha_b);
556 uchar4 col2(0, 0, 0, alpha_b);
557 uchar4 col3(0, 0, 0, alpha_b);
558
559 /* Background: since the quads batch utility draws quads, draw two
560 * segments of the circle (two triangles) in one iteration. */
561 constexpr float mul_background = 0.2f;
562 for (int i = 0; i < num_circle_points; i += 2) {
563 int idx1 = i;
564 int idx2 = (i + 1) % num_circle_points;
565 int idx3 = (i + 2) % num_circle_points;
566 float2 pt1 = center + circle_pos[idx1] * radius;
567 float2 pt2 = center + circle_pos[idx2] * radius;
568 float2 pt3 = center + circle_pos[idx3] * radius;
569 float3 rgb1 = circle_col[idx1] * mul_background;
570 float3 rgb2 = circle_col[idx2] * mul_background;
571 float3 rgb3 = circle_col[idx3] * mul_background;
572 rgb_float_to_uchar(col1, rgb1);
573 rgb_float_to_uchar(col2, rgb2);
574 rgb_float_to_uchar(col3, rgb3);
575 quads.add_quad(pt1.x,
576 pt1.y,
577 pt2.x,
578 pt2.y,
579 center.x,
580 center.y,
581 pt3.x,
582 pt3.y,
583 col1,
584 col2,
585 col_center,
586 col3);
587 }
588
589 /* Outer ring. */
590 const float outer_radius = radius * 1.02f;
591 for (int i = 0; i < num_circle_points; i++) {
592 int idx1 = i;
593 int idx2 = (i + 1) % num_circle_points;
594 float2 pt1a = center + circle_pos[idx1] * radius;
595 float2 pt2a = center + circle_pos[idx2] * radius;
596 float2 pt1b = center + circle_pos[idx1] * outer_radius;
597 float2 pt2b = center + circle_pos[idx2] * outer_radius;
598 float3 rgb1 = circle_col[idx1];
599 float3 rgb2 = circle_col[idx2];
600 rgb_float_to_uchar(col1, rgb1);
601 rgb_float_to_uchar(col2, rgb2);
602 quads.add_quad(
603 pt1a.x, pt1a.y, pt1b.x, pt1b.y, pt2a.x, pt2a.y, pt2b.x, pt2b.y, col1, col1, col2, col2);
604 }
605
606 quads.draw();
607
608 /* Draw grid and other labels using regular alpha blending. */
610 const uchar4 col_grid(128, 128, 128, 128);
611
612 /* Cross. */
613 quads.add_line(center.x - radius, center.y, center.x + radius, center.y, col_grid);
614 quads.add_line(center.x, center.y - radius, center.x, center.y + radius, col_grid);
615
616 /* Inner circles. */
617 for (int j = 1; j < 5; j++) {
618 float r = radius * j * 0.2f;
619 for (int i = 0; i < num_circle_points; i++) {
620 int idx1 = i;
621 int idx2 = (i + 1) % num_circle_points;
622 float2 pt1 = center + circle_pos[idx1] * r;
623 float2 pt2 = center + circle_pos[idx2] * r;
624 quads.add_line(pt1.x, pt1.y, pt2.x, pt2.y, col_grid);
625 }
626 }
627
628 /* "Safe" (0.75 saturation) primary color locations and labels. */
629 const float3 primaries[6] = {
630 {1, 0, 0},
631 {1, 1, 0},
632 {0, 1, 0},
633 {0, 1, 1},
634 {0, 0, 1},
635 {1, 0, 1},
636 };
637 const char *names = "RYGCBM";
638
639 /* Calculate size of single text letter. */
640 char buf[2] = {'M', 0};
641 float text_scale_x, text_scale_y;
642 UI_view2d_scale_get_inverse(&region->v2d, &text_scale_x, &text_scale_y);
643 float text_width, text_height;
644 BLF_width_and_height(BLF_default(), buf, 1, &text_width, &text_height);
645 text_width *= text_scale_x;
646 text_height *= text_scale_y;
647
648 const uchar4 col_target(128, 128, 128, 192);
649 const float delta = radius * 0.01f;
650 for (int i = 0; i < 6; i++) {
651 float3 safe = primaries[i] * 0.75f;
652 float2 pos = center + rgb_to_uv_scaled(safe) * (radius * 2);
653 quads.add_wire_quad(pos.x - delta, pos.y - delta, pos.x + delta, pos.y + delta, col_target);
654
655 buf[0] = names[i];
657 pos.x + delta * 1.2f + text_width / 4,
658 pos.y - text_height / 2,
659 buf,
660 1,
661 col_target);
662 }
663
664 /* Skin tone line. */
665 const uchar4 col_tone(255, 102, 0, 128);
666 quads.add_line(center.x,
667 center.y,
668 center.x + cosf(skin_rad) * radius,
669 center.y + sinf(skin_rad) * radius,
670 col_tone);
671
672 quads.draw();
674}
675
676static void sequencer_draw_scopes(const SpaceSeq &space_sequencer, ARegion &region)
677{
678 /* Figure out draw coordinates. */
679 const rctf preview = preview_get_full_position(region);
680
681 rctf uv;
682 BLI_rctf_init(&uv, 0.0f, 1.0f, 0.0f, 1.0f);
683 const bool keep_aspect = space_sequencer.mainb == SEQ_DRAW_IMG_VECTORSCOPE;
684 float vecscope_aspect = 1.0f;
685 if (keep_aspect) {
686 float width = std::max(BLI_rctf_size_x(&preview), 0.1f);
687 float height = std::max(BLI_rctf_size_y(&preview), 0.1f);
688 vecscope_aspect = width / height;
689 if (vecscope_aspect >= 1.0f) {
690 BLI_rctf_resize_x(&uv, vecscope_aspect);
691 }
692 else {
693 BLI_rctf_resize_y(&uv, 1.0f / vecscope_aspect);
694 }
695 }
696
697 SeqQuadsBatch quads;
698 const SeqScopes *scopes = &space_sequencer.runtime->scopes;
699
700 bool use_blend = space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF &&
701 space_sequencer.flag & SEQ_USE_ALPHA;
702
703 /* Draw black rectangle over scopes area. */
704 if (space_sequencer.mainb != SEQ_DRAW_IMG_IMBUF) {
707 uchar black[4] = {0, 0, 0, 255};
709 immUniformColor4ubv(black);
710 immRectf(pos, preview.xmin, preview.ymin, preview.xmax, preview.ymax);
712 }
713
714 /* Draw scope image if there is one. */
715 ImBuf *scope_image = nullptr;
716 if (space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF) {
717 scope_image = scopes->zebra_ibuf;
718 }
719 else if (space_sequencer.mainb == SEQ_DRAW_IMG_WAVEFORM) {
720 scope_image = scopes->waveform_ibuf;
721 }
722 else if (space_sequencer.mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
723 scope_image = scopes->vector_ibuf;
724 }
725 else if (space_sequencer.mainb == SEQ_DRAW_IMG_RGBPARADE) {
726 scope_image = scopes->sep_waveform_ibuf;
727 }
728
729 if (use_blend) {
731 }
732
733 if (scope_image != nullptr) {
734 if (scope_image->float_buffer.data && scope_image->byte_buffer.data == nullptr) {
735 IMB_byte_from_float(scope_image);
736 }
737
741 GPUTexture *texture = GPU_texture_create_2d(
742 "seq_display_buf", scope_image->x, scope_image->y, 1, format, usage, nullptr);
746
748
749 GPUVertFormat *imm_format = immVertexFormat();
751 uint texCoord = GPU_vertformat_attr_add(
752 imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
754 immUniformColor3f(1.0f, 1.0f, 1.0f);
755
757
758 immAttr2f(texCoord, uv.xmin, uv.ymin);
759 immVertex2f(pos, preview.xmin, preview.ymin);
760
761 immAttr2f(texCoord, uv.xmin, uv.ymax);
762 immVertex2f(pos, preview.xmin, preview.ymax);
763
764 immAttr2f(texCoord, uv.xmax, uv.ymax);
765 immVertex2f(pos, preview.xmax, preview.ymax);
766
767 immAttr2f(texCoord, uv.xmax, uv.ymin);
768 immVertex2f(pos, preview.xmax, preview.ymin);
769
770 immEnd();
771
774
776 }
777
778 if (space_sequencer.mainb == SEQ_DRAW_IMG_HISTOGRAM) {
779 draw_histogram(region, scopes->histogram, quads, preview);
780 }
782 use_blend = true;
783 draw_waveform_graticule(&region, quads, preview);
784 }
785 if (space_sequencer.mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
786 use_blend = true;
787 draw_vectorscope_graticule(&region, quads, preview);
788 }
789
790 quads.draw();
791
792 if (use_blend) {
794 }
795}
796
797static bool sequencer_calc_scopes(const SpaceSeq &space_sequencer,
798 const ColorManagedViewSettings &view_settings,
799 const ColorManagedDisplaySettings &display_settings,
800 const ImBuf &ibuf,
801 const int timeline_frame)
802
803{
804 if (space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF && space_sequencer.zebra == 0) {
805 return false; /* Not drawing any scopes. */
806 }
807
808 SeqScopes *scopes = &space_sequencer.runtime->scopes;
809 if (scopes->reference_ibuf != &ibuf || scopes->timeline_frame != timeline_frame) {
810 scopes->cleanup();
811 }
812
813 switch (space_sequencer.mainb) {
815 if (!scopes->zebra_ibuf) {
816 if (ibuf.float_buffer.data) {
817 ImBuf *display_ibuf = IMB_dupImBuf(&ibuf);
819 display_ibuf, &view_settings, &display_settings);
820 scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, space_sequencer.zebra);
821 IMB_freeImBuf(display_ibuf);
822 }
823 else {
824 scopes->zebra_ibuf = make_zebra_view_from_ibuf(&ibuf, space_sequencer.zebra);
825 }
826 }
827 break;
829 if (!scopes->waveform_ibuf) {
831 view_settings, display_settings, ibuf, make_waveform_view_from_ibuf);
832 }
833 break;
835 if (!scopes->vector_ibuf) {
837 view_settings, display_settings, ibuf, make_vectorscope_view_from_ibuf);
838 }
839 break;
841 ImBuf *display_ibuf = IMB_dupImBuf(&ibuf);
843 display_ibuf, &view_settings, &display_settings);
844 scopes->histogram.calc_from_ibuf(display_ibuf);
845 IMB_freeImBuf(display_ibuf);
846 } break;
848 if (!scopes->sep_waveform_ibuf) {
850 view_settings, display_settings, ibuf, make_sep_waveform_view_from_ibuf);
851 }
852 break;
853 default: /* Future files might have scopes we don't know about. */
854 return false;
855 }
856 scopes->reference_ibuf = &ibuf;
857 return true;
858}
859
860static bool sequencer_draw_get_transform_preview(const SpaceSeq &sseq, const Scene &scene)
861{
862 Strip *last_seq = seq::select_active_get(&scene);
863 if (last_seq == nullptr) {
864 return false;
865 }
866
867 return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
868 ((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
870}
871
873{
874 Strip *last_seq = seq::select_active_get(scene);
875 /* #sequencer_draw_get_transform_preview must already have been called. */
876 BLI_assert(last_seq != nullptr);
877 int preview_frame;
878
879 if (last_seq->flag & SEQ_RIGHTSEL) {
880 preview_frame = seq::time_right_handle_frame_get(scene, last_seq) - 1;
881 }
882 else {
883 preview_frame = seq::time_left_handle_frame_get(scene, last_seq);
884 }
885
886 return preview_frame;
887}
888
890 Strip *strip,
891 bool is_active_seq)
892{
893 SpaceSeq *sseq = CTX_wm_space_seq(C);
894 const ARegion *region = CTX_wm_region(C);
896 return;
897 }
898 if ((strip->flag & SELECT) == 0) {
899 return;
900 }
902 return;
903 }
904 if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
906 {
907 return;
908 }
909 if (ELEM(sseq->mainb,
914 {
915 return;
916 }
917
919 CTX_data_scene(C), strip);
920
921 /* Origin. */
925 immUniform1f("outlineWidth", 1.5f);
926 immUniformColor3f(1.0f, 1.0f, 1.0f);
927 immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
928 immUniform1f("size", 15.0f * U.pixelsize);
930 immVertex2f(pos, origin[0], origin[1]);
931 immEnd();
933
934 /* Outline. */
936 CTX_data_scene(C), strip);
937
938 GPU_line_smooth(true);
942
943 float col[3];
944 if (is_active_seq) {
946 }
947 else {
949 }
951 immUniform1f("lineWidth", U.pixelsize);
953 immVertex2f(pos, strip_image_quad[0].x, strip_image_quad[0].y);
954 immVertex2f(pos, strip_image_quad[1].x, strip_image_quad[1].y);
955 immVertex2f(pos, strip_image_quad[2].x, strip_image_quad[2].y);
956 immVertex2f(pos, strip_image_quad[3].x, strip_image_quad[3].y);
957 immEnd();
961 GPU_line_smooth(false);
962}
963
964static void text_selection_draw(const bContext *C, const Strip *strip, uint pos)
965{
966 const TextVars *data = static_cast<TextVars *>(strip->effectdata);
967 const TextVarsRuntime *text = data->runtime;
968 const Scene *scene = CTX_data_scene(C);
969
970 if (data->selection_start_offset == -1 || strip_text_selection_range_get(data).is_empty()) {
971 return;
972 }
973
976 sel_range.first());
977 const blender::int2 selection_end = strip_text_cursor_offset_to_position(text, sel_range.last());
978 const int line_start = selection_start.y;
979 const int line_end = selection_end.y;
980
981 for (int line_index = line_start; line_index <= line_end; line_index++) {
982 const blender::seq::LineInfo line = text->lines[line_index];
983 blender::seq::CharInfo character_start = line.characters.first();
984 blender::seq::CharInfo character_end = line.characters.last();
985
986 if (line_index == selection_start.y) {
987 character_start = line.characters[selection_start.x];
988 }
989 if (line_index == selection_end.y) {
990 character_end = line.characters[selection_end.x];
991 }
992
993 const float line_y = character_start.position.y + text->font_descender;
994
995 const blender::float2 view_offs{-scene->r.xsch / 2.0f, -scene->r.ysch / 2.0f};
996 const float view_aspect = scene->r.xasp / scene->r.yasp;
997 blender::float3x3 transform_mat = seq::image_transform_matrix_get(scene, strip);
998 blender::float4x2 selection_quad{
999 {character_start.position.x, line_y},
1000 {character_start.position.x, line_y + text->line_height},
1001 {character_end.position.x + character_end.advance_x, line_y + text->line_height},
1002 {character_end.position.x + character_end.advance_x, line_y},
1003 };
1004
1007
1008 for (int i : blender::IndexRange(0, 4)) {
1009 selection_quad[i] += view_offs;
1010 selection_quad[i] = blender::math::transform_point(transform_mat, selection_quad[i]);
1011 selection_quad[i].x *= view_aspect;
1012 }
1013 for (int i : blender::Vector<int>{0, 1, 2, 2, 3, 0}) {
1014 immVertex2f(pos, selection_quad[i][0], selection_quad[i][1]);
1015 }
1016
1017 immEnd();
1018 }
1019}
1020
1022{
1023 blender::int2 coords_view;
1024 UI_view2d_view_to_region(v2d, coords.x, coords.y, &coords_view.x, &coords_view.y);
1025 coords_view.x = std::round(coords_view.x);
1026 coords_view.y = std::round(coords_view.y);
1027 blender::float2 coords_region_aligned;
1029 v2d, coords_view.x, coords_view.y, &coords_region_aligned.x, &coords_region_aligned.y);
1030 return coords_region_aligned;
1031}
1032
1033static void text_edit_draw_cursor(const bContext *C, const Strip *strip, uint pos)
1034{
1035 const TextVars *data = static_cast<TextVars *>(strip->effectdata);
1036 const TextVarsRuntime *text = data->runtime;
1037 const Scene *scene = CTX_data_scene(C);
1038
1039 const blender::float2 view_offs{-scene->r.xsch / 2.0f, -scene->r.ysch / 2.0f};
1040 const float view_aspect = scene->r.xasp / scene->r.yasp;
1041 blender::float3x3 transform_mat = seq::image_transform_matrix_get(scene, strip);
1043 data->cursor_offset);
1044 const float cursor_width = 10;
1045 blender::float2 cursor_coords =
1046 text->lines[cursor_position.y].characters[cursor_position.x].position;
1047 /* Clamp cursor coords to be inside of text boundbox. Compensate for cursor width, but also line
1048 * width hardcoded in shader. */
1049 rcti text_boundbox = text->text_boundbox;
1050 text_boundbox.xmax -= cursor_width + U.pixelsize;
1051 text_boundbox.xmin += U.pixelsize;
1052
1053 cursor_coords.x = std::clamp(
1054 cursor_coords.x, float(text_boundbox.xmin), float(text_boundbox.xmax));
1055 cursor_coords = coords_region_view_align(UI_view2d_fromcontext(C), cursor_coords);
1056
1057 blender::float4x2 cursor_quad{
1058 {cursor_coords.x, cursor_coords.y},
1059 {cursor_coords.x, cursor_coords.y + text->line_height},
1060 {cursor_coords.x + cursor_width, cursor_coords.y + text->line_height},
1061 {cursor_coords.x + cursor_width, cursor_coords.y},
1062 };
1063 const blender::float2 descender_offs{0.0f, float(text->font_descender)};
1064
1067
1068 for (int i : blender::IndexRange(0, 4)) {
1069 cursor_quad[i] += descender_offs + view_offs;
1070 cursor_quad[i] = blender::math::transform_point(transform_mat, cursor_quad[i]);
1071 cursor_quad[i].x *= view_aspect;
1072 }
1073 for (int i : blender::Vector<int>{0, 1, 2, 2, 3, 0}) {
1074 immVertex2f(pos, cursor_quad[i][0], cursor_quad[i][1]);
1075 }
1076
1077 immEnd();
1078}
1079
1080static void text_edit_draw_box(const bContext *C, const Strip *strip, uint pos)
1081{
1082 const TextVars *data = static_cast<TextVars *>(strip->effectdata);
1083 const TextVarsRuntime *text = data->runtime;
1084 const Scene *scene = CTX_data_scene(C);
1085
1086 const blender::float2 view_offs{-scene->r.xsch / 2.0f, -scene->r.ysch / 2.0f};
1087 const float view_aspect = scene->r.xasp / scene->r.yasp;
1089 blender::float4x2 box_quad{
1090 {float(text->text_boundbox.xmin), float(text->text_boundbox.ymin)},
1091 {float(text->text_boundbox.xmin), float(text->text_boundbox.ymax)},
1092 {float(text->text_boundbox.xmax), float(text->text_boundbox.ymax)},
1093 {float(text->text_boundbox.xmax), float(text->text_boundbox.ymin)},
1094 };
1095
1101 immUniform1f("lineWidth", U.pixelsize);
1102 immUniform1f("dash_width", 10.0f);
1104
1105 for (int i : blender::IndexRange(0, 4)) {
1106 box_quad[i] += view_offs;
1107 box_quad[i] = blender::math::transform_point(transform_mat, box_quad[i]);
1108 box_quad[i].x *= view_aspect;
1109 immVertex2f(pos, box_quad[i][0], box_quad[i][1]);
1110 }
1111
1112 immEnd();
1114}
1115
1116static void text_edit_draw(const bContext *C)
1117{
1118 if (!sequencer_text_editing_active_poll(const_cast<bContext *>(C))) {
1119 return;
1120 }
1122 if (!seq::effects_can_render_text(strip)) {
1123 return;
1124 }
1125
1128 GPU_line_smooth(true);
1131
1132 text_selection_draw(C, strip, pos);
1133 text_edit_draw_cursor(C, strip, pos);
1134
1137 GPU_line_smooth(false);
1138
1139 text_edit_draw_box(C, strip, pos);
1140}
1141
1142/* Draw empty preview region.
1143 * The entire region is cleared with the TH_SEQ_PREVIEW color.
1144 *
1145 * Used in cases when there is no editing, or when the display is set to NONE. */
1147{
1149 BLI_assert(viewport);
1150
1151 GPUFrameBuffer *overlay_fb = GPU_viewport_framebuffer_overlay_get(viewport);
1152 GPU_framebuffer_bind_no_srgb(overlay_fb);
1153
1155}
1156
1157/* Begin drawing the sequence preview region.
1158 * Initializes the drawing state which is common for color render and overlay drawing.
1159 *
1160 * Returns true if the region is to be drawn. Example is when it is not to be drawn is when there
1161 * is ongoing offline rendering (to avoid possible threading conflict).
1162 *
1163 * If the function returns true preview_draw_end() is to be called after drawing is done. */
1164static bool preview_draw_begin(const bContext *C,
1165 const RenderData &render_data,
1166 const ColorManagedViewSettings &view_settings,
1167 const ColorManagedDisplaySettings &display_settings,
1168 ARegion &region)
1169{
1171 if (G.is_rendering) {
1172 return false;
1173 }
1174
1176 BLI_assert(viewport);
1177
1178 /* Configure color space used by the viewport.
1179 * This also checks for HDR support and enables it for the viewport when found and needed. */
1181 viewport, &view_settings, &display_settings, render_data.dither_intensity);
1182
1184
1185 /* Setup view. */
1186 View2D &v2d = region.v2d;
1187 float viewrect[2];
1188 sequencer_display_size(render_data, viewrect);
1189 UI_view2d_totRect_set(&v2d, roundf(viewrect[0]), roundf(viewrect[1]));
1192
1193 return true;
1194}
1195
1201
1202/* Configure current GPU state to draw on the color render frame-buffer of the viewport. */
1204{
1206 BLI_assert(viewport);
1207
1208 GPUFrameBuffer *render_fb = GPU_viewport_framebuffer_render_get(viewport);
1209 GPU_framebuffer_bind(render_fb);
1210
1211 float col[4] = {0, 0, 0, 0};
1212 GPU_framebuffer_clear_color(render_fb, col);
1213}
1214
1215/* Configure current GPU state to draw on the overlay frame-buffer of the viewport. */
1217{
1219 BLI_assert(viewport);
1220
1221 GPUFrameBuffer *overlay_fb = GPU_viewport_framebuffer_overlay_get(viewport);
1222 GPU_framebuffer_bind_no_srgb(overlay_fb);
1223
1225}
1226
1227/* Draw the given texture on the currently bound frame-buffer without any changes to its pixels
1228 * colors.
1229 *
1230 * The position denotes coordinates of a rectangle used to display the texture.
1231 * The texture_coord contains UV coordinates of the input texture which are mapped to the corners
1232 * of the rectangle. */
1233static void preview_draw_texture_simple(GPUTexture &texture,
1234 const rctf &position,
1235 const rctf &texture_coord)
1236{
1237 GPUVertFormat *imm_format = immVertexFormat();
1238 const uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1240 imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1241
1243 immUniformColor3f(1.0f, 1.0f, 1.0f);
1244
1246
1247 immRectf_with_texco(pos, tex_coord, position, texture_coord);
1248
1251}
1252
1253/* Draw the given texture on the currently bound frame-buffer and convert its colors to linear
1254 * space in the fragment shader. This makes it suitable to be further processed by a GPUViewport
1255 *
1256 * The position denotes coordinates of a rectangle used to display the texture.
1257 * The texture_coord contains UV coordinates of the input texture which are mapped to the corners
1258 * of the rectangle. */
1260 const char *texture_colorspace_name,
1261 const bool predivide,
1262 const rctf &position,
1263 const rctf &texture_coord)
1264{
1265 GPUVertFormat *imm_format = immVertexFormat();
1266 const uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1268 imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1269
1270 if (!IMB_colormanagement_setup_glsl_draw_to_scene_linear(texture_colorspace_name, predivide)) {
1271 /* An error happened when configuring GPU side color space conversion. Return and allow the
1272 * view to be black, so that it is obvious something went wrong and that a bug report is to
1273 * be submitted.
1274 *
1275 * Note that fallback OCIO implementation is handled on a higher level. */
1276 return;
1277 }
1278
1280
1281 immRectf_with_texco(pos, tex_coord, position, texture_coord);
1282
1284
1286}
1287
1288/* Draw overlays for the currently displayed images in the preview. */
1290 const Scene *scene,
1291 const Editing &editing,
1292 const int timeline_frame)
1293{
1294 ListBase *channels = seq::channels_displayed_get(&editing);
1296 scene, channels, editing.seqbasep, timeline_frame, 0);
1297 Strip *active_seq = seq::select_active_get(scene);
1298 for (Strip *strip : strips) {
1299 /* TODO(sergey): Avoid having per-strip strip-independent checks. */
1300 strip_draw_image_origin_and_outline(C, strip, strip == active_seq);
1302 }
1303}
1304
1305static bool is_cursor_visible(const SpaceSeq &sseq)
1306{
1307 if (G.moving & G_TRANSFORM_CURSOR) {
1308 return true;
1309 }
1310
1311 if ((sseq.flag & SEQ_SHOW_OVERLAY) &&
1313 {
1314 return true;
1315 }
1316 return false;
1317}
1318
1322static void draw_cursor_2d(const ARegion *region, const blender::float2 &cursor)
1323{
1324 int co[2];
1325 UI_view2d_view_to_region(&region->v2d, cursor[0], cursor[1], &co[0], &co[1]);
1326
1327 /* Draw nice Anti Aliased cursor. */
1329
1330 /* Draw lines */
1331 float original_proj[4][4];
1332 GPU_matrix_projection_get(original_proj);
1334 ED_region_pixelspace(region);
1335 GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f);
1336 GPU_matrix_scale_2f(U.widget_unit, U.widget_unit);
1337
1338 float viewport[4];
1339 GPU_viewport_size_get_f(viewport);
1340
1342 struct {
1343 uint pos, col;
1344 } attr_id{};
1348 immUniform2fv("viewportSize", &viewport[2]);
1349 immUniform1f("lineWidth", U.pixelsize);
1350
1351 const float f5 = 0.25f;
1352 const float f10 = 0.5f;
1353 const float f20 = 1.0f;
1354
1355 const float red[3] = {1.0f, 0.0f, 0.0f};
1356 const float white[3] = {1.0f, 1.0f, 1.0f};
1357
1358 const int segments = 16;
1359 immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
1360 for (int i = 0; i < segments + 1; i++) {
1361 float angle = float(2 * M_PI) * (float(i) / float(segments));
1362 float x = f10 * cosf(angle);
1363 float y = f10 * sinf(angle);
1364
1365 immAttr3fv(attr_id.col, (i % 2 == 0) ? red : white);
1366 immVertex2f(attr_id.pos, x, y);
1367 }
1368 immEnd();
1369
1370 float crosshair_color[3];
1371 UI_GetThemeColor3fv(TH_VIEW_OVERLAY, crosshair_color);
1372
1374 immAttr3fv(attr_id.col, crosshair_color);
1375 immVertex2f(attr_id.pos, -f20, 0);
1376 immAttr3fv(attr_id.col, crosshair_color);
1377 immVertex2f(attr_id.pos, -f5, 0);
1378
1379 immAttr3fv(attr_id.col, crosshair_color);
1380 immVertex2f(attr_id.pos, +f20, 0);
1381 immAttr3fv(attr_id.col, crosshair_color);
1382 immVertex2f(attr_id.pos, +f5, 0);
1383
1384 immAttr3fv(attr_id.col, crosshair_color);
1385 immVertex2f(attr_id.pos, 0, -f20);
1386 immAttr3fv(attr_id.col, crosshair_color);
1387 immVertex2f(attr_id.pos, 0, -f5);
1388
1389 immAttr3fv(attr_id.col, crosshair_color);
1390 immVertex2f(attr_id.pos, 0, +f20);
1391 immAttr3fv(attr_id.col, crosshair_color);
1392 immVertex2f(attr_id.pos, 0, +f5);
1393 immEnd();
1394
1396
1398
1400 GPU_matrix_projection_set(original_proj);
1401}
1402
1403/* Get offset in frame numbers of the reference frame relative to the current frame. */
1404static int get_reference_frame_offset(const Editing &editing, const RenderData &render_data)
1405{
1407 return editing.overlay_frame_abs - render_data.cfra;
1408 }
1409 return editing.overlay_frame_ofs;
1410}
1411
1412/* Create GPUTexture from the given image buffer for drawing rendered sequencer frame on the
1413 * color render frame buffer.
1414 *
1415 * The texture format and color space matches the CPU-side buffer.
1416 *
1417 * If both float and byte buffers are missing nullptr is returned.
1418 * If channel configuration is incompatible with the texture nullptr is returned. */
1419static GPUTexture *create_texture(const ImBuf &ibuf)
1420{
1421 const eGPUTextureUsage texture_usage = GPU_TEXTURE_USAGE_SHADER_READ |
1423
1424 GPUTexture *texture = nullptr;
1425
1426 if (ibuf.float_buffer.data) {
1427 eGPUTextureFormat texture_format;
1428 switch (ibuf.channels) {
1429 case 1:
1430 texture_format = GPU_R32F;
1431 break;
1432 case 3:
1433 texture_format = GPU_RGB32F;
1434 break;
1435 case 4:
1436 texture_format = GPU_RGBA32F;
1437 break;
1438 default:
1439 BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
1440 return nullptr;
1441 }
1442
1444 "seq_display_buf", ibuf.x, ibuf.y, 1, texture_format, texture_usage, nullptr);
1446 }
1447 else if (ibuf.byte_buffer.data) {
1449 "seq_display_buf", ibuf.x, ibuf.y, 1, GPU_RGBA8, texture_usage, nullptr);
1451 }
1452
1453 if (texture) {
1455 }
1456
1457 return texture;
1458}
1459
1460/* Get colorspace name of the image buffer used to create GPU texture.
1461 *
1462 * Needs to be kept in sync with create_texture() w.r.t which buffers are used to create the
1463 * texture. If the image buffer does not specify color space explicitly scene linear is returned if
1464 * there is a float buffer, and default byte space is returned if there is a byte buffer.
1465 *
1466 * If there are no buffers at all scene linear space is returned. */
1486
1487/* Part of the sequencer preview region drawing which renders images to the viewport's color render
1488 * frame-buffer. */
1489static void sequencer_preview_draw_color_render(const SpaceSeq &space_sequencer,
1490 const Editing &editing,
1491 ARegion &region,
1492 const ImBuf *current_ibuf,
1493 GPUTexture *current_texture,
1494 const ImBuf *reference_ibuf,
1495 GPUTexture *reference_texture)
1496{
1498
1499 if (current_texture) {
1500 BLI_assert(current_ibuf);
1501 const rctf position = preview_get_full_position(region);
1502 const rctf texture_coord = preview_get_full_texture_coord();
1503 const char *texture_colorspace = get_texture_colorspace_name(*current_ibuf);
1504 const bool predivide = (current_ibuf->float_buffer.data != nullptr);
1506 *current_texture, texture_colorspace, predivide, position, texture_coord);
1507 }
1508
1509 if (reference_texture) {
1510 BLI_assert(reference_ibuf);
1511 const rctf position = preview_get_reference_position(space_sequencer, editing, region);
1512 const rctf texture_coord = preview_get_reference_texture_coord(space_sequencer, editing);
1513 const char *texture_colorspace = get_texture_colorspace_name(*reference_ibuf);
1514 const bool predivide = (reference_ibuf->float_buffer.data != nullptr);
1516 *reference_texture, texture_colorspace, predivide, position, texture_coord);
1517 }
1518}
1519
1520static void draw_registered_callbacks(const bContext *C, ARegion &region)
1521{
1523 BLI_assert(viewport);
1524
1525 GPUFrameBuffer *overlay_fb = GPU_viewport_framebuffer_overlay_get(viewport);
1526
1527 GPU_framebuffer_bind(overlay_fb);
1529 GPU_framebuffer_bind_no_srgb(overlay_fb);
1530}
1531
1532/* Part of the sequencer preview region drawing which renders information overlays to the
1533 * viewport's overlay frame-buffer. */
1535 const wmWindowManager &wm,
1536 const Scene *scene,
1537 const SpaceSeq &space_sequencer,
1538 const Editing &editing,
1539 const ColorManagedViewSettings &view_settings,
1540 const ColorManagedDisplaySettings &display_settings,
1541 ARegion &region,
1542 GPUTexture *current_texture,
1543 GPUTexture *reference_texture,
1544 const ImBuf *overlay_ibuf,
1545 const int timeline_frame)
1546{
1547 const bool is_playing = ED_screen_animation_playing(&wm);
1548 const bool show_imbuf = check_show_imbuf(space_sequencer);
1549
1551
1552 bool has_scopes = false;
1553 if (overlay_ibuf &&
1555 space_sequencer, view_settings, display_settings, *overlay_ibuf, timeline_frame))
1556 {
1557 /* Draw scope. */
1558 sequencer_draw_scopes(space_sequencer, region);
1559 has_scopes = true;
1560 }
1561 else if (space_sequencer.flag & SEQ_USE_ALPHA) {
1562 /* Draw checked-board. */
1563 const View2D &v2d = region.v2d;
1564 imm_draw_box_checker_2d(v2d.tot.xmin, v2d.tot.ymin, v2d.tot.xmax, v2d.tot.ymax);
1565
1566 /* Draw current and preview textures in a special way to pierce a hole in the overlay to make
1567 * the actual image visible. */
1569 if (current_texture) {
1570 const rctf position = preview_get_full_position(region);
1571 const rctf texture_coord = preview_get_full_texture_coord();
1572 preview_draw_texture_simple(*current_texture, position, texture_coord);
1573 }
1574 if (reference_texture) {
1575 const rctf position = preview_get_reference_position(space_sequencer, editing, region);
1576 const rctf texture_coord = preview_get_reference_texture_coord(space_sequencer, editing);
1577 preview_draw_texture_simple(*reference_texture, position, texture_coord);
1578 }
1580 }
1581 else {
1582 /* The overlay framebuffer is fully cleared. Need to draw a full-frame transparent rectangle in
1583 * it to make sequencer result visible. */
1584
1585 const rctf position = preview_get_full_position(region);
1586
1587 GPUVertFormat *imm_format = immVertexFormat();
1588 const uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1589
1591
1593 immUniformColor3f(-.0f, 1.0f, 1.0f);
1594 immRectf(pos, position.xmin, position.ymin, position.xmax, position.ymax);
1596
1598 }
1599
1600 /* Draw metadata. */
1601 if (!has_scopes && overlay_ibuf) {
1602 if ((space_sequencer.preview_overlay.flag & SEQ_PREVIEW_SHOW_METADATA) &&
1603 (space_sequencer.flag & SEQ_SHOW_OVERLAY))
1604 {
1605 const View2D &v2d = region.v2d;
1606 ED_region_image_metadata_draw(0.0, 0.0, overlay_ibuf, &v2d.tot, 1.0, 1.0);
1607 }
1608 }
1609
1610 if (show_imbuf && (space_sequencer.flag & SEQ_SHOW_OVERLAY)) {
1611 sequencer_draw_borders_overlay(space_sequencer, region.v2d, scene);
1612
1613 /* Various overlays like strip selection and text editing. */
1614 preview_draw_all_image_overlays(C, scene, editing, timeline_frame);
1615
1616 if ((space_sequencer.preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && space_sequencer.gpd) {
1618 }
1619 }
1620
1622
1624
1625 /* No need to show the cursor for scopes. */
1626 if ((is_playing == false) && (space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF) &&
1627 is_cursor_visible(space_sequencer))
1628 {
1629 GPU_color_mask(true, true, true, true);
1630 GPU_depth_mask(false);
1632
1633 const float2 cursor_pixel = seq::image_preview_unit_to_px(scene, space_sequencer.cursor);
1634 draw_cursor_2d(&region, cursor_pixel);
1635 }
1636
1637 /* Gizmos. */
1638 if ((is_playing == false) && (space_sequencer.gizmo_flag & SEQ_GIZMO_HIDE) == 0) {
1640 }
1641
1642 /* FPS counter. */
1643 if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(&wm)) {
1644 const rcti *rect = ED_region_visible_rect(&region);
1645 int xoffset = rect->xmin + U.widget_unit;
1646 int yoffset = rect->ymax;
1647
1648 /* #ED_scene_draw_fps does not set text/shadow colors, except when frame-rate is too low, then
1649 * it sets text color to red. Make sure the "normal case" also has legible colors. */
1650 const int font_id = BLF_default();
1651 float text_color[4] = {1, 1, 1, 1}, shadow_color[4] = {0, 0, 0, 0.8f};
1652 BLF_color4fv(font_id, text_color);
1653 BLF_enable(font_id, BLF_SHADOW);
1654 BLF_shadow_offset(font_id, 0, 0);
1655 BLF_shadow(font_id, FontShadowType::Outline, shadow_color);
1656
1657 ED_scene_draw_fps(scene, xoffset, &yoffset);
1658
1659 BLF_disable(font_id, BLF_SHADOW);
1660 }
1661}
1662
1664{
1665 const char *view_names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
1666
1667 const ScrArea *area = CTX_wm_area(C);
1668 const SpaceSeq &space_sequencer = *static_cast<const SpaceSeq *>(area->spacedata.first);
1669 const Scene *scene = CTX_data_scene(C);
1670
1671 if (!scene->ed || space_sequencer.render_size == SEQ_RENDER_SIZE_NONE) {
1673 return;
1674 }
1675
1676 const Editing &editing = *scene->ed;
1677 const RenderData &render_data = scene->r;
1678
1679 if (!preview_draw_begin(C, render_data, scene->view_settings, scene->display_settings, *region))
1680 {
1682 return;
1683 }
1684
1685 const bool show_imbuf = check_show_imbuf(space_sequencer);
1686
1687 const bool draw_overlay = (space_sequencer.flag & SEQ_SHOW_OVERLAY);
1688 const bool draw_frame_overlay = (editing.overlay_frame_flag & SEQ_EDIT_OVERLAY_FRAME_SHOW) &&
1689 draw_overlay;
1690 const bool need_current_frame = !(draw_frame_overlay && (space_sequencer.overlay_frame_type ==
1692 const bool need_reference_frame = draw_frame_overlay && space_sequencer.overlay_frame_type !=
1694
1695 int timeline_frame = render_data.cfra;
1696 if (sequencer_draw_get_transform_preview(space_sequencer, *scene)) {
1697 timeline_frame = sequencer_draw_get_transform_preview_frame(scene);
1698 }
1699
1700 /* GPU textures for the current and reference frames.
1701 *
1702 * When non-nullptr they are to be drawn (in other words, when they are non-nullptr the
1703 * corresponding draw_current_frame and draw_reference_frame is true). */
1704 GPUTexture *current_texture = nullptr;
1705 GPUTexture *reference_texture = nullptr;
1706
1707 /* Get image buffers before setting up GPU state for drawing. This is because
1708 * sequencer_ibuf_get() might not properly restore the state.
1709 * Additionally, some image buffers might be needed for both color render and overlay drawing. */
1710 ImBuf *current_ibuf = nullptr;
1711 ImBuf *reference_ibuf = nullptr;
1712 if (need_current_frame) {
1713 current_ibuf = sequencer_ibuf_get(
1714 C, timeline_frame, view_names[space_sequencer.multiview_eye]);
1715 if (show_imbuf && current_ibuf) {
1716 current_texture = create_texture(*current_ibuf);
1717 }
1718 }
1719 if (need_reference_frame) {
1720 const int offset = get_reference_frame_offset(editing, render_data);
1721 reference_ibuf = sequencer_ibuf_get(
1722 C, timeline_frame + offset, view_names[space_sequencer.multiview_eye]);
1723 if (show_imbuf && reference_ibuf) {
1724 reference_texture = create_texture(*reference_ibuf);
1725 }
1726 }
1727
1728 /* Image buffer used for overlays: scopes, metadata etc. */
1729 ImBuf *overlay_ibuf = need_current_frame ? current_ibuf : reference_ibuf;
1730
1731 /* Draw parts of the preview region to the corresponding frame buffers. */
1733 editing,
1734 *region,
1735 current_ibuf,
1736 current_texture,
1737 reference_ibuf,
1738 reference_texture);
1740 *CTX_wm_manager(C),
1741 scene,
1742 space_sequencer,
1743 editing,
1744 scene->view_settings,
1745 scene->display_settings,
1746 *region,
1747 current_texture,
1748 reference_texture,
1749 overlay_ibuf,
1750 timeline_frame);
1751
1752#if 0
1753 sequencer_draw_maskedit(C, scene, region, sseq);
1754#endif
1755
1756 /* Free textures. */
1757 if (current_texture) {
1758 GPU_texture_free(current_texture);
1759 }
1760 if (reference_texture) {
1761 GPU_texture_free(reference_texture);
1762 }
1763
1764 /* Free CPU side resources. */
1765 IMB_freeImBuf(current_ibuf);
1766 IMB_freeImBuf(reference_ibuf);
1767
1769}
1770
1771} // namespace blender::ed::vse
Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
bScreen * CTX_wm_screen(const bContext *C)
ScrArea * CTX_wm_area(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
SpaceSeq * CTX_wm_space_seq(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
@ G_TRANSFORM_CURSOR
@ G_TRANSFORM_SEQ
void BKE_render_resolution(const RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition scene.cc:2927
int BKE_scene_multiview_view_id_get(const RenderData *rd, const char *viewname)
Definition scene.cc:3094
void BLF_shadow(int fontid, FontShadowType type, const float rgba[4]=nullptr)
Definition blf.cc:928
void BLF_width_and_height(int fontid, const char *str, size_t str_len, float *r_width, float *r_height) ATTR_NONNULL()
Definition blf.cc:792
void BLF_color4fv(int fontid, const float rgba[4])
Definition blf.cc:502
void BLF_shadow_offset(int fontid, int x, int y)
Definition blf.cc:940
@ BLF_SHADOW
Definition BLF_api.hh:435
void BLF_disable(int fontid, int option)
Definition blf.cc:329
int BLF_default()
void BLF_enable(int fontid, int option)
Definition blf.cc:320
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
MINLINE float ratiof(float min, float max, float pos)
#define BLI_YUV_ITU_BT709
void rgb_to_yuv(float r, float g, float b, float *r_y, float *r_u, float *r_v, int colorspace)
Definition math_color.cc:67
void yuv_to_rgb(float y, float u, float v, float *r_r, float *r_g, float *r_b, int colorspace)
Definition math_color.cc:91
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
#define DEG2RADF(_deg)
#define M_PI
void BLI_rctf_resize_y(struct rctf *rect, float y)
Definition rct.cc:651
BLI_INLINE float BLI_rctf_cent_y(const struct rctf *rct)
Definition BLI_rect.h:189
BLI_INLINE float BLI_rctf_cent_x(const struct rctf *rct)
Definition BLI_rect.h:185
void BLI_rctf_resize_x(struct rctf *rect, float x)
Definition rct.cc:645
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition rct.cc:404
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:202
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition BLI_rect.h:206
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
#define SNPRINTF_RLEN(dst, format,...)
Definition BLI_string.h:600
unsigned char uchar
unsigned int uint
#define ELEM(...)
@ OB_RENDER
#define STEREO_LEFT_NAME
#define STEREO_RIGHT_NAME
@ STEREO_RIGHT_ID
@ RGN_TYPE_PREVIEW
@ SEQ_RIGHTSEL
@ SEQ_LEFTSEL
struct TextVarsRuntime TextVarsRuntime
@ STRIP_TYPE_SOUND_RAM
@ SEQ_EDIT_OVERLAY_FRAME_ABS
@ SEQ_EDIT_OVERLAY_FRAME_SHOW
@ SEQ_RENDER_SIZE_SCENE
@ SEQ_RENDER_SIZE_NONE
@ SEQ_PREVIEW_SHOW_METADATA
@ SEQ_PREVIEW_SHOW_GPENCIL
@ SEQ_PREVIEW_SHOW_SAFE_MARGINS
@ SEQ_PREVIEW_SHOW_OUTLINE_SELECTED
@ SEQ_PREVIEW_SHOW_SAFE_CENTER
@ SEQ_PREVIEW_SHOW_2D_CURSOR
@ SEQ_DRAW_TRANSFORM_PREVIEW
@ SEQ_OVERLAY_FRAME_TYPE_RECT
@ SEQ_OVERLAY_FRAME_TYPE_CURRENT
@ SEQ_OVERLAY_FRAME_TYPE_REFERENCE
@ SEQ_DRAW_IMG_VECTORSCOPE
@ SEQ_DRAW_IMG_RGBPARADE
@ SEQ_DRAW_IMG_HISTOGRAM
@ SEQ_DRAW_IMG_IMBUF
@ SEQ_DRAW_IMG_WAVEFORM
@ SEQ_USE_ALPHA
@ SEQ_USE_PROXIES
@ SEQ_SHOW_OVERLAY
@ SEQ_GIZMO_HIDE
#define UI_SCALE_FAC
@ USER_SHOW_FPS
void ED_mask_draw_region(Depsgraph *depsgraph, Mask *mask, ARegion *region, char draw_flag, char draw_type, eMaskOverlayMode overlay_mode, float blend_factor, int width_i, int height_i, float aspx, float aspy, bool do_scale_applied, bool do_draw_cb, float stabmat[4][4], const bContext *C)
Definition mask_draw.cc:641
const rcti * ED_region_visible_rect(ARegion *region)
Definition area.cc:4118
bScreen * ED_screen_animation_no_scrub(const wmWindowManager *wm)
void ED_region_pixelspace(const ARegion *region)
Definition area.cc:123
bScreen * ED_screen_animation_playing(const wmWindowManager *wm)
void ED_region_draw_cb_draw(const bContext *C, ARegion *region, int type)
#define REGION_DRAW_POST_VIEW
void ED_region_image_metadata_draw(int x, int y, const ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
Definition ed_draw.cc:1036
void ED_scene_draw_fps(const Scene *scene, int xoffset, int *yoffset)
static AppView * view
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb)
GPUFrameBuffer * GPU_framebuffer_active_get()
void GPU_framebuffer_restore()
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void GPU_framebuffer_clear_color(GPUFrameBuffer *fb, const float clear_col[4])
void immUniformColor4ubv(const unsigned char rgba[4])
void immUniform4f(const char *name, float x, float y, float z, float w)
void immEnd()
void immUniform2fv(const char *name, const float data[2])
void immUnbindProgram()
void immUniform2f(const char *name, float x, float y)
void immVertex2f(uint attr_id, float x, float y)
void immUniformThemeColor(int color_id)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immUniform1i(const char *name, int x)
void immUniform1f(const char *name, float x)
GPUVertFormat * immVertexFormat()
void immUniformThemeColorBlend(int color_id1, int color_id2, float fac)
void immUniformColor3f(float r, float g, float b)
void immAttr3fv(uint attr_id, const float data[3])
void immAttr2f(uint attr_id, float x, float y)
void immBegin(GPUPrimType, uint vertex_len)
void immUniformColor3fv(const float rgb[3])
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void imm_draw_box_checker_2d(float x1, float y1, float x2, float y2)
void immRectf_with_texco(uint pos, uint tex_coord, const rctf &p, const rctf &uv)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
void GPU_matrix_scale_2f(float x, float y)
void GPU_matrix_push()
#define GPU_matrix_projection_get(x)
#define GPU_matrix_projection_set(x)
void GPU_matrix_pop()
void GPU_matrix_translate_2f(float x, float y)
@ GPU_PRIM_TRI_FAN
@ GPU_PRIM_LINE_LOOP
@ GPU_PRIM_LINES
@ GPU_PRIM_POINTS
@ GPU_PRIM_LINE_STRIP
@ GPU_PRIM_TRIS
@ GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA
@ GPU_SHADER_3D_POLYLINE_FLAT_COLOR
@ GPU_SHADER_3D_IMAGE_COLOR
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
@ GPU_BLEND_ADDITIVE
Definition GPU_state.hh:89
@ GPU_BLEND_OVERLAY_MASK_FROM_ALPHA
Definition GPU_state.hh:107
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
void GPU_line_width(float width)
Definition gpu_state.cc:166
void GPU_line_smooth(bool enable)
Definition gpu_state.cc:78
void GPU_depth_mask(bool depth)
Definition gpu_state.cc:110
void GPU_color_mask(bool r, bool g, bool b, bool a)
Definition gpu_state.cc:98
@ GPU_DEPTH_NONE
Definition GPU_state.hh:111
void GPU_depth_test(eGPUDepthTest test)
Definition gpu_state.cc:68
void GPU_viewport_size_get_f(float coords[4])
Definition gpu_state.cc:273
void GPU_texture_bind(GPUTexture *texture, int unit)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
void GPU_texture_unbind(GPUTexture *texture)
eGPUDataFormat
@ GPU_DATA_UBYTE
@ GPU_DATA_FLOAT
void GPU_texture_extend_mode(GPUTexture *texture, GPUSamplerExtendMode extend_mode)
eGPUTextureUsage
@ GPU_TEXTURE_USAGE_SHADER_READ
@ GPU_TEXTURE_USAGE_ATTACHMENT
@ GPU_SAMPLER_EXTEND_MODE_CLAMP_TO_BORDER
void GPU_texture_filter_mode(GPUTexture *texture, bool use_filter)
eGPUTextureFormat
@ GPU_R32F
@ GPU_RGBA32F
@ GPU_RGB32F
@ GPU_RGBA8
void GPU_texture_update(GPUTexture *texture, eGPUDataFormat data_format, const void *data)
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, blender::StringRef name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect)
void GPU_viewport_colorspace_set(GPUViewport *viewport, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, float dither)
GPUFrameBuffer * GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
void GPU_viewport_unbind(GPUViewport *viewport)
GPUFrameBuffer * GPU_viewport_framebuffer_render_get(GPUViewport *viewport)
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
Definition IK_Math.h:117
void IMB_colormanagement_imbuf_make_display_space(ImBuf *ibuf, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings)
const char * IMB_colormanagement_colorspace_get_name(const ColorSpace *colorspace)
@ COLOR_ROLE_DEFAULT_BYTE
@ COLOR_ROLE_SCENE_LINEAR
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_colormanagement_finish_glsl_draw()
bool IMB_colormanagement_setup_glsl_draw_to_scene_linear(const char *from_colorspace_name, bool predivide)
ImBuf * IMB_dupImBuf(const ImBuf *ibuf1)
void IMB_byte_from_float(ImBuf *ibuf)
void IMB_freeImBuf(ImBuf *ibuf)
#define C
Definition RandGen.cpp:29
void UI_draw_safe_areas(uint pos, const rctf *rect, const float title_aspect[2], const float action_aspect[2])
void UI_GetThemeColor3fv(int colorid, float col[3])
@ TH_SEQ_SELECTED
@ TH_BACK
@ TH_SEQ_SELECTED_TEXT
@ TH_SEQ_PREVIEW
@ TH_SEQ_TEXT_CURSOR
@ TH_VIEW_OVERLAY
@ TH_SEQ_ACTIVE
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3])
void UI_ThemeClearColor(int colorid)
void UI_view2d_curRect_validate(View2D *v2d)
Definition view2d.cc:828
void UI_view2d_scale_get_inverse(const View2D *v2d, float *r_x, float *r_y)
Definition view2d.cc:1928
char char char char void UI_view2d_text_cache_add(View2D *v2d, float x, float y, const char *str, size_t str_len, const unsigned char col[4])
Definition view2d.cc:2081
void UI_view2d_view_restore(const bContext *C)
Definition view2d.cc:1162
void UI_view2d_text_cache_draw(ARegion *region)
Definition view2d.cc:2141
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
Definition view2d.cc:1036
void UI_view2d_view_ortho(const View2D *v2d)
Definition view2d.cc:1095
View2D * UI_view2d_fromcontext(const bContext *C)
Definition view2d.cc:1854
void UI_view2d_region_to_view(const View2D *v2d, float x, float y, float *r_view_x, float *r_view_y) ATTR_NONNULL()
Definition view2d.cc:1667
void UI_view2d_view_to_region(const View2D *v2d, float x, float y, int *r_region_x, int *r_region_y) ATTR_NONNULL()
Definition view2d.cc:1722
@ WM_JOB_TYPE_COMPOSITE
Definition WM_api.hh:1727
@ WM_JOB_TYPE_RENDER_PREVIEW
Definition WM_api.hh:1729
@ WM_GIZMOMAP_DRAWSTEP_2D
#define ND_SEQUENCER
Definition WM_types.hh:434
#define NC_SCENE
Definition WM_types.hh:375
void ED_annotation_draw_2dimage(const bContext *C)
void ED_annotation_draw_view2d(const bContext *C, bool onlyv2d)
#define U
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
constexpr int64_t first() const
constexpr int64_t last(const int64_t n=0) const
void add_quad(float x1, float y1, float x2, float y2, const uchar color[4])
void add_line(float x1, float y1, float x2, float y2, const uchar color[4])
void add_wire_quad(float x1, float y1, float x2, float y2, const uchar color[4])
#define SELECT
#define sinf(x)
#define cosf(x)
uint pos
struct @242053044010324116347033273112253060004051364061::@373043131300025057314200265134167265161140142363 attr_id
uint col
TEX_TEMPLATE DataVec texture(T, FltCoord, float=0.0f) RET
uint tex_coord
BLI_INLINE float fb(float length, float L)
format
ccl_device_inline float2 mask(const MaskType mask, const float2 a)
#define G(x, y, z)
static bool sequencer_calc_scopes(const SpaceSeq &space_sequencer, const ColorManagedViewSettings &view_settings, const ColorManagedDisplaySettings &display_settings, const ImBuf &ibuf, const int timeline_frame)
blender::IndexRange strip_text_selection_range_get(const TextVars *data)
static Strip * special_seq_update
ImBuf * make_waveform_view_from_ibuf(const ImBuf *ibuf)
static void preview_draw_texture_to_linear(GPUTexture &texture, const char *texture_colorspace_name, const bool predivide, const rctf &position, const rctf &texture_coord)
static void sequencer_draw_scopes(const SpaceSeq &space_sequencer, ARegion &region)
ImBuf * make_vectorscope_view_from_ibuf(const ImBuf *ibuf)
static void preview_draw_end(const bContext *C)
static void preview_draw_color_render_begin(ARegion &region)
static void text_selection_draw(const bContext *C, const Strip *strip, uint pos)
static void draw_cursor_2d(const ARegion *region, const blender::float2 &cursor)
static void text_edit_draw_box(const bContext *C, const Strip *strip, uint pos)
static void sequencer_preview_clear()
bool sequencer_text_editing_active_poll(bContext *C)
static void preview_draw_overlay_begin(ARegion &region)
static GPUTexture * create_texture(const ImBuf &ibuf)
static rctf preview_get_reference_position(const SpaceSeq &space_sequencer, const Editing &editing, const ARegion &region)
static void text_edit_draw(const bContext *C)
static void draw_registered_callbacks(const bContext *C, ARegion &region)
static rctf preview_get_full_position(const ARegion &region)
static void sequencer_preview_draw_empty(ARegion &region)
static bool preview_draw_begin(const bContext *C, const RenderData &render_data, const ColorManagedViewSettings &view_settings, const ColorManagedDisplaySettings &display_settings, ARegion &region)
static rctf preview_get_full_texture_coord()
static void preview_draw_texture_simple(GPUTexture &texture, const rctf &position, const rctf &texture_coord)
void sequencer_preview_region_draw(const bContext *C, ARegion *region)
static void sequencer_preview_draw_overlays(const bContext *C, const wmWindowManager &wm, const Scene *scene, const SpaceSeq &space_sequencer, const Editing &editing, const ColorManagedViewSettings &view_settings, const ColorManagedDisplaySettings &display_settings, ARegion &region, GPUTexture *current_texture, GPUTexture *reference_texture, const ImBuf *overlay_ibuf, const int timeline_frame)
static void draw_histogram(ARegion &region, const ScopeHistogram &hist, SeqQuadsBatch &quads, const rctf &area)
static void draw_waveform_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
ImBuf * make_sep_waveform_view_from_ibuf(const ImBuf *ibuf)
bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene)
ImBuf * make_zebra_view_from_ibuf(const ImBuf *ibuf, float perc)
static void preview_draw_all_image_overlays(const bContext *C, const Scene *scene, const Editing &editing, const int timeline_frame)
static void draw_vectorscope_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
static rctf preview_get_reference_texture_coord(const SpaceSeq &space_sequencer, const Editing &editing)
static void text_edit_draw_cursor(const bContext *C, const Strip *strip, uint pos)
Strip * strip_under_mouse_get(const Scene *scene, const View2D *v2d, const int mval[2])
static ImBuf * sequencer_make_scope(const ColorManagedViewSettings &view_settings, const ColorManagedDisplaySettings &display_settings, const ImBuf &ibuf, ImBuf *(*make_scope_fn)(const ImBuf *ibuf))
bool sequencer_view_preview_only_poll(const bContext *C)
void sequencer_special_update_set(Strip *strip)
void special_preview_set(bContext *C, const int mval[2])
static void sequencer_draw_borders_overlay(const SpaceSeq &sseq, const View2D &v2d, const Scene *scene)
static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
bool check_show_imbuf(const SpaceSeq &sseq)
static void sequencer_draw_gpencil_overlay(const bContext *C)
blender::int2 strip_text_cursor_offset_to_position(const TextVarsRuntime *text, int cursor_offset)
int sequencer_draw_get_transform_preview_frame(const Scene *scene)
static void sequencer_preview_draw_color_render(const SpaceSeq &space_sequencer, const Editing &editing, ARegion &region, const ImBuf *current_ibuf, GPUTexture *current_texture, const ImBuf *reference_ibuf, GPUTexture *reference_texture)
static blender::float2 coords_region_view_align(const View2D *v2d, const blender::float2 coords)
static int get_reference_frame_offset(const Editing &editing, const RenderData &render_data)
ImBuf * sequencer_ibuf_get(const bContext *C, int timeline_frame, const char *viewname)
static blender::float2 rgb_to_uv_scaled(const blender::float3 &rgb)
static void strip_draw_image_origin_and_outline(const bContext *C, Strip *strip, bool is_active_seq)
static const char * get_texture_colorspace_name(const ImBuf &ibuf)
static void sequencer_display_size(const RenderData &render_data, float r_viewrect[2])
static bool is_cursor_visible(const SpaceSeq &sseq)
VecBase< T, 3 > transform_point(const CartesianBasis &basis, const VecBase< T, 3 > &v)
void render_new_render_data(Main *bmain, Depsgraph *depsgraph, Scene *scene, int rectx, int recty, int preview_render_size, int for_render, RenderData *r_context)
Definition render.cc:205
int time_right_handle_frame_get(const Scene *scene, const Strip *strip)
Array< float2 > image_transform_final_quad_get(const Scene *scene, const Strip *strip)
ImBuf * render_give_ibuf(const RenderData *context, float timeline_frame, int chanshown)
Definition render.cc:2002
ListBase * channels_displayed_get(const Editing *ed)
Definition channels.cc:28
bool prefetch_need_redraw(const bContext *C, Scene *scene)
Definition prefetch.cc:599
float3x3 image_transform_matrix_get(const Scene *scene, const Strip *strip)
double rendersize_to_scale_factor(int render_size)
Definition proxy.cc:87
int time_left_handle_frame_get(const Scene *, const Strip *strip)
Strip * select_active_get(const Scene *scene)
bool effects_can_render_text(const Strip *strip)
float2 image_transform_origin_offset_pixelspace_get(const Scene *scene, const Strip *strip)
VectorSet< Strip * > query_rendered_strips(const Scene *scene, ListBase *channels, ListBase *seqbase, const int timeline_frame, const int displayed_channel)
Definition iterator.cc:205
float2 image_preview_unit_to_px(const Scene *scene, const float2 co_src)
ImBuf * render_give_ibuf_direct(const RenderData *context, float timeline_frame, Strip *strip)
Definition render.cc:2082
blender::VecBase< uint8_t, 4 > uchar4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
MatBase< float, 4, 2 > float4x2
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
ARegionRuntimeHandle * runtime
ListBase * seqbasep
rctf overlay_frame_rect
const ColorSpace * colorspace
const ColorSpace * colorspace
ImBufFloatBuffer float_buffer
ImBufByteBuffer byte_buffer
void * first
float dither_intensity
ColorManagedViewSettings view_settings
struct Editing * ed
struct RenderData r
struct DisplaySafeAreas safe_areas
ColorManagedDisplaySettings display_settings
ListBase spacedata
char overlay_frame_type
float cursor[2]
struct bGPdata * gpd
short render_size
SpaceSeq_Runtime * runtime
struct SequencerPreviewOverlay preview_overlay
void * effectdata
struct wmTimer * animtimer
static constexpr float FLOAT_VAL_MAX
static constexpr float FLOAT_VAL_MIN
void calc_from_ibuf(const ImBuf *ibuf)
static constexpr float VECSCOPE_V_SCALE
static constexpr float VECSCOPE_U_SCALE
Vector< CharInfo > characters
float xmax
float xmin
float ymax
float ymin
int ymax
int xmin
int xmax
i
Definition text_draw.cc:230
GPUViewport * WM_draw_region_get_bound_viewport(ARegion *region)
Definition wm_draw.cc:922
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_gizmomap_draw(wmGizmoMap *gzmap, const bContext *C, const eWM_GizmoFlagMapDrawStep drawstep)
void WM_jobs_kill_type(wmWindowManager *wm, const void *owner, int job_type)
Definition wm_jobs.cc:598