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 if (!seq::editing_get(scene)) {
96 return;
97 }
98
99 ARegion *region = CTX_wm_region(C);
100 Strip *strip = strip_under_mouse_get(scene, &region->v2d, mval);
101 if (strip != nullptr && strip->type != STRIP_TYPE_SOUND_RAM) {
103 }
104}
105
110
111ImBuf *sequencer_ibuf_get(const bContext *C, const int timeline_frame, const char *viewname)
112{
113 Main *bmain = CTX_data_main(C);
114 ARegion *region = CTX_wm_region(C);
116 Scene *scene = CTX_data_scene(C);
117 SpaceSeq *sseq = CTX_wm_space_seq(C);
118 bScreen *screen = CTX_wm_screen(C);
119
120 seq::RenderData context = {nullptr};
121 ImBuf *ibuf;
122 int rectx, recty;
123 double render_size;
124 short is_break = G.is_break;
125
126 if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
127 return nullptr;
128 }
129
130 if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
131 render_size = scene->r.size / 100.0;
132 }
133 else {
134 render_size = seq::rendersize_to_scale_factor(sseq->render_size);
135 }
136
137 rectx = roundf(render_size * scene->r.xsch);
138 recty = roundf(render_size * scene->r.ysch);
139
141 bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
142 context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
143 context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
144 context.is_playing = screen->animtimer != nullptr;
145 context.is_scrubbing = screen->scrubbing;
146
147 /* Sequencer could start rendering, in this case we need to be sure it wouldn't be
148 * canceled by Escape pressed somewhere in the past. */
149 G.is_break = false;
150
152 GPUFrameBuffer *fb = GPU_framebuffer_active_get();
153 if (viewport) {
154 /* Unbind viewport to release the DRW context. */
155 GPU_viewport_unbind(viewport);
156 }
157 else {
158 /* Rendering can change OGL context. Save & Restore frame-buffer. */
160 }
161
162 if (special_preview_get()) {
163 ibuf = seq::render_give_ibuf_direct(&context, timeline_frame, special_preview_get());
164 }
165 else {
166 ibuf = seq::render_give_ibuf(&context, timeline_frame, sseq->chanshown);
167 }
168
169 if (viewport) {
170 /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
171 * viewport. */
172 int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
173 GPU_viewport_bind(viewport, view, &region->winrct);
174 }
175 else if (fb) {
177 }
178
179 /* Restore state so real rendering would be canceled if needed. */
180 G.is_break = is_break;
181
182 return ibuf;
183}
184
186 const ColorManagedDisplaySettings &display_settings,
187 const ImBuf &ibuf,
188 ImBuf *(*make_scope_fn)(const ImBuf *ibuf))
189{
190 ImBuf *display_ibuf = IMB_dupImBuf(&ibuf);
191 ImBuf *scope;
192
193 IMB_colormanagement_imbuf_make_display_space(display_ibuf, &view_settings, &display_settings);
194
195 scope = make_scope_fn(display_ibuf);
196
197 IMB_freeImBuf(display_ibuf);
198
199 return scope;
200}
201
202static void sequencer_display_size(const RenderData &render_data, float r_viewrect[2])
203{
204 r_viewrect[0] = float(render_data.xsch);
205 r_viewrect[1] = float(render_data.ysch);
206
207 r_viewrect[0] *= render_data.xasp / render_data.yasp;
208}
209
211{
212 /* Draw grease-pencil (image aligned). */
214
215 /* Orthographic at pixel level. */
217
218 /* Draw grease-pencil (screen aligned). */
220}
221
226 const View2D &v2d,
227 const Scene *scene)
228{
229 const float x1 = v2d.tot.xmin;
230 const float y1 = v2d.tot.ymin;
231 const float x2 = v2d.tot.xmax;
232 const float y2 = v2d.tot.ymax;
233
234 GPU_line_width(1.0f);
235
236 /* Draw border. */
237 const uint shdr_pos = GPU_vertformat_attr_add(
239
241
242 float viewport_size[4];
243 GPU_viewport_size_get_f(viewport_size);
244 immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
245
247 immUniform1i("colors_len", 0); /* Simple dashes. */
248 immUniform1f("dash_width", 6.0f);
249 immUniform1f("udash_factor", 0.5f);
250
251 imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
252
253 /* Draw safety border. */
256 rctf rect;
257 rect.xmin = x1;
258 rect.xmax = x2;
259 rect.ymin = y1;
260 rect.ymax = y2;
261 UI_draw_safe_areas(shdr_pos, &rect, scene->safe_areas.title, scene->safe_areas.action);
262
264
266 shdr_pos, &rect, scene->safe_areas.title_center, scene->safe_areas.action_center);
267 }
268 }
269
271}
272
273#if 0
274void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
275{
276 /* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
277 * For now just disable drawing since the strip frame will likely be offset. */
278
279 // if (sc->mode == SC_MODE_MASKEDIT)
280 if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
281 Mask *mask = SEQ_active_mask_get(scene);
282
283 if (mask) {
284 int width, height;
285 float aspx = 1.0f, aspy = 1.0f;
286 // ED_mask_get_size(C, &width, &height);
287
288 // Scene *scene = CTX_data_scene(C);
289 BKE_render_resolution(&scene->r, false, &width, &height);
290
292 region,
293 0,
294 0,
295 0, /* TODO */
296 width,
297 height,
298 aspx,
299 aspy,
300 false,
301 true,
302 nullptr,
303 C);
304 }
305 }
306}
307#endif
308
309/* Force redraw, when prefetching and using cache view. */
310static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
311{
312 if (seq::prefetch_need_redraw(C, scene)) {
314 }
315}
316
317static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
318{
319 if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
320 /* Stop all running jobs, except screen one. Currently previews frustrate Render.
321 * Need to make so sequencers rendering doesn't conflict with compositor. */
323
324 /* In case of final rendering used for preview, kill all previews,
325 * otherwise threading conflict will happen in rendering module. */
327 }
328}
329
334
335/* Semantic utility to get a rectangle with positions that correspond to a full frame drawn in the
336 * preview region. */
338{
339 return region.v2d.tot;
340}
341
342/* Semantic utility to generate rectangle with UV coordinates that cover an entire 0 .. 1
343 * rectangle. */
345{
346 rctf texture_coord;
347 BLI_rctf_init(&texture_coord, 0.0f, 1.0f, 0.0f, 1.0f);
348 return texture_coord;
349}
350
351/* Get rectangle positions within preview region that are to be used to draw reference frame.
352 *
353 * If the frame overlay is set to RECTANGLE this function returns coordinates of the rectangle
354 * where partial reference frame is to be drawn.
355 *
356 * If the frame overlay is set to REFERENCE this function returns full-frame rectangle, same as
357 * preview_get_full_position().
358 *
359 * If the frame overlay is set to REFERENCE or is disabled the return value is valid but
360 * corresponds to an undefined state.
361 */
362static rctf preview_get_reference_position(const SpaceSeq &space_sequencer,
363 const Editing &editing,
364 const ARegion &region)
365{
366 const View2D &v2d = region.v2d;
367
368 BLI_assert(ELEM(space_sequencer.overlay_frame_type,
371
372 if (space_sequencer.overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT) {
373 rctf position;
374 const float xmin = v2d.tot.xmin;
375 const float ymin = v2d.tot.ymin;
376
377 const float width = BLI_rctf_size_x(&v2d.tot);
378 const float height = BLI_rctf_size_y(&v2d.tot);
379
380 position.xmax = xmin + width * editing.overlay_frame_rect.xmax;
381 position.xmin = xmin + width * editing.overlay_frame_rect.xmin;
382 position.ymax = ymin + height * editing.overlay_frame_rect.ymax;
383 position.ymin = ymin + height * editing.overlay_frame_rect.ymin;
384
385 return position;
386 }
387
388 return v2d.tot;
389}
390
391/* Return rectangle with UV coordinates that are to be used to draw reference frame.
392 *
393 * If the frame overlay is set to rectangle the return value contains vUV coordinates of the
394 * rectangle within the reference frame.
395 *
396 * If the frame overlay is set to REFERENCE this function returns full-frame UV rectangle, same as
397 * preview_get_full_texture_coord().
398 *
399 * If the frame overlay is set to REFERENCE or is disabled the return value is valid but
400 * corresponds to an undefined state.
401 */
403 const Editing &editing)
404{
405 if (space_sequencer.overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT) {
406 return editing.overlay_frame_rect;
407 }
408
409 rctf texture_coord;
410 BLI_rctf_init(&texture_coord, 0.0f, 1.0f, 0.0f, 1.0f);
411
412 return texture_coord;
413}
414
415static void draw_histogram(ARegion &region,
416 const ScopeHistogram &hist,
417 SeqQuadsBatch &quads,
418 const rctf &area)
419{
420 if (hist.data.is_empty()) {
421 return;
422 }
423
424 /* Grid lines and labels. */
425 uchar col_grid[4] = {128, 128, 128, 128};
426 float grid_x_0 = area.xmin;
427 float grid_x_1 = area.xmax;
428 /* Float histograms show more than 0..1 range horizontally. */
429 if (hist.is_float_hist()) {
432 grid_x_0 = area.xmin + (area.xmax - area.xmin) * ratio_0;
433 grid_x_1 = area.xmin + (area.xmax - area.xmin) * ratio_1;
434 }
435
436 View2D &v2d = region.v2d;
437 float text_scale_x, text_scale_y;
438 UI_view2d_scale_get_inverse(&v2d, &text_scale_x, &text_scale_y);
439
440 for (int line = 0; line <= 4; line++) {
441 float val = float(line) / 4;
442 float x = grid_x_0 + (grid_x_1 - grid_x_0) * val;
443 quads.add_line(x, area.ymin, x, area.ymax, col_grid);
444
445 /* Label. */
446 char buf[10];
447 const size_t buf_len = SNPRINTF_RLEN(buf, "%.2f", val);
448
449 float text_width, text_height;
450 BLF_width_and_height(BLF_default(), buf, buf_len, &text_width, &text_height);
451 text_width *= text_scale_x;
452 text_height *= text_scale_y;
454 &v2d, x - text_width / 2, area.ymax - text_height * 1.3f, buf, buf_len, col_grid);
455 }
456
457 /* Border. */
458 uchar col_border[4] = {64, 64, 64, 128};
459 quads.add_wire_quad(area.xmin, area.ymin, area.xmax, area.ymax, col_border);
460
461 /* Histogram area & line for each R/G/B channels, additively blended. */
462 quads.draw();
464 for (int ch = 0; ch < 3; ++ch) {
465 if (hist.max_value[ch] == 0) {
466 continue;
467 }
468 uchar col_line[4] = {32, 32, 32, 255};
469 uchar col_area[4] = {64, 64, 64, 128};
470 col_line[ch] = 224;
471 col_area[ch] = 224;
472 float y_scale = (area.ymax - area.ymin) / hist.max_value[ch] * 0.95f;
473 float x_scale = (area.xmax - area.xmin) / hist.data.size();
474 float yb = area.ymin;
475 for (int bin = 0; bin < hist.data.size() - 1; bin++) {
476 float x0 = area.xmin + (bin + 0.5f) * x_scale;
477 float x1 = area.xmin + (bin + 1.5f) * x_scale;
478
479 float y0 = area.ymin + hist.data[bin][ch] * y_scale;
480 float y1 = area.ymin + hist.data[bin + 1][ch] * y_scale;
481 quads.add_quad(x0, yb, x0, y0, x1, yb, x1, y1, col_area);
482 quads.add_line(x0, y0, x1, y1, col_line);
483 }
484 }
485 quads.draw();
487
489}
490
492{
493 float y, u, v;
494 rgb_to_yuv(rgb.x, rgb.y, rgb.z, &y, &u, &v, BLI_YUV_ITU_BT709);
495 /* Scale to +-0.5 range. */
498 return blender::float2(u, v);
499}
500
501static void draw_waveform_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
502{
503 /* Horizontal lines at 10%, 70%, 90%. */
504 const float lines[3] = {0.1f, 0.7f, 0.9f};
505 uchar col_grid[4] = {160, 64, 64, 128};
506 const float x0 = area.xmin;
507 const float x1 = area.xmax;
508
509 for (int i = 0; i < 3; i++) {
510 const float y = area.ymin + (area.ymax - area.ymin) * lines[i];
511 char buf[10];
512 SNPRINTF(buf, "%.1f", lines[i]);
513 quads.add_line(x0, y, x1, y, col_grid);
514 UI_view2d_text_cache_add(&region->v2d, x0 + 8, y + 8, buf, strlen(buf), col_grid);
515 }
516 /* Border. */
517 uchar col_border[4] = {64, 64, 64, 128};
518 quads.add_wire_quad(x0, area.ymin, x1, area.ymax, col_border);
519
520 quads.draw();
522}
523
524static void draw_vectorscope_graticule(ARegion *region, SeqQuadsBatch &quads, const rctf &area)
525{
526 const float skin_rad = DEG2RADF(123.0f); /* angle in radians of the skin tone line */
527
528 const float w = BLI_rctf_size_x(&area);
529 const float h = BLI_rctf_size_y(&area);
530 const float2 center{BLI_rctf_cent_x(&area), BLI_rctf_cent_y(&area)};
531 const float radius = ((w < h) ? w : h) * 0.5f;
532
533 /* Precalculate circle points/colors. */
534 constexpr int circle_delta = 6;
535 constexpr int num_circle_points = 360 / circle_delta;
536 float2 circle_pos[num_circle_points];
537 float3 circle_col[num_circle_points];
538 for (int i = 0; i < num_circle_points; i++) {
539 float a = DEG2RADF(i * circle_delta);
540 float x = cosf(a);
541 float y = sinf(a);
542 circle_pos[i] = float2(x, y);
543 float u = x / SeqScopes::VECSCOPE_U_SCALE;
545
546 float3 col;
547 yuv_to_rgb(0.5f, u, v, &col.x, &col.y, &col.z, BLI_YUV_ITU_BT709);
548 circle_col[i] = col;
549 }
550
551 /* Draw colored background and outer ring, additively blended
552 * since vectorscope image is already drawn. */
554
555 constexpr float alpha_f = 0.8f;
556 constexpr uchar alpha_b = uchar(alpha_f * 255.0f);
557 const uchar4 col_center(50, 50, 50, alpha_b);
558
559 uchar4 col1(0, 0, 0, alpha_b);
560 uchar4 col2(0, 0, 0, alpha_b);
561 uchar4 col3(0, 0, 0, alpha_b);
562
563 /* Background: since the quads batch utility draws quads, draw two
564 * segments of the circle (two triangles) in one iteration. */
565 constexpr float mul_background = 0.2f;
566 for (int i = 0; i < num_circle_points; i += 2) {
567 int idx1 = i;
568 int idx2 = (i + 1) % num_circle_points;
569 int idx3 = (i + 2) % num_circle_points;
570 float2 pt1 = center + circle_pos[idx1] * radius;
571 float2 pt2 = center + circle_pos[idx2] * radius;
572 float2 pt3 = center + circle_pos[idx3] * radius;
573 float3 rgb1 = circle_col[idx1] * mul_background;
574 float3 rgb2 = circle_col[idx2] * mul_background;
575 float3 rgb3 = circle_col[idx3] * mul_background;
576 rgb_float_to_uchar(col1, rgb1);
577 rgb_float_to_uchar(col2, rgb2);
578 rgb_float_to_uchar(col3, rgb3);
579 quads.add_quad(pt1.x,
580 pt1.y,
581 pt2.x,
582 pt2.y,
583 center.x,
584 center.y,
585 pt3.x,
586 pt3.y,
587 col1,
588 col2,
589 col_center,
590 col3);
591 }
592
593 /* Outer ring. */
594 const float outer_radius = radius * 1.02f;
595 for (int i = 0; i < num_circle_points; i++) {
596 int idx1 = i;
597 int idx2 = (i + 1) % num_circle_points;
598 float2 pt1a = center + circle_pos[idx1] * radius;
599 float2 pt2a = center + circle_pos[idx2] * radius;
600 float2 pt1b = center + circle_pos[idx1] * outer_radius;
601 float2 pt2b = center + circle_pos[idx2] * outer_radius;
602 float3 rgb1 = circle_col[idx1];
603 float3 rgb2 = circle_col[idx2];
604 rgb_float_to_uchar(col1, rgb1);
605 rgb_float_to_uchar(col2, rgb2);
606 quads.add_quad(
607 pt1a.x, pt1a.y, pt1b.x, pt1b.y, pt2a.x, pt2a.y, pt2b.x, pt2b.y, col1, col1, col2, col2);
608 }
609
610 quads.draw();
611
612 /* Draw grid and other labels using regular alpha blending. */
614 const uchar4 col_grid(128, 128, 128, 128);
615
616 /* Cross. */
617 quads.add_line(center.x - radius, center.y, center.x + radius, center.y, col_grid);
618 quads.add_line(center.x, center.y - radius, center.x, center.y + radius, col_grid);
619
620 /* Inner circles. */
621 for (int j = 1; j < 5; j++) {
622 float r = radius * j * 0.2f;
623 for (int i = 0; i < num_circle_points; i++) {
624 int idx1 = i;
625 int idx2 = (i + 1) % num_circle_points;
626 float2 pt1 = center + circle_pos[idx1] * r;
627 float2 pt2 = center + circle_pos[idx2] * r;
628 quads.add_line(pt1.x, pt1.y, pt2.x, pt2.y, col_grid);
629 }
630 }
631
632 /* "Safe" (0.75 saturation) primary color locations and labels. */
633 const float3 primaries[6] = {
634 {1, 0, 0},
635 {1, 1, 0},
636 {0, 1, 0},
637 {0, 1, 1},
638 {0, 0, 1},
639 {1, 0, 1},
640 };
641 const char *names = "RYGCBM";
642
643 /* Calculate size of single text letter. */
644 char buf[2] = {'M', 0};
645 float text_scale_x, text_scale_y;
646 UI_view2d_scale_get_inverse(&region->v2d, &text_scale_x, &text_scale_y);
647 float text_width, text_height;
648 BLF_width_and_height(BLF_default(), buf, 1, &text_width, &text_height);
649 text_width *= text_scale_x;
650 text_height *= text_scale_y;
651
652 const uchar4 col_target(128, 128, 128, 192);
653 const float delta = radius * 0.01f;
654 for (int i = 0; i < 6; i++) {
655 float3 safe = primaries[i] * 0.75f;
656 float2 pos = center + rgb_to_uv_scaled(safe) * (radius * 2);
657 quads.add_wire_quad(pos.x - delta, pos.y - delta, pos.x + delta, pos.y + delta, col_target);
658
659 buf[0] = names[i];
661 pos.x + delta * 1.2f + text_width / 4,
662 pos.y - text_height / 2,
663 buf,
664 1,
665 col_target);
666 }
667
668 /* Skin tone line. */
669 const uchar4 col_tone(255, 102, 0, 128);
670 quads.add_line(center.x,
671 center.y,
672 center.x + cosf(skin_rad) * radius,
673 center.y + sinf(skin_rad) * radius,
674 col_tone);
675
676 quads.draw();
678}
679
680static void sequencer_draw_scopes(const SpaceSeq &space_sequencer, ARegion &region)
681{
682 /* Figure out draw coordinates. */
683 const rctf preview = preview_get_full_position(region);
684
685 rctf uv;
686 BLI_rctf_init(&uv, 0.0f, 1.0f, 0.0f, 1.0f);
687 const bool keep_aspect = space_sequencer.mainb == SEQ_DRAW_IMG_VECTORSCOPE;
688 float vecscope_aspect = 1.0f;
689 if (keep_aspect) {
690 float width = std::max(BLI_rctf_size_x(&preview), 0.1f);
691 float height = std::max(BLI_rctf_size_y(&preview), 0.1f);
692 vecscope_aspect = width / height;
693 if (vecscope_aspect >= 1.0f) {
694 BLI_rctf_resize_x(&uv, vecscope_aspect);
695 }
696 else {
697 BLI_rctf_resize_y(&uv, 1.0f / vecscope_aspect);
698 }
699 }
700
701 SeqQuadsBatch quads;
702 const SeqScopes *scopes = &space_sequencer.runtime->scopes;
703
704 bool use_blend = space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF &&
705 space_sequencer.flag & SEQ_USE_ALPHA;
706
707 /* Draw black rectangle over scopes area. */
708 if (space_sequencer.mainb != SEQ_DRAW_IMG_IMBUF) {
711 uchar black[4] = {0, 0, 0, 255};
713 immUniformColor4ubv(black);
714 immRectf(pos, preview.xmin, preview.ymin, preview.xmax, preview.ymax);
716 }
717
718 /* Draw scope image if there is one. */
719 ImBuf *scope_image = nullptr;
720 if (space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF) {
721 scope_image = scopes->zebra_ibuf;
722 }
723 else if (space_sequencer.mainb == SEQ_DRAW_IMG_WAVEFORM) {
724 scope_image = scopes->waveform_ibuf;
725 }
726 else if (space_sequencer.mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
727 scope_image = scopes->vector_ibuf;
728 }
729 else if (space_sequencer.mainb == SEQ_DRAW_IMG_RGBPARADE) {
730 scope_image = scopes->sep_waveform_ibuf;
731 }
732
733 if (use_blend) {
735 }
736
737 if (scope_image != nullptr) {
738 if (scope_image->float_buffer.data && scope_image->byte_buffer.data == nullptr) {
739 IMB_byte_from_float(scope_image);
740 }
741
745 GPUTexture *texture = GPU_texture_create_2d(
746 "seq_display_buf", scope_image->x, scope_image->y, 1, format, usage, nullptr);
750
752
753 GPUVertFormat *imm_format = immVertexFormat();
755 uint texCoord = GPU_vertformat_attr_add(
756 imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
758 immUniformColor3f(1.0f, 1.0f, 1.0f);
759
761
762 immAttr2f(texCoord, uv.xmin, uv.ymin);
763 immVertex2f(pos, preview.xmin, preview.ymin);
764
765 immAttr2f(texCoord, uv.xmin, uv.ymax);
766 immVertex2f(pos, preview.xmin, preview.ymax);
767
768 immAttr2f(texCoord, uv.xmax, uv.ymax);
769 immVertex2f(pos, preview.xmax, preview.ymax);
770
771 immAttr2f(texCoord, uv.xmax, uv.ymin);
772 immVertex2f(pos, preview.xmax, preview.ymin);
773
774 immEnd();
775
778
780 }
781
782 if (space_sequencer.mainb == SEQ_DRAW_IMG_HISTOGRAM) {
783 draw_histogram(region, scopes->histogram, quads, preview);
784 }
786 use_blend = true;
787 draw_waveform_graticule(&region, quads, preview);
788 }
789 if (space_sequencer.mainb == SEQ_DRAW_IMG_VECTORSCOPE) {
790 use_blend = true;
791 draw_vectorscope_graticule(&region, quads, preview);
792 }
793
794 quads.draw();
795
796 if (use_blend) {
798 }
799}
800
801static bool sequencer_calc_scopes(const SpaceSeq &space_sequencer,
802 const ColorManagedViewSettings &view_settings,
803 const ColorManagedDisplaySettings &display_settings,
804 const ImBuf &ibuf,
805 const int timeline_frame)
806
807{
808 if (space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF && space_sequencer.zebra == 0) {
809 return false; /* Not drawing any scopes. */
810 }
811
812 SeqScopes *scopes = &space_sequencer.runtime->scopes;
813 if (scopes->reference_ibuf != &ibuf || scopes->timeline_frame != timeline_frame) {
814 scopes->cleanup();
815 }
816
817 switch (space_sequencer.mainb) {
819 if (!scopes->zebra_ibuf) {
820 if (ibuf.float_buffer.data) {
821 ImBuf *display_ibuf = IMB_dupImBuf(&ibuf);
823 display_ibuf, &view_settings, &display_settings);
824 scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, space_sequencer.zebra);
825 IMB_freeImBuf(display_ibuf);
826 }
827 else {
828 scopes->zebra_ibuf = make_zebra_view_from_ibuf(&ibuf, space_sequencer.zebra);
829 }
830 }
831 break;
833 if (!scopes->waveform_ibuf) {
835 view_settings, display_settings, ibuf, make_waveform_view_from_ibuf);
836 }
837 break;
839 if (!scopes->vector_ibuf) {
841 view_settings, display_settings, ibuf, make_vectorscope_view_from_ibuf);
842 }
843 break;
845 ImBuf *display_ibuf = IMB_dupImBuf(&ibuf);
847 display_ibuf, &view_settings, &display_settings);
848 scopes->histogram.calc_from_ibuf(display_ibuf);
849 IMB_freeImBuf(display_ibuf);
850 } break;
852 if (!scopes->sep_waveform_ibuf) {
854 view_settings, display_settings, ibuf, make_sep_waveform_view_from_ibuf);
855 }
856 break;
857 default: /* Future files might have scopes we don't know about. */
858 return false;
859 }
860 scopes->reference_ibuf = &ibuf;
861 return true;
862}
863
864static bool sequencer_draw_get_transform_preview(const SpaceSeq &sseq, const Scene &scene)
865{
866 Strip *last_seq = seq::select_active_get(&scene);
867 if (last_seq == nullptr) {
868 return false;
869 }
870
871 return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
872 ((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
874}
875
877{
878 Strip *last_seq = seq::select_active_get(scene);
879 /* #sequencer_draw_get_transform_preview must already have been called. */
880 BLI_assert(last_seq != nullptr);
881 int preview_frame;
882
883 if (last_seq->flag & SEQ_RIGHTSEL) {
884 preview_frame = seq::time_right_handle_frame_get(scene, last_seq) - 1;
885 }
886 else {
887 preview_frame = seq::time_left_handle_frame_get(scene, last_seq);
888 }
889
890 return preview_frame;
891}
892
894 Strip *strip,
895 bool is_active_seq)
896{
897 SpaceSeq *sseq = CTX_wm_space_seq(C);
898 const ARegion *region = CTX_wm_region(C);
900 return;
901 }
902 if ((strip->flag & SELECT) == 0) {
903 return;
904 }
906 return;
907 }
908 if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
910 {
911 return;
912 }
913 if (ELEM(sseq->mainb,
918 {
919 return;
920 }
921
923 CTX_data_scene(C), strip);
924
925 /* Origin. */
929 immUniform1f("outlineWidth", 1.5f);
930 immUniformColor3f(1.0f, 1.0f, 1.0f);
931 immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
932 immUniform1f("size", 15.0f * U.pixelsize);
934 immVertex2f(pos, origin[0], origin[1]);
935 immEnd();
937
938 /* Outline. */
940 CTX_data_scene(C), strip);
941
942 GPU_line_smooth(true);
946
947 float col[3];
948 if (is_active_seq) {
950 }
951 else {
953 }
955 immUniform1f("lineWidth", U.pixelsize);
957 immVertex2f(pos, strip_image_quad[0].x, strip_image_quad[0].y);
958 immVertex2f(pos, strip_image_quad[1].x, strip_image_quad[1].y);
959 immVertex2f(pos, strip_image_quad[2].x, strip_image_quad[2].y);
960 immVertex2f(pos, strip_image_quad[3].x, strip_image_quad[3].y);
961 immEnd();
965 GPU_line_smooth(false);
966}
967
968static void text_selection_draw(const bContext *C, const Strip *strip, uint pos)
969{
970 const TextVars *data = static_cast<TextVars *>(strip->effectdata);
971 const TextVarsRuntime *text = data->runtime;
972 const Scene *scene = CTX_data_scene(C);
973
974 if (data->selection_start_offset == -1 || strip_text_selection_range_get(data).is_empty()) {
975 return;
976 }
977
980 sel_range.first());
981 const blender::int2 selection_end = strip_text_cursor_offset_to_position(text, sel_range.last());
982 const int line_start = selection_start.y;
983 const int line_end = selection_end.y;
984
985 for (int line_index = line_start; line_index <= line_end; line_index++) {
986 const blender::seq::LineInfo line = text->lines[line_index];
987 blender::seq::CharInfo character_start = line.characters.first();
988 blender::seq::CharInfo character_end = line.characters.last();
989
990 if (line_index == selection_start.y) {
991 character_start = line.characters[selection_start.x];
992 }
993 if (line_index == selection_end.y) {
994 character_end = line.characters[selection_end.x];
995 }
996
997 const float line_y = character_start.position.y + text->font_descender;
998
999 const blender::float2 view_offs{-scene->r.xsch / 2.0f, -scene->r.ysch / 2.0f};
1000 const float view_aspect = scene->r.xasp / scene->r.yasp;
1001 blender::float3x3 transform_mat = seq::image_transform_matrix_get(scene, strip);
1002 blender::float4x2 selection_quad{
1003 {character_start.position.x, line_y},
1004 {character_start.position.x, line_y + text->line_height},
1005 {character_end.position.x + character_end.advance_x, line_y + text->line_height},
1006 {character_end.position.x + character_end.advance_x, line_y},
1007 };
1008
1011
1012 for (int i : blender::IndexRange(0, 4)) {
1013 selection_quad[i] += view_offs;
1014 selection_quad[i] = blender::math::transform_point(transform_mat, selection_quad[i]);
1015 selection_quad[i].x *= view_aspect;
1016 }
1017 for (int i : blender::Vector<int>{0, 1, 2, 2, 3, 0}) {
1018 immVertex2f(pos, selection_quad[i][0], selection_quad[i][1]);
1019 }
1020
1021 immEnd();
1022 }
1023}
1024
1026{
1027 blender::int2 coords_view;
1028 UI_view2d_view_to_region(v2d, coords.x, coords.y, &coords_view.x, &coords_view.y);
1029 coords_view.x = std::round(coords_view.x);
1030 coords_view.y = std::round(coords_view.y);
1031 blender::float2 coords_region_aligned;
1033 v2d, coords_view.x, coords_view.y, &coords_region_aligned.x, &coords_region_aligned.y);
1034 return coords_region_aligned;
1035}
1036
1037static void text_edit_draw_cursor(const bContext *C, const Strip *strip, uint pos)
1038{
1039 const TextVars *data = static_cast<TextVars *>(strip->effectdata);
1040 const TextVarsRuntime *text = data->runtime;
1041 const Scene *scene = CTX_data_scene(C);
1042
1043 const blender::float2 view_offs{-scene->r.xsch / 2.0f, -scene->r.ysch / 2.0f};
1044 const float view_aspect = scene->r.xasp / scene->r.yasp;
1045 blender::float3x3 transform_mat = seq::image_transform_matrix_get(scene, strip);
1047 data->cursor_offset);
1048 const float cursor_width = 10;
1049 blender::float2 cursor_coords =
1050 text->lines[cursor_position.y].characters[cursor_position.x].position;
1051 /* Clamp cursor coords to be inside of text boundbox. Compensate for cursor width, but also line
1052 * width hardcoded in shader. */
1053 rcti text_boundbox = text->text_boundbox;
1054 text_boundbox.xmax -= cursor_width + U.pixelsize;
1055 text_boundbox.xmin += U.pixelsize;
1056
1057 cursor_coords.x = std::clamp(
1058 cursor_coords.x, float(text_boundbox.xmin), float(text_boundbox.xmax));
1059 cursor_coords = coords_region_view_align(UI_view2d_fromcontext(C), cursor_coords);
1060
1061 blender::float4x2 cursor_quad{
1062 {cursor_coords.x, cursor_coords.y},
1063 {cursor_coords.x, cursor_coords.y + text->line_height},
1064 {cursor_coords.x + cursor_width, cursor_coords.y + text->line_height},
1065 {cursor_coords.x + cursor_width, cursor_coords.y},
1066 };
1067 const blender::float2 descender_offs{0.0f, float(text->font_descender)};
1068
1071
1072 for (int i : blender::IndexRange(0, 4)) {
1073 cursor_quad[i] += descender_offs + view_offs;
1074 cursor_quad[i] = blender::math::transform_point(transform_mat, cursor_quad[i]);
1075 cursor_quad[i].x *= view_aspect;
1076 }
1077 for (int i : blender::Vector<int>{0, 1, 2, 2, 3, 0}) {
1078 immVertex2f(pos, cursor_quad[i][0], cursor_quad[i][1]);
1079 }
1080
1081 immEnd();
1082}
1083
1084static void text_edit_draw_box(const bContext *C, const Strip *strip, uint pos)
1085{
1086 const TextVars *data = static_cast<TextVars *>(strip->effectdata);
1087 const TextVarsRuntime *text = data->runtime;
1088 const Scene *scene = CTX_data_scene(C);
1089
1090 const blender::float2 view_offs{-scene->r.xsch / 2.0f, -scene->r.ysch / 2.0f};
1091 const float view_aspect = scene->r.xasp / scene->r.yasp;
1093 blender::float4x2 box_quad{
1094 {float(text->text_boundbox.xmin), float(text->text_boundbox.ymin)},
1095 {float(text->text_boundbox.xmin), float(text->text_boundbox.ymax)},
1096 {float(text->text_boundbox.xmax), float(text->text_boundbox.ymax)},
1097 {float(text->text_boundbox.xmax), float(text->text_boundbox.ymin)},
1098 };
1099
1105 immUniform1f("lineWidth", U.pixelsize);
1106 immUniform1f("dash_width", 10.0f);
1108
1109 for (int i : blender::IndexRange(0, 4)) {
1110 box_quad[i] += view_offs;
1111 box_quad[i] = blender::math::transform_point(transform_mat, box_quad[i]);
1112 box_quad[i].x *= view_aspect;
1113 immVertex2f(pos, box_quad[i][0], box_quad[i][1]);
1114 }
1115
1116 immEnd();
1118}
1119
1120static void text_edit_draw(const bContext *C)
1121{
1122 if (!sequencer_text_editing_active_poll(const_cast<bContext *>(C))) {
1123 return;
1124 }
1126 if (!seq::effects_can_render_text(strip)) {
1127 return;
1128 }
1129
1132 GPU_line_smooth(true);
1135
1136 text_selection_draw(C, strip, pos);
1137 text_edit_draw_cursor(C, strip, pos);
1138
1141 GPU_line_smooth(false);
1142
1143 text_edit_draw_box(C, strip, pos);
1144}
1145
1146/* Draw empty preview region.
1147 * The entire region is cleared with the TH_SEQ_PREVIEW color.
1148 *
1149 * Used in cases when there is no editing, or when the display is set to NONE. */
1151{
1153 BLI_assert(viewport);
1154
1155 GPUFrameBuffer *overlay_fb = GPU_viewport_framebuffer_overlay_get(viewport);
1156 GPU_framebuffer_bind_no_srgb(overlay_fb);
1157
1159}
1160
1161/* Begin drawing the sequence preview region.
1162 * Initializes the drawing state which is common for color render and overlay drawing.
1163 *
1164 * Returns true if the region is to be drawn. Example is when it is not to be drawn is when there
1165 * is ongoing offline rendering (to avoid possible threading conflict).
1166 *
1167 * If the function returns true preview_draw_end() is to be called after drawing is done. */
1168static bool preview_draw_begin(const bContext *C,
1169 const RenderData &render_data,
1170 const ColorManagedViewSettings &view_settings,
1171 const ColorManagedDisplaySettings &display_settings,
1172 ARegion &region)
1173{
1175 if (G.is_rendering) {
1176 return false;
1177 }
1178
1180 BLI_assert(viewport);
1181
1182 /* Configure color space used by the viewport.
1183 * This also checks for HDR support and enables it for the viewport when found and needed. */
1185 viewport, &view_settings, &display_settings, render_data.dither_intensity);
1186
1188
1189 /* Setup view. */
1190 View2D &v2d = region.v2d;
1191 float viewrect[2];
1192 sequencer_display_size(render_data, viewrect);
1193 UI_view2d_totRect_set(&v2d, roundf(viewrect[0]), roundf(viewrect[1]));
1196
1197 return true;
1198}
1199
1205
1206/* Configure current GPU state to draw on the color render frame-buffer of the viewport. */
1208{
1210 BLI_assert(viewport);
1211
1212 GPUFrameBuffer *render_fb = GPU_viewport_framebuffer_render_get(viewport);
1213 GPU_framebuffer_bind(render_fb);
1214
1215 float col[4] = {0, 0, 0, 0};
1216 GPU_framebuffer_clear_color(render_fb, col);
1217}
1218
1219/* Configure current GPU state to draw on the overlay frame-buffer of the viewport. */
1221{
1223 BLI_assert(viewport);
1224
1225 GPUFrameBuffer *overlay_fb = GPU_viewport_framebuffer_overlay_get(viewport);
1226 GPU_framebuffer_bind_no_srgb(overlay_fb);
1227
1229}
1230
1231/* Draw the given texture on the currently bound frame-buffer without any changes to its pixels
1232 * colors.
1233 *
1234 * The position denotes coordinates of a rectangle used to display the texture.
1235 * The texture_coord contains UV coordinates of the input texture which are mapped to the corners
1236 * of the rectangle. */
1237static void preview_draw_texture_simple(GPUTexture &texture,
1238 const rctf &position,
1239 const rctf &texture_coord)
1240{
1241 GPUVertFormat *imm_format = immVertexFormat();
1242 const uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1244 imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1245
1247 immUniformColor3f(1.0f, 1.0f, 1.0f);
1248
1250
1251 immRectf_with_texco(pos, tex_coord, position, texture_coord);
1252
1255}
1256
1257/* Draw the given texture on the currently bound frame-buffer and convert its colors to linear
1258 * space in the fragment shader. This makes it suitable to be further processed by a GPUViewport
1259 *
1260 * The position denotes coordinates of a rectangle used to display the texture.
1261 * The texture_coord contains UV coordinates of the input texture which are mapped to the corners
1262 * of the rectangle. */
1264 const char *texture_colorspace_name,
1265 const bool predivide,
1266 const rctf &position,
1267 const rctf &texture_coord)
1268{
1269 GPUVertFormat *imm_format = immVertexFormat();
1270 const uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1272 imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1273
1274 if (!IMB_colormanagement_setup_glsl_draw_to_scene_linear(texture_colorspace_name, predivide)) {
1275 /* An error happened when configuring GPU side color space conversion. Return and allow the
1276 * view to be black, so that it is obvious something went wrong and that a bug report is to
1277 * be submitted.
1278 *
1279 * Note that fallback OCIO implementation is handled on a higher level. */
1280 return;
1281 }
1282
1284
1285 immRectf_with_texco(pos, tex_coord, position, texture_coord);
1286
1288
1290}
1291
1292/* Draw overlays for the currently displayed images in the preview. */
1294 const Scene *scene,
1295 const Editing &editing,
1296 const int timeline_frame)
1297{
1298 ListBase *channels = seq::channels_displayed_get(&editing);
1300 scene, channels, editing.seqbasep, timeline_frame, 0);
1301 Strip *active_seq = seq::select_active_get(scene);
1302 for (Strip *strip : strips) {
1303 /* TODO(sergey): Avoid having per-strip strip-independent checks. */
1304 strip_draw_image_origin_and_outline(C, strip, strip == active_seq);
1306 }
1307}
1308
1309static bool is_cursor_visible(const SpaceSeq &sseq)
1310{
1311 if (G.moving & G_TRANSFORM_CURSOR) {
1312 return true;
1313 }
1314
1315 if ((sseq.flag & SEQ_SHOW_OVERLAY) &&
1317 {
1318 return true;
1319 }
1320 return false;
1321}
1322
1326static void draw_cursor_2d(const ARegion *region, const blender::float2 &cursor)
1327{
1328 int co[2];
1329 UI_view2d_view_to_region(&region->v2d, cursor[0], cursor[1], &co[0], &co[1]);
1330
1331 /* Draw nice Anti Aliased cursor. */
1333
1334 /* Draw lines */
1335 float original_proj[4][4];
1336 GPU_matrix_projection_get(original_proj);
1338 ED_region_pixelspace(region);
1339 GPU_matrix_translate_2f(co[0] + 0.5f, co[1] + 0.5f);
1340 GPU_matrix_scale_2f(U.widget_unit, U.widget_unit);
1341
1342 float viewport[4];
1343 GPU_viewport_size_get_f(viewport);
1344
1346 struct {
1347 uint pos, col;
1348 } attr_id{};
1352 immUniform2fv("viewportSize", &viewport[2]);
1353 immUniform1f("lineWidth", U.pixelsize);
1354
1355 const float f5 = 0.25f;
1356 const float f10 = 0.5f;
1357 const float f20 = 1.0f;
1358
1359 const float red[3] = {1.0f, 0.0f, 0.0f};
1360 const float white[3] = {1.0f, 1.0f, 1.0f};
1361
1362 const int segments = 16;
1363 immBegin(GPU_PRIM_LINE_STRIP, segments + 1);
1364 for (int i = 0; i < segments + 1; i++) {
1365 float angle = float(2 * M_PI) * (float(i) / float(segments));
1366 float x = f10 * cosf(angle);
1367 float y = f10 * sinf(angle);
1368
1369 immAttr3fv(attr_id.col, (i % 2 == 0) ? red : white);
1370 immVertex2f(attr_id.pos, x, y);
1371 }
1372 immEnd();
1373
1374 float crosshair_color[3];
1375 UI_GetThemeColor3fv(TH_VIEW_OVERLAY, crosshair_color);
1376
1378 immAttr3fv(attr_id.col, crosshair_color);
1379 immVertex2f(attr_id.pos, -f20, 0);
1380 immAttr3fv(attr_id.col, crosshair_color);
1381 immVertex2f(attr_id.pos, -f5, 0);
1382
1383 immAttr3fv(attr_id.col, crosshair_color);
1384 immVertex2f(attr_id.pos, +f20, 0);
1385 immAttr3fv(attr_id.col, crosshair_color);
1386 immVertex2f(attr_id.pos, +f5, 0);
1387
1388 immAttr3fv(attr_id.col, crosshair_color);
1389 immVertex2f(attr_id.pos, 0, -f20);
1390 immAttr3fv(attr_id.col, crosshair_color);
1391 immVertex2f(attr_id.pos, 0, -f5);
1392
1393 immAttr3fv(attr_id.col, crosshair_color);
1394 immVertex2f(attr_id.pos, 0, +f20);
1395 immAttr3fv(attr_id.col, crosshair_color);
1396 immVertex2f(attr_id.pos, 0, +f5);
1397 immEnd();
1398
1400
1402
1404 GPU_matrix_projection_set(original_proj);
1405}
1406
1407/* Get offset in frame numbers of the reference frame relative to the current frame. */
1408static int get_reference_frame_offset(const Editing &editing, const RenderData &render_data)
1409{
1411 return editing.overlay_frame_abs - render_data.cfra;
1412 }
1413 return editing.overlay_frame_ofs;
1414}
1415
1416/* Create GPUTexture from the given image buffer for drawing rendered sequencer frame on the
1417 * color render frame buffer.
1418 *
1419 * The texture format and color space matches the CPU-side buffer.
1420 *
1421 * If both float and byte buffers are missing nullptr is returned.
1422 * If channel configuration is incompatible with the texture nullptr is returned. */
1423static GPUTexture *create_texture(const ImBuf &ibuf)
1424{
1425 const eGPUTextureUsage texture_usage = GPU_TEXTURE_USAGE_SHADER_READ |
1427
1428 GPUTexture *texture = nullptr;
1429
1430 if (ibuf.float_buffer.data) {
1431 eGPUTextureFormat texture_format;
1432 switch (ibuf.channels) {
1433 case 1:
1434 texture_format = GPU_R32F;
1435 break;
1436 case 3:
1437 texture_format = GPU_RGB32F;
1438 break;
1439 case 4:
1440 texture_format = GPU_RGBA32F;
1441 break;
1442 default:
1443 BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
1444 return nullptr;
1445 }
1446
1448 "seq_display_buf", ibuf.x, ibuf.y, 1, texture_format, texture_usage, nullptr);
1450 }
1451 else if (ibuf.byte_buffer.data) {
1453 "seq_display_buf", ibuf.x, ibuf.y, 1, GPU_RGBA8, texture_usage, nullptr);
1455 }
1456
1457 if (texture) {
1459 }
1460
1461 return texture;
1462}
1463
1464/* Get colorspace name of the image buffer used to create GPU texture.
1465 *
1466 * Needs to be kept in sync with create_texture() w.r.t which buffers are used to create the
1467 * texture. If the image buffer does not specify color space explicitly scene linear is returned if
1468 * there is a float buffer, and default byte space is returned if there is a byte buffer.
1469 *
1470 * If there are no buffers at all scene linear space is returned. */
1490
1491/* Part of the sequencer preview region drawing which renders images to the viewport's color render
1492 * frame-buffer. */
1493static void sequencer_preview_draw_color_render(const SpaceSeq &space_sequencer,
1494 const Editing &editing,
1495 ARegion &region,
1496 const ImBuf *current_ibuf,
1497 GPUTexture *current_texture,
1498 const ImBuf *reference_ibuf,
1499 GPUTexture *reference_texture)
1500{
1502
1503 if (current_texture) {
1504 BLI_assert(current_ibuf);
1505 const rctf position = preview_get_full_position(region);
1506 const rctf texture_coord = preview_get_full_texture_coord();
1507 const char *texture_colorspace = get_texture_colorspace_name(*current_ibuf);
1508 const bool predivide = (current_ibuf->float_buffer.data != nullptr);
1510 *current_texture, texture_colorspace, predivide, position, texture_coord);
1511 }
1512
1513 if (reference_texture) {
1514 BLI_assert(reference_ibuf);
1515 const rctf position = preview_get_reference_position(space_sequencer, editing, region);
1516 const rctf texture_coord = preview_get_reference_texture_coord(space_sequencer, editing);
1517 const char *texture_colorspace = get_texture_colorspace_name(*reference_ibuf);
1518 const bool predivide = (reference_ibuf->float_buffer.data != nullptr);
1520 *reference_texture, texture_colorspace, predivide, position, texture_coord);
1521 }
1522}
1523
1524static void draw_registered_callbacks(const bContext *C, ARegion &region)
1525{
1527 BLI_assert(viewport);
1528
1529 GPUFrameBuffer *overlay_fb = GPU_viewport_framebuffer_overlay_get(viewport);
1530
1531 GPU_framebuffer_bind(overlay_fb);
1533 GPU_framebuffer_bind_no_srgb(overlay_fb);
1534}
1535
1536/* Part of the sequencer preview region drawing which renders information overlays to the
1537 * viewport's overlay frame-buffer. */
1539 const wmWindowManager &wm,
1540 const Scene *scene,
1541 const SpaceSeq &space_sequencer,
1542 const Editing &editing,
1543 const ColorManagedViewSettings &view_settings,
1544 const ColorManagedDisplaySettings &display_settings,
1545 ARegion &region,
1546 GPUTexture *current_texture,
1547 GPUTexture *reference_texture,
1548 const ImBuf *overlay_ibuf,
1549 const int timeline_frame)
1550{
1551 const bool is_playing = ED_screen_animation_playing(&wm);
1552 const bool show_imbuf = check_show_imbuf(space_sequencer);
1553
1555
1556 bool has_scopes = false;
1557 if (overlay_ibuf &&
1559 space_sequencer, view_settings, display_settings, *overlay_ibuf, timeline_frame))
1560 {
1561 /* Draw scope. */
1562 sequencer_draw_scopes(space_sequencer, region);
1563 has_scopes = true;
1564 }
1565 else if (space_sequencer.flag & SEQ_USE_ALPHA) {
1566 /* Draw checked-board. */
1567 const View2D &v2d = region.v2d;
1568 imm_draw_box_checker_2d(v2d.tot.xmin, v2d.tot.ymin, v2d.tot.xmax, v2d.tot.ymax);
1569
1570 /* Draw current and preview textures in a special way to pierce a hole in the overlay to make
1571 * the actual image visible. */
1573 if (current_texture) {
1574 const rctf position = preview_get_full_position(region);
1575 const rctf texture_coord = preview_get_full_texture_coord();
1576 preview_draw_texture_simple(*current_texture, position, texture_coord);
1577 }
1578 if (reference_texture) {
1579 const rctf position = preview_get_reference_position(space_sequencer, editing, region);
1580 const rctf texture_coord = preview_get_reference_texture_coord(space_sequencer, editing);
1581 preview_draw_texture_simple(*reference_texture, position, texture_coord);
1582 }
1584 }
1585 else {
1586 /* The overlay framebuffer is fully cleared. Need to draw a full-frame transparent rectangle in
1587 * it to make sequencer result visible. */
1588
1589 const rctf position = preview_get_full_position(region);
1590
1591 GPUVertFormat *imm_format = immVertexFormat();
1592 const uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1593
1595
1597 immUniformColor3f(-.0f, 1.0f, 1.0f);
1598 immRectf(pos, position.xmin, position.ymin, position.xmax, position.ymax);
1600
1602 }
1603
1604 /* Draw metadata. */
1605 if (!has_scopes && overlay_ibuf) {
1606 if ((space_sequencer.preview_overlay.flag & SEQ_PREVIEW_SHOW_METADATA) &&
1607 (space_sequencer.flag & SEQ_SHOW_OVERLAY))
1608 {
1609 const View2D &v2d = region.v2d;
1610 ED_region_image_metadata_draw(0.0, 0.0, overlay_ibuf, &v2d.tot, 1.0, 1.0);
1611 }
1612 }
1613
1614 if (show_imbuf && (space_sequencer.flag & SEQ_SHOW_OVERLAY)) {
1615 sequencer_draw_borders_overlay(space_sequencer, region.v2d, scene);
1616
1617 /* Various overlays like strip selection and text editing. */
1618 preview_draw_all_image_overlays(C, scene, editing, timeline_frame);
1619
1620 if ((space_sequencer.preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && space_sequencer.gpd) {
1622 }
1623 }
1624
1626
1628
1629 /* No need to show the cursor for scopes. */
1630 if ((is_playing == false) && (space_sequencer.mainb == SEQ_DRAW_IMG_IMBUF) &&
1631 is_cursor_visible(space_sequencer))
1632 {
1633 GPU_color_mask(true, true, true, true);
1634 GPU_depth_mask(false);
1636
1637 const float2 cursor_pixel = seq::image_preview_unit_to_px(scene, space_sequencer.cursor);
1638 draw_cursor_2d(&region, cursor_pixel);
1639 }
1640
1641 /* Gizmos. */
1642 if ((is_playing == false) && (space_sequencer.gizmo_flag & SEQ_GIZMO_HIDE) == 0) {
1644 }
1645
1646 /* FPS counter. */
1647 if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(&wm)) {
1648 const rcti *rect = ED_region_visible_rect(&region);
1649 int xoffset = rect->xmin + U.widget_unit;
1650 int yoffset = rect->ymax;
1651
1652 /* #ED_scene_draw_fps does not set text/shadow colors, except when frame-rate is too low, then
1653 * it sets text color to red. Make sure the "normal case" also has legible colors. */
1654 const int font_id = BLF_default();
1655 float text_color[4] = {1, 1, 1, 1}, shadow_color[4] = {0, 0, 0, 0.8f};
1656 BLF_color4fv(font_id, text_color);
1657 BLF_enable(font_id, BLF_SHADOW);
1658 BLF_shadow_offset(font_id, 0, 0);
1659 BLF_shadow(font_id, FontShadowType::Outline, shadow_color);
1660
1661 ED_scene_draw_fps(scene, xoffset, &yoffset);
1662
1663 BLF_disable(font_id, BLF_SHADOW);
1664 }
1665}
1666
1668{
1669 const char *view_names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
1670
1671 const ScrArea *area = CTX_wm_area(C);
1672 const SpaceSeq &space_sequencer = *static_cast<const SpaceSeq *>(area->spacedata.first);
1673 const Scene *scene = CTX_data_scene(C);
1674
1675 if (!scene->ed || space_sequencer.render_size == SEQ_RENDER_SIZE_NONE) {
1677 return;
1678 }
1679
1680 const Editing &editing = *scene->ed;
1681 const RenderData &render_data = scene->r;
1682
1683 if (!preview_draw_begin(C, render_data, scene->view_settings, scene->display_settings, *region))
1684 {
1686 return;
1687 }
1688
1689 const bool show_imbuf = check_show_imbuf(space_sequencer);
1690
1691 const bool draw_overlay = (space_sequencer.flag & SEQ_SHOW_OVERLAY);
1692 const bool draw_frame_overlay = (editing.overlay_frame_flag & SEQ_EDIT_OVERLAY_FRAME_SHOW) &&
1693 draw_overlay;
1694 const bool need_current_frame = !(draw_frame_overlay && (space_sequencer.overlay_frame_type ==
1696 const bool need_reference_frame = draw_frame_overlay && space_sequencer.overlay_frame_type !=
1698
1699 int timeline_frame = render_data.cfra;
1700 if (sequencer_draw_get_transform_preview(space_sequencer, *scene)) {
1701 timeline_frame = sequencer_draw_get_transform_preview_frame(scene);
1702 }
1703
1704 /* GPU textures for the current and reference frames.
1705 *
1706 * When non-nullptr they are to be drawn (in other words, when they are non-nullptr the
1707 * corresponding draw_current_frame and draw_reference_frame is true). */
1708 GPUTexture *current_texture = nullptr;
1709 GPUTexture *reference_texture = nullptr;
1710
1711 /* Get image buffers before setting up GPU state for drawing. This is because
1712 * sequencer_ibuf_get() might not properly restore the state.
1713 * Additionally, some image buffers might be needed for both color render and overlay drawing. */
1714 ImBuf *current_ibuf = nullptr;
1715 ImBuf *reference_ibuf = nullptr;
1716 if (need_current_frame) {
1717 current_ibuf = sequencer_ibuf_get(
1718 C, timeline_frame, view_names[space_sequencer.multiview_eye]);
1719 if (show_imbuf && current_ibuf) {
1720 current_texture = create_texture(*current_ibuf);
1721 }
1722 }
1723 if (need_reference_frame) {
1724 const int offset = get_reference_frame_offset(editing, render_data);
1725 reference_ibuf = sequencer_ibuf_get(
1726 C, timeline_frame + offset, view_names[space_sequencer.multiview_eye]);
1727 if (show_imbuf && reference_ibuf) {
1728 reference_texture = create_texture(*reference_ibuf);
1729 }
1730 }
1731
1732 /* Image buffer used for overlays: scopes, metadata etc. */
1733 ImBuf *overlay_ibuf = need_current_frame ? current_ibuf : reference_ibuf;
1734
1735 /* Draw parts of the preview region to the corresponding frame buffers. */
1737 editing,
1738 *region,
1739 current_ibuf,
1740 current_texture,
1741 reference_ibuf,
1742 reference_texture);
1744 *CTX_wm_manager(C),
1745 scene,
1746 space_sequencer,
1747 editing,
1748 scene->view_settings,
1749 scene->display_settings,
1750 *region,
1751 current_texture,
1752 reference_texture,
1753 overlay_ibuf,
1754 timeline_frame);
1755
1756#if 0
1757 sequencer_draw_maskedit(C, scene, region, sseq);
1758#endif
1759
1760 /* Free textures. */
1761 if (current_texture) {
1762 GPU_texture_free(current_texture);
1763 }
1764 if (reference_texture) {
1765 GPU_texture_free(reference_texture);
1766 }
1767
1768 /* Free CPU side resources. */
1769 IMB_freeImBuf(current_ibuf);
1770 IMB_freeImBuf(reference_ibuf);
1771
1773}
1774
1775} // 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
void BLF_disable(int fontid, int option)
Definition blf.cc:329
int BLF_default()
@ BLF_SHADOW
Definition BLF_api.hh:435
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_GIZMO_HIDE
@ 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
#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)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_colormanagement_finish_glsl_draw()
@ COLOR_ROLE_DEFAULT_BYTE
@ COLOR_ROLE_SCENE_LINEAR
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
uint col
struct @322267210234315156101051232377144105261061020300::@131245035034130001365207177247226171236063071202 attr_id
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)
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:272
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