diff --git a/hw/xgl/glx/xglx.c b/hw/xgl/glx/xglx.c index c89c496d8..dc2482eca 100644 --- a/hw/xgl/glx/xglx.c +++ b/hw/xgl/glx/xglx.c @@ -67,7 +67,9 @@ ScreenPtr currentScreen = NULL; xglScreenInfoRec xglScreenInfo = { NULL, 0, 0, 0, 0, FALSE, DEFAULT_GEOMETRY_DATA_TYPE, - DEFAULT_GEOMETRY_USAGE + DEFAULT_GEOMETRY_USAGE, + FALSE, + XGL_DEFAULT_PBO_MASK }; static Bool diff --git a/hw/xgl/xgl.h b/hw/xgl/xgl.h index 6bbc7b975..346d7b3b5 100644 --- a/hw/xgl/xgl.h +++ b/hw/xgl/xgl.h @@ -54,6 +54,8 @@ typedef struct _GCFuncs *GCFuncsPtr; extern WindowPtr *WindowTable; +#define XGL_DEFAULT_PBO_MASK 0 /* don't use PBO as default */ + typedef struct _xglScreenInfo { glitz_drawable_t *drawable; unsigned int width; @@ -63,6 +65,8 @@ typedef struct _xglScreenInfo { Bool fullscreen; int geometryDataType; int geometryUsage; + Bool yInverted; + int pboMask; } xglScreenInfoRec, *xglScreenInfoPtr; typedef struct _xglPixelFormat { @@ -217,6 +221,8 @@ typedef struct _xglScreen { int nOffscreen; int geometryUsage; int geometryDataType; + Bool yInverted; + int pboMask; xglGeometryRec scratchGeometry; #ifdef RENDER @@ -830,12 +836,27 @@ xglSetGeometry (xglGeometryPtr pGeometry, /* xglpixmap.c */ +#define XGL_PIXMAP_USAGE_HINT_STREAM_DRAW 1 +#define XGL_PIXMAP_USAGE_HINT_STREAM_READ 2 +#define XGL_PIXMAP_USAGE_HINT_STREAM_COPY 3 +#define XGL_PIXMAP_USAGE_HINT_STATIC_DRAW 4 +#define XGL_PIXMAP_USAGE_HINT_STATIC_READ 5 +#define XGL_PIXMAP_USAGE_HINT_STATIC_COPY 6 +#define XGL_PIXMAP_USAGE_HINT_DYNAMIC_DRAW 7 +#define XGL_PIXMAP_USAGE_HINT_DYNAMIC_READ 8 +#define XGL_PIXMAP_USAGE_HINT_DYNAMIC_COPY 9 + +#define XGL_PIXMAP_USAGE_HINT_DEFAULT XGL_PIXMAP_USAGE_HINT_STREAM_DRAW + PixmapPtr xglCreatePixmap (ScreenPtr pScreen, int width, int height, int depth); +void +xglFiniPixmap (PixmapPtr pPixmap); + Bool xglDestroyPixmap (PixmapPtr pPixmap); @@ -860,7 +881,7 @@ Bool xglCreatePixmapSurface (PixmapPtr pPixmap); Bool -xglAllocatePixmapBits (PixmapPtr pPixmap); +xglAllocatePixmapBits (PixmapPtr pPixmap, int hint); Bool xglMapPixmapBits (PixmapPtr pPixmap); diff --git a/hw/xgl/xglcmap.c b/hw/xgl/xglcmap.c index 69f43cb68..251616549 100644 --- a/hw/xgl/xglcmap.c +++ b/hw/xgl/xglcmap.c @@ -157,8 +157,8 @@ xglSetVisualTypesAndMasks (ScreenInfo *pScreenInfo, if (xglPbufferVisuals) { xglPbufferVisuals[nxglPbufferVisuals].format = format; - xglPbufferVisuals[nxglPbufferVisuals].pPixel = pPixelFormat; - xglPbufferVisuals[nxglPbufferVisuals].visuals = visuals; + xglPbufferVisuals[nxglPbufferVisuals].pPixel = NULL; + xglPbufferVisuals[nxglPbufferVisuals].visuals = 0; nxglPbufferVisuals++; } } @@ -217,23 +217,6 @@ xglInitVisuals (ScreenInfo *pScreenInfo) rm, gm, bm); } } - -#if 1 - { - for (j = 0; j < nxglVisuals; j++) - { - ErrorF ("Visual: 0x%x (%c) - r/g/b/a: %d/%d/%d/%d db: %d\n", - (int) xglVisuals[j].format->id, - xglVisuals[j].format->types.pbuffer? 'y' : 'n', - xglVisuals[j].format->color.red_size, - xglVisuals[j].format->color.green_size, - xglVisuals[j].format->color.blue_size, - xglVisuals[j].format->color.alpha_size, - xglVisuals[j].format->doublebuffer); - } - } -#endif - } void diff --git a/hw/xgl/xglcopy.c b/hw/xgl/xglcopy.c index a74a78c5e..2404597d3 100644 --- a/hw/xgl/xglcopy.c +++ b/hw/xgl/xglcopy.c @@ -158,12 +158,6 @@ xglCopyProc (DrawablePtr pSrc, pBox++; } - - if (pPixmapPriv->target == xglPixmapTargetIn) - { - if (!xglSyncSurface (pDst)) - FatalError (XGL_SW_FAILURE_STRING); - } } else xglAddCurrentBitDamage (pDst); } diff --git a/hw/xgl/xglparse.c b/hw/xgl/xglparse.c index ed95680d1..1cf6bac89 100644 --- a/hw/xgl/xglparse.c +++ b/hw/xgl/xglparse.c @@ -105,6 +105,9 @@ xglUseMsg (void) ErrorF ("-vertextype [short|float] set vertex data type\n"); ErrorF ("-vbostream " "use vertex buffer objects for streaming of vertex data\n"); + ErrorF ("-yinverted Y is upside-down\n"); + ErrorF ("-pbomask [1|4|8|16|32] " + "set bpp's to use with pixel buffer objects\n"); } int @@ -148,6 +151,22 @@ xglProcessArgument (xglScreenInfoPtr pScreenInfo, pScreenInfo->geometryUsage = GEOMETRY_USAGE_STREAM; return 1; } + else if (!strcmp (argv[i], "-yinverted")) + { + pScreenInfo->yInverted = TRUE; + return 1; + } + else if (!strcmp (argv[i], "-pbomask")) + { + if ((i + 1) < argc) + { + pScreenInfo->pboMask = atoi (argv[i + 1]); + } + else + return 1; + + return 2; + } return 0; } diff --git a/hw/xgl/xglpixmap.c b/hw/xgl/xglpixmap.c index 0f8a0cc4a..7c3d29d7b 100644 --- a/hw/xgl/xglpixmap.c +++ b/hw/xgl/xglpixmap.c @@ -26,6 +26,24 @@ #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, @@ -187,14 +205,11 @@ xglCreatePixmap (ScreenPtr pScreen, return pPixmap; } -Bool -xglDestroyPixmap (PixmapPtr pPixmap) +void +xglFiniPixmap (PixmapPtr pPixmap) { XGL_PIXMAP_PRIV (pPixmap); - - if (--pPixmap->refcnt) - return TRUE; - + if (pPixmapPriv->pArea) xglWithdrawArea (pPixmapPriv->pArea); @@ -215,6 +230,15 @@ xglDestroyPixmap (PixmapPtr pPixmap) if (pPixmapPriv->surface) glitz_surface_destroy (pPixmapPriv->surface); +} + +Bool +xglDestroyPixmap (PixmapPtr pPixmap) +{ + if (--pPixmap->refcnt) + return TRUE; + + xglFiniPixmap (pPixmap); xfree (pPixmap); @@ -362,7 +386,6 @@ xglModifyPixmapHeader (PixmapPtr pPixmap, glitz_surface_reference (pScreenPriv->surface); pPixmapPriv->surface = pScreenPriv->surface; - pPixmapPriv->pPixel = pScreenPriv->pVisual[0].pPixel; pPixmapPriv->target = xglPixmapTargetIn; pScreenPriv->pScreenPixmap = pPixmap; @@ -405,7 +428,8 @@ xglPixmapToGeometry (PixmapPtr pPixmap, if (!pPixmapPriv->buffer) { - if (!xglAllocatePixmapBits (pPixmap)) + if (!xglAllocatePixmapBits (pPixmap, + XGL_PIXMAP_USAGE_HINT_DEFAULT)) return NULL; } @@ -476,11 +500,12 @@ xglCreatePixmapSurface (PixmapPtr pPixmap) } Bool -xglAllocatePixmapBits (PixmapPtr pPixmap) +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; @@ -490,22 +515,37 @@ xglAllocatePixmapBits (PixmapPtr pPixmap) if (stride) { - pPixmapPriv->bits = xalloc (height * stride); - if (!pPixmapPriv->bits) - return FALSE; - - pPixmapPriv->buffer = - glitz_buffer_create_for_data (pPixmapPriv->bits); - if (!pPixmapPriv->buffer) + glitz_buffer_t *buffer; + + if ((pScreenPriv->pboMask & bpp) && hint) { - xfree (pPixmapPriv->bits); + 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; } - /* XXX: pPixmapPriv->stride = -stride */ - pPixmapPriv->stride = stride; + if (pScreenPriv->yInverted) + pPixmapPriv->stride = stride; + else + pPixmapPriv->stride = -stride; return TRUE; } @@ -520,7 +560,8 @@ xglMapPixmapBits (PixmapPtr pPixmap) XGL_PIXMAP_PRIV (pPixmap); if (!pPixmapPriv->buffer) - if (!xglAllocatePixmapBits (pPixmap)) + if (!xglAllocatePixmapBits (pPixmap, + XGL_PIXMAP_USAGE_HINT_DEFAULT)) return FALSE; bits = glitz_buffer_map (pPixmapPriv->buffer, diff --git a/hw/xgl/xglscreen.c b/hw/xgl/xglscreen.c index 0ccd772ee..0426c06f8 100644 --- a/hw/xgl/xglscreen.c +++ b/hw/xgl/xglscreen.c @@ -135,6 +135,7 @@ xglScreenInit (ScreenPtr pScreen, xglScreenInfoPtr pScreenInfo) { xglScreenPtr pScreenPriv; + int depth; #ifdef RENDER PictureScreenPtr pPictureScreen; @@ -152,15 +153,19 @@ xglScreenInit (ScreenPtr pScreen, pScreenPriv->features = glitz_drawable_get_features (pScreenInfo->drawable); + depth = pScreenPriv->pVisual->pPixel->depth; + if (!xglInitOffscreen (pScreen, pScreenInfo)) return FALSE; xglInitPixmapFormats (pScreen); - if (!pScreenPriv->pixmapFormats[32].format) + if (!pScreenPriv->pixmapFormats[depth].format) return FALSE; pScreenPriv->geometryDataType = pScreenInfo->geometryDataType; pScreenPriv->geometryUsage = pScreenInfo->geometryUsage; + pScreenPriv->yInverted = pScreenInfo->yInverted; + pScreenPriv->pboMask = pScreenInfo->pboMask; GEOMETRY_INIT (pScreen, &pScreenPriv->scratchGeometry, GLITZ_GEOMETRY_TYPE_VERTEX, @@ -168,7 +173,7 @@ xglScreenInit (ScreenPtr pScreen, pScreenPriv->surface = glitz_surface_create (pScreenPriv->drawable, - pScreenPriv->pixmapFormats[32].format, + pScreenPriv->pixmapFormats[depth].format, pScreenInfo->width, pScreenInfo->height, 0, NULL); if (!pScreenPriv->surface) @@ -283,7 +288,9 @@ xglFinishScreenInit (ScreenPtr pScreen) XGL_SCREEN_PRIV (pScreen); - miInitializeBackingStore (pScreen); + /* Do we want to use BackingStore? + miInitializeBackingStore (pScreen); + */ if (!fbCreateDefColormap (pScreen)) return FALSE; @@ -348,7 +355,8 @@ xglCloseScreen (int index, ScreenPtr pScreen) { XGL_SCREEN_PRIV (pScreen); - + XGL_PIXMAP_PRIV (pScreenPriv->pScreenPixmap); + #ifdef RENDER int i; @@ -362,6 +370,10 @@ xglCloseScreen (int index, glitz_surface_destroy (pScreenPriv->trapInfo.mask); #endif + xglFiniPixmap (pScreenPriv->pScreenPixmap); + if (pPixmapPriv->pDamage) + DamageDestroy (pPixmapPriv->pDamage); + if (pScreenPriv->solid) glitz_surface_destroy (pScreenPriv->solid); diff --git a/hw/xgl/xglshm.c b/hw/xgl/xglshm.c index 574c1095a..020abd33f 100644 --- a/hw/xgl/xglshm.c +++ b/hw/xgl/xglshm.c @@ -64,7 +64,8 @@ xglShmPutImage (DrawablePtr pDrawable, XGL_PIXMAP_PRIV (pPixmap); - if (!xglAllocatePixmapBits (pPixmap)) + if (!xglAllocatePixmapBits (pPixmap, + XGL_PIXMAP_USAGE_HINT_DEFAULT)) { (*pScreen->DestroyPixmap) (pPixmap); return; diff --git a/hw/xgl/xglsync.c b/hw/xgl/xglsync.c index 35c359482..1552419b1 100644 --- a/hw/xgl/xglsync.c +++ b/hw/xgl/xglsync.c @@ -80,7 +80,7 @@ xglSyncBits (DrawablePtr pDrawable, pBitBox = &pPixmapPriv->bitBox; - if (pExtents) + if (pPixmapPriv->target == xglPixmapTargetIn && pExtents) { box.x1 = MAX (0, pExtents->x1); box.y1 = MAX (0, pExtents->y1); @@ -150,7 +150,7 @@ xglSyncBits (DrawablePtr pDrawable, } if (!pPixmapPriv->buffer) - if (!xglAllocatePixmapBits (pPixmap)) + if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT)) return FALSE; if (pPixmapPriv->pDamage) @@ -176,23 +176,24 @@ xglSyncBits (DrawablePtr pDrawable, nBox = REGION_NUM_RECTS (®ion); format.masks = pPixmapPriv->pPixel->masks; - - if (pPixmapPriv->stride < 0) - { - format.bytes_per_line = -pPixmapPriv->stride; - format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; - } - else - { - format.bytes_per_line = pPixmapPriv->stride; - format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; - } while (nBox--) { - format.xoffset = pBox->x1; - format.skip_lines = pBox->y1; - + format.xoffset = pBox->x1; + + if (pPixmapPriv->stride < 0) + { + format.skip_lines = pPixmap->drawable.height - pBox->y2; + format.bytes_per_line = -pPixmapPriv->stride; + format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; + } + else + { + format.skip_lines = pBox->y1; + format.bytes_per_line = pPixmapPriv->stride; + format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; + } + glitz_get_pixels (pPixmapPriv->surface, pBox->x1, pBox->y1, @@ -254,17 +255,18 @@ xglSyncSurface (DrawablePtr pDrawable) pBox = REGION_RECTS (pRegion); pExt = REGION_EXTENTS (pDrawable->pScreen, pRegion); - format.masks = pPixmapPriv->pPixel->masks; - format.xoffset = pExt->x1; - format.skip_lines = pExt->y1; - + format.masks = pPixmapPriv->pPixel->masks; + format.xoffset = pExt->x1; + if (pPixmapPriv->stride < 0) { + format.skip_lines = pPixmap->drawable.height - pExt->y2; format.bytes_per_line = -pPixmapPriv->stride; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP; } else { + format.skip_lines = pExt->y1; format.bytes_per_line = pPixmapPriv->stride; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; } diff --git a/hw/xgl/xgltrap.c b/hw/xgl/xgltrap.c index 48d228d35..b4c2878ca 100644 --- a/hw/xgl/xgltrap.c +++ b/hw/xgl/xgltrap.c @@ -66,17 +66,13 @@ xglCreateMaskPicture (ScreenPtr pScreen, { XGL_PIXMAP_PRIV (pPixmap); - if (!xglAllocatePixmapBits (pPixmap)) + if (!xglAllocatePixmapBits (pPixmap, XGL_PIXMAP_USAGE_HINT_DEFAULT)) { (*pScreen->DestroyPixmap) (pPixmap); return 0; } pPixmapPriv->target = xglPixmapTargetNo; - - /* force negative stride */ - if (pPixmapPriv->stride > 0) - pPixmapPriv->stride = -pPixmapPriv->stride; } pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);