summaryrefslogtreecommitdiff
path: root/hw/xgl/xglpixmap.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@linux.ie>2006-01-18 07:15:55 +0000
committerDave Airlie <airlied@linux.ie>2006-01-18 07:15:55 +0000
commite70b64b93024d05519014fb1b76fe26bd9f3a496 (patch)
treeadde5d80999ebeed1bf361eafbae114a9d65dc93 /hw/xgl/xglpixmap.c
parentb5356e0afaf2b660c8905f63d5fdcb03402b81c5 (diff)
Updated xgl code drop from Novell + xserver tree changes
Diffstat (limited to 'hw/xgl/xglpixmap.c')
-rw-r--r--hw/xgl/xglpixmap.c353
1 files changed, 248 insertions, 105 deletions
diff --git a/hw/xgl/xglpixmap.c b/hw/xgl/xglpixmap.c
index 8f043081e..368c3eaeb 100644
--- a/hw/xgl/xglpixmap.c
+++ b/hw/xgl/xglpixmap.c
@@ -1,6 +1,6 @@
/*
* 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
@@ -12,11 +12,11 @@
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
- * DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * 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,
+ * 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.
*
@@ -69,7 +69,8 @@ xglPixmapDamageReport (DamagePtr pDamage,
if (pExt->y2 > pPixmapPriv->damageBox.y2)
pPixmapPriv->damageBox.y2 = pExt->y2;
- } else
+ }
+ else
pPixmapPriv->damageBox = *pExt;
}
@@ -88,34 +89,119 @@ xglPixmapCreateDamage (PixmapPtr pPixmap)
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;
- pPixmapPriv->lock = 0;
- if (pPixmapPriv->format)
+ 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)
{
- XGL_SCREEN_PRIV (pPixmap->drawable.pScreen);
-
if (width == 1 && height == 1)
{
pPixmapPriv->acceleratedTile = TRUE;
@@ -126,28 +212,6 @@ xglPixmapSurfaceInit (PixmapPtr pPixmap,
(POWER_OF_TWO (width) && POWER_OF_TWO (height)))
pPixmapPriv->acceleratedTile = TRUE;
}
-
- /*
- * Accelerated drawing to pixmaps when using FBOs
- */
- if (pScreenPriv->fbo)
- {
- pPixmapPriv->target = xglPixmapTargetOut;
-
- /*
- * Do not allow accelerated drawing to bitmaps.
- */
- if (pPixmap->drawable.depth == 1)
- pPixmapPriv->target = xglPixmapTargetNo;
-
- /*
- * Drawing to really small pixmaps is not worth accelerating.
- */
- if (width < 8 && height < 8)
- pPixmapPriv->target = xglPixmapTargetNo;
- }
- else
- pPixmapPriv->target = xglPixmapTargetNo;
}
}
@@ -157,7 +221,7 @@ xglPixmapSurfaceInit (PixmapPtr pPixmap,
PixmapPtr
xglCreatePixmap (ScreenPtr pScreen,
int width,
- int height,
+ int height,
int depth)
{
xglPixmapPtr pPixmapPriv;
@@ -180,37 +244,32 @@ xglCreatePixmap (ScreenPtr pScreen,
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;
pPixmapPriv = XGL_GET_PIXMAP_PRIV (pPixmap);
- pPixmapPriv->format = pScreenPriv->pixmapFormats[depth].format;
- pPixmapPriv->pPixel = pScreenPriv->pixmapFormats[depth].pPixel;
+ 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->bitBox.x1 = 0;
- pPixmapPriv->bitBox.y1 = 0;
- pPixmapPriv->bitBox.x2 = 32767;
- pPixmapPriv->bitBox.y2 = 32767;
+
pPixmapPriv->damageBox = miEmptyBox;
-
+
return pPixmap;
}
@@ -218,7 +277,7 @@ void
xglFiniPixmap (PixmapPtr pPixmap)
{
XGL_PIXMAP_PRIV (pPixmap);
-
+
if (pPixmap->devPrivate.ptr)
{
if (pPixmapPriv->buffer)
@@ -230,10 +289,15 @@ xglFiniPixmap (PixmapPtr pPixmap)
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);
}
@@ -247,7 +311,7 @@ xglDestroyPixmap (PixmapPtr pPixmap)
xglFiniPixmap (pPixmap);
xfree (pPixmap);
-
+
return TRUE;
}
@@ -260,18 +324,16 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
int devKind,
pointer pPixData)
{
- xglScreenPtr pScreenPriv;
- xglPixmapPtr pPixmapPriv;
- glitz_format_t *oldFormat;
- int oldWidth, oldHeight;
-
+ 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);
- oldFormat = pPixmapPriv->format;
oldWidth = pPixmap->drawable.width;
oldHeight = pPixmap->drawable.height;
@@ -293,13 +355,13 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
{
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))
@@ -312,18 +374,20 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->drawable.depth);
}
- depth = pPixmap->drawable.depth;
-
- pPixmapPriv->pPixel = pScreenPriv->pixmapFormats[depth].pPixel;
- pPixmapPriv->format = pScreenPriv->pixmapFormats[depth].format;
-
- if (pPixmapPriv->format != oldFormat ||
- pPixmap->drawable.width != oldWidth ||
+ 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,
@@ -333,6 +397,8 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
if (pPixData)
{
+ BoxRec box;
+
if (pPixmap->devPrivate.ptr)
{
if (pPixmapPriv->buffer)
@@ -346,10 +412,10 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
pPixmapPriv->pGeometry = NULL;
}
-
+
if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer);
-
+
if (pPixmapPriv->bits)
xfree (pPixmapPriv->bits);
@@ -359,36 +425,54 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
return FALSE;
pPixmapPriv->allBits = TRUE;
- pPixmapPriv->bitBox.x1 = 0;
- pPixmapPriv->bitBox.y1 = 0;
- pPixmapPriv->bitBox.x2 = pPixmap->drawable.width;
- pPixmapPriv->bitBox.y2 = pPixmap->drawable.height;
+
+ 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,
- &pPixmapPriv->bitBox, 1);
+ REGION_INIT (pPixmap->drawable.pScreen, pRegion, NullBox, 0);
+ REGION_SUBTRACT (pPixmap->drawable.pScreen, pRegion,
+ &pPixmapPriv->bitRegion, pRegion);
+
}
}
/*
- * Maybe there's a nicer way to detect if this is the screen pixmap.
+ * Screen pixmap
*/
- if (!pScreenPriv->pScreenPixmap)
+ if (!pScreenPriv->pScreenPixmap || pScreenPriv->pScreenPixmap == pPixmap)
{
- glitz_surface_reference (pScreenPriv->surface);
-
- pPixmapPriv->surface = pScreenPriv->surface;
+ 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;
-
- pScreenPriv->pScreenPixmap = pPixmap;
+
+ if (!pScreenPriv->pScreenPixmap)
+ pScreenPriv->pScreenPixmap = pPixmap;
}
-
+
return TRUE;
}
@@ -397,12 +481,12 @@ 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);
@@ -423,14 +507,14 @@ xglPixmapToGeometry (PixmapPtr 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;
@@ -453,7 +537,7 @@ xglPixmapToGeometry (PixmapPtr pPixmap,
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;
@@ -473,27 +557,28 @@ xglCreatePixmapSurface (PixmapPtr pPixmap)
{
XGL_PIXMAP_PRIV (pPixmap);
- if (!pPixmapPriv->format)
- return FALSE;
-
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->format,
+ pPixmapPriv->pVisual->format.surface,
pPixmap->drawable.width,
pPixmap->drawable.height,
0, NULL);
if (!pPixmapPriv->surface)
{
- pPixmapPriv->format = NULL;
- pPixmapPriv->target = xglPixmapTargetNo;
+ pPixmapPriv->pVisual = NULL;
+ pPixmapPriv->target = xglPixmapTargetNo;
+
return FALSE;
}
}
-
+
return TRUE;
}
@@ -501,20 +586,20 @@ 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,
@@ -544,7 +629,7 @@ xglAllocatePixmapBits (PixmapPtr pPixmap, int hint)
pPixmapPriv->stride = stride;
else
pPixmapPriv->stride = -stride;
-
+
return TRUE;
}
@@ -554,14 +639,14 @@ 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)
@@ -578,7 +663,7 @@ xglMapPixmapBits (PixmapPtr pPixmap)
pPixmap->devPrivate.ptr = bits;
}
}
-
+
return TRUE;
}
@@ -589,10 +674,68 @@ xglUnmapPixmapBits (PixmapPtr 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;
+ }
+ }
+}