aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/xgl/xglpixmap.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
committermarha <marha@users.sourceforge.net>2009-06-28 22:07:26 +0000
commit3562e78743202e43aec8727005182a2558117eca (patch)
tree8f9113a77d12470c5c851a2a8e4cb02e89df7d43 /xorg-server/hw/xgl/xglpixmap.c
downloadvcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.gz
vcxsrv-3562e78743202e43aec8727005182a2558117eca.tar.bz2
vcxsrv-3562e78743202e43aec8727005182a2558117eca.zip
Checked in the following released items:
xkeyboard-config-1.4.tar.gz ttf-bitstream-vera-1.10.tar.gz font-alias-1.0.1.tar.gz font-sun-misc-1.0.0.tar.gz font-sun-misc-1.0.0.tar.gz font-sony-misc-1.0.0.tar.gz font-schumacher-misc-1.0.0.tar.gz font-mutt-misc-1.0.0.tar.gz font-misc-misc-1.0.0.tar.gz font-misc-meltho-1.0.0.tar.gz font-micro-misc-1.0.0.tar.gz font-jis-misc-1.0.0.tar.gz font-isas-misc-1.0.0.tar.gz font-dec-misc-1.0.0.tar.gz font-daewoo-misc-1.0.0.tar.gz font-cursor-misc-1.0.0.tar.gz font-arabic-misc-1.0.0.tar.gz font-winitzki-cyrillic-1.0.0.tar.gz font-misc-cyrillic-1.0.0.tar.gz font-cronyx-cyrillic-1.0.0.tar.gz font-screen-cyrillic-1.0.1.tar.gz font-xfree86-type1-1.0.1.tar.gz font-adobe-utopia-type1-1.0.1.tar.gz font-ibm-type1-1.0.0.tar.gz font-bitstream-type1-1.0.0.tar.gz font-bitstream-speedo-1.0.0.tar.gz font-bh-ttf-1.0.0.tar.gz font-bh-type1-1.0.0.tar.gz font-bitstream-100dpi-1.0.0.tar.gz font-bh-lucidatypewriter-100dpi-1.0.0.tar.gz font-bh-100dpi-1.0.0.tar.gz font-adobe-utopia-100dpi-1.0.1.tar.gz font-adobe-100dpi-1.0.0.tar.gz font-util-1.0.1.tar.gz font-bitstream-75dpi-1.0.0.tar.gz font-bh-lucidatypewriter-75dpi-1.0.0.tar.gz font-adobe-utopia-75dpi-1.0.1.tar.gz font-bh-75dpi-1.0.0.tar.gz bdftopcf-1.0.1.tar.gz font-adobe-75dpi-1.0.0.tar.gz mkfontscale-1.0.6.tar.gz openssl-0.9.8k.tar.gz bigreqsproto-1.0.2.tar.gz xtrans-1.2.2.tar.gz resourceproto-1.0.2.tar.gz inputproto-1.4.4.tar.gz compositeproto-0.4.tar.gz damageproto-1.1.0.tar.gz zlib-1.2.3.tar.gz xkbcomp-1.0.5.tar.gz freetype-2.3.9.tar.gz pthreads-w32-2-8-0-release.tar.gz pixman-0.12.0.tar.gz kbproto-1.0.3.tar.gz evieext-1.0.2.tar.gz fixesproto-4.0.tar.gz recordproto-1.13.2.tar.gz randrproto-1.2.2.tar.gz scrnsaverproto-1.1.0.tar.gz renderproto-0.9.3.tar.gz xcmiscproto-1.1.2.tar.gz fontsproto-2.0.2.tar.gz xextproto-7.0.3.tar.gz xproto-7.0.14.tar.gz libXdmcp-1.0.2.tar.gz libxkbfile-1.0.5.tar.gz libfontenc-1.0.4.tar.gz libXfont-1.3.4.tar.gz libX11-1.1.5.tar.gz libXau-1.0.4.tar.gz libxcb-1.1.tar.gz xorg-server-1.5.3.tar.gz
Diffstat (limited to 'xorg-server/hw/xgl/xglpixmap.c')
-rw-r--r--xorg-server/hw/xgl/xglpixmap.c744
1 files changed, 744 insertions, 0 deletions
diff --git a/xorg-server/hw/xgl/xglpixmap.c b/xorg-server/hw/xgl/xglpixmap.c
new file mode 100644
index 000000000..8e602cee3
--- /dev/null
+++ b/xorg-server/hw/xgl/xglpixmap.c
@@ -0,0 +1,744 @@
+/*
+ * Copyright © 2004 David Reveman
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * David Reveman not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior permission.
+ * David Reveman makes no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+ * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: David Reveman <davidr@novell.com>
+ */
+
+#include "xgl.h"
+#include "fb.h"
+
+static glitz_buffer_hint_t xglPixmapUsageHints[] = {
+ (glitz_buffer_hint_t) 0, /* reserved for system memory */
+ GLITZ_BUFFER_HINT_STREAM_DRAW,
+ GLITZ_BUFFER_HINT_STREAM_READ,
+ GLITZ_BUFFER_HINT_STREAM_COPY,
+ GLITZ_BUFFER_HINT_STATIC_DRAW,
+ GLITZ_BUFFER_HINT_STATIC_READ,
+ GLITZ_BUFFER_HINT_STATIC_COPY,
+ GLITZ_BUFFER_HINT_DYNAMIC_DRAW,
+ GLITZ_BUFFER_HINT_DYNAMIC_READ,
+ GLITZ_BUFFER_HINT_DYNAMIC_COPY
+};
+
+#define NUM_XGL_PIXMAP_USAGE_HINTS \
+ (sizeof (xglPixmapUsageHints) / sizeof (xglPixmapUsageHints[0]))
+
+#define XGL_PIXMAP_USAGE_HINT(hint) (xglPixmapUsageHints[hint])
+
+static void
+xglPixmapDamageReport (DamagePtr pDamage,
+ RegionPtr pRegion,
+ void *closure)
+{
+ PixmapPtr pPixmap = (PixmapPtr) closure;
+ BoxPtr pExt;
+
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ pExt = REGION_EXTENTS (pPixmap->drawable.pScreen, pRegion);
+
+ if (BOX_NOTEMPTY (&pPixmapPriv->damageBox))
+ {
+ if (pExt->x1 < pPixmapPriv->damageBox.x1)
+ pPixmapPriv->damageBox.x1 = pExt->x1;
+
+ if (pExt->y1 < pPixmapPriv->damageBox.y1)
+ pPixmapPriv->damageBox.y1 = pExt->y1;
+
+ if (pExt->x2 > pPixmapPriv->damageBox.x2)
+ pPixmapPriv->damageBox.x2 = pExt->x2;
+
+ if (pExt->y2 > pPixmapPriv->damageBox.y2)
+ pPixmapPriv->damageBox.y2 = pExt->y2;
+ }
+ else
+ pPixmapPriv->damageBox = *pExt;
+}
+
+
+static Bool
+xglPixmapCreateDamage (PixmapPtr pPixmap)
+{
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ pPixmapPriv->pDamage =
+ DamageCreate (xglPixmapDamageReport, (DamageDestroyFunc) 0,
+ DamageReportRawRegion, TRUE,
+ pPixmap->drawable.pScreen,
+ (void *) pPixmap);
+ if (!pPixmapPriv->pDamage)
+ return FALSE;
+
+ DamageRegister (&pPixmap->drawable, pPixmapPriv->pDamage);
+
+ return TRUE;
+}
+
+void
+xglSetPixmapVisual (PixmapPtr pPixmap,
+ xglVisualPtr pVisual)
+{
+ xglVisualPtr pOldVisual;
+
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ pOldVisual = pPixmapPriv->pVisual;
+ if (pOldVisual && pVisual)
+ {
+ glitz_surface_t *surface;
+
+ if (pOldVisual->vid != pVisual->vid)
+ {
+ surface = pPixmapPriv->surface;
+ if (surface)
+ {
+ glitz_drawable_t *drawable;
+
+ drawable = glitz_surface_get_attached_drawable (surface);
+ if (drawable)
+ {
+ if (pOldVisual->format.drawable->id !=
+ pVisual->format.drawable->id)
+ {
+ glitz_surface_detach (pPixmapPriv->surface);
+ pPixmapPriv->target = xglPixmapTargetOut;
+ }
+ }
+
+ if (pOldVisual->format.surface->id != pVisual->format.surface->id)
+ {
+ xglSyncBits (&pPixmap->drawable, NULL);
+ glitz_surface_destroy (pPixmapPriv->surface);
+ pPixmapPriv->surface = 0;
+ }
+ }
+ }
+ }
+ else if (pOldVisual)
+ {
+ if (pPixmapPriv->surface)
+ {
+ xglSyncBits (&pPixmap->drawable, NULL);
+ glitz_surface_destroy (pPixmapPriv->surface);
+ pPixmapPriv->surface = 0;
+ }
+ pPixmapPriv->target = xglPixmapTargetNo;
+ }
+
+ pPixmapPriv->pVisual = pVisual;
+
+ if (pPixmapPriv->pVisual && pPixmapPriv->pVisual->format.surface)
+ {
+ if (!pPixmapPriv->pDamage)
+ {
+ if (!xglPixmapCreateDamage (pPixmap))
+ FatalError (XGL_SW_FAILURE_STRING);
+ }
+ }
+}
+
+static Bool
+xglPixmapSurfaceInit (PixmapPtr pPixmap,
+ unsigned long features,
+ int width,
+ int height)
+{
+ BoxRec box;
+
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ pPixmapPriv->surface = NULL;
+ pPixmapPriv->drawable = NULL;
+ pPixmapPriv->acceleratedTile = FALSE;
+ pPixmapPriv->pictureMask = ~0;
+ pPixmapPriv->target = xglPixmapTargetNo;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+
+ REGION_INIT (pScreen, &pPixmapPriv->bitRegion, &box, 1);
+
+ pPixmapPriv->pVisual = xglFindVisualWithDepth (pPixmap->drawable.pScreen,
+ pPixmap->drawable.depth);
+ if (pPixmapPriv->pVisual)
+ {
+ XGL_SCREEN_PRIV (pPixmap->drawable.pScreen);
+
+ /* general pixmap acceleration */
+ if (pPixmapPriv->pVisual->format.drawable &&
+ pScreenPriv->accel.pixmap.enabled &&
+ xglCheckPixmapSize (pPixmap, &pScreenPriv->accel.pixmap.size))
+ pPixmapPriv->target = xglPixmapTargetOut;
+ }
+
+ if (pPixmapPriv->pVisual && pPixmapPriv->pVisual->format.surface)
+ {
+ if (!pPixmapPriv->pDamage)
+ {
+ if (!xglPixmapCreateDamage (pPixmap))
+ FatalError (XGL_SW_FAILURE_STRING);
+ }
+
+ if (width && height)
+ {
+ if (width == 1 && height == 1)
+ {
+ pPixmapPriv->acceleratedTile = TRUE;
+ }
+ else if (features & GLITZ_FEATURE_TEXTURE_BORDER_CLAMP_MASK)
+ {
+ if ((features & GLITZ_FEATURE_TEXTURE_NON_POWER_OF_TWO_MASK) ||
+ (POWER_OF_TWO (width) && POWER_OF_TWO (height)))
+ pPixmapPriv->acceleratedTile = TRUE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+PixmapPtr
+xglCreatePixmap (ScreenPtr pScreen,
+ int width,
+ int height,
+ int depth,
+ unsigned usage_hint)
+{
+ xglPixmapPtr pPixmapPriv;
+ PixmapPtr pPixmap;
+
+ XGL_SCREEN_PRIV (pScreen);
+
+ pPixmap = AllocatePixmap (pScreen, 0);
+ if (!pPixmap)
+ return NullPixmap;
+
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = BitsPerPixel (depth);
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+
+#ifdef COMPOSITE
+ pPixmap->screen_x = 0;
+ pPixmap->screen_y = 0;
+#endif
+
+ pPixmap->devKind = 0;
+ pPixmap->refcnt = 1;
+ pPixmap->devPrivate.ptr = 0;
+ pPixmap->usage_hint = usage_hint;
+
+ pPixmapPriv = XGL_GET_PIXMAP_PRIV (pPixmap);
+
+ pPixmapPriv->pVisual = NULL;
+ pPixmapPriv->pDamage = NULL;
+
+ if (!xglPixmapSurfaceInit (pPixmap, pScreenPriv->features, width, height))
+ return NullPixmap;
+
+ pPixmapPriv->buffer = NULL;
+ pPixmapPriv->bits = (pointer) 0;
+ pPixmapPriv->stride = 0;
+ pPixmapPriv->pGeometry = NULL;
+ pPixmapPriv->allBits = TRUE;
+
+ pPixmapPriv->damageBox = miEmptyBox;
+
+ return pPixmap;
+}
+
+void
+xglFiniPixmap (PixmapPtr pPixmap)
+{
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (pPixmap->devPrivate.ptr)
+ {
+ if (pPixmapPriv->buffer)
+ glitz_buffer_unmap (pPixmapPriv->buffer);
+ }
+
+ if (pPixmapPriv->pGeometry)
+ GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
+
+ if (pPixmapPriv->buffer)
+ glitz_buffer_destroy (pPixmapPriv->buffer);
+
+ if (pPixmapPriv->bits)
+ xfree (pPixmapPriv->bits);
+
+ REGION_UNINIT (pPixmap->drawable.pScreen, &pPixmapPriv->bitRegion);
+
+ if (pPixmapPriv->drawable)
+ glitz_drawable_destroy (pPixmapPriv->drawable);
+
+ if (pPixmapPriv->surface)
+ glitz_surface_destroy (pPixmapPriv->surface);
+}
+
+Bool
+xglDestroyPixmap (PixmapPtr pPixmap)
+{
+ if (--pPixmap->refcnt)
+ return TRUE;
+
+ xglFiniPixmap (pPixmap);
+
+ dixFreePrivates(pPixmap->devPrivates);
+ xfree (pPixmap);
+
+ return TRUE;
+}
+
+Bool
+xglModifyPixmapHeader (PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ pointer pPixData)
+{
+ xglScreenPtr pScreenPriv;
+ xglPixmapPtr pPixmapPriv;
+ int oldWidth, oldHeight;
+
+ if (!pPixmap)
+ return FALSE;
+
+ pScreenPriv = XGL_GET_SCREEN_PRIV (pPixmap->drawable.pScreen);
+ pPixmapPriv = XGL_GET_PIXMAP_PRIV (pPixmap);
+
+ oldWidth = pPixmap->drawable.width;
+ oldHeight = pPixmap->drawable.height;
+
+ if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) &&
+ (devKind > 0) && pPixData)
+ {
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmapPriv->stride = devKind;
+ pPixmap->refcnt = 1;
+ }
+ else
+ {
+ if (width > 0)
+ pPixmap->drawable.width = width;
+
+ if (height > 0)
+ pPixmap->drawable.height = height;
+
+ if (depth > 0)
+ pPixmap->drawable.depth = depth;
+
+ if (bitsPerPixel > 0)
+ pPixmap->drawable.bitsPerPixel = bitsPerPixel;
+ else if ((bitsPerPixel < 0) && (depth > 0))
+ pPixmap->drawable.bitsPerPixel = BitsPerPixel (depth);
+
+ if (devKind > 0)
+ pPixmapPriv->stride = devKind;
+ else if ((devKind < 0) && ((width > 0) || (depth > 0)))
+ pPixmapPriv->stride = PixmapBytePad (pPixmap->drawable.width,
+ pPixmap->drawable.depth);
+ }
+
+ if (pPixmap->drawable.width != oldWidth ||
+ pPixmap->drawable.height != oldHeight)
+ {
+ pPixmapPriv->pVisual = NULL;
+ pPixmapPriv->target = xglPixmapTargetNo;
+
+ if (pPixmapPriv->drawable)
+ glitz_drawable_destroy (pPixmapPriv->drawable);
+
+ if (pPixmapPriv->surface)
+ glitz_surface_destroy (pPixmapPriv->surface);
+
+ REGION_UNINIT (pPixmap->drawable.pScreen, &pPixmapPriv->bitRegion);
+
+ if (!xglPixmapSurfaceInit (pPixmap,
+ pScreenPriv->features,
+ pPixmap->drawable.width,
+ pPixmap->drawable.height))
+ return FALSE;
+ }
+
+ if (pPixData)
+ {
+ BoxRec box;
+
+ if (pPixmap->devPrivate.ptr)
+ {
+ if (pPixmapPriv->buffer)
+ glitz_buffer_unmap (pPixmapPriv->buffer);
+
+ pPixmap->devPrivate.ptr = 0;
+ }
+
+ if (pPixmapPriv->pGeometry)
+ {
+ GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
+ pPixmapPriv->pGeometry = NULL;
+ }
+
+ if (pPixmapPriv->buffer)
+ glitz_buffer_destroy (pPixmapPriv->buffer);
+
+ if (pPixmapPriv->bits)
+ xfree (pPixmapPriv->bits);
+
+ pPixmapPriv->bits = (pointer) 0;
+ pPixmapPriv->buffer = glitz_buffer_create_for_data (pPixData);
+ if (!pPixmapPriv->buffer)
+ return FALSE;
+
+ pPixmapPriv->allBits = TRUE;
+
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pPixmap->drawable.width;
+ box.y2 = pPixmap->drawable.height;
+
+ REGION_UNINIT (pPixmap->drawable.pScreen, &pPixmapPriv->bitRegion);
+ REGION_INIT (pPixmap->drawable.pScreen, &pPixmapPriv->bitRegion,
+ &box, 1);
+
+ if (pPixmapPriv->pDamage)
+ {
+ RegionPtr pRegion;
+
+ pRegion = DamageRegion (pPixmapPriv->pDamage);
+
+ REGION_UNINIT (pPixmap->drawable.pScreen, pRegion);
+ REGION_INIT (pPixmap->drawable.pScreen, pRegion, NullBox, 0);
+ REGION_SUBTRACT (pPixmap->drawable.pScreen, pRegion,
+ &pPixmapPriv->bitRegion, pRegion);
+
+ }
+ }
+
+ /*
+ * Screen pixmap
+ */
+ if (!pScreenPriv->pScreenPixmap || pScreenPriv->pScreenPixmap == pPixmap)
+ {
+ if (!pPixmapPriv->drawable)
+ {
+ glitz_drawable_reference (pScreenPriv->drawable);
+ pPixmapPriv->drawable = pScreenPriv->drawable;
+ }
+
+ if (!pPixmapPriv->surface)
+ {
+ glitz_surface_reference (pScreenPriv->surface);
+ pPixmapPriv->surface = pScreenPriv->surface;
+ }
+
+ pPixmapPriv->pVisual = pScreenPriv->rootVisual;
+ pPixmapPriv->target = xglPixmapTargetIn;
+
+ if (!pScreenPriv->pScreenPixmap)
+ pScreenPriv->pScreenPixmap = pPixmap;
+ }
+
+ return TRUE;
+}
+
+RegionPtr
+xglPixmapToRegion (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ RegionPtr pRegion;
+
+ XGL_SCREEN_PRIV (pScreen);
+
+ if (!xglSyncBits (&pPixmap->drawable, NullBox))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ XGL_SCREEN_UNWRAP (BitmapToRegion);
+ pRegion = (*pScreen->BitmapToRegion) (pPixmap);
+ XGL_SCREEN_WRAP (BitmapToRegion, xglPixmapToRegion);
+
+ return pRegion;
+}
+
+xglGeometryPtr
+xglPixmapToGeometry (PixmapPtr pPixmap,
+ int xOff,
+ int yOff)
+{
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (pPixmap->devPrivate.ptr)
+ xglUnmapPixmapBits (pPixmap);
+
+ if (!pPixmapPriv->pGeometry)
+ {
+ xglGeometryPtr pGeometry;
+
+ if (!pPixmapPriv->buffer)
+ {
+ if (!xglAllocatePixmapBits (pPixmap,
+ XGL_PIXMAP_USAGE_HINT_DEFAULT))
+ return NULL;
+ }
+
+ pGeometry = xalloc (sizeof (xglGeometryRec));
+ if (!pGeometry)
+ return NULL;
+
+ GEOMETRY_INIT (pPixmap->drawable.pScreen, pGeometry,
+ GLITZ_GEOMETRY_TYPE_BITMAP,
+ GEOMETRY_USAGE_DYNAMIC, 0);
+
+ GEOMETRY_SET_BUFFER (pGeometry, pPixmapPriv->buffer);
+
+ if (pPixmapPriv->stride < 0)
+ {
+ pGeometry->f.bitmap.bytes_per_line = -pPixmapPriv->stride;
+ pGeometry->f.bitmap.scanline_order =
+ GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
+ }
+ else
+ {
+ pGeometry->f.bitmap.bytes_per_line = pPixmapPriv->stride;
+ pGeometry->f.bitmap.scanline_order =
+ GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+ }
+
+ pGeometry->f.bitmap.pad = ((1 + FB_MASK) >> FB_SHIFT) *
+ sizeof (FbBits);
+ pGeometry->width = pPixmap->drawable.width;
+ pGeometry->count = pPixmap->drawable.height;
+
+ pPixmapPriv->pGeometry = pGeometry;
+ }
+
+ pPixmapPriv->pGeometry->xOff = xOff << 16;
+ pPixmapPriv->pGeometry->yOff = yOff << 16;
+
+ return pPixmapPriv->pGeometry;
+}
+
+Bool
+xglCreatePixmapSurface (PixmapPtr pPixmap)
+{
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (!pPixmapPriv->surface)
+ {
+ XGL_SCREEN_PRIV (pPixmap->drawable.pScreen);
+
+ if (!pPixmapPriv->pVisual || !pPixmapPriv->pVisual->format.surface)
+ return FALSE;
+
+ pPixmapPriv->surface =
+ glitz_surface_create (pScreenPriv->drawable,
+ pPixmapPriv->pVisual->format.surface,
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ 0, NULL);
+ if (!pPixmapPriv->surface)
+ {
+ pPixmapPriv->pVisual = NULL;
+ pPixmapPriv->target = xglPixmapTargetNo;
+
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+Bool
+xglAllocatePixmapBits (PixmapPtr pPixmap, int hint)
+{
+ int width, height, bpp, stride;
+
+ XGL_PIXMAP_PRIV (pPixmap);
+ XGL_SCREEN_PRIV (pPixmap->drawable.pScreen);
+
+ width = pPixmap->drawable.width;
+ height = pPixmap->drawable.height;
+ bpp = pPixmap->drawable.bitsPerPixel;
+
+ stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
+
+ if (stride)
+ {
+ glitz_buffer_t *buffer;
+
+ if ((pScreenPriv->pboMask & bpp) && hint)
+ {
+ buffer = glitz_pixel_buffer_create (pScreenPriv->drawable,
+ NULL, height * stride,
+ XGL_PIXMAP_USAGE_HINT (hint));
+ }
+ else
+ {
+ pPixmapPriv->bits = xalloc (height * stride);
+ if (!pPixmapPriv->bits)
+ return FALSE;
+
+ buffer = glitz_buffer_create_for_data (pPixmapPriv->bits);
+ }
+
+ if (!buffer)
+ {
+ if (pPixmapPriv->bits)
+ xfree (pPixmapPriv->bits);
+ pPixmapPriv->bits = NULL;
+ return FALSE;
+ }
+ pPixmapPriv->buffer = buffer;
+ }
+
+ if (pScreenPriv->yInverted)
+ pPixmapPriv->stride = stride;
+ else
+ pPixmapPriv->stride = -stride;
+
+ return TRUE;
+}
+
+Bool
+xglMapPixmapBits (PixmapPtr pPixmap)
+{
+ if (!pPixmap->devPrivate.ptr)
+ {
+ CARD8 *bits;
+
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (!pPixmapPriv->buffer)
+ if (!xglAllocatePixmapBits (pPixmap,
+ XGL_PIXMAP_USAGE_HINT_DEFAULT))
+ return FALSE;
+
+ bits = glitz_buffer_map (pPixmapPriv->buffer,
+ GLITZ_BUFFER_ACCESS_READ_WRITE);
+ if (!bits)
+ return FALSE;
+
+ pPixmap->devKind = pPixmapPriv->stride;
+ if (pPixmapPriv->stride < 0)
+ {
+ pPixmap->devPrivate.ptr = bits +
+ (pPixmap->drawable.height - 1) * -pPixmapPriv->stride;
+ }
+ else
+ {
+ pPixmap->devPrivate.ptr = bits;
+ }
+ }
+
+ return TRUE;
+}
+
+Bool
+xglUnmapPixmapBits (PixmapPtr pPixmap)
+{
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ pPixmap->devKind = 0;
+ pPixmap->devPrivate.ptr = 0;
+
+ if (pPixmapPriv->buffer)
+ if (glitz_buffer_unmap (pPixmapPriv->buffer))
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+xglCheckPixmapSize (PixmapPtr pPixmap,
+ xglSizeConstraintPtr pSize)
+{
+ if (pPixmap->drawable.width < pSize->minWidth ||
+ pPixmap->drawable.height < pSize->minHeight)
+ return FALSE;
+
+ if (pPixmap->drawable.width > pSize->aboveWidth ||
+ pPixmap->drawable.height > pSize->aboveHeight)
+ return TRUE;
+
+ return FALSE;
+}
+
+void
+xglEnablePixmapAccel (PixmapPtr pPixmap,
+ xglAccelInfoPtr pAccel)
+{
+ XGL_SCREEN_PRIV (pPixmap->drawable.pScreen);
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (pAccel->enabled && xglCheckPixmapSize (pPixmap, &pAccel->size))
+ {
+ xglVisualPtr v;
+
+ if (pAccel->pbuffer)
+ {
+ for (v = pScreenPriv->pVisual; v; v = v->next)
+ {
+ if (v->pPixel->depth != pPixmap->drawable.depth)
+ continue;
+
+ if (v->format.drawable && v->pbuffer)
+ break;
+ }
+ }
+ else
+ {
+ for (v = pScreenPriv->pVisual; v; v = v->next)
+ {
+ if (v->pPixel->depth != pPixmap->drawable.depth)
+ continue;
+
+ if (v->format.drawable && !v->pbuffer)
+ break;
+ }
+ }
+
+ if (v)
+ {
+ xglSetPixmapVisual (pPixmap, v);
+ if (!pPixmapPriv->target)
+ pPixmapPriv->target = xglPixmapTargetOut;
+ }
+ }
+}