Commit 2d20a495 authored by Attilio Fiandrotti's avatar Attilio Fiandrotti

Committed several patches by Denis Oliver Knoppwhich are expected to improve...

Committed several patches by Denis Oliver Knoppwhich are expected to improve the performance of the DirectFB backend

svn path=/trunk/; revision=19132
parent 48541776
2007-12-09 09:56:06 Attilio Fiandrotti <attilio.fiandrotti@gmail.com>
* gdk/directfb/gdkgc-directfb.c:
* gdk/directfb/gdkdrawable-directfb.c:
* gdk/directfb/gdkdirectfb.h:
* gdk/directfb/gdkwindow-directfb.c:
* gdk/directfb/gdkprivate-directfb.h: Committed several patches
(window_flip_group, no_background_pixmap_fix, opt_temp_region2,
blit_after_cairo_fix, rect_clip_fix, fast_blend, opt_temp_region_etc,
opt_clip_region_and_fill_rects, no_state_resets) by Denis Oliver Knopp
which are expected to improve the performance of the DirectFB backend.
Experimental pieces of code (GDK_DIRECTFB_NO_EXPERIMENTS) are disabled.
2007-12-07 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkcontainer.c: Correct the documentation of child
......
......@@ -33,6 +33,11 @@
#ifndef __GDK_DIRECTFB_H__
#define __GDK_DIRECTFB_H__
/* This define disables some experimental code
*/
#ifndef GDK_DIRECTFB_NO_EXPERIMENTS
#define GDK_DIRECTFB_NO_EXPERIMENTS
#include <cairo.h>
#include <directfb.h>
#include "gdk/gdkprivate.h"
......
This diff is collapsed.
......@@ -113,8 +113,8 @@ gdk_gc_directfb_finalize (GObject *object)
GdkGC *gc = GDK_GC (object);
GdkGCDirectFB *private = GDK_GC_DIRECTFB (gc);
if (private->clip_region)
gdk_region_destroy (private->clip_region);
if (private->clip_region.numRects)
temp_region_deinit (&private->clip_region);
if (private->values.clip_mask)
g_object_unref (private->values.clip_mask);
if (private->values.stipple)
......@@ -262,11 +262,7 @@ gdk_directfb_gc_set_values (GdkGC *gc,
if (oldpm)
g_object_unref (oldpm);
if (private->clip_region)
{
gdk_region_destroy (private->clip_region);
private->clip_region = NULL;
}
temp_region_reset (&private->clip_region);
}
if (values_mask & GDK_GC_SUBWINDOW)
......@@ -363,17 +359,13 @@ _gdk_windowing_gc_set_clip_region (GdkGC *gc,
data = GDK_GC_DIRECTFB (gc);
if (region == data->clip_region)
if (region == &data->clip_region)
return;
if (data->clip_region)
{
gdk_region_destroy (data->clip_region);
data->clip_region = NULL;
}
if (region)
data->clip_region = gdk_region_copy (region);
temp_region_init_copy (&data->clip_region, region);
else
temp_region_reset (&data->clip_region);
gc->clip_x_origin = 0;
gc->clip_y_origin = 0;
......@@ -394,8 +386,7 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc,
dst_private = GDK_GC_DIRECTFB (dst_gc);
if (dst_private->clip_region)
gdk_region_destroy(dst_private->clip_region);
temp_region_reset(&dst_private->clip_region);
if (dst_private->values_mask & GDK_GC_FONT)
gdk_font_unref (dst_private->values.font);
......@@ -415,8 +406,6 @@ _gdk_windowing_gc_copy (GdkGC *dst_gc,
g_object_ref (dst_private->values.stipple);
if (dst_private->values_mask & GDK_GC_CLIP_MASK)
g_object_ref (dst_private->values.clip_mask);
if (dst_private->clip_region)
dst_private->clip_region = gdk_region_copy (dst_private->clip_region);
}
/**
......
......@@ -38,8 +38,12 @@
#include "gdkinternals.h"
#include "gdkcursor.h"
#include "gdkdisplay-directfb.h"
#include "gdkregion-generic.h"
#include <cairo.h>
#include <string.h>
#include <directfb_util.h>
#define GDK_TYPE_DRAWABLE_IMPL_DIRECTFB (gdk_drawable_impl_directfb_get_type ())
......@@ -68,13 +72,15 @@ struct _GdkDrawableImplDirectFB
gboolean buffered;
GdkRegion *paint_region;
GdkRegion paint_region;
gint paint_depth;
gint width;
gint height;
gint abs_x;
gint abs_y;
GdkRegion clip_region;
GdkColormap *colormap;
IDirectFBSurface *surface;
......@@ -151,6 +157,9 @@ struct _GdkWindowImplDirectFB
guint8 opacity;
GdkWindowTypeHint type_hint;
DFBUpdates flips;
DFBRegion flip_regions[4];
};
typedef struct
......@@ -204,7 +213,7 @@ typedef struct
{
GdkGC parent_instance;
GdkRegion *clip_region;
GdkRegion clip_region;
GdkGCValuesMask values_mask;
GdkGCValues values;
......@@ -317,5 +326,88 @@ void gdk_fb_window_set_child_handler (GdkWindow *window,
GdkWindowChildGetPos get_pos,
gpointer user_data);
void gdk_directfb_clip_region (GdkDrawable *drawable,
GdkGC *gc,
GdkRectangle *draw_rect,
GdkRegion *ret_clip);
/* Utilities for avoiding mallocs */
static inline void
temp_region_init_copy( GdkRegion *region,
const GdkRegion *source)
{
if (region != source) /* don't want to copy to itself */
{
if (region->size < source->numRects)
{
if (region->rects && region->rects != &region->extents)
g_free( region->rects );
region->rects = g_new (GdkRegionBox, source->numRects);
region->size = source->numRects;
}
region->numRects = source->numRects;
region->extents = source->extents;
memcpy( region->rects, source->rects, source->numRects * sizeof (GdkRegionBox) );
}
}
static inline void
temp_region_init_rectangle( GdkRegion *region,
const GdkRectangle *rect )
{
region->numRects = 1;
region->rects = &region->extents;
region->extents.x1 = rect->x;
region->extents.y1 = rect->y;
region->extents.x2 = rect->x + rect->width;
region->extents.y2 = rect->y + rect->height;
region->size = 1;
}
static inline void
temp_region_init_rectangle_vals( GdkRegion *region,
int x,
int y,
int w,
int h )
{
region->numRects = 1;
region->rects = &region->extents;
region->extents.x1 = x;
region->extents.y1 = y;
region->extents.x2 = x + w;
region->extents.y2 = y + h;
region->size = 1;
}
static inline void
temp_region_reset( GdkRegion *region )
{
if (region->size > 32 && region->rects && region->rects != &region->extents) {
g_free( region->rects );
region->size = 1;
region->rects = &region->extents;
}
region->numRects = 0;
}
static inline void
temp_region_deinit( GdkRegion *region )
{
if (region->rects && region->rects != &region->extents) {
g_free( region->rects );
region->rects = NULL;
}
region->numRects = 0;
}
#endif /* __GDK_PRIVATE_DIRECTFB_H__ */
......@@ -46,6 +46,8 @@
#include "cairo.h"
#include <assert.h>
#include <directfb_util.h>
static GdkRegion * gdk_window_impl_directfb_get_visible_region (GdkDrawable *drawable);
static void gdk_window_impl_directfb_set_colormap (GdkDrawable *drawable,
GdkColormap *colormap);
......@@ -93,6 +95,35 @@ gdk_window_directfb_process_all_updates (void)
tmp_list = tmp_list->next;
}
#ifndef GDK_DIRECTFB_NO_EXPERIMENTS
tmp_list = old_update_windows;
g_slist_foreach (old_update_windows, (GFunc)g_object_ref, NULL);
while (tmp_list) {
GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( tmp_list->data ) );
if (top) {
GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
if (wimpl->flips.num_regions) {
//direct_log_printf( NULL, "Flipping bounding box of paints: %d,%d - %dx%d (top %p, wimpl %p)\n",
// DFB_RECTANGLE_VALS_FROM_REGION( &wimpl->flips.bounding ), top, wimpl );
wimpl->drawable.surface->Flip( wimpl->drawable.surface, &wimpl->flips.bounding, DSFLIP_NONE );
dfb_updates_reset( &wimpl->flips );
}
}
g_object_unref (tmp_list->data);
tmp_list = tmp_list->next;
}
#endif
g_slist_free (old_update_windows);
}
......@@ -311,6 +342,12 @@ create_directfb_window (GdkWindowImplDirectFB *impl,
impl->window = window;
#ifndef GDK_DIRECTFB_NO_EXPERIMENTS
//direct_log_printf( NULL, "Initializing (window %p, wimpl %p)\n", win, impl );
dfb_updates_init( &impl->flips, impl->flip_regions, G_N_ELEMENTS(impl->flip_regions) );
#endif
return TRUE;
}
......@@ -333,7 +370,7 @@ _gdk_windowing_window_init (void)
private->window_type = GDK_WINDOW_ROOT;
private->state = 0;
private->children = NULL;
impl->drawable.paint_region = NULL;
// impl->drawable.paint_region = NULL;
impl->gdkWindow = _gdk_parent_root;
impl->window = NULL;
impl->drawable.abs_x = 0;
......@@ -1797,10 +1834,15 @@ gdk_window_set_back_pixmap (GdkWindow *window,
}
else
{
if (pixmap && pixmap != GDK_NO_BG && pixmap != GDK_PARENT_RELATIVE_BG)
g_object_ref (pixmap);
private->bg_pixmap = pixmap;
if (pixmap)
{
g_object_ref (pixmap);
private->bg_pixmap = pixmap;
}
else
{
private->bg_pixmap = GDK_NO_BG;
}
}
}
......@@ -2777,9 +2819,9 @@ gdk_window_set_urgency_hint (GdkWindow *window,
static void
gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable *paintable,
GdkRegion *region,
gboolean (*child_func) (GdkWindow *, gpointer),
gpointer user_data)
GdkRegion *region,
gboolean (*child_func) (GdkWindow *, gpointer),
gpointer user_data)
{
GdkWindow *window;
GdkWindowObject *private;
......@@ -2791,7 +2833,7 @@ gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable *paintable,
window = wimpl->gdkWindow;
private = (GdkWindowObject *)window;
GdkRegion *visible_region;
GdkRegion visible_region;
GList *tmp_list;
g_return_if_fail (window != NULL);
......@@ -2803,69 +2845,65 @@ gdk_window_impl_directfb_invalidate_maybe_recurse (GdkPaintable *paintable,
if (private->input_only || !GDK_WINDOW_IS_MAPPED (window))
return;
visible_region = gdk_drawable_get_visible_region (window);
gdk_region_intersect (visible_region, region);
temp_region_init_rectangle_vals( &visible_region, 0, 0, impl->width, impl->height );
gdk_region_intersect (&visible_region, region);
tmp_list = private->children;
while (tmp_list)
{
GdkWindowObject *child = tmp_list->data;
GdkWindowObject *child = tmp_list->data;
GdkDrawableImplDirectFB *cimpl = (GdkDrawableImplDirectFB *) child->impl;
if (!child->input_only)
{
GdkRegion *child_region;
GdkRectangle child_rect;
gdk_window_get_position ((GdkWindow *)child,
&child_rect.x, &child_rect.y);
gdk_drawable_get_size ((GdkDrawable *)child,
&child_rect.width, &child_rect.height);
child_region = gdk_region_rectangle (&child_rect);
/* remove child area from the invalid area of the parent */
if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
gdk_region_subtract (visible_region, child_region);
if (child_func && (*child_func) ((GdkWindow *)child, user_data))
{
gdk_region_offset (region, - child_rect.x, - child_rect.y);
gdk_region_offset (child_region, - child_rect.x, - child_rect.y);
gdk_region_intersect (child_region, region);
gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
child_region, child_func, user_data);
gdk_region_offset (region, child_rect.x, child_rect.y);
}
gdk_region_destroy (child_region);
}
{
GdkRegion child_region;
temp_region_init_rectangle_vals( &child_region, child->x, child->y, cimpl->width, cimpl->height );
/* remove child area from the invalid area of the parent */
if (GDK_WINDOW_IS_MAPPED (child) && !child->shaped)
gdk_region_subtract (&visible_region, &child_region);
if (child_func && (*child_func) ((GdkWindow *)child, user_data))
{
gdk_region_offset (region, - child->x, - child->y);
gdk_region_offset (&child_region, - child->x, - child->y);
gdk_region_intersect (&child_region, region);
gdk_window_invalidate_maybe_recurse ((GdkWindow *)child,
&child_region, child_func, user_data);
gdk_region_offset (region, child->x, child->y);
}
temp_region_deinit( &child_region );
}
tmp_list = tmp_list->next;
}
if (!gdk_region_empty (visible_region))
if (!gdk_region_empty (&visible_region))
{
if (private->update_area)
{
gdk_region_union (private->update_area, visible_region);
}
{
gdk_region_union (private->update_area, &visible_region);
}
else
{
update_windows = g_slist_prepend (update_windows, window);
private->update_area = gdk_region_copy (visible_region);
gdk_window_schedule_update (window);
}
{
update_windows = g_slist_prepend (update_windows, window);
private->update_area = gdk_region_copy (&visible_region);
gdk_window_schedule_update (window);
}
}
gdk_region_destroy (visible_region);
temp_region_deinit( &visible_region );
}
static void
gdk_window_impl_directfb_process_updates (GdkPaintable *paintable,
gboolean update_children)
gboolean update_children)
{
GdkWindow *window;
GdkWindowObject *private;
......@@ -2888,58 +2926,49 @@ gdk_window_impl_directfb_process_updates (GdkPaintable *paintable,
private->update_area = NULL;
if (_gdk_event_func && gdk_window_is_viewable (window))
{
GdkRectangle window_rect;
GdkRegion *expose_region;
GdkRegion *window_region;
gint width, height;
save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
if (save_region)
expose_region = gdk_region_copy (update_area);
else
expose_region = update_area;
gdk_drawable_get_size (GDK_DRAWABLE (private), &width, &height);
window_rect.x = 0;
window_rect.y = 0;
window_rect.width = width;
window_rect.height = height;
window_region = gdk_region_rectangle (&window_rect);
gdk_region_intersect (expose_region,
window_region);
gdk_region_destroy (window_region);
if (!gdk_region_empty (expose_region) &&
(private->event_mask & GDK_EXPOSURE_MASK))
{
GdkEvent event;
event.expose.type = GDK_EXPOSE;
event.expose.window = g_object_ref (window);
event.expose.send_event = FALSE;
event.expose.count = 0;
event.expose.region = expose_region;
gdk_region_get_clipbox (expose_region, &event.expose.area);
(*_gdk_event_func) (&event, _gdk_event_data);
g_object_unref (window);
}
if (expose_region != update_area)
gdk_region_destroy (expose_region);
}
{
GdkRegion *expose_region;
GdkRegion window_region;
save_region = _gdk_windowing_window_queue_antiexpose (window, update_area);
if (save_region)
expose_region = gdk_region_copy (update_area);
else
expose_region = update_area;
temp_region_init_rectangle_vals( &window_region, 0, 0, impl->width, impl->height );
gdk_region_intersect (expose_region,
&window_region);
temp_region_deinit (&window_region);
if (!gdk_region_empty (expose_region) &&
(private->event_mask & GDK_EXPOSURE_MASK))
{
GdkEvent event;
event.expose.type = GDK_EXPOSE;
event.expose.window = g_object_ref (window);
event.expose.send_event = FALSE;
event.expose.count = 0;
event.expose.region = expose_region;
gdk_region_get_clipbox (expose_region, &event.expose.area);
(*_gdk_event_func) (&event, _gdk_event_data);
g_object_unref (window);
}
if (expose_region != update_area)
gdk_region_destroy (expose_region);
}
if (!save_region)
gdk_region_destroy (update_area);
gdk_region_destroy (update_area);
}
}
static void
gdk_window_impl_directfb_begin_paint_region (GdkPaintable *paintable,
GdkRegion *region)
GdkRegion *region)
{
GdkDrawableImplDirectFB *impl;
GdkWindowImplDirectFB *wimpl;
......@@ -2949,16 +2978,29 @@ gdk_window_impl_directfb_begin_paint_region (GdkPaintable *paintable,
g_assert (region != NULL );
wimpl = GDK_WINDOW_IMPL_DIRECTFB (paintable);
impl = (GdkDrawableImplDirectFB *)wimpl;
impl->buffered = TRUE;
impl->paint_depth++;
if (!region)
return;
if (impl->paint_region)
gdk_region_union (impl->paint_region, region);
else
impl->paint_region = gdk_region_copy (region);
if (impl->buffered) {
g_assert( impl->paint_depth > 0 );
gdk_region_union (&impl->paint_region, region);
}
else {
g_assert( impl->paint_depth == 0 );
gdk_directfb_clip_region( GDK_DRAWABLE(paintable), NULL, NULL, &impl->clip_region );
temp_region_init_copy( &impl->paint_region, region );
impl->buffered = TRUE;
}
gdk_region_intersect (&impl->paint_region, &impl->clip_region);
impl->paint_depth++;
for (i = 0; i < region->numRects; i++)
{
......@@ -2982,24 +3024,59 @@ gdk_window_impl_directfb_end_paint (GdkPaintable *paintable)
g_return_if_fail (impl->paint_depth > 0);
g_assert( impl->buffered );
impl->paint_depth--;
#ifdef GDK_DIRECTFB_NO_EXPERIMENTS
if (impl->paint_depth == 0)
{
impl->buffered = FALSE;
if (impl->paint_region)
if (impl->paint_region.numRects)
{
DFBRegion reg = { impl->paint_region->extents.x1,
impl->paint_region->extents.y1,
impl->paint_region->extents.x2 ,
impl->paint_region->extents.y2 };
impl->surface->Flip(impl->surface, &reg,0);
gdk_region_destroy (impl->paint_region);
impl->paint_region = NULL;
DFBRegion reg = { impl->paint_region.extents.x1,
impl->paint_region.extents.y1,
impl->paint_region.extents.x2 ,
impl->paint_region.extents.y2 };
impl->surface->Flip( impl->surface, &reg, 0 );
temp_region_reset( &impl->paint_region );
}
}
#else
if (impl->paint_depth == 0) {
impl->buffered = FALSE;
temp_region_deinit( &impl->clip_region );
if (impl->paint_region.numRects) {
GdkWindow *window = GDK_WINDOW( impl->wrapper );
if (GDK_IS_WINDOW(window)) {
GdkWindowObject *top = GDK_WINDOW_OBJECT( gdk_window_get_toplevel( window ) );
if (top) {
DFBRegion reg;
GdkWindowImplDirectFB *wimpl = GDK_WINDOW_IMPL_DIRECTFB (top->impl);
reg.x1 = impl->abs_x - top->x + impl->paint_region.extents.x1;
reg.y1 = impl->abs_y - top->y + impl->paint_region.extents.y1;
reg.x2 = impl->abs_x - top->x + impl->paint_region.extents.x2 - 1;
reg.y2 = impl->abs_y - top->y + impl->paint_region.extents.y2 - 1;
//direct_log_printf( NULL, "Adding bounding box of paint: %d,%d - %dx%d (top %p, wimpl %p)\n",
// DFB_RECTANGLE_VALS_FROM_REGION( &reg ), top, wimpl );
dfb_updates_add( &wimpl->flips, &reg );
}
}
temp_region_reset( &impl->paint_region );
}
}
#endif
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment