Blender  V3.3
wm_playanim.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2001-2002 NaN Holding BV. All rights reserved. */
3 
14 #include <fcntl.h>
15 #include <math.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/types.h>
19 
20 #ifndef WIN32
21 # include <sys/times.h>
22 # include <sys/wait.h>
23 # include <unistd.h>
24 #else
25 # include <io.h>
26 #endif
27 #include "MEM_guardedalloc.h"
28 
29 #include "PIL_time.h"
30 
31 #include "BLI_fileops.h"
32 #include "BLI_listbase.h"
33 #include "BLI_path_util.h"
34 #include "BLI_rect.h"
35 #include "BLI_string.h"
36 #include "BLI_system.h"
37 #include "BLI_utildefines.h"
38 
39 #include "IMB_colormanagement.h"
40 #include "IMB_imbuf.h"
41 #include "IMB_imbuf_types.h"
42 
43 #include "BKE_image.h"
44 
45 #include "BIF_glutil.h"
46 
47 #include "GPU_context.h"
48 #include "GPU_framebuffer.h"
49 #include "GPU_immediate.h"
50 #include "GPU_immediate_util.h"
51 #include "GPU_init_exit.h"
52 #include "GPU_matrix.h"
53 #include "GPU_state.h"
54 
55 #include "BLF_api.h"
56 #include "DNA_scene_types.h"
57 #include "ED_datafiles.h" /* for fonts */
58 #include "GHOST_C-api.h"
59 
60 #include "DEG_depsgraph.h"
61 
62 #include "WM_api.h" /* only for WM_main_playanim */
63 
64 #ifdef WITH_AUDASPACE
65 # include <AUD_Device.h>
66 # include <AUD_Handle.h>
67 # include <AUD_Sound.h>
68 # include <AUD_Special.h>
69 
70 static AUD_Sound *source = NULL;
71 static AUD_Handle *playback_handle = NULL;
72 static AUD_Handle *scrub_handle = NULL;
73 static AUD_Device *audio_device = NULL;
74 #endif
75 
76 /* simple limiter to avoid flooding memory */
77 #define USE_FRAME_CACHE_LIMIT
78 #ifdef USE_FRAME_CACHE_LIMIT
79 # define PLAY_FRAME_CACHE_MAX 30
80 #endif
81 
82 struct PlayState;
83 static void playanim_window_zoom(struct PlayState *ps, const float zoom_offset);
84 
92 typedef struct PlayState {
93 
95  int win_x, win_y;
96 
98  float zoom;
99 
101  short direction;
103  short next_frame;
104 
106  bool once;
108  bool pingpong;
110  bool noskip;
112  bool indicator;
114  bool sstep;
116  bool wait2;
118  bool stopped;
125  bool go;
127  bool loading;
129  bool draw_flip[2];
130 
132  int fstep;
133 
136 
138  int ibufx, ibufy;
140  int fontid;
141 
144 
149 
153 
154 /* for debugging */
155 #if 0
156 static void print_ps(PlayState *ps)
157 {
158  printf("ps:\n");
159  printf(" direction=%d,\n", (int)ps->direction);
160  printf(" once=%d,\n", ps->once);
161  printf(" pingpong=%d,\n", ps->pingpong);
162  printf(" noskip=%d,\n", ps->noskip);
163  printf(" sstep=%d,\n", ps->sstep);
164  printf(" wait2=%d,\n", ps->wait2);
165  printf(" stopped=%d,\n", ps->stopped);
166  printf(" go=%d,\n\n", ps->go);
167  fflush(stdout);
168 }
169 #endif
170 
171 /* global for window and events */
172 typedef enum eWS_Qual {
173  WS_QUAL_LSHIFT = (1 << 0),
174  WS_QUAL_RSHIFT = (1 << 1),
176  WS_QUAL_LALT = (1 << 2),
177  WS_QUAL_RALT = (1 << 3),
179  WS_QUAL_LCTRL = (1 << 4),
180  WS_QUAL_RCTRL = (1 << 5),
182  WS_QUAL_LMOUSE = (1 << 16),
183  WS_QUAL_MMOUSE = (1 << 17),
184  WS_QUAL_RMOUSE = (1 << 18),
187 
188 static struct WindowStateGlobal {
189  GHOST_SystemHandle ghost_system;
192 
193  /* events */
195 } g_WS = {NULL};
196 
197 static void playanim_window_get_size(int *r_width, int *r_height)
198 {
199  GHOST_RectangleHandle bounds = GHOST_GetClientBounds(g_WS.ghost_window);
200  *r_width = GHOST_GetWidthRectangle(bounds);
201  *r_height = GHOST_GetHeightRectangle(bounds);
203 }
204 
205 static void playanim_gl_matrix(void)
206 {
207  /* unified matrix, note it affects offset for drawing */
208  /* NOTE: cannot use GPU_matrix_ortho_2d_set here because shader ignores. */
209  GPU_matrix_ortho_set(0.0f, 1.0f, 0.0f, 1.0f, -1.0, 1.0f);
210 }
211 
212 /* implementation */
213 static void playanim_event_qual_update(void)
214 {
215  bool val;
216 
217  /* Shift */
220 
223 
224  /* Control */
227 
230 
231  /* Alt */
234 
237 }
238 
239 typedef struct PlayAnimPict {
240  struct PlayAnimPict *next, *prev;
242  int size;
243  const char *name;
244  struct ImBuf *ibuf;
245  struct anim *anim;
246  int frame;
247  int IB_flags;
248 
249 #ifdef USE_FRAME_CACHE_LIMIT
253 #endif
255 
256 static struct ListBase picsbase = {NULL, NULL};
257 /* frames in memory - store them here to for easy deallocation later */
258 static bool fromdisk = false;
259 static double ptottime = 0.0, swaptime = 0.04;
260 #ifdef WITH_AUDASPACE
261 static double fps_movie;
262 #endif
263 
264 #ifdef USE_FRAME_CACHE_LIMIT
265 static struct {
267  struct ListBase pics;
269  int pics_len;
273  size_t memory_limit;
274 } g_frame_cache = {
275  .pics = {NULL, NULL},
276  .pics_len = 0,
277  .pics_size_in_memory = 0,
278  .memory_limit = 0,
279 };
280 
281 static void frame_cache_add(PlayAnimPict *pic)
282 {
285  g_frame_cache.pics_len++;
286 
287  if (g_frame_cache.memory_limit != 0) {
288  BLI_assert(pic->size_in_memory == 0);
290  g_frame_cache.pics_size_in_memory += pic->size_in_memory;
291  }
292 }
293 
295 {
297  IMB_freeImBuf(pic->ibuf);
298  if (g_frame_cache.memory_limit != 0) {
299  BLI_assert(pic->size_in_memory != 0);
300  g_frame_cache.pics_size_in_memory -= pic->size_in_memory;
301  pic->size_in_memory = 0;
302  }
303  pic->ibuf = NULL;
304  pic->frame_cache_node = NULL;
306  g_frame_cache.pics_len--;
307 }
308 
309 /* Don't free the current frame by moving it to the head of the list. */
311 {
312  BLI_assert(pic->frame_cache_node->data == pic);
315 }
316 
317 static bool frame_cache_limit_exceeded(void)
318 {
319  return g_frame_cache.memory_limit ?
320  (g_frame_cache.pics_size_in_memory > g_frame_cache.memory_limit) :
321  (g_frame_cache.pics_len > PLAY_FRAME_CACHE_MAX);
322 }
323 
324 static void frame_cache_limit_apply(ImBuf *ibuf_keep)
325 {
326  /* Really basic memory conservation scheme. Keep frames in a FIFO queue. */
327  LinkData *node = g_frame_cache.pics.last;
328  while (node && frame_cache_limit_exceeded()) {
329  PlayAnimPict *pic = node->data;
331 
332  node = node->prev;
333  if (pic->ibuf && pic->ibuf != ibuf_keep) {
334  frame_cache_remove(pic);
335  }
336  }
337 }
338 
339 #endif /* USE_FRAME_CACHE_LIMIT */
340 
342 {
343  ImBuf *ibuf = NULL;
344 
345  if (pic->ibuf) {
346  ibuf = pic->ibuf;
347  }
348  else if (pic->anim) {
350  }
351  else if (pic->mem) {
352  /* use correct colorspace here */
353  ibuf = IMB_ibImageFromMemory(pic->mem, pic->size, pic->IB_flags, NULL, pic->name);
354  }
355  else {
356  /* use correct colorspace here */
357  ibuf = IMB_loadiffname(pic->name, pic->IB_flags, NULL);
358  }
359 
360  return ibuf;
361 }
362 
363 static PlayAnimPict *playanim_step(PlayAnimPict *playanim, int step)
364 {
365  if (step > 0) {
366  while (step-- && playanim) {
367  playanim = playanim->next;
368  }
369  }
370  else if (step < 0) {
371  while (step++ && playanim) {
372  playanim = playanim->prev;
373  }
374  }
375  return playanim;
376 }
377 
378 static int pupdate_time(void)
379 {
380  static double ltime;
381 
382  double time = PIL_check_seconds_timer();
383 
384  ptottime += (time - ltime);
385  ltime = time;
386  return (ptottime < 0);
387 }
388 
390  ImBuf *ibuf,
391  bool *r_glsl_used,
392  eGPUTextureFormat *r_format,
393  eGPUDataFormat *r_data,
394  void **r_buffer_cache_handle)
395 {
396  void *display_buffer;
397  bool force_fallback = false;
398  *r_glsl_used = false;
399  force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
400  force_fallback |= (ibuf->dither != 0.0f);
401 
402  /* Default */
403  *r_format = GPU_RGBA8;
404  *r_data = GPU_DATA_UBYTE;
405 
406  /* Fallback to CPU based color space conversion. */
407  if (force_fallback) {
408  *r_glsl_used = false;
409  display_buffer = NULL;
410  }
411  else if (ibuf->rect_float) {
412  display_buffer = ibuf->rect_float;
413 
414  *r_data = GPU_DATA_FLOAT;
415  if (ibuf->channels == 4) {
416  *r_format = GPU_RGBA16F;
417  }
418  else if (ibuf->channels == 3) {
419  /* Alpha is implicitly 1. */
420  *r_format = GPU_RGB16F;
421  }
422 
423  if (ibuf->float_colorspace) {
425  &ps->display_settings,
426  ibuf->float_colorspace,
427  ibuf->dither,
428  false,
429  false);
430  }
431  else {
433  &ps->view_settings, &ps->display_settings, ibuf->dither, false);
434  }
435  }
436  else if (ibuf->rect) {
437  display_buffer = ibuf->rect;
439  &ps->display_settings,
440  ibuf->rect_colorspace,
441  ibuf->dither,
442  false,
443  false);
444  }
445  else {
446  display_buffer = NULL;
447  }
448 
449  /* There is data to be displayed, but GLSL is not initialized
450  * properly, in this case we fallback to CPU-based display transform. */
451  if ((ibuf->rect || ibuf->rect_float) && !*r_glsl_used) {
452  display_buffer = IMB_display_buffer_acquire(
453  ibuf, &ps->view_settings, &ps->display_settings, r_buffer_cache_handle);
454  *r_format = GPU_RGBA8;
455  *r_data = GPU_DATA_UBYTE;
456  }
457 
458  return display_buffer;
459 }
460 
461 static void draw_display_buffer(PlayState *ps, ImBuf *ibuf)
462 {
463  void *display_buffer;
464 
465  /* Format needs to be created prior to any #immBindShader call.
466  * Do it here because OCIO binds its own shader. */
469  bool glsl_used = false;
470  GPUVertFormat *imm_format = immVertexFormat();
471  uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
472  uint texCoord = GPU_vertformat_attr_add(
473  imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
474 
475  void *buffer_cache_handle = NULL;
476  display_buffer = ocio_transform_ibuf(ps, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
477 
478  GPUTexture *texture = GPU_texture_create_2d("display_buf", ibuf->x, ibuf->y, 1, format, NULL);
479  GPU_texture_update(texture, data, display_buffer);
480  GPU_texture_filter_mode(texture, false);
481 
482  GPU_texture_bind(texture, 0);
483 
484  if (!glsl_used) {
486  immUniformColor3f(1.0f, 1.0f, 1.0f);
487  }
488 
490 
491  rctf preview;
492  rctf canvas;
493 
494  BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
495  BLI_rctf_init(&preview, 0.0f, 1.0f, 0.0f, 1.0f);
496 
497  if (ps->draw_flip[0]) {
498  SWAP(float, canvas.xmin, canvas.xmax);
499  }
500  if (ps->draw_flip[1]) {
501  SWAP(float, canvas.ymin, canvas.ymax);
502  }
503 
504  immAttr2f(texCoord, canvas.xmin, canvas.ymin);
505  immVertex2f(pos, preview.xmin, preview.ymin);
506 
507  immAttr2f(texCoord, canvas.xmin, canvas.ymax);
508  immVertex2f(pos, preview.xmin, preview.ymax);
509 
510  immAttr2f(texCoord, canvas.xmax, canvas.ymax);
511  immVertex2f(pos, preview.xmax, preview.ymax);
512 
513  immAttr2f(texCoord, canvas.xmax, canvas.ymin);
514  immVertex2f(pos, preview.xmax, preview.ymin);
515 
516  immEnd();
517 
518  GPU_texture_unbind(texture);
519  GPU_texture_free(texture);
520 
521  if (!glsl_used) {
523  }
524  else {
526  }
527 
528  if (buffer_cache_handle) {
529  IMB_display_buffer_release(buffer_cache_handle);
530  }
531 }
532 
533 static void playanim_toscreen(
534  PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
535 {
536  if (ibuf == NULL) {
537  printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>");
538  return;
539  }
540 
542 
543  /* size within window */
544  float span_x = (ps->zoom * ibuf->x) / (float)ps->win_x;
545  float span_y = (ps->zoom * ibuf->y) / (float)ps->win_y;
546 
547  /* offset within window */
548  float offs_x = 0.5f * (1.0f - span_x);
549  float offs_y = 0.5f * (1.0f - span_y);
550 
551  CLAMP(offs_x, 0.0f, 1.0f);
552  CLAMP(offs_y, 0.0f, 1.0f);
553 
554  GPU_clear_color(0.1f, 0.1f, 0.1f, 0.0f);
555 
556  /* checkerboard for case alpha */
557  if (ibuf->planes == 32) {
559 
561  offs_y,
562  offs_x + span_x,
563  offs_y + span_y,
564  (const float[4]){0.15, 0.15, 0.15, 1.0},
565  (const float[4]){0.20, 0.20, 0.20, 1.0},
566  8);
567  }
568 
569  draw_display_buffer(ps, ibuf);
570 
572 
573  pupdate_time();
574 
575  if (picture && (g_WS.qual & (WS_QUAL_SHIFT | WS_QUAL_LMOUSE)) && (fontid != -1)) {
576  int sizex, sizey;
577  float fsizex_inv, fsizey_inv;
578  char str[32 + FILE_MAX];
579  BLI_snprintf(str, sizeof(str), "%s | %.2f frames/s", picture->name, fstep / swaptime);
580 
581  playanim_window_get_size(&sizex, &sizey);
582  fsizex_inv = 1.0f / sizex;
583  fsizey_inv = 1.0f / sizey;
584 
585  BLF_color4f(fontid, 1.0, 1.0, 1.0, 1.0);
586  BLF_enable(fontid, BLF_ASPECT);
587  BLF_aspect(fontid, fsizex_inv, fsizey_inv, 1.0f);
588  BLF_position(fontid, 10.0f * fsizex_inv, 10.0f * fsizey_inv, 0.0f);
589  BLF_draw(fontid, str, sizeof(str));
590  }
591 
592  if (ps->indicator) {
593  float fac = ps->picture->frame / (double)(((PlayAnimPict *)picsbase.last)->frame -
594  ((PlayAnimPict *)picsbase.first)->frame);
595 
596  fac = 2.0f * fac - 1.0f;
599  GPU_matrix_push();
601 
603 
605  immUniformColor3ub(0, 255, 0);
606 
608  immVertex2f(pos, fac, -1.0f);
609  immVertex2f(pos, fac, 1.0f);
610  immEnd();
611 
613 
614  GPU_matrix_pop();
616  }
617 
619 }
620 
621 static void build_pict_list_ex(
622  PlayState *ps, const char *first, int totframes, int fstep, int fontid)
623 {
624  if (IMB_isanim(first)) {
625  /* OCIO_TODO: support different input color space */
626  struct anim *anim = IMB_open_anim(first, IB_rect, 0, NULL);
627  if (anim) {
628  int pic;
630  if (ibuf) {
631  playanim_toscreen(ps, NULL, ibuf, fontid, fstep);
632  IMB_freeImBuf(ibuf);
633  }
634 
635  for (pic = 0; pic < IMB_anim_get_duration(anim, IMB_TC_NONE); pic++) {
636  PlayAnimPict *picture = (PlayAnimPict *)MEM_callocN(sizeof(PlayAnimPict), "Pict");
637  picture->anim = anim;
638  picture->frame = pic;
639  picture->IB_flags = IB_rect;
640  picture->name = BLI_sprintfN("%s : %4.d", first, pic + 1);
641  BLI_addtail(&picsbase, picture);
642  }
643  }
644  else {
645  printf("couldn't open anim %s\n", first);
646  }
647  }
648  else {
649  /* Load images into cache until the cache is full,
650  * this resolves choppiness for images that are slow to load, see: T81751. */
651 #ifdef USE_FRAME_CACHE_LIMIT
652  bool fill_cache = true;
653 #else
654  bool fill_cache = false;
655 #endif
656 
657  int count = 0;
658 
659  int fp_framenr;
660  struct {
661  char head[FILE_MAX], tail[FILE_MAX];
662  unsigned short digits;
663  } fp_decoded;
664 
665  char filepath[FILE_MAX];
666  BLI_strncpy(filepath, first, sizeof(filepath));
667  fp_framenr = BLI_path_sequence_decode(
668  filepath, fp_decoded.head, fp_decoded.tail, &fp_decoded.digits);
669 
670  pupdate_time();
671  ptottime = 1.0;
672 
673  /* O_DIRECT
674  *
675  * If set, all reads and writes on the resulting file descriptor will
676  * be performed directly to or from the user program buffer, provided
677  * appropriate size and alignment restrictions are met. Refer to the
678  * F_SETFL and F_DIOINFO commands in the fcntl(2) manual entry for
679  * information about how to determine the alignment constraints.
680  * O_DIRECT is a Silicon Graphics extension and is only supported on
681  * local EFS and XFS file systems.
682  */
683 
684  while (IMB_ispic(filepath) && totframes) {
685  bool has_event;
686  size_t size;
687  int file;
688 
689  file = BLI_open(filepath, O_BINARY | O_RDONLY, 0);
690  if (file < 0) {
691  /* print errno? */
692  return;
693  }
694 
695  PlayAnimPict *picture = (PlayAnimPict *)MEM_callocN(sizeof(PlayAnimPict), "picture");
696  if (picture == NULL) {
697  printf("Not enough memory for pict struct '%s'\n", filepath);
698  close(file);
699  return;
700  }
702 
703  if (size < 1) {
704  close(file);
705  MEM_freeN(picture);
706  return;
707  }
708 
709  picture->size = size;
710  picture->IB_flags = IB_rect;
711 
712  uchar *mem;
713  if (fromdisk == false) {
714  mem = MEM_mallocN(size, "build pic list");
715  if (mem == NULL) {
716  printf("Couldn't get memory\n");
717  close(file);
718  MEM_freeN(picture);
719  return;
720  }
721 
722  if (read(file, mem, size) != size) {
723  printf("Error while reading %s\n", filepath);
724  close(file);
725  MEM_freeN(picture);
726  MEM_freeN(mem);
727  return;
728  }
729  }
730  else {
731  mem = NULL;
732  }
733 
734  picture->mem = mem;
735  picture->name = BLI_strdup(filepath);
736  picture->frame = count;
737  close(file);
738  BLI_addtail(&picsbase, picture);
739  count++;
740 
741  pupdate_time();
742 
743  const bool display_imbuf = ptottime > 1.0;
744 
745  if (display_imbuf || fill_cache) {
746  /* OCIO_TODO: support different input color space */
747  ImBuf *ibuf = ibuf_from_picture(picture);
748 
749  if (ibuf) {
750  if (display_imbuf) {
751  playanim_toscreen(ps, picture, ibuf, fontid, fstep);
752  }
753 #ifdef USE_FRAME_CACHE_LIMIT
754  if (fill_cache) {
755  picture->ibuf = ibuf;
756  frame_cache_add(picture);
757  fill_cache = !frame_cache_limit_exceeded();
758  }
759  else
760 #endif
761  {
762  IMB_freeImBuf(ibuf);
763  }
764  }
765 
766  if (display_imbuf) {
767  pupdate_time();
768  ptottime = 0.0;
769  }
770  }
771 
772  /* create a new filepath each time */
773  fp_framenr += fstep;
775  filepath, fp_decoded.head, fp_decoded.tail, fp_decoded.digits, fp_framenr);
776 
777  while ((has_event = GHOST_ProcessEvents(g_WS.ghost_system, false))) {
779  if (ps->loading == false) {
780  return;
781  }
782  }
783 
784  totframes--;
785  }
786  }
787 }
788 
789 static void build_pict_list(PlayState *ps, const char *first, int totframes, int fstep, int fontid)
790 {
791  ps->loading = true;
792  build_pict_list_ex(ps, first, totframes, fstep, fontid);
793  ps->loading = false;
794 }
795 
796 static void update_sound_fps(void)
797 {
798 #ifdef WITH_AUDASPACE
799  if (playback_handle) {
800  /* swaptime stores the 1.0/fps ratio */
801  double speed = 1.0 / (swaptime * fps_movie);
802 
803  AUD_Handle_setPitch(playback_handle, speed);
804  }
805 #endif
806 }
807 
808 static void tag_change_frame(PlayState *ps, int cx)
809 {
810  ps->need_frame_update = true;
811  ps->frame_cursor_x = cx;
812 }
813 
814 static void change_frame(PlayState *ps)
815 {
816  if (!ps->need_frame_update) {
817  return;
818  }
819 
820  int sizex, sizey;
821  int i, i_last;
822 
824  return;
825  }
826 
827  playanim_window_get_size(&sizex, &sizey);
828  i_last = ((struct PlayAnimPict *)picsbase.last)->frame;
829  i = (i_last * ps->frame_cursor_x) / sizex;
830  CLAMP(i, 0, i_last);
831 
832 #ifdef WITH_AUDASPACE
833  if (scrub_handle) {
834  AUD_Handle_stop(scrub_handle);
835  scrub_handle = NULL;
836  }
837 
838  if (playback_handle) {
839  AUD_Status status = AUD_Handle_getStatus(playback_handle);
840  if (status != AUD_STATUS_PLAYING) {
841  AUD_Handle_stop(playback_handle);
842  playback_handle = AUD_Device_play(audio_device, source, 1);
843  if (playback_handle) {
844  AUD_Handle_setPosition(playback_handle, i / fps_movie);
845  scrub_handle = AUD_pauseAfter(playback_handle, 1 / fps_movie);
846  }
848  }
849  else {
850  AUD_Handle_setPosition(playback_handle, i / fps_movie);
851  scrub_handle = AUD_pauseAfter(playback_handle, 1 / fps_movie);
852  }
853  }
854  else if (source) {
855  playback_handle = AUD_Device_play(audio_device, source, 1);
856  if (playback_handle) {
857  AUD_Handle_setPosition(playback_handle, i / fps_movie);
858  scrub_handle = AUD_pauseAfter(playback_handle, 1 / fps_movie);
859  }
861  }
862 #endif
863 
864  ps->picture = BLI_findlink(&picsbase, i);
865  BLI_assert(ps->picture != NULL);
866 
867  ps->sstep = true;
868  ps->wait2 = false;
869  ps->next_frame = 0;
870 
871  ps->need_frame_update = false;
872 }
873 
874 static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
875 {
876  PlayState *ps = (PlayState *)ps_void;
878  /* Convert ghost event into value keyboard or mouse. */
880 
881  // print_ps(ps);
882 
884 
885  /* first check if we're busy loading files */
886  if (ps->loading) {
887  switch (type) {
888  case GHOST_kEventKeyDown:
889  case GHOST_kEventKeyUp: {
890  GHOST_TEventKeyData *key_data;
891 
892  key_data = (GHOST_TEventKeyData *)GHOST_GetEventData(evt);
893  switch (key_data->key) {
894  case GHOST_kKeyEsc:
895  ps->loading = false;
896  break;
897  default:
898  break;
899  }
900  break;
901  }
902  default:
903  break;
904  }
905  return true;
906  }
907 
908  if (ps->wait2 && ps->stopped == false) {
909  ps->stopped = true;
910  }
911 
912  if (ps->wait2) {
913  pupdate_time();
914  ptottime = 0;
915  }
916 
917  switch (type) {
918  case GHOST_kEventKeyDown:
919  case GHOST_kEventKeyUp: {
920  GHOST_TEventKeyData *key_data;
921 
922  key_data = (GHOST_TEventKeyData *)GHOST_GetEventData(evt);
923  switch (key_data->key) {
924  case GHOST_kKeyA:
925  if (val) {
926  ps->noskip = !ps->noskip;
927  }
928  break;
929  case GHOST_kKeyI:
930  if (val) {
931  ps->indicator = !ps->indicator;
932  }
933  break;
934  case GHOST_kKeyP:
935  if (val) {
936  ps->pingpong = !ps->pingpong;
937  }
938  break;
939  case GHOST_kKeyF: {
940  if (val) {
941  int axis = (g_WS.qual & WS_QUAL_SHIFT) ? 1 : 0;
942  ps->draw_flip[axis] = !ps->draw_flip[axis];
943  }
944  break;
945  }
946  case GHOST_kKey1:
947  case GHOST_kKeyNumpad1:
948  if (val) {
949  swaptime = ps->fstep / 60.0;
951  }
952  break;
953  case GHOST_kKey2:
954  case GHOST_kKeyNumpad2:
955  if (val) {
956  swaptime = ps->fstep / 50.0;
958  }
959  break;
960  case GHOST_kKey3:
961  case GHOST_kKeyNumpad3:
962  if (val) {
963  swaptime = ps->fstep / 30.0;
965  }
966  break;
967  case GHOST_kKey4:
968  case GHOST_kKeyNumpad4:
969  if (g_WS.qual & WS_QUAL_SHIFT) {
970  swaptime = ps->fstep / 24.0;
972  }
973  else {
974  swaptime = ps->fstep / 25.0;
976  }
977  break;
978  case GHOST_kKey5:
979  case GHOST_kKeyNumpad5:
980  if (val) {
981  swaptime = ps->fstep / 20.0;
983  }
984  break;
985  case GHOST_kKey6:
986  case GHOST_kKeyNumpad6:
987  if (val) {
988  swaptime = ps->fstep / 15.0;
990  }
991  break;
992  case GHOST_kKey7:
993  case GHOST_kKeyNumpad7:
994  if (val) {
995  swaptime = ps->fstep / 12.0;
997  }
998  break;
999  case GHOST_kKey8:
1000  case GHOST_kKeyNumpad8:
1001  if (val) {
1002  swaptime = ps->fstep / 10.0;
1003  update_sound_fps();
1004  }
1005  break;
1006  case GHOST_kKey9:
1007  case GHOST_kKeyNumpad9:
1008  if (val) {
1009  swaptime = ps->fstep / 6.0;
1010  update_sound_fps();
1011  }
1012  break;
1013  case GHOST_kKeyLeftArrow:
1014  if (val) {
1015  ps->sstep = true;
1016  ps->wait2 = false;
1017  if (g_WS.qual & WS_QUAL_SHIFT) {
1018  ps->picture = picsbase.first;
1019  ps->next_frame = 0;
1020  }
1021  else {
1022  ps->next_frame = -1;
1023  }
1024  }
1025  break;
1026  case GHOST_kKeyDownArrow:
1027  if (val) {
1028  ps->wait2 = false;
1029  if (g_WS.qual & WS_QUAL_SHIFT) {
1030  ps->next_frame = ps->direction = -1;
1031  }
1032  else {
1033  ps->next_frame = -10;
1034  ps->sstep = true;
1035  }
1036  }
1037  break;
1038  case GHOST_kKeyRightArrow:
1039  if (val) {
1040  ps->sstep = true;
1041  ps->wait2 = false;
1042  if (g_WS.qual & WS_QUAL_SHIFT) {
1043  ps->picture = picsbase.last;
1044  ps->next_frame = 0;
1045  }
1046  else {
1047  ps->next_frame = 1;
1048  }
1049  }
1050  break;
1051  case GHOST_kKeyUpArrow:
1052  if (val) {
1053  ps->wait2 = false;
1054  if (g_WS.qual & WS_QUAL_SHIFT) {
1055  ps->next_frame = ps->direction = 1;
1056  }
1057  else {
1058  ps->next_frame = 10;
1059  ps->sstep = true;
1060  }
1061  }
1062  break;
1063 
1064  case GHOST_kKeySlash:
1065  case GHOST_kKeyNumpadSlash:
1066  if (val) {
1067  if (g_WS.qual & WS_QUAL_SHIFT) {
1068  if (ps->picture && ps->picture->ibuf) {
1069  printf(" Name: %s | Speed: %.2f frames/s\n",
1070  ps->picture->ibuf->name,
1071  ps->fstep / swaptime);
1072  }
1073  }
1074  else {
1075  swaptime = ps->fstep / 5.0;
1076  update_sound_fps();
1077  }
1078  }
1079  break;
1080  case GHOST_kKey0:
1081  case GHOST_kKeyNumpad0:
1082  if (val) {
1083  if (ps->once) {
1084  ps->once = ps->wait2 = false;
1085  }
1086  else {
1087  ps->picture = NULL;
1088  ps->once = true;
1089  ps->wait2 = false;
1090  }
1091  }
1092  break;
1093 
1094  case GHOST_kKeySpace:
1095  if (val) {
1096  if (ps->wait2 || ps->sstep) {
1097  ps->wait2 = ps->sstep = false;
1098 #ifdef WITH_AUDASPACE
1099  {
1100  PlayAnimPict *picture = picsbase.first;
1101  /* TODO: store in ps direct? */
1102  int i = 0;
1103 
1104  while (picture && picture != ps->picture) {
1105  i++;
1106  picture = picture->next;
1107  }
1108  if (playback_handle) {
1109  AUD_Handle_stop(playback_handle);
1110  }
1111  playback_handle = AUD_Device_play(audio_device, source, 1);
1112  if (playback_handle) {
1113  AUD_Handle_setPosition(playback_handle, i / fps_movie);
1114  }
1115  update_sound_fps();
1116  }
1117 #endif
1118  }
1119  else {
1120  ps->sstep = true;
1121  ps->wait2 = true;
1122 #ifdef WITH_AUDASPACE
1123  if (playback_handle) {
1124  AUD_Handle_stop(playback_handle);
1125  playback_handle = NULL;
1126  }
1127 #endif
1128  }
1129  }
1130  break;
1131  case GHOST_kKeyEnter:
1132  case GHOST_kKeyNumpadEnter:
1133  if (val) {
1134  ps->wait2 = ps->sstep = false;
1135 #ifdef WITH_AUDASPACE
1136  {
1137  PlayAnimPict *picture = picsbase.first;
1138  /* TODO: store in ps direct? */
1139  int i = 0;
1140  while (picture && picture != ps->picture) {
1141  i++;
1142  picture = picture->next;
1143  }
1144  if (playback_handle) {
1145  AUD_Handle_stop(playback_handle);
1146  }
1147  playback_handle = AUD_Device_play(audio_device, source, 1);
1148  if (playback_handle) {
1149  AUD_Handle_setPosition(playback_handle, i / fps_movie);
1150  }
1151  update_sound_fps();
1152  }
1153 #endif
1154  }
1155  break;
1156  case GHOST_kKeyPeriod:
1158  if (val) {
1159  if (ps->sstep) {
1160  ps->wait2 = false;
1161  }
1162  else {
1163  ps->sstep = true;
1164  ps->wait2 = !ps->wait2;
1165 #ifdef WITH_AUDASPACE
1166  if (playback_handle) {
1167  AUD_Handle_stop(playback_handle);
1168  playback_handle = NULL;
1169  }
1170 #endif
1171  }
1172  }
1173  break;
1174  case GHOST_kKeyEqual:
1175  case GHOST_kKeyPlus:
1176  case GHOST_kKeyNumpadPlus: {
1177  if (val == 0) {
1178  break;
1179  }
1180  if (g_WS.qual & WS_QUAL_CTRL) {
1181  playanim_window_zoom(ps, 0.1f);
1182  }
1183  else {
1184  if (swaptime > ps->fstep / 60.0) {
1185  swaptime /= 1.1;
1186  update_sound_fps();
1187  }
1188  }
1189  break;
1190  }
1191  case GHOST_kKeyMinus:
1192  case GHOST_kKeyNumpadMinus: {
1193  if (val == 0) {
1194  break;
1195  }
1196  if (g_WS.qual & WS_QUAL_CTRL) {
1197  playanim_window_zoom(ps, -0.1f);
1198  }
1199  else {
1200  if (swaptime < ps->fstep / 5.0) {
1201  swaptime *= 1.1;
1202  update_sound_fps();
1203  }
1204  }
1205  break;
1206  }
1207  case GHOST_kKeyEsc:
1208  ps->go = false;
1209  break;
1210  default:
1211  break;
1212  }
1213  break;
1214  }
1216  case GHOST_kEventButtonUp: {
1218  int cx, cy, sizex, sizey, inside_window;
1219 
1221  playanim_window_get_size(&sizex, &sizey);
1222 
1223  inside_window = (cx >= 0 && cx < sizex && cy >= 0 && cy <= sizey);
1224 
1225  if (bd->button == GHOST_kButtonMaskLeft) {
1226  if (type == GHOST_kEventButtonDown) {
1227  if (inside_window) {
1229  tag_change_frame(ps, cx);
1230  }
1231  }
1232  else {
1233  g_WS.qual &= ~WS_QUAL_LMOUSE;
1234  }
1235  }
1236  else if (bd->button == GHOST_kButtonMaskMiddle) {
1237  if (type == GHOST_kEventButtonDown) {
1238  if (inside_window) {
1240  }
1241  }
1242  else {
1243  g_WS.qual &= ~WS_QUAL_MMOUSE;
1244  }
1245  }
1246  else if (bd->button == GHOST_kButtonMaskRight) {
1247  if (type == GHOST_kEventButtonDown) {
1248  if (inside_window) {
1250  }
1251  }
1252  else {
1253  g_WS.qual &= ~WS_QUAL_RMOUSE;
1254  }
1255  }
1256  break;
1257  }
1258  case GHOST_kEventCursorMove: {
1259  if (g_WS.qual & WS_QUAL_LMOUSE) {
1261  int cx, cy;
1262 
1263  /* Ignore 'in-between' events, since they can make scrubbing lag.
1264  *
1265  * Ideally we would keep into the event queue and see if this is the last motion event.
1266  * however the API currently doesn't support this. */
1267  {
1268  int x_test, y_test;
1270  GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &x_test, &y_test);
1271 
1272  if (cx != x_test || cy != y_test) {
1273  /* we're not the last event... skipping */
1274  break;
1275  }
1276  }
1277 
1278  tag_change_frame(ps, cx);
1279  }
1280  break;
1281  }
1284  g_WS.qual &= ~WS_QUAL_MOUSE;
1285  break;
1286  }
1288  case GHOST_kEventWindowMove: {
1289  float zoomx, zoomy;
1290 
1291  playanim_window_get_size(&ps->win_x, &ps->win_y);
1293 
1294  zoomx = (float)ps->win_x / ps->ibufx;
1295  zoomy = (float)ps->win_y / ps->ibufy;
1296 
1297  /* zoom always show entire image */
1298  ps->zoom = MIN2(zoomx, zoomy);
1299 
1300  GPU_viewport(0, 0, ps->win_x, ps->win_y);
1301  GPU_scissor(0, 0, ps->win_x, ps->win_y);
1302 
1304 
1305  ptottime = 0.0;
1307  ps, ps->picture, ps->picture ? ps->picture->ibuf : NULL, ps->fontid, ps->fstep);
1308 
1309  break;
1310  }
1312  case GHOST_kEventWindowClose: {
1313  ps->go = false;
1314  break;
1315  }
1318 
1320  GHOST_TStringArray *stra = ddd->data;
1321  int a;
1322 
1323  for (a = 0; a < stra->count; a++) {
1324  BLI_strncpy(ps->dropped_file, (char *)stra->strings[a], sizeof(ps->dropped_file));
1325  ps->go = false;
1326  printf("drop file %s\n", stra->strings[a]);
1327  break; /* only one drop element supported now */
1328  }
1329  }
1330  break;
1331  }
1332  default:
1333  /* quiet warnings */
1334  break;
1335  }
1336 
1337  return true;
1338 }
1339 
1340 static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
1341 {
1342  GHOST_GLSettings glsettings = {0};
1343  uint32_t scr_w, scr_h;
1344 
1346 
1347  posy = (scr_h - posy - sizey);
1348 
1350  NULL,
1351  title,
1352  posx,
1353  posy,
1354  sizex,
1355  sizey,
1356  /* could optionally start fullscreen */
1358  false,
1360  glsettings);
1361 }
1362 
1363 static void playanim_window_zoom(PlayState *ps, const float zoom_offset)
1364 {
1365  int sizex, sizey;
1366  /* int ofsx, ofsy; */ /* UNUSED */
1367 
1368  if (ps->zoom + zoom_offset > 0.0f) {
1369  ps->zoom += zoom_offset;
1370  }
1371 
1372  // playanim_window_get_position(&ofsx, &ofsy);
1373  playanim_window_get_size(&sizex, &sizey);
1374  /* ofsx += sizex / 2; */ /* UNUSED */
1375  /* ofsy += sizey / 2; */ /* UNUSED */
1376  sizex = ps->zoom * ps->ibufx;
1377  sizey = ps->zoom * ps->ibufy;
1378  /* ofsx -= sizex / 2; */ /* UNUSED */
1379  /* ofsy -= sizey / 2; */ /* UNUSED */
1380  // window_set_position(g_WS.ghost_window, sizex, sizey);
1381  GHOST_SetClientSize(g_WS.ghost_window, sizex, sizey);
1382 }
1383 
1387 static char *wm_main_playanim_intern(int argc, const char **argv)
1388 {
1389  struct ImBuf *ibuf = NULL;
1390  static char filepath[FILE_MAX]; /* abused to return dropped file path */
1391  uint32_t maxwinx, maxwiny;
1392  int i;
1393  /* This was done to disambiguate the name for use under c++. */
1394  int start_x = 0, start_y = 0;
1395  int sfra = -1;
1396  int efra = -1;
1397  int totblock;
1398 
1399  PlayState ps = {0};
1400 
1401  ps.go = true;
1402  ps.direction = true;
1403  ps.next_frame = 1;
1404  ps.once = false;
1405  ps.pingpong = false;
1406  ps.noskip = false;
1407  ps.sstep = false;
1408  ps.wait2 = false;
1409  ps.stopped = false;
1410  ps.loading = false;
1411  ps.picture = NULL;
1412  ps.indicator = false;
1413  ps.dropped_file[0] = 0;
1414  ps.zoom = 1.0f;
1415  ps.draw_flip[0] = false;
1416  ps.draw_flip[1] = false;
1417 
1418  ps.fstep = 1;
1419 
1420  ps.fontid = -1;
1421 
1425 
1426  /* Skip the first argument which is assumed to be '-a' (used to launch this player). */
1427  while (argc > 1) {
1428  if (argv[1][0] == '-') {
1429  switch (argv[1][1]) {
1430  case 'm':
1431  fromdisk = true;
1432  break;
1433  case 'p':
1434  if (argc > 3) {
1435  start_x = atoi(argv[2]);
1436  start_y = atoi(argv[3]);
1437  argc -= 2;
1438  argv += 2;
1439  }
1440  else {
1441  printf("too few arguments for -p (need 2): skipping\n");
1442  }
1443  break;
1444  case 'f':
1445  if (argc > 3) {
1446  double fps = atof(argv[2]);
1447  double fps_base = atof(argv[3]);
1448  if (fps == 0.0) {
1449  fps = 1;
1450  printf(
1451  "invalid fps,"
1452  "forcing 1\n");
1453  }
1454  swaptime = fps_base / fps;
1455  argc -= 2;
1456  argv += 2;
1457  }
1458  else {
1459  printf("too few arguments for -f (need 2): skipping\n");
1460  }
1461  break;
1462  case 's':
1463  sfra = atoi(argv[2]);
1464  CLAMP(sfra, 1, MAXFRAME);
1465  argc--;
1466  argv++;
1467  break;
1468  case 'e':
1469  efra = atoi(argv[2]);
1470  CLAMP(efra, 1, MAXFRAME);
1471  argc--;
1472  argv++;
1473  break;
1474  case 'j':
1475  ps.fstep = atoi(argv[2]);
1476  CLAMP(ps.fstep, 1, MAXFRAME);
1477  swaptime *= ps.fstep;
1478  argc--;
1479  argv++;
1480  break;
1481  case 'c': {
1482 #ifdef USE_FRAME_CACHE_LIMIT
1483  const int memory_in_mb = max_ii(0, atoi(argv[2]));
1484  g_frame_cache.memory_limit = (size_t)memory_in_mb * (1024 * 1024);
1485 #endif
1486  argc--;
1487  argv++;
1488  break;
1489  }
1490  default:
1491  printf("unknown option '%c': skipping\n", argv[1][1]);
1492  break;
1493  }
1494  argc--;
1495  argv++;
1496  }
1497  else {
1498  break;
1499  }
1500  }
1501 
1502  if (argc > 1) {
1503  BLI_strncpy(filepath, argv[1], sizeof(filepath));
1504  }
1505  else {
1506  printf("%s: no filepath argument given\n", __func__);
1507  exit(1);
1508  }
1509 
1510  if (IMB_isanim(filepath)) {
1511  /* OCIO_TODO: support different input color spaces */
1512  struct anim *anim;
1513  anim = IMB_open_anim(filepath, IB_rect, 0, NULL);
1514  if (anim) {
1517  anim = NULL;
1518  }
1519  }
1520  else if (!IMB_ispic(filepath)) {
1521  printf("%s: '%s' not an image file\n", __func__, filepath);
1522  exit(1);
1523  }
1524 
1525  if (ibuf == NULL) {
1526  /* OCIO_TODO: support different input color space */
1527  ibuf = IMB_loadiffname(filepath, IB_rect, NULL);
1528  }
1529 
1530  if (ibuf == NULL) {
1531  printf("%s: '%s' couldn't open\n", __func__, filepath);
1532  exit(1);
1533  }
1534 
1535  {
1536 
1537  GHOST_EventConsumerHandle consumer = GHOST_CreateEventConsumer(ghost_event_proc, &ps);
1538 
1540 
1543 
1544  playanim_window_open("Blender Animation Player", start_x, start_y, ibuf->x, ibuf->y);
1545  }
1546 
1547  GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &maxwinx, &maxwiny);
1548 
1549  // GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
1550 
1551  /* initialize OpenGL immediate mode */
1553  GPU_init();
1554 
1555  /* initialize the font */
1556  BLF_init();
1558  ps.fontid = BLF_load_mono_default(false);
1559  BLF_size(ps.fontid, 11.0f, 72);
1560 
1561  ps.ibufx = ibuf->x;
1562  ps.ibufy = ibuf->y;
1563 
1564  ps.win_x = ps.ibufx;
1565  ps.win_y = ps.ibufy;
1566 
1567  if (maxwinx % ibuf->x) {
1568  maxwinx = ibuf->x * (1 + (maxwinx / ibuf->x));
1569  }
1570  if (maxwiny % ibuf->y) {
1571  maxwiny = ibuf->y * (1 + (maxwiny / ibuf->y));
1572  }
1573 
1574  GPU_clear_color(0.1f, 0.1f, 0.1f, 0.0f);
1575 
1576  int win_x, win_y;
1577  playanim_window_get_size(&win_x, &win_y);
1578  GPU_viewport(0, 0, win_x, win_y);
1579  GPU_scissor(0, 0, win_x, win_y);
1581 
1583 
1584  if (sfra == -1 || efra == -1) {
1585  /* one of the frames was invalid, just use all images */
1586  sfra = 1;
1587  efra = MAXFRAME;
1588  }
1589 
1590  build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
1591 
1592 #ifdef WITH_AUDASPACE
1593  source = AUD_Sound_file(filepath);
1594  {
1595  struct anim *anim_movie = ((struct PlayAnimPict *)picsbase.first)->anim;
1596  if (anim_movie) {
1597  short frs_sec = 25;
1598  float frs_sec_base = 1.0;
1599 
1600  IMB_anim_get_fps(anim_movie, &frs_sec, &frs_sec_base, true);
1601 
1602  fps_movie = (double)frs_sec / (double)frs_sec_base;
1603  /* enforce same fps for movie as sound */
1604  swaptime = ps.fstep / fps_movie;
1605  }
1606  }
1607 #endif
1608 
1609  for (i = 2; i < argc; i++) {
1610  BLI_strncpy(filepath, argv[i], sizeof(filepath));
1611  build_pict_list(&ps, filepath, (efra - sfra) + 1, ps.fstep, ps.fontid);
1612  }
1613 
1615  ibuf = NULL;
1616 
1617  pupdate_time();
1618  ptottime = 0;
1619 
1620  /* newly added in 2.6x, without this images never get freed */
1621 #define USE_IMB_CACHE
1622 
1623  while (ps.go) {
1624  if (ps.pingpong) {
1625  ps.direction = -ps.direction;
1626  }
1627 
1628  if (ps.direction == 1) {
1629  ps.picture = picsbase.first;
1630  }
1631  else {
1632  ps.picture = picsbase.last;
1633  }
1634 
1635  if (ps.picture == NULL) {
1636  printf("couldn't find pictures\n");
1637  ps.go = false;
1638  }
1639  if (ps.pingpong) {
1640  if (ps.direction == 1) {
1641  ps.picture = ps.picture->next;
1642  }
1643  else {
1644  ps.picture = ps.picture->prev;
1645  }
1646  }
1647  if (ptottime > 0.0) {
1648  ptottime = 0.0;
1649  }
1650 
1651 #ifdef WITH_AUDASPACE
1652  if (playback_handle) {
1653  AUD_Handle_stop(playback_handle);
1654  }
1655  playback_handle = AUD_Device_play(audio_device, source, 1);
1656  update_sound_fps();
1657 #endif
1658 
1659  while (ps.picture) {
1660  bool has_event;
1661 #ifndef USE_IMB_CACHE
1662  if (ibuf != NULL && ibuf->ftype == IMB_FTYPE_NONE) {
1664  }
1665 #endif
1666 
1668 
1669  if (ibuf) {
1670 #ifdef USE_IMB_CACHE
1671  ps.picture->ibuf = ibuf;
1672 #endif
1673 
1674 #ifdef USE_FRAME_CACHE_LIMIT
1675  if (ps.picture->frame_cache_node == NULL) {
1677  }
1678  else {
1680  }
1682 
1683 #endif /* USE_FRAME_CACHE_LIMIT */
1684 
1685  BLI_strncpy(ibuf->name, ps.picture->name, sizeof(ibuf->name));
1686 
1687  /* why only windows? (from 2.4x) - campbell */
1688 #ifdef _WIN32
1690 #endif
1691 
1692  while (pupdate_time()) {
1693  PIL_sleep_ms(1);
1694  }
1695  ptottime -= swaptime;
1696  playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep);
1697  } /* else delete */
1698  else {
1699  printf("error: can't play this image type\n");
1700  exit(0);
1701  }
1702 
1703  if (ps.once) {
1704  if (ps.picture->next == NULL) {
1705  ps.wait2 = true;
1706  }
1707  else if (ps.picture->prev == NULL) {
1708  ps.wait2 = true;
1709  }
1710  }
1711 
1712  ps.next_frame = ps.direction;
1713 
1714  while ((has_event = GHOST_ProcessEvents(g_WS.ghost_system, false))) {
1716  }
1717  if (ps.go == false) {
1718  break;
1719  }
1720  change_frame(&ps);
1721  if (!has_event) {
1722  PIL_sleep_ms(1);
1723  }
1724  if (ps.wait2) {
1725  continue;
1726  }
1727 
1728  ps.wait2 = ps.sstep;
1729 
1730  if (ps.wait2 == false && ps.stopped) {
1731  ps.stopped = false;
1732  }
1733 
1734  pupdate_time();
1735 
1736  if (ps.picture && ps.next_frame) {
1737  /* Advance to the next frame, always at least set one step.
1738  * Implement frame-skipping when enabled and playback is not fast enough. */
1739  while (ps.picture) {
1740  ps.picture = playanim_step(ps.picture, ps.next_frame);
1741 
1742  if (ps.once && ps.picture != NULL) {
1743  if (ps.picture->next == NULL) {
1744  ps.wait2 = true;
1745  }
1746  else if (ps.picture->prev == NULL) {
1747  ps.wait2 = true;
1748  }
1749  }
1750 
1751  if (ps.wait2 || ptottime < swaptime || ps.noskip) {
1752  break;
1753  }
1754  ptottime -= swaptime;
1755  }
1756  if (ps.picture == NULL && ps.sstep) {
1757  ps.picture = playanim_step(ps.picture, ps.next_frame);
1758  }
1759  }
1760  if (ps.go == false) {
1761  break;
1762  }
1763  }
1764  }
1765  while ((ps.picture = BLI_pophead(&picsbase))) {
1766  if (ps.picture->anim) {
1767  if ((ps.picture->next == NULL) || (ps.picture->next->anim != ps.picture->anim)) {
1769  }
1770  }
1771 
1772  if (ps.picture->ibuf) {
1773  IMB_freeImBuf(ps.picture->ibuf);
1774  }
1775  if (ps.picture->mem) {
1776  MEM_freeN(ps.picture->mem);
1777  }
1778 
1779  MEM_freeN((void *)ps.picture->name);
1780  MEM_freeN(ps.picture);
1781  }
1782 
1783  /* cleanup */
1784 #ifndef USE_IMB_CACHE
1785  if (ibuf) {
1787  }
1788 #endif
1789 
1791 
1792 #ifdef USE_FRAME_CACHE_LIMIT
1794  g_frame_cache.pics_len = 0;
1795  g_frame_cache.pics_size_in_memory = 0;
1796 #endif
1797 
1798 #ifdef WITH_AUDASPACE
1799  if (playback_handle) {
1800  AUD_Handle_stop(playback_handle);
1801  playback_handle = NULL;
1802  }
1803  if (scrub_handle) {
1804  AUD_Handle_stop(scrub_handle);
1805  scrub_handle = NULL;
1806  }
1807  AUD_Sound_free(source);
1808  source = NULL;
1809 #endif
1810 
1811  /* we still miss freeing a lot!,
1812  * but many areas could skip initialization too for anim play */
1813 
1814  IMB_exit();
1816 
1817  BLF_exit();
1818 
1819  if (g_WS.gpu_context) {
1821  GPU_exit();
1823  g_WS.gpu_context = NULL;
1824  }
1825 
1827 
1828  /* early exit, IMB and BKE should be exited only in end */
1829  if (ps.dropped_file[0]) {
1830  BLI_strncpy(filepath, ps.dropped_file, sizeof(filepath));
1831  return filepath;
1832  }
1833 
1835  if (totblock != 0) {
1836  /* prints many bAKey, bArgument's which are tricky to fix */
1837 #if 0
1838  printf("Error Totblock: %d\n", totblock);
1839  MEM_printmemlist();
1840 #endif
1841  }
1842 
1843  return NULL;
1844 }
1845 
1846 void WM_main_playanim(int argc, const char **argv)
1847 {
1848  const char *argv_next[2];
1849  bool looping = true;
1850 
1851 #ifdef WITH_AUDASPACE
1852  {
1853  AUD_DeviceSpecs specs;
1854 
1855  specs.rate = AUD_RATE_48000;
1856  specs.format = AUD_FORMAT_FLOAT32;
1857  specs.channels = AUD_CHANNELS_STEREO;
1858 
1859  AUD_initOnce();
1860 
1861  if (!(audio_device = AUD_init(NULL, specs, 1024, "Blender"))) {
1862  audio_device = AUD_init("None", specs, 0, "Blender");
1863  }
1864  }
1865 #endif
1866 
1867  while (looping) {
1868  const char *filepath = wm_main_playanim_intern(argc, argv);
1869 
1870  if (filepath) { /* use simple args */
1871  argv_next[0] = argv[0];
1872  argv_next[1] = filepath;
1873  argc = 2;
1874 
1875  /* continue with new args */
1876  argv = argv_next;
1877  }
1878  else {
1879  looping = false;
1880  }
1881  }
1882 
1883 #ifdef WITH_AUDASPACE
1884  AUD_exit(audio_device);
1885  AUD_exitOnce();
1886 #endif
1887 }
typedef float(TangentPoint)[2]
int ED_draw_imbuf_method(struct ImBuf *ibuf)
Definition: glutil.c:600
@ BLF_ASPECT
Definition: BLF_api.h:339
void BLF_aspect(int fontid, float x, float y, float z)
Definition: blf.c:288
int BLF_init(void)
Definition: blf.c:59
int BLF_load_mono_default(bool unique)
void BLF_draw(int fontid, const char *str, size_t str_len) ATTR_NONNULL(2)
Definition: blf.c:538
void BLF_exit(void)
Definition: blf.c:70
void BLF_load_font_stack(void)
void BLF_enable(int fontid, int option)
Definition: blf.c:270
void BLF_color4f(int fontid, float r, float g, float b, float a)
Definition: blf.c:446
void BLF_size(int fontid, float size, int dpi)
Definition: blf.c:363
void BLF_position(int fontid, float x, float y, float z)
Definition: blf.c:308
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
#define O_BINARY
Definition: BLI_fileops.h:319
size_t BLI_file_descriptor_size(int file) ATTR_WARN_UNUSED_RESULT
Definition: storage.c:178
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:920
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void * BLI_pophead(ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:221
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:842
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
void * BLI_findlink(const struct ListBase *listbase, int number) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
int BLI_path_sequence_decode(const char *string, char *head, char *tail, unsigned short *r_digits_len)
Definition: path_util.c:56
#define FILE_MAX
void BLI_path_sequence_encode(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
Definition: path_util.c:123
void BLI_rctf_init(struct rctf *rect, float xmin, float xmax, float ymin, float ymax)
Definition: rct.c:407
size_t size_t char * BLI_sprintfN(const char *__restrict format,...) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC ATTR_PRINTF_FORMAT(1
#define STRNCPY(dst, src)
Definition: BLI_string.h:483
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
unsigned char uchar
Definition: BLI_sys_types.h:70
unsigned int uint
Definition: BLI_sys_types.h:67
void BLI_system_backtrace(FILE *fp)
Definition: system.c:62
#define SWAP(type, a, b)
#define SET_FLAG_FROM_TEST(value, test, flag)
#define ELEM(...)
#define MIN2(a, b)
typedef double(DMatrix)[4][4]
void DEG_free_node_types(void)
#define MAXFRAME
@ IMAGE_DRAW_METHOD_GLSL
GHOST C-API function and type declarations.
int32_t GHOST_GetWidthRectangle(GHOST_RectangleHandle rectanglehandle)
GHOST_TSuccess GHOST_GetCursorPosition(const GHOST_SystemHandle systemhandle, const GHOST_WindowHandle windowhandle, int32_t *x, int32_t *y)
GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle, uint32_t width, uint32_t height)
GHOST_SystemHandle GHOST_CreateSystem(void)
Definition: GHOST_C-api.cpp:25
GHOST_TSuccess GHOST_AddEventConsumer(GHOST_SystemHandle systemhandle, GHOST_EventConsumerHandle consumerhandle)
void GHOST_DisposeRectangle(GHOST_RectangleHandle rectanglehandle)
bool GHOST_ProcessEvents(GHOST_SystemHandle systemhandle, bool waitForEvent)
void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title)
void GHOST_ScreenToClient(GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY)
GHOST_TSuccess GHOST_DisposeWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle windowhandle)
void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
int32_t GHOST_GetHeightRectangle(GHOST_RectangleHandle rectanglehandle)
void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle, uint32_t *width, uint32_t *height)
GHOST_TSuccess GHOST_SwapWindowBuffers(GHOST_WindowHandle windowhandle)
GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
GHOST_TSuccess GHOST_ActivateWindowDrawingContext(GHOST_WindowHandle windowhandle)
GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle, GHOST_TModifierKey mask, bool *r_is_down)
GHOST_TEventType GHOST_GetEventType(GHOST_EventHandle eventhandle)
void GHOST_DispatchEvents(GHOST_SystemHandle systemhandle)
GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle, GHOST_WindowHandle parent_windowhandle, const char *title, int32_t left, int32_t top, uint32_t width, uint32_t height, GHOST_TWindowState state, bool is_dialog, GHOST_TDrawingContextType type, GHOST_GLSettings glSettings)
GHOST_EventConsumerHandle GHOST_CreateEventConsumer(GHOST_EventCallbackProcPtr eventCallback, GHOST_TUserDataPtr userdata)
Definition: GHOST_C-api.cpp:59
GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
@ GHOST_kWindowStateNormal
Definition: GHOST_Types.h:130
void * GHOST_TUserDataPtr
Definition: GHOST_Types.h:72
GHOST_TEventType
Definition: GHOST_Types.h:169
@ GHOST_kEventWindowClose
Definition: GHOST_Types.h:189
@ GHOST_kEventWindowMove
Definition: GHOST_Types.h:194
@ GHOST_kEventWindowSize
Definition: GHOST_Types.h:193
@ GHOST_kEventDraggingDropDone
Definition: GHOST_Types.h:200
@ GHOST_kEventCursorMove
Definition: GHOST_Types.h:172
@ GHOST_kEventButtonUp
Definition: GHOST_Types.h:174
@ GHOST_kEventWindowActivate
Definition: GHOST_Types.h:190
@ GHOST_kEventWindowDeactivate
Definition: GHOST_Types.h:191
@ GHOST_kEventButtonDown
Definition: GHOST_Types.h:173
@ GHOST_kEventKeyDown
Definition: GHOST_Types.h:183
@ GHOST_kEventKeyUp
Definition: GHOST_Types.h:184
@ GHOST_kEventQuitRequest
Definition: GHOST_Types.h:187
@ GHOST_kKey5
Definition: GHOST_Types.h:282
@ GHOST_kKey4
Definition: GHOST_Types.h:281
@ GHOST_kKeyNumpad3
Definition: GHOST_Types.h:357
@ GHOST_kKeyNumpad1
Definition: GHOST_Types.h:355
@ GHOST_kKey3
Definition: GHOST_Types.h:280
@ GHOST_kKeyI
Definition: GHOST_Types.h:300
@ GHOST_kKeyEnter
Definition: GHOST_Types.h:265
@ GHOST_kKeyP
Definition: GHOST_Types.h:307
@ GHOST_kKeyNumpadSlash
Definition: GHOST_Types.h:369
@ GHOST_kKeyRightArrow
Definition: GHOST_Types.h:339
@ GHOST_kKeyNumpad4
Definition: GHOST_Types.h:358
@ GHOST_kKeyMinus
Definition: GHOST_Types.h:271
@ GHOST_kKey6
Definition: GHOST_Types.h:283
@ GHOST_kKey0
Definition: GHOST_Types.h:277
@ GHOST_kKeyDownArrow
Definition: GHOST_Types.h:341
@ GHOST_kKeyNumpadPeriod
Definition: GHOST_Types.h:364
@ GHOST_kKeyF
Definition: GHOST_Types.h:297
@ GHOST_kKey1
Definition: GHOST_Types.h:278
@ GHOST_kKey8
Definition: GHOST_Types.h:285
@ GHOST_kKeyNumpad2
Definition: GHOST_Types.h:356
@ GHOST_kKeyPeriod
Definition: GHOST_Types.h:273
@ GHOST_kKeyNumpadPlus
Definition: GHOST_Types.h:366
@ GHOST_kKey9
Definition: GHOST_Types.h:286
@ GHOST_kKeyNumpad5
Definition: GHOST_Types.h:359
@ GHOST_kKeyLeftArrow
Definition: GHOST_Types.h:338
@ GHOST_kKeyEqual
Definition: GHOST_Types.h:289
@ GHOST_kKey7
Definition: GHOST_Types.h:284
@ GHOST_kKeyNumpad6
Definition: GHOST_Types.h:360
@ GHOST_kKeyNumpad8
Definition: GHOST_Types.h:362
@ GHOST_kKeyNumpad9
Definition: GHOST_Types.h:363
@ GHOST_kKeyUpArrow
Definition: GHOST_Types.h:340
@ GHOST_kKeyNumpad0
Definition: GHOST_Types.h:354
@ GHOST_kKeyA
Definition: GHOST_Types.h:292
@ GHOST_kKey2
Definition: GHOST_Types.h:279
@ GHOST_kKeyNumpad7
Definition: GHOST_Types.h:361
@ GHOST_kKeyEsc
Definition: GHOST_Types.h:267
@ GHOST_kKeyPlus
Definition: GHOST_Types.h:272
@ GHOST_kKeySlash
Definition: GHOST_Types.h:274
@ GHOST_kKeyNumpadEnter
Definition: GHOST_Types.h:365
@ GHOST_kKeyNumpadMinus
Definition: GHOST_Types.h:367
@ GHOST_kKeySpace
Definition: GHOST_Types.h:268
@ GHOST_kDrawingContextTypeOpenGL
Definition: GHOST_Types.h:150
@ GHOST_kModifierKeyRightControl
Definition: GHOST_Types.h:124
@ GHOST_kModifierKeyLeftControl
Definition: GHOST_Types.h:123
@ GHOST_kModifierKeyRightAlt
Definition: GHOST_Types.h:122
@ GHOST_kModifierKeyRightShift
Definition: GHOST_Types.h:120
@ GHOST_kModifierKeyLeftAlt
Definition: GHOST_Types.h:121
@ GHOST_kModifierKeyLeftShift
Definition: GHOST_Types.h:119
void(* GHOST_TBacktraceFn)(void *file_handle)
Definition: GHOST_Types.h:45
@ GHOST_kDragnDropTypeFilenames
Definition: GHOST_Types.h:476
@ GHOST_kButtonMaskRight
Definition: GHOST_Types.h:160
@ GHOST_kButtonMaskLeft
Definition: GHOST_Types.h:158
@ GHOST_kButtonMaskMiddle
Definition: GHOST_Types.h:159
struct GPUContext GPUContext
Definition: GPU_context.h:27
void GPU_context_discard(GPUContext *)
Definition: gpu_context.cc:110
GPUContext * GPU_context_create(void *ghost_window)
Definition: gpu_context.cc:93
void GPU_context_active_set(GPUContext *)
Definition: gpu_context.cc:127
void immUniformColor3ub(unsigned char r, unsigned char g, unsigned char b)
void immUnbindProgram(void)
void immVertex2f(uint attr_id, float x, float y)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
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_checker_2d_ex(float x1, float y1, float x2, float y2, const float color_primary[4], const float color_secondary[4], int checker_size)
void GPU_init(void)
Definition: gpu_init_exit.c:24
void GPU_exit(void)
Definition: gpu_init_exit.c:45
_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 type
void GPU_matrix_pop(void)
Definition: gpu_matrix.cc:126
void GPU_matrix_ortho_set(float left, float right, float bottom, float top, float near, float far)
Definition: gpu_matrix.cc:399
void GPU_matrix_identity_projection_set(void)
Definition: gpu_matrix.cc:154
void GPU_matrix_pop_projection(void)
Definition: gpu_matrix.cc:140
void GPU_matrix_push(void)
Definition: gpu_matrix.cc:119
void GPU_matrix_identity_set(void)
Definition: gpu_matrix.cc:168
void GPU_matrix_push_projection(void)
Definition: gpu_matrix.cc:133
@ GPU_PRIM_TRI_FAN
Definition: GPU_primitive.h:25
@ GPU_PRIM_LINES
Definition: GPU_primitive.h:20
@ GPU_SHADER_2D_UNIFORM_COLOR
Definition: GPU_shader.h:201
@ GPU_SHADER_2D_IMAGE_COLOR
Definition: GPU_shader.h:217
@ GPU_BLEND_NONE
Definition: GPU_state.h:60
@ GPU_BLEND_ALPHA
Definition: GPU_state.h:62
void GPU_blend(eGPUBlend blend)
Definition: gpu_state.cc:39
void GPU_scissor(int x, int y, int width, int height)
Definition: gpu_state.cc:185
void GPU_viewport(int x, int y, int width, int height)
Definition: gpu_state.cc:191
struct GPUTexture GPUTexture
Definition: GPU_texture.h:17
eGPUDataFormat
Definition: GPU_texture.h:170
@ GPU_DATA_UBYTE
Definition: GPU_texture.h:174
@ GPU_DATA_FLOAT
Definition: GPU_texture.h:171
void GPU_texture_update(GPUTexture *tex, eGPUDataFormat data_format, const void *data)
Definition: gpu_texture.cc:444
void GPU_texture_free(GPUTexture *tex)
Definition: gpu_texture.cc:564
void GPU_texture_filter_mode(GPUTexture *tex, bool use_filter)
Definition: gpu_texture.cc:518
void GPU_texture_unbind(GPUTexture *tex)
Definition: gpu_texture.cc:472
GPUTexture * GPU_texture_create_2d(const char *name, int w, int h, int mip_len, eGPUTextureFormat format, const float *data)
Definition: gpu_texture.cc:291
eGPUTextureFormat
Definition: GPU_texture.h:83
@ GPU_RGB16F
Definition: GPU_texture.h:127
@ GPU_RGBA8
Definition: GPU_texture.h:87
void GPU_texture_bind(GPUTexture *tex, int unit)
Definition: gpu_texture.cc:466
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, const char *name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
@ COLOR_ROLE_DEFAULT_BYTE
void IMB_display_buffer_release(void *cache_handle)
bool IMB_colormanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, float dither, bool predivide)
void IMB_colormanagement_init_default_view_settings(struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings)
unsigned char * IMB_display_buffer_acquire(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, void **cache_handle)
const char * IMB_colormanagement_role_colorspace_name_get(int role)
void IMB_colormanagement_finish_glsl_draw(void)
bool IMB_colormanagement_setup_glsl_draw_from_space(const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, struct ColorSpace *colorspace, float dither, bool predivide, bool do_overlay_merge)
bool IMB_anim_get_fps(struct anim *anim, short *frs_sec, float *frs_sec_base, bool no_av_base)
Definition: anim_movie.c:1678
@ IMB_PROXY_NONE
Definition: IMB_imbuf.h:341
void IMB_close_anim(struct anim *anim)
Definition: anim_movie.c:215
size_t IMB_get_size_in_memory(struct ImBuf *ibuf)
Definition: allocimbuf.c:655
struct anim * IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE])
Definition: anim_movie.c:268
void IMB_exit(void)
Definition: module.c:25
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:209
bool IMB_isanim(const char *filepath)
Definition: util.c:385
struct ImBuf * IMB_ibImageFromMemory(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:84
bool IMB_ispic(const char *filepath)
Definition: util.c:183
struct ImBuf * IMB_anim_absolute(struct anim *anim, int position, IMB_Timecode_Type tc, IMB_Proxy_Size preview_size)
Definition: anim_movie.c:1571
int IMB_anim_get_duration(struct anim *anim, IMB_Timecode_Type tc)
Definition: anim_movie.c:1658
@ IMB_TC_NONE
Definition: IMB_imbuf.h:318
Contains defines and structs used throughout the imbuf module.
@ IB_rect
#define IMB_FTYPE_NONE
Read Guarded memory(de)allocation.
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
Platform independent time functions.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
static btDbvtVolume bounds(btDbvtNode **leaves, int count)
Definition: btDbvt.cpp:299
OperationNode * node
FILE * file
double time
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img GPU_RGBA16F
#define str(s)
uint pos
void GPU_clear_color(float red, float green, float blue, float alpha)
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
int count
format
Definition: logImageCore.h:38
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
unsigned int(* MEM_get_memory_blocks_in_use)(void)
Definition: mallocn.c:46
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
void(* MEM_printmemlist)(void)
Definition: mallocn.c:39
static unsigned int totblock
static unsigned a[3]
Definition: RandGen.cpp:78
static const pxr::TfToken preview("preview", pxr::TfToken::Immortal)
unsigned int uint32_t
Definition: stdint.h:80
GHOST_TButton button
Definition: GHOST_Types.h:440
GHOST_TEventDataPtr data
Definition: GHOST_Types.h:489
GHOST_TDragnDropTypes dataType
Definition: GHOST_Types.h:487
uint8_t ** strings
Definition: GHOST_Types.h:508
int channels
struct ColorSpace * rect_colorspace
float dither
unsigned char planes
char name[IMB_FILENAME_SIZE]
enum eImbFileType ftype
unsigned int * rect
float * rect_float
struct ColorSpace * float_colorspace
void * data
Definition: DNA_listBase.h:26
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
struct anim * anim
Definition: wm_playanim.c:245
struct PlayAnimPict * prev
Definition: wm_playanim.c:240
struct ImBuf * ibuf
Definition: wm_playanim.c:244
size_t size_in_memory
Definition: wm_playanim.c:252
LinkData * frame_cache_node
Definition: wm_playanim.c:251
struct PlayAnimPict * next
Definition: wm_playanim.c:240
uchar * mem
Definition: wm_playanim.c:241
const char * name
Definition: wm_playanim.c:243
short next_frame
Definition: wm_playanim.c:103
ColorManagedViewSettings view_settings
Definition: wm_playanim.c:150
bool wait2
Definition: wm_playanim.c:116
bool sstep
Definition: wm_playanim.c:114
struct PlayAnimPict * picture
Definition: wm_playanim.c:135
bool pingpong
Definition: wm_playanim.c:108
char dropped_file[FILE_MAX]
Definition: wm_playanim.c:143
bool stopped
Definition: wm_playanim.c:118
float zoom
Definition: wm_playanim.c:98
bool draw_flip[2]
Definition: wm_playanim.c:129
short direction
Definition: wm_playanim.c:101
bool noskip
Definition: wm_playanim.c:110
ColorManagedDisplaySettings display_settings
Definition: wm_playanim.c:151
bool indicator
Definition: wm_playanim.c:112
bool need_frame_update
Definition: wm_playanim.c:146
bool loading
Definition: wm_playanim.c:127
int frame_cursor_x
Definition: wm_playanim.c:148
GPUContext * gpu_context
Definition: wm_playanim.c:191
GHOST_SystemHandle ghost_system
Definition: wm_playanim.c:189
Definition: IMB_anim.h:71
char first[1024]
Definition: IMB_anim.h:84
float xmax
Definition: DNA_vec_types.h:69
float xmin
Definition: DNA_vec_types.h:69
float ymax
Definition: DNA_vec_types.h:70
float ymin
Definition: DNA_vec_types.h:70
void PIL_sleep_ms(int ms)
Definition: time.c:84
double PIL_check_seconds_timer(void)
Definition: time.c:64
static void playanim_gl_matrix(void)
Definition: wm_playanim.c:205
static char * wm_main_playanim_intern(int argc, const char **argv)
Definition: wm_playanim.c:1387
struct PlayAnimPict PlayAnimPict
void WM_main_playanim(int argc, const char **argv)
Definition: wm_playanim.c:1846
size_t memory_limit
Definition: wm_playanim.c:273
static void frame_cache_remove(PlayAnimPict *pic)
Definition: wm_playanim.c:294
static struct WindowStateGlobal g_WS
static void playanim_window_open(const char *title, int posx, int posy, int sizex, int sizey)
Definition: wm_playanim.c:1340
static bool fromdisk
Definition: wm_playanim.c:258
static bool ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
Definition: wm_playanim.c:874
static struct ListBase picsbase
Definition: wm_playanim.c:256
static void frame_cache_touch(PlayAnimPict *pic)
Definition: wm_playanim.c:310
static void build_pict_list_ex(PlayState *ps, const char *first, int totframes, int fstep, int fontid)
Definition: wm_playanim.c:621
static double swaptime
Definition: wm_playanim.c:259
static int pupdate_time(void)
Definition: wm_playanim.c:378
static void frame_cache_add(PlayAnimPict *pic)
Definition: wm_playanim.c:281
static bool frame_cache_limit_exceeded(void)
Definition: wm_playanim.c:317
static void playanim_window_get_size(int *r_width, int *r_height)
Definition: wm_playanim.c:197
static void playanim_window_zoom(struct PlayState *ps, const float zoom_offset)
Definition: wm_playanim.c:1363
static ImBuf * ibuf_from_picture(PlayAnimPict *pic)
Definition: wm_playanim.c:341
static PlayAnimPict * playanim_step(PlayAnimPict *playanim, int step)
Definition: wm_playanim.c:363
static void change_frame(PlayState *ps)
Definition: wm_playanim.c:814
static void frame_cache_limit_apply(ImBuf *ibuf_keep)
Definition: wm_playanim.c:324
size_t pics_size_in_memory
Definition: wm_playanim.c:271
int pics_len
Definition: wm_playanim.c:269
static void update_sound_fps(void)
Definition: wm_playanim.c:796
static struct @1199 g_frame_cache
struct PlayState PlayState
eWS_Qual
Definition: wm_playanim.c:172
@ WS_QUAL_LCTRL
Definition: wm_playanim.c:179
@ WS_QUAL_RMOUSE
Definition: wm_playanim.c:184
@ WS_QUAL_MOUSE
Definition: wm_playanim.c:185
@ WS_QUAL_CTRL
Definition: wm_playanim.c:181
@ WS_QUAL_RALT
Definition: wm_playanim.c:177
@ WS_QUAL_MMOUSE
Definition: wm_playanim.c:183
@ WS_QUAL_LMOUSE
Definition: wm_playanim.c:182
@ WS_QUAL_LALT
Definition: wm_playanim.c:176
@ WS_QUAL_ALT
Definition: wm_playanim.c:178
@ WS_QUAL_SHIFT
Definition: wm_playanim.c:175
@ WS_QUAL_RCTRL
Definition: wm_playanim.c:180
@ WS_QUAL_LSHIFT
Definition: wm_playanim.c:173
@ WS_QUAL_RSHIFT
Definition: wm_playanim.c:174
static void tag_change_frame(PlayState *ps, int cx)
Definition: wm_playanim.c:808
static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
Definition: wm_playanim.c:533
#define PLAY_FRAME_CACHE_MAX
Definition: wm_playanim.c:79
static double ptottime
Definition: wm_playanim.c:259
static void draw_display_buffer(PlayState *ps, ImBuf *ibuf)
Definition: wm_playanim.c:461
static void playanim_event_qual_update(void)
Definition: wm_playanim.c:213
static void * ocio_transform_ibuf(PlayState *ps, ImBuf *ibuf, bool *r_glsl_used, eGPUTextureFormat *r_format, eGPUDataFormat *r_data, void **r_buffer_cache_handle)
Definition: wm_playanim.c:389
static void build_pict_list(PlayState *ps, const char *first, int totframes, int fstep, int fontid)
Definition: wm_playanim.c:789
struct ListBase pics
Definition: wm_playanim.c:267