Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 x) |
|
Daniel Erat
2010/12/17 19:15:42
nit: better variable names ('spec' instead of 'x',
| |
| 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 y; |
| 499 | 496 y = x.tv_sec; |
| 500 if (bad_clock) | 497 y *= BILLION; |
| 501 { | 498 y += x.tv_nsec; |
| 502 return 0; | 499 return y; |
| 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 Loading... | |
| 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 } |
| OLD | NEW |