summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@gnome.org>2007-12-13 16:17:08 +0100
committerBenjamin Otte <otte@gnome.org>2007-12-13 16:17:08 +0100
commit6a22a70a1ccc3c286b559b0ae99df240307324d0 (patch)
tree02c9fbf96b05a4de3f5678ea8767c5180976f3d5
parentf41c2e1f0ba9d3b7f22705401b0061411dcb17ef (diff)
seperate out the renderer functionality
-rw-r--r--player/main.c64
-rw-r--r--swfdec-directfb/Makefile.am6
-rw-r--r--swfdec-directfb/swfdec-directfb.h1
-rw-r--r--swfdec-directfb/swfdec_directfb_player.h1
-rw-r--r--swfdec-directfb/swfdec_directfb_renderer.c137
-rw-r--r--swfdec-directfb/swfdec_directfb_renderer.h73
6 files changed, 235 insertions, 47 deletions
diff --git a/player/main.c b/player/main.c
index 2b91c33..87c052b 100644
--- a/player/main.c
+++ b/player/main.c
@@ -20,10 +20,8 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#include <libswfdec/swfdec.h>
#include <swfdec-directfb/swfdec-directfb.h>
#include <directfb.h>
-#include <cairo-directfb.h>
#include <stdio.h>
#define ERROR_CHECK(x) G_STMT_START{ \
@@ -33,31 +31,6 @@
} \
}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[])
{
@@ -65,8 +38,10 @@ main (int argc, char *argv[])
GOptionContext *ctx;
DFBSurfaceDescription dsc;
SwfdecPlayer *player;
+ SwfdecDfbRenderer *renderer;
guint w, h;
- Data data;
+ IDirectFB *dfb;
+ IDirectFBSurface *surface;
/* config variables */
char *size = NULL;
@@ -94,38 +69,37 @@ main (int argc, char *argv[])
return 1;
}
- ERROR_CHECK (DirectFBCreate (&data.dfb));
- player = swfdec_dfb_player_new_from_file (data.dfb, argv[1]);
+ ERROR_CHECK (DirectFBCreate (&dfb));
+ player = swfdec_dfb_player_new_from_file (dfb, argv[1]);
+ dsc.flags = DSDESC_CAPS;
+ dsc.caps = DSCAPS_DOUBLE | DSCAPS_PRIMARY;
if (size) {
if (g_ascii_strcasecmp (size, "fullscreen") == 0) {
- ERROR_CHECK (data.dfb->SetCooperativeLevel (data.dfb, DFSCL_FULLSCREEN));
- dsc.flags = DSDESC_CAPS;
+ ERROR_CHECK (dfb->SetCooperativeLevel (dfb, DFSCL_FULLSCREEN));
} else if (sscanf (size, "%ux%u", &w, &h) == 2) {
- dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
+ dsc.flags |= DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT;
+ dsc.width = w;
+ dsc.height = h;
} else {
g_printerr ("invalid argument for --size specified\n");
g_object_unref (player);
return 1;
}
- } else {
- dsc.flags = DSDESC_CAPS;
}
- 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);
-
- ERROR_CHECK (data.dfbsurface->GetSize (data.dfbsurface, &dsc.width, &dsc.height));
- swfdec_player_set_size (player, dsc.width, dsc.height);
- render (player, &data, 0, 0, dsc.width, dsc.height);
+ ERROR_CHECK (dfb->CreateSurface (dfb, &dsc, &surface));
+ //ERROR_CHECK (surface->GetSize (surface, &dsc.width, &dsc.height));
+ //swfdec_player_set_size (player, dsc.width, dsc.height);
+ renderer = swfdec_dfb_renderer_new (dfb, surface, player);
- g_signal_connect (player, "invalidate", G_CALLBACK (invalidate), &data);
swfdec_dfb_player_set_playing (SWFDEC_DFB_PLAYER (player), TRUE);
swfdec_dfb_main ();
+ g_object_unref (renderer);
+ g_object_unref (player);
+ surface->Release (surface);
+ dfb->Release (dfb);
return 0;
}
diff --git a/swfdec-directfb/Makefile.am b/swfdec-directfb/Makefile.am
index c23a890..ca37298 100644
--- a/swfdec-directfb/Makefile.am
+++ b/swfdec-directfb/Makefile.am
@@ -3,7 +3,8 @@ lib_LTLIBRARIES = libswfdec-directfb-@SWFDEC_MAJORMINOR@.la
libswfdec_directfb_@SWFDEC_MAJORMINOR@_la_SOURCES = \
swfdec_source.c \
swfdec_directfb_main.c \
- swfdec_directfb_player.c
+ swfdec_directfb_player.c \
+ swfdec_directfb_renderer.c
noinst_HEADERS = \
swfdec_source.h
@@ -22,5 +23,6 @@ libswfdec_@SWFDEC_MAJORMINOR@includedir = $(includedir)/swfdec-@SWFDEC_MAJORMINO
libswfdec_@SWFDEC_MAJORMINOR@include_HEADERS = \
swfdec-directfb.h \
swfdec_directfb_main.h \
- swfdec_directfb_player.h
+ swfdec_directfb_player.h \
+ swfdec_directfb_renderer.h
diff --git a/swfdec-directfb/swfdec-directfb.h b/swfdec-directfb/swfdec-directfb.h
index 1091919..fd92227 100644
--- a/swfdec-directfb/swfdec-directfb.h
+++ b/swfdec-directfb/swfdec-directfb.h
@@ -22,5 +22,6 @@
#include <swfdec-directfb/swfdec_directfb_main.h>
#include <swfdec-directfb/swfdec_directfb_player.h>
+#include <swfdec-directfb/swfdec_directfb_renderer.h>
#endif
diff --git a/swfdec-directfb/swfdec_directfb_player.h b/swfdec-directfb/swfdec_directfb_player.h
index 16a6765..72b3693 100644
--- a/swfdec-directfb/swfdec_directfb_player.h
+++ b/swfdec-directfb/swfdec_directfb_player.h
@@ -41,6 +41,7 @@ struct _SwfdecDfbPlayer
IDirectFB * dfb; /* the DirectFB object we play on */
+ /* properties */
GSource * source; /* source if playing, NULL otherwise */
gboolean audio_enabled; /* TRUE if audio should be played */
double speed; /* desired playback speed */
diff --git a/swfdec-directfb/swfdec_directfb_renderer.c b/swfdec-directfb/swfdec_directfb_renderer.c
new file mode 100644
index 0000000..f78f7ef
--- /dev/null
+++ b/swfdec-directfb/swfdec_directfb_renderer.c
@@ -0,0 +1,137 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "swfdec-directfb/swfdec_directfb_renderer.h"
+#include <cairo-directfb.h>
+
+G_DEFINE_TYPE (SwfdecDfbRenderer, swfdec_dfb_renderer, G_TYPE_OBJECT)
+
+static void
+swfdec_dfb_renderer_dispose (GObject *object)
+{
+ SwfdecDfbRenderer *renderer = SWFDEC_DFB_RENDERER (object);
+
+ if (renderer->dfb) {
+ renderer->dfb->Release (renderer->dfb);
+ renderer->dfb = NULL;
+ }
+ if (renderer->surface) {
+ cairo_surface_destroy (renderer->surface);
+ renderer->surface = NULL;
+ renderer->dfbsurface = NULL;
+ }
+ if (renderer->player) {
+ g_object_unref (renderer->player);
+ renderer->player = NULL;
+ }
+
+ G_OBJECT_CLASS (swfdec_dfb_renderer_parent_class)->dispose (object);
+}
+
+static void
+swfdec_dfb_renderer_class_init (SwfdecDfbRendererClass * g_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (g_class);
+
+ object_class->dispose = swfdec_dfb_renderer_dispose;
+}
+
+static void
+swfdec_dfb_renderer_init (SwfdecDfbRenderer * renderer)
+{
+}
+
+/*** PUBLIC API ***/
+
+static gboolean
+swfdec_dfb_renderer_do_render (gpointer rendererp)
+{
+ SwfdecDfbRenderer *renderer = rendererp;
+
+ renderer->repaint_id = 0;
+ swfdec_dfb_renderer_render (renderer,
+ renderer->repaint_area.x, renderer->repaint_area.y,
+ renderer->repaint_area.width, renderer->repaint_area.height);
+ return FALSE;
+}
+
+static void
+swfdec_dfb_renderer_queue_repaint (SwfdecDfbRenderer *renderer, const SwfdecRectangle *rect)
+{
+ if (renderer->repaint_id) {
+ swfdec_rectangle_union (&renderer->repaint_area, &renderer->repaint_area, rect);
+ } else {
+ renderer->repaint_area = *rect;
+ renderer->repaint_id = g_idle_add (swfdec_dfb_renderer_do_render, renderer);
+ }
+}
+
+static void
+swfdec_dfb_renderer_invalidate_cb (SwfdecPlayer *player, const SwfdecRectangle *extents,
+ const SwfdecRectangle *rects, guint n_rects, SwfdecDfbRenderer *renderer)
+{
+ swfdec_dfb_renderer_queue_repaint (renderer, extents);
+}
+
+SwfdecDfbRenderer *
+swfdec_dfb_renderer_new (IDirectFB *dfb, IDirectFBSurface *surface,
+ SwfdecPlayer *player)
+{
+ SwfdecDfbRenderer *renderer;
+
+ g_return_val_if_fail (dfb != NULL, NULL);
+ g_return_val_if_fail (surface != NULL, NULL);
+ g_return_val_if_fail (SWFDEC_IS_PLAYER (player), NULL);
+
+ renderer = g_object_new (SWFDEC_TYPE_DFB_RENDERER, NULL);
+ dfb->AddRef (dfb);
+ renderer->dfb = dfb;
+ renderer->dfbsurface = surface;
+ renderer->surface = cairo_directfb_surface_create (dfb, surface);
+ surface->GetSize (surface, &renderer->width, &renderer->height);
+ renderer->player = g_object_ref (player);
+ g_signal_connect (player, "invalidate", G_CALLBACK (swfdec_dfb_renderer_invalidate_cb), renderer);
+
+ return renderer;
+}
+
+void
+swfdec_dfb_renderer_render (SwfdecDfbRenderer *renderer, int x, int y,
+ int width, int height)
+{
+ DFBRegion region = { x, y, x + width - 1, y + height - 1 };
+ cairo_t *cr;
+
+ g_return_if_fail (SWFDEC_IS_DFB_RENDERER (renderer));
+ g_return_if_fail (x >= 0);
+ g_return_if_fail (y >= 0);
+ g_return_if_fail (width > 0);
+ g_return_if_fail (height > 0);
+ g_return_if_fail (x + width <= renderer->width);
+ g_return_if_fail (y + height <= renderer->height);
+
+ cr = cairo_create (renderer->surface);
+ swfdec_player_render (renderer->player, cr, x, y, width, height);
+ cairo_destroy (cr);
+ renderer->dfbsurface->Flip (renderer->dfbsurface, &region, DSFLIP_ONSYNC);
+}
diff --git a/swfdec-directfb/swfdec_directfb_renderer.h b/swfdec-directfb/swfdec_directfb_renderer.h
new file mode 100644
index 0000000..7917f22
--- /dev/null
+++ b/swfdec-directfb/swfdec_directfb_renderer.h
@@ -0,0 +1,73 @@
+/* Swfdec
+ * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef _SWFDEC_DFB_RENDERER_H_
+#define _SWFDEC_DFB_RENDERER_H_
+
+#include <libswfdec/swfdec.h>
+#include <directfb.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SwfdecDfbRenderer SwfdecDfbRenderer;
+typedef struct _SwfdecDfbRendererClass SwfdecDfbRendererClass;
+
+#define SWFDEC_TYPE_DFB_RENDERER (swfdec_dfb_renderer_get_type())
+#define SWFDEC_IS_DFB_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SWFDEC_TYPE_DFB_RENDERER))
+#define SWFDEC_IS_DFB_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SWFDEC_TYPE_DFB_RENDERER))
+#define SWFDEC_DFB_RENDERER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SWFDEC_TYPE_DFB_RENDERER, SwfdecDfbRenderer))
+#define SWFDEC_DFB_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SWFDEC_TYPE_DFB_RENDERER, SwfdecDfbRendererClass))
+#define SWFDEC_DFB_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SWFDEC_TYPE_DFB_RENDERER, SwfdecDfbRendererClass))
+
+struct _SwfdecDfbRenderer
+{
+ GObject * object;
+
+ IDirectFB * dfb; /* the DirectFB object we play on */
+ SwfdecPlayer * player; /* the player we display */
+
+ IDirectFBSurface * dfbsurface; /* surface we render to (reference held by cairo surface) */
+ cairo_surface_t * surface; /* same in cairo terms (we reference it) */
+ SwfdecRectangle repaint_area; /* rectange that needs repainting */
+ guint repaint_id; /* ID of source for repainting or 0 if none */
+ /* cached values */
+ int width;
+ int height;
+};
+
+struct _SwfdecDfbRendererClass
+{
+ GObjectClass object_class;
+};
+
+GType swfdec_dfb_renderer_get_type (void);
+
+SwfdecDfbRenderer * swfdec_dfb_renderer_new (IDirectFB * dfb,
+ IDirectFBSurface * surface,
+ SwfdecPlayer * player);
+
+void swfdec_dfb_renderer_render (SwfdecDfbRenderer * renderer,
+ int x,
+ int y,
+ int width,
+ int height);
+
+
+G_END_DECLS
+#endif