[Spice-devel] [PATCH xf86-video-qxl] Tune the dfps region tracking to collapse to the bounding rectangle if too many small, incremental, updates are provided.
Christophe Fergeau
cfergeau at redhat.com
Fri Sep 19 04:32:41 PDT 2014
Hey,
Looks good, ACK.
I would have split it one patch introducing dfps_update_{box,region}
with no functional change, and one patch adding the
DFPS_MAX_UPDATE_REGION limit.
Christophe
On Wed, Sep 10, 2014 at 12:26:26PM -0500, Jeremy White wrote:
> Attempting to use x11perf to measure performance revealed a fairly
> serious weakness in the dfps code in that use case. In between
> fps ticks, the updated_region would grow to have thousands of
> rectangles, which made processing extraordinarily slow.
>
> This patch provides a cap on the number of rectangles inside
> a region; once it reaches the cap, we collapse the update_region
> to just transmit the bounding rectangle instead.
>
> Signed-off-by: Jeremy White <jwhite at codeweavers.com>
> ---
> src/dfps.c | 75 +++++++++++++++++++++++++++++++++++-------------------------
> 1 file changed, 44 insertions(+), 31 deletions(-)
>
> diff --git a/src/dfps.c b/src/dfps.c
> index 4ab20a8..5db34dc 100644
> --- a/src/dfps.c
> +++ b/src/dfps.c
> @@ -128,6 +128,45 @@ static Bool unaccel (void)
> return FALSE;
> }
>
> +
> +/* Establish a maximum number of disparate regions we'll track before we just
> + treat the entire bounding rectangle as having changed.
> +
> + The number 20 seemed intuitive, and also produced the best results in
> + benchmarking x11perf -circle10 -repeat 1
> +*/
> +#define DFPS_MAX_UPDATE_REGIONS 20
> +static void dfps_update_box(RegionPtr dest, int x_1, int x_2, int y_1, int y_2);
> +
> +static void dfps_update_region(RegionPtr dest, RegionPtr src)
> +{
> + Bool throwaway_bool;
> +
> + RegionAppend(dest, src);
> + RegionValidate(dest, &throwaway_bool);
> + if (RegionNumRects(dest) > DFPS_MAX_UPDATE_REGIONS)
> + {
> + struct pixman_box16 box = * (RegionExtents(dest));
> + RegionUninit(dest);
> + RegionInit(dest, NULL, 0);
> + dfps_update_box(dest, box.x1, box.x2, box.y1, box.y2);
> + }
> +}
> +
> +static void dfps_update_box(RegionPtr dest, int x_1, int x_2, int y_1, int y_2)
> +{
> + struct pixman_box16 box;
> + RegionPtr region;
> +
> + box.x1 = x_1; box.x2 = x_2; box.y1 = y_1; box.y2 = y_2;
> + region = RegionCreate(&box, 1);
> +
> + dfps_update_region(dest, region);
> +
> + RegionUninit(region);
> + RegionDestroy(region);
> +}
> +
> static Bool dfps_prepare_solid (PixmapPtr pixmap, int alu, Pixel planemask, Pixel fg)
> {
> dfps_info_t *info;
> @@ -152,9 +191,6 @@ static Bool dfps_prepare_solid (PixmapPtr pixmap, int alu, Pixel planemask, Pixe
>
> static void dfps_solid (PixmapPtr pixmap, int x_1, int y_1, int x_2, int y_2)
> {
> - struct pixman_box16 box;
> - RegionPtr region;
> - Bool throwaway_bool;
> dfps_info_t *info;
>
> if (!(info = dfps_get_info (pixmap)))
> @@ -164,12 +200,7 @@ static void dfps_solid (PixmapPtr pixmap, int x_1, int y_1, int x_2, int y_2)
> fbFill(&pixmap->drawable, info->pgc, x_1, y_1, x_2 - x_1, y_2 - y_1);
>
> /* Track the updated region */
> - box.x1 = x_1; box.x2 = x_2; box.y1 = y_1; box.y2 = y_2;
> - region = RegionCreate(&box, 1);
> - RegionAppend(&info->updated_region, region);
> - RegionValidate(&info->updated_region, &throwaway_bool);
> - RegionUninit(region);
> - RegionDestroy(region);
> + dfps_update_box(&info->updated_region, x_1, x_2, y_1, y_2);
> return;
> }
>
> @@ -212,10 +243,6 @@ static void dfps_copy (PixmapPtr dest,
> int dest_x1, int dest_y1,
> int width, int height)
> {
> - struct pixman_box16 box;
> - RegionPtr region;
> - Bool throwaway_bool;
> -
> dfps_info_t *info;
>
> if (!(info = dfps_get_info (dest)))
> @@ -225,12 +252,7 @@ static void dfps_copy (PixmapPtr dest,
> fbCopyArea(&info->copy_src->drawable, &dest->drawable, info->pgc, src_x1, src_y1, width, height, dest_x1, dest_y1);
>
> /* Update the tracking region */
> - box.x1 = dest_x1; box.x2 = dest_x1 + width; box.y1 = dest_y1; box.y2 = dest_y1 + height;
> - region = RegionCreate(&box, 1);
> - RegionAppend(&info->updated_region, region);
> - RegionValidate(&info->updated_region, &throwaway_bool);
> - RegionUninit(region);
> - RegionDestroy(region);
> + dfps_update_box(&info->updated_region, dest_x1, dest_x1 + width, dest_y1, dest_y1 + height);
> }
>
> static void dfps_done_copy (PixmapPtr dest)
> @@ -247,20 +269,12 @@ static void dfps_done_copy (PixmapPtr dest)
> static Bool dfps_put_image (PixmapPtr dest, int x, int y, int w, int h,
> char *src, int src_pitch)
> {
> - struct pixman_box16 box;
> - RegionPtr region;
> - Bool throwaway_bool;
> dfps_info_t *info;
>
> if (!(info = dfps_get_info (dest)))
> return FALSE;
>
> - box.x1 = x; box.x2 = x + w; box.y1 = y; box.y2 = y + h;
> - region = RegionCreate(&box, 1);
> - RegionAppend(&info->updated_region, region);
> - RegionValidate(&info->updated_region, &throwaway_bool);
> - RegionUninit(region);
> - RegionDestroy(region);
> + dfps_update_box(&info->updated_region, x, x + w, y, y + h);
>
> /* We can avoid doing the put image ourselves, as the uxa driver
> will fall back and do it for us if we return false */
> @@ -274,12 +288,11 @@ static Bool dfps_prepare_access (PixmapPtr pixmap, RegionPtr region, uxa_access_
> if (requested_access == UXA_ACCESS_RW)
> {
> dfps_info_t *info;
> - Bool throwaway_bool;
>
> if (!(info = dfps_get_info (pixmap)))
> return FALSE;
> - RegionAppend(&info->updated_region, region);
> - RegionValidate(&info->updated_region, &throwaway_bool);
> +
> + dfps_update_region(&info->updated_region, region);
> }
> return TRUE;
> }
> --
> 1.7.10.4
>
> _______________________________________________
> Spice-devel mailing list
> Spice-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/spice-devel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/spice-devel/attachments/20140919/360d9dfe/attachment.sig>
More information about the Spice-devel
mailing list