configure.ac | 4 src/Makefile.am | 7 src/mspace.h | 2 src/qxl.h | 64 + src/qxl_cursor.c | 4 src/qxl_driver.c | 2420 +++++++++++++++++++++++++++++++++---------------- src/qxl_edid.c | 209 ++++ src/qxl_image.c | 20 src/qxl_mem.c | 31 src/qxl_ring.c | 20 src/qxl_surface.c | 275 +++++ src/spiceqxl_inputs.c | 28 src/spiceqxl_io_port.c | 4 src/uxa/uxa-glyphs.c | 9 src/uxa/uxa-priv.h | 2 src/uxa/uxa.c | 7 16 files changed, 2277 insertions(+), 829 deletions(-)
New commits: commit d8bb331784792bfd35bf158875b434243f0fe019 Author: Søren Sandmann Pedersen <[email protected]> Date: Thu Sep 20 19:11:55 2012 -0400 Version bump to 0.1.0 diff --git a/configure.ac b/configure.ac index 11ef73c..48904a2 100644 --- a/configure.ac +++ b/configure.ac @@ -23,7 +23,7 @@ # Initialize Autoconf AC_PREREQ([2.60]) AC_INIT([xf86-video-qxl], - [0.0.17], + [0.1.0], [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg], [xf86-video-qxl]) AC_CONFIG_SRCDIR([Makefile.am]) commit 6520293e1e1f57bafbcf99592e766f810ce3ad2d Author: Søren Sandmann Pedersen <[email protected]> Date: Thu Sep 20 16:26:36 2012 -0400 Make the checks for composite and a8 return FALSE for Xspice They depend on the PCI revision which is not available for Xspice. diff --git a/src/qxl_driver.c b/src/qxl_driver.c index 531c761..f52fec6 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -1385,17 +1385,27 @@ can_accelerate_picture (PicturePtr pict) static Bool qxl_has_composite (qxl_screen_t *qxl) { +#ifndef XSPICE return qxl->pci->revision >= 4 && QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE); +#else + /* FIXME */ + return FALSE; +#endif } static Bool qxl_has_a8_surfaces (qxl_screen_t *qxl) { +#ifndef XSPICE return qxl->pci->revision >= 4 && QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_A8_SURFACE); +#else + /* FIXME */ + return FALSE; +#endif } static Bool commit 7f0b820d919eb944eae201de03b186bd247b0324 Author: Jeremy White <[email protected]> Date: Wed Sep 12 10:38:41 2012 -0500 Only use dixScreenSpecificPrivatesSize if we have a new enough Xorg. This lets us continue to support older Xorg releases. This reverts 4f37cd85 and partially reverts 4a43bd4. diff --git a/configure.ac b/configure.ac index b8a4b35..11ef73c 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(XFreeXDGA, xf86dgaproto) # Obtain compiler/linker options for the driver dependencies -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.12.99.901] xproto fontsproto $REQUIRED_MODULES) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901] xproto fontsproto $REQUIRED_MODULES) save_CFLAGS="$CFLAGS" CFLAGS="$XORG_CFLAGS" diff --git a/src/qxl_driver.c b/src/qxl_driver.c index 04a9aa8..531c761 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -1821,10 +1821,14 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL) DamageSetup (pScreen); /* We need to set totalPixmapSize after setup_uxa and Damage, - * as the privatssize is not computed correctly until then + as the privates size is not computed correctly until then */ +#if (XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(1, 12, 99, 901, 0)) + pScreen->totalPixmapSize = BitmapBytePad ((sizeof (PixmapRec) + dixPrivatesSize (PRIVATE_PIXMAP) ) * 8); +#else pScreen->totalPixmapSize = BitmapBytePad((sizeof(PixmapRec) + dixScreenSpecificPrivatesSize(pScreen, PRIVATE_PIXMAP) ) * 8); +#endif miDCInitialize (pScreen, xf86GetPointerScreenFuncs()); if (!miCreateDefColormap (pScreen)) commit fb038eb37906eba9a88e0cb6622a59f06dcc2a68 Author: Søren Sandmann <[email protected]> Date: Wed Sep 12 12:54:06 2012 -0400 Don't issue composite commands or create a8 surfaces when not available When the device or the client are not capable of composite commands or a8 surfaces, don't issue these commands. diff --git a/src/qxl_driver.c b/src/qxl_driver.c index c7b8486..04a9aa8 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -47,6 +47,7 @@ #include "qxl.h" #include "assert.h" #include "qxl_option_helpers.h" +#include <spice/protocol.h> #ifdef XSPICE #include "spiceqxl_driver.h" @@ -1378,6 +1379,25 @@ can_accelerate_picture (PicturePtr pict) return TRUE; } +#define QXL_HAS_CAP(qxl, cap) \ + (((qxl)->rom->client_capabilities[(cap) / 8]) & (1 << ((cap) % 8))) + +static Bool +qxl_has_composite (qxl_screen_t *qxl) +{ + return + qxl->pci->revision >= 4 && + QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_COMPOSITE); +} + +static Bool +qxl_has_a8_surfaces (qxl_screen_t *qxl) +{ + return + qxl->pci->revision >= 4 && + QXL_HAS_CAP (qxl, SPICE_DISPLAY_CAP_A8_SURFACE); +} + static Bool qxl_check_composite (int op, PicturePtr pSrcPicture, @@ -1386,7 +1406,10 @@ qxl_check_composite (int op, int width, int height) { int i; - + ScreenPtr pScreen = pDstPicture->pDrawable->pScreen; + ScrnInfoPtr pScrn = xf86ScreenToScrn (pScreen); + qxl_screen_t *qxl = pScrn->driverPrivate; + static const int accelerated_ops[] = { PictOpClear, PictOpSrc, PictOpDst, PictOpOver, PictOpOverReverse, @@ -1397,6 +1420,9 @@ qxl_check_composite (int op, PictOpHardLight, PictOpSoftLight, PictOpDifference, PictOpExclusion, PictOpHSLHue, PictOpHSLSaturation, PictOpHSLColor, PictOpHSLLuminosity, }; + + if (!qxl_has_composite (qxl)) + return FALSE; if (!can_accelerate_picture (pSrcPicture) || !can_accelerate_picture (pMaskPicture) || @@ -1502,6 +1528,15 @@ qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage) if (uxa_swapped_out (screen)) goto fallback; + + if (depth == 8 && !qxl_has_a8_surfaces (qxl)) + { + /* FIXME: When we detect a _change_ in the property of having a8 + * surfaces, we should copy all existing a8 surface to host memory + * and then destroy the ones on the device. + */ + goto fallback; + } surface = qxl_surface_create (qxl->surface_cache, w, h, depth); commit 4f37cd854f128714b8fcf3c0ab8afd72986407a0 Author: Johannes Obermayr <[email protected]> Date: Fri Sep 7 18:05:21 2012 +0200 Require XServer >= 1.12.99.901 in conjunction with commit 4a43bd4. diff --git a/configure.ac b/configure.ac index 11ef73c..b8a4b35 100644 --- a/configure.ac +++ b/configure.ac @@ -60,7 +60,7 @@ XORG_DRIVER_CHECK_EXT(XV, videoproto) XORG_DRIVER_CHECK_EXT(XFreeXDGA, xf86dgaproto) # Obtain compiler/linker options for the driver dependencies -PKG_CHECK_MODULES(XORG, [xorg-server >= 1.0.99.901] xproto fontsproto $REQUIRED_MODULES) +PKG_CHECK_MODULES(XORG, [xorg-server >= 1.12.99.901] xproto fontsproto $REQUIRED_MODULES) save_CFLAGS="$CFLAGS" CFLAGS="$XORG_CFLAGS" commit 7059cff787eef80f3d3345de705e912b292a9f97 Author: Søren Sandmann <[email protected]> Date: Thu Jul 12 09:53:31 2012 -0400 Add Render support This commit adds support for using the new Composite command in spice protocol 0.12.0. This command is similar to the Composite request in the X Render protocol. By implementing the UXA composite stubs, we get acceleration for most common Composite requests, including glyphs. diff --git a/src/qxl.h b/src/qxl.h index d976fd5..8494550 100644 --- a/src/qxl.h +++ b/src/qxl.h @@ -392,7 +392,21 @@ Bool qxl_surface_put_image (qxl_surface_t *dest, const char *src, int src_pitch); void qxl_surface_unref (surface_cache_t *cache, uint32_t surface_id); - + +/* composite */ +Bool qxl_surface_prepare_composite (int op, + PicturePtr src_picture, + PicturePtr mask_picture, + PicturePtr dst_picture, + qxl_surface_t *src, + qxl_surface_t *mask, + qxl_surface_t *dest); +void qxl_surface_composite (qxl_surface_t *dest, + int src_x, int src_y, + int mask_x, int mask_y, + int dst_x, int dst_y, + int width, int height); + #if HAS_DEVPRIVATEKEYREC extern DevPrivateKeyRec uxa_pixmap_index; #else diff --git a/src/qxl_driver.c b/src/qxl_driver.c index 634f181..c7b8486 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -339,14 +339,14 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id) int is_cursor = FALSE; int is_surface = FALSE; int is_drawable = FALSE; - + if ((id & POINTER_MASK) == 1) is_cursor = TRUE; else if ((id & POINTER_MASK) == 2) is_surface = TRUE; else is_drawable = TRUE; - + if (is_cursor && cmd->type == QXL_CURSOR_SET) { struct QXLCursor *cursor = (void *)virtual_address ( @@ -358,7 +358,7 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id) { struct QXLImage *image = virtual_address ( qxl, u64_to_pointer (drawable->u.copy.src_bitmap), qxl->main_mem_slot); - + if (image->descriptor.type == SPICE_IMAGE_TYPE_SURFACE) { qxl_surface_unref (qxl->surface_cache, image->surface_image.surface_id); @@ -370,16 +370,50 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id) qxl_image_destroy (qxl, image); } } + else if (is_drawable && drawable->type == QXL_DRAW_COMPOSITE) + { + struct QXLTransform *src_trans, *mask_trans; + struct QXLImage *src_img, *mask_img; + struct QXLComposite *composite = &drawable->u.composite; + + /* Source */ + src_img = virtual_address ( + qxl, u64_to_pointer (drawable->u.composite.src), qxl->main_mem_slot); + qxl_free (qxl->mem, src_img, "image struct"); + + if (composite->src_transform) + { + src_trans = virtual_address ( + qxl, u64_to_pointer (composite->src_transform), qxl->main_mem_slot); + qxl_free (qxl->mem, src_trans, "transform"); + } + + /* Mask */ + if (drawable->u.composite.mask) + { + if (drawable->u.composite.mask_transform) + { + mask_trans = virtual_address ( + qxl, u64_to_pointer (drawable->u.composite.mask_transform), qxl->main_mem_slot); + + qxl_free (qxl->mem, mask_trans, "transform"); + } + + mask_img = virtual_address ( + qxl, u64_to_pointer (drawable->u.composite.mask), qxl->main_mem_slot); + qxl_free (qxl->mem, mask_img, "image struct"); + } + } else if (is_surface && surface_cmd->type == QXL_SURFACE_CMD_DESTROY) { qxl_surface_recycle (qxl->surface_cache, surface_cmd->surface_id); qxl_surface_cache_sanity_check (qxl->surface_cache); } - + id = info->next; - + qxl_free (qxl->mem, info, "command"); - + return id; } @@ -1198,12 +1232,6 @@ int uxa_pixmap_index; #endif static Bool -unaccel (void) -{ - return FALSE; -} - -static Bool qxl_prepare_access (PixmapPtr pixmap, RegionPtr region, uxa_access_t access) { return qxl_surface_prepare_access (get_surface (pixmap), @@ -1312,6 +1340,131 @@ qxl_done_copy (PixmapPtr dest) { } +/* + * Composite + */ +static Bool +can_accelerate_picture (PicturePtr pict) +{ + if (!pict) + return TRUE; + + if (pict->format != PICT_a8r8g8b8 && + pict->format != PICT_x8r8g8b8 && + pict->format != PICT_a8) + { + return FALSE; + } + + if (!pict->pDrawable) + return FALSE; + + if (pict->transform) + { + if (pict->transform->matrix[2][0] != 0 || + pict->transform->matrix[2][1] != 0 || + pict->transform->matrix[2][2] != pixman_int_to_fixed (1)) + { + return FALSE; + } + } + + if (pict->filter != PictFilterBilinear && + pict->filter != PictFilterNearest) + { + return FALSE; + } + + return TRUE; +} + +static Bool +qxl_check_composite (int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture, + int width, int height) +{ + int i; + + static const int accelerated_ops[] = + { + PictOpClear, PictOpSrc, PictOpDst, PictOpOver, PictOpOverReverse, + PictOpIn, PictOpInReverse, PictOpOut, PictOpOutReverse, + PictOpAtop, PictOpAtopReverse, PictOpXor, PictOpAdd, + PictOpSaturate, PictOpMultiply, PictOpScreen, PictOpOverlay, + PictOpDarken, PictOpLighten, PictOpColorDodge, PictOpColorBurn, + PictOpHardLight, PictOpSoftLight, PictOpDifference, PictOpExclusion, + PictOpHSLHue, PictOpHSLSaturation, PictOpHSLColor, PictOpHSLLuminosity, + }; + + if (!can_accelerate_picture (pSrcPicture) || + !can_accelerate_picture (pMaskPicture) || + !can_accelerate_picture (pDstPicture)) + { + return FALSE; + } + + for (i = 0; i < sizeof (accelerated_ops) / sizeof (accelerated_ops[0]); ++i) + { + if (accelerated_ops[i] == op) + goto found; + } + return FALSE; + +found: + return TRUE; +} + +static Bool +qxl_check_composite_target (PixmapPtr pixmap) +{ + return TRUE; +} + +static Bool +qxl_check_composite_texture (ScreenPtr screen, + PicturePtr pPicture) +{ + return TRUE; +} + +static Bool +qxl_prepare_composite (int op, + PicturePtr pSrcPicture, + PicturePtr pMaskPicture, + PicturePtr pDstPicture, + PixmapPtr pSrc, + PixmapPtr pMask, + PixmapPtr pDst) +{ + return qxl_surface_prepare_composite ( + op, pSrcPicture, pMaskPicture, pDstPicture, + get_surface (pSrc), + pMask? get_surface (pMask) : NULL, + get_surface (pDst)); +} + +static void +qxl_composite (PixmapPtr pDst, + int src_x, int src_y, + int mask_x, int mask_y, + int dst_x, int dst_y, + int width, int height) +{ + qxl_surface_composite ( + get_surface (pDst), + src_x, src_y, + mask_x, mask_y, + dst_x, dst_y, width, height); +} + +static void +qxl_done_composite (PixmapPtr pDst) +{ + ; +} + static Bool qxl_put_image (PixmapPtr pDst, int x, int y, int w, int h, char *src, int src_pitch) @@ -1453,12 +1606,12 @@ setup_uxa (qxl_screen_t *qxl, ScreenPtr screen) qxl->uxa->done_copy = qxl_done_copy; /* Composite */ - qxl->uxa->check_composite = (typeof (qxl->uxa->check_composite))unaccel; - qxl->uxa->check_composite_target = (typeof (qxl->uxa->check_composite_target))unaccel; - qxl->uxa->check_composite_texture = (typeof (qxl->uxa->check_composite_texture))unaccel; - qxl->uxa->prepare_composite = (typeof (qxl->uxa->prepare_composite))unaccel; - qxl->uxa->composite = (typeof (qxl->uxa->composite))unaccel; - qxl->uxa->done_composite = (typeof (qxl->uxa->done_composite))unaccel; + qxl->uxa->check_composite = qxl_check_composite; + qxl->uxa->check_composite_target = qxl_check_composite_target; + qxl->uxa->check_composite_texture = qxl_check_composite_texture; + qxl->uxa->prepare_composite = qxl_prepare_composite; + qxl->uxa->composite = qxl_composite; + qxl->uxa->done_composite = qxl_done_composite; /* PutImage */ qxl->uxa->put_image = qxl_put_image; @@ -1625,6 +1778,10 @@ qxl_screen_init (SCREEN_INIT_ARGS_DECL) pScreen->SaveScreen = qxl_blank_screen; setup_uxa (qxl, pScreen); + +#if 0 + uxa_set_fallback_debug(pScreen, TRUE); +#endif DamageSetup (pScreen); diff --git a/src/qxl_image.c b/src/qxl_image.c index 4d9bc77..fcecf8a 100644 --- a/src/qxl_image.c +++ b/src/qxl_image.c @@ -138,7 +138,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, struct QXLImage *image; struct QXLDataChunk *head; struct QXLDataChunk *tail; - int dest_stride = width * Bpp; + int dest_stride = (width * Bpp + 3) & (~3); int h; data += y * stride + x * Bpp; @@ -216,7 +216,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, image->bitmap.flags = SPICE_BITMAP_FLAGS_TOP_DOWN; image->bitmap.x = width; image->bitmap.y = height; - image->bitmap.stride = width * Bpp; + image->bitmap.stride = dest_stride; image->bitmap.palette = 0; image->bitmap.data = physical_address (qxl, head, qxl->main_mem_slot); diff --git a/src/qxl_surface.c b/src/qxl_surface.c index 0169350..e88675f 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -89,6 +89,17 @@ struct qxl_surface_t { qxl_surface_t *copy_src; Pixel solid_pixel; + + struct + { + int op; + PicturePtr src_picture; + PicturePtr mask_picture; + PicturePtr dest_picture; + qxl_surface_t *src; + qxl_surface_t *mask; + qxl_surface_t *dest; + } composite; } u; }; @@ -302,7 +313,7 @@ get_formats (int bpp, SpiceBitmapFmt *format, pixman_format_code_t *pformat) break; } } - + static qxl_surface_t * surface_get_from_cache (surface_cache_t *cache, int width, int height, int bpp) { @@ -674,7 +685,8 @@ retry: push_surface_cmd (cache, cmd); - dev_addr = (uint32_t *)((uint8_t *)surface->address + stride * (height - 1)); + dev_addr + = (uint32_t *)((uint8_t *)surface->address + stride * (height - 1)); surface->dev_image = pixman_image_create_bits ( pformat, width, height, dev_addr, - stride); @@ -735,7 +747,7 @@ qxl_surface_create (surface_cache_t * cache, if (!(surface = surface_get_from_cache (cache, width, height, bpp))) if (!(surface = surface_send_create (cache, width, height, bpp))) return NULL; - + surface->next = cache->live_surfaces; surface->prev = NULL; if (cache->live_surfaces) @@ -1367,6 +1379,189 @@ qxl_surface_copy (qxl_surface_t *dest, push_drawable (qxl, drawable); } +/* composite */ +Bool +qxl_surface_prepare_composite (int op, + PicturePtr src_picture, + PicturePtr mask_picture, + PicturePtr dest_picture, + qxl_surface_t * src, + qxl_surface_t * mask, + qxl_surface_t * dest) +{ + dest->u.composite.op = op; + dest->u.composite.src_picture = src_picture; + dest->u.composite.mask_picture = mask_picture; + dest->u.composite.dest_picture = dest_picture; + dest->u.composite.src = src; + dest->u.composite.mask = mask; + dest->u.composite.dest = dest; + + return TRUE; +} + +static QXLImage * +image_from_picture (qxl_screen_t *qxl, + PicturePtr picture, + qxl_surface_t *surface, + int *force_opaque) +{ + struct QXLImage *image = qxl_allocnf (qxl, sizeof *image, "image struct for picture"); + + image->descriptor.id = 0; + image->descriptor.type = SPICE_IMAGE_TYPE_SURFACE; + image->descriptor.width = 0; + image->descriptor.height = 0; + image->surface_image.surface_id = surface->id; + + if (picture->format == PICT_x8r8g8b8) + *force_opaque = TRUE; + else + *force_opaque = FALSE; + + return image; +} + +static QXLTransform * +get_transform (qxl_screen_t *qxl, PictTransform *transform) +{ + if (transform) + { + QXLTransform *qxform = qxl_allocnf (qxl, sizeof (QXLTransform), "transform"); + + qxform->t00 = transform->matrix[0][0]; + qxform->t01 = transform->matrix[0][1]; + qxform->t02 = transform->matrix[0][2]; + qxform->t10 = transform->matrix[1][0]; + qxform->t11 = transform->matrix[1][1]; + qxform->t12 = transform->matrix[1][2]; + + return qxform; + } + else + { + return NULL; + } +} + +static QXLRect +full_rect (qxl_surface_t *surface) +{ + QXLRect r; + int w = pixman_image_get_width (surface->host_image); + int h = pixman_image_get_height (surface->host_image); + + r.left = r.top = 0; + r.right = w; + r.bottom = h; + + return r; +} + +void +qxl_surface_composite (qxl_surface_t *dest, + int src_x, int src_y, + int mask_x, int mask_y, + int dest_x, int dest_y, + int width, int height) +{ + qxl_screen_t *qxl = dest->cache->qxl; + PicturePtr src = dest->u.composite.src_picture; + qxl_surface_t *qsrc = dest->u.composite.src; + PicturePtr mask = dest->u.composite.mask_picture; + qxl_surface_t *qmask = dest->u.composite.mask; + int op = dest->u.composite.op; + struct QXLDrawable *drawable; + QXLComposite *composite; + QXLRect rect; + QXLImage *img; + QXLTransform *trans; + int n_deps = 0; + int force_opaque; + +#if 0 + ErrorF ("QXL Composite: src: %x (%d %d) id: %d; \n" + " mask: id: %d\n" + " dest: %x %d %d %d %d (id: %d)\n", + dest->u.composite.src_picture->format, + dest->u.composite.src_picture->pDrawable->width, + dest->u.composite.src_picture->pDrawable->height, + dest->u.composite.src->id, + dest->u.composite.mask? dest->u.composite.mask->id : -1, + dest->u.composite.dest_picture->format, + dest_x, dest_y, width, height, + dest->id + ); +#endif + + rect.left = dest_x; + rect.right = dest_x + width; + rect.top = dest_y; + rect.bottom = dest_y + height; + + drawable = make_drawable (qxl, dest->id, QXL_DRAW_COMPOSITE, &rect); + + composite = &drawable->u.composite; + + composite->flags = 0; + + if (dest->u.composite.dest_picture->format == PICT_x8r8g8b8) + composite->flags |= SPICE_COMPOSITE_DEST_OPAQUE; + + composite->flags |= (op & 0xff); + + img = image_from_picture (qxl, src, qsrc, &force_opaque); + if (force_opaque) + composite->flags |= SPICE_COMPOSITE_SOURCE_OPAQUE; + composite->src = physical_address (qxl, img, qxl->main_mem_slot); + composite->flags |= (src->filter << 8); + composite->flags |= (src->repeat << 14); + trans = get_transform (qxl, src->transform); + composite->src_transform = trans? + physical_address (qxl, trans, qxl->main_mem_slot) : 0x00000000; + + drawable->surfaces_dest[n_deps] = qsrc->id; + drawable->surfaces_rects[n_deps] = full_rect (qsrc); + + n_deps++; + + if (mask) + { + img = image_from_picture (qxl, mask, qmask, &force_opaque); + if (force_opaque) + composite->flags |= SPICE_COMPOSITE_MASK_OPAQUE; + composite->mask = physical_address (qxl, img, qxl->main_mem_slot); + composite->flags |= (mask->filter << 11); + composite->flags |= (mask->repeat << 16); + composite->flags |= (mask->componentAlpha << 18); + + drawable->surfaces_dest[n_deps] = qmask->id; + drawable->surfaces_rects[n_deps] = full_rect (qmask); + n_deps++; + + trans = get_transform (qxl, src->transform); + composite->mask_transform = trans? + physical_address (qxl, trans, qxl->main_mem_slot) : 0x00000000; + } + else + { + composite->mask = 0x00000000; + composite->mask_transform = 0x00000000; + } + + drawable->surfaces_dest[n_deps] = dest->id; + drawable->surfaces_rects[n_deps] = full_rect (dest); + + composite->src_origin.x = src_x; + composite->src_origin.y = src_y; + composite->mask_origin.x = mask_x; + composite->mask_origin.y = mask_y; + + drawable->effect = QXL_EFFECT_BLEND; + + push_drawable (qxl, drawable); +} + Bool qxl_surface_put_image (qxl_surface_t *dest, int x, int y, int width, int height, commit 2fecf3a171e64ca0dad5653ed740409dc5af2edf Author: Søren Sandmann <[email protected]> Date: Tue Dec 20 09:01:17 2011 -0500 Enable 8 bit pixmaps. a8 surfaces are now supported with the 8BIT_A format in spice, so we can have support 8 bit pixmaps. diff --git a/src/qxl_image.c b/src/qxl_image.c index 6211035..4d9bc77 100644 --- a/src/qxl_image.c +++ b/src/qxl_image.c @@ -202,7 +202,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, } else if (Bpp == 1) { - image->bitmap.format = SPICE_BITMAP_FMT_8BIT; + image->bitmap.format = SPICE_BITMAP_FMT_8BIT_A; } else if (Bpp == 4) { diff --git a/src/qxl_surface.c b/src/qxl_surface.c index 579a284..0169350 100644 --- a/src/qxl_surface.c +++ b/src/qxl_surface.c @@ -706,6 +706,7 @@ qxl_surface_create (surface_cache_t * cache, return NULL; } +#if 0 if (bpp == 8) { static int warned; @@ -717,6 +718,7 @@ qxl_surface_create (surface_cache_t * cache, return NULL; } +#endif if (bpp != 8 && bpp != 16 && bpp != 32 && bpp != 24) { commit 37c97620da959d9214abfc760835aa3031d54daa Author: Søren Sandmann <[email protected]> Date: Sun Aug 12 11:03:16 2012 -0400 Use an RGBA format for 32 bit images With the upcoming Render changes, we can no longer assume that the fourth channel of images is unused. diff --git a/src/qxl_image.c b/src/qxl_image.c index 68d063e..6211035 100644 --- a/src/qxl_image.c +++ b/src/qxl_image.c @@ -206,7 +206,7 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, } else if (Bpp == 4) { - image->bitmap.format = SPICE_BITMAP_FMT_32BIT; + image->bitmap.format = SPICE_BITMAP_FMT_RGBA; } else { @@ -220,10 +220,6 @@ qxl_image_create (qxl_screen_t *qxl, const uint8_t *data, image->bitmap.palette = 0; image->bitmap.data = physical_address (qxl, head, qxl->main_mem_slot); -#if 0 - ErrorF ("%p has size %d %d\n", image, width, height); -#endif - /* Add to hash table if caching is enabled */ if ((fallback && qxl->enable_fallback_cache) || (!fallback && qxl->enable_image_cache)) commit 1e89aab2dc0beb01f43a2397faa05a8cd01a7547 Author: Søren Sandmann <[email protected]> Date: Wed Aug 22 15:27:09 2012 -0400 uxa: Plug leak in uxa_glyphs_via_masks If prepare_composite() fails, we need to free the temporary mask before returning. diff --git a/src/uxa/uxa-glyphs.c b/src/uxa/uxa-glyphs.c index 997feb7..6dd8e58 100644 --- a/src/uxa/uxa-glyphs.c +++ b/src/uxa/uxa-glyphs.c @@ -992,8 +992,10 @@ uxa_glyphs_via_mask(CARD8 op, if (!uxa_screen->info->prepare_composite(PictOpAdd, this_atlas, NULL, mask, - src_pixmap, NULL, pixmap)) + src_pixmap, NULL, pixmap)) { + FreePicture(mask, 0); return -1; + } glyph_atlas = this_atlas; } commit afd8d20b84a4b4e9b22483e379d594517333e8c7 Author: Søren Sandmann <[email protected]> Date: Tue Aug 14 14:20:11 2012 -0400 uxa-glyphs: don't prepare composite when dest is not offscreen It is possbible for a pixmap to not be in video memory after uxa_clear_pixmap() was called. When this happens, we need to destroy the pixmap and return 1 to indicate that the operation can't be accelerated. diff --git a/src/uxa/uxa-glyphs.c b/src/uxa/uxa-glyphs.c index dd50dfc..997feb7 100644 --- a/src/uxa/uxa-glyphs.c +++ b/src/uxa/uxa-glyphs.c @@ -932,6 +932,11 @@ uxa_glyphs_via_mask(CARD8 op, uxa_clear_pixmap(screen, uxa_screen, pixmap); + if (!uxa_pixmap_is_offscreen(pixmap)) { + screen->DestroyPixmap(pixmap); + return 1; + } + component_alpha = NeedsComponent(maskFormat->format); mask = CreatePicture(0, &pixmap->drawable, maskFormat, CPComponentAlpha, commit e738d00e1fb3cd469f850765e2b42976c2a85764 Author: Søren Sandmann <[email protected]> Date: Tue Aug 21 12:56:52 2012 -0400 Improved support for memory debugging. Make all memory allocation functions take a string that will explain what the memory will be used for. This allows debug print statements to be added to the allocation functions and could later potentially be used for more detailed statistics. diff --git a/src/qxl.h b/src/qxl.h index 1d9ca75..d976fd5 100644 --- a/src/qxl.h +++ b/src/qxl.h @@ -446,12 +446,15 @@ struct qxl_mem * qxl_mem_create (void *base, void qxl_mem_dump_stats (struct qxl_mem *mem, const char *header); void * qxl_alloc (struct qxl_mem *mem, - unsigned long n_bytes); + unsigned long n_bytes, + const char * name); void qxl_free (struct qxl_mem *mem, - void *d); + void *d, + const char * name); void qxl_mem_free_all (struct qxl_mem *mem); void * qxl_allocnf (qxl_screen_t *qxl, - unsigned long size); + unsigned long size, + const char * name); int qxl_garbage_collect (qxl_screen_t *qxl); #ifdef DEBUG_QXL_MEM diff --git a/src/qxl_cursor.c b/src/qxl_cursor.c index 72c6c9f..459cbd7 100644 --- a/src/qxl_cursor.c +++ b/src/qxl_cursor.c @@ -50,7 +50,7 @@ static struct QXLCursorCmd * qxl_alloc_cursor_cmd(qxl_screen_t *qxl) { struct QXLCursorCmd *cmd = - qxl_allocnf (qxl, sizeof(struct QXLCursorCmd)); + qxl_allocnf (qxl, sizeof(struct QXLCursorCmd), "cursor command"); cmd->release_info.id = pointer_to_u64 (cmd) | 1; @@ -94,7 +94,7 @@ qxl_load_cursor_argb (ScrnInfoPtr pScrn, CursorPtr pCurs) struct QXLCursorCmd *cmd = qxl_alloc_cursor_cmd (qxl); struct QXLCursor *cursor = - qxl_allocnf(qxl, sizeof(struct QXLCursor) + size); + qxl_allocnf(qxl, sizeof(struct QXLCursor) + size, "cursor data"); cursor->header.unique = 0; cursor->header.type = SPICE_CURSOR_TYPE_ALPHA; diff --git a/src/qxl_driver.c b/src/qxl_driver.c index 7535e11..634f181 100644 --- a/src/qxl_driver.c +++ b/src/qxl_driver.c @@ -331,7 +331,7 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id) * question is a cursor command */ #define POINTER_MASK ((1 << 2) - 1) - + union QXLReleaseInfo *info = u64_to_pointer (id & ~POINTER_MASK); struct QXLCursorCmd *cmd = (struct QXLCursorCmd *)info; struct QXLDrawable *drawable = (struct QXLDrawable *)info; @@ -339,34 +339,31 @@ qxl_garbage_collect_internal (qxl_screen_t *qxl, uint64_t id) int is_cursor = FALSE; int is_surface = FALSE; int is_drawable = FALSE; - + if ((id & POINTER_MASK) == 1) is_cursor = TRUE; else if ((id & POINTER_MASK) == 2) -- To UNSUBSCRIBE, email to [email protected] with a subject of "unsubscribe". Trouble? Contact [email protected] Archive: http://lists.debian.org/[email protected]

