diff options
author | Benjamin Otte <otte@gnome.org> | 2007-12-13 16:17:08 +0100 |
---|---|---|
committer | Benjamin Otte <otte@gnome.org> | 2007-12-13 16:17:08 +0100 |
commit | 6a22a70a1ccc3c286b559b0ae99df240307324d0 (patch) | |
tree | 02c9fbf96b05a4de3f5678ea8767c5180976f3d5 | |
parent | f41c2e1f0ba9d3b7f22705401b0061411dcb17ef (diff) |
seperate out the renderer functionality
-rw-r--r-- | player/main.c | 64 | ||||
-rw-r--r-- | swfdec-directfb/Makefile.am | 6 | ||||
-rw-r--r-- | swfdec-directfb/swfdec-directfb.h | 1 | ||||
-rw-r--r-- | swfdec-directfb/swfdec_directfb_player.h | 1 | ||||
-rw-r--r-- | swfdec-directfb/swfdec_directfb_renderer.c | 137 | ||||
-rw-r--r-- | swfdec-directfb/swfdec_directfb_renderer.h | 73 |
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, ®ion, 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, ®ion, 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 |