summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--swfdec-directfb/swfdec_directfb_renderer.c74
-rw-r--r--swfdec-directfb/swfdec_directfb_renderer.h10
2 files changed, 38 insertions, 46 deletions
diff --git a/swfdec-directfb/swfdec_directfb_renderer.c b/swfdec-directfb/swfdec_directfb_renderer.c
index 4ee98cc..e9b3667 100644
--- a/swfdec-directfb/swfdec_directfb_renderer.c
+++ b/swfdec-directfb/swfdec_directfb_renderer.c
@@ -1,5 +1,5 @@
/* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ * Copyright (C) 2007-2008 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
@@ -44,6 +44,10 @@ swfdec_dfb_renderer_dispose (GObject *object)
g_object_unref (renderer->player);
renderer->player = NULL;
}
+ if (renderer->repaint_area) {
+ g_array_free (renderer->repaint_area, TRUE);
+ renderer->repaint_area = NULL;
+ }
if (renderer->repaint_id) {
g_source_remove (renderer->repaint_id);
renderer->repaint_id = 0;
@@ -63,6 +67,7 @@ swfdec_dfb_renderer_class_init (SwfdecDfbRendererClass * g_class)
static void
swfdec_dfb_renderer_init (SwfdecDfbRenderer * renderer)
{
+ renderer->repaint_area = g_array_new (FALSE, FALSE, sizeof (SwfdecRectangle));
}
/*** PUBLIC API ***/
@@ -73,40 +78,20 @@ 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);
+ swfdec_dfb_renderer_render (renderer, (const SwfdecRectangle *) renderer->repaint_area->data,
+ renderer->repaint_area->len);
+ g_array_set_size (renderer->repaint_area, 0);
return FALSE;
}
static void
-swfdec_dfb_renderer_queue_repaint (SwfdecDfbRenderer *renderer, const SwfdecRectangle *rect)
+swfdec_dfb_renderer_queue_repaint (SwfdecDfbRenderer *renderer,
+ const SwfdecRectangle *rects, guint n_rects)
{
- if (renderer->repaint_id) {
- swfdec_rectangle_union (&renderer->repaint_area, &renderer->repaint_area, rect);
- } else {
- renderer->repaint_area = *rect;
+ if (!renderer->repaint_id) {
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)
-{
- SwfdecRectangle tmp = *extents;
-
- if (tmp.x + tmp.width > renderer->width) {
- if (tmp.x >= renderer->width)
- return;
- tmp.width = renderer->width - tmp.x;
- }
- if (tmp.y + tmp.height > renderer->height) {
- if (tmp.y >= renderer->height)
- return;
- tmp.height = renderer->height - tmp.y;
- }
- swfdec_dfb_renderer_queue_repaint (renderer, &tmp);
+ g_array_append_vals (renderer->repaint_area, rects, n_rects);
}
SwfdecDfbRenderer *
@@ -127,32 +112,41 @@ swfdec_dfb_renderer_new (IDirectFB *dfb, IDirectFBSurface *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);
+ g_signal_connect_swapped (player, "invalidate", G_CALLBACK (swfdec_dfb_renderer_queue_repaint), renderer);
rect.x = rect.y = 0;
rect.width = renderer->width;
rect.height = renderer->height;
- swfdec_dfb_renderer_queue_repaint (renderer, &rect);
+ swfdec_dfb_renderer_queue_repaint (renderer, &rect, 1);
return renderer;
}
void
-swfdec_dfb_renderer_render (SwfdecDfbRenderer *renderer, int x, int y,
- int width, int height)
+swfdec_dfb_renderer_render (SwfdecDfbRenderer *renderer,
+ const SwfdecRectangle *areas, guint n_areas)
{
- DFBRegion region = { x, y, x + width - 1, y + height - 1 };
+ DFBRegion region;
cairo_t *cr;
+ guint i;
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);
+ g_return_if_fail (n_areas > 0);
cr = cairo_create (renderer->surface);
- swfdec_player_render (renderer->player, cr, x, y, width, height);
+ /* FIXME: don't just accumulate, create a proper region here */
+ region.x1 = areas->x;
+ region.y1 = areas->y;
+ region.x2 = areas->x + areas->width - 1;
+ region.y2 = areas->y + areas->height - 1;
+ for (i = 1; i < n_areas; i++) {
+ region.x1 = MIN (region.x1, areas[i].x);
+ region.y1 = MIN (region.y1, areas[i].y);
+ region.x2 = MAX (region.x2, areas[i].x + areas[i].width - 1);
+ region.y2 = MAX (region.y2, areas[i].y + areas[i].height - 1);
+ }
+ cairo_rectangle (cr, region.x1, region.y1, region.x2 + 1 - region.x1, region.y2 + 1 - region.y1);
+ cairo_clip (cr);
+ swfdec_player_render (renderer->player, cr);
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
index 65a6240..606a3d2 100644
--- a/swfdec-directfb/swfdec_directfb_renderer.h
+++ b/swfdec-directfb/swfdec_directfb_renderer.h
@@ -1,5 +1,5 @@
/* Swfdec
- * Copyright (C) 2007 Benjamin Otte <otte@gnome.org>
+ * Copyright (C) 2007-2008 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
@@ -44,7 +44,7 @@ struct _SwfdecDfbRenderer
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 */
+ GArray * repaint_area; /* SwfdecRectangle array that needs repainting */
guint repaint_id; /* ID of source for repainting or 0 if none */
/* cached values */
int width;
@@ -63,10 +63,8 @@ SwfdecDfbRenderer * swfdec_dfb_renderer_new (IDirectFB * dfb,
SwfdecPlayer * player);
void swfdec_dfb_renderer_render (SwfdecDfbRenderer * renderer,
- int x,
- int y,
- int width,
- int height);
+ const SwfdecRectangle *rects,
+ guint n_rects);
G_END_DECLS