Blender  V2.93
sequencer_draw.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <math.h>
25 #include <string.h>
26 
27 #include "BLI_blenlib.h"
28 #include "BLI_math.h"
29 #include "BLI_string_utils.h"
30 #include "BLI_threads.h"
31 #include "BLI_utildefines.h"
32 
33 #include "IMB_imbuf_types.h"
34 
35 #include "DNA_anim_types.h"
36 #include "DNA_mask_types.h"
37 #include "DNA_object_types.h"
38 #include "DNA_scene_types.h"
39 #include "DNA_screen_types.h"
40 #include "DNA_sound_types.h"
41 #include "DNA_space_types.h"
42 #include "DNA_userdef_types.h"
43 
44 #include "BKE_context.h"
45 #include "BKE_fcurve.h"
46 #include "BKE_global.h"
47 #include "BKE_scene.h"
48 #include "BKE_sound.h"
49 
50 #include "IMB_colormanagement.h"
51 #include "IMB_imbuf.h"
52 
53 #include "GPU_framebuffer.h"
54 #include "GPU_immediate.h"
55 #include "GPU_immediate_util.h"
56 #include "GPU_matrix.h"
57 #include "GPU_state.h"
58 #include "GPU_vertex_buffer.h"
59 #include "GPU_viewport.h"
60 
61 #include "ED_anim_api.h"
62 #include "ED_gpencil.h"
63 #include "ED_markers.h"
64 #include "ED_mask.h"
65 #include "ED_screen.h"
66 #include "ED_sequencer.h"
67 #include "ED_space_api.h"
68 #include "ED_time_scrub_ui.h"
69 #include "ED_util.h"
70 
71 #include "BIF_glutil.h"
72 
73 #include "SEQ_effects.h"
74 #include "SEQ_prefetch.h"
75 #include "SEQ_proxy.h"
76 #include "SEQ_relations.h"
77 #include "SEQ_render.h"
78 #include "SEQ_select.h"
79 #include "SEQ_sequencer.h"
80 #include "SEQ_time.h"
81 #include "SEQ_transform.h"
82 #include "SEQ_utils.h"
83 
84 #include "UI_interface.h"
85 #include "UI_resources.h"
86 #include "UI_view2d.h"
87 
88 #include "WM_api.h"
89 #include "WM_types.h"
90 
91 #include "BLF_api.h"
92 
93 #include "MEM_guardedalloc.h"
94 
95 /* Own include. */
96 #include "sequencer_intern.h"
97 
98 #define SEQ_LEFTHANDLE 1
99 #define SEQ_RIGHTHANDLE 2
100 #define SEQ_HANDLE_SIZE 8.0f
101 #define SEQ_SCROLLER_TEXT_OFFSET 8
102 #define MUTE_ALPHA 120
103 
104 /* Note, Don't use SEQ_ALL_BEGIN/SEQ_ALL_END while drawing!
105  * it messes up transform. */
106 #undef SEQ_ALL_BEGIN
107 #undef SEQ_ALL_END
108 
110 
111 void color3ubv_from_seq(Scene *curscene, Sequence *seq, uchar col[3])
112 {
113  uchar blendcol[3];
114 
115  switch (seq->type) {
116  case SEQ_TYPE_IMAGE:
118  break;
119 
120  case SEQ_TYPE_META:
122  break;
123 
124  case SEQ_TYPE_MOVIE:
126  break;
127 
128  case SEQ_TYPE_MOVIECLIP:
130  break;
131 
132  case SEQ_TYPE_MASK:
134  break;
135 
136  case SEQ_TYPE_SCENE:
138 
139  if (seq->scene == curscene) {
141  }
142  break;
143 
144  /* Transitions use input colors, fallback for when the input is a transition itself. */
145  case SEQ_TYPE_CROSS:
146  case SEQ_TYPE_GAMCROSS:
147  case SEQ_TYPE_WIPE:
148  col[0] = 130;
149  col[1] = 130;
150  col[2] = 130;
151  break;
152 
153  /* Effects. */
154  case SEQ_TYPE_TRANSFORM:
155  case SEQ_TYPE_SPEED:
156  case SEQ_TYPE_ADD:
157  case SEQ_TYPE_SUB:
158  case SEQ_TYPE_MUL:
159  case SEQ_TYPE_ALPHAOVER:
160  case SEQ_TYPE_ALPHAUNDER:
161  case SEQ_TYPE_OVERDROP:
162  case SEQ_TYPE_GLOW:
163  case SEQ_TYPE_MULTICAM:
164  case SEQ_TYPE_ADJUSTMENT:
166  case SEQ_TYPE_COLORMIX:
168 
169  /* Slightly offset hue to distinguish different effects. */
170  if (seq->type == SEQ_TYPE_ADD) {
172  }
173  else if (seq->type == SEQ_TYPE_SUB) {
175  }
176  else if (seq->type == SEQ_TYPE_MUL) {
178  }
179  else if (seq->type == SEQ_TYPE_ALPHAOVER) {
181  }
182  else if (seq->type == SEQ_TYPE_ALPHAUNDER) {
184  }
185  else if (seq->type == SEQ_TYPE_OVERDROP) {
187  }
188  else if (seq->type == SEQ_TYPE_COLORMIX) {
190  }
191  else if (seq->type == SEQ_TYPE_GAUSSIAN_BLUR) {
193  }
194  else if (seq->type == SEQ_TYPE_GLOW) {
196  }
197  else if (seq->type == SEQ_TYPE_ADJUSTMENT) {
199  }
200  else if (seq->type == SEQ_TYPE_SPEED) {
202  }
203  else if (seq->type == SEQ_TYPE_TRANSFORM) {
205  }
206  else if (seq->type == SEQ_TYPE_MULTICAM) {
208  }
209  break;
210 
211  case SEQ_TYPE_COLOR:
213  break;
214 
215  case SEQ_TYPE_SOUND_RAM:
217  blendcol[0] = blendcol[1] = blendcol[2] = 128;
218  if (seq->flag & SEQ_MUTE) {
219  UI_GetColorPtrBlendShade3ubv(col, blendcol, col, 0.5, 20);
220  }
221  break;
222 
223  case SEQ_TYPE_TEXT:
225  break;
226 
227  default:
228  col[0] = 10;
229  col[1] = 255;
230  col[2] = 40;
231  break;
232  }
233 }
234 
235 typedef struct WaveVizData {
236  float pos[2];
237  float rms_pos;
238  bool clip;
239  bool end;
241 
242 static int get_section_len(WaveVizData *start, WaveVizData *end)
243 {
244  int len = 0;
245  while (start != end) {
246  len++;
247  if (start->end) {
248  return len;
249  }
250  start++;
251  }
252  return len;
253 }
254 
255 static void draw_waveform(WaveVizData *iter, WaveVizData *end, GPUPrimType prim_type, bool use_rms)
256 {
257  int strip_len = get_section_len(iter, end);
258  if (strip_len > 1) {
263 
265  immBegin(prim_type, strip_len);
266 
267  while (iter != end) {
268  if (iter->clip) {
269  immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f);
270  }
271  else if (use_rms) {
272  immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.8f);
273  }
274  else {
275  immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.5f);
276  }
277 
278  if (use_rms) {
279  immVertex2f(pos, iter->pos[0], iter->rms_pos);
280  }
281  else {
282  immVertex2f(pos, iter->pos[0], iter->pos[1]);
283  }
284 
285  if (iter->end) {
286  /* End of line. */
287  iter++;
288  strip_len = get_section_len(iter, end);
289  if (strip_len != 0) {
290  immEnd();
293  immBegin(prim_type, strip_len);
294  }
295  }
296  else {
297  iter++;
298  }
299  }
300  immEnd();
302 
304  }
305 }
306 
307 static float clamp_frame_coord_to_pixel(float frame_coord,
308  float pixel_frac,
309  float frames_per_pixel)
310 {
311  float cur_pixel = (frame_coord / frames_per_pixel);
312  float new_pixel = (int)(frame_coord / frames_per_pixel) + pixel_frac;
313  if (cur_pixel > new_pixel) {
314  new_pixel += 1.0f;
315  }
316  return new_pixel * frames_per_pixel;
317 }
318 
324  const bContext *C,
325  SpaceSeq *sseq,
326  Scene *scene,
327  Sequence *seq,
328  float x1,
329  float y1,
330  float x2,
331  float y2,
332  float frames_per_pixel)
333 {
334  if (seq->sound && ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) {
335  /* Make sure that the start drawing position is aligned to the pixels on the screen to avoid
336  * flickering whem moving around the strip.
337  * To do this we figure out the fractional offset in pixel space by checking where the
338  * window starts.
339  * We then append this pixel offset to our strip start coordiate to ensure we are aligned to
340  * the screen pixel grid. */
341  float pixel_frac = v2d->cur.xmin / frames_per_pixel - floor(v2d->cur.xmin / frames_per_pixel);
342  float x1_adj = clamp_frame_coord_to_pixel(x1, pixel_frac, frames_per_pixel);
343 
344  /* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */
345  float x1_offset = max_ff(v2d->cur.xmin, x1_adj);
346  float x2_offset = min_ff(v2d->cur.xmax, x2);
347 
348  /* Calculate how long the strip that is in view is in pixels. */
349  int pix_strip_len = round((x2_offset - x1_offset) / frames_per_pixel);
350 
351  if (pix_strip_len < 2) {
352  return;
353  }
354 
355  bSound *sound = seq->sound;
356 
357  BLI_spin_lock(sound->spinlock);
358  if (!sound->waveform) {
359  /* Load the waveform data if it hasn't been loaded and cached already. */
360  if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
361  /* Prevent sounds from reloading. */
363  BLI_spin_unlock(sound->spinlock);
365  }
366  else {
367  BLI_spin_unlock(sound->spinlock);
368  }
369  return; /* Nothing to draw. */
370  }
371  BLI_spin_unlock(sound->spinlock);
372 
373  SoundWaveform *waveform = sound->waveform;
374 
375  /* Waveform could not be built. */
376  if (waveform->length == 0) {
377  return;
378  }
379 
380  /* F-curve lookup is quite expensive, so do this after precondition. */
381  FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
382 
383  WaveVizData *tri_strip_arr = MEM_callocN(sizeof(*tri_strip_arr) * pix_strip_len * 2,
384  "tri_strip");
385  WaveVizData *line_strip_arr = MEM_callocN(sizeof(*line_strip_arr) * pix_strip_len,
386  "line_strip");
387 
388  WaveVizData *tri_strip_iter = tri_strip_arr;
389  WaveVizData *line_strip_iter = line_strip_arr;
390 
391  /* The y coordinate for the middle of the strip. */
392  float y_mid = (y1 + y2) / 2.0f;
393  /* The lenght from the middle of the strip to the top/bottom. */
394  float y_scale = (y2 - y1) / 2.0f;
395  float volume = seq->volume;
396 
397  /* Value to keep track if the previous item to be drawn was a line strip. */
398  int8_t was_line_strip = -1; /* -1 == no previous value. */
399 
400  float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS;
401 
402  /* How many samples do we have for each pixel? */
403  float samples_per_pix = samples_per_frame * frames_per_pixel;
404 
405  float strip_start_offset = seq->startofs + seq->anim_startofs;
406  float start_sample = 0;
407 
408  if (strip_start_offset != 0) {
409  /* If start offset is not zero, we need to make sure that we pick the same start sample as if
410  * we simply scrolled the start of the strip offscreen. Otherwise we will get flickering when
411  * changing start offset as the pixel alignment will not be the same for the drawn samples.
412  */
413  strip_start_offset = clamp_frame_coord_to_pixel(
414  x1 - strip_start_offset, pixel_frac, frames_per_pixel);
415  start_sample = fabsf(strip_start_offset - x1_adj) * samples_per_frame;
416  }
417 
418  start_sample += seq->sound->offset_time * SOUND_WAVE_SAMPLES_PER_SECOND;
419  /* If we scrolled the start off-screen, then the start sample should be at the first visible
420  * sample. */
421  start_sample += (x1_offset - x1_adj) * samples_per_frame;
422 
423  for (int i = 0; i < pix_strip_len; i++) {
424  float sample_offset = start_sample + i * samples_per_pix;
425  int p = sample_offset;
426 
427  if (p >= waveform->length) {
428  break;
429  }
430 
431  float value_min = waveform->data[p * 3];
432  float value_max = waveform->data[p * 3 + 1];
433  float rms = waveform->data[p * 3 + 2];
434 
435  if (p + 1 < waveform->length) {
436  /* Use simple linear interpolation. */
437  float f = sample_offset - p;
438  value_min = (1.0f - f) * value_min + f * waveform->data[p * 3 + 3];
439  value_max = (1.0f - f) * value_max + f * waveform->data[p * 3 + 4];
440  rms = (1.0f - f) * rms + f * waveform->data[p * 3 + 5];
441  if (samples_per_pix > 1.0f) {
442  /* We need to sum up the values we skip over until the next step. */
443  float next_pos = sample_offset + samples_per_pix;
444  int end_idx = next_pos;
445 
446  for (int j = p + 1; (j < waveform->length) && (j < end_idx); j++) {
447  value_min = min_ff(value_min, waveform->data[j * 3]);
448  value_max = max_ff(value_max, waveform->data[j * 3 + 1]);
449  rms = max_ff(rms, waveform->data[j * 3 + 2]);
450  }
451  }
452  }
453 
454  if (fcu && !BKE_fcurve_is_empty(fcu)) {
455  float evaltime = x1_offset + (i * frames_per_pixel);
456  volume = evaluate_fcurve(fcu, evaltime);
457  CLAMP_MIN(volume, 0.0f);
458  }
459 
460  value_min *= volume;
461  value_max *= volume;
462  rms *= volume;
463 
464  bool clipping = false;
465 
466  if (value_max > 1 || value_min < -1) {
467  clipping = true;
468 
469  CLAMP_MAX(value_max, 1.0f);
470  CLAMP_MIN(value_min, -1.0f);
471  }
472 
473  bool is_line_strip = (value_max - value_min < 0.05f);
474 
475  if (was_line_strip != -1 && is_line_strip != was_line_strip) {
476  /* If the previously added strip type isn't the same as the current one,
477  * add transision areas so they transistion smoothly between each other.
478  */
479  if (is_line_strip) {
480  /* This will be a line strip, end the tri strip. */
481  tri_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
482  tri_strip_iter->pos[1] = y_mid + value_min * y_scale;
483  tri_strip_iter->clip = clipping;
484  tri_strip_iter->rms_pos = tri_strip_iter->pos[1];
485  tri_strip_iter->end = true;
486 
487  /* End of section. */
488  tri_strip_iter++;
489 
490  /* Check if we are at the end.
491  * If so, skip one point line. */
492  if (i + 1 == pix_strip_len) {
493  continue;
494  }
495  }
496  else {
497  /* This will be a tri strip. */
498  line_strip_iter--;
499  tri_strip_iter->pos[0] = line_strip_iter->pos[0];
500  tri_strip_iter->pos[1] = line_strip_iter->pos[1];
501  tri_strip_iter->clip = line_strip_iter->clip;
502  tri_strip_iter->rms_pos = line_strip_iter->pos[1];
503  tri_strip_iter++;
504 
505  /* Check if line had only one point. */
506  line_strip_iter--;
507  if (line_strip_iter < line_strip_arr || line_strip_iter->end) {
508  /* Only one point, skip it. */
509  line_strip_iter++;
510  }
511  else {
512  /* End of section. */
513  line_strip_iter++;
514  line_strip_iter->end = true;
515  line_strip_iter++;
516  }
517  }
518  }
519 
520  was_line_strip = is_line_strip;
521 
522  if (is_line_strip) {
523  line_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
524  line_strip_iter->pos[1] = y_mid + value_min * y_scale;
525  line_strip_iter->clip = clipping;
526  line_strip_iter++;
527  }
528  else {
529  tri_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
530  tri_strip_iter->pos[1] = y_mid + value_min * y_scale;
531  tri_strip_iter->clip = clipping;
532  tri_strip_iter->rms_pos = y_mid + max_ff(-rms, value_min) * y_scale;
533  tri_strip_iter++;
534 
535  tri_strip_iter->pos[0] = x1_offset + i * frames_per_pixel;
536  tri_strip_iter->pos[1] = y_mid + value_max * y_scale;
537  tri_strip_iter->clip = clipping;
538  tri_strip_iter->rms_pos = y_mid + min_ff(rms, value_max) * y_scale;
539  tri_strip_iter++;
540  }
541  }
542 
543  WaveVizData *tri_strip_end = tri_strip_iter;
544  WaveVizData *line_strip_end = line_strip_iter;
545 
546  tri_strip_iter = tri_strip_arr;
547  line_strip_iter = line_strip_arr;
548 
549  draw_waveform(line_strip_iter, line_strip_end, GPU_PRIM_LINE_STRIP, false);
550  draw_waveform(tri_strip_iter, tri_strip_end, GPU_PRIM_TRI_STRIP, false);
551  draw_waveform(tri_strip_iter, tri_strip_end, GPU_PRIM_TRI_STRIP, true);
552 
553  MEM_freeN(tri_strip_arr);
554  MEM_freeN(line_strip_arr);
555  }
556 }
557 
558 static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
559 {
560  /* Don't use SEQ_ALL_BEGIN/SEQ_ALL_END here,
561  * because it changes seq->depth, which is needed for transform. */
562  Sequence *seq;
563  uchar col[4];
564 
565  int chan_min = MAXSEQ;
566  int chan_max = 0;
567  int chan_range = 0;
568  float draw_range = y2 - y1;
569  float draw_height;
570  ListBase *seqbase;
571  int offset;
572 
573  seqbase = SEQ_get_seqbase_from_sequence(seqm, &offset);
574  if (!seqbase || BLI_listbase_is_empty(seqbase)) {
575  return;
576  }
577 
578  if (seqm->type == SEQ_TYPE_SCENE) {
579  offset = seqm->start - offset;
580  }
581  else {
582  offset = 0;
583  }
584 
586 
587  for (seq = seqbase->first; seq; seq = seq->next) {
588  chan_min = min_ii(chan_min, seq->machine);
589  chan_max = max_ii(chan_max, seq->machine);
590  }
591 
592  chan_range = (chan_max - chan_min) + 1;
593  draw_height = draw_range / chan_range;
594 
595  col[3] = 196; /* Alpha, used for all meta children. */
596 
599 
600  /* Draw only immediate children (1 level depth). */
601  for (seq = seqbase->first; seq; seq = seq->next) {
602  const int startdisp = seq->startdisp + offset;
603  const int enddisp = seq->enddisp + offset;
604 
605  if ((startdisp > x2 || enddisp < x1) == 0) {
606  float y_chan = (seq->machine - chan_min) / (float)(chan_range)*draw_range;
607  float x1_chan = startdisp;
608  float x2_chan = enddisp;
609  float y1_chan, y2_chan;
610 
611  if (seq->type == SEQ_TYPE_COLOR) {
612  SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
613  rgb_float_to_uchar(col, colvars->col);
614  }
615  else {
617  }
618 
619  if ((seqm->flag & SEQ_MUTE) || (seq->flag & SEQ_MUTE)) {
620  col[3] = 64;
621  }
622  else {
623  col[3] = 196;
624  }
625 
627 
628  /* Clamp within parent sequence strip bounds. */
629  if (x1_chan < x1) {
630  x1_chan = x1;
631  }
632  if (x2_chan > x2) {
633  x2_chan = x2;
634  }
635 
636  y1_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSBOTTOM);
637  y2_chan = y1 + y_chan + (draw_height * SEQ_STRIP_OFSTOP);
638 
639  immRectf(pos, x1_chan, y1_chan, x2_chan, y2_chan);
640  }
641  }
642 
644 
646 }
647 
648 /* Get handle width in pixels. */
649 float sequence_handle_size_get_clamped(Sequence *seq, const float pixelx)
650 {
651  const float maxhandle = (pixelx * SEQ_HANDLE_SIZE) * U.pixelsize;
652 
653  /* Ensure that handle is not wider, than half of strip. */
654  return min_ff(maxhandle, ((float)(seq->enddisp - seq->startdisp) / 2.0f) / pixelx);
655 }
656 
657 /* Draw a handle, on left or right side of strip. */
658 static void draw_seq_handle(View2D *v2d,
659  Sequence *seq,
660  const float handsize_clamped,
661  const short direction,
662  uint pos,
663  bool seq_active,
664  float pixelx,
665  bool y_threshold)
666 {
667  float rx1 = 0, rx2 = 0;
668  float x1, x2, y1, y2;
669  uint whichsel = 0;
670  uchar col[4];
671 
672  x1 = seq->startdisp;
673  x2 = seq->enddisp;
674 
675  y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
676  y2 = seq->machine + SEQ_STRIP_OFSTOP;
677 
678  /* Set up co-ordinates and dimensions for either left or right handle. */
679  if (direction == SEQ_LEFTHANDLE) {
680  rx1 = x1;
681  rx2 = x1 + handsize_clamped;
682  whichsel = SEQ_LEFTSEL;
683  }
684  else if (direction == SEQ_RIGHTHANDLE) {
685  rx1 = x2 - handsize_clamped;
686  rx2 = x2;
687  whichsel = SEQ_RIGHTSEL;
688  }
689 
690  if (!(seq->type & SEQ_TYPE_EFFECT) || SEQ_effect_get_num_inputs(seq->type) == 0) {
692 
694 
695  if (seq->flag & whichsel) {
696  if (seq_active) {
698  }
699  else {
701  /* Make handles slightly brighter than the outlines. */
703  }
704  col[3] = 255;
706  }
707  else {
708  immUniformColor4ub(0, 0, 0, 50);
709  }
710 
711  immRectf(pos, rx1, y1, rx2, y2);
713  }
714 
715  /* Draw numbers for start and end of the strip next to its handles. */
716  if (y_threshold &&
717  (((seq->flag & SELECT) && (G.moving & G_TRANSFORM_SEQ)) || (seq->flag & whichsel))) {
718 
719  char numstr[64];
720  size_t numstr_len;
721  const int fontid = BLF_default();
722  BLF_set_default();
723 
724  /* Calculate if strip is wide enough for showing the labels. */
725  numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d%d", seq->startdisp, seq->enddisp);
726  float tot_width = BLF_width(fontid, numstr, numstr_len);
727 
728  if ((x2 - x1) / pixelx > 20 + tot_width) {
729  col[0] = col[1] = col[2] = col[3] = 255;
730  float text_margin = 1.2f * handsize_clamped;
731 
732  if (direction == SEQ_LEFTHANDLE) {
733  numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->startdisp);
734  x1 += text_margin;
735  y1 += 0.09f;
736  }
737  else {
738  numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%d", seq->enddisp - 1);
739  x1 = x2 - (text_margin + pixelx * BLF_width(fontid, numstr, numstr_len));
740  y1 += 0.09f;
741  }
742  UI_view2d_text_cache_add(v2d, x1, y1, numstr, numstr_len, col);
743  }
744  }
745 }
746 
747 static void draw_seq_outline(Sequence *seq,
748  uint pos,
749  float x1,
750  float x2,
751  float y1,
752  float y2,
753  float pixelx,
754  float pixely,
755  bool seq_active)
756 {
757  uchar col[3];
758 
759  /* Get the color for the outline. */
760  if (seq_active && (seq->flag & SELECT)) {
762  }
763  else if (seq->flag & SELECT) {
765  }
766  else {
767  /* Color for unselected strips is a bit darker than the background. */
769  }
770 
771  /* Outline while translating strips:
772  * - Slightly lighter.
773  * - Red when overlapping with other strips.
774  */
775  if ((G.moving & G_TRANSFORM_SEQ) && (seq->flag & SELECT)) {
776  if (seq->flag & SEQ_OVERLAP) {
777  col[0] = 255;
778  col[1] = col[2] = 33;
779  }
780  else {
782  }
783  }
785 
786  /* 2px wide outline for selected strips. */
787  /* XXX: some platforms don't support OpenGL lines wider than 1px (see T57570),
788  * draw outline as four boxes instead. */
789  if (seq->flag & SELECT) {
790  /* Left */
791  immRectf(pos, x1 - pixelx, y1, x1 + pixelx, y2);
792  /* Bottom */
793  immRectf(pos, x1 - pixelx, y1, x2 + pixelx, y1 + 2 * pixely);
794  /* Right */
795  immRectf(pos, x2 - pixelx, y1, x2 + pixelx, y2);
796  /* Top */
797  immRectf(pos, x1 - pixelx, y2 - 2 * pixely, x2 + pixelx, y2);
798  }
799  else {
800  /* 1px wide outline for unselected strips. */
801  imm_draw_box_wire_2d(pos, x1, y1, x2, y2);
802  }
803 }
804 
805 static const char *draw_seq_text_get_name(Sequence *seq)
806 {
807  const char *name = seq->name + 2;
808  if (name[0] == '\0') {
809  name = SEQ_sequence_give_name(seq);
810  }
811  return name;
812 }
813 
814 static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t source_len)
815 {
816  *r_source = '\0';
817 
818  /* Set source for the most common types. */
819  switch (seq->type) {
820  case SEQ_TYPE_IMAGE:
821  case SEQ_TYPE_MOVIE: {
822  BLI_join_dirfile(r_source, source_len, seq->strip->dir, seq->strip->stripdata->name);
823  break;
824  }
825  case SEQ_TYPE_SOUND_RAM: {
826  if (seq->sound != NULL) {
827  BLI_strncpy(r_source, seq->sound->filepath, source_len);
828  }
829  break;
830  }
831  case SEQ_TYPE_MULTICAM: {
832  BLI_snprintf(r_source, source_len, "Channel: %d", seq->multicam_source);
833  break;
834  }
835  case SEQ_TYPE_TEXT: {
836  const TextVars *textdata = seq->effectdata;
837  BLI_strncpy(r_source, textdata->text, source_len);
838  break;
839  }
840  case SEQ_TYPE_SCENE: {
841  if (seq->scene != NULL) {
842  if (seq->scene_camera != NULL) {
843  BLI_snprintf(r_source,
844  source_len,
845  "%s (%s)",
846  seq->scene->id.name + 2,
847  seq->scene_camera->id.name + 2);
848  }
849  else {
850  BLI_strncpy(r_source, seq->scene->id.name + 2, source_len);
851  }
852  }
853  break;
854  }
855  case SEQ_TYPE_MOVIECLIP: {
856  if (seq->clip != NULL) {
857  BLI_strncpy(r_source, seq->clip->id.name + 2, source_len);
858  }
859  break;
860  }
861  case SEQ_TYPE_MASK: {
862  if (seq->mask != NULL) {
863  BLI_strncpy(r_source, seq->mask->id.name + 2, source_len);
864  }
865  break;
866  }
867  }
868 }
869 
871  Sequence *seq,
872  char *r_overlay_string,
873  size_t overlay_string_len)
874 {
875  const char *text_sep = " | ";
876  const char *text_array[5];
877  int i = 0;
878 
879  if (sseq->flag & SEQ_SHOW_STRIP_NAME) {
880  text_array[i++] = draw_seq_text_get_name(seq);
881  }
882 
883  char source[FILE_MAX];
884  if (sseq->flag & SEQ_SHOW_STRIP_SOURCE) {
885  draw_seq_text_get_source(seq, source, sizeof(source));
886  if (source[0] != '\0') {
887  if (i != 0) {
888  text_array[i++] = text_sep;
889  }
890  text_array[i++] = source;
891  }
892  }
893 
894  char strip_duration_text[16];
895  if (sseq->flag & SEQ_SHOW_STRIP_DURATION) {
896  const int strip_duration = seq->enddisp - seq->startdisp;
897  SNPRINTF(strip_duration_text, "%d", strip_duration);
898  if (i != 0) {
899  text_array[i++] = text_sep;
900  }
901  text_array[i++] = strip_duration_text;
902  }
903 
904  BLI_assert(i <= ARRAY_SIZE(text_array));
905 
906  return BLI_string_join_array(r_overlay_string, overlay_string_len, text_array, i) -
907  r_overlay_string;
908 }
909 
910 /* Draw info text on a sequence strip. */
911 static void draw_seq_text_overlay(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 {
920  char overlay_string[FILE_MAX];
921  size_t overlay_string_len = draw_seq_text_get_overlay_string(
922  sseq, seq, overlay_string, sizeof(overlay_string));
923 
924  if (overlay_string_len == 0) {
925  return;
926  }
927 
928  /* White text for the active strip. */
929  uchar col[4];
930  col[0] = col[1] = col[2] = seq_active ? 255 : 10;
931  col[3] = 255;
932 
933  /* Make the text duller when the strip is muted. */
934  if (seq->flag & SEQ_MUTE) {
935  if (seq_active) {
937  }
938  else {
940  }
941  }
942 
943  rctf rect;
944  rect.xmin = x1;
945  rect.ymin = y1;
946  rect.xmax = x2;
947  rect.ymax = y2;
948 
949  UI_view2d_text_cache_add_rectf(v2d, &rect, overlay_string, overlay_string_len, col);
950 }
951 
952 static void draw_sequence_extensions_overlay(Scene *scene, Sequence *seq, uint pos, float pixely)
953 {
954  float x1, x2, y1, y2;
955  uchar col[4], blend_col[3];
956 
957  x1 = seq->startdisp;
958  x2 = seq->enddisp;
959 
960  y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
961  y2 = seq->machine + SEQ_STRIP_OFSTOP;
962 
964 
966  if (seq->flag & SELECT) {
968  }
969  col[3] = seq->flag & SEQ_MUTE ? MUTE_ALPHA : 200;
970  UI_GetColorPtrShade3ubv(col, blend_col, 10);
971 
972  if (seq->startofs) {
974  immRectf(pos, (float)(seq->start), y1 - pixely, x1, y1 - SEQ_STRIP_OFSBOTTOM);
975 
976  /* Outline. */
977  immUniformColor3ubv(blend_col);
978  imm_draw_box_wire_2d(pos, x1, y1 - pixely, (float)(seq->start), y1 - SEQ_STRIP_OFSBOTTOM);
979  }
980  if (seq->endofs) {
982  immRectf(pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
983 
984  /* Outline. */
985  immUniformColor3ubv(blend_col);
987  pos, x2, y2 + pixely, (float)(seq->start + seq->len), y2 + SEQ_STRIP_OFSBOTTOM);
988  }
990 }
991 
992 static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1)
993 {
994  uchar col[4];
995  SolidColorVars *colvars = (SolidColorVars *)seq->effectdata;
996 
997  rgb_float_to_uchar(col, colvars->col);
998  if (seq->flag & SEQ_MUTE) {
1000  col[3] = MUTE_ALPHA;
1001  }
1002  else {
1003  col[3] = 255;
1004  }
1005 
1007 
1008  immRectf(pos, seq->startdisp, y1, seq->enddisp, text_margin_y);
1009 
1010  /* 1px line to better separate the color band. */
1013 
1015  immVertex2f(pos, seq->startdisp, text_margin_y);
1016  immVertex2f(pos, seq->enddisp, text_margin_y);
1017  immEnd();
1018 
1019  if (seq->flag & SEQ_MUTE) {
1021  }
1022 }
1023 
1025  Sequence *seq,
1026  uint pos,
1027  float x1,
1028  float x2,
1029  float y1,
1030  float y2,
1031  bool is_single_image)
1032 {
1033  uchar col[4];
1034 
1035  /* Get the correct color per strip type, transitions use their inputs ones. */
1037  Sequence *seq1 = seq->seq1;
1038  if (seq1->type == SEQ_TYPE_COLOR) {
1039  SolidColorVars *colvars = (SolidColorVars *)seq1->effectdata;
1040  rgb_float_to_uchar(col, colvars->col);
1041  }
1042  else {
1043  color3ubv_from_seq(scene, seq1, col);
1044  }
1045  }
1046  else {
1047  color3ubv_from_seq(scene, seq, col);
1048  }
1049 
1050  if (seq->flag & SEQ_MUTE) {
1052 
1053  col[3] = MUTE_ALPHA;
1054  }
1055  else {
1056  col[3] = 255;
1057  }
1059 
1060  /* Draw the main strip body. */
1061  if (is_single_image) {
1062  immRectf(pos,
1064  y1,
1066  y2);
1067  }
1068  else {
1069  immRectf(pos, x1, y1, x2, y2);
1070  }
1071 
1072  /* Draw background for hold still regions. */
1073  if (!is_single_image && (seq->startstill || seq->endstill)) {
1076 
1077  if (seq->startstill) {
1078  const float content_start = min_ff(seq->enddisp, seq->start);
1079  immRectf(pos, seq->startdisp, y1, content_start, y2);
1080  }
1081  if (seq->endstill) {
1082  const float content_end = max_ff(seq->startdisp, seq->start + seq->len);
1083  immRectf(pos, content_end, y1, seq->enddisp, y2);
1084  }
1085  }
1086 
1087  /* Draw right half of transition strips. */
1089  float vert_pos[3][2];
1090  Sequence *seq1 = seq->seq1;
1091  Sequence *seq2 = seq->seq2;
1092 
1093  if (seq2->type == SEQ_TYPE_COLOR) {
1094  SolidColorVars *colvars = (SolidColorVars *)seq2->effectdata;
1095  rgb_float_to_uchar(col, colvars->col);
1096  }
1097  else {
1098  color3ubv_from_seq(scene, seq2, col);
1099  /* If the transition inputs are of the same type, draw the right side slightly darker. */
1100  if (seq1->type == seq2->type) {
1102  }
1103  }
1105 
1106  copy_v2_fl2(vert_pos[0], x1, y2);
1107  copy_v2_fl2(vert_pos[1], x2, y2);
1108  copy_v2_fl2(vert_pos[2], x2, y1);
1109 
1110  immBegin(GPU_PRIM_TRIS, 3);
1111  immVertex2fv(pos, vert_pos[0]);
1112  immVertex2fv(pos, vert_pos[1]);
1113  immVertex2fv(pos, vert_pos[2]);
1114  immEnd();
1115  }
1116 
1117  if (seq->flag & SEQ_MUTE) {
1119  }
1120 }
1121 
1122 static void draw_seq_locked(float x1, float y1, float x2, float y2)
1123 {
1125 
1128 
1129  immUniform4f("color1", 1.0f, 1.0f, 1.0f, 0.0f);
1130  immUniform4f("color2", 0.0f, 0.0f, 0.0f, 0.25f);
1131  immUniform1i("size1", 8);
1132  immUniform1i("size2", 4);
1133 
1134  immRectf(pos, x1, y1, x2, y2);
1135 
1136  immUnbindProgram();
1137 
1139 }
1140 
1141 static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
1142 {
1144 
1147  immUniformColor4f(1.0f, 0.0f, 0.0f, 0.9f);
1148  immRectf(pos, x1, y2, x2, text_margin_y);
1149 
1150  immUnbindProgram();
1152 }
1153 
1155  View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx)
1156 {
1157  const float handsize_clamped = sequence_handle_size_get_clamped(seq, pixelx);
1158  float text_margin = 2.0f * handsize_clamped;
1159 
1160  *x1 += text_margin;
1161  *x2 -= text_margin;
1162 
1163  float scroller_vert_xoffs = (V2D_SCROLL_HANDLE_WIDTH + SEQ_SCROLLER_TEXT_OFFSET) * pixelx;
1164 
1165  /* Info text on the strip. */
1166  if (*x1 < v2d->cur.xmin + scroller_vert_xoffs) {
1167  *x1 = v2d->cur.xmin + scroller_vert_xoffs;
1168  }
1169  else if (*x1 > v2d->cur.xmax) {
1170  *x1 = v2d->cur.xmax;
1171  }
1172  if (*x2 < v2d->cur.xmin) {
1173  *x2 = v2d->cur.xmin;
1174  }
1175  else if (*x2 > v2d->cur.xmax) {
1176  *x2 = v2d->cur.xmax;
1177  }
1178 }
1179 
1181  float y1,
1182  float y2,
1183  float y_height,
1184  int timeline_frame,
1185  float curve_val,
1186  unsigned int *vert_count)
1187 {
1188  float vert_pos[2][2];
1189 
1190  copy_v2_fl2(vert_pos[0], timeline_frame, (curve_val * y_height) + y1);
1191  copy_v2_fl2(vert_pos[1], timeline_frame, y2);
1192 
1193  GPU_vertbuf_vert_set(vbo, *vert_count, vert_pos[0]);
1194  GPU_vertbuf_vert_set(vbo, *vert_count + 1, vert_pos[1]);
1195  *vert_count += 2;
1196 }
1197 
1204  Scene *scene, View2D *v2d, Sequence *seq, float x1, float y1, float x2, float y2, float pixelx)
1205 {
1206  FCurve *fcu;
1207 
1208  if (seq->type == SEQ_TYPE_SOUND_RAM) {
1209  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
1210  }
1211  else {
1212  fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "blend_alpha", 0, NULL);
1213  }
1214 
1215  if (fcu && !BKE_fcurve_is_empty(fcu)) {
1216 
1217  /* Clamp curve evaluation to the editor's borders. */
1218  int eval_start = max_ff(x1, v2d->cur.xmin);
1219  int eval_end = min_ff(x2, v2d->cur.xmax + 1);
1220 
1221  int eval_step = max_ii(1, floor(pixelx));
1222 
1223  if (eval_start >= eval_end) {
1224  return;
1225  }
1226 
1227  GPUVertFormat format = {0};
1230 
1231  uint max_verts = 2 * ((eval_end - eval_start) / eval_step + 1);
1232  GPU_vertbuf_data_alloc(vbo, max_verts);
1233  uint vert_count = 0;
1234 
1235  const float y_height = y2 - y1;
1236  float curve_val;
1237  float prev_val = INT_MIN;
1238  bool skip = false;
1239 
1240  for (int timeline_frame = eval_start; timeline_frame <= eval_end;
1241  timeline_frame += eval_step) {
1242  curve_val = evaluate_fcurve(fcu, timeline_frame);
1243  CLAMP(curve_val, 0.0f, 1.0f);
1244 
1245  /* Avoid adding adjacent verts that have the same value. */
1246  if (curve_val == prev_val && timeline_frame < eval_end - eval_step) {
1247  skip = true;
1248  continue;
1249  }
1250 
1251  /* If some frames were skipped above, we need to close the shape. */
1252  if (skip) {
1254  vbo, y1, y2, y_height, timeline_frame - eval_step, prev_val, &vert_count);
1255  skip = false;
1256  }
1257 
1258  fcurve_batch_add_verts(vbo, y1, y2, y_height, timeline_frame, curve_val, &vert_count);
1259  prev_val = curve_val;
1260  }
1261 
1263  GPU_vertbuf_data_len_set(vbo, vert_count);
1265  GPU_batch_uniform_4f(batch, "color", 0.0f, 0.0f, 0.0f, 0.15f);
1267 
1268  if (vert_count > 0) {
1270  }
1271 
1274  }
1275 }
1276 
1277 /* Draw visible strips. Bounds check are already made. */
1278 static void draw_seq_strip(const bContext *C,
1279  SpaceSeq *sseq,
1280  Scene *scene,
1281  ARegion *region,
1282  Sequence *seq,
1283  float pixelx,
1284  bool seq_active)
1285 {
1286  View2D *v2d = &region->v2d;
1287  float x1, x2, y1, y2;
1288  const float handsize_clamped = sequence_handle_size_get_clamped(seq, pixelx);
1289  float pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
1290 
1291  /* Check if we are doing "solo preview". */
1292  bool is_single_image = (char)SEQ_transform_single_image_check(seq);
1293 
1294  /* Draw strip body. */
1295  x1 = (seq->startstill) ? seq->start : seq->startdisp;
1296  y1 = seq->machine + SEQ_STRIP_OFSBOTTOM;
1297  x2 = (seq->endstill) ? (seq->start + seq->len) : seq->enddisp;
1298  y2 = seq->machine + SEQ_STRIP_OFSTOP;
1299 
1300  /* Limit body to strip bounds. Meta strip can end up with content outside of strip range. */
1301  x1 = min_ff(x1, seq->enddisp);
1302  x2 = max_ff(x2, seq->startdisp);
1303 
1304  float text_margin_y;
1305  bool y_threshold;
1306  if ((sseq->flag & SEQ_SHOW_STRIP_NAME) || (sseq->flag & SEQ_SHOW_STRIP_SOURCE) ||
1307  (sseq->flag & SEQ_SHOW_STRIP_DURATION)) {
1308 
1309  /* Calculate height needed for drawing text on strip. */
1310  text_margin_y = y2 - min_ff(0.40f, 20 * U.dpi_fac * pixely);
1311 
1312  /* Is there enough space for drawing something else than text? */
1313  y_threshold = ((y2 - y1) / pixely) > 20 * U.dpi_fac;
1314  }
1315  else {
1316  text_margin_y = y2;
1317  y_threshold = false;
1318  }
1319 
1322 
1323  draw_seq_background(scene, seq, pos, x1, x2, y1, y2, is_single_image);
1324 
1325  /* Draw a color band inside color strip. */
1326  if (seq->type == SEQ_TYPE_COLOR && y_threshold) {
1327  draw_color_strip_band(seq, pos, text_margin_y, y1);
1328  }
1329 
1330  /* Draw strip offsets when flag is enabled or during "solo preview". */
1331  if ((sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) {
1332  if (!is_single_image && (seq->startofs || seq->endofs) && pixely > 0) {
1333  if ((sseq->draw_flag & SEQ_DRAW_OFFSET_EXT) || (seq == special_seq_update)) {
1335  }
1336  }
1337  }
1338  immUnbindProgram();
1339 
1340  x1 = seq->startdisp;
1341  x2 = seq->enddisp;
1342 
1343  if ((seq->type == SEQ_TYPE_META) ||
1344  ((seq->type == SEQ_TYPE_SCENE) && (seq->flag & SEQ_SCENE_STRIPS))) {
1345  drawmeta_contents(scene, seq, x1, y1, x2, y2);
1346  }
1347 
1348  if ((sseq->flag & SEQ_SHOW_STRIP_OVERLAY) && (sseq->flag & SEQ_SHOW_FCURVES)) {
1349  draw_seq_fcurve_overlay(scene, v2d, seq, x1, y1, x2, y2, pixelx);
1350  }
1351 
1352  /* Draw sound strip waveform. */
1353  if ((seq->type == SEQ_TYPE_SOUND_RAM) && ((sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) &&
1354  (sseq->flag & SEQ_NO_WAVEFORMS) == 0) {
1356  C,
1357  sseq,
1358  scene,
1359  seq,
1360  x1,
1361  y_threshold ? y1 + 0.05f : y1,
1362  x2,
1363  y_threshold ? text_margin_y : y2,
1364  BLI_rctf_size_x(&region->v2d.cur) / region->winx);
1365  }
1366  /* Draw locked state. */
1367  if (seq->flag & SEQ_LOCK) {
1368  draw_seq_locked(x1, y1, x2, y2);
1369  }
1370 
1371  /* Draw Red line on the top of invalid strip (Missing media). */
1372  if (!SEQ_sequence_has_source(seq)) {
1373  draw_seq_invalid(x1, x2, y2, text_margin_y);
1374  }
1375 
1378 
1379  if ((seq->flag & SEQ_LOCK) == 0) {
1381  v2d, seq, handsize_clamped, SEQ_LEFTHANDLE, pos, seq_active, pixelx, y_threshold);
1383  v2d, seq, handsize_clamped, SEQ_RIGHTHANDLE, pos, seq_active, pixelx, y_threshold);
1384  }
1385 
1386  draw_seq_outline(seq, pos, x1, x2, y1, y2, pixelx, pixely, seq_active);
1387 
1388  immUnbindProgram();
1389 
1390  calculate_seq_text_offsets(v2d, seq, &x1, &x2, pixelx);
1391 
1392  /* If a waveform is drawn, avoid drawing text when there is not enough vertical space. */
1393  if (seq->type == SEQ_TYPE_SOUND_RAM) {
1394  if (!y_threshold && (sseq->flag & SEQ_NO_WAVEFORMS) == 0 &&
1395  ((sseq->flag & SEQ_ALL_WAVEFORMS) || (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) {
1396  return;
1397  }
1398  }
1399 
1400  if (sseq->flag & SEQ_SHOW_STRIP_OVERLAY) {
1401  /* Don't draw strip if there is not enough vertical or horizontal space. */
1402  if (((x2 - x1) > 32 * pixelx * U.dpi_fac) && ((y2 - y1) > 8 * pixely * U.dpi_fac)) {
1403  /* Depending on the vertical space, draw text on top or in the center of strip. */
1405  v2d, seq, sseq, x1, x2, y_threshold ? text_margin_y : y1, y2, seq_active);
1406  }
1407  }
1408 }
1409 
1411 {
1412  Sequence *seq1 = seq->seq1;
1413  Sequence *seq2 = seq->seq2;
1414  Sequence *seq3 = seq->seq3;
1416 
1419 
1420  immUniformColor4ub(255, 255, 255, 48);
1421  immRectf(pos,
1422  seq1->startdisp,
1423  seq1->machine + SEQ_STRIP_OFSBOTTOM,
1424  seq1->enddisp,
1425  seq1->machine + SEQ_STRIP_OFSTOP);
1426 
1427  if (seq2 && seq2 != seq1) {
1428  immRectf(pos,
1429  seq2->startdisp,
1430  seq2->machine + SEQ_STRIP_OFSBOTTOM,
1431  seq2->enddisp,
1432  seq2->machine + SEQ_STRIP_OFSTOP);
1433  }
1434  if (seq3 && !ELEM(seq3, seq1, seq2)) {
1435  immRectf(pos,
1436  seq3->startdisp,
1437  seq3->machine + SEQ_STRIP_OFSBOTTOM,
1438  seq3->enddisp,
1439  seq3->machine + SEQ_STRIP_OFSTOP);
1440  }
1441  immUnbindProgram();
1443 }
1444 
1446 {
1447  special_seq_update = seq;
1448 }
1449 
1451 {
1452  return special_seq_update;
1453 }
1454 
1456 {
1458  ARegion *region = CTX_wm_region(C);
1459  int hand;
1460  Sequence *seq;
1461  seq = find_nearest_seq(scene, &region->v2d, &hand, mval);
1463 }
1464 
1466 {
1468 }
1469 
1478  ARegion *region,
1479  struct Depsgraph *depsgraph,
1480  Scene *scene,
1481  SpaceSeq *sseq,
1482  int timeline_frame,
1483  int frame_ofs,
1484  const char *viewname)
1485 {
1486  SeqRenderData context = {0};
1487  ImBuf *ibuf;
1488  int rectx, recty;
1489  double render_size;
1490  short is_break = G.is_break;
1491 
1492  if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
1493  return NULL;
1494  }
1495 
1496  if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
1497  render_size = scene->r.size / 100.0;
1498  }
1499  else {
1500  render_size = SEQ_rendersize_to_scale_factor(sseq->render_size);
1501  }
1502 
1503  rectx = roundf(render_size * scene->r.xsch);
1504  recty = roundf(render_size * scene->r.ysch);
1505 
1507  bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
1508  context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
1509  context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
1510 
1511  /* Sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
1512  * by Escape pressed somewhere in the past. */
1513  G.is_break = false;
1514 
1515  GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
1517  if (viewport) {
1518  /* Unbind viewport to release the DRW context. */
1519  GPU_viewport_unbind(viewport);
1520  }
1521  else {
1522  /* Rendering can change OGL context. Save & Restore frame-buffer. */
1524  }
1525 
1526  if (special_seq_update) {
1527  ibuf = SEQ_render_give_ibuf_direct(&context, timeline_frame + frame_ofs, special_seq_update);
1528  }
1529  else {
1530  ibuf = SEQ_render_give_ibuf(&context, timeline_frame + frame_ofs, sseq->chanshown);
1531  }
1532 
1533  if (viewport) {
1534  /* Follows same logic as wm_draw_window_offscreen to make sure to restore the same viewport. */
1535  int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
1536  GPU_viewport_bind(viewport, view, &region->winrct);
1537  }
1538  else if (fb) {
1540  }
1541 
1542  /* Restore state so real rendering would be canceled if needed. */
1543  G.is_break = is_break;
1544 
1545  return ibuf;
1546 }
1547 
1548 static void sequencer_check_scopes(SequencerScopes *scopes, ImBuf *ibuf)
1549 {
1550  if (scopes->reference_ibuf != ibuf) {
1551  if (scopes->zebra_ibuf) {
1552  IMB_freeImBuf(scopes->zebra_ibuf);
1553  scopes->zebra_ibuf = NULL;
1554  }
1555 
1556  if (scopes->waveform_ibuf) {
1557  IMB_freeImBuf(scopes->waveform_ibuf);
1558  scopes->waveform_ibuf = NULL;
1559  }
1560 
1561  if (scopes->sep_waveform_ibuf) {
1563  scopes->sep_waveform_ibuf = NULL;
1564  }
1565 
1566  if (scopes->vector_ibuf) {
1567  IMB_freeImBuf(scopes->vector_ibuf);
1568  scopes->vector_ibuf = NULL;
1569  }
1570 
1571  if (scopes->histogram_ibuf) {
1572  IMB_freeImBuf(scopes->histogram_ibuf);
1573  scopes->histogram_ibuf = NULL;
1574  }
1575  }
1576 }
1577 
1578 static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(ImBuf *ibuf))
1579 {
1580  ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
1581  ImBuf *scope;
1582 
1584  display_ibuf, &scene->view_settings, &scene->display_settings);
1585 
1586  scope = make_scope_fn(display_ibuf);
1587 
1588  IMB_freeImBuf(display_ibuf);
1589 
1590  return scope;
1591 }
1592 
1593 static void sequencer_display_size(Scene *scene, float r_viewrect[2])
1594 {
1595  r_viewrect[0] = (float)scene->r.xsch;
1596  r_viewrect[1] = (float)scene->r.ysch;
1597 
1598  r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
1599 }
1600 
1602 {
1603  /* Draw grease-pencil (image aligned). */
1605 
1606  /* Orthographic at pixel level. */
1608 
1609  /* Draw grease-pencil (screen aligned). */
1611 }
1612 
1613 /* Draw content and safety borders borders. */
1615  const View2D *v2d,
1616  const Scene *scene)
1617 {
1618  float x1 = v2d->tot.xmin;
1619  float y1 = v2d->tot.ymin;
1620  float x2 = v2d->tot.xmax;
1621  float y2 = v2d->tot.ymax;
1622 
1623  GPU_line_width(1.0f);
1624 
1625  /* Draw border. */
1626  const uint shdr_pos = GPU_vertformat_attr_add(
1628 
1630 
1631  float viewport_size[4];
1632  GPU_viewport_size_get_f(viewport_size);
1633  immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
1634 
1636  immUniform1i("colors_len", 0); /* Simple dashes. */
1637  immUniform1f("dash_width", 6.0f);
1638  immUniform1f("dash_factor", 0.5f);
1639 
1640  imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
1641 
1642  /* Draw safety border. */
1643  if (sseq->flag & SEQ_SHOW_SAFE_MARGINS) {
1645 
1646  UI_draw_safe_areas(shdr_pos,
1647  &(const rctf){
1648  .xmin = x1,
1649  .xmax = x2,
1650  .ymin = y1,
1651  .ymax = y2,
1652  },
1655 
1656  if (sseq->flag & SEQ_SHOW_SAFE_CENTER) {
1657  UI_draw_safe_areas(shdr_pos,
1658  &(const rctf){
1659  .xmin = x1,
1660  .xmax = x2,
1661  .ymin = y1,
1662  .ymax = y2,
1663  },
1666  }
1667  }
1668 
1669  immUnbindProgram();
1670 }
1671 
1672 #if 0
1673 void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
1674 {
1675  /* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
1676  * For now just disable drawing since the strip frame will likely be offset. */
1677 
1678  // if (sc->mode == SC_MODE_MASKEDIT)
1679  if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
1681 
1682  if (mask) {
1683  int width, height;
1684  float aspx = 1.0f, aspy = 1.0f;
1685  // ED_mask_get_size(C, &width, &height);
1686 
1687  //Scene *scene = CTX_data_scene(C);
1688  width = (scene->r.size * scene->r.xsch) / 100;
1689  height = (scene->r.size * scene->r.ysch) / 100;
1690 
1692  region,
1693  0,
1694  0,
1695  0, /* TODO */
1696  width,
1697  height,
1698  aspx,
1699  aspy,
1700  false,
1701  true,
1702  NULL,
1703  C);
1704  }
1705  }
1706 }
1707 #endif
1708 
1709 /* Force redraw, when prefetching and using cache view. */
1711 {
1714  }
1715 }
1716 
1718  ImBuf *ibuf,
1719  bool *r_glsl_used,
1720  eGPUTextureFormat *r_format,
1721  eGPUDataFormat *r_data,
1722  void **r_buffer_cache_handle)
1723 {
1724  void *display_buffer;
1725  bool force_fallback = false;
1726  *r_glsl_used = false;
1727  force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
1728  force_fallback |= (ibuf->dither != 0.0f);
1729 
1730  /* Default */
1731  *r_format = GPU_RGBA8;
1732  *r_data = GPU_DATA_UBYTE;
1733 
1734  /* Fallback to CPU based color space conversion. */
1735  if (force_fallback) {
1736  *r_glsl_used = false;
1737  display_buffer = NULL;
1738  }
1739  else if (ibuf->rect_float) {
1740  display_buffer = ibuf->rect_float;
1741 
1742  *r_data = GPU_DATA_FLOAT;
1743  if (ibuf->channels == 4) {
1744  *r_format = GPU_RGBA16F;
1745  }
1746  else if (ibuf->channels == 3) {
1747  /* Alpha is implicitly 1. */
1748  *r_format = GPU_RGB16F;
1749  }
1750  else {
1751  BLI_assert(!"Incompatible number of channels for float buffer in sequencer");
1752  *r_format = GPU_RGBA16F;
1753  display_buffer = NULL;
1754  }
1755 
1756  if (ibuf->float_colorspace) {
1758  C, ibuf->float_colorspace, ibuf->dither, true);
1759  }
1760  else {
1761  *r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
1762  }
1763  }
1764  else if (ibuf->rect) {
1765  display_buffer = ibuf->rect;
1766 
1768  C, ibuf->rect_colorspace, ibuf->dither, false);
1769  }
1770  else {
1771  display_buffer = NULL;
1772  }
1773 
1774  /* There is data to be displayed, but GLSL is not initialized
1775  * properly, in this case we fallback to CPU-based display transform. */
1776  if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
1777  display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
1778  *r_format = GPU_RGBA8;
1779  *r_data = GPU_DATA_UBYTE;
1780  }
1781 
1782  return display_buffer;
1783 }
1784 
1786 {
1787  if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
1788  /* Stop all running jobs, except screen one. Currently previews frustrate Render.
1789  * Need to make so sequencers rendering doesn't conflict with compositor. */
1791 
1792  /* In case of final rendering used for preview, kill all previews,
1793  * otherwise threading conflict will happen in rendering module. */
1795  }
1796 }
1797 
1798 static void sequencer_preview_clear(void)
1799 {
1801 }
1802 
1803 static void sequencer_preview_get_rect(rctf *preview,
1804  Scene *scene,
1805  ARegion *region,
1806  SpaceSeq *sseq,
1807  bool draw_overlay,
1808  bool draw_backdrop)
1809 {
1810  struct View2D *v2d = &region->v2d;
1811  float viewrect[2];
1812 
1813  sequencer_display_size(scene, viewrect);
1814  BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
1815 
1816  if (draw_overlay && sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
1817  preview->xmax = v2d->tot.xmin +
1819  preview->xmin = v2d->tot.xmin +
1821  preview->ymax = v2d->tot.ymin +
1823  preview->ymin = v2d->tot.ymin +
1825  }
1826  else if (draw_backdrop) {
1827  float aspect = BLI_rcti_size_x(&region->winrct) / (float)BLI_rcti_size_y(&region->winrct);
1828  float image_aspect = viewrect[0] / viewrect[1];
1829 
1830  if (aspect >= image_aspect) {
1831  preview->xmax = image_aspect / aspect;
1832  preview->xmin = -preview->xmax;
1833  }
1834  else {
1835  preview->ymax = aspect / image_aspect;
1836  preview->ymin = -preview->ymax;
1837  }
1838  }
1839  else {
1840  *preview = v2d->tot;
1841  }
1842 }
1843 
1845  Scene *scene,
1846  ARegion *region,
1847  SpaceSeq *sseq,
1848  ImBuf *ibuf,
1849  ImBuf *scope,
1850  bool draw_overlay,
1851  bool draw_backdrop)
1852 {
1853  void *display_buffer;
1854  void *buffer_cache_handle = NULL;
1855 
1856  if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
1858  }
1859 
1860  /* Format needs to be created prior to any #immBindShader call.
1861  * Do it here because OCIO binds its own shader. */
1864  bool glsl_used = false;
1865  GPUVertFormat *imm_format = immVertexFormat();
1866  uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1867  uint texCoord = GPU_vertformat_attr_add(
1868  imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
1869 
1870  if (scope) {
1871  ibuf = scope;
1872 
1873  if (ibuf->rect_float && ibuf->rect == NULL) {
1874  IMB_rect_from_float(ibuf);
1875  }
1876 
1877  display_buffer = (uchar *)ibuf->rect;
1878  format = GPU_RGBA8;
1879  data = GPU_DATA_UBYTE;
1880  }
1881  else {
1882  display_buffer = sequencer_OCIO_transform_ibuf(
1883  C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
1884  }
1885 
1886  if (draw_backdrop) {
1887  GPU_matrix_push();
1891  }
1892 
1894  "seq_display_buf", ibuf->x, ibuf->y, 1, format, NULL);
1895  GPU_texture_update(texture, data, display_buffer);
1897 
1899 
1900  if (!glsl_used) {
1902  immUniformColor3f(1.0f, 1.0f, 1.0f);
1903  immUniform1i("image", 0);
1904  }
1905 
1907 
1908  rctf preview;
1909  rctf canvas;
1910  sequencer_preview_get_rect(&preview, scene, region, sseq, draw_overlay, draw_backdrop);
1911 
1912  if (draw_overlay && sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
1913  canvas = scene->ed->over_border;
1914  }
1915  else {
1916  BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
1917  }
1918 
1919  immAttr2f(texCoord, canvas.xmin, canvas.ymin);
1920  immVertex2f(pos, preview.xmin, preview.ymin);
1921 
1922  immAttr2f(texCoord, canvas.xmin, canvas.ymax);
1923  immVertex2f(pos, preview.xmin, preview.ymax);
1924 
1925  immAttr2f(texCoord, canvas.xmax, canvas.ymax);
1926  immVertex2f(pos, preview.xmax, preview.ymax);
1927 
1928  immAttr2f(texCoord, canvas.xmax, canvas.ymin);
1929  immVertex2f(pos, preview.xmax, preview.ymin);
1930 
1931  immEnd();
1932 
1935 
1936  if (!glsl_used) {
1937  immUnbindProgram();
1938  }
1939  else {
1941  }
1942 
1943  if (buffer_cache_handle) {
1944  IMB_display_buffer_release(buffer_cache_handle);
1945  }
1946 
1947  if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
1949  }
1950 
1951  if (draw_backdrop) {
1952  GPU_matrix_pop();
1954  }
1955 }
1956 
1957 static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
1958 {
1959  struct ImBuf *scope = NULL;
1960  SequencerScopes *scopes = &sseq->scopes;
1961 
1962  if (!draw_backdrop && (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0)) {
1963  sequencer_check_scopes(scopes, ibuf);
1964 
1965  switch (sseq->mainb) {
1966  case SEQ_DRAW_IMG_IMBUF:
1967  if (!scopes->zebra_ibuf) {
1968  ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
1969 
1970  if (display_ibuf->rect_float) {
1972  display_ibuf, &scene->view_settings, &scene->display_settings);
1973  }
1974  scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra);
1975  IMB_freeImBuf(display_ibuf);
1976  }
1977  scope = scopes->zebra_ibuf;
1978  break;
1979  case SEQ_DRAW_IMG_WAVEFORM:
1980  if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
1981  if (!scopes->sep_waveform_ibuf) {
1984  }
1985  scope = scopes->sep_waveform_ibuf;
1986  }
1987  else {
1988  if (!scopes->waveform_ibuf) {
1991  }
1992  scope = scopes->waveform_ibuf;
1993  }
1994  break;
1996  if (!scopes->vector_ibuf) {
1998  }
1999  scope = scopes->vector_ibuf;
2000  break;
2002  if (!scopes->histogram_ibuf) {
2005  }
2006  scope = scopes->histogram_ibuf;
2007  break;
2008  }
2009 
2010  /* Future files may have new scopes we don't catch above. */
2011  if (scope) {
2012  scopes->reference_ibuf = ibuf;
2013  }
2014  }
2015  return scope;
2016 }
2017 
2019 {
2020  Sequence *last_seq = SEQ_select_active_get(scene);
2021  if (last_seq == NULL) {
2022  return false;
2023  }
2024 
2025  return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
2026  ((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
2028 }
2029 
2031 {
2032  Sequence *last_seq = SEQ_select_active_get(scene);
2033  /* #sequencer_draw_get_transform_preview must already have been called. */
2034  BLI_assert(last_seq != NULL);
2035  int preview_frame;
2036 
2037  if (last_seq->flag & SEQ_RIGHTSEL) {
2038  preview_frame = last_seq->enddisp - 1;
2039  }
2040  else {
2041  preview_frame = last_seq->startdisp;
2042  }
2043 
2044  return preview_frame;
2045 }
2046 
2048  Scene *scene,
2049  ARegion *region,
2050  SpaceSeq *sseq,
2051  int timeline_frame,
2052  int offset,
2053  bool draw_overlay,
2054  bool draw_backdrop)
2055 {
2056  struct Main *bmain = CTX_data_main(C);
2058  struct View2D *v2d = &region->v2d;
2059  struct ImBuf *ibuf = NULL;
2060  struct ImBuf *scope = NULL;
2061  float viewrect[2];
2062  const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
2063  const bool draw_gpencil = ((sseq->flag & SEQ_SHOW_GPENCIL) && sseq->gpd);
2064  const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
2065 
2067  if (G.is_rendering) {
2068  return;
2069  }
2070 
2071  int preview_frame = timeline_frame;
2074  }
2075 
2076  /* Get image. */
2077  ibuf = sequencer_ibuf_get(
2078  bmain, region, depsgraph, scene, sseq, preview_frame, offset, names[sseq->multiview_eye]);
2079 
2080  /* Setup off-screen buffers. */
2081  GPUViewport *viewport = WM_draw_region_get_viewport(region);
2082  GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
2083  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2085 
2086  if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
2088  return;
2089  }
2090 
2091  /* Setup view. */
2092  sequencer_display_size(scene, viewrect);
2093  UI_view2d_totRect_set(v2d, roundf(viewrect[0] + 0.5f), roundf(viewrect[1] + 0.5f));
2095  UI_view2d_view_ortho(v2d);
2096 
2097  /* Draw background. */
2098  if (!draw_backdrop && (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE)) {
2100 
2101  if (sseq->flag & SEQ_USE_ALPHA) {
2102  imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
2103  }
2104  }
2105 
2106  if (ibuf) {
2107  scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
2108 
2109  /* Draw image. */
2111  C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop);
2112 
2113  /* Draw over image. */
2114  if (sseq->flag & SEQ_SHOW_METADATA && sseq->flag & SEQ_SHOW_STRIP_OVERLAY) {
2115  ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
2116  }
2117  }
2118 
2119  if (show_imbuf && (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) {
2121  }
2122 
2123  if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_STRIP_OVERLAY)) {
2125  }
2126 #if 0
2127  sequencer_draw_maskedit(C, scene, region, sseq);
2128 #endif
2129 
2130  /* Scope is freed in sequencer_check_scopes when `ibuf` changes and redraw is needed. */
2131  if (ibuf) {
2132  IMB_freeImBuf(ibuf);
2133  }
2134 
2137 }
2138 
2139 /* Draw backdrop in sequencer timeline. */
2140 static void draw_seq_backdrop(View2D *v2d)
2141 {
2142  int i;
2143 
2146 
2147  /* View backdrop. */
2149  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2150 
2151  /* Darker overlay over the view backdrop. */
2153  immRectf(pos, v2d->cur.xmin, -1.0, v2d->cur.xmax, 1.0);
2154 
2155  /* Alternating horizontal stripes. */
2156  i = max_ii(1, ((int)v2d->cur.ymin) - 1);
2157 
2160 
2161  while (i < v2d->cur.ymax) {
2162  if (i & 1) {
2163  immRectf(pos, v2d->cur.xmin, i, v2d->cur.xmax, i + 1);
2164  }
2165  i++;
2166  }
2167 
2169 
2170  /* Lines separating the horizontal bands. */
2171  i = max_ii(1, ((int)v2d->cur.ymin) - 1);
2172  int line_len = (int)v2d->cur.ymax - i + 1;
2174  immBegin(GPU_PRIM_LINES, line_len * 2);
2175  while (line_len--) {
2176  immVertex2f(pos, v2d->cur.xmax, i);
2177  immVertex2f(pos, v2d->cur.xmin, i);
2178  i++;
2179  }
2180  immEnd();
2181 
2182  immUnbindProgram();
2183 }
2184 
2185 static void draw_seq_strips(const bContext *C, Editing *ed, ARegion *region)
2186 {
2188  View2D *v2d = &region->v2d;
2189  SpaceSeq *sseq = CTX_wm_space_seq(C);
2190  Sequence *last_seq = SEQ_select_active_get(scene);
2191  int sel = 0, j;
2192  float pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
2193 
2194  /* Loop through twice, first unselected, then selected. */
2195  for (j = 0; j < 2; j++) {
2196  Sequence *seq;
2197  /* Loop through strips, checking for those that are visible. */
2198  for (seq = ed->seqbasep->first; seq; seq = seq->next) {
2199  /* Bound-box and selection tests for NOT drawing the strip. */
2200  if ((seq->flag & SELECT) != sel) {
2201  continue;
2202  }
2203  if (seq == last_seq && (last_seq->flag & SELECT)) {
2204  continue;
2205  }
2206  if (min_ii(seq->startdisp, seq->start) > v2d->cur.xmax) {
2207  continue;
2208  }
2209  if (max_ii(seq->enddisp, seq->start + seq->len) < v2d->cur.xmin) {
2210  continue;
2211  }
2212  if (seq->machine + 1.0f < v2d->cur.ymin) {
2213  continue;
2214  }
2215  if (seq->machine > v2d->cur.ymax) {
2216  continue;
2217  }
2218 
2219  /* Strip passed all tests, draw it now. */
2220  draw_seq_strip(C, sseq, scene, region, seq, pixelx, seq == last_seq ? true : false);
2221  }
2222 
2223  /* Draw selected next time round. */
2224  sel = SELECT;
2225  }
2226 
2227  /* When selected draw the last selected (active) strip last,
2228  * removes some overlapping error. */
2229  if (last_seq && (last_seq->flag & SELECT)) {
2230  draw_seq_strip(C, sseq, scene, region, last_seq, pixelx, true);
2231 
2232  /* When active strip is an effect, highlight its inputs. */
2233  if (SEQ_effect_get_num_inputs(last_seq->type) > 0) {
2234  draw_effect_inputs_highlight(last_seq);
2235  }
2236  /* When active is a Multi-cam strip, highlight its source channel. */
2237  else if (last_seq->type == SEQ_TYPE_MULTICAM) {
2238  int channel = last_seq->multicam_source;
2239  if (channel != 0) {
2244 
2245  immUniformColor4ub(255, 255, 255, 48);
2246  immRectf(pos, v2d->cur.xmin, channel, v2d->cur.xmax, channel + 1);
2247 
2248  immUnbindProgram();
2250  }
2251  }
2252  }
2253 
2254  /* Draw highlight if "solo preview" is used. */
2255  if (special_seq_update) {
2256  const Sequence *seq = special_seq_update;
2258 
2261 
2262  immUniformColor4ub(255, 255, 255, 48);
2263  immRectf(pos,
2264  seq->startdisp,
2266  seq->enddisp,
2267  seq->machine + SEQ_STRIP_OFSTOP);
2268 
2269  immUnbindProgram();
2270 
2272  }
2273 }
2274 
2276 {
2277  const Editing *ed = SEQ_editing_get(scene, false);
2278  const int frame_sta = scene->r.sfra;
2279  const int frame_end = scene->r.efra + 1;
2280 
2282 
2285 
2286  /* Draw overlay outside of frame range. */
2288 
2289  if (frame_sta < frame_end) {
2290  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)frame_sta, v2d->cur.ymax);
2291  immRectf(pos, (float)frame_end, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2292  }
2293  else {
2294  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2295  }
2296 
2298 
2299  /* Draw frame range boundary. */
2301 
2302  immVertex2f(pos, frame_sta, v2d->cur.ymin);
2303  immVertex2f(pos, frame_sta, v2d->cur.ymax);
2304 
2305  immVertex2f(pos, frame_end, v2d->cur.ymin);
2306  immVertex2f(pos, frame_end, v2d->cur.ymax);
2307 
2308  immEnd();
2309 
2310  /* While in meta strip, draw a checkerboard overlay outside of frame range. */
2311  if (ed && !BLI_listbase_is_empty(&ed->metastack)) {
2312  MetaStack *ms = ed->metastack.last;
2313  immUnbindProgram();
2314 
2316 
2317  immUniform4f("color1", 0.0f, 0.0f, 0.0f, 0.22f);
2318  immUniform4f("color2", 1.0f, 1.0f, 1.0f, 0.0f);
2319  immUniform1i("size", 8);
2320 
2321  immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, ms->disp_range[0], v2d->cur.ymax);
2322  immRectf(pos, ms->disp_range[1], v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
2323 
2324  immUnbindProgram();
2325 
2328 
2330 
2331  immVertex2f(pos, ms->disp_range[0], v2d->cur.ymin);
2332  immVertex2f(pos, ms->disp_range[0], v2d->cur.ymax);
2333 
2334  immVertex2f(pos, ms->disp_range[1], v2d->cur.ymin);
2335  immVertex2f(pos, ms->disp_range[1], v2d->cur.ymax);
2336 
2337  immEnd();
2338  }
2339 
2340  immUnbindProgram();
2341 
2343 }
2344 
2345 typedef struct CacheDrawData {
2346  struct View2D *v2d;
2348  float stripe_ht;
2359 
2360 /* Called as a callback. */
2361 static bool draw_cache_view_init_fn(void *userdata, size_t item_count)
2362 {
2363  if (item_count == 0) {
2364  return true;
2365  }
2366 
2367  CacheDrawData *drawdata = userdata;
2368  /* We can not get item count per cache type, so using total item count is safe. */
2369  size_t max_vert_count = item_count * 6;
2370  GPU_vertbuf_data_alloc(drawdata->raw_vbo, max_vert_count);
2371  GPU_vertbuf_data_alloc(drawdata->preprocessed_vbo, max_vert_count);
2372  GPU_vertbuf_data_alloc(drawdata->composite_vbo, max_vert_count);
2373  GPU_vertbuf_data_alloc(drawdata->final_out_vbo, max_vert_count);
2374 
2375  return false;
2376 }
2377 
2378 /* Called as a callback */
2379 static bool draw_cache_view_iter_fn(void *userdata,
2380  struct Sequence *seq,
2381  int timeline_frame,
2382  int cache_type)
2383 {
2384  CacheDrawData *drawdata = userdata;
2385  struct View2D *v2d = drawdata->v2d;
2386  float stripe_bot, stripe_top, stripe_ofs_y, stripe_ht;
2387  GPUVertBuf *vbo;
2388  size_t *vert_count;
2389 
2390  if ((cache_type & SEQ_CACHE_STORE_FINAL_OUT) &&
2391  (drawdata->cache_flag & SEQ_CACHE_VIEW_FINAL_OUT)) {
2392  stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) - v2d->cur.ymin;
2394  stripe_top = stripe_bot + stripe_ht;
2395  vbo = drawdata->final_out_vbo;
2396  vert_count = &drawdata->final_out_vert_count;
2397  }
2398  else if ((cache_type & SEQ_CACHE_STORE_RAW) && (drawdata->cache_flag & SEQ_CACHE_VIEW_RAW)) {
2399  stripe_ofs_y = drawdata->stripe_ofs_y;
2400  stripe_ht = drawdata->stripe_ht;
2401  stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_ofs_y;
2402  stripe_top = stripe_bot + stripe_ht;
2403  vbo = drawdata->raw_vbo;
2404  vert_count = &drawdata->raw_vert_count;
2405  }
2406  else if ((cache_type & SEQ_CACHE_STORE_PREPROCESSED) &&
2407  (drawdata->cache_flag & SEQ_CACHE_VIEW_PREPROCESSED)) {
2408  stripe_ofs_y = drawdata->stripe_ofs_y;
2409  stripe_ht = drawdata->stripe_ht;
2410  stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + (stripe_ofs_y + stripe_ht) + stripe_ofs_y;
2411  stripe_top = stripe_bot + stripe_ht;
2412  vbo = drawdata->preprocessed_vbo;
2413  vert_count = &drawdata->preprocessed_vert_count;
2414  }
2415  else if ((cache_type & SEQ_CACHE_STORE_COMPOSITE) &&
2416  (drawdata->cache_flag & SEQ_CACHE_VIEW_COMPOSITE)) {
2417  stripe_ofs_y = drawdata->stripe_ofs_y;
2418  stripe_ht = drawdata->stripe_ht;
2419  stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_ofs_y;
2420  stripe_bot = stripe_top - stripe_ht;
2421  vbo = drawdata->composite_vbo;
2422  vert_count = &drawdata->composite_vert_count;
2423  }
2424  else {
2425  return false;
2426  }
2427 
2428  float vert_pos[6][2];
2429  copy_v2_fl2(vert_pos[0], timeline_frame, stripe_bot);
2430  copy_v2_fl2(vert_pos[1], timeline_frame, stripe_top);
2431  copy_v2_fl2(vert_pos[2], timeline_frame + 1, stripe_top);
2432  copy_v2_v2(vert_pos[3], vert_pos[2]);
2433  copy_v2_v2(vert_pos[4], vert_pos[0]);
2434  copy_v2_fl2(vert_pos[5], timeline_frame + 1, stripe_bot);
2435 
2436  for (int i = 0; i < 6; i++) {
2437  GPU_vertbuf_vert_set(vbo, *vert_count + i, vert_pos[i]);
2438  }
2439 
2440  *vert_count += 6;
2441  return false;
2442 }
2443 
2445  GPUVertBuf *vbo, size_t vert_count, float col_r, float col_g, float col_b, float col_a)
2446 {
2448  if (vert_count > 0) {
2449  GPU_vertbuf_data_len_set(vbo, vert_count);
2451  GPU_batch_uniform_4f(batch, "color", col_r, col_g, col_b, col_a);
2453  }
2455 }
2456 
2457 static void draw_cache_view(const bContext *C)
2458 {
2460  ARegion *region = CTX_wm_region(C);
2461  struct View2D *v2d = &region->v2d;
2462 
2463  if ((scene->ed->cache_flag & SEQ_CACHE_VIEW_ENABLE) == 0) {
2464  return;
2465  }
2466 
2470 
2471  float stripe_bot, stripe_top;
2472  float stripe_ofs_y = UI_view2d_region_to_view_y(v2d, 1.0f) - v2d->cur.ymin;
2473  float stripe_ht = UI_view2d_region_to_view_y(v2d, 4.0f * UI_DPI_FAC * U.pixelsize) -
2474  v2d->cur.ymin;
2475 
2476  CLAMP_MAX(stripe_ht, 0.2f);
2477  CLAMP_MIN(stripe_ofs_y, stripe_ht / 2);
2478 
2481  stripe_top = stripe_bot + stripe_ht;
2482  const float bg_color[4] = {1.0f, 0.4f, 0.2f, 0.1f};
2483 
2484  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2485  immRectf(pos, scene->r.sfra, stripe_bot, scene->r.efra, stripe_top);
2486  }
2487 
2488  for (Sequence *seq = scene->ed->seqbasep->first; seq != NULL; seq = seq->next) {
2489  if (seq->type == SEQ_TYPE_SOUND_RAM) {
2490  continue;
2491  }
2492 
2493  if (seq->startdisp > v2d->cur.xmax || seq->enddisp < v2d->cur.xmin) {
2494  continue;
2495  }
2496 
2497  stripe_bot = seq->machine + SEQ_STRIP_OFSBOTTOM + stripe_ofs_y;
2498  stripe_top = stripe_bot + stripe_ht;
2499 
2501  const float bg_color[4] = {1.0f, 0.1f, 0.02f, 0.1f};
2502  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2503  immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
2504  }
2505 
2506  stripe_bot += stripe_ht + stripe_ofs_y;
2507  stripe_top = stripe_bot + stripe_ht;
2508 
2510  const float bg_color[4] = {0.1f, 0.1f, 0.75f, 0.1f};
2511  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2512  immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
2513  }
2514 
2515  stripe_top = seq->machine + SEQ_STRIP_OFSTOP - stripe_ofs_y;
2516  stripe_bot = stripe_top - stripe_ht;
2517 
2519  const float bg_color[4] = {1.0f, 0.6f, 0.0f, 0.1f};
2520  immUniformColor4f(bg_color[0], bg_color[1], bg_color[2], bg_color[3]);
2521  immRectf(pos, seq->startdisp, stripe_bot, seq->enddisp, stripe_top);
2522  }
2523  }
2524 
2525  immUnbindProgram();
2526 
2527  GPUVertFormat format = {0};
2529 
2530  CacheDrawData userdata;
2531  userdata.v2d = v2d;
2532  userdata.stripe_ofs_y = stripe_ofs_y;
2533  userdata.stripe_ht = stripe_ht;
2534  userdata.cache_flag = scene->ed->cache_flag;
2535  userdata.raw_vert_count = 0;
2536  userdata.preprocessed_vert_count = 0;
2537  userdata.composite_vert_count = 0;
2538  userdata.final_out_vert_count = 0;
2543 
2545 
2546  draw_cache_view_batch(userdata.raw_vbo, userdata.raw_vert_count, 1.0f, 0.1f, 0.02f, 0.4f);
2548  userdata.preprocessed_vbo, userdata.preprocessed_vert_count, 0.1f, 0.1f, 0.75f, 0.4f);
2550  userdata.composite_vbo, userdata.composite_vert_count, 1.0f, 0.6f, 0.0f, 0.4f);
2552  userdata.final_out_vbo, userdata.final_out_vert_count, 1.0f, 0.4f, 0.2f, 0.4f);
2553 
2555 }
2556 
2557 /* Draw sequencer timeline. */
2558 void draw_timeline_seq(const bContext *C, ARegion *region)
2559 {
2561  Editing *ed = SEQ_editing_get(scene, false);
2562  SpaceSeq *sseq = CTX_wm_space_seq(C);
2563  View2D *v2d = &region->v2d;
2564  short cfra_flag = 0;
2565  float col[3];
2566 
2568 
2569  GPUViewport *viewport = WM_draw_region_get_viewport(region);
2570  GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
2571  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2573 
2575  if (ed && ed->metastack.first) {
2576  GPU_clear_color(col[0], col[1], col[2] - 0.1f, 0.0f);
2577  }
2578  else {
2579  GPU_clear_color(col[0], col[1], col[2], 0.0f);
2580  }
2581 
2582  UI_view2d_view_ortho(v2d);
2583  /* Get timeline bound-box, needed for the scroll-bars. */
2585  draw_seq_backdrop(v2d);
2587 
2588  /* Only draw backdrop in timeline view. */
2589  if (sseq->view == SEQ_VIEW_SEQUENCE && sseq->draw_flag & SEQ_DRAW_BACKDROP) {
2590  int preview_frame = scene->r.cfra;
2593  }
2594 
2595  sequencer_draw_preview(C, scene, region, sseq, preview_frame, 0, false, true);
2596  UI_view2d_view_ortho(v2d);
2597  }
2598 
2599  /* Draw attached callbacks. */
2600  GPU_framebuffer_bind(framebuffer_overlay);
2602  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2603 
2604  seq_draw_sfra_efra(scene, v2d);
2605 
2606  if (ed) {
2607  draw_seq_strips(C, ed, region);
2608  /* Draw text added in previous function. */
2609  UI_view2d_text_cache_draw(region);
2610  }
2611 
2612  UI_view2d_view_ortho(v2d);
2613  if ((sseq->flag & SEQ_DRAWFRAMES) == 0) {
2614  cfra_flag |= DRAWCFRA_UNIT_SECONDS;
2615  }
2616 
2617  /* Draw overlap frame frame indicator. */
2619  int overlap_frame = (scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS) ?
2620  scene->ed->over_cfra :
2621  scene->r.cfra + scene->ed->over_ofs;
2622 
2625  float viewport_size[4];
2626  GPU_viewport_size_get_f(viewport_size);
2627  immUniform2f("viewport_size", viewport_size[2], viewport_size[3]);
2628  /* Shader may have color set from past usage - reset it. */
2629  immUniform1i("colors_len", 0);
2630  immUniform1f("dash_width", 20.0f * U.pixelsize);
2631  immUniform1f("dash_factor", 0.5f);
2633 
2635  immVertex2f(pos, overlap_frame, v2d->cur.ymin);
2636  immVertex2f(pos, overlap_frame, v2d->cur.ymax);
2637  immEnd();
2638 
2639  immUnbindProgram();
2640  }
2641 
2642  UI_view2d_view_orthoSpecial(region, v2d, 1);
2643  int marker_draw_flag = DRAW_MARKERS_MARGIN;
2644  if (sseq->flag & SEQ_SHOW_MARKERS) {
2645  ED_markers_draw(C, marker_draw_flag);
2646  }
2647 
2648  UI_view2d_view_ortho(v2d);
2649 
2650  if (ed) {
2651  draw_cache_view(C);
2652  }
2653 
2654  ANIM_draw_previewrange(C, v2d, 1);
2655 
2656  /* Draw registered callbacks. */
2657  GPU_framebuffer_bind(framebuffer_overlay);
2659  GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
2660 
2662  ED_time_scrub_draw(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
2663 
2664  /* Draw channel numbers. */
2665  {
2666  rcti rect;
2667  BLI_rcti_init(
2668  &rect, 0, 15 * UI_DPI_FAC, 15 * UI_DPI_FAC, region->winy - UI_TIME_SCRUB_MARGIN_Y);
2669  UI_view2d_draw_scale_y__block(region, v2d, &rect, TH_SCROLL_TEXT);
2670  }
2671 }
2672 
2674 {
2675  const Scene *scene = CTX_data_scene(C);
2676  const SpaceSeq *sseq = CTX_wm_space_seq(C);
2677  View2D *v2d = &region->v2d;
2678 
2679  ED_time_scrub_draw_current_frame(region, scene, !(sseq->flag & SEQ_DRAWFRAMES), true);
2681 }
typedef float(TangentPoint)[2]
int ED_draw_imbuf_method(struct ImBuf *ibuf)
Definition: glutil.c:566
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1034
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:689
struct SpaceSeq * CTX_wm_space_seq(const bContext *C)
Definition: context.c:827
struct Depsgraph * CTX_data_expect_evaluated_depsgraph(const bContext *C)
Definition: context.c:1415
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
float evaluate_fcurve(struct FCurve *fcu, float evaltime)
Definition: fcurve.c:2186
bool BKE_fcurve_is_empty(struct FCurve *fcu)
Definition: fcurve.c:2250
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:221
@ G_TRANSFORM_SEQ
Definition: BKE_global.h:220
int BKE_scene_multiview_view_id_get(const struct RenderData *rd, const char *viewname)
#define SOUND_WAVE_SAMPLES_PER_SECOND
Definition: BKE_sound.h:29
float BLF_width(int fontid, const char *str, size_t len) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: blf.c:723
int BLF_default(void)
Definition: blf_default.c:55
int BLF_set_default(void)
Definition: blf_default.c:61
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:124
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, float hue_offset)
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
Definition: math_color.c:422
MINLINE void copy_v2_fl2(float v[2], float x, float y)
MINLINE void copy_v2_v2(float r[2], const float a[2])
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:157
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:446
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition: rct.c:436
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:153
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:161
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:165
#define SNPRINTF(dst, format,...)
Definition: BLI_string.h:165
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
char * BLI_string_join_array(char *result, size_t result_len, const char *strings[], uint strings_len) ATTR_NONNULL()
Definition: string_utils.c:419
unsigned char uchar
Definition: BLI_sys_types.h:86
unsigned int uint
Definition: BLI_sys_types.h:83
void BLI_spin_unlock(SpinLock *spin)
Definition: threads.cc:480
void BLI_spin_lock(SpinLock *spin)
Definition: threads.cc:461
#define CLAMP_MAX(a, c)
#define ARRAY_SIZE(arr)
#define ELEM(...)
#define CLAMP_MIN(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ OB_RENDER
Object is a sort of wrapper for general info.
#define STEREO_LEFT_NAME
#define STEREO_RIGHT_NAME
@ STEREO_RIGHT_ID
#define FPS
@ SEQ_MUTE
@ SEQ_RIGHTSEL
@ SEQ_SCENE_STRIPS
@ SEQ_OVERLAP
@ SEQ_LOCK
@ SEQ_AUDIO_DRAW_WAVEFORM
@ SEQ_LEFTSEL
#define SEQ_EDIT_OVERLAY_ABS
@ 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
#define SEQ_EDIT_OVERLAY_SHOW
#define SEQ_STRIP_OFSBOTTOM
#define MAXSEQ
@ 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_STRIP_OFSTOP
@ SOUND_TAGS_WAVEFORM_LOADING
@ SEQ_DRAW_OVERLAY_REFERENCE
@ SEQ_DRAW_OVERLAY_RECT
@ SEQ_RENDER_SIZE_SCENE
@ SEQ_RENDER_SIZE_NONE
@ SEQ_VIEW_SEQUENCE
@ SEQ_DRAW_TRANSFORM_PREVIEW
@ SEQ_DRAW_BACKDROP
@ SEQ_DRAW_OFFSET_EXT
@ SEQ_DRAW_IMG_VECTORSCOPE
@ SEQ_DRAW_IMG_HISTOGRAM
@ SEQ_DRAW_IMG_IMBUF
@ SEQ_DRAW_IMG_WAVEFORM
@ SEQ_DRAWFRAMES
@ SEQ_SHOW_MARKERS
@ SEQ_SHOW_GPENCIL
@ SEQ_USE_ALPHA
@ SEQ_SHOW_STRIP_DURATION
@ SEQ_SHOW_FCURVES
@ SEQ_USE_PROXIES
@ SEQ_SHOW_STRIP_NAME
@ SEQ_DRAW_COLOR_SEPARATED
@ SEQ_SHOW_METADATA
@ SEQ_ALL_WAVEFORMS
@ SEQ_NO_WAVEFORMS
@ SEQ_SHOW_STRIP_SOURCE
@ SEQ_SHOW_SAFE_MARGINS
@ SEQ_SHOW_SAFE_CENTER
@ SEQ_SHOW_STRIP_OVERLAY
@ IMAGE_DRAW_METHOD_GLSL
@ DRAWCFRA_UNIT_SECONDS
Definition: ED_anim_api.h:658
@ DRAW_MARKERS_MARGIN
Definition: ED_markers.h:42
void ED_mask_draw_region(struct Depsgraph *depsgraph, struct Mask *mask, struct ARegion *region, const char draw_flag, const char draw_type, const eMaskOverlayMode overlay_mode, const int width_i, const int height_i, const float aspx, const float aspy, const bool do_scale_applied, const bool do_draw_cb, float stabmat[4][4], const struct bContext *C)
bool ED_space_sequencer_check_show_imbuf(struct SpaceSeq *sseq)
#define REGION_DRAW_POST_VIEW
Definition: ED_space_api.h:66
void ED_region_draw_cb_draw(const struct bContext *, struct ARegion *, int)
#define REGION_DRAW_PRE_VIEW
Definition: ED_space_api.h:68
void ED_region_image_metadata_draw(int x, int y, struct ImBuf *ibuf, const rctf *frame, float zoomx, float zoomy)
Definition: ed_draw.c:313
static AppView * view
GPUBatch
Definition: GPU_batch.h:93
void GPU_batch_discard(GPUBatch *)
Definition: gpu_batch.cc:127
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
Definition: gpu_batch.cc:299
GPUBatch * GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, eGPUBatchFlag owns_flag)
Definition: gpu_batch.cc:60
void GPU_batch_draw(GPUBatch *batch)
Definition: gpu_batch.cc:234
#define GPU_batch_uniform_4f(batch, name, x, y, z, w)
Definition: GPU_batch.h:138
@ GPU_BATCH_OWNS_VBO
Definition: GPU_batch.h:45
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 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 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
_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 height
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:142
void GPU_matrix_identity_projection_set(void)
Definition: gpu_matrix.cc:170
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:156
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:135
void GPU_matrix_identity_set(void)
Definition: gpu_matrix.cc:184
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:149
GPUPrimType
Definition: GPU_primitive.h:34
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:41
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:36
@ GPU_PRIM_LINE_STRIP
Definition: GPU_primitive.h:38
@ GPU_PRIM_TRI_STRIP
Definition: GPU_primitive.h:40
@ GPU_PRIM_TRIS
Definition: GPU_primitive.h:37
@ GPU_SHADER_2D_DIAG_STRIPES
Definition: GPU_shader.h:192
@ GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR
Definition: GPU_shader.h:365
@ GPU_SHADER_2D_CHECKER
Definition: GPU_shader.h:191
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:171
@ GPU_SHADER_2D_IMAGE_COLOR
Definition: GPU_shader.h:187
@ GPU_SHADER_2D_FLAT_COLOR
Definition: GPU_shader.h:178
@ GPU_BLEND_NONE
Definition: GPU_state.h:55
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:57
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:55
void GPU_line_width(float width)
Definition: gpu_state.cc:173
@ GPU_DEPTH_NONE
Definition: GPU_state.h:78
void GPU_depth_test(eGPUDepthTest test)
Definition: gpu_state.cc:75
void GPU_viewport_size_get_f(float coords[4])
Definition: gpu_state.cc:279
struct GPUTexture GPUTexture
Definition: GPU_texture.h:33
eGPUDataFormat
Definition: GPU_texture.h:171
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:175
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:172
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:391
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:508
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:468
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:421
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:250
eGPUTextureFormat
Definition: GPU_texture.h:84
@ GPU_RGBA16F
Definition: GPU_texture.h:94
@ GPU_RGB16F
Definition: GPU_texture.h:128
@ GPU_RGBA8
Definition: GPU_texture.h:88
void GPU_texture_bind(GPUTexture *tex, int unit)
Definition: gpu_texture.cc:415
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:495
struct GPUFrameBuffer * GPU_viewport_framebuffer_overlay_get(GPUViewport *viewport)
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:720
void IMB_freeImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:211
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
StructRNA RNA_Sequence
#define C
Definition: RandGen.cpp:39
#define UI_DPI_FAC
Definition: UI_interface.h:309
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:1191
@ TH_ROW_ALTERNATE
Definition: UI_resources.h:278
@ TH_GRID
Definition: UI_resources.h:84
@ TH_SEQ_SELECTED
Definition: UI_resources.h:215
@ TH_BACK
Definition: UI_resources.h:55
@ TH_SEQ_TEXT
Definition: UI_resources.h:211
@ TH_SEQ_MASK
Definition: UI_resources.h:205
@ TH_SEQ_MOVIE
Definition: UI_resources.h:203
@ TH_SEQ_COLOR
Definition: UI_resources.h:213
@ TH_SEQ_META
Definition: UI_resources.h:210
@ TH_CFRAME
Definition: UI_resources.h:113
@ TH_SCROLL_TEXT
Definition: UI_resources.h:295
@ TH_SEQ_PREVIEW
Definition: UI_resources.h:212
@ TH_VIEW_OVERLAY
Definition: UI_resources.h:343
@ TH_SEQ_AUDIO
Definition: UI_resources.h:208
@ TH_SEQ_ACTIVE
Definition: UI_resources.h:214
@ TH_SEQ_EFFECT
Definition: UI_resources.h:209
@ TH_SEQ_SCENE
Definition: UI_resources.h:207
@ TH_SEQ_MOVIECLIP
Definition: UI_resources.h:204
@ TH_SEQ_IMAGE
Definition: UI_resources.h:206
void UI_ThemeClearColor(int colorid)
Definition: resources.c:1478
void UI_GetThemeColor3ubv(int colorid, unsigned char col[3])
Definition: resources.c:1350
void UI_GetThemeColorShade3ubv(int colorid, int offset, unsigned char col[3])
Definition: resources.c:1235
void UI_GetColorPtrBlendShade3ubv(const unsigned char cp1[3], const unsigned char cp2[3], unsigned char col[3], float fac, int offset)
Definition: resources.c:1459
void UI_GetColorPtrShade3ubv(const unsigned char cp1[3], unsigned char col[3], int offset)
Definition: resources.c:1441
void UI_view2d_constant_grid_draw(const struct View2D *v2d, float step)
#define V2D_SCROLL_HANDLE_HEIGHT
Definition: UI_view2d.h:70
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.c:2087
void UI_view2d_totRect_set(struct View2D *v2d, int width, int height)
Definition: view2d.c:1052
void UI_view2d_draw_scale_y__block(const struct ARegion *region, const struct View2D *v2d, const struct rcti *rect, int colorid)
void UI_view2d_view_restore(const struct bContext *C)
#define V2D_SCROLL_HANDLE_WIDTH
Definition: UI_view2d.h:71
#define UI_TIME_SCRUB_MARGIN_Y
Definition: UI_view2d.h:283
void UI_view2d_view_ortho(const struct View2D *v2d)
void UI_view2d_text_cache_draw(struct ARegion *region)
Definition: view2d.c:2148
void UI_view2d_scrollers_draw(struct View2D *v2d, const struct rcti *mask_custom)
void UI_view2d_view_orthoSpecial(struct ARegion *region, struct View2D *v2d, const bool xaxis)
Definition: view2d.c:1159
float UI_view2d_region_to_view_y(const struct View2D *v2d, float y)
Definition: view2d.c:1664
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.c:851
@ WM_JOB_TYPE_COMPOSITE
Definition: WM_api.h:735
@ WM_JOB_TYPE_RENDER_PREVIEW
Definition: WM_api.h:737
#define ND_SEQUENCER
Definition: WM_types.h:337
#define NC_SCENE
Definition: WM_types.h:279
void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
Definition: anim_draw.c:95
void ED_markers_draw(const bContext *C, int flag)
Definition: anim_markers.c:567
void ED_annotation_draw_2dimage(const bContext *C)
void ED_annotation_draw_view2d(const bContext *C, bool onlyv2d)
float evaltime
Definition: bpy_driver.c:181
unsigned int U
Definition: btGjkEpa3.h:78
#define SELECT
Scene scene
const Depsgraph * depsgraph
GPUBatch * batch
Definition: drawnode.c:3779
int SEQ_effect_get_num_inputs(int seq_type)
Definition: effects.c:4328
uint pos
uint col
void GPU_clear_color(float red, float green, float blue, float alpha)
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:1476
BLI_INLINE float fb(float length, float L)
#define fabsf(x)
format
Definition: logImageCore.h:47
static char ** names
Definition: makesdna.c:162
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
bool SEQ_prefetch_need_redraw(Main *bmain, Scene *scene)
Definition: prefetch.c:561
double SEQ_rendersize_to_scale_factor(int render_size)
Definition: proxy.c:99
ImBuf * SEQ_render_give_ibuf(const SeqRenderData *context, float timeline_frame, int chanshown)
Definition: render.c:1964
ImBuf * SEQ_render_give_ibuf_direct(const SeqRenderData *context, float timeline_frame, Sequence *seq)
Definition: render.c:2027
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:211
struct SELECTID_Context context
Definition: select_engine.c:47
ListBase * SEQ_active_seqbase_get(const Editing *ed)
Definition: sequencer.c:350
Editing * SEQ_editing_get(Scene *scene, bool alloc)
Definition: sequencer.c:232
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_seq_text_overlay(View2D *v2d, Sequence *seq, SpaceSeq *sseq, float x1, float x2, float y1, float y2, bool seq_active)
#define SEQ_HANDLE_SIZE
#define SEQ_LEFTHANDLE
Sequence * ED_sequencer_special_preview_get(void)
static void draw_seq_outline(Sequence *seq, uint pos, float x1, float x2, float y1, float y2, float pixelx, float pixely, bool seq_active)
static void calculate_seq_text_offsets(View2D *v2d, Sequence *seq, float *x1, float *x2, float pixelx)
struct WaveVizData WaveVizData
static void draw_waveform(WaveVizData *iter, WaveVizData *end, GPUPrimType prim_type, bool use_rms)
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)
void color3ubv_from_seq(Scene *curscene, Sequence *seq, uchar col[3])
static float clamp_frame_coord_to_pixel(float frame_coord, float pixel_frac, float frames_per_pixel)
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)
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 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 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_seq_background(Scene *scene, Sequence *seq, uint pos, float x1, float x2, float y1, float y2, bool is_single_image)
static void draw_color_strip_band(Sequence *seq, uint pos, float text_margin_y, float y1)
static void draw_effect_inputs_highlight(Sequence *seq)
static void draw_seq_handle(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_locked(float x1, float y1, float x2, float y2)
static void drawmeta_contents(Scene *scene, Sequence *seqm, float x1, float y1, float x2, float y2)
static void sequencer_draw_gpencil_overlay(const bContext *C)
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 draw_sequence_extensions_overlay(Scene *scene, Sequence *seq, uint pos, float pixely)
float sequence_handle_size_get_clamped(Sequence *seq, const float pixelx)
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 void seq_draw_sfra_efra(Scene *scene, View2D *v2d)
static int get_section_len(WaveVizData *start, WaveVizData *end)
static void draw_seq_text_get_source(Sequence *seq, char *r_source, size_t source_len)
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 void draw_seq_strip(const bContext *C, SpaceSeq *sseq, Scene *scene, ARegion *region, Sequence *seq, float pixelx, bool seq_active)
static void draw_seq_invalid(float x1, float x2, float y2, float text_margin_y)
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
static void draw_seq_backdrop(View2D *v2d)
static void draw_seq_waveform_overlay(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *scene, Sequence *seq, float x1, float y1, float x2, float y2, float frames_per_pixel)
static size_t draw_seq_text_get_overlay_string(SpaceSeq *sseq, Sequence *seq, char *r_overlay_string, size_t overlay_string_len)
struct CacheDrawData CacheDrawData
#define SEQ_RIGHTHANDLE
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])
signed char int8_t
Definition: stdint.h:78
Sequence * SEQ_select_active_get(Scene *scene)
Definition: strip_select.c:35
void SEQ_timeline_boundbox(const Scene *scene, const ListBase *seqbase, rctf *rect)
Definition: strip_time.c:385
bool SEQ_transform_single_image_check(Sequence *seq)
int SEQ_transform_get_right_handle_frame(Sequence *seq, bool metaclip)
int SEQ_transform_get_left_handle_frame(Sequence *seq, bool metaclip)
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
char name[66]
Definition: DNA_ID.h:283
int channels
struct ColorSpace * rect_colorspace
float dither
unsigned int * rect
float * rect_float
struct ColorSpace * float_colorspace
void * last
Definition: DNA_listBase.h:47
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
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:42
short chanshown
struct SequencerScopes scopes
struct bGPdata * gpd
char multiview_eye
short render_size
char name[256]
StripElem * stripdata
char dir[768]
char text[512]
float pos[2]
char filepath[1024]
void * spinlock
void * waveform
short tags
double offset_time
float xmax
Definition: DNA_vec_types.h:85
float xmin
Definition: DNA_vec_types.h:85
float ymax
Definition: DNA_vec_types.h:86
float ymin
Definition: DNA_vec_types.h:86
void ED_time_scrub_draw_current_frame(const ARegion *region, const Scene *scene, bool display_seconds, bool draw_line)
void ED_time_scrub_draw(const ARegion *region, const Scene *scene, bool display_seconds, bool discrete_frames)
ccl_device_inline float2 floor(const float2 &a)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
#define G(x, y, z)
const char * SEQ_sequence_give_name(Sequence *seq)
Definition: utils.c:227
Mask * SEQ_active_mask_get(Scene *scene)
Definition: utils.c:505
ListBase * SEQ_get_seqbase_from_sequence(Sequence *seq, int *r_offset)
Definition: utils.c:241
bool SEQ_sequence_has_source(Sequence *seq)
Definition: utils.c:526
uint len
GPUViewport * WM_draw_region_get_viewport(ARegion *region)
Definition: wm_draw.c:634
GPUViewport * WM_draw_region_get_bound_viewport(ARegion *region)
Definition: wm_draw.c:644
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
void WM_jobs_kill_type(struct wmWindowManager *wm, void *owner, int job_type)
Definition: wm_jobs.c:572