Blender  V3.3
sequencer_draw.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
8 #include <math.h>
9 #include <string.h>
10 
11 #include "BLI_blenlib.h"
12 #include "BLI_math.h"
13 #include "BLI_string_utils.h"
14 #include "BLI_threads.h"
15 #include "BLI_utildefines.h"
16 
17 #include "IMB_imbuf_types.h"
18 
19 #include "DNA_anim_types.h"
20 #include "DNA_mask_types.h"
21 #include "DNA_object_types.h"
22 #include "DNA_scene_types.h"
23 #include "DNA_screen_types.h"
24 #include "DNA_sound_types.h"
25 #include "DNA_space_types.h"
26 #include "DNA_userdef_types.h"
27 
28 #include "BKE_context.h"
29 #include "BKE_fcurve.h"
30 #include "BKE_global.h"
31 #include "BKE_scene.h"
32 #include "BKE_sound.h"
33 
34 #include "IMB_colormanagement.h"
35 #include "IMB_imbuf.h"
36 
37 #include "GPU_framebuffer.h"
38 #include "GPU_immediate.h"
39 #include "GPU_immediate_util.h"
40 #include "GPU_matrix.h"
41 #include "GPU_state.h"
42 #include "GPU_vertex_buffer.h"
43 #include "GPU_viewport.h"
44 
45 #include "ED_anim_api.h"
46 #include "ED_gpencil.h"
47 #include "ED_markers.h"
48 #include "ED_mask.h"
49 #include "ED_screen.h"
50 #include "ED_sequencer.h"
51 #include "ED_space_api.h"
52 #include "ED_time_scrub_ui.h"
53 #include "ED_util.h"
54 
55 #include "BIF_glutil.h"
56 
57 #include "RNA_prototypes.h"
58 
59 #include "SEQ_channels.h"
60 #include "SEQ_effects.h"
61 #include "SEQ_iterator.h"
62 #include "SEQ_prefetch.h"
63 #include "SEQ_proxy.h"
64 #include "SEQ_relations.h"
65 #include "SEQ_render.h"
66 #include "SEQ_select.h"
67 #include "SEQ_sequencer.h"
68 #include "SEQ_time.h"
69 #include "SEQ_transform.h"
70 #include "SEQ_utils.h"
71 
72 #include "UI_interface.h"
73 #include "UI_resources.h"
74 #include "UI_view2d.h"
75 
76 #include "WM_api.h"
77 #include "WM_types.h"
78 
79 #include "BLF_api.h"
80 
81 #include "MEM_guardedalloc.h"
82 
83 /* Own include. */
84 #include "sequencer_intern.h"
85 
86 #define SEQ_LEFTHANDLE 1
87 #define SEQ_RIGHTHANDLE 2
88 #define SEQ_HANDLE_SIZE 8.0f
89 #define SEQ_SCROLLER_TEXT_OFFSET 8
90 #define MUTE_ALPHA 120
91 
93 
94 void color3ubv_from_seq(const Scene *curscene,
95  const Sequence *seq,
96  const bool show_strip_color_tag,
97  uchar r_col[3])
98 {
99  Editing *ed = SEQ_editing_get(curscene);
101 
102  if (show_strip_color_tag && (uint)seq->color_tag < SEQUENCE_COLOR_TOT &&
103  seq->color_tag != SEQUENCE_COLOR_NONE) {
104  bTheme *btheme = UI_GetTheme();
105  const ThemeStripColor *strip_color = &btheme->strip_color[seq->color_tag];
106  copy_v3_v3_uchar(r_col, strip_color->color);
107  return;
108  }
109 
110  uchar blendcol[3];
111 
112  /* Sometimes the active theme is not the sequencer theme, e.g. when an operator invokes the file
113  * browser. This makes sure we get the right color values for the theme. */
114  struct bThemeState theme_state;
115  UI_Theme_Store(&theme_state);
117 
118  switch (seq->type) {
119  case SEQ_TYPE_IMAGE:
121  break;
122 
123  case SEQ_TYPE_META:
125  break;
126 
127  case SEQ_TYPE_MOVIE:
129  break;
130 
131  case SEQ_TYPE_MOVIECLIP:
133  break;
134 
135  case SEQ_TYPE_MASK:
137  break;
138 
139  case SEQ_TYPE_SCENE:
141 
142  if (seq->scene == curscene) {
143  UI_GetColorPtrShade3ubv(r_col, r_col, 20);
144  }
145  break;
146 
147  /* Transitions use input colors, fallback for when the input is a transition itself. */
148  case SEQ_TYPE_CROSS:
149  case SEQ_TYPE_GAMCROSS:
150  case SEQ_TYPE_WIPE:
151  r_col[0] = 130;
152  r_col[1] = 130;
153  r_col[2] = 130;
154  break;
155 
156  /* Effects. */
157  case SEQ_TYPE_TRANSFORM:
158  case SEQ_TYPE_SPEED:
159  case SEQ_TYPE_ADD:
160  case SEQ_TYPE_SUB:
161  case SEQ_TYPE_MUL:
162  case SEQ_TYPE_ALPHAOVER:
163  case SEQ_TYPE_ALPHAUNDER:
164  case SEQ_TYPE_OVERDROP:
165  case SEQ_TYPE_GLOW:
166  case SEQ_TYPE_MULTICAM:
167  case SEQ_TYPE_ADJUSTMENT:
169  case SEQ_TYPE_COLORMIX:
171 
172  /* Slightly offset hue to distinguish different effects. */
173  if (seq->type == SEQ_TYPE_ADD) {
174  rgb_byte_set_hue_float_offset(r_col, 0.03);
175  }
176  else if (seq->type == SEQ_TYPE_SUB) {
177  rgb_byte_set_hue_float_offset(r_col, 0.06);
178  }
179  else if (seq->type == SEQ_TYPE_MUL) {
180  rgb_byte_set_hue_float_offset(r_col, 0.13);
181  }
182  else if (seq->type == SEQ_TYPE_ALPHAOVER) {
183  rgb_byte_set_hue_float_offset(r_col, 0.16);
184  }
185  else if (seq->type == SEQ_TYPE_ALPHAUNDER) {
186  rgb_byte_set_hue_float_offset(r_col, 0.23);
187  }
188  else if (seq->type == SEQ_TYPE_OVERDROP) {
189  rgb_byte_set_hue_float_offset(r_col, 0.26);
190  }
191  else if (seq->type == SEQ_TYPE_COLORMIX) {
192  rgb_byte_set_hue_float_offset(r_col, 0.33);
193  }
194  else if (seq->type == SEQ_TYPE_GAUSSIAN_BLUR) {
195  rgb_byte_set_hue_float_offset(r_col, 0.43);
196  }
197  else if (seq->type == SEQ_TYPE_GLOW) {
198  rgb_byte_set_hue_float_offset(r_col, 0.46);
199  }
200  else if (seq->type == SEQ_TYPE_ADJUSTMENT) {
201  rgb_byte_set_hue_float_offset(r_col, 0.55);
202  }
203  else if (seq->type == SEQ_TYPE_SPEED) {
204  rgb_byte_set_hue_float_offset(r_col, 0.65);
205  }
206  else if (seq->type == SEQ_TYPE_TRANSFORM) {
207  rgb_byte_set_hue_float_offset(r_col, 0.75);
208  }
209  else if (seq->type == SEQ_TYPE_MULTICAM) {
210  rgb_byte_set_hue_float_offset(r_col, 0.85);
211  }
212  break;
213 
214  case SEQ_TYPE_COLOR:
216  break;
217 
218  case SEQ_TYPE_SOUND_RAM:
220  blendcol[0] = blendcol[1] = blendcol[2] = 128;
221  if (SEQ_render_is_muted(channels, seq)) {
222  UI_GetColorPtrBlendShade3ubv(r_col, blendcol, r_col, 0.5, 20);
223  }
224  break;
225 
226  case SEQ_TYPE_TEXT:
228  break;
229 
230  default:
231  r_col[0] = 10;
232  r_col[1] = 255;
233  r_col[2] = 40;
234  break;
235  }
236 
237  UI_Theme_Restore(&theme_state);
238 }
239 
240 typedef struct WaveVizData {
241  float pos[2];
242  float rms_pos;
243  bool clip;
244  bool draw_line; /* Draw triangle otherwise. */
245  bool final_sample; /* There are no more samples. */
247 
248 static bool seq_draw_waveforms_poll(const bContext *UNUSED(C), SpaceSeq *sseq, Sequence *seq)
249 {
250  const bool strip_is_valid = seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != NULL;
251  const bool overlays_enabled = (sseq->flag & SEQ_SHOW_OVERLAY) != 0;
252  const bool ovelay_option = ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) != 0 ||
253  (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM));
254 
255  if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) != 0) {
256  return false;
257  }
258 
259  if (strip_is_valid && overlays_enabled && ovelay_option) {
260  return true;
261  }
262 
263  return false;
264 }
265 
267 {
268  bSound *sound = seq->sound;
269 
270  BLI_spin_lock(sound->spinlock);
271  if (!sound->waveform) {
272  /* Load the waveform data if it hasn't been loaded and cached already. */
273  if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
274  /* Prevent sounds from reloading. */
276  BLI_spin_unlock(sound->spinlock);
278  }
279  else {
280  BLI_spin_unlock(sound->spinlock);
281  }
282  }
283  BLI_spin_unlock(sound->spinlock);
284 }
285 
286 static size_t get_vertex_count(WaveVizData *waveform_data)
287 {
288  bool draw_line = waveform_data->draw_line;
289  size_t length = 0;
290 
291  while (waveform_data->draw_line == draw_line && !waveform_data->final_sample) {
292  waveform_data++;
293  length++;
294  }
295 
296  return length;
297 }
298 
299 static size_t draw_waveform_segment(WaveVizData *waveform_data, bool use_rms)
300 {
301  size_t vertices_done = 0;
302  size_t vertex_count = get_vertex_count(waveform_data);
303 
304  /* Not enough data to draw. */
305  if (vertex_count <= 2) {
306  return vertex_count;
307  }
308 
311  GPUPrimType prim_type = waveform_data->draw_line ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP;
315  immBegin(prim_type, vertex_count);
316 
317  while (vertices_done < vertex_count && !waveform_data->final_sample) {
318  /* Color. */
319  if (waveform_data->clip) {
320  immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f);
321  }
322  else if (use_rms) {
323  immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.8f);
324  }
325  else {
326  immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.5f);
327  }
328 
329  /* Vertices. */
330  if (use_rms) {
331  immVertex2f(pos, waveform_data->pos[0], waveform_data->rms_pos);
332  }
333  else {
334  immVertex2f(pos, waveform_data->pos[0], waveform_data->pos[1]);
335  }
336 
337  vertices_done++;
338  waveform_data++;
339  }
340 
341  immEnd();
343 
345 
346  return vertices_done;
347 }
348 
349 static void draw_waveform(WaveVizData *waveform_data, size_t wave_data_len)
350 {
351  size_t items_done = 0;
352  while (items_done < wave_data_len) {
353  if (!waveform_data[items_done].draw_line) { /* Draw RMS. */
354  draw_waveform_segment(&waveform_data[items_done], true);
355  }
356  items_done += draw_waveform_segment(&waveform_data[items_done], false);
357  }
358 }
359 
360 static float align_frame_with_pixel(float frame_coord, float frames_per_pixel)
361 {
362  return round_fl_to_int(frame_coord / frames_per_pixel) * frames_per_pixel;
363 }
364 
365 static void write_waveform_data(WaveVizData *waveform_data,
366  const vec2f pos,
367  const float rms,
368  const bool is_clipping,
369  const bool draw_line)
370 {
371  waveform_data->pos[0] = pos.x;
372  waveform_data->pos[1] = pos.y;
373  waveform_data->clip = is_clipping;
374  waveform_data->rms_pos = rms;
375  waveform_data->draw_line = draw_line;
376 }
377 
378 static size_t waveform_append_sample(WaveVizData *waveform_data,
379  vec2f pos,
380  const float value_min,
381  const float value_max,
382  const float y_mid,
383  const float y_scale,
384  const float rms,
385  const bool is_clipping,
386  const bool is_line_strip)
387 {
388  size_t data_written = 0;
389  pos.y = y_mid + value_min * y_scale;
390  float rms_value = y_mid + max_ff(-rms, value_min) * y_scale;
391  write_waveform_data(&waveform_data[0], pos, rms_value, is_clipping, is_line_strip);
392  data_written++;
393 
394  /* Use `value_max` as second vertex for triangle drawing. */
395  if (!is_line_strip) {
396  pos.y = y_mid + value_max * y_scale;
397  rms_value = y_mid + min_ff(rms, value_max) * y_scale;
398  write_waveform_data(&waveform_data[1], pos, rms_value, is_clipping, is_line_strip);
399  data_written++;
400  }
401  return data_written;
402 }
403 
409  const bContext *C, ARegion *region, Sequence *seq, float x1, float y1, float x2, float y2)
410 {
411  const View2D *v2d = &region->v2d;
413 
414  const float frames_per_pixel = BLI_rctf_size_x(&region->v2d.cur) / region->winx;
415  const float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS;
416  float samples_per_pixel = samples_per_frame * frames_per_pixel;
417 
418  /* Align strip start with nearest pixel to prevent waveform flickering. */
419  const float x1_aligned = align_frame_with_pixel(x1, frames_per_pixel);
420  /* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */
421  const float frame_start = max_ff(v2d->cur.xmin, x1_aligned);
422  const float frame_end = min_ff(v2d->cur.xmax, x2);
423  const int pixels_to_draw = round_fl_to_int((frame_end - frame_start) / frames_per_pixel);
424 
425  if (pixels_to_draw < 2) {
426  return; /* Not much to draw, exit before running job. */
427  }
428 
430 
431  SoundWaveform *waveform = seq->sound->waveform;
432  if (waveform == NULL || waveform->length == 0) {
433  return; /* Waveform was not built. */
434  }
435 
436  /* F-Curve lookup is quite expensive, so do this after precondition. */
437  FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
438  WaveVizData *waveform_data = MEM_callocN(sizeof(WaveVizData) * pixels_to_draw * 3, __func__);
439  size_t wave_data_len = 0;
440 
441  /* Offset must be also aligned, otherwise waveform flickers when moving left handle. */
442  const float strip_offset = align_frame_with_pixel(seq->startofs + seq->anim_startofs,
443  frames_per_pixel);
444  float start_sample = strip_offset * samples_per_frame;
445  start_sample += seq->sound->offset_time * SOUND_WAVE_SAMPLES_PER_SECOND;
446  /* Add off-screen part of strip to offset. */
447  start_sample += (frame_start - x1_aligned) * samples_per_frame;
448 
449  for (int i = 0; i < pixels_to_draw; i++) {
450  float sample = start_sample + i * samples_per_pixel;
451  int sample_index = round_fl_to_int(sample);
452 
453  if (sample_index < 0) {
454  continue;
455  }
456 
457  if (sample_index >= waveform->length) {
458  break;
459  }
460 
461  float value_min = waveform->data[sample_index * 3];
462  float value_max = waveform->data[sample_index * 3 + 1];
463  float rms = waveform->data[sample_index * 3 + 2];
464 
465  if (sample_index + 1 < waveform->length) {
466  /* Use simple linear interpolation. */
467  float f = sample - sample_index;
468  value_min = (1.0f - f) * value_min + f * waveform->data[sample_index * 3 + 3];
469  value_max = (1.0f - f) * value_max + f * waveform->data[sample_index * 3 + 4];
470  rms = (1.0f - f) * rms + f * waveform->data[sample_index * 3 + 5];
471  if (samples_per_pixel > 1.0f) {
472  /* We need to sum up the values we skip over until the next step. */
473  float next_pos = sample + samples_per_pixel;
474  int end_idx = next_pos;
475 
476  for (int j = sample_index + 1; (j < waveform->length) && (j < end_idx); j++) {
477  value_min = min_ff(value_min, waveform->data[j * 3]);
478  value_max = max_ff(value_max, waveform->data[j * 3 + 1]);
479  rms = max_ff(rms, waveform->data[j * 3 + 2]);
480  }
481  }
482  }
483 
484  float volume = seq->volume;
485  if (fcu && !BKE_fcurve_is_empty(fcu)) {
486  float evaltime = frame_start + (i * frames_per_pixel);
487  volume = evaluate_fcurve(fcu, evaltime);
488  CLAMP_MIN(volume, 0.0f);
489  }
490 
491  value_min *= volume;
492  value_max *= volume;
493  rms *= volume;
494 
495  bool is_clipping = false;
496 
497  if (value_max > 1 || value_min < -1) {
498  is_clipping = true;
499 
500  CLAMP_MAX(value_max, 1.0f);
501  CLAMP_MIN(value_min, -1.0f);
502  }
503 
504  bool is_line_strip = (value_max - value_min < 0.05f);
505  /* The y coordinate for the middle of the strip. */
506  float y_mid = (y1 + y2) / 2.0f;
507  /* The length from the middle of the strip to the top/bottom. */
508  float y_scale = (y2 - y1) / 2.0f;
509 
510  vec2f pos = {frame_start + i * frames_per_pixel, y_mid + value_min * y_scale};
511  WaveVizData *new_data = &waveform_data[wave_data_len];
512  wave_data_len += waveform_append_sample(
513  new_data, pos, value_min, value_max, y_mid, y_scale, rms, is_clipping, is_line_strip);
514  }
515 
516  /* Terminate array, so `get_segment_length()` can know when to stop. */
517  waveform_data[wave_data_len].final_sample = true;
518  draw_waveform(waveform_data, wave_data_len);
519  MEM_freeN(waveform_data);
520 }
521 
522 /*
523 static size_t *waveform_append(WaveVizData *waveform_data,
524  vec2f pos,
525  const float value_min,
526  const float value_max,
527  const float y_mid,
528  const float y_scale,
529  const float rms,
530  const bool is_clipping,
531  const bool is_line_strip)
532 */
533 
535  Sequence *seqm,
536  float x1,
537  float y1,
538  float x2,
539  float y2,
540  const bool show_strip_color_tag)
541 {
542  Sequence *seq;
543  uchar col[4];
544 
545  int chan_min = MAXSEQ;
546  int chan_max = 0;
547  int chan_range = 0;
548  float draw_range = y2 - y1;
549  float draw_height;
550 
553  ListBase *meta_seqbase;
554  ListBase *meta_channels;
555  int offset;
556 
557  meta_seqbase = SEQ_get_seqbase_from_sequence(seqm, &meta_channels, &offset);
558 
559  if (!meta_seqbase || BLI_listbase_is_empty(meta_seqbase)) {
560  return;
561  }
562 
563  if (seqm->type == SEQ_TYPE_SCENE) {
564  offset = seqm->start - offset;
565  }
566  else {
567  offset = 0;
568  }
569 
571 
572  for (seq = meta_seqbase->first; seq; seq = seq->next) {
573  chan_min = min_ii(chan_min, seq->machine);
574  chan_max = max_ii(chan_max, seq->machine);
575  }
576 
577  chan_range = (chan_max - chan_min) + 1;
578  draw_height = draw_range / chan_range;
579 
580  col[3] = 196; /* Alpha, used for all meta children. */
581 
584 
585  /* Draw only immediate children (1 level depth). */
586  for (seq = meta_seqbase->first; seq; seq = seq->next) {
587  const int startdisp = SEQ_time_left_handle_frame_get(scene, seq) + offset;
588  const int enddisp = SEQ_time_right_handle_frame_get(scene, seq) + offset;
589 
590  if ((startdisp > x2 || enddisp < x1) == 0) {
591  float y_chan = (seq->machine - chan_min) / (float)(chan_range)*draw_range;
592  float x1_chan = startdisp;
593  float x2_chan = enddisp;
594  float y1_chan, y2_chan;
595 
596  if (seq->type == SEQ_TYPE_COLOR) {
597  SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
598  rgb_float_to_uchar(col, colvars->col);
599  }
600  else {
601  color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
602  }
603 
604  if (SEQ_render_is_muted(channels, seqm) || SEQ_render_is_muted(meta_channels, seq)) {
605  col[3] = 64;
606  }
607  else {
608  col[3] = 196;
609  }
610 
612 
613  /* Clamp within parent sequence strip bounds. */
614  if (x1_chan < x1) {
615  x1_chan = x1;
616  }
617  if (x2_chan > x2) {
618  x2_chan = x2;
619  }
620 
621  y1_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
622  y2_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
623 
624  immRectf(pos, x1_chan, y1_chan, x2_chan, y2_chan);
625  }
626  }
627 
629 
631 }
632 
633 float sequence_handle_size_get_clamped(const Scene *scene, Sequence *seq, const float pixelx)
634 {
635  const float maxhandle = (pixelx * SEQ_HANDLE_SIZE) * U.pixelsize;
636 
637  /* Ensure that handle is not wider, than quarter of strip. */
638  return min_ff(maxhandle,
639  ((float)(SEQ_time_right_handle_frame_get(scene, seq) -
641  4.0f));
642 }
643 
644 /* Draw a handle, on left or right side of strip. */
645 static void draw_seq_handle(const Scene *scene,
646  View2D *v2d,
647  Sequence *seq,
648  const float handsize_clamped,
649  const short direction,
650  uint pos,
651  bool seq_active,
652  float pixelx,
653  bool y_threshold)
654 {
655  float rx1 = 0, rx2 = 0;
656  float x1, x2, y1, y2;
657  uint whichsel = 0;
658  uchar col[4];
659 
662 
663  y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
664  y2 = seq->machine + SEQ_STRIP_OFSTOP;
665 
666  /* Set up co-ordinates and dimensions for either left or right handle. */
667  if (direction == SEQ_LEFTHANDLE) {
668  rx1 = x1;
669  rx2 = x1 + handsize_clamped;
670  whichsel = SEQ_LEFTSEL;
671  }
672  else if (direction == SEQ_RIGHTHANDLE) {
673  rx1 = x2 - handsize_clamped;
674  rx2 = x2;
675  whichsel = SEQ_RIGHTSEL;
676  }
677 
678  if (!(seq->type & SEQ_TYPE_EFFECT) || SEQ_effect_get_num_inputs(seq->type) == 0) {
680 
682 
683  if (seq->flag & whichsel) {
684  if (seq_active) {
686  }
687  else {
689  /* Make handles slightly brighter than the outlines. */
691  }
692  col[3] = 255;
694  }
695  else {
696  immUniformColor4ub(0, 0, 0, 50);
697  }
698 
699  immRectf(pos, rx1, y1, rx2, y2);
701  }
702 
703  /* Draw numbers for start and end of the strip next to its handles. */
704  if (y_threshold &&
705  (((seq->flag & SELECT) && (G.moving & G_TRANSFORM_SEQ)) || (seq->flag & whichsel))) {
706 
707  char numstr[64];
708  size_t numstr_len;
709  const int fontid = BLF_default();
710  BLF_set_default();
711 
712  /* Calculate if strip is wide enough for showing the labels. */
713  numstr_len = BLI_snprintf_rlen(numstr,
714  sizeof(numstr),
715  "%d%d",
718  float tot_width = BLF_width(fontid, numstr, numstr_len);
719 
720  if ((x2 - x1) / pixelx > 20 + tot_width) {
721  col[0] = col[1] = col[2] = col[3] = 255;
722  float text_margin = 1.2f * handsize_clamped;
723 
724  if (direction == SEQ_LEFTHANDLE) {
725  numstr_len = BLI_snprintf_rlen(
726  numstr, sizeof(numstr), "%d", SEQ_time_left_handle_frame_get(scene, seq));
727  x1 += text_margin;
728  y1 += 0.09f;
729  }
730  else {
731  numstr_len = BLI_snprintf_rlen(
732  numstr, sizeof(numstr), "%d", SEQ_time_right_handle_frame_get(scene, seq) - 1);
733  x1 = x2 - (text_margin + pixelx * BLF_width(fontid, numstr, numstr_len));
734  y1 += 0.09f;
735  }
736  UI_view2d_text_cache_add(v2d, x1, y1, numstr, numstr_len, col);
737  }
738  }
739 }
740 
742  Sequence *seq,
743  uint pos,
744  float x1,
745  float x2,
746  float y1,
747  float y2,
748  float pixelx,
749  float pixely,
750  bool seq_active)
751 {
752  uchar col[3];
753 
754  /* Get the color for the outline. */
755  if (seq_active && (seq->flag & SELECT)) {
757  }
758  else if (seq->flag & SELECT) {
760  }
761  else {
762  /* Color for unselected strips is a bit darker than the background. */
764  }
765 
766  /* Outline while translating strips:
767  * - Slightly lighter.
768  * - Red when overlapping with other strips.
769  */
771  if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT) &&
772  overlap_mode != SEQ_OVERLAP_OVERWRITE) {
773  if (seq->flag & SEQ_OVERLAP) {
774  col[0] = 255;
775  col[1] = col[2] = 33;
776  }
777  else {
779  }
780  }
782 
783  /* 2px wide outline for selected strips. */
784  /* XXX: some platforms don't support OpenGL lines wider than 1px (see T57570),
785  * draw outline as four boxes instead. */
786  if (seq->flag & SELECT) {
787  /* Left */
788  immRectf(pos, x1 - pixelx, y1, x1 + pixelx, y2);
789  /* Bottom */
790  immRectf(pos, x1 - pixelx, y1, x2 + pixelx, y1 + 2 * pixely);
791  /* Right */
792  immRectf(pos, x2 - pixelx, y1, x2 + pixelx, y2);
793  /* Top */
794  immRectf(pos, x1 - pixelx, y2 - 2 * pixely, x2 + pixelx, y2);
795  }
796  else {
797  /* 1px wide outline for unselected strips. */
798  imm_draw_box_wire_2d(pos, x1, y1, x2, y2);
799  }
800 }
801 
802 static const char *draw_seq_text_get_name(Sequence *seq)
803 {
804  const char *name = seq->name + 2;
805  if (name[0] == '\0') {
806  name = SEQ_sequence_give_name(seq);
807  }
808  return name;
809 }
810 
811 static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t source_len)
812 {
813  *r_source = '\0';
814 
815  /* Set source for the most common types. */
816  switch (seq->type) {
817  case SEQ_TYPE_IMAGE:
818  case SEQ_TYPE_MOVIE: {
819  BLI_join_dirfile(r_source, source_len, seq->strip->dir, seq->strip->stripdata->name);
820  break;
821  }
822  case SEQ_TYPE_SOUND_RAM: {
823  if (seq->sound != NULL) {
824  BLI_strncpy(r_source, seq->sound->filepath, source_len);
825  }
826  break;
827  }
828  case SEQ_TYPE_MULTICAM: {
829  BLI_snprintf(r_source, source_len, "Channel: %d", seq->multicam_source);
830  break;
831  }
832  case SEQ_TYPE_TEXT: {
833  const TextVars *textdata = seq->effectdata;
834  BLI_strncpy(r_source, textdata->text, source_len);
835  break;
836  }
837  case SEQ_TYPE_SCENE: {
838  if (seq->scene != NULL) {
839  if (seq->scene_camera != NULL) {
840  BLI_snprintf(r_source,
841  source_len,
842  "%s (%s)",
843  seq->scene->id.name + 2,
844  seq->scene_camera->id.name + 2);
845  }
846  else {
847  BLI_strncpy(r_source, seq->scene->id.name + 2, source_len);
848  }
849  }
850  break;
851  }
852  case SEQ_TYPE_MOVIECLIP: {
853  if (seq->clip != NULL) {
854  BLI_strncpy(r_source, seq->clip->id.name + 2, source_len);
855  }
856  break;
857  }
858  case SEQ_TYPE_MASK: {
859  if (seq->mask != NULL) {
860  BLI_strncpy(r_source, seq->mask->id.name + 2, source_len);
861  }
862  break;
863  }
864  }
865 }
866 
868  SpaceSeq *sseq,
869  Sequence *seq,
870  char *r_overlay_string,
871  size_t overlay_string_len)
872 {
873  const char *text_sep = " | ";
874  const char *text_array[5];
875  int i = 0;
876 
878  text_array[i++] = draw_seq_text_get_name(seq);
879  }
880 
881  char source[FILE_MAX];
883  draw_seq_text_get_source(seq, source, sizeof(source));
884  if (source[0] != '\0') {
885  if (i != 0) {
886  text_array[i++] = text_sep;
887  }
888  text_array[i++] = source;
889  }
890  }
891 
892  char strip_duration_text[16];
894  const int strip_duration = SEQ_time_right_handle_frame_get(scene, seq) -
896  SNPRINTF(strip_duration_text, "%d", strip_duration);
897  if (i != 0) {
898  text_array[i++] = text_sep;
899  }
900  text_array[i++] = strip_duration_text;
901  }
902 
903  BLI_assert(i <= ARRAY_SIZE(text_array));
904 
905  return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i) -
906  r_overlay_string;
907 }
908 
909 /* Draw info text on a sequence strip. */
911  View2D *v2d,
912  Sequence *seq,
913  SpaceSeq *sseq,
914  float x1,
915  float x2,
916  float y1,
917  float y2,
918  bool seq_active)
919 {
922  char overlay_string[FILE_MAX];
923  size_t overlay_string_len = draw_seq_text_get_overlay_string(
924  scene, sseq, seq, overlay_string, sizeof(overlay_string));
925 
926  if (overlay_string_len == 0) {
927  return;
928  }
929 
930  /* White text for the active strip. */
931  uchar col[4];
932  col[0] = col[1] = col[2] = seq_active ? 255 : 10;
933  col[3] = 255;
934 
935  /* Make the text duller when the strip is muted. */
936  if (SEQ_render_is_muted(channels, seq)) {
937  if (seq_active) {
939  }
940  else {
942  }
943  }
944 
945  rctf rect;
946  rect.xmin = x1;
947  rect.ymin = y1;
948  rect.xmax = x2;
949  rect.ymax = y2;
950 
951  UI_view2d_text_cache_add_rectf(v2d, &rect, overlay_string, overlay_string_len, col);
952 }
953 
955  Scene *scene, Sequence *seq, uint pos, float pixely, const bool show_strip_color_tag)
956 {
959  float x1, x2, y1, y2;
960  uchar col[4], blend_col[3];
961 
964 
965  y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
966  y2 = seq->machine + SEQ_STRIP_OFSTOP;
967 
969 
970  color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
971  if (seq->flag & SELECT) {
973  }
974  col[3] = SEQ_render_is_muted(channels, seq) ? MUTE_ALPHA : 200;
975  UI_GetColorPtrShade3ubv(col, blend_col, 10);
976 
977  const float strip_content_start = SEQ_time_start_frame_get(seq);
978  const float strip_content_end = SEQ_time_start_frame_get(seq) +
980  float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq);
981  float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
982 
983  if (left_handle_frame > strip_content_start) {
985  immRectf(pos, strip_content_start, y1 - pixely, x1, y1 - SEQ_STRIP_OFSBOTTOM);
986 
987  /* Outline. */
988  immUniformColor3ubv(blend_col);
989  imm_draw_box_wire_2d(pos, x1, y1 - pixely, strip_content_start, y1 - SEQ_STRIP_OFSBOTTOM);
990  }
991  if (right_handle_frame < strip_content_end) {
993  immRectf(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM);
994 
995  /* Outline. */ immUniformColor3ubv(blend_col);
996  imm_draw_box_wire_2d(pos, x2, y2 + pixely, strip_content_end, y2 + SEQ_STRIP_OFSBOTTOM);
997  }
999 }
1000 
1002  const Scene *scene, ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1)
1003 {
1004  uchar col[4];
1005  SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
1006 
1008  rgb_float_to_uchar(col, colvars->col);
1009 
1010  /* Draw muted strips semi-transparent. */
1011  if (SEQ_render_is_muted(channels, seq)) {
1012  col[3] = MUTE_ALPHA;
1013  }
1014  /* Draw background semi-transparent when overlapping strips. */
1015  else if (seq->flag & SEQ_OVERLAP) {
1016  col[3] = OVERLAP_ALPHA;
1017  }
1018  else {
1019  col[3] = 255;
1020  }
1021 
1023 
1024  immRectf(pos,
1026  y1,
1028  text_margin_y);
1029 
1030  /* 1px line to better separate the color band. */
1033 
1035  immVertex2f(pos, SEQ_time_left_handle_frame_get(scene, seq), text_margin_y);
1036  immVertex2f(pos, SEQ_time_right_handle_frame_get(scene, seq), text_margin_y);
1037  immEnd();
1038 
1040 }
1041 
1043  Sequence *seq,
1044  uint pos,
1045  float x1,
1046  float x2,
1047  float y1,
1048  float y2,
1049  bool is_single_image,
1050  bool show_strip_color_tag)
1051 {
1052  Editing *ed = SEQ_editing_get(scene);
1054  uchar col[4];
1056 
1057  /* Get the correct color per strip type, transitions use their inputs ones. */
1059  Sequence *seq1 = seq->seq1;
1060  if (seq1->type == SEQ_TYPE_COLOR) {
1061  SolidColorVars *colvars = (SolidColorVars *)seq1->effectdata;
1062  rgb_float_to_uchar(col, colvars->col);
1063  }
1064  else {
1065  color3ubv_from_seq(scene, seq1, show_strip_color_tag, col);
1066  }
1067  }
1068  else {
1069  color3ubv_from_seq(scene, seq, show_strip_color_tag, col);
1070  }
1071 
1072  /* Draw muted strips semi-transparent. */
1073  if (SEQ_render_is_muted(channels, seq)) {
1074  col[3] = MUTE_ALPHA;
1075  }
1076  /* Draw background semi-transparent when overlapping strips. */
1077  else if (seq->flag & SEQ_OVERLAP) {
1078  col[3] = OVERLAP_ALPHA;
1079  }
1080  else {
1081  col[3] = 255;
1082  }
1083 
1085 
1086  /* Draw the main strip body. */
1087  if (is_single_image) {
1088  immRectf(pos,
1090  y1,
1092  y2);
1093  }
1094  else {
1095  immRectf(pos, x1, y1, x2, y2);
1096  }
1097 
1098  /* Draw background for hold still regions. */
1099  if (!is_single_image) {
1102 
1104  float left_handle_frame = SEQ_time_left_handle_frame_get(scene, seq);
1105  const float content_start = SEQ_time_start_frame_get(seq);
1106  immRectf(pos, left_handle_frame, y1, content_start, y2);
1107  }
1109  float right_handle_frame = SEQ_time_right_handle_frame_get(scene, seq);
1110  const float content_end = SEQ_time_start_frame_get(seq) +
1112  immRectf(pos, content_end, y1, right_handle_frame, y2);
1113  }
1114  }
1115 
1116  /* Draw right half of transition strips. */
1118  float vert_pos[3][2];
1119  Sequence *seq1 = seq->seq1;
1120  Sequence *seq2 = seq->seq2;
1121 
1122  if (seq2->type == SEQ_TYPE_COLOR) {
1123  SolidColorVars *colvars = (SolidColorVars *)seq2->effectdata;
1124  rgb_float_to_uchar(col, colvars->col);
1125  }
1126  else {
1127  color3ubv_from_seq(scene, seq2, show_strip_color_tag, col);
1128  /* If the transition inputs are of the same type, draw the right side slightly darker. */
1129  if (seq1->type == seq2->type) {
1131  }
1132  }
1134 
1135  copy_v2_fl2(vert_pos[0], x1, y2);
1136  copy_v2_fl2(vert_pos[1], x2, y2);
1137  copy_v2_fl2(vert_pos[2], x2, y1);
1138 
1139  immBegin(GPU_PRIM_TRIS, 3);
1140  immVertex2fv(pos, vert_pos[0]);
1141  immVertex2fv(pos, vert_pos[1]);
1142  immVertex2fv(pos, vert_pos[2]);
1143  immEnd();
1144  }
1145 
1147 }
1148 
1149 static void draw_seq_locked(float x1, float y1, float x2, float y2)
1150 {
1152 
1155 
1156  immUniform4f("color1", 1.0f, 1.0f, 1.0f, 0.0f);
1157  immUniform4f("color2", 0.0f, 0.0f, 0.0f, 0.25f);
1158  immUniform1i("size1", 8);
1159  immUniform1i("size2", 4);
1160 
1161  immRectf(pos, x1, y1, x2, y2);
1162 
1163  immUnbindProgram();
1164 
1166 }
1167 
1168 static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
1169 {
1171 
1174  immUniformColor4f(1.0f, 0.0f, 0.0f, 0.9f);
1175  immRectf(pos, x1, y2, x2, text_margin_y);
1176 
1177  immUnbindProgram();
1179 }
1180 
1182  const Scene *scene, View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx)
1183 {
1184  const float handsize_clamped = sequence_handle_size_get_clamped(scene, seq, pixelx);
1185  float text_margin = 2.0f * handsize_clamped;
1186 
1187  *x1 += text_margin;
1188  *x2 -= text_margin;
1189 
1190  float scroller_vert_xoffs = (V2D_SCROLL_HANDLE_WIDTH + SEQ_SCROLLER_TEXT_OFFSET) * pixelx;
1191 
1192  /* Info text on the strip. */
1193  if (*x1 < v2d->cur.xmin + scroller_vert_xoffs) {
1194  *x1 = v2d->cur.xmin + scroller_vert_xoffs;
1195  }
1196  else if (*x1 > v2d->cur.xmax) {
1197  *x1 = v2d->cur.xmax;
1198  }
1199  if (*x2 < v2d->cur.xmin) {
1200  *x2 = v2d->cur.xmin;
1201  }
1202  else if (*x2 > v2d->cur.xmax) {
1203  *x2 = v2d->cur.xmax;
1204  }
1205 }
1206 
1208  float y1,
1209  float y2,
1210  float y_height,
1211  int timeline_frame,
1212  float curve_val,
1213  unsigned int *vert_count)
1214 {
1215  float vert_pos[2][2];
1216 
1217  copy_v2_fl2(vert_pos[0], timeline_frame, (curve_val * y_height) + y1);
1218  copy_v2_fl2(vert_pos[1], timeline_frame, y2);
1219 
1220  GPU_vertbuf_vert_set(vbo, *vert_count, vert_pos[0]);
1221  GPU_vertbuf_vert_set(vbo, *vert_count + 1, vert_pos[1]);
1222  *vert_count += 2;
1223 }
1224 
1231  Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, float pixelx)
1232 {
1233  FCurve *fcu;
1234 
1235  if (seq->type == SEQ_TYPE_SOUND_RAM) {
1236  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
1237  }
1238  else {
1239  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "blend_alpha", 0, NULL);
1240  }
1241 
1242  if (fcu && !BKE_fcurve_is_empty(fcu)) {
1243 
1244  /* Clamp curve evaluation to the editor's borders. */
1245  int eval_start = max_ff(x1, v2d->cur.xmin);
1246  int eval_end = min_ff(x2, v2d->cur.xmax + 1);
1247 
1248  int eval_step = max_ii(1, floor(pixelx));
1249 
1250  if (eval_start >= eval_end) {
1251  return;
1252  }
1253 
1254  GPUVertFormat format = {0};
1257 
1258  uint max_verts = 2 * ((eval_end - eval_start) / eval_step + 1);
1259  GPU_vertbuf_data_alloc(vbo, max_verts);
1260  uint vert_count = 0;
1261 
1262  const float y_height = y2 - y1;
1263  float curve_val;
1264  float prev_val = INT_MIN;
1265  bool skip = false;
1266 
1267  for (int timeline_frame = eval_start; timeline_frame <= eval_end;
1268  timeline_frame += eval_step) {
1269  curve_val = evaluate_fcurve(fcu, timeline_frame);
1270  CLAMP(curve_val, 0.0f, 1.0f);
1271 
1272  /* Avoid adding adjacent verts that have the same value. */
1273  if (curve_val == prev_val && timeline_frame < eval_end - eval_step) {
1274  skip = true;
1275  continue;
1276  }
1277 
1278  /* If some frames were skipped above, we need to close the shape. */
1279  if (skip) {
1281  vbo, y1, y2, y_height, timeline_frame - eval_step, prev_val, &vert_count);
1282  skip = false;
1283  }
1284 
1285  fcurve_batch_add_verts(vbo, y1, y2, y_height, timeline_frame, curve_val, &vert_count);
1286  prev_val = curve_val;
1287  }
1288 
1290  GPU_vertbuf_data_len_set(vbo, vert_count);
1292  GPU_batch_uniform_4f(batch, "color", 0.0f, 0.0f, 0.0f, 0.15f);
1294 
1295  if (vert_count > 0) {
1297  }
1298 
1301  }
1302 }
1303 
1304 /* Draw visible strips. Bounds check are already made. */
1305 static void draw_seq_strip(const bContext *C,
1306  SpaceSeq *sseq,
1307  Scene *scene,
1308  ARegion *region,
1309  Sequence *seq,
1310  float pixelx,
1311  bool seq_active)
1312 {
1315 
1316  View2D *v2d = &region->v2d;
1317  float x1, x2, y1, y2;
1318  const float handsize_clamped = sequence_handle_size_get_clamped(scene, seq, pixelx);
1319  float pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
1320 
1321  /* Check if we are doing "solo preview". */
1322  bool is_single_image = (char)SEQ_transform_single_image_check(seq);
1323 
1324  /* Use the seq->color_tag to display the tag color. */
1325  const bool show_strip_color_tag = (sseq->timeline_overlay.flag &
1327 
1328  /* Draw strip body. */
1331  y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
1335  y2 = seq->machine + SEQ_STRIP_OFSTOP;
1336 
1337  /* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
1340 
1341  float text_margin_y;
1342  bool y_threshold;
1346 
1347  /* Calculate height needed for drawing text on strip. */
1348  text_margin_y = y2 - min_ff(0.40f, 20 * U.dpi_fac * pixely);
1349 
1350  /* Is there enough space for drawing something else than text? */
1351  y_threshold = ((y2 - y1) / pixely) > 20 * U.dpi_fac;
1352  }
1353  else {
1354  text_margin_y = y2;
1355  y_threshold = false;
1356  }
1357 
1360 
1361  draw_seq_background(scene, seq, pos, x1, x2, y1, y2, is_single_image, show_strip_color_tag);
1362 
1363  /* Draw a color band inside color strip. */
1364  if (seq->type == SEQ_TYPE_COLOR && y_threshold) {
1365  draw_color_strip_band(scene, channels, seq, pos, text_margin_y, y1);
1366  }
1367 
1368  /* Draw strip offsets when flag is enabled or during "solo preview". */
1369  if (sseq->flag & SEQ_SHOW_OVERLAY) {
1370  if (!is_single_image && pixely > 0) {
1372  (seq == special_seq_update)) {
1373  draw_sequence_extensions_overlay(scene, seq, pos, pixely, show_strip_color_tag);
1374  }
1375  }
1376  }
1377  immUnbindProgram();
1378 
1381 
1382  if ((seq->type == SEQ_TYPE_META) ||
1383  ((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS))) {
1384  drawmeta_contents(scene, seq, x1, y1, x2, y2, show_strip_color_tag);
1385  }
1386 
1387  if ((sseq->flag & SEQ_SHOW_OVERLAY) &&
1389  (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE))) {
1391  v2d, C, scene, seq, y1, y_threshold ? text_margin_y : y2, pixelx, pixely);
1392  }
1393 
1394  if ((sseq->flag & SEQ_SHOW_OVERLAY) &&
1396  draw_seq_fcurve_overlay(scene, v2d, seq, x1, y1, x2, y2, pixelx);
1397  }
1398 
1399  /* Draw sound strip waveform. */
1400  if (seq_draw_waveforms_poll(C, sseq, seq)) {
1402  C, region, seq, x1, y_threshold ? y1 + 0.05f : y1, x2, y_threshold ? text_margin_y : y2);
1403  }
1404  /* Draw locked state. */
1405  if (SEQ_transform_is_locked(channels, seq)) {
1406  draw_seq_locked(x1, y1, x2, y2);
1407  }
1408 
1409  /* Draw Red line on the top of invalid strip (Missing media). */
1410  if (!SEQ_sequence_has_source(seq)) {
1411  draw_seq_invalid(x1, x2, y2, text_margin_y);
1412  }
1413 
1416 
1417  if (!SEQ_transform_is_locked(channels, seq)) {
1419  scene, v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos, seq_active, pixelx, y_threshold);
1421  scene, v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos, seq_active, pixelx, y_threshold);
1422  }
1423 
1424  draw_seq_outline(scene, seq, pos, x1, x2, y1, y2, pixelx, pixely, seq_active);
1425 
1426  immUnbindProgram();
1427 
1428  calculate_seq_text_offsets(scene, v2d, seq, &x1, &x2, pixelx);
1429 
1430  /* If a waveform is drawn, avoid drawing text when there is not enough vertical space. */
1431  if (seq->type == SEQ_TYPE_SOUND_RAM) {
1432  if (!y_threshold && (sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) == 0 &&
1434  (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) {
1435  return;
1436  }
1437  }
1438 
1439  if (sseq->flag & SEQ_SHOW_OVERLAY) {
1440  /* Don't draw strip if there is not enough vertical or horizontal space. */
1441  if (((x2 - x1) > 32 * pixelx * U.dpi_fac) && ((y2 - y1) > 8 * pixely * U.dpi_fac)) {
1442  /* Depending on the vertical space, draw text on top or in the center of strip. */
1444  scene, v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active);
1445  }
1446  }
1447 }
1448 
1450 {
1451  Sequence *seq1 = seq->seq1;
1452  Sequence *seq2 = seq->seq2;
1453  Sequence *seq3 = seq->seq3;
1455 
1458 
1459  immUniformColor4ub(255, 255, 255, 48);
1460  immRectf(pos,
1462  seq1->machine + SEQ_STRIP_OFSBOTTOM,
1464  seq1->machine + SEQ_STRIP_OFSTOP);
1465 
1466  if (seq2 && seq2 != seq1) {
1467  immRectf(pos,
1469  seq2->machine + SEQ_STRIP_OFSBOTTOM,
1471  seq2->machine + SEQ_STRIP_OFSTOP);
1472  }
1473  if (seq3 && !ELEM(seq3, seq1, seq2)) {
1474  immRectf(pos,
1476  seq3->machine + SEQ_STRIP_OFSBOTTOM,
1478  seq3->machine + SEQ_STRIP_OFSTOP);
1479  }
1480  immUnbindProgram();
1482 }
1483 
1485 {
1486  special_seq_update = seq;
1487 }
1488 
1490 {
1491  return special_seq_update;
1492 }
1493 
1495 {
1497  ARegion *region = CTX_wm_region(C);
1498  int hand;
1499  Sequence *seq;
1500  seq = find_nearest_seq(scene, &region->v2d, &hand, mval);
1502 }
1503 
1505 {
1507 }
1508 
1510  ARegion *region,
1511  struct Depsgraph *depsgraph,
1512  Scene *scene,
1513  SpaceSeq *sseq,
1514  int timeline_frame,
1515  int frame_ofs,
1516  const char *viewname)
1517 {
1518  SeqRenderData context = {0};
1519  ImBuf *ibuf;
1520  int rectx, recty;
1521  double render_size;
1522  short is_break = G.is_break;
1523 
1524  if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
1525  return NULL;
1526  }
1527 
1528  if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
1529  render_size = scene->r.size / 100.0;
1530  }
1531  else {
1532  render_size = SEQ_rendersize_to_scale_factor(sseq->render_size);
1533  }
1534 
1535  rectx = roundf(render_size * scene->r.xsch);
1536  recty = roundf(render_size * scene->r.ysch);
1537 
1539  bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
1540  context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
1541  context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
1542 
1543  /* Sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
1544  * by Escape pressed somewhere in the past. */
1545  G.is_break = false;
1546 
1547  GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
1549  if (viewport) {
1550  /* Unbind viewport to release the DRW context. */
1551  GPU_viewport_unbind(viewport);
1552  }
1553  else {
1554  /* Rendering can change OGL context. Save & Restore frame-buffer. */
1556  }
1557 
1558  if (special_seq_update) {
1559  ibuf = SEQ_render_give_ibuf_direct(&context, timeline_frame + frame_ofs, special_seq_update);
1560  }
1561  else {
1562  ibuf = SEQ_render_give_ibuf(&context, timeline_frame + frame_ofs, sseq->chanshown);
1563  }
1564 
1565  if (viewport) {
1566  /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
1567  * viewport. */
1568  int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
1569  GPU_viewport_bind(viewport, view, &region->winrct);
1570  }
1571  else if (fb) {
1573  }
1574 
1575  /* Restore state so real rendering would be canceled if needed. */
1576  G.is_break = is_break;
1577 
1578  return ibuf;
1579 }
1580 
1581 static void sequencer_check_scopes(SequencerScopes *scopes, ImBuf *ibuf)
1582 {
1583  if (scopes->reference_ibuf != ibuf) {
1584  if (scopes->zebra_ibuf) {
1585  IMB_freeImBuf(scopes->zebra_ibuf);
1586  scopes->zebra_ibuf = NULL;
1587  }
1588 
1589  if (scopes->waveform_ibuf) {
1590  IMB_freeImBuf(scopes->waveform_ibuf);
1591  scopes->waveform_ibuf = NULL;
1592  }
1593 
1594  if (scopes->sep_waveform_ibuf) {
1596  scopes->sep_waveform_ibuf = NULL;
1597  }
1598 
1599  if (scopes->vector_ibuf) {
1600  IMB_freeImBuf(scopes->vector_ibuf);
1601  scopes->vector_ibuf = NULL;
1602  }
1603 
1604  if (scopes->histogram_ibuf) {
1605  IMB_freeImBuf(scopes->histogram_ibuf);
1606  scopes->histogram_ibuf = NULL;
1607  }
1608  }
1609 }
1610 
1611 static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(ImBuf *ibuf))
1612 {
1613  ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
1614  ImBuf *scope;
1615 
1617  display_ibuf, &scene->view_settings, &scene->display_settings);
1618 
1619  scope = make_scope_fn(display_ibuf);
1620 
1621  IMB_freeImBuf(display_ibuf);
1622 
1623  return scope;
1624 }
1625 
1626 static void sequencer_display_size(Scene *scene, float r_viewrect[2])
1627 {
1628  r_viewrect[0] = (float)scene->r.xsch;
1629  r_viewrect[1] = (float)scene->r.ysch;
1630 
1631  r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
1632 }
1633 
1635 {
1636  /* Draw grease-pencil (image aligned). */
1638 
1639  /* Orthographic at pixel level. */
1641 
1642  /* Draw grease-pencil (screen aligned). */
1644 }
1645 
1650  const View2D *v2d,
1651  const Scene *scene)
1652 {
1653  float x1 = v2d->tot.xmin;
1654  float y1 = v2d->tot.ymin;
1655  float x2 = v2d->tot.xmax;
1656  float y2 = v2d->tot.ymax;
1657 
1658  GPU_line_width(1.0f);
1659 
1660  /* Draw border. */
1661  const uint shdr_pos = GPU_vertformat_attr_add(
1663 
1665 
1666  float viewport_size[4];
1667  GPU_viewport_size_get_f(viewport_size);
1668  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
1669 
1671  immUniform1i("colors_len", 0); /* Simple dashes. */
1672  immUniform1f("dash_width", 6.0f);
1673  immUniform1f("dash_factor", 0.5f);
1674 
1675  imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
1676 
1677  /* Draw safety border. */
1680 
1681  UI_draw_safe_areas(shdr_pos,
1682  &(const rctf){
1683  .xmin = x1,
1684  .xmax = x2,
1685  .ymin = y1,
1686  .ymax = y2,
1687  },
1690 
1692  UI_draw_safe_areas(shdr_pos,
1693  &(const rctf){
1694  .xmin = x1,
1695  .xmax = x2,
1696  .ymin = y1,
1697  .ymax = y2,
1698  },
1701  }
1702  }
1703 
1704  immUnbindProgram();
1705 }
1706 
1707 #if 0
1708 void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
1709 {
1710  /* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
1711  * For now just disable drawing since the strip frame will likely be offset. */
1712 
1713  // if (sc->mode == SC_MODE_MASKEDIT)
1714  if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
1716 
1717  if (mask) {
1718  int width, height;
1719  float aspx = 1.0f, aspy = 1.0f;
1720  // ED_mask_get_size(C, &width, &height);
1721 
1722  //Scene *scene = CTX_data_scene(C);
1723  BKE_render_resolution(&scene->r, false, &width, &height);
1724 
1726  region,
1727  0,
1728  0,
1729  0, /* TODO */
1730  width,
1731  height,
1732  aspx,
1733  aspy,
1734  false,
1735  true,
1736  NULL,
1737  C);
1738  }
1739  }
1740 }
1741 #endif
1742 
1743 /* Force redraw, when prefetching and using cache view. */
1745 {
1748  }
1749 }
1750 
1752  ImBuf *ibuf,
1753  bool *r_glsl_used,
1754  eGPUTextureFormat *r_format,
1755  eGPUDataFormat *r_data,
1756  void **r_buffer_cache_handle)
1757 {
1758  void *display_buffer;
1759  bool force_fallback = false;
1760  *r_glsl_used = false;
1761  force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
1762  force_fallback |= (ibuf->dither != 0.0f);
1763 
1764  /* Default */
1765  *r_format = GPU_RGBA8;
1766  *r_data = GPU_DATA_UBYTE;
1767 
1768  /* Fallback to CPU based color space conversion. */
1769  if (force_fallback) {
1770  *r_glsl_used = false;
1771  display_buffer = NULL;
1772  }
1773  else if (ibuf->rect_float) {
1774  display_buffer = ibuf->rect_float;
1775 
1776  *r_data = GPU_DATA_FLOAT;
1777  if (ibuf->channels == 4) {
1778  *r_format = GPU_RGBA16F;
1779  }
1780  else if (ibuf->channels == 3) {
1781  /* Alpha is implicitly 1. */
1782  *r_format = GPU_RGB16F;
1783  }
1784  else {
1785  BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
1786  *r_format = GPU_RGBA16F;
1787  display_buffer = NULL;
1788  }
1789 
1790  if (ibuf->float_colorspace) {
1792  C, ibuf->float_colorspace, ibuf->dither, true);
1793  }
1794  else {
1795  *r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
1796  }
1797  }
1798  else if (ibuf->rect) {
1799  display_buffer = ibuf->rect;
1800 
1802  C, ibuf->rect_colorspace, ibuf->dither, false);
1803  }
1804  else {
1805  display_buffer = NULL;
1806  }
1807 
1808  /* There is data to be displayed, but GLSL is not initialized
1809  * properly, in this case we fallback to CPU-based display transform. */
1810  if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
1811  display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
1812  *r_format = GPU_RGBA8;
1813  *r_data = GPU_DATA_UBYTE;
1814  }
1815 
1816  return display_buffer;
1817 }
1818 
1820 {
1821  if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
1822  /* Stop all running jobs, except screen one. Currently previews frustrate Render.
1823  * Need to make so sequencers rendering doesn't conflict with compositor. */
1825 
1826  /* In case of final rendering used for preview, kill all previews,
1827  * otherwise threading conflict will happen in rendering module. */
1829  }
1830 }
1831 
1832 static void sequencer_preview_clear(void)
1833 {
1835 }
1836 
1838  Scene *scene,
1839  ARegion *region,
1840  SpaceSeq *sseq,
1841  bool draw_overlay,
1842  bool draw_backdrop)
1843 {
1844  struct View2D *v2d = &region->v2d;
1845  float viewrect[2];
1846 
1847  sequencer_display_size(scene, viewrect);
1848  BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
1849 
1850  if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
1851  preview->xmax = v2d->tot.xmin +
1853  preview->xmin = v2d->tot.xmin +
1855  preview->ymax = v2d->tot.ymin +
1857  preview->ymin = v2d->tot.ymin +
1859  }
1860  else if (draw_backdrop) {
1861  float aspect = BLI_rcti_size_x(&region->winrct) / (float)BLI_rcti_size_y(&region->winrct);
1862  float image_aspect = viewrect[0] / viewrect[1];
1863 
1864  if (aspect >= image_aspect) {
1865  preview->xmax = image_aspect / aspect;
1866  preview->xmin = -preview->xmax;
1867  }
1868  else {
1869  preview->ymax = aspect / image_aspect;
1870  preview->ymin = -preview->ymax;
1871  }
1872  }
1873  else {
1874  *preview = v2d->tot;
1875  }
1876 }
1877 
1879  Scene *scene,
1880  ARegion *region,
1881  SpaceSeq *sseq,
1882  ImBuf *ibuf,
1883  ImBuf *scope,
1884  bool draw_overlay,
1885  bool draw_backdrop)
1886 {
1887  void *display_buffer;
1888  void *buffer_cache_handle = NULL;
1889 
1890  if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
1892  }
1893 
1894  /* Format needs to be created prior to any #immBindShader call.
1895  * Do it here because OCIO binds its own shader. */
1898  bool glsl_used = false;
1899  GPUVertFormat *imm_format = immVertexFormat();
1900  uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1901  uint texCoord = GPU_vertformat_attr_add(
1902  imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1903 
1904  if (scope) {
1905  ibuf = scope;
1906 
1907  if (ibuf->rect_float && ibuf->rect == NULL) {
1908  IMB_rect_from_float(ibuf);
1909  }
1910 
1911  display_buffer = (uchar *)ibuf->rect;
1912  format = GPU_RGBA8;
1913  data = GPU_DATA_UBYTE;
1914  }
1915  else {
1916  display_buffer = sequencer_OCIO_transform_ibuf(
1917  C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
1918  }
1919 
1920  if (draw_backdrop) {
1921  GPU_matrix_push();
1925  }
1926 
1927  GPUTexture *texture = GPU_texture_create_2d(
1928  "seq_display_buf", ibuf->x, ibuf->y, 1, format, NULL);
1929  GPU_texture_update(texture, data, display_buffer);
1930  GPU_texture_filter_mode(texture, false);
1931 
1932  GPU_texture_bind(texture, 0);
1933 
1934  if (!glsl_used) {
1936  immUniformColor3f(1.0f, 1.0f, 1.0f);
1937  }
1938 
1940 
1941  rctf preview;
1942  rctf canvas;
1943  sequencer_preview_get_rect(&preview, scene, region, sseq, draw_overlay, draw_backdrop);
1944 
1945  if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
1946  canvas = scene->ed->overlay_frame_rect;
1947  }
1948  else {
1949  BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
1950  }
1951 
1952  immAttr2f(texCoord, canvas.xmin, canvas.ymin);
1953  immVertex2f(pos, preview.xmin, preview.ymin);
1954 
1955  immAttr2f(texCoord, canvas.xmin, canvas.ymax);
1956  immVertex2f(pos, preview.xmin, preview.ymax);
1957 
1958  immAttr2f(texCoord, canvas.xmax, canvas.ymax);
1959  immVertex2f(pos, preview.xmax, preview.ymax);
1960 
1961  immAttr2f(texCoord, canvas.xmax, canvas.ymin);
1962  immVertex2f(pos, preview.xmax, preview.ymin);
1963 
1964  immEnd();
1965 
1966  GPU_texture_unbind(texture);
1967  GPU_texture_free(texture);
1968 
1969  if (!glsl_used) {
1970  immUnbindProgram();
1971  }
1972  else {
1974  }
1975 
1976  if (buffer_cache_handle) {
1977  IMB_display_buffer_release(buffer_cache_handle);
1978  }
1979 
1980  if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
1982  }
1983 
1984  if (draw_backdrop) {
1985  GPU_matrix_pop();
1987  }
1988 }
1989 
1991 {
1992  struct ImBuf *scope = NULL;
1993  SequencerScopes *scopes = &sseq->scopes;
1994 
1995  if (!draw_backdrop && (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0)) {
1996  sequencer_check_scopes(scopes, ibuf);
1997 
1998  switch (sseq->mainb) {
1999  case SEQ_DRAW_IMG_IMBUF:
2000  if (!scopes->zebra_ibuf) {
2001  ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
2002 
2003  if (display_ibuf->rect_float) {
2005  display_ibuf, &scene->view_settings, &scene->display_settings);
2006  }
2007  scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra);
2008  IMB_freeImBuf(display_ibuf);
2009  }
2010  scope = scopes->zebra_ibuf;
2011  break;
2012  case SEQ_DRAW_IMG_WAVEFORM:
2013  if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
2014  if (!scopes->sep_waveform_ibuf) {
2017  }
2018  scope = scopes->sep_waveform_ibuf;
2019  }
2020  else {
2021  if (!scopes->waveform_ibuf) {
2024  }
2025  scope = scopes->waveform_ibuf;
2026  }
2027  break;
2029  if (!scopes->vector_ibuf) {
2031  }
2032  scope = scopes->vector_ibuf;
2033  break;
2035  if (!scopes->histogram_ibuf) {
2038  }
2039  scope = scopes->histogram_ibuf;
2040  break;
2041  }
2042 
2043  /* Future files may have new scopes we don't catch above. */
2044  if (scope) {
2045  scopes->reference_ibuf = ibuf;
2046  }
2047  }
2048  return scope;
2049 }
2050 
2052 {
2053  Sequence *last_seq = SEQ_select_active_get(scene);
2054  if (last_seq == NULL) {
2055  return false;
2056  }
2057 
2058  return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
2059  ((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
2061 }
2062 
2064 {
2065  Sequence *last_seq = SEQ_select_active_get(scene);
2066  /* #sequencer_draw_get_transform_preview must already have been called. */
2067  BLI_assert(last_seq != NULL);
2068  int preview_frame;
2069 
2070  if (last_seq->flag & SEQ_RIGHTSEL) {
2071  preview_frame = SEQ_time_right_handle_frame_get(scene, last_seq) - 1;
2072  }
2073  else {
2074  preview_frame = SEQ_time_left_handle_frame_get(scene, last_seq);
2075  }
2076 
2077  return preview_frame;
2078 }
2079 
2080 static void seq_draw_image_origin_and_outline(const bContext *C, Sequence *seq, bool is_active_seq)
2081 {
2082  SpaceSeq *sseq = CTX_wm_space_seq(C);
2083  const ARegion *region = CTX_wm_region(C);
2085  return;
2086  }
2087  if ((seq->flag & SELECT) == 0) {
2088  return;
2089  }
2091  return;
2092  }
2093  if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
2095  return;
2096  }
2098  return;
2099  }
2100 
2101  float origin[2];
2103 
2104  /* Origin. */
2108  immUniform1f("outlineWidth", 1.5f);
2109  immUniformColor3f(1.0f, 1.0f, 1.0f);
2110  immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
2111  immUniform1f("size", 15.0f * U.pixelsize);
2113  immVertex2f(pos, origin[0], origin[1]);
2114  immEnd();
2115  immUnbindProgram();
2116 
2117  /* Outline. */
2118  float seq_image_quad[4][2];
2119  SEQ_image_transform_final_quad_get(CTX_data_scene(C), seq, seq_image_quad);
2120 
2121  GPU_line_smooth(true);
2123  GPU_line_width(2);
2125 
2126  float col[3];
2127  if (is_active_seq) {
2129  }
2130  else {
2132  }
2134  immUniform1f("lineWidth", U.pixelsize);
2136  immVertex2f(pos, seq_image_quad[0][0], seq_image_quad[0][1]);
2137  immVertex2f(pos, seq_image_quad[1][0], seq_image_quad[1][1]);
2138  immVertex2f(pos, seq_image_quad[2][0], seq_image_quad[2][1]);
2139  immVertex2f(pos, seq_image_quad[3][0], seq_image_quad[3][1]);
2140  immEnd();
2141  immUnbindProgram();
2142  GPU_line_width(1);
2144  GPU_line_smooth(false);
2145 }
2146 
2148  Scene *scene,
2149  ARegion *region,
2150  SpaceSeq *sseq,
2151  int timeline_frame,
2152  int offset,
2153  bool draw_overlay,
2154  bool draw_backdrop)
2155 {
2156  struct Main *bmain = CTX_data_main(C);
2158  struct View2D *v2d = &region->v2d;
2159  struct ImBuf *ibuf = NULL;
2160  struct ImBuf *scope = NULL;
2161  float viewrect[2];
2162  const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
2163  const bool draw_gpencil = ((sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && sseq->gpd);
2164  const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
2165 
2167  if (G.is_rendering) {
2168  return;
2169  }
2170 
2171  int preview_frame = timeline_frame;
2174  }
2175 
2176  /* Get image. */
2177  ibuf = sequencer_ibuf_get(
2178  bmain, region, depsgraph, scene, sseq, preview_frame, offset, names[sseq->multiview_eye]);
2179 
2180  /* Setup off-screen buffers. */
2181  GPUViewport *viewport = WM_draw_region_get_viewport(region);
2182  GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
2183  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2185 
2186  if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
2188  return;
2189  }
2190 
2191  /* Setup view. */
2192  sequencer_display_size(scene, viewrect);
2193  UI_view2d_totRect_set(v2d, roundf(viewrect[0] + 0.5f), roundf(viewrect[1] + 0.5f));
2195  UI_view2d_view_ortho(v2d);
2196 
2197  /* Draw background. */
2198  if (!draw_backdrop &&
2199  (!draw_overlay || (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_REFERENCE))) {
2201 
2202  if (sseq->flag & SEQ_USE_ALPHA) {
2203  imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
2204  }
2205  }
2206 
2207  if (ibuf) {
2208  scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
2209 
2210  /* Draw image. */
2212  C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop);
2213 
2214  /* Draw over image. */
2216  ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
2217  }
2218  }
2219 
2220  if (show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
2222  }
2223 
2224  if (!draw_backdrop && scene->ed != NULL) {
2225  Editing *ed = SEQ_editing_get(scene);
2228  scene, channels, ed->seqbasep, timeline_frame, 0);
2229  Sequence *seq;
2230  Sequence *active_seq = SEQ_select_active_get(scene);
2231  SEQ_ITERATOR_FOREACH (seq, collection) {
2232  seq_draw_image_origin_and_outline(C, seq, seq == active_seq);
2233  }
2234  SEQ_collection_free(collection);
2235  }
2236 
2237  if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
2239  }
2240 
2241 #if 0
2242  sequencer_draw_maskedit(C, scene, region, sseq);
2243 #endif
2244 
2245  /* Draw registered callbacks. */
2246  GPU_framebuffer_bind(framebuffer_overlay);
2248  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2249 
2250  /* Scope is freed in sequencer_check_scopes when `ibuf` changes and redraw is needed. */
2251  if (ibuf) {
2252  IMB_freeImBuf(ibuf);
2253  }
2254 
2257 }
2258 
2260 {
2265 
2266  /* Alternating horizontal stripes. */
2267  int i = max_ii(1, ((int)v2d->cur.ymin) - 1);
2268  while (i < v2d->cur.ymax) {
2269  if (i & 1) {
2270  immRectf(pos, v2d->cur.xmin, i, v2d->cur.xmax, i + 1);
2271  }
2272  i++;
2273  }
2274 
2276  immUnbindProgram();
2277 }
2278 
2279 static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
2280 {
2282  View2D *v2d = &region->v2d;
2283  SpaceSeq *sseq = CTX_wm_space_seq(C);
2284  Sequence *last_seq = SEQ_select_active_get(scene);
2285  int sel = 0, j;
2286  float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
2287 
2288  /* Loop through twice, first unselected, then selected. */
2289  for (j = 0; j < 2; j++) {
2290  Sequence *seq;
2291  /* Loop through strips, checking for those that are visible. */
2292  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2293  /* Bound-box and selection tests for NOT drawing the strip. */
2294  if ((seq->flag & SELECT) != sel) {
2295  continue;
2296  }
2297  if (seq == last_seq && (last_seq->flag & SELECT)) {
2298  continue;
2299  }
2301  v2d->cur.xmax) {
2302  continue;
2303  }
2306  v2d->cur.xmin) {
2307  continue;
2308  }
2309  if (seq->machine + 1.0f < v2d->cur.ymin) {
2310  continue;
2311  }
2312  if (seq->machine > v2d->cur.ymax) {
2313  continue;
2314  }
2315 
2316  /* Strip passed all tests, draw it now. */
2317  draw_seq_strip(C, sseq, scene, region, seq, pixelx, seq == last_seq ? true : false);
2318  }
2319 
2320  /* Draw selected next time round. */
2321  sel = SELECT;
2322  }
2323 
2324  /* When selected draw the last selected (active) strip last,
2325  * removes some overlapping error. */
2326  if (last_seq && (last_seq->flag & SELECT)) {
2327  draw_seq_strip(C, sseq, scene, region, last_seq, pixelx, true);
2328 
2329  /* When active strip is an effect, highlight its inputs. */
2330  if (SEQ_effect_get_num_inputs(last_seq->type) > 0) {
2332  }
2333  /* When active is a Multi-cam strip, highlight its source channel. */
2334  else if (last_seq->type == SEQ_TYPE_MULTICAM) {
2335  int channel = last_seq->multicam_source;
2336  if (channel != 0) {
2341 
2342  immUniformColor4ub(255, 255, 255, 48);
2343  immRectf(pos, v2d->cur.xmin, channel, v2d->cur.xmax, channel + 1);
2344 
2345  immUnbindProgram();
2347  }
2348  }
2349  }
2350 
2351  /* Draw highlight if "solo preview" is used. */
2352  if (special_seq_update) {
2353  const Sequence *seq = special_seq_update;
2355 
2358 
2359  immUniformColor4ub(255, 255, 255, 48);
2360  immRectf(pos,
2364  seq->machine + SEQ_STRIP_OFSTOP);
2365 
2366  immUnbindProgram();
2367 
2369  }
2370 }
2371 
2372 static void seq_draw_sfra_efra(const Scene *scene, View2D *v2d)
2373 {
2374  const Editing *ed = SEQ_editing_get(scene);
2375  const int frame_sta = scene->r.sfra;
2376  const int frame_end = scene->r.efra + 1;
2377 
2379 
2382 
2383  /* Draw overlay outside of frame range. */
2385 
2386  if (frame_sta < frame_end) {
2387  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax);
2388  immRectf(pos, (float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2389  }
2390  else {
2391  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2392  }
2393 
2395 
2396  /* Draw frame range boundary. */
2398 
2399  immVertex2f(pos, frame_sta, v2d->cur.ymin);
2400  immVertex2f(pos, frame_sta, v2d->cur.ymax);
2401 
2402  immVertex2f(pos, frame_end, v2d->cur.ymin);
2403  immVertex2f(pos, frame_end, v2d->cur.ymax);
2404 
2405  immEnd();
2406 
2407  /* While in meta strip, draw a checkerboard overlay outside of frame range. */
2408  if (ed && !BLI_listbase_is_empty(&ed->metastack)) {
2409  const MetaStack *ms = ed->metastack.last;
2410  immUnbindProgram();
2411 
2413 
2414  immUniform4f("color1", 0.0f, 0.0f, 0.0f, 0.22f);
2415  immUniform4f("color2", 1.0f, 1.0f, 1.0f, 0.0f);
2416  immUniform1i("size", 8);
2417 
2418  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, ms->disp_range[0], v2d->cur.ymax);
2419  immRectf(pos, ms->disp_range[1], v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2420 
2421  immUnbindProgram();
2422 
2425 
2427 
2428  immVertex2f(pos, ms->disp_range[0], v2d->cur.ymin);
2429  immVertex2f(pos, ms->disp_range[0], v2d->cur.ymax);
2430 
2431  immVertex2f(pos, ms->disp_range[1], v2d->cur.ymin);
2432  immVertex2f(pos, ms->disp_range[1], v2d->cur.ymax);
2433 
2434  immEnd();
2435  }
2436 
2437  immUnbindProgram();
2438 
2440 }
2441 
2442 typedef struct CacheDrawData {
2443  struct View2D *v2d;
2445  float stripe_ht;
2456 
2457 /* Called as a callback. */
2458 static bool draw_cache_view_init_fn(void *userdata, size_t item_count)
2459 {
2460  if (item_count == 0) {
2461  return true;
2462  }
2463 
2464  CacheDrawData *drawdata = userdata;
2465  /* We can not get item count per cache type, so using total item count is safe. */
2466  size_t max_vert_count = item_count * 6;
2467  GPU_vertbuf_data_alloc(drawdata->raw_vbo, max_vert_count);
2468  GPU_vertbuf_data_alloc(drawdata->preprocessed_vbo, max_vert_count);
2469  GPU_vertbuf_data_alloc(drawdata->composite_vbo, max_vert_count);
2470  GPU_vertbuf_data_alloc(drawdata->final_out_vbo, max_vert_count);
2471 
2472  return false;
2473 }
2474 
2475 /* Called as a callback */
2476 static bool draw_cache_view_iter_fn(void *userdata,
2477  struct Sequence *seq,
2478  int timeline_frame,
2479  int cache_type)
2480 {
2481  CacheDrawData *drawdata = userdata;
2482  struct View2D *v2d = drawdata->v2d;
2483  float stripe_bot, stripe_top, stripe_ofs_y, stripe_ht;
2484  GPUVertBuf *vbo;
2485  size_t *vert_count;
2486 
2487  if ((cache_type & SEQ_CACHE_STORE_FINAL_OUT) &&
2488  (drawdata->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT)) {
2489  stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) - v2d->cur.ymin;
2491  stripe_top = stripe_bot + stripe_ht;
2492  vbo = drawdata->final_out_vbo;
2493  vert_count = &drawdata->final_out_vert_count;
2494  }
2495  else if ((cache_type & SEQ_CACHE_STORE_RAW) && (drawdata->cache_flag & SEQ_CACHE_VIEW_RAW)) {
2496  stripe_ofs_y = drawdata->stripe_ofs_y;
2497  stripe_ht = drawdata->stripe_ht;
2498  stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_ofs_y;
2499  stripe_top = stripe_bot + stripe_ht;
2500  vbo = drawdata->raw_vbo;
2501  vert_count = &drawdata->raw_vert_count;
2502  }
2503  else if ((cache_type & SEQ_CACHE_STORE_PREPROCESSED) &&
2504  (drawdata->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED)) {
2505  stripe_ofs_y = drawdata->stripe_ofs_y;
2506  stripe_ht = drawdata->stripe_ht;
2507  stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + (stripe_ofs_y + stripe_ht) + stripe_ofs_y;
2508  stripe_top = stripe_bot + stripe_ht;
2509  vbo = drawdata->preprocessed_vbo;
2510  vert_count = &drawdata->preprocessed_vert_count;
2511  }
2512  else if ((cache_type & SEQ_CACHE_STORE_COMPOSITE) &&
2513  (drawdata->cache_flag & SEQ_CACHE_VIEW_COMPOSITE)) {
2514  stripe_ofs_y = drawdata->stripe_ofs_y;
2515  stripe_ht = drawdata->stripe_ht;
2516  stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_ofs_y;
2517  stripe_bot = stripe_top - stripe_ht;
2518  vbo = drawdata->composite_vbo;
2519  vert_count = &drawdata->composite_vert_count;
2520  }
2521  else {
2522  return false;
2523  }
2524 
2525  float vert_pos[6][2];
2526  copy_v2_fl2(vert_pos[0], timeline_frame, stripe_bot);
2527  copy_v2_fl2(vert_pos[1], timeline_frame, stripe_top);
2528  copy_v2_fl2(vert_pos[2], timeline_frame + 1, stripe_top);
2529  copy_v2_v2(vert_pos[3], vert_pos[2]);
2530  copy_v2_v2(vert_pos[4], vert_pos[0]);
2531  copy_v2_fl2(vert_pos[5], timeline_frame + 1, stripe_bot);
2532 
2533  for (int i = 0; i < 6; i++) {
2534  GPU_vertbuf_vert_set(vbo, *vert_count + i, vert_pos[i]);
2535  }
2536 
2537  *vert_count += 6;
2538  return false;
2539 }
2540 
2542  GPUVertBuf *vbo, size_t vert_count, float col_r, float col_g, float col_b, float col_a)
2543 {
2545  if (vert_count > 0) {
2546  GPU_vertbuf_data_len_set(vbo, vert_count);
2548  GPU_batch_uniform_4f(batch, "color", col_r, col_g, col_b, col_a);
2550  }
2552 }
2553 
2554 static void draw_cache_view(const bContext *C)
2555 {
2557  ARegion *region = CTX_wm_region(C);
2558  struct View2D *v2d = &region->v2d;
2559 
2560  if ((scene->ed->cache_flag & SEQ_CACHE_VIEW_ENABLE) == 0) {
2561  return;
2562  }
2563 
2567 
2568  float stripe_bot, stripe_top;
2569  float stripe_ofs_y = UI_view2d_region_to_view_y(v2d, 1.0f) - v2d->cur.ymin;
2570  float stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) -
2571  v2d->cur.ymin;
2572 
2573  CLAMP_MAX(stripe_ht, 0.2f);
2574  CLAMP_MIN(stripe_ofs_y, stripe_ht / 2);
2575 
2578  stripe_top = stripe_bot + stripe_ht;
2579  const float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f};
2580 
2581  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2582  immRectf(pos, scene->r.sfra, stripe_bot, scene->r.efra, stripe_top);
2583  }
2584 
2585  for (Sequence *seq = scene->ed->seqbasep->first; seq != NULL; seq = seq->next) {
2586  if (seq->type == SEQ_TYPE_SOUND_RAM) {
2587  continue;
2588  }
2589 
2590  if (SEQ_time_left_handle_frame_get(scene, seq) > v2d->cur.xmax ||
2592  continue;
2593  }
2594 
2595  stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_ofs_y;
2596  stripe_top = stripe_bot + stripe_ht;
2597 
2599  const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f};
2600  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2601  immRectf(pos,
2603  stripe_bot,
2605  stripe_top);
2606  }
2607 
2608  stripe_bot += stripe_ht + stripe_ofs_y;
2609  stripe_top = stripe_bot + stripe_ht;
2610 
2612  const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f};
2613  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2614  immRectf(pos,
2616  stripe_bot,
2618  stripe_top);
2619  }
2620 
2621  stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_ofs_y;
2622  stripe_bot = stripe_top - stripe_ht;
2623 
2625  const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f};
2626  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2627  immRectf(pos,
2629  stripe_bot,
2631  stripe_top);
2632  }
2633  }
2634 
2635  immUnbindProgram();
2636 
2637  GPUVertFormat format = {0};
2639 
2640  CacheDrawData userdata;
2641  userdata.v2d = v2d;
2642  userdata.stripe_ofs_y = stripe_ofs_y;
2643  userdata.stripe_ht = stripe_ht;
2644  userdata.cache_flag = scene->ed->cache_flag;
2645  userdata.raw_vert_count = 0;
2646  userdata.preprocessed_vert_count = 0;
2647  userdata.composite_vert_count = 0;
2648  userdata.final_out_vert_count = 0;
2653 
2655 
2656  draw_cache_view_batch(userdata.raw_vbo, userdata.raw_vert_count, 1.0f, 0.1f, 0.02f, 0.4f);
2658  userdata.preprocessed_vbo, userdata.preprocessed_vert_count, 0.1f, 0.1f, 0.75f, 0.4f);
2660  userdata.composite_vbo, userdata.composite_vert_count, 1.0f, 0.6f, 0.0f, 0.4f);
2662  userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f);
2663 
2665 }
2666 
2667 /* Draw sequencer timeline. */
2668 static void draw_overlap_frame_indicator(const struct Scene *scene, const View2D *v2d)
2669 {
2670  int overlap_frame = (scene->ed->overlay_frame_flag & SEQ_EDIT_OVERLAY_FRAME_ABS) ?
2673 
2676  float viewport_size[4];
2677  GPU_viewport_size_get_f(viewport_size);
2678  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
2679  /* Shader may have color set from past usage - reset it. */
2680  immUniform1i("colors_len", 0);
2681  immUniform1f("dash_width", 20.0f * U.pixelsize);
2682  immUniform1f("dash_factor", 0.5f);
2684 
2686  immVertex2f(pos, overlap_frame, v2d->cur.ymin);
2687  immVertex2f(pos, overlap_frame, v2d->cur.ymax);
2688  immEnd();
2689 
2690  immUnbindProgram();
2691 }
2692 
2693 void draw_timeline_seq(const bContext *C, ARegion *region)
2694 {
2696  Editing *ed = SEQ_editing_get(scene);
2697  SpaceSeq *sseq = CTX_wm_space_seq(C);
2698  View2D *v2d = &region->v2d;
2699  float col[3];
2700 
2702 
2703  GPUViewport *viewport = WM_draw_region_get_viewport(region);
2704  GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
2705  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2707 
2709  GPU_clear_color(col[0], col[1], col[2], 0.0f);
2710 
2711  UI_view2d_view_ortho(v2d);
2713 
2714  if ((sseq->flag & SEQ_SHOW_OVERLAY) && (sseq->timeline_overlay.flag & SEQ_TIMELINE_SHOW_GRID)) {
2715  U.v2d_min_gridsize *= 3;
2717  v2d, scene, (sseq->flag & SEQ_DRAWFRAMES) == 0, false);
2718  U.v2d_min_gridsize /= 3;
2719  }
2720 
2721  /* Only draw backdrop in timeline view. */
2722  if (sseq->view == SEQ_VIEW_SEQUENCE && sseq->draw_flag & SEQ_DRAW_BACKDROP) {
2723  int preview_frame = scene->r.cfra;
2726  }
2727 
2728  sequencer_draw_preview(C, scene, region, sseq, preview_frame, 0, false, true);
2729  UI_view2d_view_ortho(v2d);
2730  }
2731 
2732  /* Draw attached callbacks. */
2733  GPU_framebuffer_bind(framebuffer_overlay);
2735  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2736 
2737  seq_draw_sfra_efra(scene, v2d);
2738 
2739  if (ed) {
2740  draw_seq_strips(C, ed, region);
2741  /* Draw text added in previous function. */
2742  UI_view2d_text_cache_draw(region);
2743  }
2744 
2745  UI_view2d_view_ortho(v2d);
2746 
2747  UI_view2d_view_orthoSpecial(region, v2d, 1);
2748  int marker_draw_flag = DRAW_MARKERS_MARGIN;
2749  if (sseq->flag & SEQ_SHOW_MARKERS) {
2750  ED_markers_draw(C, marker_draw_flag);
2751  }
2752 
2753  UI_view2d_view_ortho(v2d);
2754  ANIM_draw_previewrange(C, v2d, 1);
2755 
2756  if ((sseq->gizmo_flag & SEQ_GIZMO_HIDE) == 0) {
2758  }
2759 
2760  /* Draw registered callbacks. */
2761  GPU_framebuffer_bind(framebuffer_overlay);
2763  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2764 
2766  ED_time_scrub_draw(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
2767 }
2768 
2770 {
2771  const Scene *scene = CTX_data_scene(C);
2772  const SpaceSeq *sseq = CTX_wm_space_seq(C);
2773  View2D *v2d = &region->v2d;
2774 
2775  if (scene->ed != NULL) {
2776  UI_view2d_view_ortho(v2d);
2777  draw_cache_view(C);
2780  }
2782  }
2783 
2785 
2787  SEQ_timeline_boundbox(scene, seqbase, &v2d->tot);
2789 }
typedef float(TangentPoint)[2]
int ED_draw_imbuf_method(struct ImBuf *ibuf)
Definition: glutil.c:600
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct SpaceSeq * CTX_wm_space_seq(const bContext *C)
Definition: context.c:851
struct Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
Definition: context.c:1519
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2135
bool BKE_fcurve_is_empty(struct FCurve *fcu)
Definition: fcurve.c:2198
struct FCurve * id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, bool *r_driven)
Definition: fcurve.c:201
@ G_TRANSFORM_SEQ
Definition: BKE_global.h:249
void BKE_render_resolution(const struct RenderData *r, const bool use_crop, int *r_width, int *r_height)
Definition: scene.cc:2960
int BKE_scene_multiview_view_id_get(const struct RenderData *rd, const char *viewname)
#define SOUND_WAVE_SAMPLES_PER_SECOND
Definition: BKE_sound.h:13
int BLF_default(void)
Definition: blf_default.c:44
float BLF_width(int fontid, const char *str, size_t str_len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:688
int BLF_set_default(void)
Definition: blf_default.c:50
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition: BLI_assert.h:53
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
MINLINE int round_fl_to_int(float a)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE float min_ff(float a, float b)
MINLINE int max_ii(int a, int b)
void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
Definition: math_color.c:503
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
Definition: math_color.c:391
MINLINE void copy_v2_fl2(float v[2], float x, float y)
MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1531
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition: rct.c:407
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:485
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_string_join_array(char *result, size_t result_len, const char *strings[], uint strings_len) ATTR_NONNULL()
Definition: string_utils.c:347
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_spin_unlock(SpinLock *spin)
Definition: threads.cc:452
void BLI_spin_lock(SpinLock *spin)
Definition: threads.cc:433
#define CLAMP_MAX(a, c)
#define ARRAY_SIZE(arr)
#define UNUSED(x)
#define ELEM(...)
#define CLAMP_MIN(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
@ OB_RENDER
Object is a sort of wrapper for general info.
#define STEREO_LEFT_NAME
eSeqOverlapMode
@ SEQ_OVERLAP_OVERWRITE
#define STEREO_RIGHT_NAME
@ STEREO_RIGHT_ID
#define FPS
@ RGN_TYPE_WINDOW
@ RGN_TYPE_PREVIEW
@ SEQ_TYPE_TRANSFORM
@ SEQ_TYPE_SOUND_RAM
@ SEQ_TYPE_CROSS
@ SEQ_TYPE_GLOW
@ SEQ_TYPE_COLORMIX
@ SEQ_TYPE_WIPE
@ SEQ_TYPE_META
@ SEQ_TYPE_OVERDROP
@ SEQ_TYPE_ALPHAUNDER
@ SEQ_TYPE_SCENE
@ SEQ_TYPE_GAMCROSS
@ SEQ_TYPE_MULTICAM
@ SEQ_TYPE_MOVIECLIP
@ SEQ_TYPE_MUL
@ SEQ_TYPE_GAUSSIAN_BLUR
@ SEQ_TYPE_ADD
@ SEQ_TYPE_ALPHAOVER
@ SEQ_TYPE_TEXT
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_SUB
@ SEQ_TYPE_SPEED
@ SEQ_TYPE_COLOR
@ SEQ_TYPE_EFFECT
@ SEQ_TYPE_MOVIE
@ SEQ_TYPE_MASK
@ SEQ_TYPE_ADJUSTMENT
#define SEQ_EDIT_OVERLAY_FRAME_ABS
@ SEQUENCE_COLOR_NONE
@ SEQUENCE_COLOR_TOT
#define SEQ_EDIT_OVERLAY_FRAME_SHOW
@ SEQ_CACHE_VIEW_RAW
@ SEQ_CACHE_STORE_PREPROCESSED
@ SEQ_CACHE_STORE_RAW
@ SEQ_CACHE_STORE_FINAL_OUT
@ SEQ_CACHE_VIEW_ENABLE
@ SEQ_CACHE_STORE_COMPOSITE
@ SEQ_CACHE_VIEW_FINAL_OUT
@ SEQ_CACHE_VIEW_COMPOSITE
@ SEQ_CACHE_VIEW_PREPROCESSED
@ SEQ_RIGHTSEL
@ SEQ_SCENE_STRIPS
@ SEQ_OVERLAP
@ SEQ_AUDIO_DRAW_WAVEFORM
@ SEQ_LEFTSEL
#define SEQ_STRIP_OFSBOTTOM
#define MAXSEQ
#define SEQ_STRIP_OFSTOP
@ SOUND_TAGS_WAVEFORM_LOADING
@ SEQ_RENDER_SIZE_SCENE
@ SEQ_RENDER_SIZE_NONE
@ SPACE_SEQ
@ SEQ_TIMELINE_SHOW_FCURVES
@ SEQ_TIMELINE_SHOW_STRIP_DURATION
@ SEQ_TIMELINE_SHOW_THUMBNAILS
@ SEQ_TIMELINE_SHOW_STRIP_OFFSETS
@ SEQ_TIMELINE_ALL_WAVEFORMS
@ SEQ_TIMELINE_SHOW_STRIP_SOURCE
@ SEQ_TIMELINE_SHOW_STRIP_NAME
@ SEQ_TIMELINE_SHOW_GRID
@ SEQ_TIMELINE_NO_WAVEFORMS
@ SEQ_TIMELINE_SHOW_STRIP_COLOR_TAG
@ SEQ_GIZMO_HIDE
@ SEQ_VIEW_SEQUENCE
@ SEQ_PREVIEW_SHOW_METADATA
@ SEQ_PREVIEW_SHOW_GPENCIL
@ SEQ_PREVIEW_SHOW_SAFE_MARGINS
@ SEQ_PREVIEW_SHOW_OUTLINE_SELECTED
@ SEQ_PREVIEW_SHOW_SAFE_CENTER
@ SEQ_DRAW_TRANSFORM_PREVIEW
@ SEQ_DRAW_BACKDROP
@ SEQ_OVERLAY_FRAME_TYPE_RECT
@ SEQ_OVERLAY_FRAME_TYPE_REFERENCE
@ SEQ_DRAW_IMG_VECTORSCOPE
@ SEQ_DRAW_IMG_HISTOGRAM
@ SEQ_DRAW_IMG_IMBUF
@ SEQ_DRAW_IMG_WAVEFORM
@ SEQ_DRAWFRAMES
@ SEQ_SHOW_MARKERS
@ SEQ_USE_ALPHA
@ SEQ_USE_PROXIES
@ SEQ_DRAW_COLOR_SEPARATED
@ SEQ_SHOW_OVERLAY
@ IMAGE_DRAW_METHOD_GLSL
@ DRAW_MARKERS_MARGIN
Definition: ED_markers.h:28
void ED_mask_draw_region(struct Depsgraph *depsgraph, struct Mask *mask, struct 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 struct bContext *C)
bScreen * ED_screen_animation_no_scrub(const struct wmWindowManager *wm)
bool ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq)
#define REGION_DRAW_POST_VIEW
Definition: ED_space_api.h:62
void ED_region_draw_cb_draw(const struct bContext *C, struct ARegion *region, int type)
#define REGION_DRAW_PRE_VIEW
Definition: ED_space_api.h:64
void ED_region_image_metadata_draw(int x, int y, struct ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
Definition: ed_draw.c:755
static AppView * view
GPUBatch
Definition: GPU_batch.h:78
void GPU_batch_discard(GPUBatch *)
Definition: gpu_batch.cc:109
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
Definition: gpu_batch.cc:287
GPUBatch * GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, eGPUBatchFlag owns_flag)
Definition: gpu_batch.cc:43
void GPU_batch_draw(GPUBatch *batch)
Definition: gpu_batch.cc:223
#define GPU_batch_uniform_4f(batch, name, x, y, z, w)
Definition: GPU_batch.h:148
@ GPU_BATCH_OWNS_VBO
Definition: GPU_batch.h:30
struct GPUFrameBuffer GPUFrameBuffer
void GPU_framebuffer_bind_no_srgb(GPUFrameBuffer *fb)
void GPU_framebuffer_restore(void)
GPUFrameBuffer * GPU_framebuffer_active_get(void)
void GPU_framebuffer_bind(GPUFrameBuffer *fb)
void immUniformColor4ubv(const unsigned char rgba[4])
void immUniform4f(const char *name, float x, float y, float z, float w)
void immUniform2f(const char *name, float x, float y)
void immUniformThemeColorShadeAlpha(int color_id, int color_offset, int alpha_offset)
void immUniformColor4f(float r, float g, float b, float a)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immUniformThemeColor(int color_id)
void immUniformThemeColorShade(int color_id, int offset)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
void immUniformColor3ubv(const unsigned char rgb[3])
void immUniform1i(const char *name, int x)
void immUniform1f(const char *name, float x)
void immUniformColor4ub(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
void immAttr4f(uint attr_id, float x, float y, float z, float w)
void immUniformThemeColorBlend(int color_id1, int color_id2, float fac)
GPUVertFormat * immVertexFormat(void)
void immUniformColor3f(float r, float g, float b)
void immAttr2f(uint attr_id, float x, float y)
void immBegin(GPUPrimType, uint vertex_len)
void immEnd(void)
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(uint pos, float x1, float y1, float x2, float y2)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble y1
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble x2
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_identity_projection_set(void)
Definition: gpu_matrix.cc:154
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:140
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
void GPU_matrix_identity_set(void)
Definition: gpu_matrix.cc:168
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:133
GPUPrimType
Definition: GPU_primitive.h:18
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:25
@ GPU_PRIM_LINE_LOOP
Definition: GPU_primitive.h:23
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_PRIM_POINTS
Definition: GPU_primitive.h:19
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:22
@ GPU_PRIM_TRI_STRIP
Definition: GPU_primitive.h:24
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:21
@ GPU_SHADER_2D_DIAG_STRIPES
Definition: GPU_shader.h:222
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:349
@ GPU_SHADER_2D_CHECKER
Definition: GPU_shader.h:221
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA
Definition: GPU_shader.h:321
@ GPU_SHADER_2D_IMAGE_COLOR
Definition: GPU_shader.h:217
@ GPU_SHADER_2D_FLAT_COLOR
Definition: GPU_shader.h:208
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_line_width(float width)
Definition: gpu_state.cc:158
void GPU_line_smooth(bool enable)
Definition: gpu_state.cc:75
@ GPU_DEPTH_NONE
Definition: GPU_state.h:83
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:65
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:259
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
eGPUDataFormat
Definition: GPU_texture.h:170
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:174
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:171
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:444
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:564
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:518
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:472
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
eGPUTextureFormat
Definition: GPU_texture.h:83
@ GPU_RGB16F
Definition: GPU_texture.h:127
@ GPU_RGBA8
Definition: GPU_texture.h:87
void GPU_texture_bind(GPUTexture *tex, int unit)
Definition: gpu_texture.cc:466
void GPU_vertbuf_vert_set(GPUVertBuf *verts, uint v_idx, const void *data)
#define GPU_vertbuf_create_with_format(format)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void GPU_vertbuf_data_len_set(GPUVertBuf *, uint v_len)
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
void GPU_viewport_bind(GPUViewport *viewport, int view, const rcti *rect)
Definition: gpu_viewport.c:170
GPUFrameBuffer * GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
Definition: gpu_viewport.c:574
void GPU_viewport_unbind(GPUViewport *viewport)
unsigned char * IMB_display_buffer_acquire_ctx(const struct bContext *C, struct ImBuf *ibuf, void **cache_handle)
void IMB_colormanagement_imbuf_make_display_space(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings)
bool IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C, struct ColorSpace *colorspace, float dither, bool predivide)
void IMB_display_buffer_release(void *cache_handle)
bool IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, float dither, bool predivide)
void IMB_colormanagement_finish_glsl_draw(void)
struct ImBuf * IMB_dupImBuf(const struct ImBuf *ibuf1)
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:696
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a producing a negative Combine Generate a color from its and blue channels(Deprecated)") DefNode(ShaderNode
#define C
Definition: RandGen.cpp:25
#define SEQ_ITERATOR_FOREACH(var, collection)
Definition: SEQ_iterator.h:35
#define UI_DPI_FAC
Definition: UI_interface.h:305
void UI_draw_safe_areas(uint pos, const struct rctf *rect, const float title_aspect[2], const float action_aspect[2])
void UI_GetThemeColor3fv(int colorid, float col[3])
Definition: resources.c:1165
@ TH_ROW_ALTERNATE
Definition: UI_resources.h:262
@ TH_SEQ_SELECTED
Definition: UI_resources.h:199
@ TH_BACK
Definition: UI_resources.h:39
@ TH_SEQ_TEXT
Definition: UI_resources.h:195
@ TH_SEQ_MASK
Definition: UI_resources.h:189
@ TH_SEQ_MOVIE
Definition: UI_resources.h:187
@ TH_SEQ_COLOR
Definition: UI_resources.h:197
@ TH_SEQ_META
Definition: UI_resources.h:194
@ TH_CFRAME
Definition: UI_resources.h:97
@ TH_SEQ_PREVIEW
Definition: UI_resources.h:196
@ TH_VIEW_OVERLAY
Definition: UI_resources.h:327
@ TH_SEQ_AUDIO
Definition: UI_resources.h:192
@ TH_SEQ_ACTIVE
Definition: UI_resources.h:198
@ TH_SEQ_EFFECT
Definition: UI_resources.h:193
@ TH_SEQ_SCENE
Definition: UI_resources.h:191
@ TH_SEQ_MOVIECLIP
Definition: UI_resources.h:188
@ TH_SEQ_IMAGE
Definition: UI_resources.h:190
void UI_ThemeClearColor(int colorid)
Definition: resources.c:1448
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
Definition: resources.c:1323
void UI_Theme_Restore(struct bThemeState *theme_state)
Definition: resources.c:1076
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1067
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3])
Definition: resources.c:1208
void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3], float fac, int offset)
Definition: resources.c:1429
void UI_SetTheme(int spacetype, int regionid)
Definition: resources.c:1045
void UI_GetColorPtrShade3ubv(const unsigned char cp1[3], unsigned char col[3], int offset)
Definition: resources.c:1412
void UI_Theme_Store(struct bThemeState *theme_state)
Definition: resources.c:1072
char char char char void UI_view2d_text_cache_add(struct View2D *v2d, float x, float y, const char *str, size_t str_len, const unsigned char col[4])
Definition: view2d.cc:2068
#define V2D_SCROLL_HANDLE_HEIGHT
Definition: UI_view2d.h:68
void UI_view2d_totRect_set(struct View2D *v2d, int width, int height)
Definition: view2d.cc:1022
void UI_view2d_view_restore(const struct bContext *C)
#define V2D_SCROLL_HANDLE_WIDTH
Definition: UI_view2d.h:69
void UI_view2d_view_orthoSpecial(struct ARegion *region, struct View2D *v2d, bool xaxis)
Definition: view2d.cc:1122
void UI_view2d_draw_lines_x__discrete_frames_or_seconds(const struct View2D *v2d, const struct Scene *scene, bool display_seconds, bool display_minor_lines)
void UI_view2d_view_ortho(const struct View2D *v2d)
void UI_view2d_text_cache_draw(struct ARegion *region)
Definition: view2d.cc:2128
void UI_view2d_scrollers_draw(struct View2D *v2d, const struct rcti *mask_custom)
float UI_view2d_region_to_view_y(const struct View2D *v2d, float y)
Definition: view2d.cc:1660
void UI_view2d_text_cache_add_rectf(struct View2D *v2d, const struct rctf *rect_view, const char *str, size_t str_len, const unsigned char col[4])
void UI_view2d_curRect_validate(struct View2D *v2d)
Definition: view2d.cc:828
@ WM_JOB_TYPE_COMPOSITE
Definition: WM_api.h:1348
@ WM_JOB_TYPE_RENDER_PREVIEW
Definition: WM_api.h:1350
@ WM_GIZMOMAP_DRAWSTEP_2D
#define ND_SEQUENCER
Definition: WM_types.h:385
#define NC_SCENE
Definition: WM_types.h:328
void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
Definition: anim_draw.c:79
void ED_markers_draw(const bContext *C, int flag)
Definition: anim_markers.c:535
void ED_annotation_draw_2dimage(const bContext *C)
void ED_annotation_draw_view2d(const bContext *C, bool onlyv2d)
float evaltime
Definition: bpy_driver.c:161
unsigned int U
Definition: btGjkEpa3.h:78
ListBase * SEQ_channels_displayed_get(Editing *ed)
Definition: channels.c:23
#define SELECT
Scene scene
const Depsgraph * depsgraph
static void draw_backdrop(const int fontid, const rctf *main_line_rect, const uint8_t color_bg[4], const short region_y_size, const float base_tick_height)
Definition: ed_draw.c:208
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:3741
uint pos
uint col
struct @653::@655 batch
void GPU_clear_color(float red, float green, float blue, float alpha)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
void SEQ_cache_iterate(struct Scene *scene, void *userdata, bool callback_init(void *userdata, size_t item_count), bool callback_iter(void *userdata, struct Sequence *seq, int timeline_frame, int cache_type))
Definition: image_cache.c:891
BLI_INLINE float fb(float length, float L)
SeqCollection * SEQ_query_rendered_strips(const Scene *scene, ListBase *channels, ListBase *seqbase, const int timeline_frame, const int displayed_channel)
Definition: iterator.c:309
void SEQ_collection_free(SeqCollection *collection)
Definition: iterator.c:81
ccl_gpu_kernel_postfix ccl_global float int int int int float bool int offset
format
Definition: logImageCore.h:38
static char ** names
Definition: makesdna.c:65
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
#define G(x, y, z)
#define fabsf(x)
Definition: metal/compat.h:219
T length(const vec_base< T, Size > &a)
T floor(const T &a)
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
bool SEQ_prefetch_need_redraw(Main *bmain, Scene *scene)
Definition: prefetch.c:585
double SEQ_rendersize_to_scale_factor(int render_size)
Definition: proxy.c:86
ImBuf * SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame, int chanshown)
Definition: render.c:1925
ImBuf * SEQ_render_give_ibuf_direct(const SeqRenderData *context, float timeline_frame, Sequence *seq)
Definition: render.c:1994
void SEQ_render_new_render_data(Main *bmain, struct Depsgraph *depsgraph, Scene *scene, int rectx, int recty, int preview_render_size, int for_render, SeqRenderData *r_context)
Definition: render.c:205
bool SEQ_render_is_muted(const ListBase *channels, const Sequence *seq)
Definition: render.c:2199
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition: sequencer.c:388
eSeqOverlapMode SEQ_tool_settings_overlap_mode_get(Scene *scene)
Definition: sequencer.c:376
Editing * SEQ_editing_get(const Scene *scene)
Definition: sequencer.c:241
static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
static void sequencer_display_size(Scene *scene, float r_viewrect[2])
static void draw_cache_view(const bContext *C)
static void sequencer_check_scopes(SequencerScopes *scopes, ImBuf *ibuf)
static void * sequencer_OCIO_transform_ibuf(const bContext *C, ImBuf *ibuf, bool *r_glsl_used, eGPUTextureFormat *r_format, eGPUDataFormat *r_data, void **r_buffer_cache_handle)
static void draw_color_strip_band(const Scene *scene, ListBase *channels, Sequence *seq, uint pos, float text_margin_y, float y1)
static float align_frame_with_pixel(float frame_coord, float frames_per_pixel)
static void draw_sequence_extensions_overlay(Scene *scene, Sequence *seq, uint pos, float pixely, const bool show_strip_color_tag)
#define SEQ_HANDLE_SIZE
#define SEQ_LEFTHANDLE
Sequence * ED_sequencer_special_preview_get(void)
static void draw_seq_outline(Scene *scene, Sequence *seq, uint pos, float x1, float x2, float y1, float y2, float pixelx, float pixely, bool seq_active)
struct WaveVizData WaveVizData
static void sequencer_preview_get_rect(rctf *preview, Scene *scene, ARegion *region, SpaceSeq *sseq, bool draw_overlay, bool draw_backdrop)
static int sequencer_draw_get_transform_preview_frame(Scene *scene)
#define SEQ_SCROLLER_TEXT_OFFSET
void draw_timeline_seq_display(const bContext *C, ARegion *region)
void sequencer_draw_preview(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq, int timeline_frame, int offset, bool draw_overlay, bool draw_backdrop)
static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
static void draw_effect_inputs_highlight(const Scene *scene, Sequence *seq)
static size_t draw_waveform_segment(WaveVizData *waveform_data, bool use_rms)
static bool draw_cache_view_iter_fn(void *userdata, struct Sequence *seq, int timeline_frame, int cache_type)
static bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene)
void color3ubv_from_seq(const Scene *curscene, const Sequence *seq, const bool show_strip_color_tag, uchar r_col[3])
static void write_waveform_data(WaveVizData *waveform_data, const vec2f pos, const float rms, const bool is_clipping, const bool draw_line)
static void sequencer_preview_clear(void)
ImBuf * sequencer_ibuf_get(struct Main *bmain, ARegion *region, struct Depsgraph *depsgraph, Scene *scene, SpaceSeq *sseq, int timeline_frame, int frame_ofs, const char *viewname)
static void draw_seq_background(Scene *scene, Sequence *seq, uint pos, float x1, float x2, float y1, float y2, bool is_single_image, bool show_strip_color_tag)
static ImBuf * sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
static const char * draw_seq_text_get_name(Sequence *seq)
void sequencer_special_update_set(Sequence *seq)
static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2, const bool show_strip_color_tag)
static void fcurve_batch_add_verts(GPUVertBuf *vbo, float y1, float y2, float y_height, int timeline_frame, float curve_val, unsigned int *vert_count)
static void draw_seq_fcurve_overlay(Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, float pixelx)
static ImBuf * sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(ImBuf *ibuf))
static void sequencer_draw_display_buffer(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq, ImBuf *ibuf, ImBuf *scope, bool draw_overlay, bool draw_backdrop)
static void draw_waveform(WaveVizData *waveform_data, size_t wave_data_len)
static void draw_seq_locked(float x1, float y1, float x2, float y2)
static void draw_seq_handle(const Scene *scene, View2D *v2d, Sequence *seq, const float handsize_clamped, const short direction, uint pos, bool seq_active, float pixelx, bool y_threshold)
static void draw_seq_waveform_overlay(const bContext *C, ARegion *region, Sequence *seq, float x1, float y1, float x2, float y2)
static void sequencer_draw_gpencil_overlay(const bContext *C)
static bool seq_draw_waveforms_poll(const bContext *UNUSED(C), SpaceSeq *sseq, Sequence *seq)
static void draw_seq_timeline_channels(View2D *v2d)
static void draw_cache_view_batch(GPUVertBuf *vbo, size_t vert_count, float col_r, float col_g, float col_b, float col_a)
void draw_timeline_seq(const bContext *C, ARegion *region)
static void seq_draw_image_origin_and_outline(const bContext *C, Sequence *seq, bool is_active_seq)
static Sequence * special_seq_update
static bool draw_cache_view_init_fn(void *userdata, size_t item_count)
static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
static size_t get_vertex_count(WaveVizData *waveform_data)
static void draw_overlap_frame_indicator(const struct Scene *scene, const View2D *v2d)
static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t source_len)
static void seq_draw_sfra_efra(const Scene *scene, View2D *v2d)
void ED_sequencer_special_preview_clear(void)
static void sequencer_draw_borders_overlay(const SpaceSeq *sseq, const View2D *v2d, const Scene *scene)
#define MUTE_ALPHA
static size_t waveform_append_sample(WaveVizData *waveform_data, vec2f pos, const float value_min, const float value_max, const float y_mid, const float y_scale, const float rms, const bool is_clipping, const bool is_line_strip)
float sequence_handle_size_get_clamped(const Scene *scene, Sequence *seq, const float pixelx)
static void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, ARegion *region, Sequence *seq, float pixelx, bool seq_active)
static void calculate_seq_text_offsets(const Scene *scene, View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx)
static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
static size_t draw_seq_text_get_overlay_string(const Scene *scene, SpaceSeq *sseq, Sequence *seq, char *r_overlay_string, size_t overlay_string_len)
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
static void waveform_job_start_if_needed(const bContext *C, Sequence *seq)
static void draw_seq_text_overlay(Scene *scene, View2D *v2d, Sequence *seq, SpaceSeq *sseq, float x1, float x2, float y1, float y2, bool seq_active)
struct CacheDrawData CacheDrawData
#define SEQ_RIGHTHANDLE
bool sequencer_view_preview_only_poll(const bContext *C)
#define OVERLAP_ALPHA
struct ImBuf * make_vectorscope_view_from_ibuf(struct ImBuf *ibuf)
struct ImBuf * make_waveform_view_from_ibuf(struct ImBuf *ibuf)
struct ImBuf * make_histogram_view_from_ibuf(struct ImBuf *ibuf)
void sequencer_preview_add_sound(const struct bContext *C, struct Sequence *seq)
struct ImBuf * make_sep_waveform_view_from_ibuf(struct ImBuf *ibuf)
struct ImBuf * make_zebra_view_from_ibuf(struct ImBuf *ibuf, float perc)
struct Sequence * find_nearest_seq(struct Scene *scene, struct View2D *v2d, int *hand, const int mval[2])
void draw_seq_strip_thumbnail(struct View2D *v2d, const struct bContext *C, struct Scene *scene, struct Sequence *seq, float y1, float y2, float pixelx, float pixely)
Sequence * SEQ_select_active_get(Scene *scene)
Definition: strip_select.c:18
int SEQ_time_strip_length_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:484
bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:471
bool SEQ_time_has_left_still_frames(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:466
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
Definition: strip_time.c:506
void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
Definition: strip_time.c:373
float SEQ_time_start_frame_get(const Sequence *seq)
Definition: strip_time.c:494
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:515
bool SEQ_transform_is_locked(ListBase *channels, Sequence *seq)
void SEQ_image_transform_origin_offset_pixelspace_get(const Scene *scene, const Sequence *seq, float r_origin[2])
void SEQ_image_transform_final_quad_get(const Scene *scene, const Sequence *seq, float r_quad[4][2])
bool SEQ_transform_single_image_check(Sequence *seq)
short regiontype
struct wmGizmoMap * gizmo_map
GPUVertBuf * preprocessed_vbo
GPUVertBuf * raw_vbo
size_t composite_vert_count
struct View2D * v2d
size_t final_out_vert_count
GPUVertBuf * composite_vbo
size_t preprocessed_vert_count
GPUVertBuf * final_out_vbo
ListBase * seqbasep
ListBase metastack
rctf overlay_frame_rect
int overlay_frame_flag
char name[66]
Definition: DNA_ID.h:378
int channels
struct ColorSpace * rect_colorspace
float dither
unsigned int * rect
float * rect_float
struct ColorSpace * float_colorspace
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
Definition: BKE_main.h:121
ColorManagedViewSettings view_settings
struct Editing * ed
struct RenderData r
struct DisplaySafeAreas safe_areas
ColorManagedDisplaySettings display_settings
struct MovieClip * clip
struct Scene * scene
struct Object * scene_camera
struct Sequence * seq3
struct Mask * mask
struct bSound * sound
struct Sequence * seq1
struct Sequence * seq2
struct Sequence * next
struct ImBuf * reference_ibuf
struct ImBuf * waveform_ibuf
struct ImBuf * sep_waveform_ibuf
struct ImBuf * zebra_ibuf
struct ImBuf * histogram_ibuf
struct ImBuf * vector_ibuf
float * data
Definition: BKE_sound.h:27
short chanshown
char overlay_frame_type
struct SequencerScopes scopes
struct bGPdata * gpd
struct SequencerTimelineOverlay timeline_overlay
char multiview_eye
short render_size
struct SequencerPreviewOverlay preview_overlay
char name[256]
StripElem * stripdata
char dir[768]
char text[512]
unsigned char color[4]
float pos[2]
char filepath[1024]
void * spinlock
void * waveform
short tags
double offset_time
ThemeStripColor strip_color[9]
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
void ED_time_scrub_draw_current_frame(const ARegion *region, const Scene *scene, bool display_seconds)
void ED_time_scrub_draw(const ARegion *region, const Scene *scene, bool display_seconds, bool discrete_frames)
const char * SEQ_sequence_give_name(Sequence *seq)
Definition: utils.c:168
Mask * SEQ_active_mask_get(Scene *scene)
Definition: utils.c:440
ListBase * SEQ_get_seqbase_from_sequence(Sequence *seq, ListBase **r_channels, int *r_offset)
Definition: utils.c:182
bool SEQ_sequence_has_source(const Sequence *seq)
Definition: utils.c:459
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition: wm_draw.c:846
GPUViewport * WM_draw_region_get_bound_viewport(ARegion *region)
Definition: wm_draw.c:856
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)
Definition: wm_gizmo_map.c:483
void WM_jobs_kill_type(struct wmWindowManager *wm, const void *owner, int job_type)
Definition: wm_jobs.c:572