From 37959907658e666fadef87a2d65bf73f12dbe066 Mon Sep 17 00:00:00 2001
From: Benjamin Otte <otte@gnome.org>
Date: Wed, 12 Dec 2007 14:13:44 +0100
Subject: [PATCH] write a simple test application that renders as fast as
 possible

---
 player/main.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 72 insertions(+), 3 deletions(-)

diff --git a/player/main.c b/player/main.c
index 376f286..0cdc839 100644
--- a/player/main.c
+++ b/player/main.c
@@ -21,16 +21,57 @@
 #include "config.h"
 #endif
 #include <libswfdec/swfdec.h>
+#include <directfb.h>
+#include <cairo-directfb.h>
+
+#define ERROR_CHECK(x) G_STMT_START{ \
+  DFBResult err = (x); \
+  if (err != DFB_OK) { \
+    DirectFBErrorFatal ("fatal error", err); \
+  } \
+}G_STMT_END
+
+typedef struct {
+  IDirectFB *dfb;
+  IDirectFBSurface *dfbsurface;
+  cairo_surface_t *surface;
+} Data;
+
+static void
+render (SwfdecPlayer *player, Data *data, guint x, guint y, guint w, guint h)
+{
+  /* region include the bottom right pixel */
+  DFBRegion region = { x, y, x + w - 1, y + h - 1 };
+  cairo_t *cr;
+
+  cr = cairo_create (data->surface);
+  swfdec_player_render (player, cr, x, y, w, h);
+  cairo_destroy (cr);
+  data->dfbsurface->Flip (data->dfbsurface, &region, DSFLIP_ONSYNC);
+}
+
+static void
+invalidate (SwfdecPlayer *player, SwfdecRectangle *extents, SwfdecRectangle *rects, guint n_rects, Data *data)
+{
+  render (player, data, extents->x, extents->y, extents->width, extents->height);
+}
 
 int 
 main (int argc, char *argv[])
 {
   GError *error = NULL;
+  GOptionContext *ctx;
+  DFBSurfaceDescription dsc;
+  SwfdecPlayer *player;
+  guint w, h;
+  Data data;
 
   static const GOptionEntry options[] = {
     { NULL }
   };
-  GOptionContext *ctx;
+
+  ERROR_CHECK (DirectFBInit (&argc, &argv));
+  swfdec_init ();
 
   ctx = g_option_context_new ("");
   g_option_context_add_main_entries (ctx, options, "options");
@@ -43,13 +84,41 @@ main (int argc, char *argv[])
     return 1;
   }
 
-  swfdec_init ();
-
   if (argc < 2) {
     g_printerr ("Usage: %s [OPTIONS] filename\n", argv[0]);
     return 1;
   }
   
+  ERROR_CHECK (DirectFBCreate (&data.dfb));
+  ERROR_CHECK (data.dfb->SetCooperativeLevel (data.dfb, DFSCL_NORMAL));
+
+  player = swfdec_player_new_from_file (argv[1]);
+  /* advance till initialized or fail */
+  /* NB: This method only knows for file loading */
+  while (!swfdec_player_is_initialized (player)) {
+    long next_event = swfdec_player_get_next_event (player);
+    if (next_event < 0) {
+      g_object_unref (player);
+      g_printerr ("\"%s\" is not a file Swfdec can play.\n", argv[1]);
+      return 1;
+    }
+    swfdec_player_advance (player, next_event);
+  }
+  swfdec_player_get_default_size (player, &w, &h);
+
+  dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
+  dsc.caps = DSCAPS_DOUBLE | DSCAPS_PRIMARY;
+  dsc.width = w;
+  dsc.height = h;
+  ERROR_CHECK (data.dfb->CreateSurface (data.dfb, &dsc, &data.dfbsurface));
+  data.surface = cairo_directfb_surface_create (data.dfb, data.dfbsurface);
+  render (player, &data, 0, 0, w, h);
+  g_signal_connect (player, "invalidate", G_CALLBACK (invalidate), &data);
+  while (TRUE) {
+    int next_event = swfdec_player_get_next_event (player);
+    swfdec_player_advance (player, next_event);
+  };
+
   return 0;
 }
 
-- 
GitLab