[Bf-blender-cvs] [82f65d8971e] master: Cleanup: VSE waveform drawing

Richard Antalik noreply at git.blender.org
Fri Jul 15 15:52:15 CEST 2022


Commit: 82f65d8971ea2def50ab6cd6031793207cc45168
Author: Richard Antalik
Date:   Fri Jul 15 15:46:50 2022 +0200
Branches: master
https://developer.blender.org/rB82f65d8971ea2def50ab6cd6031793207cc45168

Cleanup: VSE waveform drawing

No functional changes.

===================================================================

M	source/blender/editors/space_sequencer/sequencer_draw.c

===================================================================

diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index aa5681306a4..b1e13850bf2 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -241,329 +241,296 @@ typedef struct WaveVizData {
   float pos[2];
   float rms_pos;
   bool clip;
-  bool end;
+  bool draw_line;    /* Draw triangle otherwise. */
+  bool final_sample; /* There are no more samples. */
 } WaveVizData;
 
-static int get_section_len(WaveVizData *start, WaveVizData *end)
+static bool seq_draw_waveforms_poll(const bContext *C, SpaceSeq *sseq, Sequence *seq)
 {
-  int len = 0;
-  while (start != end) {
-    len++;
-    if (start->end) {
-      return len;
-    }
-    start++;
-  }
-  return len;
-}
+  const bool strip_is_valid = seq->type == SEQ_TYPE_SOUND_RAM && seq->sound != NULL;
+  const bool overlays_enabled = (sseq->flag & SEQ_SHOW_OVERLAY) != 0;
+  const bool ovelay_option = ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) != 0 ||
+                              (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM));
 
-static void draw_waveform(WaveVizData *iter, WaveVizData *end, GPUPrimType prim_type, bool use_rms)
-{
-  int strip_len = get_section_len(iter, end);
-  if (strip_len > 1) {
-    GPU_blend(GPU_BLEND_ALPHA);
-    GPUVertFormat *format = immVertexFormat();
-    uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-    uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+  if ((sseq->timeline_overlay.flag & SEQ_TIMELINE_NO_WAVEFORMS) != 0) {
+    return false;
+  }
 
-    immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-    immBegin(prim_type, strip_len);
+  if (strip_is_valid && overlays_enabled && ovelay_option) {
+    return true;
+  }
 
-    while (iter != end) {
-      if (iter->clip) {
-        immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f);
-      }
-      else if (use_rms) {
-        immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.8f);
-      }
-      else {
-        immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.5f);
-      }
+  return false;
+}
 
-      if (use_rms) {
-        immVertex2f(pos, iter->pos[0], iter->rms_pos);
-      }
-      else {
-        immVertex2f(pos, iter->pos[0], iter->pos[1]);
-      }
+static void waveform_job_start_if_needed(const bContext *C, Sequence *seq)
+{
+  bSound *sound = seq->sound;
 
-      if (iter->end) {
-        /* End of line. */
-        iter++;
-        strip_len = get_section_len(iter, end);
-        if (strip_len != 0) {
-          immEnd();
-          immUnbindProgram();
-          immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-          immBegin(prim_type, strip_len);
-        }
-      }
-      else {
-        iter++;
-      }
+  BLI_spin_lock(sound->spinlock);
+  if (!sound->waveform) {
+    /* Load the waveform data if it hasn't been loaded and cached already. */
+    if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
+      /* Prevent sounds from reloading. */
+      sound->tags |= SOUND_TAGS_WAVEFORM_LOADING;
+      BLI_spin_unlock(sound->spinlock);
+      sequencer_preview_add_sound(C, seq);
+    }
+    else {
+      BLI_spin_unlock(sound->spinlock);
     }
-    immEnd();
-    immUnbindProgram();
-
-    GPU_blend(GPU_BLEND_NONE);
   }
+  BLI_spin_unlock(sound->spinlock);
 }
 
-static float clamp_frame_coord_to_pixel(float frame_coord,
-                                        float pixel_frac,
-                                        float frames_per_pixel)
+static size_t get_vertex_count(WaveVizData *waveform_data)
 {
-  float cur_pixel = (frame_coord / frames_per_pixel);
-  float new_pixel = (int)(frame_coord / frames_per_pixel) + pixel_frac;
-  if (cur_pixel > new_pixel) {
-    new_pixel += 1.0f;
+  bool draw_line = waveform_data->draw_line;
+  size_t length = 0;
+
+  while (waveform_data->draw_line == draw_line && !waveform_data->final_sample) {
+    waveform_data++;
+    length++;
   }
-  return new_pixel * frames_per_pixel;
+
+  return length;
 }
 
-/**
- * \param x1, x2, y1, y2: The starting and end X value to draw the wave, same for y1 and y2.
- * \param frames_per_pixel: The amount of pixels a whole frame takes up (x-axis direction).
- */
-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_waveform_segment(WaveVizData *waveform_data, bool use_rms)
 {
-  if (seq->sound && ((sseq->timeline_overlay.flag & SEQ_TIMELINE_ALL_WAVEFORMS) ||
-                     (seq->flag & SEQ_AUDIO_DRAW_WAVEFORM))) {
-    /* Make sure that the start drawing position is aligned to the pixels on the screen to avoid
-     * flickering when moving around the strip.
-     * To do this we figure out the fractional offset in pixel space by checking where the
-     * window starts.
-     * We then append this pixel offset to our strip start coordinate to ensure we are aligned to
-     * the screen pixel grid. */
-    float pixel_frac = v2d->cur.xmin / frames_per_pixel - floor(v2d->cur.xmin / frames_per_pixel);
-    float x1_adj = clamp_frame_coord_to_pixel(x1, pixel_frac, frames_per_pixel);
-
-    /* Offset x1 and x2 values, to match view min/max, if strip is out of bounds. */
-    float x1_offset = max_ff(v2d->cur.xmin, x1_adj);
-    float x2_offset = min_ff(v2d->cur.xmax, x2);
-
-    /* Calculate how long the strip that is in view is in pixels. */
-    int pix_strip_len = round((x2_offset - x1_offset) / frames_per_pixel);
-
-    if (pix_strip_len < 2) {
-      return;
-    }
+  size_t vertices_done = 0;
+  size_t vertex_count = get_vertex_count(waveform_data);
 
-    bSound *sound = seq->sound;
+  /* Not enough data to draw. */
+  if (vertex_count <= 2) {
+    return vertex_count;
+  }
 
-    BLI_spin_lock(sound->spinlock);
-    if (!sound->waveform) {
-      /* Load the waveform data if it hasn't been loaded and cached already. */
-      if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
-        /* Prevent sounds from reloading. */
-        sound->tags |= SOUND_TAGS_WAVEFORM_LOADING;
-        BLI_spin_unlock(sound->spinlock);
-        sequencer_preview_add_sound(C, seq);
-      }
-      else {
-        BLI_spin_unlock(sound->spinlock);
-      }
-      return; /* Nothing to draw. */
-    }
-    BLI_spin_unlock(sound->spinlock);
+  GPU_blend(GPU_BLEND_ALPHA);
+  GPUVertFormat *format = immVertexFormat();
+  GPUPrimType prim_type = waveform_data->draw_line ? GPU_PRIM_LINE_STRIP : GPU_PRIM_TRI_STRIP;
+  uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+  uint col = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+  immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+  immBegin(prim_type, vertex_count);
 
-    SoundWaveform *waveform = sound->waveform;
+  while (vertices_done < vertex_count && !waveform_data->final_sample) {
+    /* Color. */
+    if (waveform_data->clip) {
+      immAttr4f(col, 1.0f, 0.0f, 0.0f, 0.5f);
+    }
+    else if (use_rms) {
+      immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.8f);
+    }
+    else {
+      immAttr4f(col, 1.0f, 1.0f, 1.0f, 0.5f);
+    }
 
-    /* Waveform could not be built. */
-    if (waveform->length == 0) {
-      return;
+    /* Vertices. */
+    if (use_rms) {
+      immVertex2f(pos, waveform_data->pos[0], waveform_data->rms_pos);
+    }
+    else {
+      immVertex2f(pos, waveform_data->pos[0], waveform_data->pos[1]);
     }
 
-    /* F-Curve lookup is quite expensive, so do this after precondition. */
-    FCurve *fcu = id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "volume", 0, NULL);
+    vertices_done++;
+    waveform_data++;
+  }
 
-    WaveVizData *tri_strip_arr = MEM_callocN(sizeof(*tri_strip_arr) * pix_strip_len * 2,
-                                             "tri_strip");
-    WaveVizData *line_strip_arr = MEM_callocN(sizeof(*line_strip_arr) * pix_strip_len,
-                                              "line_strip");
+  immEnd();
+  immUnbindProgram();
 
-    WaveVizData *tri_strip_iter = tri_strip_arr;
-    WaveVizData *line_strip_iter = line_strip_arr;
+  GPU_blend(GPU_BLEND_NONE);
 
-    /* The y coordinate for the middle of the strip. */
-    float y_mid = (y1 + y2) / 2.0f;
-    /* The length from the middle of the strip to the top/bottom. */
-    float y_scale = (y2 - y1) / 2.0f;
-    float volume = seq->volume;
+  return vertices_done;
+}
 
-    /* Value to keep track if the previous item to be drawn was a line strip. */
-    int8_t was_line_strip = -1; /* -1 == no previous value. */
+static void draw_waveform(WaveVizData *waveform_data, size_t wave_data_len)
+{
+  size_t items_done = 0;
+  while (items_done < wave_data_len) {
+    if (!waveform_data[items_done].draw_line) { /* Draw RMS. */
+      draw_waveform_segment(&waveform_data[items_done], true);
+    }
+    items_done += draw_waveform_segment(&waveform_data[items_done], false);
+  }
+}
 
-    float samples_per_frame = SOUND_WAVE_SAMPLES_PER_SECOND / FPS;
+static float align_frame_with_pixel(const View2D *v2d, float frame_coord, float frames_per_pixel)
+{
+  return round_fl_to_int(frame_coord / frames_per_pixel) * frames_per_pixel;
+}
 
-    /* How many samples do we have for each pixel? */
-    float samples_per_pix = samples_per_frame * frames_per_pixel;
+static void write_waveform_data(WaveVizData *waveform_data,
+                                const vec2f pos,
+                                const float rms,
+                                const bool is_clipping,
+                                const bool draw_line)
+{
+  waveform_data->pos[0] = pos.x;
+  waveform_data->pos[1] = pos.y;
+  waveform_data->clip = is_clipping;
+  waveform_data->rms_pos = rms;
+  waveform_data->draw_line = draw_line;
+}
 
-    float strip_start_offset = seq->startofs + seq->anim_st

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list