]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/omapdrmtest.git/blobdiff - util/util.c
omx cam: add test app
[glsdk/omapdrmtest.git] / util / util.c
index 69f8c45b0cc6350c59c78ee42cf1807be07d50e3..0b9e0eb984ff69fc19568d4cd19ff70d6375f41d 100644 (file)
 
 #include <drm.h>
 
+/* Dynamic debug. */
+int debug = 0;
+
 void disp_kms_usage(void);
 struct display * disp_kms_open(int argc, char **argv);
 
 #ifdef HAVE_X11
 void disp_x11_usage(void);
 struct display * disp_x11_open(int argc, char **argv);
+void disp_x11_close(struct display *disp);
 #endif
 
 void
 disp_usage(void)
 {
+       MSG("Generic Display options:");
+       MSG("\t--debug\tTurn on debug messages.");
+       MSG("\t--fps <fps>\tforce playback rate (0 means \"do not force\")");
+       MSG("\t--no-post\tDo not post buffers (disables screen updates) for benchmarking. Rate can still be controlled.");
+
 #ifdef HAVE_X11
        disp_x11_usage();
 #endif
        disp_kms_usage();
 }
 
+static int
+empty_post_buffer(struct display *disp, struct buffer *buf)
+{
+       return 0;
+}
+
+static int
+empty_post_vid_buffer(struct display *disp, struct buffer *buf,
+                       uint32_t x, uint32_t y, uint32_t w, uint32_t h)
+{
+       return 0;
+}
+
 struct display *
 disp_open(int argc, char **argv)
 {
        struct display *disp;
+       int i, fps = 0, no_post = 0;
+
+       for (i = 1; i < argc; i++) {
+               if (!argv[i]) {
+                       continue;
+               }
+               if (!strcmp("--debug", argv[i])) {
+                       debug = 1;
+                       MSG("Enabling dynamic debug.");
+                       argv[i] = NULL;
+
+               } else if (!strcmp("--fps", argv[i])) {
+                       argv[i++] = NULL;
+
+                       if (sscanf(argv[i], "%d", &fps) != 1) {
+                               ERROR("invalid arg: %s", argv[i]);
+                               return NULL;
+                       }
+
+                       MSG("Forcing playback rate at %d fps.", fps);
+                       argv[i] = NULL;
+
+               } else if (!strcmp("--no-post", argv[i])) {
+                       MSG("Disabling buffers posting.");
+                       no_post = 1;
+                       argv[i] = NULL;
+               }
+       }
 
 #ifdef HAVE_X11
        disp = disp_x11_open(argc, argv);
        if (disp)
-               return disp;
+               goto out;
 #endif
 
        disp = disp_kms_open(argc, argv);
 
        if (!disp) {
                ERROR("unable to create display");
+               return NULL;
+       }
+
+out:
+       disp->rtctl.fps = fps;
+
+       /* If buffer posting is disabled from command line, override post
+        * functions with empty ones. */
+       if (no_post) {
+               disp->post_buffer = empty_post_buffer;
+               disp->post_vid_buffer = empty_post_vid_buffer;
        }
 
        return disp;
@@ -103,6 +164,56 @@ disp_put_vid_buffer(struct display *disp, struct buffer *buf)
        list_add(&buf->unlocked, &disp->unlocked);
 }
 
+/* Maintain playback rate if fps > 0. */
+static void maintain_playback_rate(struct rate_control *p)
+{
+       long usecs_since_last_frame;
+       int usecs_between_frames, usecs_to_sleep;
+
+       if (p->fps <= 0)
+               return;
+
+       usecs_between_frames = 1000000 / p->fps;
+       usecs_since_last_frame = mark(&p->last_frame_mark);
+       DBG("fps: %.02f", 1000000.0 / usecs_since_last_frame);
+       usecs_to_sleep = usecs_between_frames - usecs_since_last_frame + p->usecs_to_sleep;
+
+       if (usecs_to_sleep < 0)
+               usecs_to_sleep = 0;
+
+       /* mark() has a limitation that >1s time deltas will make the whole
+        * loop diverge. Workaround that limitation by clamping our desired sleep time
+        * to a maximum. TODO: Remove when mark() is in better shape. */
+       if (usecs_to_sleep >= 1000000)
+               usecs_to_sleep = 999999;
+
+       /* We filter a bit our rate adaptation, to avoid being too "choppy".
+        * Adjust the "alpha" value as needed. */
+       p->usecs_to_sleep = ((67 * p->usecs_to_sleep) + (33 * usecs_to_sleep)) / 100;
+
+       if (p->usecs_to_sleep >= 1) {
+               DBG("sleeping %dus", p->usecs_to_sleep);
+               usleep(p->usecs_to_sleep);
+       }
+}
+
+/* flip to / post the specified buffer */
+int
+disp_post_buffer(struct display *disp, struct buffer *buf)
+{
+       maintain_playback_rate(&disp->rtctl);
+       return disp->post_buffer(disp, buf);
+}
+
+/* flip to / post the specified video buffer */
+int
+disp_post_vid_buffer(struct display *disp, struct buffer *buf,
+               uint32_t x, uint32_t y, uint32_t w, uint32_t h)
+{
+       maintain_playback_rate(&disp->rtctl);
+       return disp->post_vid_buffer(disp, buf, x, y, w, h);
+}
+
 struct buffer *
 disp_get_fb(struct display *disp)
 {