[Spice-devel] [PATCH 00/30] Convert cairo canvas to use pixman

Izik Eidus ieidus at redhat.com
Sat Feb 20 01:18:10 PST 2010


On Fri, 19 Feb 2010 16:52:36 +0100
Alexander Larsson <alexl at redhat.com> wrote:

> On Fri, 2010-02-19 at 16:50 +0100, Alexander Larsson wrote:
> > On Thu, 2010-02-18 at 21:58 +0100, Alexander Larsson wrote:
> > > This series converts the software based canvas "cairo_canvas" to use
> > > pixman for rendering instead of cairo. It uses the upstream pixman
> > > (the latest version, 0.7.16 is needed) thus dropping the
> > dependencies
> > > on qcairo and qpixman (and additionally cairo is not linked into the
> > > server at all).
> > > 
> > > After the whole series is applied its possible to build spice with
> > > upstream cairo and pixman 0.7.16. However, if you want to compile
> > and
> > > run intermediate steps (for instance when bisecting) you need to do
> > > some extra work:
> > 
> > Seems i missed some qcairo parts:
> 
> Wrong patch:
> 
> commit 0de8c72dc4f57cbba6bb93e97a44b09da45a6ffd
> Author: Alexander Larsson <alexl at redhat.com>
> Date:   Fri Feb 19 16:48:55 2010 +0100
> 
>     Remove cairo use in client
> 
> diff --git a/client/x11/pixels_source.cpp b/client/x11/pixels_source.cpp
> index 7b9ed05..144c296 100644
> --- a/client/x11/pixels_source.cpp
> +++ b/client/x11/pixels_source.cpp
> @@ -25,9 +25,9 @@
>  
>  
>  static void create_image(const PixmapHeader* pixmap, PixelsSource_p& pixels_source,
> -                         cairo_format_t cairo_format)
> +                         pixman_format_code_t format)
>  {
> -    cairo_surface_t* cairo_surf;
> +    pixman_image_t *pixman_image;
>      XImage *image = new XImage;
>  
>      memset(image, 0, sizeof(*image));
> @@ -53,10 +53,11 @@ static void create_image(const PixmapHeader* pixmap, PixelsSource_p& pixels_sour
>              THROW("init image failed");
>          }
>  
> -        cairo_surf = cairo_image_surface_create_for_data(pixmap->data, cairo_format,
> -                                                         pixmap->width, pixmap->height,
> -                                                         pixmap->stride);
> -        if (cairo_surface_status(cairo_surf) != CAIRO_STATUS_SUCCESS) {
> +        pixman_image = pixman_image_create_bits(format,
> +                                                pixmap->width, pixmap->height,
> +                                                (uint32_t *)pixmap->data,
> +                                                pixmap->stride);
> +        if (pixman_image == NULL) {
>              THROW("surf create failed");
>          }
>      } catch (...) {
> @@ -66,7 +67,7 @@ static void create_image(const PixmapHeader* pixmap, PixelsSource_p& pixels_sour
>  
>      pixels_source.type = PIXELS_SOURCE_TYPE_PIXMAP;
>      pixels_source.pixmap.x_image = image;
> -    pixels_source.pixmap.cairo_surf = cairo_surf;
> +    pixels_source.pixmap.pixman_image = pixman_image;
>  }
>  
>  PixelsSource::PixelsSource()
> @@ -85,12 +86,12 @@ ImageFromRes::ImageFromRes(int res_id)
>      if (!pixmap) {
>          THROW("no image %d", res_id);
>      }
> -    create_image(pixmap, *(PixelsSource_p*)get_opaque(), CAIRO_FORMAT_RGB24);
> +    create_image(pixmap, *(PixelsSource_p*)get_opaque(), PIXMAN_x8r8g8b8);
>  }
>  
>  ImageFromRes::~ImageFromRes()
>  {
> -    cairo_surface_destroy(((PixelsSource_p*)get_opaque())->pixmap.cairo_surf);
> +    pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image);
>      delete ((PixelsSource_p*)get_opaque())->pixmap.x_image;
>  }
>  
> @@ -109,12 +110,12 @@ AlphaImageFromRes::AlphaImageFromRes(int res_id)
>      if (!pixmap) {
>          THROW("no image %d", res_id);
>      }
> -    create_image(pixmap, *(PixelsSource_p*)get_opaque(), CAIRO_FORMAT_ARGB32);
> +    create_image(pixmap, *(PixelsSource_p*)get_opaque(), PIXMAN_a8r8g8b8);
>  }
>  
>  AlphaImageFromRes::~AlphaImageFromRes()
>  {
> -    cairo_surface_destroy(((PixelsSource_p*)get_opaque())->pixmap.cairo_surf);
> +    pixman_image_unref(((PixelsSource_p*)get_opaque())->pixmap.pixman_image);
>      delete ((PixelsSource_p*)get_opaque())->pixmap.x_image;
>  }
>  
> diff --git a/client/x11/pixels_source_p.h b/client/x11/pixels_source_p.h
> index 69d6998..9605ae4 100644
> --- a/client/x11/pixels_source_p.h
> +++ b/client/x11/pixels_source_p.h
> @@ -24,7 +24,7 @@
>  #include <X11/extensions/XShm.h>
>  #include "red_window.h"
>  #include "red_pixmap_gl.h"
> -#include "cairo.h"
> +#include "pixman_utils.h"
>  
>  enum {
>      PIXELS_SOURCE_TYPE_INVALID,
> @@ -53,12 +53,12 @@ struct PixelsSource_p {
>          struct {
>              XImage* x_image;
>              XShmSegmentInfo *shminfo;
> -            cairo_surface_t* cairo_surf;
> +            pixman_image_t* pixman_image;
>          } x_shm_drawable;
>  
>          struct {
>              XImage* x_image;
> -            cairo_surface_t* cairo_surf;
> +            pixman_image_t* pixman_image;
>          } pixmap;
>  
>          struct {
> @@ -79,9 +79,6 @@ struct PixelsSource_p {
>  
>  struct RedDrawable_p {
>      PixelsSource_p source;
> -    union {
> -        cairo_t* cairo;
> -    };
>  };
>  
>  #endif
> diff --git a/client/x11/red_drawable.cpp b/client/x11/red_drawable.cpp
> index 7485c94..dc33749 100644
> --- a/client/x11/red_drawable.cpp
> +++ b/client/x11/red_drawable.cpp
> @@ -237,18 +237,18 @@ static inline void copy_to_pixmap_from_shmdrawable(const RedDrawable_p* dest,
>                                                     const PixelsSource_p* source,
>                                                     int src_x, int src_y)
>  {
> -    cairo_t* cairo = dest->cairo;
> -    cairo_surface_t* surf = source->x_shm_drawable.cairo_surf;
> -
> -    ASSERT(cairo);
> -    ASSERT(surf);
> -
> -    cairo_set_source_surface(cairo, surf, area.left + offset.x - src_x,
> -                             area.top + offset.y - src_y);
> -    cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY);
> -    cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                    area.bottom - area.top);
> -    cairo_fill(cairo);
> +    pixman_image_t *dest_surface =  dest->source.pixmap.pixman_image;
> +    pixman_image_t *src_surface = source->x_shm_drawable.pixman_image;
> +
> +    pixman_image_composite32 (PIXMAN_OP_SRC,
> +                              src_surface, NULL, dest_surface,
> +                              src_x + offset.x,
> +                              src_y + offset.y,
> +                              0, 0,
> +                              area.left + offset.x,
> +                              area.top + offset.y,
> +                              area.right - area.left,
> +                              area.bottom - area.top);
>  }
>  
>  static inline void copy_to_pixmap_from_pixmap(const RedDrawable_p* dest,
> @@ -257,18 +257,18 @@ static inline void copy_to_pixmap_from_pixmap(const RedDrawable_p* dest,
>                                                const PixelsSource_p* source,
>                                                int src_x, int src_y)
>  {
> -    cairo_t* cairo = dest->cairo;
> -    cairo_surface_t* surf = source->pixmap.cairo_surf;
> -
> -    ASSERT(cairo);
> -    ASSERT(surf);
> -
> -    cairo_set_source_surface(cairo, surf, area.left + offset.x - src_x,
> -                             area.top + offset.y - src_y);
> -    cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY);
> -    cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                    area.bottom - area.top);
> -    cairo_fill(cairo);
> +    pixman_image_t *dest_surface =  dest->source.pixmap.pixman_image;
> +    pixman_image_t *src_surface = source->pixmap.pixman_image;
> +
> +    pixman_image_composite32 (PIXMAN_OP_SRC,
> +                              src_surface, NULL, dest_surface,
> +                              src_x + offset.x,
> +                              src_y + offset.y,
> +                              0, 0,
> +                              area.left + offset.x,
> +                              area.top + offset.y,
> +                              area.right - area.left,
> +                              area.bottom - area.top);
>  }
>  
>  static inline void copy_to_pixmap_from_gltexture(const RedDrawable_p* dest,
> @@ -384,18 +384,18 @@ static inline void blend_to_pixmap_from_pixmap(const RedDrawable_p* dest,
>                                                 const PixelsSource_p* source,
>                                                 int src_x, int src_y)
>  {
> -    cairo_t* cairo = dest->cairo;
> -    cairo_surface_t* surf = source->pixmap.cairo_surf;
> -
> -    ASSERT(cairo);
> -    ASSERT(surf);
> -
> -    cairo_set_source_surface(cairo, surf, (area.left + offset.x - src_x),
> -                             (area.top + offset.y - src_y));
> -    cairo_set_operator(cairo, CAIRO_OPERATOR_ATOP);
> -    cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                    area.bottom - area.top);
> -    cairo_fill(cairo);
> +    pixman_image_t *dest_surface =  dest->source.pixmap.pixman_image;
> +    pixman_image_t *src_surface = source->pixmap.pixman_image;
> +
> +    pixman_image_composite32 (PIXMAN_OP_ATOP,
> +                              src_surface, NULL, dest_surface,
> +                              src_x + offset.x,
> +                              src_y + offset.y,
> +                              0, 0,
> +                              area.left + offset.x,
> +                              area.top + offset.y,
> +                              area.right - area.left,
> +                              area.bottom - area.top);
>  }
>  
>  static inline void blend_to_pixmap(const RedDrawable_p* dest,
> @@ -460,41 +460,74 @@ static inline void combine_to_pixmap_from_pixmap(const RedDrawable_p* dest,
>                                                   int src_x, int src_y,
>                                                   RedDrawable::CombineOP op)
>  {
> -    cairo_t* cairo = dest->cairo;
> -    cairo_surface_t* surf = source->pixmap.cairo_surf;
> +    pixman_image_t *dest_surface =  dest->source.pixmap.pixman_image;
> +    pixman_image_t *src_surface = source->pixmap.pixman_image;
>  
> -    ASSERT(cairo);
> -    ASSERT(surf);
> -    cairo_operator_t cairo_op;
> +    SpiceROP rop;
>      switch (op) {
>      case RedDrawable::OP_COPY:
> -        cairo_op = CAIRO_OPERATOR_RASTER_COPY;
> +        rop = SPICE_ROP_COPY;
>          break;
>      case RedDrawable::OP_AND:
> -        cairo_op = CAIRO_OPERATOR_RASTER_AND;
> +        rop = SPICE_ROP_AND;
>          break;
>      case RedDrawable::OP_XOR:
> -        cairo_op = CAIRO_OPERATOR_RASTER_XOR;
> +        rop = SPICE_ROP_XOR;
>          break;
>      default:
>          THROW("invalid op %d", op);
>      }
>  
>  
> -    cairo_set_operator(cairo, cairo_op);
> -    if (cairo_image_surface_get_format(surf) == CAIRO_FORMAT_A1) {
> -        cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                        area.bottom - area.top);
> -        cairo_clip(cairo);
> -        cairo_set_source_rgb(cairo, 1, 1, 1);
> -        cairo_mask_surface(cairo, surf, area.left + offset.x - src_x, area.top + offset.y - src_y);
> -        cairo_reset_clip(cairo);
> +    if (pixman_image_get_depth (src_surface) == 1) {
> +        pixman_image_t *temp;
> +
> +        temp = pixman_image_create_bits(pixman_image_get_depth(dest_surface) == 24 ?
> +                                        PIXMAN_x8r8g8b8 : PIXMAN_a8r8g8b8,
> +                                        area.right - area.left,
> +                                        area.bottom - area.top, NULL, 0);
> +
> +        /* Copy from dest to temp */
> +        pixman_image_composite32(PIXMAN_OP_SRC,
> +                                 dest_surface, NULL, temp,
> +                                 area.left + offset.x,
> +                                 area.top + offset.y,
> +                                 0, 0,
> +                                 0, 0,
> +                                 area.right - area.left,
> +                                 area.bottom - area.top);
> +
> +        /* rop white over temp */
> +        spice_pixman_fill_rect_rop(temp,
> +                                   0, 0,
> +                                   area.right - area.left,
> +                                   area.bottom - area.top,
> +                                   0xffffff,
> +                                   rop);
> +
> +        /* copy back using a1 mask */
> +        pixman_image_composite32(PIXMAN_OP_SRC,
> +                                 dest_surface, src_surface, dest_surface,
> +                                 0, 0,
> +                                 src_x + offset.x,
> +                                 src_y + offset.y,
> +                                 area.left + offset.x,
> +                                 area.top + offset.y,
> +                                 area.right - area.left,
> +                                 area.bottom - area.top);
> +
> +        pixman_image_unref(temp);
> +
>      } else {
> -        cairo_set_source_surface(cairo, surf, area.left + offset.x - src_x,
> -                                 area.top + offset.y - src_y);
> -        cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                        area.bottom - area.top);
> -        cairo_fill(cairo);
> +        spice_pixman_blit_rop (dest_surface,
> +                               src_surface,
> +                               src_x + offset.x,
> +                               src_y + offset.y,
> +                               area.left + offset.x,
> +                               area.top + offset.y,
> +                               area.right - area.left,
> +                               area.bottom - area.top,
> +                               rop);
>      }
>  }
>  
> @@ -606,17 +639,13 @@ static inline void fill_gl_drawable(RedDrawable_p* dest, const SpiceRect& area,
>  static inline void fill_pixmap(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color,
>                                 const SpicePoint& offset)
>  {
> -    cairo_t* cairo = dest->cairo;
> -
> -    ASSERT(cairo);
> -    cairo_set_source_rgb(cairo,
> -                         (double)rgb32_get_red(color) / 0xff,
> -                         (double)rgb32_get_green(color) / 0xff,
> -                         (double)rgb32_get_blue(color) / 0xff);
> -    cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                    area.bottom - area.top);
> -    cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY);
> -    cairo_fill(cairo);
> +    pixman_image_t *dest_surface =  dest->source.pixmap.pixman_image;
> +
> +    spice_pixman_fill_rect (dest_surface,
> +                            area.left + offset.x, area.top + offset.y,
> +                            area.right - area.left,
> +                            area.bottom - area.top,
> +                            color);
>  }
>  
>  void RedDrawable::fill_rect(const SpiceRect& area, rgb32_t color)
> @@ -668,18 +697,28 @@ static inline void frame_drawable(RedDrawable_p* dest, const SpiceRect& area, rg
>  static inline void frame_pixmap(RedDrawable_p* dest, const SpiceRect& area, rgb32_t color,
>                                  const SpicePoint& offset)
>  {
> -    cairo_t* cairo = dest->cairo;
> -
> -    ASSERT(cairo);
> -    cairo_set_source_rgb(cairo,
> -                         (double)rgb32_get_red(color) / 0xff,
> -                         (double)rgb32_get_green(color) / 0xff,
> -                         (double)rgb32_get_blue(color) / 0xff);
> -    cairo_rectangle(cairo, area.left + offset.x, area.top + offset.y, area.right - area.left,
> -                    area.bottom - area.top);
> -    cairo_set_line_width(cairo, 1);
> -    cairo_set_operator(cairo, CAIRO_OPERATOR_RASTER_COPY);
> -    cairo_stroke(cairo);
> +    pixman_image_t *dest_surface =  dest->source.pixmap.pixman_image;
> +
> +    spice_pixman_fill_rect (dest_surface,
> +                            area.left + offset.x, area.top + offset.y,
> +                            area.right - area.left,
> +                            1,
> +                            color);
> +    spice_pixman_fill_rect (dest_surface,
> +                            area.left + offset.x, area.bottom + offset.y,
> +                            area.right - area.left,
> +                            1,
> +                            color);
> +    spice_pixman_fill_rect (dest_surface,
> +                            area.left + offset.x, area.top + offset.y,
> +                            1,
> +                            area.bottom - area.top,
> +                            color);
> +    spice_pixman_fill_rect (dest_surface,
> +                            area.right + offset.x, area.top + offset.y,
> +                            1,
> +                            area.bottom - area.top,
> +                            color);
>  }
>  
>  void RedDrawable::frame_rect(const SpiceRect& area, rgb32_t color)
> diff --git a/client/x11/red_pixmap_cairo.cpp b/client/x11/red_pixmap_cairo.cpp
> index 7ca9315..b8b627b 100644
> --- a/client/x11/red_pixmap_cairo.cpp
> +++ b/client/x11/red_pixmap_cairo.cpp
> @@ -28,10 +28,9 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
>                                 bool top_bottom, rgb32_t* pallet, RedWindow *win)
>      : RedPixmap(width, height, format, top_bottom, pallet)
>  {
> -    cairo_surface_t* cairo_surf = NULL;
> -    cairo_t* cairo = NULL;
>      ASSERT(format == RedPixmap::ARGB32 || format == RedPixmap::RGB32 || format == RedPixmap::A1);
>      ASSERT(sizeof(RedDrawable_p) <= PIXELES_SOURCE_OPAQUE_SIZE);
> +    pixman_image_t *pixman_image;
>      XImage *image = NULL;
>      XShmSegmentInfo *shminfo = NULL;
>      _data = NULL;
> @@ -40,7 +39,7 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
>  
>  
>      try {
> -        cairo_format_t cairo_format;
> +        pixman_format_code_t pixman_format;
>  
>          if (win) {
>              vinfo = XPlatform::get_vinfo()[win->get_screen_num()];
> @@ -55,12 +54,12 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
>              case RedPixmap::ARGB32:
>              case RedPixmap::RGB32:
>                  depth = XPlatform::get_vinfo()[0]->depth;
> -                cairo_format = format == RedPixmap::ARGB32 ? CAIRO_FORMAT_ARGB32 :
> -                                                             CAIRO_FORMAT_RGB24;
> +                pixman_format = format == RedPixmap::ARGB32 ? PIXMAN_a8r8g8b8 :
> +                                                             PIXMAN_x8r8g8b8;
>                  break;
>              case RedPixmap::A1:
>                  depth = 1;
> -                cairo_format = CAIRO_FORMAT_A1;
> +                pixman_format = PIXMAN_a1;
>                  break;
>              default:
>                  THROW("unsupported format %d", format);
> @@ -122,13 +121,13 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
>                  image->red_mask = 0x00ff0000;
>                  image->green_mask = 0x0000ff00;
>                  image->blue_mask = 0x000000ff;
> -                cairo_format = format == RedPixmap::ARGB32 ? CAIRO_FORMAT_ARGB32 :
> -                                                             CAIRO_FORMAT_RGB24;
> +                pixman_format = format == RedPixmap::ARGB32 ? PIXMAN_a8r8g8b8 :
> +                                                             PIXMAN_x8r8g8b8;
>                  break;
>              case RedPixmap::A1:
>                  image->depth = 1;
>                  image->format = XYBitmap;
> -                cairo_format = CAIRO_FORMAT_A1;
> +                pixman_format = PIXMAN_a1;
>                  break;
>              default:
>                  THROW("unsupported format %d", format);
> @@ -138,23 +137,16 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
>                  THROW("init image failed");
>              }
>          }
> -        cairo_surf = cairo_image_surface_create_for_data(_data, cairo_format, _width, _height,
> -                                                         _stride);
> -        if (cairo_surface_status(cairo_surf) != CAIRO_STATUS_SUCCESS) {
> +        pixman_image = pixman_image_create_bits (pixman_format, _width, _height, (uint32_t *)_data, _stride);
> +        if (pixman_image == NULL) {
>              THROW("surf create failed");
>          }
>  
> -        cairo = cairo_create(cairo_surf);
> -        cairo_surface_destroy(cairo_surf);
> -        if (cairo_status(cairo) != CAIRO_STATUS_SUCCESS) {
> -            THROW("cairo create failed failed");
> -        }
>          if (!using_shm) {
> -            ((PixelsSource_p*)get_opaque())->pixmap.cairo_surf = cairo_surf;
> +            ((PixelsSource_p*)get_opaque())->pixmap.pixman_image = pixman_image;
>          } else {
> -            ((PixelsSource_p*)get_opaque())->x_shm_drawable.cairo_surf = cairo_surf;
> +            ((PixelsSource_p*)get_opaque())->x_shm_drawable.pixman_image = pixman_image;
>          }
> -        ((RedDrawable_p*)get_opaque())->cairo = cairo;
>      } catch (...) {
>          if (using_shm) {
>              if (image) {
> @@ -178,11 +170,12 @@ RedPixmapCairo::RedPixmapCairo(int width, int height, RedPixmap::Format format,
>  
>  RedPixmapCairo::~RedPixmapCairo()
>  {
> -    cairo_destroy(((RedDrawable_p*)get_opaque())->cairo);
>      if (((PixelsSource_p*)get_opaque())->type == PIXELS_SOURCE_TYPE_PIXMAP) {
> +        pixman_image_unref (((PixelsSource_p*)get_opaque())->pixmap.pixman_image);
>          delete ((PixelsSource_p*)get_opaque())->pixmap.x_image;
>          delete[] _data;
>      } else {
> +        pixman_image_unref (((PixelsSource_p*)get_opaque())->x_shm_drawable.pixman_image);
>          XShmSegmentInfo *shminfo = ((PixelsSource_p*)get_opaque())->x_shm_drawable.shminfo;
>          XShmDetach(XPlatform::get_display(), shminfo);
>          XDestroyImage(((PixelsSource_p*)get_opaque())->x_shm_drawable.x_image);
> diff --git a/common/cairo_canvas.c b/common/cairo_canvas.c
> index a6c82ee..8d549e6 100644
> --- a/common/cairo_canvas.c
> +++ b/common/cairo_canvas.c
> @@ -240,7 +240,7 @@ static void canvas_mask_pixman (CairoCanvas *canvas,
>                                  pixman_region32_t *dest_region,
>                                  SpiceQMask *mask, int x, int y)
>  {
> -    pixman_image_t *image;
> +    pixman_image_t *image, *subimage;
>      int needs_invert;
>      pixman_region32_t mask_region;
>      uint32_t *mask_data;
> @@ -298,10 +298,11 @@ static void canvas_mask_pixman (CairoCanvas *canvas,
>      mask_width = extents.x2 - extents.x1;
>      mask_height = extents.y2 - extents.y1;
>  
> -    spice_pixman_region32_init_from_bitmap (&mask_region,
> -                                            mask_data,
> -                                            mask_width, mask_height,
> -                                            mask_stride / 4);
> +    subimage = pixman_image_create_bits (PIXMAN_a1, mask_width, mask_height,
> +                                         mask_data, mask_stride);
> +    pixman_region32_init_from_image (&mask_region,
> +                                     subimage);
> +    pixman_image_unref (subimage);
>  
>      if (needs_invert) {
>          pixman_box32_t rect;
> 
> 

After appling everything include of this on top of the last patch
and build pixman from the git repo i still get:
cc1: warnings being treated as errors
../common/cairo_canvas.c: In function ‘canvas_mask_pixman’:
../common/cairo_canvas.c:303: error: implicit declaration of function ‘pixman_region32_init_from_image’


Any ideas what I am doing wrong?


More information about the Spice-devel mailing list