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 <neil@linux.intel.com>
Signed-off-by: Emmanuele Bassi <ebassi@linux.intel.com>
This commit is contained in:
Robert Bragg 2011-07-12 01:11:51 +01:00
parent df751a8a25
commit 3183240fef

View File

@ -31,6 +31,7 @@
#include <string.h> #include <string.h>
#include <glib-object.h> #include <glib-object.h>
#include <math.h>
#include "clutter-actor-private.h" #include "clutter-actor-private.h"
#include "clutter-paint-volume-private.h" #include "clutter-paint-volume-private.h"
@ -1098,6 +1099,8 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
CoglMatrix modelview; CoglMatrix modelview;
CoglMatrix projection; CoglMatrix projection;
float viewport[4]; float viewport[4];
float width;
float height;
_clutter_paint_volume_copy_static (pv, &projected_pv); _clutter_paint_volume_copy_static (pv, &projected_pv);
@ -1121,7 +1124,51 @@ _clutter_paint_volume_get_stage_paint_box (ClutterPaintVolume *pv,
viewport); viewport);
_clutter_paint_volume_get_bounding_box (&projected_pv, box); _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); clutter_paint_volume_free (&projected_pv);
} }