canvas: Allow invalidating the content along with the size

Currently, clutter_canvas_set_size() causes invalidation of the canvas
contents only if the newly set size is different. There are cases when
we want to invalidate the content regardless of the size set, but we
cannot do that right now without possibly causing two invalidations,
for instance:

  clutter_canvas_set_size (canvas, new_width, new_height);
  clutter_content_invalidate (canvas);

will cause two invalidations if the newly set size is different than
the existing one. One way to work around it is to check the current
size of the canvas and either call set_size() or invalidate() depending
on whether the size differs or not, respectively:

  g_object_get (canvas, "width", &width, "height", &height, NULL);
  if (width != new_width || height != new_height)
    clutter_canvas_set_size (canvas, new_width, new_height);
  else
    clutter_content_invalidate (canvas);

this, howevere, implies knowledge of the internals of ClutterCanvas,
and of its optimizations — and encodes a certain behaviour in third
party code, which makes changes further down the line harder.

We could remove the optimization, and just issue an invalidation
regardless of the surface size, but it's not something I'd be happy to
do. Instead, we can add a new function specifically for ClutterCanvas
that causes a forced invalidation regardless of the size change. If we
ever decide to remove the optimization further down the road, we can
simply deprecate the function, and make it an alias of invalidate()
or set_size().
This commit is contained in:
Emmanuele Bassi 2013-04-11 13:05:03 +01:00
parent dc5284681c
commit 264c67c2aa
2 changed files with 64 additions and 25 deletions

View File

@ -494,28 +494,14 @@ clutter_canvas_new (void)
return g_object_new (CLUTTER_TYPE_CANVAS, NULL);
}
/**
* clutter_canvas_set_size:
* @canvas: a #ClutterCanvas
* @width: the width of the canvas, in pixels
* @height: the height of the canvas, in pixels
*
* Sets the size of the @canvas.
*
* This function will cause the @canvas to be invalidated.
*
* Since: 1.10
*/
void
clutter_canvas_set_size (ClutterCanvas *canvas,
int width,
int height)
static inline void
clutter_canvas_invalidate_internal (ClutterCanvas *canvas,
int width,
int height,
gboolean force_invalidate)
{
GObject *obj;
gboolean width_changed = FALSE, height_changed = FALSE;
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (width >= -1 && height >= -1);
GObject *obj;
obj = G_OBJECT (canvas);
@ -537,8 +523,56 @@ clutter_canvas_set_size (ClutterCanvas *canvas,
g_object_notify_by_pspec (obj, obj_props[PROP_HEIGHT]);
}
if (width_changed || height_changed)
if (force_invalidate || (width_changed || height_changed))
clutter_content_invalidate (CLUTTER_CONTENT (canvas));
g_object_thaw_notify (obj);
}
/**
* clutter_canvas_set_size:
* @canvas: a #ClutterCanvas
* @width: the width of the canvas, in pixels
* @height: the height of the canvas, in pixels
*
* Sets the size of the @canvas, and invalidates the content.
*
* This function will cause the @canvas to be invalidated only
* if the size of the canvas surface has changed.
*
* Since: 1.10
*/
void
clutter_canvas_set_size (ClutterCanvas *canvas,
int width,
int height)
{
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (width >= -1 && height >= -1);
clutter_canvas_invalidate_internal (canvas, width, height, FALSE);
}
/**
* clutter_canvas_invalidate_with_size:
* @canvas: a #ClutterCanvas
* @width: the width of the canvas, in pixels
* @height: the height of the canvas, in pixels
*
* Sets the size of the @canvas, and invalidates the content.
*
* This function will cause the @canvas to be invalidated regardless
* of the size change.
*
* Since: 1.16
*/
void
clutter_canvas_invalidate_with_size (ClutterCanvas *canvas,
int width,
int height)
{
g_return_if_fail (CLUTTER_IS_CANVAS (canvas));
g_return_if_fail (width >= -1 && height >= -1);
clutter_canvas_invalidate_internal (canvas, width, height, TRUE);
}

View File

@ -89,11 +89,16 @@ CLUTTER_AVAILABLE_IN_1_10
GType clutter_canvas_get_type (void) G_GNUC_CONST;
CLUTTER_AVAILABLE_IN_1_10
ClutterContent * clutter_canvas_new (void);
ClutterContent * clutter_canvas_new (void);
CLUTTER_AVAILABLE_IN_1_10
void clutter_canvas_set_size (ClutterCanvas *canvas,
int width,
int height);
void clutter_canvas_set_size (ClutterCanvas *canvas,
int width,
int height);
CLUTTER_AVAILABLE_IN_1_16
void clutter_canvas_invalidate_with_size (ClutterCanvas *canvas,
int width,
int height);
G_END_DECLS