From 3183240fef315bb8be2391eac7b714520da88bd6 Mon Sep 17 00:00:00 2001 From: Robert Bragg Date: Tue, 12 Jul 2011 01:11:51 +0100 Subject: [PATCH] Provide stable paint-boxes for fixed sized actors This updates _clutter_paint_volume_get_stage_paint_box to try and calculate more stable paint-box sizes for fixed sized paint-volumes by not basing the size on the volume's sub-pixel position. So the aim is that for a given rectangle defined with floating point coordinates we want to determine a stable quantized size in pixels that doesn't vary due to the original box's sub-pixel position. The reason this is important is because effects will use this API to determine the size of offscreen framebuffers and so for a fixed-size object that may be animated across the screen we want to make sure that the stage paint-box has an equally stable size so that effects aren't made to continuously re-allocate a corresponding fbo. The other thing we consider is that the calculation of this box is subject to floating point precision issues that might be slightly different to the precision issues involved with actually painting the actor, which might result in painting slightly leaking outside the user's calculated paint-volume. This patch now adds padding to consider this too. Signed-off-by: Neil Roberts Signed-off-by: Emmanuele Bassi --- clutter/clutter-paint-volume.c | 49 +++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/clutter/clutter-paint-volume.c b/clutter/clutter-paint-volume.c index 7b01e244b..611d57f0d 100644 --- a/clutter/clutter-paint-volume.c +++ b/clutter/clutter-paint-volume.c @@ -31,6 +31,7 @@ #include #include +#include #include "clutter-actor-private.h" #include "clutter-paint-volume-private.h" @@ -1098,6 +1099,8 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv, CoglMatrix modelview; CoglMatrix projection; float viewport[4]; + float width; + float height; _clutter_paint_volume_copy_static (pv, &projected_pv); @@ -1121,7 +1124,51 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv, viewport); _clutter_paint_volume_get_bounding_box (&projected_pv, box); - clutter_actor_box_clamp_to_pixel (box); + + /* The aim here is that for a given rectangle defined with floating point + * coordinates we want to determine a stable quantized size in pixels + * that doesn't vary due to the original box's sub-pixel position. + * + * The reason this is important is because effects will use this + * API to determine the size of offscreen framebuffers and so for + * a fixed-size object that may be animated accross the screen we + * want to make sure that the stage paint-box has an equally stable + * size so that effects aren't made to continuously re-allocate + * a corresponding fbo. + * + * The other thing we consider is that the calculation of this box is + * subject to floating point precision issues that might be slightly + * different to the precision issues involved with actually painting the + * actor, which might result in painting slightly leaking outside the + * user's calculated paint-volume. For this we simply aim to pad out the + * paint-volume by at least half a pixel all the way around. + */ + width = box->x2 - box->x1; + height = box->y2 - box->y1; + width = CLUTTER_NEARBYINT (width); + height = CLUTTER_NEARBYINT (height); + /* XXX: NB the width/height may now be up to 0.5px too small so we + * must also pad by 0.25px all around to account for this. In total we + * must padd by at least 0.75px around all sides. */ + + /* XXX: The furthest that we can overshoot the bottom right corner by + * here is 1.75px in total if you consider that the 0.75 padding could + * just cross an integer boundary and so ceil will effectively add 1. + */ + box->x2 = ceilf (box->x2 + 0.75); + box->y2 = ceilf (box->y2 + 0.75); + + /* Now we redefine the top-left relative to the bottom right based on the + * rounded width/height determined above + a constant so that the overall + * size of the box will be stable and not dependant on the box's + * position. + * + * Adding 3px to the width/height will ensure we cover the maximum of + * 1.75px padding on the bottom/right and still ensure we have > 0.75px + * padding on the top/left. + */ + box->x1 = box->x2 - width - 3; + box->y1 = box->y2 - height - 3; clutter_paint_volume_free (&projected_pv); }