Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(52)

Side by Side Diff: src/ply-image.c

Issue 6019001: Make animation loop more understandable. (Closed) Base URL: http://git.chromium.org/git/ply-image.git@master
Patch Set: rename variables Created 10 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* ply-image.c - png file loader 1 /* ply-image.c - png file loader
2 * 2 *
3 * Copyright (C) 2006, 2007 Red Hat, Inc. 3 * Copyright (C) 2006, 2007 Red Hat, Inc.
4 * Copyright (C) 2003 University of Southern California 4 * Copyright (C) 2003 University of Southern California
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option) 8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version. 9 * any later version.
10 * 10 *
(...skipping 471 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 ply_frame_buffer_get_size (buffer, &area); 482 ply_frame_buffer_get_size (buffer, &area);
483 area.x = (area.width / 2) - (width / 2); // + x; 483 area.x = (area.width / 2) - (width / 2); // + x;
484 area.y = (area.height / 2) - (height / 2); // + y; 484 area.y = (area.height / 2) - (height / 2); // + y;
485 area.width = width; 485 area.width = width;
486 area.height = height; 486 area.height = height;
487 487
488 ply_frame_buffer_fill (buffer, &area, x, y, data); 488 ply_frame_buffer_fill (buffer, &area, x, y, data);
489 ply_image_free (image); 489 ply_image_free (image);
490 } 490 }
491 491
492 /* 492
493 * Compute the difference in nanoseconds between two timevals. Return 0 if the 493 int64_t timespec_to_nsec(struct timespec ts)
494 * clock is not reliable.
495 */
496 int64_t difference_nsec(struct timespec x, struct timespec y)
497 { 494 {
498 int64_t z; 495 int64_t nsec;
499 496 nsec = ts.tv_sec;
500 if (bad_clock) 497 nsec *= BILLION;
501 { 498 nsec += ts.tv_nsec;
502 return 0; 499 return nsec;
503 }
504
505 z = x.tv_sec - y.tv_sec;
506 z *= BILLION;
507 z += x.tv_nsec - y.tv_nsec;
508 return z;
509 } 500 }
510 501
511 502
512 void gettime_check(struct timespec *ts) 503 int64_t gettime_check(void)
513 { 504 {
514 int r = clock_gettime(CLOCK_MONOTONIC, ts); 505 struct timespec ts;
506 int r = clock_gettime(CLOCK_MONOTONIC, &ts);
515 if (r) 507 if (r)
516 { 508 {
517 bad_clock = 1; 509 bad_clock = 1;
510 return 0;
518 } 511 }
512 return timespec_to_nsec(ts);
519 } 513 }
520 514
521 515
522 int usage(void) 516 int usage(void)
523 { 517 {
524 fprintf(stderr, 518 fprintf(stderr,
525 "usage: ply-image --clear\n" 519 "usage: ply-image --clear\n"
526 " ply-image <background> [<x-offset> <y-offset> " 520 " ply-image <background> [<x-offset> <y-offset> "
527 "<frame-1> ... <frame-n>]\n"); 521 "<frame-1> ... <frame-n>]\n");
528 exit(1); 522 exit(1);
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 /* 571 /*
578 * Display main image. 572 * Display main image.
579 */ 573 */
580 ply_frame_buffer_show_file_at_xy (buffer, argv[1], 0, 0); 574 ply_frame_buffer_show_file_at_xy (buffer, argv[1], 0, 0);
581 575
582 if (argc >= 4) 576 if (argc >= 4)
583 { 577 {
584 /* 578 /*
585 * Animate frames. 579 * Animate frames.
586 */ 580 */
587 struct timespec then, now; 581 int64_t draw_time_nsec, frame_period_nsec;
588 int64_t error_nsec; 582 int64_t sleep_time_nsec, now_nsec, then_nsec;
589 int64_t interval_nsec;
590 583
591 xoff = strtol (argv[2], &endptr, 10); 584 xoff = strtol (argv[2], &endptr, 10);
592 if (endptr == argv[2] || *endptr != '\0') 585 if (endptr == argv[2] || *endptr != '\0')
593 { 586 {
594 usage (); 587 usage ();
595 } 588 }
596 yoff = strtol (argv[3], &endptr, 10); 589 yoff = strtol (argv[3], &endptr, 10);
597 if (endptr == argv[3] || *endptr != '\0') 590 if (endptr == argv[3] || *endptr != '\0')
598 { 591 {
599 usage (); 592 usage ();
600 } 593 }
601 594
602 /* 595 /*
603 * Begin animation. 596 * Begin animation.
604 * 597 *
605 * The first time around, we don't know how long it takes to draw a 598 * The first time around, we don't know how long it takes to draw a
606 * frame, so we assume it's instantaneous. After that, we assume 599 * frame, so we approximate it as 0. After that, we assume that the
607 * that the drawing time for the previous cycle is a good estimate 600 * drawing time for the previous cycle is a good estimate for the
608 * for the next cycle. Errors may be introduced by different frame 601 * next cycle. Errors may be introduced by different frame size and
609 * size and complexity (PNG decoding). 602 * complexity (PNG decoding) and by the CPU load.
610 */ 603 */
611 error_nsec = 0; 604 draw_time_nsec = 0;
612 interval_nsec = BILLION / frame_rate; 605 frame_period_nsec = BILLION / frame_rate;
613 gettime_check (&now); 606 now_nsec = gettime_check ();
614 607
615 for (i = 4; i < argc; i++) 608 for (i = 4; i < argc; i++)
616 { 609 {
617 /* 610 /*
618 * Before displaying the next frame, sleep for the inter-frame 611 * Before displaying the next frame, sleep for the right amount
619 * interval, adjusted by the error in the previous cycle. 612 * of time so that the achieved period approximates the desired
620 * Positive error means the last cycle took longer than desired. 613 * period.
621 */ 614 */
622 if (interval_nsec - error_nsec > 0) 615 sleep_time_nsec = frame_period_nsec - draw_time_nsec;
616 if (sleep_time_nsec > 0)
623 { 617 {
624 struct timespec req; 618 struct timespec req;
625 req.tv_sec = (interval_nsec - error_nsec) / BILLION; 619 req.tv_sec = sleep_time_nsec / BILLION;
626 req.tv_nsec = (interval_nsec - error_nsec) % BILLION; 620 req.tv_nsec = sleep_time_nsec % BILLION;
627 nanosleep (&req, NULL); 621 nanosleep (&req, NULL);
628 } 622 }
629 ply_frame_buffer_show_file_at_xy (buffer, argv[i], xoff, yoff); 623 ply_frame_buffer_show_file_at_xy (buffer, argv[i], xoff, yoff);
630 then = now; 624 then_nsec = now_nsec;
631 gettime_check (&now); 625 now_nsec = gettime_check ();
632 error_nsec = difference_nsec (now, then) - interval_nsec; 626 /*
627 * If the clock is bad (unlikely), assume draw time is
628 * instantaneous as a rough guess.
629 */
630 draw_time_nsec = bad_clock ? 0 :
631 now_nsec - then_nsec - sleep_time_nsec;
633 } 632 }
634 } 633 }
635 } 634 }
636 635
637 // Skip these to save time. 636 // Skip these to save time.
638 // ply_frame_buffer_close (buffer); 637 // ply_frame_buffer_close (buffer);
639 // ply_frame_buffer_free (buffer); 638 // ply_frame_buffer_free (buffer);
640 639
641 return exit_code; 640 return exit_code;
642 } 641 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698