Blender  V3.3
sequencer_thumbnails.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2021 Blender Foundation. All rights reserved. */
3 
8 #include "BLI_blenlib.h"
9 #include "BLI_ghash.h"
10 #include "BLI_math.h"
11 
12 #include "BKE_context.h"
13 #include "BKE_global.h"
14 #include "BKE_scene.h"
15 
16 #include "IMB_imbuf.h"
17 #include "IMB_imbuf_types.h"
18 
19 #include "ED_screen.h"
20 
21 #include "BIF_glutil.h"
22 
23 #include "SEQ_relations.h"
24 #include "SEQ_render.h"
25 #include "SEQ_sequencer.h"
26 #include "SEQ_time.h"
27 
28 #include "WM_api.h"
29 #include "WM_types.h"
30 
31 #include "MEM_guardedalloc.h"
32 
33 /* Own include. */
34 #include "sequencer_intern.h"
35 
36 typedef struct ThumbnailDrawJob {
41  float pixelx;
42  float pixely;
43  float thumb_height;
45 
46 typedef struct ThumbDataItem {
50 
51 static void thumbnail_hash_data_free(void *val)
52 {
53  ThumbDataItem *item = val;
54  SEQ_sequence_free(item->scene, item->seq_dupli);
55  MEM_freeN(val);
56 }
57 
58 static void thumbnail_freejob(void *data)
59 {
60  ThumbnailDrawJob *tj = data;
62  MEM_freeN(tj->view_area);
63  MEM_freeN(tj);
64 }
65 
66 static void thumbnail_endjob(void *data)
67 {
68  ThumbnailDrawJob *tj = data;
70 }
71 
72 static bool check_seq_need_thumbnails(const Scene *scene, Sequence *seq, rctf *view_area)
73 {
74  if (!ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_IMAGE)) {
75  return false;
76  }
77  if (min_ii(SEQ_time_left_handle_frame_get(scene, seq), seq->start) > view_area->xmax) {
78  return false;
79  }
80  if (max_ii(SEQ_time_right_handle_frame_get(scene, seq), seq->start + seq->len) <
81  view_area->xmin) {
82  return false;
83  }
84  if (seq->machine + 1.0f < view_area->ymin) {
85  return false;
86  }
87  if (seq->machine > view_area->ymax) {
88  return false;
89  }
90 
91  /* Handle is moved, but not for this strip. */
92  if ((G.moving & G_TRANSFORM_SEQ) != 0 && (seq->flag & (SEQ_LEFTSEL | SEQ_RIGHTSEL)) == 0) {
93  return false;
94  }
95 
96  return true;
97 }
98 
100  float pixelx,
101  float pixely,
102  float *r_thumb_width,
103  float thumb_height,
104  float *r_image_width,
105  float *r_image_height)
106 {
107  float image_width = seq->strip->stripdata->orig_width;
108  float image_height = seq->strip->stripdata->orig_height;
109 
110  /* Fix the dimensions to be max SEQ_RENDER_THUMB_SIZE (256) for x or y. */
111  float aspect_ratio = (float)image_width / image_height;
112  if (image_width > image_height) {
113  image_width = SEQ_RENDER_THUMB_SIZE;
114  image_height = round_fl_to_int(image_width / aspect_ratio);
115  }
116  else {
117  image_height = SEQ_RENDER_THUMB_SIZE;
118  image_width = round_fl_to_int(image_height * aspect_ratio);
119  }
120 
121  /* Calculate thumb dimensions. */
122  aspect_ratio = ((float)image_width) / image_height;
123  float thumb_h_px = thumb_height / pixely;
124  float thumb_width = aspect_ratio * thumb_h_px * pixelx;
125 
126  *r_thumb_width = thumb_width;
127  if (r_image_width && r_image_height) {
128  *r_image_width = image_width;
129  *r_image_height = image_height;
130  }
131 }
132 
133 static void thumbnail_start_job(void *data,
134  short *stop,
135  short *UNUSED(do_update),
136  float *UNUSED(progress))
137 {
138  ThumbnailDrawJob *tj = data;
139  const Scene *scene = tj->scene;
140  float frame_step;
141 
142  GHashIterator gh_iter;
143 
144  /* First pass: render visible images. */
146  while (!BLI_ghashIterator_done(&gh_iter) & !*stop) {
147  Sequence *seq_orig = BLI_ghashIterator_getKey(&gh_iter);
148  ThumbDataItem *val = BLI_ghash_lookup(tj->sequences_ghash, seq_orig);
149 
150  if (check_seq_need_thumbnails(scene, seq_orig, tj->view_area)) {
152  val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL);
154  &tj->context, val->seq_dupli, seq_orig, frame_step, tj->view_area, stop);
156  }
157  BLI_ghashIterator_step(&gh_iter);
158  }
159 
160  /* Second pass: render "guaranteed" set of images. */
162  while (!BLI_ghashIterator_done(&gh_iter) & !*stop) {
163  Sequence *seq_orig = BLI_ghashIterator_getKey(&gh_iter);
164  ThumbDataItem *val = BLI_ghash_lookup(tj->sequences_ghash, seq_orig);
165 
166  if (check_seq_need_thumbnails(scene, seq_orig, tj->view_area)) {
168  val->seq_dupli, tj->pixelx, tj->pixely, &frame_step, tj->thumb_height, NULL, NULL);
169  SEQ_render_thumbnails_base_set(&tj->context, val->seq_dupli, seq_orig, tj->view_area, stop);
171  }
172  BLI_ghashIterator_step(&gh_iter);
173  }
174 }
175 
177 {
178  struct Main *bmain = CTX_data_main(C);
181  SpaceSeq *sseq = CTX_wm_space_seq(C);
182  SeqRenderData context = {0};
183 
184  /* Taking rectx and recty as 0 as dimensions not known here, and context is used to calculate
185  * hash key but not necessary as other variables of SeqRenderData are unique enough. */
186  SEQ_render_new_render_data(bmain, depsgraph, scene, 0, 0, sseq->render_size, false, &context);
188  context.use_proxies = false;
189 
190  return context;
191 }
192 
194 {
196 
197  /* Set the data for thumbnail caching job. */
198  GHash *thumb_data_hash = BLI_ghash_ptr_new("seq_duplicates_and_origs");
199 
200  LISTBASE_FOREACH (Sequence *, seq, ed->seqbasep) {
201  ThumbDataItem *val_need_update = BLI_ghash_lookup(thumb_data_hash, seq);
202  if (val_need_update == NULL && check_seq_need_thumbnails(scene, seq, &v2d->cur)) {
203  ThumbDataItem *val = MEM_callocN(sizeof(ThumbDataItem), "Thumbnail Hash Values");
205  val->scene = scene;
206  BLI_ghash_insert(thumb_data_hash, seq, val);
207  }
208  else {
209  if (val_need_update != NULL) {
210  val_need_update->seq_dupli->start = seq->start;
211  val_need_update->seq_dupli->startdisp = SEQ_time_left_handle_frame_get(scene, seq);
212  }
213  }
214  }
215 
216  return thumb_data_hash;
217 }
218 
220  View2D *v2d,
221  Editing *ed,
222  float thumb_height)
223 {
224  wmJob *wm_job;
225  ThumbnailDrawJob *tj = NULL;
227  wm_job = WM_jobs_get(CTX_wm_manager(C),
228  CTX_wm_window(C),
229  CTX_data_scene(C),
230  "Draw Thumbnails",
231  0,
233 
234  /* Get the thumbnail job if it exists. */
235  tj = WM_jobs_customdata_get(wm_job);
236  if (!tj) {
237  tj = MEM_callocN(sizeof(ThumbnailDrawJob), "Thumbnail cache job");
238 
239  /* Duplicate value of v2d->cur and v2d->tot to have module separation. */
240  rctf *view_area = MEM_callocN(sizeof(struct rctf), "viewport area");
241  view_area->xmax = v2d->cur.xmax;
242  view_area->xmin = v2d->cur.xmin;
243  view_area->ymax = v2d->cur.ymax;
244  view_area->ymin = v2d->cur.ymin;
245 
246  tj->scene = CTX_data_scene(C);
247  tj->view_area = view_area;
250  tj->pixelx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
251  tj->pixely = BLI_rctf_size_y(&v2d->cur) / BLI_rcti_size_y(&v2d->mask);
252  tj->thumb_height = thumb_height;
256  }
257 
258  if (!WM_jobs_is_running(wm_job)) {
259  G.is_break = false;
260  WM_jobs_start(CTX_wm_manager(C), wm_job);
261  }
262  else {
264  }
265 
267 }
268 
270 {
271  ARegion *region = CTX_wm_region(C);
272  View2D *v2d = &region->v2d;
273  return (v2d->flag & V2D_IS_NAVIGATING) != 0;
274 }
275 
277  const bContext *C, Editing *ed, View2D *v2d, bool thumbnail_is_missing, float thumb_height)
278 {
279  SpaceSeq *sseq = CTX_wm_space_seq(C);
280 
283  return;
284  }
285 
286  /* During rendering, cache is wiped, it doesn't make sense to render thumbnails. */
287  if (G.is_rendering) {
288  return;
289  }
290 
291  /* Job start requested, but over area which has been processed. Unless `thumbnail_is_missing` is
292  * true, ignore this request as all images are in view. */
293  if (v2d->cur.xmax == sseq->runtime.last_thumbnail_area.xmax &&
294  v2d->cur.ymax == sseq->runtime.last_thumbnail_area.ymax && !thumbnail_is_missing) {
295  return;
296  }
297 
298  /* Stop the job first as view has changed. Pointless to continue old job. */
299  if (v2d->cur.xmax != sseq->runtime.last_thumbnail_area.xmax ||
300  v2d->cur.ymax != sseq->runtime.last_thumbnail_area.ymax) {
302  }
303 
304  sequencer_thumbnail_init_job(C, v2d, ed, thumb_height);
305  sseq->runtime.last_thumbnail_area = v2d->cur;
306 }
307 
309 {
310  BLI_gset_free(val, NULL);
311 }
312 
314 {
315  SpaceSeq *sseq = CTX_wm_space_seq(C);
316  if (sseq->runtime.last_displayed_thumbnails == NULL) {
318  }
319 
320  GSet *displayed_thumbnails = BLI_ghash_lookup(sseq->runtime.last_displayed_thumbnails, seq);
321  if (displayed_thumbnails == NULL) {
322  displayed_thumbnails = BLI_gset_int_new(__func__);
323  BLI_ghash_insert(sseq->runtime.last_displayed_thumbnails, seq, displayed_thumbnails);
324  }
325 
326  return displayed_thumbnails;
327 }
328 
329 static void last_displayed_thumbnails_list_cleanup(GSet *previously_displayed,
330  float range_start,
331  float range_end)
332 {
333  GSetIterator gset_iter;
334  BLI_gsetIterator_init(&gset_iter, previously_displayed);
335  while (!BLI_gsetIterator_done(&gset_iter)) {
336  int frame = (float)POINTER_AS_INT(BLI_gsetIterator_getKey(&gset_iter));
337  BLI_gsetIterator_step(&gset_iter);
338 
339  if (frame > range_start && frame < range_end) {
340  BLI_gset_remove(previously_displayed, POINTER_FROM_INT(frame), NULL);
341  }
342  }
343 }
344 
346  GSet *previously_displayed)
347 {
348  int best_diff = INT_MAX;
349  int best_frame = timeline_frame;
350 
351  /* Previously displayed thumbnails. */
352  GSetIterator gset_iter;
353  BLI_gsetIterator_init(&gset_iter, previously_displayed);
354  while (!BLI_gsetIterator_done(&gset_iter)) {
355  int frame = POINTER_AS_INT(BLI_gsetIterator_getKey(&gset_iter));
356  int diff = abs(frame - timeline_frame);
357  if (diff < best_diff) {
358  best_diff = diff;
359  best_frame = frame;
360  }
361  BLI_gsetIterator_step(&gset_iter);
362  }
363  return best_frame;
364 }
365 
367  Sequence *seq,
368  int timeline_frame)
369 {
370  if (timeline_frame <= SEQ_time_left_handle_frame_get(scene, seq)) {
372  }
373 
374  /* Set of "guaranteed" thumbnails. */
375  const int frame_index = timeline_frame - SEQ_time_left_handle_frame_get(scene, seq);
376  const int frame_step = SEQ_render_thumbnails_guaranteed_set_frame_step_get(scene, seq);
377  const int relative_base_frame = round_fl_to_int((frame_index / (float)frame_step)) * frame_step;
378  const int nearest_guaranted_absolute_frame = relative_base_frame +
380  return nearest_guaranted_absolute_frame;
381 }
382 
384  Sequence *seq,
385  int timeline_frame,
386  GSet *previously_displayed,
387  rcti *crop,
388  bool clipped)
389 {
390  int frame_previous = sequencer_thumbnail_closest_previous_frame_get(timeline_frame,
391  previously_displayed);
392  ImBuf *ibuf_previous = SEQ_get_thumbnail(context, seq, frame_previous, crop, clipped);
393 
395  context->scene, seq, timeline_frame);
396  ImBuf *ibuf_guaranteed = SEQ_get_thumbnail(context, seq, frame_guaranteed, crop, clipped);
397 
398  ImBuf *closest_in_memory = NULL;
399 
400  if (ibuf_previous && ibuf_guaranteed) {
401  if (abs(frame_previous - timeline_frame) < abs(frame_guaranteed - timeline_frame)) {
402  IMB_freeImBuf(ibuf_guaranteed);
403  closest_in_memory = ibuf_previous;
404  }
405  else {
406  IMB_freeImBuf(ibuf_previous);
407  closest_in_memory = ibuf_guaranteed;
408  }
409  }
410 
411  if (ibuf_previous == NULL) {
412  closest_in_memory = ibuf_guaranteed;
413  }
414 
415  if (ibuf_guaranteed == NULL) {
416  closest_in_memory = ibuf_previous;
417  }
418 
419  return closest_in_memory;
420 }
421 
423  const bContext *C,
424  Scene *scene,
425  Sequence *seq,
426  float y1,
427  float y2,
428  float pixelx,
429  float pixely)
430 {
431  bool clipped = false;
432  float image_height, image_width, thumb_width;
433  rcti crop;
434 
435  StripElem *se = seq->strip->stripdata;
436  if (se->orig_height == 0 || se->orig_width == 0) {
437  return;
438  }
439 
440  /* If width of the strip too small ignore drawing thumbnails. */
441  if ((y2 - y1) / pixely <= 20 * U.dpi_fac) {
442  return;
443  }
444 
446 
447  if ((seq->flag & SEQ_FLAG_SKIP_THUMBNAILS) != 0) {
448  return;
449  }
450 
451  const float thumb_height = y2 - y1;
453  seq, pixelx, pixely, &thumb_width, thumb_height, &image_width, &image_height);
454 
455  float thumb_y_end = y1 + thumb_height;
456 
457  float cut_off = 0;
458  float upper_thumb_bound = SEQ_time_has_right_still_frames(scene, seq) ?
459  (seq->start + seq->len) :
461  if (seq->type == SEQ_TYPE_IMAGE) {
462  upper_thumb_bound = SEQ_time_right_handle_frame_get(scene, seq);
463  }
464 
465  float timeline_frame = SEQ_render_thumbnail_first_frame_get(scene, seq, thumb_width, &v2d->cur);
466  float thumb_x_end;
467 
468  GSet *last_displayed_thumbnails = last_displayed_thumbnails_list_ensure(C, seq);
469  /* Cleanup thumbnail list outside of rendered range, which is cleaned up one by one to prevent
470  * flickering after zooming. */
472  last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, -FLT_MAX, timeline_frame);
473  }
474 
475  /* Start drawing. */
476  while (timeline_frame < upper_thumb_bound) {
477  thumb_x_end = timeline_frame + thumb_width;
478  clipped = false;
479 
480  /* Checks to make sure that thumbs are loaded only when in view and within the confines of the
481  * strip. Some may not be required but better to have conditions for safety as x1 here is
482  * point to start caching from and not drawing. */
483  if (timeline_frame > v2d->cur.xmax) {
484  break;
485  }
486 
487  /* Set the clipping bound to show the left handle moving over thumbs and not shift thumbs. */
488  if (IN_RANGE_INCL(SEQ_time_left_handle_frame_get(scene, seq), timeline_frame, thumb_x_end)) {
489  cut_off = SEQ_time_left_handle_frame_get(scene, seq) - timeline_frame;
490  clipped = true;
491  }
492 
493  /* Clip if full thumbnail cannot be displayed. */
494  if (thumb_x_end > (upper_thumb_bound)) {
495  thumb_x_end = upper_thumb_bound;
496  clipped = true;
497  if (thumb_x_end - timeline_frame < 1) {
498  break;
499  }
500  }
501 
502  float zoom_x = thumb_width / image_width;
503  float zoom_y = thumb_height / image_height;
504 
505  float cropx_min = (cut_off / pixelx) / (zoom_y / pixely);
506  float cropx_max = ((thumb_x_end - timeline_frame) / pixelx) / (zoom_y / pixely);
507  if (cropx_max == (thumb_x_end - timeline_frame)) {
508  cropx_max = cropx_max + 1;
509  }
510  BLI_rcti_init(&crop, (int)(cropx_min), (int)cropx_max, 0, (int)(image_height)-1);
511 
512  /* Get the image. */
513  ImBuf *ibuf = SEQ_get_thumbnail(&context, seq, timeline_frame, &crop, clipped);
514 
515  if (!ibuf) {
516  sequencer_thumbnail_start_job_if_necessary(C, scene->ed, v2d, true, thumb_height);
517 
519  &context, seq, timeline_frame, last_displayed_thumbnails, &crop, clipped);
520  }
521  /* Store recently rendered frames, so they can be reused when zooming. */
523  /* Clear images in frame range occupied by new thumbnail. */
525  last_displayed_thumbnails, timeline_frame, thumb_x_end);
526  /* Insert new thumbnail frame to list. */
527  BLI_gset_add(last_displayed_thumbnails, POINTER_FROM_INT(timeline_frame));
528  }
529 
530  /* If there is no image still, abort. */
531  if (!ibuf) {
532  break;
533  }
534 
535  /* Transparency on overlap. */
536  if (seq->flag & SEQ_OVERLAP) {
538  if (ibuf->rect) {
539  unsigned char *buf = (unsigned char *)ibuf->rect;
540  for (int pixel = ibuf->x * ibuf->y; pixel--; buf += 4) {
541  buf[3] = OVERLAP_ALPHA;
542  }
543  }
544  else if (ibuf->rect_float) {
545  float *buf = (float *)ibuf->rect_float;
546  for (int pixel = ibuf->x * ibuf->y; pixel--; buf += ibuf->channels) {
547  buf[3] = (OVERLAP_ALPHA / 255.0f);
548  }
549  }
550  }
551 
553  ibuf,
554  timeline_frame + cut_off,
555  y1,
556  true,
557  timeline_frame + cut_off,
558  y1,
559  thumb_x_end,
560  thumb_y_end,
561  zoom_x,
562  zoom_y);
563  IMB_freeImBuf(ibuf);
565  cut_off = 0;
566  timeline_frame = SEQ_render_thumbnail_next_frame_get(scene, seq, timeline_frame, thumb_width);
567  }
568  last_displayed_thumbnails_list_cleanup(last_displayed_thumbnails, timeline_frame, FLT_MAX);
569 }
typedef float(TangentPoint)[2]
void ED_draw_imbuf_ctx_clipping(const struct bContext *C, struct ImBuf *ibuf, float x, float y, bool use_filter, float clip_min_x, float clip_min_y, float clip_max_x, float clip_max_y, float zoom_x, float zoom_y)
struct ScrArea * CTX_wm_area(const bContext *C)
Definition: context.c:738
struct Scene * CTX_data_scene(const bContext *C)
Definition: context.c:1090
struct wmWindowManager * CTX_wm_manager(const bContext *C)
Definition: context.c:713
struct SpaceSeq * CTX_wm_space_seq(const bContext *C)
Definition: context.c:851
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:749
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Definition: context.c:1505
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
@ G_TRANSFORM_SEQ
Definition: BKE_global.h:249
int BKE_scene_multiview_view_id_get(const struct RenderData *rd, const char *viewname)
struct GSet GSet
Definition: BLI_ghash.h:340
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:298
GSet * BLI_gset_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghashIterator_step(GHashIterator *ghi)
Definition: BLI_ghash.c:914
BLI_INLINE bool BLI_gsetIterator_done(const GSetIterator *gsi)
Definition: BLI_ghash.h:466
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
BLI_INLINE void BLI_gsetIterator_init(GSetIterator *gsi, GSet *gs)
Definition: BLI_ghash.h:450
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
Definition: BLI_ghash.c:898
BLI_INLINE void BLI_gsetIterator_step(GSetIterator *gsi)
Definition: BLI_ghash.h:462
BLI_INLINE void * BLI_gsetIterator_getKey(GSetIterator *gsi)
Definition: BLI_ghash.h:458
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:969
BLI_INLINE bool BLI_ghashIterator_done(const GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:310
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1002
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition: BLI_rect.h:190
void BLI_rcti_init(struct rcti *rect, int xmin, int xmax, int ymin, int ymax)
Definition: rct.c:417
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition: BLI_rect.h:186
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition: BLI_rect.h:194
BLI_INLINE float BLI_rctf_size_y(const struct rctf *rct)
Definition: BLI_rect.h:198
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define ELEM(...)
#define IN_RANGE_INCL(a, b, c)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
#define STEREO_LEFT_NAME
@ SEQ_TYPE_IMAGE
@ SEQ_TYPE_MOVIE
@ SEQ_RIGHTSEL
@ SEQ_FLAG_SKIP_THUMBNAILS
@ SEQ_OVERLAP
@ SEQ_LEFTSEL
@ V2D_IS_NAVIGATING
void ED_area_tag_redraw(ScrArea *area)
Definition: area.c:729
_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
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:25
#define SEQ_RENDER_THUMB_SIZE
Definition: SEQ_render.h:14
@ WM_JOB_TYPE_SEQ_DRAW_THUMBNAIL
Definition: WM_api.h:1374
#define ND_SEQUENCER
Definition: WM_types.h:385
#define NC_SCENE
Definition: WM_types.h:328
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
const Depsgraph * depsgraph
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
#define G(x, y, z)
IMETHOD Vector diff(const Vector &a, const Vector &b, double dt=1)
static void area(int d1, int d2, int e1, int e2, float weights[2])
T abs(const T &a)
int SEQ_render_thumbnails_guaranteed_set_frame_step_get(const Scene *scene, const Sequence *seq)
Definition: render.c:2142
ImBuf * SEQ_get_thumbnail(const SeqRenderData *context, Sequence *seq, float timeline_frame, rcti *crop, bool clipped)
Definition: render.c:2072
void SEQ_render_new_render_data(Main *bmain, struct Depsgraph *depsgraph, Scene *scene, int rectx, int recty, int preview_render_size, int for_render, SeqRenderData *r_context)
Definition: render.c:205
void SEQ_render_thumbnails_base_set(const SeqRenderData *context, Sequence *seq, Sequence *seq_orig, rctf *view_area, const short *stop)
Definition: render.c:2157
float SEQ_render_thumbnail_first_frame_get(const Scene *scene, Sequence *seq, float frame_step, rctf *view_area)
Definition: render.c:2005
void SEQ_render_thumbnails(const SeqRenderData *context, Sequence *seq, Sequence *seq_orig, float frame_step, rctf *view_area, const short *stop)
Definition: render.c:2096
float SEQ_render_thumbnail_next_frame_get(const Scene *scene, Sequence *seq, float last_frame, float frame_step)
Definition: render.c:2023
void SEQ_sequence_free(Scene *scene, Sequence *seq)
Definition: sequencer.c:224
Sequence * SEQ_sequence_dupli_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *new_seq_list, Sequence *seq, int dupe_flag)
Definition: sequencer.c:602
#define OVERLAP_ALPHA
static void sequencer_thumbnail_start_job_if_necessary(const bContext *C, Editing *ed, View2D *v2d, bool thumbnail_is_missing, float thumb_height)
void draw_seq_strip_thumbnail(View2D *v2d, const bContext *C, Scene *scene, Sequence *seq, float y1, float y2, float pixelx, float pixely)
void last_displayed_thumbnails_list_free(void *val)
struct ThumbDataItem ThumbDataItem
static ImBuf * sequencer_thumbnail_closest_from_memory(const SeqRenderData *context, Sequence *seq, int timeline_frame, GSet *previously_displayed, rcti *crop, bool clipped)
static SeqRenderData sequencer_thumbnail_context_init(const bContext *C)
static int sequencer_thumbnail_closest_guaranteed_frame_get(struct Scene *scene, Sequence *seq, int timeline_frame)
static void thumbnail_hash_data_free(void *val)
static GHash * sequencer_thumbnail_ghash_init(const bContext *C, View2D *v2d, Editing *ed)
static void last_displayed_thumbnails_list_cleanup(GSet *previously_displayed, float range_start, float range_end)
static bool check_seq_need_thumbnails(const Scene *scene, Sequence *seq, rctf *view_area)
static void sequencer_thumbnail_init_job(const bContext *C, View2D *v2d, Editing *ed, float thumb_height)
static bool sequencer_thumbnail_v2d_is_navigating(const bContext *C)
struct ThumbnailDrawJob ThumbnailDrawJob
static void thumbnail_freejob(void *data)
static int sequencer_thumbnail_closest_previous_frame_get(int timeline_frame, GSet *previously_displayed)
static void thumbnail_endjob(void *data)
static void seq_get_thumb_image_dimensions(Sequence *seq, float pixelx, float pixely, float *r_thumb_width, float thumb_height, float *r_image_width, float *r_image_height)
static GSet * last_displayed_thumbnails_list_ensure(const bContext *C, Sequence *seq)
static void thumbnail_start_job(void *data, short *stop, short *UNUSED(do_update), float *UNUSED(progress))
void SEQ_relations_sequence_free_anim(Sequence *seq)
bool SEQ_time_has_right_still_frames(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:471
int SEQ_time_left_handle_frame_get(const Scene *UNUSED(scene), const Sequence *seq)
Definition: strip_time.c:506
int SEQ_time_right_handle_frame_get(const Scene *scene, const Sequence *seq)
Definition: strip_time.c:515
ListBase * seqbasep
int channels
unsigned int * rect
float * rect_float
Definition: BKE_main.h:121
struct Editing * ed
struct RenderData r
struct GHash * last_displayed_thumbnails
struct rctf last_thumbnail_area
SpaceSeqRuntime runtime
short render_size
StripElem * stripdata
short flag
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
Definition: wm_jobs.c:57
void WM_main_add_notifier(unsigned int type, void *reference)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
bool WM_jobs_is_running(const wmJob *wm_job)
Definition: wm_jobs.c:304
void WM_jobs_start(wmWindowManager *wm, wmJob *wm_job)
Definition: wm_jobs.c:437
void WM_jobs_callbacks(wmJob *wm_job, wm_jobs_start_callback startjob, void(*initjob)(void *), void(*update)(void *), void(*endjob)(void *))
Definition: wm_jobs.c:351
void * WM_jobs_customdata_get(wmJob *wm_job)
Definition: wm_jobs.c:315
void WM_jobs_stop(wmWindowManager *wm, const void *owner, void *startjob)
Definition: wm_jobs.c:583
void WM_jobs_customdata_set(wmJob *wm_job, void *customdata, void(*free)(void *))
Definition: wm_jobs.c:323
void WM_jobs_timer(wmJob *wm_job, double timestep, unsigned int note, unsigned int endnote)
Definition: wm_jobs.c:339
wmJob * WM_jobs_get(wmWindowManager *wm, wmWindow *win, const void *owner, const char *name, int flag, int job_type)
Definition: wm_jobs.c:184