Xgl improvements

This commit is contained in:
David Reveman 2005-01-26 10:58:52 +00:00
parent 13b5a93b70
commit 9817582328
26 changed files with 4658 additions and 1702 deletions

View File

@ -13,13 +13,13 @@ libxgl_a_SOURCES = \
xglcmap.c \
xglparse.c \
xglscreen.c \
xglarea.c \
xgloffscreen.c \
xglgeometry.c \
xglpixmap.c \
xglsync.c \
xglsolid.c \
xgltile.c \
xglpixel.c \
xglcopy.c \
xglfill.c \
xglwindow.c \
@ -27,4 +27,6 @@ libxgl_a_SOURCES = \
xglget.c \
xglgc.c \
xglcomp.c \
xglpict.c
xglpict.c \
xglglyph.c \
xgltrap.c

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include <X11/Xlib.h>
@ -64,7 +64,11 @@ int xscreen;
glitz_format_t *xglxCurrentFormat;
CARD32 lastEventTime = 0;
ScreenPtr currentScreen = NULL;
xglScreenInfoRec xglScreenInfo = { 0, 0, 0, 0, FALSE };
xglScreenInfoRec xglScreenInfo = {
NULL, 0, 0, 0, 0, FALSE,
DEFAULT_GEOMETRY_DATA_TYPE,
DEFAULT_GEOMETRY_USAGE
};
static Bool
xglxAllocatePrivates (ScreenPtr pScreen)
@ -386,9 +390,15 @@ xglxBlockHandler (pointer blockData,
OSTimePtr pTimeout,
pointer pReadMask)
{
glitz_surface_flush (XGL_GET_SCREEN_PRIV (currentScreen)->surface);
glitz_drawable_flush (XGL_GET_SCREEN_PRIV (currentScreen)->drawable);
XFlush (xdisplay);
XGL_SCREEN_PRIV (currentScreen);
if (!xglSyncSurface (&pScreenPriv->pScreenPixmap->drawable))
FatalError (XGL_SW_FAILURE_STRING);
glitz_surface_flush (pScreenPriv->surface);
glitz_drawable_finish (pScreenPriv->drawable);
XSync (xdisplay, FALSE);
}
static void
@ -397,8 +407,8 @@ xglxWakeupHandler (pointer blockData,
pointer pReadMask)
{
ScreenPtr pScreen = currentScreen;
XEvent X;
xEvent x;
XEvent X;
xEvent x;
while (XPending (xdisplay)) {
XNextEvent (xdisplay, &X);
@ -578,7 +588,7 @@ InitInput (int argc, char **argv)
void
ddxUseMsg (void)
{
ErrorF ("\nXglx Usage:\n");
ErrorF ("\nXglx usage:\n");
ErrorF ("-display string display name of the real server\n");
xglUseMsg ();

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#ifndef _XGL_H_
@ -61,6 +61,8 @@ typedef struct _xglScreenInfo {
unsigned int widthMm;
unsigned int heightMm;
Bool fullscreen;
int geometryDataType;
int geometryUsage;
} xglScreenInfoRec, *xglScreenInfoPtr;
typedef struct _xglPixelFormat {
@ -85,29 +87,123 @@ extern int nxglVisuals;
extern xglVisualPtr xglPbufferVisuals;
extern int nxglPbufferVisuals;
#define xglOffscreenAreaAvailable 0
#define xglOffscreenAreaDivided 1
#define xglOffscreenAreaOccupied 2
#define xglAreaAvailable 0
#define xglAreaDivided 1
#define xglAreaOccupied 2
typedef struct _xglOffscreen *xglOffscreenPtr;
typedef struct _xglPixmap *xglPixmapPtr;
typedef struct _xglRootArea *xglRootAreaPtr;
typedef struct _xglOffscreenArea {
int level;
int state;
int x, y;
xglPixmapPtr pPixmapPriv;
struct _xglOffscreenArea *pArea[4];
xglOffscreenPtr pOffscreen;
} xglOffscreenAreaRec, *xglOffscreenAreaPtr;
typedef struct _xglArea {
int state;
int level;
int x, y;
int width, height;
struct _xglArea *pArea[4];
xglRootAreaPtr pRoot;
pointer closure;
DevUnion devPrivate;
} xglAreaRec, *xglAreaPtr;
typedef struct _xglAreaFuncs {
Bool (*Create) (xglAreaPtr pArea);
Bool (*MoveIn) (xglAreaPtr pArea,
pointer closure);
void (*MoveOut) (xglAreaPtr pArea,
pointer closure);
int (*CompareScore) (xglAreaPtr pArea,
pointer closure1,
pointer closure2);
} xglAreaFuncsRec, *xglAreaFuncsPtr;
typedef struct _xglRootArea {
int maxLevel;
int width, height;
xglAreaPtr pArea;
xglAreaFuncsPtr funcs;
int devPrivateSize;
pointer closure;
} xglRootAreaRec;
typedef struct xglGeometry {
glitz_buffer_t *buffer;
pointer *data;
Bool broken;
glitz_fixed16_16_t xOff, yOff;
int dataType;
int usage;
int size, endOffset;
glitz_geometry_type_t type;
glitz_geometry_format_t f;
int first, width, count;
glitz_multi_array_t *array;
} xglGeometryRec, *xglGeometryPtr;
#ifdef RENDER
typedef struct _xglFBox {
glitz_float_t x1, y1, x2, y2;
} xglFBoxRec;
typedef union _xglBox {
BoxRec sBox;
xglFBoxRec fBox;
} xglBoxRec, *xglBoxPtr;
typedef struct _xglRange {
int first;
unsigned int count;
} xglRangeRec, *xglRangePtr;
typedef struct _xglGlyphTexture {
glitz_surface_t *mask;
glitz_pixel_format_t pixel;
glitz_geometry_format_t format;
int geometryDataType;
} xglGlyphTextureRec, *xglGlyphTexturePtr;
typedef struct _xglGlyphArea {
unsigned long serial;
union {
xglBoxRec box;
xglRangeRec range;
} u;
} xglGlyphAreaRec, *xglGlyphAreaPtr;
typedef struct _xglGlyphCache {
ScreenPtr pScreen;
int depth;
xglRootAreaRec rootArea;
union {
xglGlyphTextureRec texture;
xglGeometryRec geometry;
} u;
} xglGlyphCacheRec, *xglGlyphCachePtr;
typedef struct _xglGlyph {
xglAreaPtr pArea;
} xglGlyphRec, *xglGlyphPtr;
extern int xglGlyphPrivateIndex;
#define XGL_GET_GLYPH_PRIV(pScreen, pGlyph) ((xglGlyphPtr) \
(GetGlyphPrivatesForScreen (pGlyph, pScreen))[xglGlyphPrivateIndex].ptr)
#define XGL_GLYPH_PRIV(pScreen, pGlyph) \
xglGlyphPtr pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, pGlyph)
#endif
#define XGL_MAX_OFFSCREEN_AREAS 8
typedef struct _xglOffscreen {
xglRootAreaRec rootArea;
glitz_drawable_t *drawable;
glitz_drawable_format_t *format;
glitz_drawable_buffer_t buffer;
int width, height;
xglOffscreenAreaPtr pArea;
} xglOffscreenRec;
} xglOffscreenRec, *xglOffscreenPtr;
typedef struct _xglScreen {
xglVisualPtr pVisual;
@ -117,12 +213,26 @@ typedef struct _xglScreen {
glitz_surface_t *solid;
PixmapPtr pScreenPixmap;
unsigned long features;
xglOffscreenPtr pOffscreen;
xglOffscreenRec pOffscreen[XGL_MAX_OFFSCREEN_AREAS];
int nOffscreen;
int geometryUsage;
int geometryDataType;
xglGeometryRec scratchGeometry;
#ifdef RENDER
xglGlyphCacheRec glyphCache[33];
PicturePtr pSolidAlpha;
struct _trapInfo {
PicturePtr pMask;
glitz_surface_t *mask;
glitz_geometry_format_t format;
} trapInfo;
#endif
GetImageProcPtr GetImage;
GetSpansProcPtr GetSpans;
CreateWindowProcPtr CreateWindow;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
PaintWindowBackgroundProcPtr PaintWindowBackground;
PaintWindowBorderProcPtr PaintWindowBorder;
CopyWindowProcPtr CopyWindow;
@ -133,11 +243,16 @@ typedef struct _xglScreen {
#ifdef RENDER
CompositeProcPtr Composite;
RasterizeTrapezoidProcPtr RasterizeTrapezoid;
GlyphsProcPtr Glyphs;
TrapezoidsProcPtr Trapezoids;
AddTrapsProcPtr AddTraps;
AddTrianglesProcPtr AddTriangles;
ChangePictureProcPtr ChangePicture;
ChangePictureTransformProcPtr ChangePictureTransform;
ChangePictureFilterProcPtr ChangePictureFilter;
RealizeGlyphProcPtr RealizeGlyph;
UnrealizeGlyphProcPtr UnrealizeGlyph;
#endif
BSFuncRec BackingStoreFuncs;
@ -213,22 +328,23 @@ extern int xglGCPrivateIndex;
#define xglPixmapTargetIn 2
typedef struct _xglPixmap {
xglPixelFormatPtr pPixel;
glitz_format_t *format;
glitz_surface_t *surface;
glitz_buffer_t *buffer;
int target;
xglOffscreenAreaPtr pArea;
int score;
Bool acceleratedTile;
pointer bits;
unsigned int stride;
DamagePtr pDamage;
BoxRec damageBox;
BoxRec bitBox;
Bool allBits;
unsigned long pictureMask;
} xglPixmapRec;
xglPixelFormatPtr pPixel;
glitz_format_t *format;
glitz_surface_t *surface;
glitz_buffer_t *buffer;
int target;
xglAreaPtr pArea;
int score;
Bool acceleratedTile;
pointer bits;
unsigned int stride;
DamagePtr pDamage;
BoxRec damageBox;
BoxRec bitBox;
Bool allBits;
unsigned long pictureMask;
xglGeometryPtr pGeometry;
} xglPixmapRec, *xglPixmapPtr;
extern int xglPixmapPrivateIndex;
@ -271,19 +387,6 @@ extern int xglWinPrivateIndex;
#define XGL_DRAWABLE_PIXMAP_PRIV(pDrawable) \
xglPixmapPtr pPixmapPriv = XGL_GET_DRAWABLE_PIXMAP_PRIV (pDrawable)
typedef struct xglGeometry {
glitz_buffer_t *buffer;
pointer *data;
glitz_geometry_primitive_t primitive;
Bool broken;
glitz_fixed16_16_t xOff, yOff;
int dataType;
int usage;
int size, endOffset;
} xglGeometryRec, *xglGeometryPtr;
#ifdef COMPOSITE
#define __XGL_OFF_X_WIN(pPix) (-(pPix)->screen_x)
#define __XGL_OFF_Y_WIN(pPix) (-(pPix)->screen_y)
@ -308,11 +411,6 @@ typedef struct xglGeometry {
#define XGL_DEFAULT_DPI 96
#define XGL_INTERNAL_SCANLINE_ORDER GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN
#define XGL_INTERNAL_SCANLINE_ORDER_UPSIDE_DOWN \
(XGL_INTERNAL_SCANLINE_ORDER == GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP)
#define XGL_SW_FAILURE_STRING "software fall-back failure"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@ -322,32 +420,13 @@ typedef struct xglGeometry {
#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
#define FIXED_TO_FLOAT(f) (((glitz_float_t) (f)) / 65536)
#define FLOAT_TO_FIXED(f) ((int) ((f) * 65536))
#define BOX_NOTEMPTY(pBox) \
(((pBox)->x2 - (pBox)->x1) > 0 && \
((pBox)->y2 - (pBox)->y1) > 0)
#define BOX_EXTENTS(pBox, nBox, pExt) \
{ \
int i; \
(pExt)->x1 = (pExt)->y1 = 32767; \
(pExt)->x2 = (pExt)->y2 = -32767; \
for (i = 0; i < (nBox); i++) \
{ \
if ((pBox)[i].x1 < (pExt)->x1) \
(pExt)->x1 = (pBox)[i].x1; \
if ((pBox)[i].y1 < (pExt)->y1) \
(pExt)->y1 = (pBox)[i].y1; \
if ((pBox)[i].x2 > (pExt)->x2) \
(pExt)->x2 = (pBox)[i].x2; \
if ((pBox)[i].y2 > (pExt)->y2) \
(pExt)->y2 = (pBox)[i].y2; \
} \
if (((pExt)->x2 - (pExt)->x1) < 0) \
(pExt)->x1 = (pExt)->x2 = 0; \
if (((pExt)->y2 - (pExt)->y1) < 0) \
(pExt)->y1 = (pExt)->y2 = 0; \
}
#define XGL_MAX_PIXMAP_SCORE 32768
#define XGL_MIN_PIXMAP_SCORE -32768
@ -453,6 +532,37 @@ Bool
xglCloseScreen (int index,
ScreenPtr pScreen);
void
xglCreateSolidAlphaPicture (ScreenPtr pScreen);
/* xglarea.c */
Bool
xglRootAreaInit (xglRootAreaPtr pRoot,
int maxLevel,
int width,
int height,
int devPrivateSize,
xglAreaFuncsPtr funcs,
pointer closure);
void
xglRootAreaFini (xglRootAreaPtr pRoot);
void
xglLeaveArea (xglAreaPtr pArea);
void
xglWithdrawArea (xglAreaPtr pArea);
Bool
xglFindArea (xglAreaPtr pArea,
int width,
int height,
Bool kickOut,
pointer closure);
/* xgloffscreen.c */
@ -468,7 +578,7 @@ xglFindOffscreenArea (ScreenPtr pScreen,
PixmapPtr pPixmap);
void
xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
xglLeaveOffscreenArea (PixmapPtr pPixmap);
/* xglgeometry.c */
@ -476,40 +586,101 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
#define GEOMETRY_DATA_TYPE_SHORT 0
#define GEOMETRY_DATA_TYPE_FLOAT 1
typedef struct _xglDataTypeInfo {
glitz_data_type_t type;
int size;
} xglDataTypeInfoRec, *xglDataTypeInfoPtr;
extern xglDataTypeInfoRec xglGeometryDataTypes[2];
#define DEFAULT_GEOMETRY_DATA_TYPE GEOMETRY_DATA_TYPE_FLOAT
#define GEOMETRY_USAGE_STREAM 0
#define GEOMETRY_USAGE_STATIC 1
#define GEOMETRY_USAGE_DYNAMIC 2
#define GEOMETRY_USAGE_USERMEM 3
#define GEOMETRY_USAGE_SYSMEM 3
#define GEOMETRY_INIT(pScreen, pGeometry, _size) \
{ \
(pGeometry)->dataType = GEOMETRY_DATA_TYPE_FLOAT; \
(pGeometry)->usage = GEOMETRY_USAGE_USERMEM; \
(pGeometry)->primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; \
(pGeometry)->size = 0; \
(pGeometry)->endOffset = 0; \
(pGeometry)->data = (pointer) 0; \
(pGeometry)->buffer = NULL; \
(pGeometry)->broken = FALSE; \
(pGeometry)->xOff = 0; \
(pGeometry)->yOff = 0; \
xglGeometryResize (pScreen, pGeometry, _size); \
#define DEFAULT_GEOMETRY_USAGE GEOMETRY_USAGE_SYSMEM
#define GEOMETRY_INIT(pScreen, pGeometry, _type, _usage, _size) \
{ \
(pGeometry)->type = _type; \
(pGeometry)->usage = _usage; \
(pGeometry)->dataType = DEFAULT_GEOMETRY_DATA_TYPE; \
(pGeometry)->usage = _usage; \
(pGeometry)->size = 0; \
(pGeometry)->endOffset = 0; \
(pGeometry)->data = (pointer) 0; \
(pGeometry)->buffer = NULL; \
(pGeometry)->broken = FALSE; \
(pGeometry)->xOff = 0; \
(pGeometry)->yOff = 0; \
(pGeometry)->array = NULL; \
(pGeometry)->first = 0; \
(pGeometry)->count = 0; \
if (_type == GLITZ_GEOMETRY_TYPE_VERTEX) \
{ \
(pGeometry)->width = 2; \
(pGeometry)->f.vertex.type = \
xglGeometryDataTypes[(pGeometry)->dataType].type; \
(pGeometry)->f.vertex.bytes_per_vertex = (pGeometry)->width * \
xglGeometryDataTypes[(pGeometry)->dataType].size; \
(pGeometry)->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS; \
(pGeometry)->f.vertex.attributes = 0; \
(pGeometry)->f.vertex.src.type = GLITZ_DATA_TYPE_FLOAT; \
(pGeometry)->f.vertex.src.size = GLITZ_COORDINATE_SIZE_X; \
(pGeometry)->f.vertex.src.offset = 0; \
(pGeometry)->f.vertex.mask.type = GLITZ_DATA_TYPE_FLOAT; \
(pGeometry)->f.vertex.mask.size = GLITZ_COORDINATE_SIZE_X; \
(pGeometry)->f.vertex.mask.offset = 0; \
} \
else \
{ \
(pGeometry)->width = 0; \
(pGeometry)->f.bitmap.scanline_order = \
GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; \
(pGeometry)->f.bitmap.bytes_per_line = 0; \
(pGeometry)->f.bitmap.pad = GLYPHPADBYTES; \
} \
if (_size) \
xglGeometryResize (pScreen, pGeometry, _size); \
}
#define GEOMETRY_UNINIT(pGeometry) \
#define GEOMETRY_UNINIT(pGeometry) \
{ \
if ((pGeometry)->array) \
glitz_multi_array_destroy ((pGeometry)->array); \
if ((pGeometry)->buffer) \
glitz_buffer_destroy ((pGeometry)->buffer); \
if ((pGeometry)->data) \
xfree ((pGeometry)->data); \
}
#define GEOMETRY_SET_BUFFER(pGeometry, _buffer) \
{ \
glitz_buffer_reference (_buffer); \
if ((pGeometry)->buffer) \
glitz_buffer_destroy ((pGeometry)->buffer); \
if ((pGeometry)->data) \
xfree ((pGeometry)->data); \
(pGeometry)->buffer = _buffer; \
}
#define GEOMETRY_SET_PRIMITIVE(pScreen, pGeometry, _primitive) \
(pGeometry)->primitive = _primitive
#define GEOMETRY_SET_MULTI_ARRAY(pGeometry, _array) \
{ \
glitz_multi_array_reference (_array); \
if ((pGeometry)->array) \
glitz_multi_array_destroy ((pGeometry)->array); \
(pGeometry)->array = _array; \
}
#define GEOMETRY_RESIZE(pScreen, pGeometry, size) \
xglGeometryResize (pScreen, pGeometry, size)
#define GEOMETRY_SET_TRANSLATE(pGeometry, _x, _y) \
{ \
(pGeometry)->xOff = (_x) << 16; \
(pGeometry)->yOff = (_y) << 16; \
}
#define GEOMETRY_TRANSLATE(pGeometry, tx, ty) \
{ \
(pGeometry)->xOff += (tx) << 16; \
@ -522,58 +693,84 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
(pGeometry)->yOff += (fty); \
}
#define GEOMETRY_ADD_RECT(pScreen, pGeometry, pRect, nRect) \
xglGeometryAddRect (pScreen, pGeometry, pRect, nRect)
#define GEOMETRY_SET_VERTEX_PRIMITIVE(pGeometry, _primitive) \
(pGeometry)->f.vertex.primitive = _primitive
#define GEOMETRY_SET_VERTEX_DATA_TYPE(pGeometry, _type) \
{ \
(pGeometry)->dataType = _type; \
(pGeometry)->f.vertex.type = xglGeometryDataTypes[_type].type; \
(pGeometry)->f.vertex.bytes_per_vertex = (pGeometry)->width * \
xglGeometryDataTypes[_type].size; \
}
#define GEOMETRY_ADD_BOX(pScreen, pGeometry, pBox, nBox) \
xglGeometryAddBox (pScreen, pGeometry, pBox, nBox)
xglGeometryAddBox (pScreen, pGeometry, pBox, nBox, \
(pGeometry)->endOffset)
#define GEOMETRY_ADD_REGION_AT(pScreen, pGeometry, pRegion, offset) \
xglGeometryAddBox (pScreen, pGeometry, \
REGION_RECTS (pRegion), \
REGION_NUM_RECTS (pRegion), \
offset)
#define GEOMETRY_ADD_REGION(pScreen, pGeometry, pRegion) \
xglGeometryAddBox (pScreen, pGeometry, \
REGION_RECTS (pRegion), \
REGION_NUM_RECTS (pRegion))
REGION_NUM_RECTS (pRegion), \
(pGeometry)->endOffset)
#define GEOMETRY_ADD_SPAN(pScreen, pGeometry, ppt, pwidth, n) \
xglGeometryAddSpan (pScreen, pGeometry, ppt, pwidth, n)
xglGeometryAddSpan (pScreen, pGeometry, ppt, pwidth, n, \
(pGeometry)->endOffset)
#define GEOMETRY_ADD_LINE(pScreen, pGeometry, loop, mode, npt, ppt) \
xglGeometryAddLine (pScreen, pGeometry, loop, mode, npt, ppt)
xglGeometryAddLine (pScreen, pGeometry, loop, mode, npt, ppt, \
(pGeometry)->endOffset)
#define GEOMETRY_ADD_SEGMENT(pScreen, pGeometry, nsegInit, pSegInit) \
xglGeometryAddSegment (pScreen, pGeometry, nsegInit, pSegInit)
xglGeometryAddSegment (pScreen, pGeometry, nsegInit, pSegInit, \
(pGeometry)->endOffset)
#define GEOMETRY_ENABLE(pGeometry, surface, first, count) \
xglSetGeometry (pGeometry, surface, first, count);
#define GEOMETRY_FOR_GLYPH(pScreen, pGeometry, nGlyph, ppciInit, pglyphBase) \
xglGeometryForGlyph (pScreen, pGeometry, nGlyph, ppciInit, pglyphBase);
#define GEOMETRY_ENABLE_ALL_VERTICES(pGeometry, surface) \
xglSetGeometry (pGeometry, surface, 0, (pGeometry)->endOffset / 2)
#define GEOMETRY_ADD_TRAPEZOID(pScreen, pGeometry, pTrap, nTrap) \
xglGeometryAddTrapezoid (pScreen, pGeometry, pTrap, nTrap, \
(pGeometry)->endOffset)
#define GEOMETRY_DISABLE(surface) \
glitz_set_geometry (surface, 0, 0, NULL, NULL)
#define GEOMETRY_ADD_TRAP(pScreen, pGeometry, pTrap, nTrap) \
xglGeometryAddTrap (pScreen, pGeometry, pTrap, nTrap, \
(pGeometry)->endOffset)
#define GEOMETRY_GET_FORMAT(pGeometry, format) \
xglGeometryGetFormat (pGeometry, format)
#define GEOMETRY_ENABLE(pGeometry, surface) \
xglSetGeometry (pGeometry, surface)
#define GEOMETRY_DISABLE(surface) \
glitz_set_geometry (surface, GLITZ_GEOMETRY_TYPE_NONE, NULL, NULL)
void
xglGeometryResize (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
int size);
void
xglGeometryAddRect (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xRectangle *pRect,
int nRect);
void
xglGeometryAddBox (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
BoxPtr pBox,
int nBox);
int nBox,
int offset);
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
int n);
int n,
int offset);
void
xglGeometryAddLine (ScreenPtr pScreen,
@ -581,19 +778,53 @@ xglGeometryAddLine (ScreenPtr pScreen,
int loop,
int mode,
int npt,
DDXPointPtr ppt);
DDXPointPtr ppt,
int offset);
void
xglGeometryAddSegment (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
int nsegInit,
xSegment *pSegInit);
xSegment *pSegInit,
int offset);
void
xglGeometryForGlyph (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
unsigned int nGlyph,
CharInfoPtr *ppciInit,
pointer pglyphBase);
void
xglGeometryAddTrapezoid (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xTrapezoid *pTrap,
int nTrap,
int offset);
void
xglGeometryAddTrap (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xTrap *pTrap,
int nTrap,
int offset);
xglGeometryPtr
xglGetScratchGeometryWithSize (ScreenPtr pScreen,
int size);
xglGeometryPtr
xglGetScratchVertexGeometryWithType (ScreenPtr pScreen,
int type,
int count);
xglGeometryPtr
xglGetScratchVertexGeometry (ScreenPtr pScreen,
int count);
Bool
xglSetGeometry (xglGeometryPtr pGeometry,
glitz_surface_t *surface,
int first,
int count);
glitz_surface_t *surface);
/* xglpixmap.c */
@ -619,6 +850,11 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
RegionPtr
xglPixmapToRegion (PixmapPtr pPixmap);
xglGeometryPtr
xglPixmapToGeometry (PixmapPtr pPixmap,
int xOff,
int yOff);
Bool
xglCreatePixmapSurface (PixmapPtr pPixmap);
@ -648,10 +884,14 @@ Bool
xglPrepareTarget (DrawablePtr pDrawable);
void
xglAddSurfaceDamage (DrawablePtr pDrawable);
xglAddSurfaceDamage (DrawablePtr pDrawable,
RegionPtr pRegion);
void
xglAddBitDamage (DrawablePtr pDrawable);
xglAddCurrentSurfaceDamage (DrawablePtr pDrawable);
void
xglAddCurrentBitDamage (DrawablePtr pDrawable);
/* xglsolid.c */
@ -661,12 +901,32 @@ xglSolid (DrawablePtr pDrawable,
glitz_operator_t op,
glitz_color_t *color,
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox);
Bool
xglSolidGlyph (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nGlyph,
CharInfoPtr *ppci,
pointer pglyphBase);
/* xgltile.c */
xglGeometryPtr
xglTiledBoxGeometry (PixmapPtr pTile,
int tileX,
int tileY,
BoxPtr pBox,
int nBox);
Bool
xglTile (DrawablePtr pDrawable,
glitz_operator_t op,
@ -674,41 +934,13 @@ xglTile (DrawablePtr pDrawable,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox);
#define TILE_SOURCE 0
#define TILE_MASK 1
void
xglSwTile (glitz_operator_t op,
glitz_surface_t *srcSurface,
glitz_surface_t *maskSurface,
glitz_surface_t *dstSurface,
int xSrc,
int ySrc,
int xMask,
int yMask,
int what,
BoxPtr pBox,
int nBox,
int xOff,
int yOff);
/* xglpixel.c */
Bool
xglSetPixels (DrawablePtr pDrawable,
char *src,
int stride,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox);
/* xglcopy.c */
@ -737,9 +969,15 @@ xglCopyProc (DrawablePtr pSrc,
/* xglfill.c */
Bool
xglFill (DrawablePtr pDrawable,
GCPtr pGC,
xglGeometryPtr pGeometry);
xglFill (DrawablePtr pDrawable,
GCPtr pGC,
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox);
Bool
xglFillSpan (DrawablePtr pDrawable,
@ -748,7 +986,7 @@ xglFillSpan (DrawablePtr pDrawable,
DDXPointPtr ppt,
int *pwidth);
Bool
void
xglFillRect (DrawablePtr pDrawable,
GCPtr pGC,
int nrect,
@ -767,12 +1005,25 @@ xglFillSegment (DrawablePtr pDrawable,
int nsegInit,
xSegment *pSegInit);
Bool
xglFillGlyph (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nglyph,
CharInfoPtr *ppciInit,
pointer pglyphBase);
/* xglwindow.c */
Bool
xglCreateWindow (WindowPtr pWin);
Bool
xglChangeWindowAttributes (WindowPtr pWin,
unsigned long mask);
void
xglCopyWindow (WindowPtr pWin,
DDXPointRec ptOldOrg,
@ -959,18 +1210,20 @@ xglPushPixels (GCPtr pGC,
/* xglcomp.c */
Bool
xglComp (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
xglComp (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height,
xglGeometryPtr pGeometry,
glitz_surface_t *mask);
/* xglpict.c */
@ -990,21 +1243,11 @@ xglComposite (CARD8 op,
CARD16 height);
void
xglGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs);
void
xglRasterizeTrapezoid (PicturePtr pDst,
xTrapezoid *trap,
int xOff,
int yOff);
xglAddTriangles (PicturePtr pDst,
INT16 xOff,
INT16 yOff,
int ntri,
xTriangle *tris);
void
xglChangePicture (PicturePtr pPicture,
@ -1023,6 +1266,59 @@ xglChangePictureFilter (PicturePtr pPicture,
void
xglUpdatePicture (PicturePtr pPicture);
Bool
xglPictureInit (ScreenPtr pScreen);
/* xglglyph.c */
Bool
xglRealizeGlyph (ScreenPtr pScreen,
GlyphPtr pGlyph);
void
xglUnrealizeGlyph (ScreenPtr pScreen,
GlyphPtr pGlyph);
Bool
xglInitGlyphCache (xglGlyphCachePtr pCache,
ScreenPtr pScreen,
PictFormatPtr format);
void
xglFiniGlyphCache (xglGlyphCachePtr pCache);
void
xglGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs);
/* xgltrap.c */
void
xglTrapezoids (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nTrap,
xTrapezoid *traps);
void
xglAddTraps (PicturePtr pDst,
INT16 xOff,
INT16 yOff,
int nTrap,
xTrap *traps);
#endif
#endif /* _XGL_H_ */

318
hw/xgl/xglarea.c Normal file
View File

@ -0,0 +1,318 @@
/*
* Copyright © 2005 Novell, Inc.
*
* 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
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. 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"
static Bool
xglAreaMoveIn (xglAreaPtr pArea,
pointer closure)
{
pArea->closure = closure;
pArea->state = xglAreaOccupied;
return (*pArea->pRoot->funcs->MoveIn) (pArea, closure);
}
static void
xglAreaMoveOut (xglAreaPtr pArea)
{
(*pArea->pRoot->funcs->MoveOut) (pArea, pArea->closure);
pArea->state = xglAreaAvailable;
}
static xglAreaPtr
xglAreaCreate (xglRootAreaPtr pRoot,
int level,
int x,
int y,
int width,
int height)
{
xglAreaPtr pArea;
int n = 4;
pArea = xalloc (sizeof (xglAreaRec) + pRoot->devPrivateSize);
if (!pArea)
return NULL;
pArea->level = level;
pArea->x = x;
pArea->y = y;
pArea->width = width;
pArea->height = height;
pArea->pRoot = pRoot;
pArea->closure = (pointer) 0;
pArea->state = xglAreaAvailable;
while (n--)
pArea->pArea[n] = NULL;
if (pRoot->devPrivateSize)
pArea->devPrivate.ptr = pArea + 1;
else
pArea->devPrivate.ptr = (pointer) 0;
if (!(*pArea->pRoot->funcs->Create) (pArea))
{
free (pArea);
return NULL;
}
return pArea;
}
static void
xglAreaDestroy (xglAreaPtr pArea)
{
if (!pArea)
return;
if (pArea->state == xglAreaOccupied)
{
xglAreaMoveOut (pArea);
}
else
{
int n = 4;
while (n--)
xglAreaDestroy (pArea->pArea[n]);
}
xfree (pArea);
}
static xglAreaPtr
xglAreaGetTopScoredSubArea (xglAreaPtr pArea)
{
switch (pArea->state) {
case xglAreaOccupied:
return pArea;
case xglAreaAvailable:
break;
case xglAreaDivided:
{
xglAreaPtr tmp, top = NULL;
int i;
for (i = 0; i < 4; i++)
{
if (pArea->pArea[i])
{
tmp = xglAreaGetTopScoredSubArea (pArea->pArea[i]);
if (!tmp)
break;
if ((!top) ||
(*pArea->pRoot->funcs->CompareScore) (tmp,
tmp->closure,
top->closure) > 0)
top = tmp;
}
}
return top;
}
}
return NULL;
}
static Bool
xglAreaFind (xglAreaPtr pArea,
int width,
int height,
Bool kickOut,
pointer closure)
{
if (pArea->width < width || pArea->height < height)
return FALSE;
switch (pArea->state) {
case xglAreaOccupied:
if (kickOut)
{
if ((*pArea->pRoot->funcs->CompareScore) (pArea,
pArea->closure,
closure) >= 0)
return FALSE;
xglAreaMoveOut (pArea);
} else
return FALSE;
/* fall-through */
case xglAreaAvailable:
{
if (pArea->level == pArea->pRoot->maxLevel ||
(pArea->width == width && pArea->height == height))
{
if (xglAreaMoveIn (pArea, closure))
return TRUE;
}
else
{
int dx[4], dy[4], w[4], h[4], i;
dx[0] = dx[2] = dy[0] = dy[1] = 0;
w[0] = w[2] = dx[1] = dx[3] = width;
h[0] = h[1] = dy[2] = dy[3] = height;
w[1] = w[3] = pArea->width - width;
h[2] = h[3] = pArea->height - height;
for (i = 0; i < 2; i++)
{
if (w[i])
pArea->pArea[i] =
xglAreaCreate (pArea->pRoot,
pArea->level + 1,
pArea->x + dx[i],
pArea->y + dy[i],
w[i], h[i]);
}
for (; i < 4; i++)
{
if (w[i] && h[i])
pArea->pArea[i] =
xglAreaCreate (pArea->pRoot,
pArea->level + 1,
pArea->x + dx[i],
pArea->y + dy[i],
w[i], h[i]);
}
pArea->state = xglAreaDivided;
if (xglAreaFind (pArea->pArea[0], width, height, kickOut, closure))
return TRUE;
}
} break;
case xglAreaDivided:
{
xglAreaPtr topArea;
int i, rejected = FALSE;
for (i = 0; i < 4; i++)
{
if (pArea->pArea[i])
{
if (pArea->pArea[i]->width >= width &&
pArea->pArea[i]->height >= height)
{
if (xglFindArea (pArea->pArea[i], width, height, kickOut,
closure))
return TRUE;
rejected = TRUE;
}
}
}
if (rejected)
return FALSE;
topArea = xglAreaGetTopScoredSubArea (pArea);
if (topArea)
{
if (kickOut)
{
if ((*pArea->pRoot->funcs->CompareScore) (topArea,
topArea->closure,
closure) >= 0)
return FALSE;
} else
return FALSE;
}
for (i = 0; i < 4; i++)
{
xglAreaDestroy (pArea->pArea[i]);
pArea->pArea[i] = NULL;
}
pArea->state = xglAreaAvailable;
if (xglFindArea (pArea, width, height, TRUE, closure))
return TRUE;
} break;
}
return FALSE;
}
Bool
xglRootAreaInit (xglRootAreaPtr pRoot,
int maxLevel,
int width,
int height,
int devPrivateSize,
xglAreaFuncsPtr funcs,
pointer closure)
{
pRoot->maxLevel = maxLevel;
pRoot->funcs = funcs;
pRoot->devPrivateSize = devPrivateSize;
pRoot->closure = closure;
pRoot->pArea = xglAreaCreate (pRoot, 0, 0, 0, width, height);
if (!pRoot->pArea)
return FALSE;
return TRUE;
}
void
xglRootAreaFini (xglRootAreaPtr pRoot)
{
xglAreaDestroy (pRoot->pArea);
}
void
xglLeaveArea (xglAreaPtr pArea)
{
xglAreaMoveOut (pArea);
}
void
xglWithdrawArea (xglAreaPtr pArea)
{
pArea->closure = NULL;
pArea->state = xglAreaAvailable;
}
Bool
xglFindArea (xglAreaPtr pArea,
int width,
int height,
Bool kickOut,
pointer closure)
{
if (width < 1 || height < 0)
return FALSE;
return xglAreaFind (pArea, width, height, kickOut, closure);
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -31,7 +31,7 @@
#define XGL_BSTORE_FALLBACK_EPILOGUE(pDrawable, func, xglfunc) \
XGL_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (pDrawable)
xglAddCurrentSurfaceDamage (pDrawable)
/*
* The follwong functions are not yet tested so we can assume that they
@ -61,7 +61,7 @@ xglSaveAreas (PixmapPtr pPixmap,
REGION_RECTS (prgnSave),
REGION_NUM_RECTS (prgnSave)))
{
xglAddBitDamage (&pPixmap->drawable);
xglAddCurrentBitDamage (&pPixmap->drawable);
return;
}
@ -101,7 +101,7 @@ xglRestoreAreas (PixmapPtr pPixmap,
REGION_RECTS (prgnRestore),
REGION_NUM_RECTS (prgnRestore)))
{
xglAddBitDamage (&pPixmap->drawable);
xglAddCurrentBitDamage (&pPixmap->drawable);
return;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -257,7 +257,7 @@ xglClearVisualTypes (void)
void
xglInitPixmapFormats (ScreenPtr pScreen)
{
glitz_format_t *format;
glitz_format_t *format, **best;
int i, j;
XGL_SCREEN_PRIV (pScreen);
@ -275,6 +275,7 @@ xglInitPixmapFormats (ScreenPtr pScreen)
pScreenPriv->pixmapFormats[i].pPixel = &xglPixelFormats[j];
pScreenPriv->pixmapFormats[i].format = NULL;
best = &pScreenPriv->pixmapFormats[i].format;
rs = Ones (xglPixelFormats[j].masks.red_mask);
gs = Ones (xglPixelFormats[j].masks.green_mask);
@ -287,13 +288,28 @@ xglInitPixmapFormats (ScreenPtr pScreen)
0, NULL, k++);
if (format && format->type == GLITZ_FORMAT_TYPE_COLOR)
{
if (rs == format->color.red_size &&
gs == format->color.green_size &&
bs == format->color.blue_size &&
as == format->color.alpha_size)
/* formats must have an alpha channel, otherwise
filtering wont match the render spec. */
if (!format->color.alpha_size)
continue;
/* find best matching sufficient format */
if (format->color.red_size >= rs &&
format->color.green_size >= gs &&
format->color.blue_size >= bs &&
format->color.alpha_size >= as)
{
pScreenPriv->pixmapFormats[i].format = format;
break;
if (*best)
{
if (((format->color.red_size - rs) +
(format->color.green_size - gs) +
(format->color.blue_size - bs)) <
(((*best)->color.red_size - rs) +
((*best)->color.green_size - gs) +
((*best)->color.blue_size - bs)))
*best = format;
} else
*best = format;
}
}
} while (format);

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -49,22 +49,24 @@ static glitz_operator_t xglOperators[] = {
#define XGL_OPERATOR(op) (xglOperators[op])
Bool
xglComp (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
xglComp (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
PicturePtr pDst,
INT16 xSrc,
INT16 ySrc,
INT16 xMask,
INT16 yMask,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height,
xglGeometryPtr pGeometry,
glitz_surface_t *mask)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
xglPixmapPtr pSrcPriv, pMaskPriv;
glitz_surface_t *dst;
xglPixmapPtr pSrcPriv;
glitz_surface_t *src, *dst;
int dstXoff, dstYoff;
RegionRec region;
BoxPtr pBox;
@ -78,24 +80,21 @@ xglComp (CARD8 op,
if (op >= NUM_XGL_OPERATORS)
return FALSE;
if (pSrc->pDrawable->type != DRAWABLE_PIXMAP)
return FALSE;
if (pSrc->pDrawable->bitsPerPixel == 1)
return FALSE;
if (pMask)
{
if (pMask->pDrawable->type != DRAWABLE_PIXMAP)
return FALSE;
/*
* Why?
*/
if (pSrc->pDrawable == pMask->pDrawable)
if (pSrc->pDrawable == pMask->pDrawable && pSrc != pMask)
return FALSE;
}
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask,
@ -105,29 +104,6 @@ xglComp (CARD8 op,
pBox = REGION_RECTS (&region);
nBox = REGION_NUM_RECTS (&region);
/*
* Simple copy
*/
if (op == PictOpSrc && !pMask &&
!pSrc->transform && !pSrc->repeat && pSrc->filter <= 1)
{
if (xglCopy (pSrc->pDrawable,
pDst->pDrawable,
xSrc - xDst,
ySrc - yDst,
pBox,
nBox))
{
REGION_UNINIT (pScreen, &region);
xglAddBitDamage (pDst->pDrawable);
return TRUE;
}
REGION_UNINIT (pScreen, &region);
return FALSE;
}
if (!xglPrepareTarget (pDst->pDrawable))
{
REGION_UNINIT (pScreen, &region);
@ -135,116 +111,159 @@ xglComp (CARD8 op,
}
XGL_GET_DRAWABLE (pDst->pDrawable, dst, dstXoff, dstYoff);
if (!xglSyncSurface (pSrc->pDrawable))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pSrcPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable);
if (XGL_PICTURE_CHANGES (pSrcPriv->pictureMask))
xglUpdatePicture (pSrc);
if (pMask)
{
if (!xglSyncSurface (pMask->pDrawable))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pMaskPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pMask->pDrawable);
if (XGL_PICTURE_CHANGES (pMaskPriv->pictureMask))
xglUpdatePicture (pMask);
} else
pMaskPriv = NULL;
if (nBox > 1)
{
xglGeometryRec geometry;
GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (&region) << 3);
GEOMETRY_ADD_BOX (pScreen, &geometry, pBox, nBox);
GEOMETRY_TRANSLATE (&geometry, dstXoff, dstYoff);
if (!GEOMETRY_ENABLE_ALL_VERTICES (&geometry, dst))
{
GEOMETRY_UNINIT (&geometry);
return FALSE;
}
pBox = REGION_EXTENTS (pScreen, &region);
} else
GEOMETRY_DISABLE (dst);
xSrc += pBox->x1 - xDst;
ySrc += pBox->y1 - yDst;
src = pSrcPriv->surface;
if (pMask)
{
xMask += pBox->x1 - xDst;
yMask += pBox->y1 - yDst;
xglPixmapPtr pMaskPriv;
/* bitmap as mask */
if (pMask->pDrawable->bitsPerPixel == 1)
{
if (pGeometry)
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pGeometry =
xglPixmapToGeometry ((PixmapPtr) pMask->pDrawable,
xDst - xMask,
yDst - yMask);
if (!pGeometry)
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
}
else
{
if (!xglSyncSurface (pMask->pDrawable))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pMaskPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pMask->pDrawable);
if (XGL_PICTURE_CHANGES (pMaskPriv->pictureMask))
xglUpdatePicture (pMask);
mask = pMaskPriv->surface;
}
}
xDst = pBox->x1;
yDst = pBox->y1;
width = pBox->x2 - pBox->x1;
height = pBox->y2 - pBox->y1;
REGION_UNINIT (pScreen, &region);
/*
* Do software tile instead if hardware can't do it.
*/
if (pSrc->repeat && !pSrcPriv->acceleratedTile)
if (!pGeometry)
{
BoxRec box;
if (!pSrc->transform && pSrc->filter != PictFilterConvolution)
{
if (pSrc->repeat)
{
/* tile */
if (!pSrcPriv->acceleratedTile &&
(pSrc->pDrawable->width > 1 ||
pSrc->pDrawable->height > 1))
{
pGeometry =
xglTiledBoxGeometry ((PixmapPtr) pSrc->pDrawable,
xSrc - xDst, ySrc - yDst,
pBox, nBox);
if (!pGeometry)
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pBox = REGION_EXTENTS (pScreen, &region);
nBox = 1;
}
}
else
{
/* copy */
if (op == PictOpSrc && !mask)
{
if (xglCopy (pSrc->pDrawable,
pDst->pDrawable,
xSrc - xDst,
ySrc - yDst,
pBox,
nBox))
{
REGION_UNINIT (pScreen, &region);
return TRUE;
}
}
}
}
if (pSrc->transform || pSrc->filter > 1)
return FALSE;
if (nBox > 1)
{
pGeometry = xglGetScratchVertexGeometry (pScreen, 4 * nBox);
GEOMETRY_ADD_BOX (pScreen, pGeometry, pBox, nBox);
pBox = REGION_EXTENTS (pScreen, &region);
}
xSrc += pBox->x1 - xDst;
ySrc += pBox->y1 - yDst;
if (pMask)
{
xMask += pBox->x1 - xDst;
yMask += pBox->y1 - yDst;
}
/*
* Don't allow software tile with really small pixmaps.
*/
if (pSrc->pDrawable->width < 8 && pSrc->pDrawable->height < 8)
return FALSE;
box.x1 = xDst + dstXoff;
box.y1 = yDst + dstYoff;
box.x2 = box.x1 + width;
box.y2 = box.y1 + height;
glitz_surface_set_fill (pSrcPriv->surface, GLITZ_FILL_TRANSPARENT);
xglSwTile (XGL_OPERATOR (op),
pSrcPriv->surface,
(pMaskPriv)? pMaskPriv->surface: NULL,
dst,
xSrc - box.x1, ySrc - box.y1,
xMask - box.x1, yMask - box.y1,
TILE_SOURCE,
&box, 1,
0, 0);
xDst = pBox->x1;
yDst = pBox->y1;
width = pBox->x2 - pBox->x1;
height = pBox->y2 - pBox->y1;
}
else
{
glitz_composite (XGL_OPERATOR (op),
pSrcPriv->surface,
(pMaskPriv)? pMaskPriv->surface: NULL,
dst,
xSrc, ySrc,
xMask, yMask,
xDst + dstXoff, yDst + dstYoff,
width, height);
glitz_surface_set_clip_region (dst,
dstXoff, dstYoff,
(glitz_box_t *) pBox, nBox);
}
if (pGeometry)
{
GEOMETRY_TRANSLATE (pGeometry, dstXoff, dstYoff);
if (!GEOMETRY_ENABLE (pGeometry, dst))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
} else
GEOMETRY_DISABLE (dst);
glitz_composite (XGL_OPERATOR (op),
src, mask, dst,
xSrc, ySrc,
xMask, yMask,
xDst + dstXoff, yDst + dstYoff,
width, height);
glitz_surface_set_clip_region (dst, 0, 0, NULL, 0);
REGION_UNINIT (pScreen, &region);
if (glitz_surface_get_status (dst))
return FALSE;
xglAddBitDamage (pDst->pDrawable);
return TRUE;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,10 +20,11 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "fb.h"
Bool
xglCopy (DrawablePtr pSrc,
@ -33,101 +34,59 @@ xglCopy (DrawablePtr pSrc,
BoxPtr pBox,
int nBox)
{
glitz_surface_t *srcSurface;
glitz_surface_t *dstSurface;
glitz_surface_t *src, *dst;
int srcXoff, srcYoff;
int dstXoff, dstYoff;
if (!nBox)
return TRUE;
if (xglPrepareTarget (pDst))
{
glitz_drawable_t *srcDrawable;
glitz_drawable_t *dstDrawable;
XGL_SCREEN_PRIV (pDst->pScreen);
XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
if (!xglSyncSurface (pSrc))
return FALSE;
XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff);
XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
/*
* Blit to screen.
*/
if (dstSurface == pScreenPriv->surface)
XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 5000);
srcDrawable = glitz_surface_get_attached_drawable (srcSurface);
dstDrawable = glitz_surface_get_attached_drawable (dstSurface);
if (srcDrawable != dstDrawable && nBox > 1)
/* blit to screen */
if (dst == pScreenPriv->surface)
{
xglGeometryRec geometry;
BoxRec extents;
BOX_EXTENTS (pBox, nBox, &extents);
XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
GEOMETRY_INIT (pDst->pScreen, &geometry, nBox << 3);
GEOMETRY_ADD_BOX (pDst->pScreen, &geometry, pBox, nBox);
GEOMETRY_TRANSLATE (&geometry, dstXoff, dstYoff);
if (!GEOMETRY_ENABLE_ALL_VERTICES (&geometry, dstSurface))
return FALSE;
pPixmapPriv->pictureMask |=
xglPCFillMask | xglPCFilterMask | xglPCTransformMask;
glitz_surface_set_fill (srcSurface, GLITZ_FILL_TRANSPARENT);
glitz_surface_set_filter (srcSurface, GLITZ_FILTER_NEAREST,
NULL, 0);
glitz_surface_set_transform (srcSurface, NULL);
glitz_composite (GLITZ_OPERATOR_SRC,
srcSurface, NULL, dstSurface,
extents.x1 + dx + srcXoff,
extents.y1 + dy + srcYoff,
0, 0,
extents.x1 + dstXoff,
extents.y1 + dstYoff,
extents.x2 - extents.x1,
extents.y2 - extents.y1);
GEOMETRY_UNINIT (&geometry);
if (glitz_surface_get_status (dstSurface))
return FALSE;
return TRUE;
XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 5000);
}
}
else
{
if (!xglPrepareTarget (pSrc))
return FALSE;
if (!xglSyncSurface (pDst))
return FALSE;
XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff);
XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
}
while (nBox--)
{
glitz_copy_area (srcSurface,
dstSurface,
pBox->x1 + dx + srcXoff,
pBox->y1 + dy + srcYoff,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
pBox->x1 + dstXoff,
pBox->y1 + dstYoff);
pBox++;
XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
}
if (glitz_surface_get_status (dstSurface))
XGL_GET_DRAWABLE (pSrc, src, srcXoff, srcYoff);
glitz_surface_set_clip_region (dst,
dstXoff, dstYoff,
(glitz_box_t *) pBox, nBox);
glitz_copy_area (src,
dst,
pDst->x + srcXoff + dx,
pDst->y + srcYoff + dy,
pDst->width,
pDst->height,
pDst->x + dstXoff,
pDst->y + dstYoff);
glitz_surface_set_clip_region (dst, 0, 0, NULL, 0);
if (glitz_surface_get_status (dst))
return FALSE;
return TRUE;
@ -146,7 +105,59 @@ xglCopyProc (DrawablePtr pSrc,
Pixel bitplane,
void *closure)
{
Bool *pRet = (Bool *) closure;
*pRet = xglCopy (pSrc, pDst, dx, dy, pBox, nBox);
BoxPtr pSrcBox = (BoxPtr) closure;
if (!xglCopy (pSrc, pDst, dx, dy, pBox, nBox))
{
RegionPtr pDamageRegion;
glitz_surface_t *dst;
int dstXoff, dstYoff;
RegionRec region;
BoxRec box;
XGL_DRAWABLE_PIXMAP (pDst);
XGL_PIXMAP_PRIV (pPixmap);
XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
pDamageRegion = DamageRegion (pPixmapPriv->pDamage);
if (!xglMapPixmapBits (pPixmap))
FatalError (XGL_SW_FAILURE_STRING);
if (!xglSyncBits (pSrc, pSrcBox))
FatalError (XGL_SW_FAILURE_STRING);
fbCopyNtoN (pSrc, pDst, pGC,
pBox, nBox,
dx, dy,
reverse, upsidedown, bitplane,
(void *) 0);
pPixmapPriv->damageBox = miEmptyBox;
if (!pPixmapPriv->format)
return;
while (nBox--)
{
box.x1 = pBox->x1 + dstXoff;
box.y1 = pBox->y1 + dstYoff;
box.x2 = pBox->x2 + dstXoff;
box.y2 = pBox->y2 + dstYoff;
REGION_INIT (pDst->pScreen, &region, &box, 1);
REGION_UNION (pDst->pScreen,
pDamageRegion, pDamageRegion, &region);
REGION_UNINIT (pDst->pScreen, &region);
pBox++;
}
if (pPixmapPriv->target == xglPixmapTargetIn)
{
if (!xglSyncSurface (pDst))
FatalError (XGL_SW_FAILURE_STRING);
}
} else
xglAddCurrentBitDamage (pDst);
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,36 +20,48 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "gcstruct.h"
#include "fb.h"
Bool
xglFill (DrawablePtr pDrawable,
GCPtr pGC,
xglGeometryPtr pGeometry)
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox)
{
XGL_GC_PRIV (pGC);
switch (pGC->fillStyle) {
case FillSolid:
if (xglSolid (pDrawable, pGCPriv->op, &pGCPriv->fg,
if (xglSolid (pDrawable,
pGCPriv->op, &pGCPriv->fg,
pGeometry,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
x, y,
width, height,
pBox, nBox))
return TRUE;
break;
case FillStippled:
case FillOpaqueStippled:
break;
case FillTiled:
if (xglTile (pDrawable, pGCPriv->op, pGC->tile.pixmap,
-pGC->patOrg.x, -pGC->patOrg.y,
if (xglTile (pDrawable,
pGCPriv->op, pGC->tile.pixmap,
-(pGC->patOrg.x + pDrawable->x),
-(pGC->patOrg.y + pDrawable->y),
pGeometry,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
x, y,
width, height,
pBox, nBox))
return TRUE;
break;
}
@ -57,26 +69,163 @@ xglFill (DrawablePtr pDrawable,
return FALSE;
}
Bool
#define N_STACK_BOX 1024
static BoxPtr
xglMoreBoxes (BoxPtr stackBox,
BoxPtr heapBox,
int nBoxes)
{
Bool stack = !heapBox;
heapBox = xrealloc (heapBox, sizeof (BoxRec) * nBoxes);
if (!heapBox)
return NULL;
if (stack)
memcpy (heapBox, stackBox, sizeof (BoxRec) * N_STACK_BOX);
return heapBox;
}
#define ADD_BOX(pBox, nBox, stackBox, heapBox, size, box) \
{ \
if ((nBox) == (size)) \
{ \
(size) *= 2; \
(heapBox) = xglMoreBoxes (stackBox, heapBox, size); \
if (!(heapBox)) \
return; \
(pBox) = (heapBox) + (nBox); \
} \
*(pBox)++ = (box); \
(nBox)++; \
}
void
xglFillRect (DrawablePtr pDrawable,
GCPtr pGC,
int nrect,
xRectangle *prect)
{
xglGeometryRec geometry;
RegionPtr pClip = pGC->pCompositeClip;
BoxPtr pClipBox;
BoxPtr pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
BoxRec full, part;
BoxPtr heapBox = NULL;
BoxRec stackBox[N_STACK_BOX];
int size = N_STACK_BOX;
BoxPtr pBox = stackBox;
int n, nBox = 0;
GEOMETRY_INIT (pGC->pScreen, &geometry, nrect << 3);
GEOMETRY_ADD_RECT (pGC->pScreen, &geometry, prect, nrect);
GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
if (xglFill (pDrawable, pGC, &geometry))
while (nrect--)
{
GEOMETRY_UNINIT (&geometry);
return TRUE;
}
full.x1 = prect->x + pDrawable->x;
full.y1 = prect->y + pDrawable->y;
full.x2 = full.x1 + (int) prect->width;
full.y2 = full.y1 + (int) prect->height;
prect++;
if (full.x1 < pExtent->x1)
full.x1 = pExtent->x1;
if (full.y1 < pExtent->y1)
full.y1 = pExtent->y1;
if (full.x2 > pExtent->x2)
full.x2 = pExtent->x2;
if (full.y2 > pExtent->y2)
full.y2 = pExtent->y2;
if (full.x1 >= full.x2 || full.y1 >= full.y2)
continue;
n = REGION_NUM_RECTS (pClip);
if (n == 1)
{
ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
}
else
{
pClipBox = REGION_RECTS (pClip);
while (n--)
{
part.x1 = pClipBox->x1;
if (part.x1 < full.x1)
part.x1 = full.x1;
part.y1 = pClipBox->y1;
if (part.y1 < full.y1)
part.y1 = full.y1;
part.x2 = pClipBox->x2;
if (part.x2 > full.x2)
part.x2 = full.x2;
part.y2 = pClipBox->y2;
if (part.y2 > full.y2)
part.y2 = full.y2;
GEOMETRY_UNINIT (&geometry);
return FALSE;
pClipBox++;
if (part.x1 < part.x2 && part.y1 < part.y2)
ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
}
}
}
pBox = (heapBox) ? heapBox : stackBox;
if (!xglFill (pDrawable, pGC, NULL,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
pBox, nBox))
{
RegionRec region;
Bool overlap;
XGL_DRAWABLE_PIXMAP (pDrawable);
if (!xglMapPixmapBits (pPixmap))
FatalError (XGL_SW_FAILURE_STRING);
switch (pGC->fillStyle) {
case FillSolid:
break;
case FillStippled:
case FillOpaqueStippled:
if (!xglSyncBits (&pGC->stipple->drawable, NullBox))
FatalError (XGL_SW_FAILURE_STRING);
break;
case FillTiled:
if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox))
FatalError (XGL_SW_FAILURE_STRING);
break;
}
REGION_INIT (pGC->pScreen, &region, pBox, nBox);
while (nBox--)
{
fbFill (pDrawable, pGC,
pBox->x1, pBox->y1,
pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
pBox++;
}
/* hmm, overlap can't be good, don't know what to do about that */
REGION_VALIDATE (pGC->pScreen, &region, &overlap);
xglAddSurfaceDamage (pDrawable, &region);
REGION_UNINIT (pGC->pScreen, &region);
} else
xglAddCurrentBitDamage (pDrawable);
if (heapBox)
xfree (heapBox);
}
Bool
@ -86,23 +235,26 @@ xglFillSpan (DrawablePtr pDrawable,
DDXPointPtr ppt,
int *pwidth)
{
xglGeometryRec geometry;
BoxPtr pExtent;
xglGeometryPtr pGeometry;
GEOMETRY_INIT (pGC->pScreen, &geometry, n << 2);
GEOMETRY_ADD_SPAN (pGC->pScreen, &geometry, ppt, pwidth, n);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * n);
GEOMETRY_ADD_SPAN (pGC->pScreen, pGeometry, ppt, pwidth, n);
/* Spans are treated as lines so they need a 0.5 translate */
GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15);
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
GLITZ_GEOMETRY_PRIMITIVE_LINES);
GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
if (xglFill (pDrawable, pGC, &geometry))
{
GEOMETRY_UNINIT (&geometry);
if (xglFill (pDrawable, pGC, pGeometry,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@ -113,9 +265,12 @@ xglFillLine (DrawablePtr pDrawable,
int npt,
DDXPointPtr ppt)
{
xglGeometryRec geometry;
BoxPtr pExtent;
xglGeometryPtr pGeometry;
Bool coincident_endpoints;
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
coincident_endpoints = FALSE;
if (mode == CoordModePrevious)
{
@ -148,29 +303,30 @@ xglFillLine (DrawablePtr pDrawable,
if (coincident_endpoints)
npt--;
GEOMETRY_INIT (pGC->pScreen, &geometry, npt << 1);
GEOMETRY_ADD_LINE (pGC->pScreen, &geometry,
pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, npt);
GEOMETRY_ADD_LINE (pGC->pScreen, pGeometry,
coincident_endpoints, mode, npt, ppt);
if (coincident_endpoints)
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP);
GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_LOOP);
else
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP);
GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_STRIP);
/* Lines need a 0.5 translate */
GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15);
GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
if (xglFill (pDrawable, pGC, &geometry))
{
GEOMETRY_UNINIT (&geometry);
if (xglFill (pDrawable, pGC, pGeometry,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@ -180,19 +336,65 @@ xglFillSegment (DrawablePtr pDrawable,
int nsegInit,
xSegment *pSegInit)
{
xglGeometryRec geometry;
BoxPtr pExtent;
xglGeometryPtr pGeometry;
GEOMETRY_INIT (pGC->pScreen, &geometry, nsegInit << 2);
GEOMETRY_ADD_SEGMENT (pGC->pScreen, &geometry, nsegInit, pSegInit);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * nsegInit);
GEOMETRY_ADD_SEGMENT (pGC->pScreen, pGeometry, nsegInit, pSegInit);
/* Line segments need 0.5 translate */
GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15);
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
GLITZ_GEOMETRY_PRIMITIVE_LINES);
GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
if (xglFill (pDrawable, pGC, &geometry))
if (xglFill (pDrawable, pGC, pGeometry,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE;
return FALSE;
}
Bool
xglFillGlyph (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nGlyph,
CharInfoPtr *ppci,
pointer pglyphBase)
{
BoxPtr pExtent;
xglGeometryRec geometry;
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
x += pDrawable->x;
y += pDrawable->y;
GEOMETRY_INIT (pDrawable->pScreen, &geometry,
GLITZ_GEOMETRY_TYPE_BITMAP,
GEOMETRY_USAGE_SYSMEM, 0);
GEOMETRY_FOR_GLYPH (pDrawable->pScreen,
&geometry,
nGlyph,
ppci,
pglyphBase);
GEOMETRY_TRANSLATE (&geometry, x, y);
if (xglFill (pDrawable, pGC, &geometry,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
{
GEOMETRY_UNINIT (&geometry);
return TRUE;

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -36,7 +36,7 @@
#define XGL_GC_OP_FALLBACK_EPILOGUE(pDrawable) \
XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs); \
XGL_GC_WRAP (ops, (GCOps *) &xglGCOps); \
xglAddSurfaceDamage (pDrawable)
xglAddCurrentSurfaceDamage (pDrawable)
#define XGL_GC_FILL_OP_FALLBACK_PROLOGUE(pDrawable) \
switch (pGC->fillStyle) { \
@ -104,7 +104,7 @@ xglFillSpans (DrawablePtr pDrawable,
{
if (xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth))
{
xglAddBitDamage (pDrawable);
xglAddCurrentBitDamage (pDrawable);
return;
}
}
@ -144,38 +144,45 @@ xglPutImage (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
switch (format) {
case XYBitmap:
break;
case XYPixmap:
case ZPixmap:
if (!pGCPriv->flags)
{
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
if (!pPixmapPriv->allBits &&
pPixmapPriv->target == xglPixmapTargetIn)
{
if (xglSetPixels (pDrawable,
bits,
PixmapBytePad (w, pDrawable->depth),
x + pDrawable->x, y + pDrawable->y,
w, h,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
{
xglAddBitDamage (pDrawable);
return;
}
}
}
break;
if (pGC->alu != GXcopy || (pGCPriv->flags & xglGCPlaneMaskFlag))
{
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PutImage) (pDrawable, pGC, depth,
x, y, w, h, leftPad, format, bits);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
else
{
RegionPtr pClip = pGC->pCompositeClip;
RegionRec region;
BoxRec box;
XGL_DRAWABLE_PIXMAP (pDrawable);
if (!xglMapPixmapBits (pPixmap))
FatalError (XGL_SW_FAILURE_STRING);
XGL_GC_UNWRAP (funcs);
XGL_GC_UNWRAP (ops);
(*pGC->ops->PutImage) (pDrawable, pGC, depth,
x, y, w, h, leftPad, format, bits);
XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
box.x1 = pDrawable->x + x;
box.y1 = pDrawable->y + y;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
REGION_INIT (pDrawable->pScreen, &region, &box, 1);
REGION_INTERSECT (pDrawable->pScreen, &region, pClip, &region);
xglAddSurfaceDamage (pDrawable, &region);
REGION_UNINIT (pDrawable->pScreen, &region);
}
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PutImage) (pDrawable, pGC, depth,
x, y, w, h, leftPad, format, bits);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
RegionPtr
@ -195,45 +202,37 @@ xglCopyArea (DrawablePtr pSrc,
XGL_GC_PRIV (pGC);
box.x1 = pSrc->x + srcX;
box.y1 = pSrc->y + srcY;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
flags = pGCPriv->flags;
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (pSrc)->target == xglPixmapTargetIn)
flags &= ~xglGCReadOnlyDrawableFlag;
if (!flags)
if (flags)
{
Bool ret;
ret = TRUE;
if (!xglSyncBits (pSrc, &box))
FatalError (XGL_SW_FAILURE_STRING);
XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
srcX, srcY, w, h, dstX, dstY);
XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
}
else
{
/* xglCopyProc handles fall-back */
pRegion = fbDoCopy (pSrc, pDst, pGC,
srcX, srcY,
w, h,
dstX, dstY,
xglCopyProc, 0,
(void *) &ret);
if (ret)
{
xglAddBitDamage (pDst);
return pRegion;
}
if (pRegion)
REGION_DESTROY (pDst->pScreen, pRegion);
(void *) &box);
}
box.x1 = pSrc->x + srcX;
box.y1 = pSrc->y + srcY;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
if (!xglSyncBits (pSrc, &box))
FatalError (XGL_SW_FAILURE_STRING);
XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
srcX, srcY, w, h, dstX, dstY);
XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
return pRegion;
}
@ -302,13 +301,13 @@ xglPolylines (DrawablePtr pDrawable,
{
if (xglFillLine (pDrawable, pGC, mode, npt, ppt))
{
xglAddBitDamage (pDrawable);
xglAddCurrentBitDamage (pDrawable);
return;
}
}
}
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppt);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
@ -337,13 +336,13 @@ xglPolySegment (DrawablePtr pDrawable,
{
if (xglFillSegment (pDrawable, pGC, nsegInit, pSegInit))
{
xglAddBitDamage (pDrawable);
xglAddCurrentBitDamage (pDrawable);
return;
}
}
}
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolySegment) (pDrawable, pGC, nsegInit, pSegInit);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} else
@ -360,7 +359,7 @@ xglPolyArc (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyArc) (pDrawable, pGC, narcs, pArcs);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} else
@ -375,18 +374,17 @@ xglPolyFillRect (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
if (!pGCPriv->flags)
if (pGCPriv->flags || pGC->fillStyle == FillStippled)
{
if (xglFillRect (pDrawable, pGC, nrect, prect))
{
xglAddBitDamage (pDrawable);
return;
}
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
else
{
/* xglFillRect handles fall-back */
xglFillRect (pDrawable, pGC, nrect, prect);
}
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
void
@ -412,7 +410,22 @@ xglImageGlyphBlt (DrawablePtr pDrawable,
pointer pglyphBase)
{
XGL_GC_PRIV (pGC);
if (!(pGCPriv->flags & ~xglGCBadFunctionFlag))
{
if (xglSolidGlyph (pDrawable,
pGC,
x,
y,
nglyph,
ppci,
pglyphBase))
{
xglAddCurrentBitDamage (pDrawable);
return;
}
}
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
@ -429,8 +442,23 @@ xglPolyGlyphBlt (DrawablePtr pDrawable,
pointer pglyphBase)
{
XGL_GC_PRIV (pGC);
if (!pGCPriv->flags)
{
if (xglFillGlyph (pDrawable,
pGC,
x,
y,
nglyph,
ppci,
pglyphBase))
{
xglAddCurrentBitDamage (pDrawable);
return;
}
}
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
@ -486,6 +514,20 @@ xglValidateGC (GCPtr pGC,
{
XGL_GC_PRIV (pGC);
if (changes & GCTile)
{
if (!pGC->tileIsPixel &&
FbEvenTile (pGC->tile.pixmap->drawable.width *
pDrawable->bitsPerPixel))
xglSyncBits (&pGC->tile.pixmap->drawable, NULL);
}
if (changes & GCStipple)
{
if (pGC->stipple)
xglSyncBits (&pGC->stipple->drawable, NULL);
}
XGL_GC_UNWRAP (funcs);
XGL_GC_UNWRAP (ops);
(*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,15 +20,14 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "fontstruct.h"
#include "dixfontstr.h"
struct xglDataTypeInfo {
glitz_data_type_t type;
int size;
} dataTypes[] = {
xglDataTypeInfoRec xglGeometryDataTypes[2] = {
{ GLITZ_DATA_TYPE_SHORT, sizeof (glitz_short_t) },
{ GLITZ_DATA_TYPE_FLOAT, sizeof (glitz_float_t) }
};
@ -45,19 +44,17 @@ xglGeometryResize (ScreenPtr pScreen,
int size)
{
XGL_SCREEN_PRIV (pScreen);
if (pGeometry->broken)
return;
if (size == pGeometry->size)
return;
if (pGeometry->usage == GEOMETRY_USAGE_USERMEM)
{
pGeometry->data =
xrealloc (pGeometry->data,
size * dataTypes[pGeometry->dataType].size);
if (pGeometry->broken)
return;
if (pGeometry->usage == GEOMETRY_USAGE_SYSMEM)
{
pGeometry->data = xrealloc (pGeometry->data, size);
if (pGeometry->buffer)
glitz_buffer_destroy (pGeometry->buffer);
@ -81,16 +78,11 @@ xglGeometryResize (ScreenPtr pScreen,
else
{
glitz_buffer_t *newBuffer;
int dataTypeSize;
dataTypeSize = dataTypes[pGeometry->dataType].size;
if (size)
{
newBuffer =
glitz_geometry_buffer_create (pScreenPriv->drawable, NULL,
size * dataTypeSize,
usageTypes[pGeometry->usage]);
glitz_vertex_buffer_create (pScreenPriv->drawable, NULL, size,
usageTypes[pGeometry->usage]);
if (!newBuffer)
{
pGeometry->broken = TRUE;
@ -109,8 +101,7 @@ xglGeometryResize (ScreenPtr pScreen,
GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (oldData && newData)
memcpy (newData, oldData,
MIN (size, pGeometry->size) * dataTypeSize);
memcpy (newData, oldData, MIN (size, pGeometry->size));
glitz_buffer_unmap (pGeometry->buffer);
glitz_buffer_unmap (newBuffer);
@ -126,103 +117,39 @@ xglGeometryResize (ScreenPtr pScreen,
pGeometry->endOffset = size;
}
/*
* Storage for 100 extra vertices are always allocated if
* buffer size is to small. Geometry should be initialized
* to desired size prior to calling this function when size
* is known.
*/
#define RESIZE_GEOMETRY_FOR_VERTICES(pScreen, pGeometry, nvertices) \
if (((pGeometry)->size - (pGeometry)->endOffset) < ((nvertices) << 1)) \
#define MAP_GEOMETRY(pScreen, pGeometry, offset, units, ptr, _size) \
if ((pGeometry)->broken) \
return; \
(_size) = (units) * xglGeometryDataTypes[(pGeometry)->dataType].size; \
if (((pGeometry)->size - (offset)) < (_size)) \
{ \
xglGeometryResize (pScreen, pGeometry, \
(pGeometry)->endOffset + (_size) + 500); \
if ((pGeometry)->broken) \
return; \
} \
(ptr) = glitz_buffer_map ((pGeometry)->buffer, \
GLITZ_BUFFER_ACCESS_WRITE_ONLY); \
if (!(ptr)) \
{ \
(pGeometry)->broken = TRUE; \
return; \
} \
(ptr) += (offset)
#define UNMAP_GEOMETRY(pGeometry, offset, _size) \
if (glitz_buffer_unmap ((pGeometry)->buffer)) \
{ \
xglGeometryResize (pScreen, pGeometry, \
(pGeometry)->endOffset + \
((nvertices) << 1) + 200); \
if ((pGeometry)->broken) \
return; \
}
/*
* Adds a number of rectangles as GL_QUAD primitives
*/
void
xglGeometryAddRect (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xRectangle *pRect,
int nRect)
{
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
if (nRect < 1)
return;
nvertices = nRect << 2;
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (nRect--)
{
*data++ = pRect->x;
*data++ = pRect->y;
*data++ = pRect->x + pRect->width;
*data++ = pRect->y;
*data++ = pRect->x + pRect->width;
*data++ = pRect->y + pRect->height;
*data++ = pRect->x;
*data++ = pRect->y + pRect->height;
pRect++;
}
} break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (nRect--)
{
*data++ = (glitz_float_t) pRect->x;
*data++ = (glitz_float_t) pRect->y;
*data++ = (glitz_float_t) pRect->x + pRect->width;
*data++ = (glitz_float_t) pRect->y;
*data++ = (glitz_float_t) pRect->x + pRect->width;
*data++ = (glitz_float_t) pRect->y + pRect->height;
*data++ = (glitz_float_t) pRect->x;
*data++ = (glitz_float_t) pRect->y + pRect->height;
pRect++;
}
} break;
(pGeometry)->broken = TRUE; \
return; \
} \
if (((offset) + (_size)) > (pGeometry)->endOffset) \
{ \
(pGeometry)->endOffset = (offset) + (_size); \
(pGeometry)->count = (pGeometry)->endOffset / \
(2 * xglGeometryDataTypes[(pGeometry)->dataType].size); \
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
}
/*
* Adds a number of boxes as GL_QUAD primitives
*/
@ -230,124 +157,88 @@ void
xglGeometryAddBox (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
BoxPtr pBox,
int nBox)
int nBox,
int offset)
{
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
int size;
char *ptr;
if (nBox < 1)
return;
nvertices = nBox << 2;
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (nBox--)
{
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y2;
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y2;
pBox++;
}
} break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (nBox--)
{
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y2;
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y2;
pBox++;
}
} break;
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
}
/*
* Adds a number of spans as GL_LINE primitives
*
* An extra 1 is added to *pwidth as OpenGL line segments are half-opened.
*/
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
int n)
{
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
if (n < 1)
return;
nvertices = n << 1;
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
MAP_GEOMETRY (pScreen, pGeometry, offset, nBox * 8, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (nBox--)
{
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y2;
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y2;
pBox++;
}
} break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
while (nBox--)
{
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y2;
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y2;
pBox++;
}
} break;
}
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
* Adds a number of spans as GL_LINE primitives
*/
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
int n,
int offset)
{
int size;
char *ptr;
if (n < 1)
return;
MAP_GEOMETRY (pScreen, pGeometry, offset, n * 4, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
while (n--)
{
*data++ = (glitz_short_t) ppt->x;
*data++ = (glitz_short_t) ppt->y;
*data++ = (glitz_short_t) (ppt->x + *pwidth + 1);
*data++ = (glitz_short_t) (ppt->x + *pwidth);
*data++ = (glitz_short_t) ppt->y;
ppt++;
@ -358,13 +249,11 @@ xglGeometryAddSpan (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (n--)
{
*data++ = (glitz_float_t) ppt->x;
*data++ = (glitz_float_t) ppt->y;
*data++ = (glitz_float_t) (ppt->x + *pwidth + 1);
*data++ = (glitz_float_t) (ppt->x + *pwidth);
*data++ = (glitz_float_t) ppt->y;
ppt++;
@ -372,14 +261,8 @@ xglGeometryAddSpan (ScreenPtr pScreen,
}
} break;
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
@ -401,28 +284,17 @@ xglGeometryAddLine (ScreenPtr pScreen,
int loop,
int mode,
int npt,
DDXPointPtr ppt)
DDXPointPtr ppt,
int offset)
{
DDXPointRec pt;
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
int size;
char *ptr;
if (npt < 2)
return;
nvertices = npt;
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
MAP_GEOMETRY (pScreen, pGeometry, offset, npt * 2, ptr, size);
pt.x = 0;
pt.y = 0;
@ -432,8 +304,6 @@ xglGeometryAddLine (ScreenPtr pScreen,
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (npt--)
{
if (mode == CoordModePrevious)
@ -447,19 +317,17 @@ xglGeometryAddLine (ScreenPtr pScreen,
pt.y = ppt->y;
}
*data++ = pt.x;
*data++ = pt.y;
if (npt || loop)
{
*data++ = pt.x;
*data++ = pt.y;
*data++ = (glitz_short_t) pt.x;
*data++ = (glitz_short_t) pt.y;
}
else
{
ppt--;
*data++ = ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
*data++ = ADJUST_END_POINT (ppt->y, pt.y, 0);
*data++ = (glitz_short_t)
ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
*data++ = (glitz_short_t) ADJUST_END_POINT (ppt->y, pt.y, 0);
}
ppt++;
@ -469,8 +337,6 @@ xglGeometryAddLine (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (npt--)
{
if (mode == CoordModePrevious)
@ -501,14 +367,8 @@ xglGeometryAddLine (ScreenPtr pScreen,
}
} break;
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
@ -518,42 +378,31 @@ void
xglGeometryAddSegment (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
int nsegInit,
xSegment *pSegInit)
xSegment *pSegInit,
int offset)
{
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
int size;
char *ptr;
if (nsegInit < 1)
return;
nvertices = nsegInit << 1;
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
MAP_GEOMETRY (pScreen, pGeometry, offset, nsegInit * 4, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (nsegInit--)
{
*data++ = pSegInit->x1;
*data++ = pSegInit->y1;
*data++ = ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
pSegInit->y1 == pSegInit->y2);
*data++ = ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
*data++ = (glitz_short_t) pSegInit->x1;
*data++ = (glitz_short_t) pSegInit->y1;
*data++ = (glitz_short_t)
ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
pSegInit->y1 == pSegInit->y2);
*data++ = (glitz_short_t)
ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
pSegInit++;
}
@ -562,8 +411,6 @@ xglGeometryAddSegment (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (nsegInit--)
{
*data++ = (glitz_float_t) pSegInit->x1;
@ -578,38 +425,299 @@ xglGeometryAddSegment (ScreenPtr pScreen,
}
} break;
}
if (glitz_buffer_unmap (pGeometry->buffer))
UNMAP_GEOMETRY (pGeometry, offset, size);
}
void
xglGeometryForGlyph (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
unsigned int nGlyph,
CharInfoPtr *ppciInit,
pointer pglyphBase)
{
CharInfoPtr *ppci;
CharInfoPtr pci;
unsigned char *glyphbase = (pointer) ~0;
unsigned char *pglyph;
int x = 0;
int gx, gy;
int gWidth, gHeight;
int n, lastX = 0, lastY = 0;
glitz_multi_array_t *array;
glitz_buffer_t *buffer;
ppci = ppciInit;
n = nGlyph;
while (n--)
{
pglyph = FONTGLYPHBITS (pglyphBase, *ppci++);
if (pglyph < glyphbase)
glyphbase = pglyph;
}
buffer = glitz_buffer_create_for_data (glyphbase);
if (!buffer)
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
GEOMETRY_SET_BUFFER (pGeometry, buffer);
array = glitz_multi_array_create (nGlyph);
if (!array)
{
pGeometry->broken = TRUE;
return;
}
GEOMETRY_SET_MULTI_ARRAY (pGeometry, array);
ppci = ppciInit;
while (nGlyph--)
{
pci = *ppci++;
pglyph = FONTGLYPHBITS (pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS (pci);
gHeight = GLYPHHEIGHTPIXELS (pci);
if (gWidth && gHeight)
{
gx = x + pci->metrics.leftSideBearing;
gy = -pci->metrics.ascent;
glitz_multi_array_add (array,
(pglyph - glyphbase) * 8,
gWidth, gHeight,
(gx - lastX) << 16, (gy - lastY) << 16);
lastX = gx;
lastY = gy;
}
x += pci->metrics.characterWidth;
}
glitz_buffer_destroy (buffer);
glitz_multi_array_destroy (array);
}
#define FIXED_LINE_X_TO_FLOAT(line, v) \
(((glitz_float_t) \
((line).p1.x + (xFixed_16_16) \
(((xFixed_32_32) ((v) - (line).p1.y) * \
((line).p2.x - (line).p1.x)) / \
((line).p2.y - (line).p1.y)))) / 65536)
#define FIXED_LINE_X_CEIL_TO_FLOAT(line, v) \
(((glitz_float_t) \
((line).p1.x + (xFixed_16_16) \
(((((line).p2.y - (line).p1.y) - 1) + \
((xFixed_32_32) ((v) - (line).p1.y) * \
((line).p2.x - (line).p1.x))) / \
((line).p2.y - (line).p1.y)))) / 65536)
/*
* Adds a number of trapezoids as GL_QUAD primitives
*/
void
xglGeometryAddTrapezoid (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xTrapezoid *pTrap,
int nTrap,
int offset)
{
int size;
char *ptr;
if (nTrap < 1)
return;
MAP_GEOMETRY (pScreen, pGeometry, offset, nTrap * 8, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
/* not supported */
pGeometry->broken = TRUE;
break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
glitz_float_t top, bottom;
while (nTrap--)
{
top = FIXED_TO_FLOAT (pTrap->top);
bottom = FIXED_TO_FLOAT (pTrap->bottom);
*data++ = FIXED_LINE_X_TO_FLOAT (pTrap->left, pTrap->top);
*data++ = top;
*data++ = FIXED_LINE_X_CEIL_TO_FLOAT (pTrap->right, pTrap->top);
*data++ = top;
*data++ = FIXED_LINE_X_CEIL_TO_FLOAT (pTrap->right, pTrap->bottom);
*data++ = bottom;
*data++ = FIXED_LINE_X_TO_FLOAT (pTrap->left, pTrap->bottom);
*data++ = bottom;
pTrap++;
}
} break;
}
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
* Adds a number of traps as GL_QUAD primitives
*/
void
xglGeometryAddTrap (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xTrap *pTrap,
int nTrap,
int offset)
{
int size;
char *ptr;
if (nTrap < 1)
return;
MAP_GEOMETRY (pScreen, pGeometry, offset, nTrap * 8, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
/* not supported */
pGeometry->broken = TRUE;
break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
glitz_float_t top, bottom;
while (nTrap--)
{
top = FIXED_TO_FLOAT (pTrap->top.y);
bottom = FIXED_TO_FLOAT (pTrap->bot.y);
*data++ = FIXED_TO_FLOAT (pTrap->top.l);
*data++ = top;
*data++ = FIXED_TO_FLOAT (pTrap->top.r);
*data++ = top;
*data++ = FIXED_TO_FLOAT (pTrap->bot.r);
*data++ = bottom;
*data++ = FIXED_TO_FLOAT (pTrap->bot.l);
*data++ = bottom;
pTrap++;
}
} break;
}
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/* XXX: scratch geometry size never shrinks, it just gets larger when
required. this is not acceptable. */
xglGeometryPtr
xglGetScratchGeometryWithSize (ScreenPtr pScreen,
int size)
{
xglGeometryPtr pGeometry;
XGL_SCREEN_PRIV (pScreen);
pGeometry = &pScreenPriv->scratchGeometry;
if (pGeometry->broken || pGeometry->size < size)
{
GEOMETRY_UNINIT (pGeometry);
GEOMETRY_INIT (pScreen, pGeometry, pGeometry->type,
pScreenPriv->geometryUsage, size);
}
else
{
if (pGeometry->array)
{
glitz_multi_array_destroy (pGeometry->array);
pGeometry->array = NULL;
}
pGeometry->endOffset = 0;
pGeometry->xOff = 0;
pGeometry->yOff = 0;
pGeometry->first = 0;
pGeometry->count = 0;
pGeometry->width = 2;
}
return pGeometry;
}
xglGeometryPtr
xglGetScratchVertexGeometryWithType (ScreenPtr pScreen,
int type,
int count)
{
xglGeometryPtr pGeometry;
int stride;
stride = 2 * xglGeometryDataTypes[type].size;
pGeometry = xglGetScratchGeometryWithSize (pScreen, count * stride);
pGeometry->type = GLITZ_GEOMETRY_TYPE_VERTEX;
pGeometry->dataType = type;
pGeometry->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS;
pGeometry->f.vertex.type = xglGeometryDataTypes[type].type;
pGeometry->f.vertex.bytes_per_vertex = stride;
pGeometry->f.vertex.attributes = 0;
return pGeometry;
}
xglGeometryPtr
xglGetScratchVertexGeometry (ScreenPtr pScreen,
int count)
{
xglGeometryPtr pGeometry;
int type, stride;
XGL_SCREEN_PRIV (pScreen);
type = pScreenPriv->geometryDataType;
stride = 2 * xglGeometryDataTypes[type].size;
pGeometry = xglGetScratchGeometryWithSize (pScreen, count * stride);
pGeometry->type = GLITZ_GEOMETRY_TYPE_VERTEX;
pGeometry->dataType = type;
pGeometry->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS;
pGeometry->f.vertex.type = xglGeometryDataTypes[type].type;
pGeometry->f.vertex.bytes_per_vertex = stride;
pGeometry->f.vertex.attributes = 0;
return pGeometry;
}
Bool
xglSetGeometry (xglGeometryPtr pGeometry,
glitz_surface_t *surface,
int first,
int count)
glitz_surface_t *surface)
{
glitz_geometry_format_t format;
if (pGeometry->broken)
return FALSE;
format.first = first;
format.count = count;
format.primitive = pGeometry->primitive;
format.type = dataTypes[pGeometry->dataType].type;
format.mode = GLITZ_GEOMETRY_MODE_DIRECT;
format.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_SHARP;
glitz_set_geometry (surface,
pGeometry->xOff, pGeometry->yOff,
&format,
glitz_set_geometry (surface, pGeometry->type, &pGeometry->f,
pGeometry->buffer);
if (pGeometry->array)
glitz_set_multi_array (surface, pGeometry->array,
pGeometry->xOff, pGeometry->yOff);
else
glitz_set_array (surface,
pGeometry->first, pGeometry->width, pGeometry->count,
pGeometry->xOff, pGeometry->yOff);
return TRUE;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -35,8 +35,10 @@ xglGetImage (DrawablePtr pDrawable,
unsigned long planeMask,
char *d)
{
ScreenPtr pScreen = pDrawable->pScreen;
BoxRec box;
ScreenPtr pScreen = pDrawable->pScreen;
glitz_surface_t *surface;
int xOff, yOff;
BoxRec box;
XGL_SCREEN_PRIV (pScreen);
@ -44,11 +46,13 @@ xglGetImage (DrawablePtr pDrawable,
if (pDrawable->type == DRAWABLE_WINDOW)
{
glitz_surface_flush (pScreenPriv->surface);
glitz_drawable_flush (pScreenPriv->drawable);
glitz_drawable_finish (pScreenPriv->drawable);
}
box.x1 = x + pDrawable->x;
box.y1 = y + pDrawable->y;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
box.x1 = pDrawable->x + xOff + x;
box.y1 = pDrawable->y + yOff + y;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;

1080
hw/xgl/xglglyph.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,278 +20,98 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
/*
* This offscreen memory manager is horrible and needs some serious work.
*
* It's a recursive memory manager. It's quite fast but wastes huge
* amounts of memory. A simple scoring mechanism is used and pixmaps
* that blit to screen get high scores which makes a compositing
* manager run fast.
*
* NOTE: With GL_ARB_uber_buffer or GL_EXT_render_target we probably
* wont need this offscreen management at all.
*/
static glitz_drawable_buffer_t _buffers[] = {
GLITZ_DRAWABLE_BUFFER_BACK_COLOR,
GLITZ_DRAWABLE_BUFFER_FRONT_COLOR
};
#define MAX_LEVEL 6
#define MAX_OFFSCREEN_LEVEL 8
static Bool
xglOffscreenMoveIn (xglOffscreenAreaPtr pArea,
PixmapPtr pPixmap)
xglOffscreenCreate (xglAreaPtr pArea)
{
return TRUE;
}
static Bool
xglOffscreenMoveIn (xglAreaPtr pArea,
pointer closure)
{
xglOffscreenPtr pOffscreen = (xglOffscreenPtr) pArea->pRoot->closure;
PixmapPtr pPixmap = (PixmapPtr) closure;
XGL_PIXMAP_PRIV (pPixmap);
if (!xglSyncSurface (&pPixmap->drawable))
FatalError (XGL_SW_FAILURE_STRING);
pArea->pPixmapPriv = pPixmapPriv;
pArea->state = xglOffscreenAreaOccupied;
pPixmapPriv->pArea = pArea;
pPixmapPriv->target = xglPixmapTargetIn;
glitz_surface_attach (pPixmapPriv->surface,
pArea->pOffscreen->drawable,
pArea->pOffscreen->buffer,
pOffscreen->drawable, pOffscreen->buffer,
pArea->x, pArea->y);
XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 500);
XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 100);
return TRUE;
}
static void
xglOffscreenMoveOut (xglOffscreenAreaPtr pArea)
xglOffscreenMoveOut (xglAreaPtr pArea,
pointer closure)
{
glitz_surface_detach (pArea->pPixmapPriv->surface);
PixmapPtr pPixmap = (PixmapPtr) closure;
pArea->pPixmapPriv->pArea = NULL;
pArea->pPixmapPriv->target = xglPixmapTargetOut;
pArea->pPixmapPriv = NULL;
pArea->state = xglOffscreenAreaAvailable;
}
static xglOffscreenAreaPtr
xglCreateOffscreenArea (xglOffscreenPtr pOffscreen,
int level,
int x,
int y)
{
xglOffscreenAreaPtr pArea;
int i;
pArea = xalloc (sizeof (xglOffscreenAreaRec));
if (!pArea)
return NULL;
pArea->level = level;
pArea->x = x;
pArea->y = y;
pArea->pOffscreen = pOffscreen;
pArea->pPixmapPriv = NULL;
pArea->state = xglOffscreenAreaAvailable;
for (i = 0; i < 4; i++)
pArea->pArea[i] = NULL;
return pArea;
}
static void
xglDestroyOffscreenArea (xglOffscreenAreaPtr pArea)
{
if (!pArea)
return;
if (pArea->pPixmapPriv)
{
xglOffscreenMoveOut (pArea);
}
else
{
int i;
XGL_PIXMAP_PRIV (pPixmap);
for (i = 0; i < 4; i++)
xglDestroyOffscreenArea (pArea->pArea[i]);
}
glitz_surface_detach (pPixmapPriv->surface);
xfree (pArea);
}
static Bool
xglOffscreenInit (xglOffscreenPtr pOffscreen,
glitz_drawable_t *drawable,
glitz_drawable_buffer_t buffer,
unsigned int width,
unsigned int height)
{
pOffscreen->pArea = xglCreateOffscreenArea (NULL, 0, 0, 0);
if (!pOffscreen->pArea)
return FALSE;
glitz_drawable_reference (drawable);
pOffscreen->drawable = drawable;
pOffscreen->format = glitz_drawable_get_format (drawable);
pOffscreen->buffer = buffer;
pOffscreen->width = width;
pOffscreen->height = height;
return TRUE;
}
static void
xglOffscreenFini (xglOffscreenPtr pOffscreen)
{
xglDestroyOffscreenArea (pOffscreen->pArea);
glitz_drawable_destroy (pOffscreen->drawable);
pPixmapPriv->pArea = NULL;
pPixmapPriv->target = xglPixmapTargetOut;
}
static int
xglOffscreenAreaGetTopScore (xglOffscreenAreaPtr pArea)
xglOffscreenCompareScore (xglAreaPtr pArea,
pointer closure1,
pointer closure2)
{
int topScore;
int s1, s2;
if (pArea->pPixmapPriv)
{
topScore = pArea->pPixmapPriv->score;
XGL_DECREMENT_PIXMAP_SCORE (pArea->pPixmapPriv, 5);
return topScore;
}
else
{
int topScore, score, i;
topScore = 0;
for (i = 0; i < 4; i++)
{
if (pArea->pArea[i])
{
score = xglOffscreenAreaGetTopScore (pArea->pArea[i]);
if (score > topScore)
topScore = score;
}
}
return topScore;
}
XGL_PIXMAP_PRIV ((PixmapPtr) closure1);
s1 = pPixmapPriv->score;
s2 = XGL_GET_PIXMAP_PRIV ((PixmapPtr) closure2)->score;
if (s1 > s2)
XGL_DECREMENT_PIXMAP_SCORE (pPixmapPriv, 10);
return s1 - s2;
}
static Bool
xglOffscreenFindArea (xglOffscreenAreaPtr pArea,
PixmapPtr pPixmap,
int level)
{
if (pArea->level > level)
return FALSE;
switch (pArea->state) {
case xglOffscreenAreaOccupied:
{
XGL_PIXMAP_PRIV (pPixmap);
if (pPixmapPriv->score < pArea->pPixmapPriv->score)
{
XGL_DECREMENT_PIXMAP_SCORE (pArea->pPixmapPriv, 10);
return FALSE;
}
xglOffscreenMoveOut (pArea);
}
/* fall-through */
case xglOffscreenAreaAvailable:
{
if (pArea->level == level || pArea->level == MAX_LEVEL)
{
if (xglOffscreenMoveIn (pArea, pPixmap))
return TRUE;
}
else
{
int dx[4], dy[4], i;
dx[0] = dx[2] = dy[0] = dy[1] = 0;
dx[1] = dx[3] = pArea->pOffscreen->width >> (pArea->level + 1);
dy[2] = dy[3] = pArea->pOffscreen->height >> (pArea->level + 1);
for (i = 0; i < 4; i++)
{
pArea->pArea[i] =
xglCreateOffscreenArea (pArea->pOffscreen,
pArea->level + 1,
pArea->x + dx[i],
pArea->y + dy[i]);
}
pArea->state = xglOffscreenAreaDivided;
if (xglOffscreenFindArea (pArea->pArea[0], pPixmap, level))
return TRUE;
}
} break;
case xglOffscreenAreaDivided:
{
int i;
if (pArea->level == level)
{
int topScore;
XGL_PIXMAP_PRIV (pPixmap);
topScore = xglOffscreenAreaGetTopScore (pArea);
if (pPixmapPriv->score >= topScore)
{
/*
* Kick out old pixmaps
*/
for (i = 0; i < 4; i++)
{
xglDestroyOffscreenArea (pArea->pArea[i]);
pArea->pArea[i] = NULL;
}
if (xglOffscreenMoveIn (pArea, pPixmap))
return TRUE;
}
}
else
{
for (i = 0; i < 4; i++)
{
if (xglOffscreenFindArea (pArea->pArea[i], pPixmap, level))
return TRUE;
}
}
} break;
}
return FALSE;
}
static const xglAreaFuncsRec xglOffscreenAreaFuncs = {
xglOffscreenCreate,
xglOffscreenMoveIn,
xglOffscreenMoveOut,
xglOffscreenCompareScore
};
Bool
xglInitOffscreen (ScreenPtr pScreen,
xglScreenInfoPtr pScreenInfo)
{
xglOffscreenPtr pOffscreen;
int nOffscreen;
glitz_drawable_format_t *format;
XGL_SCREEN_PRIV (pScreen);
pScreenPriv->pOffscreen = NULL;
pOffscreen = pScreenPriv->pOffscreen;
pScreenPriv->nOffscreen = 0;
format = glitz_drawable_get_format (pScreenPriv->drawable);
@ -301,33 +121,32 @@ xglInitOffscreen (ScreenPtr pScreen,
*/
if (format->doublebuffer)
{
pScreenPriv->pOffscreen =
xrealloc (pScreenPriv->pOffscreen,
sizeof (xglOffscreenRec) *
(pScreenPriv->nOffscreen + 1));
if (pScreenPriv->pOffscreen)
pOffscreen->drawable = pScreenPriv->drawable;
pOffscreen->format = format;
pOffscreen->buffer = GLITZ_DRAWABLE_BUFFER_BACK_COLOR;
if (xglRootAreaInit (&pOffscreen->rootArea,
MAX_OFFSCREEN_LEVEL,
pScreenInfo->width,
pScreenInfo->height, 0,
(xglAreaFuncsPtr) &xglOffscreenAreaFuncs,
(pointer) pOffscreen))
{
pOffscreen = &pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
glitz_drawable_reference (pOffscreen->drawable);
if (xglOffscreenInit (pOffscreen,
pScreenPriv->drawable,
GLITZ_DRAWABLE_BUFFER_BACK_COLOR,
pScreenInfo->width, pScreenInfo->height))
{
pScreenPriv->nOffscreen++;
ErrorF ("Initialized %dx%d back buffer offscreen area\n",
pScreenInfo->width, pScreenInfo->height);
}
pScreenPriv->nOffscreen++;
pOffscreen++;
ErrorF ("Initialized %dx%d back buffer offscreen area\n",
pScreenInfo->width, pScreenInfo->height);
}
}
if (nxglPbufferVisuals)
{
glitz_pbuffer_attributes_t attributes;
unsigned long mask;
glitz_drawable_t *pbuffer;
int i;
glitz_drawable_t *pbuffer;
unsigned int width, height;
int i;
for (i = 0; i < nxglPbufferVisuals; i++)
{
/*
@ -338,26 +157,25 @@ xglInitOffscreen (ScreenPtr pScreen,
* supports accelerated pbuffers but offscreen drawing is really
* slow, try decrementing these values.
*/
attributes.width = 2048;
attributes.height = 2048;
mask = GLITZ_PBUFFER_WIDTH_MASK | GLITZ_PBUFFER_HEIGHT_MASK;
width = 2048;
height = 2048;
pbuffer =
glitz_create_pbuffer_drawable (pScreenPriv->drawable,
xglPbufferVisuals[i].format,
&attributes, mask);
do {
pbuffer =
glitz_create_pbuffer_drawable (pScreenPriv->drawable,
xglPbufferVisuals[i].format,
width, height);
width >>= 1;
height >>= 1;
} while (!pbuffer && width);
if (pbuffer)
{
unsigned long width, height;
int j;
int j = 0;
width = glitz_drawable_get_width (pbuffer);
height = glitz_drawable_get_height (pbuffer);
j = 0;
/*
* No back buffer? only add front buffer.
*/
@ -366,23 +184,23 @@ xglInitOffscreen (ScreenPtr pScreen,
while (j < 2)
{
pScreenPriv->pOffscreen =
xrealloc (pScreenPriv->pOffscreen,
sizeof (xglOffscreenRec) *
(pScreenPriv->nOffscreen + 1));
if (pScreenPriv->pOffscreen)
pOffscreen->drawable = pbuffer;
pOffscreen->format = xglPbufferVisuals[i].format;
pOffscreen->buffer = _buffers[j];
if (xglRootAreaInit (&pOffscreen->rootArea,
MAX_OFFSCREEN_LEVEL,
width, height, 0,
(xglAreaFuncsPtr)
&xglOffscreenAreaFuncs,
(pointer) pOffscreen))
{
pOffscreen =
&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
if (xglOffscreenInit (pOffscreen,
pbuffer, _buffers[j],
width, height))
{
pScreenPriv->nOffscreen++;
ErrorF ("Initialized %dx%d pbuffer offscreen "
"area\n", width, height);
}
glitz_drawable_reference (pbuffer);
pScreenPriv->nOffscreen++;
pOffscreen++;
ErrorF ("Initialized %dx%d pbuffer offscreen area\n",
width, height);
}
j++;
}
@ -390,18 +208,6 @@ xglInitOffscreen (ScreenPtr pScreen,
}
}
}
pOffscreen = pScreenPriv->pOffscreen;
nOffscreen = pScreenPriv->nOffscreen;
/*
* Update offscreen pointers in root offscreen areas
*/
while (nOffscreen--)
{
pOffscreen->pArea->pOffscreen = pOffscreen;
pOffscreen++;
}
return TRUE;
}
@ -409,13 +215,18 @@ xglInitOffscreen (ScreenPtr pScreen,
void
xglFiniOffscreen (ScreenPtr pScreen)
{
XGL_SCREEN_PRIV (pScreen);
while (pScreenPriv->nOffscreen--)
xglOffscreenFini (&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen]);
int n;
if (pScreenPriv->pOffscreen)
xfree (pScreenPriv->pOffscreen);
XGL_SCREEN_PRIV (pScreen);
n = pScreenPriv->nOffscreen;
while (n--)
{
xglRootAreaFini (&pScreenPriv->pOffscreen[n].rootArea);
glitz_drawable_destroy (pScreenPriv->pOffscreen[n].drawable);
}
pScreenPriv->nOffscreen = 0;
}
Bool
@ -439,34 +250,41 @@ xglFindOffscreenArea (ScreenPtr pScreen,
while (nOffscreen--)
{
int level;
if (pOffscreen->format->color.red_size >= pColor->red_size &&
pOffscreen->format->color.green_size >= pColor->green_size &&
pOffscreen->format->color.blue_size >= pColor->blue_size &&
pOffscreen->format->color.alpha_size >= pColor->alpha_size)
{
/* Find available area */
if (xglFindArea (pOffscreen->rootArea.pArea,
pPixmap->drawable.width,
pPixmap->drawable.height,
FALSE,
(pointer) pPixmap))
return TRUE;
level = 0;
while ((pOffscreen->width >> level) >= pPixmap->drawable.width &&
(pOffscreen->height >> level) >= pPixmap->drawable.height)
level++;
if (!level)
continue;
if (xglOffscreenFindArea (pOffscreen->pArea, pPixmap, level - 1))
/* Kicking out area with lower score */
if (xglFindArea (pOffscreen->rootArea.pArea,
pPixmap->drawable.width,
pPixmap->drawable.height,
TRUE,
(pointer) pPixmap))
return TRUE;
}
pOffscreen++;
}
return FALSE;
}
void
xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea)
xglLeaveOffscreenArea (PixmapPtr pPixmap)
{
pArea->pPixmapPriv = NULL;
pArea->state = xglOffscreenAreaAvailable;
XGL_PIXMAP_PRIV (pPixmap);
if (pPixmapPriv->pArea)
xglLeaveArea (pPixmapPriv->pArea);
pPixmapPriv->pArea = NULL;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -100,8 +100,11 @@ void
xglUseMsg (void)
{
ErrorF ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM] "
"Specify screen characteristics\n");
ErrorF ("-fullscreen Run fullscreen\n");
"specify screen characteristics\n");
ErrorF ("-fullscreen run fullscreen\n");
ErrorF ("-vertextype [short|float] set vertex data type\n");
ErrorF ("-vbostream "
"use vertex buffer objects for streaming of vertex data\n");
}
int
@ -121,12 +124,30 @@ xglProcessArgument (xglScreenInfoPtr pScreenInfo,
return 2;
}
if (!strcmp (argv[i], "-fullscreen"))
else if (!strcmp (argv[i], "-fullscreen"))
{
pScreenInfo->fullscreen = TRUE;
return 1;
}
else if (!strcmp (argv[i], "-vertextype"))
{
if ((i + 1) < argc)
{
if (!strcasecmp (argv[i + 1], "short"))
pScreenInfo->geometryDataType = GEOMETRY_DATA_TYPE_SHORT;
else if (!strcasecmp (argv[i + 1], "float"))
pScreenInfo->geometryDataType = GEOMETRY_DATA_TYPE_FLOAT;
}
else
return 1;
return 2;
}
else if (!strcmp (argv[i], "-vbostream"))
{
pScreenInfo->geometryUsage = GEOMETRY_USAGE_STREAM;
return 1;
}
return 0;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,10 +20,11 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "fb.h"
#ifdef RENDER
@ -33,7 +34,7 @@
#define XGL_PICTURE_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \
XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (pPicture->pDrawable)
xglAddCurrentSurfaceDamage (pPicture->pDrawable)
void
xglComposite (CARD8 op,
@ -49,7 +50,7 @@ xglComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
PictureScreenPtr pPictureScreen;
PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen);
@ -58,9 +59,13 @@ xglComposite (CARD8 op,
pSrc, pMask, pDst,
xSrc, ySrc,
xMask, yMask,
xDst, yDst,
width, height))
xDst + pDst->pDrawable->x, yDst + pDst->pDrawable->y,
width, height,
NULL, NULL))
{
xglAddCurrentBitDamage (pDst->pDrawable);
return;
}
pPictureScreen = GetPictureScreen (pScreen);
@ -73,46 +78,74 @@ xglComposite (CARD8 op,
FatalError (XGL_SW_FAILURE_STRING);
}
XGL_PICTURE_FALLBACK_PROLOGUE (pDst, Composite);
if (op == PictOpSrc)
{
XGL_DRAWABLE_PIXMAP (pDst->pDrawable);
if (!xglMapPixmapBits (pPixmap))
FatalError (XGL_SW_FAILURE_STRING);
} else
xglSyncDamageBoxBits (pDst->pDrawable);
XGL_PICTURE_SCREEN_UNWRAP (Composite);
(*pPictureScreen->Composite) (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height);
XGL_PICTURE_FALLBACK_EPILOGUE (pDst, Composite, xglComposite);
XGL_PICTURE_SCREEN_WRAP (Composite, xglComposite);
if (op == PictOpSrc)
{
RegionRec region;
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (pMask)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
}
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height))
return;
xglAddSurfaceDamage (pDst->pDrawable, &region);
REGION_UNINIT (pDst->pDrawable->pScreen, &region);
} else
xglAddCurrentSurfaceDamage (pDst->pDrawable);
}
void
xglGlyphs (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs)
{
miGlyphs (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
}
void
xglRasterizeTrapezoid (PicturePtr pDst,
xTrapezoid *trap,
int xOff,
int yOff)
xglAddTriangles (PicturePtr pDst,
INT16 xOff,
INT16 yOff,
int ntri,
xTriangle *tris)
{
PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen);
XGL_DRAWABLE_PIXMAP_PRIV (pDst->pDrawable);
pPictureScreen = GetPictureScreen (pScreen);
XGL_PICTURE_FALLBACK_PROLOGUE (pDst, RasterizeTrapezoid);
(*pPictureScreen->RasterizeTrapezoid) (pDst, trap, xOff, yOff);
XGL_PICTURE_FALLBACK_EPILOGUE (pDst, RasterizeTrapezoid,
xglRasterizeTrapezoid);
pPixmapPriv->damageBox.x1 = 0;
pPixmapPriv->damageBox.y1 = 0;
pPixmapPriv->damageBox.x2 = pDst->pDrawable->width;
pPixmapPriv->damageBox.y2 = pDst->pDrawable->height;
XGL_PICTURE_FALLBACK_PROLOGUE (pDst, AddTriangles);
(*pPictureScreen->AddTriangles) (pDst, xOff, yOff, ntri, tris);
XGL_PICTURE_FALLBACK_EPILOGUE (pDst, AddTriangles, xglAddTriangles);
}
void
xglChangePicture (PicturePtr pPicture,
Mask mask)
@ -207,16 +240,18 @@ xglUpdatePicture (PicturePtr pPicture)
case PictFilterNearest:
case PictFilterFast:
glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0);
pPixmapPriv->pictureMask &= ~xglPFFilterMask;
break;
case PictFilterGood:
case PictFilterBest:
case PictFilterBilinear:
glitz_surface_set_filter (surface, GLITZ_FILTER_BILINEAR, NULL, 0);
pPixmapPriv->pictureMask &= ~xglPFFilterMask;
break;
default:
pPixmapPriv->pictureMask |= xglPFFilterMask;
case PictFilterConvolution:
glitz_surface_set_filter (surface, GLITZ_FILTER_CONVOLUTION,
(glitz_fixed16_16_t *)
pPicture->filter_params,
pPicture->filter_nparams);
break;
}
}
@ -237,4 +272,185 @@ xglUpdatePicture (PicturePtr pPicture)
pPixmapPriv->pictureMask &= ~XGL_PICTURE_CHANGES (~0);
}
static int
xglVisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
{
DepthPtr pDepth;
int d, v;
for (d = 0; d < pScreen->numDepths; d++)
{
pDepth = &pScreen->allowedDepths[d];
for (v = 0; v < pDepth->numVids; v++)
if (pDepth->vids[v] == pVisual->vid)
return pDepth->depth;
}
return 0;
}
typedef struct _xglformatInit {
CARD32 format;
CARD8 depth;
} xglFormatInitRec, *xglFormatInitPtr;
static int
xglAddFormat (xglFormatInitPtr formats,
int nformat,
CARD32 format,
CARD8 depth)
{
int n;
for (n = 0; n < nformat; n++)
if (formats[n].format == format && formats[n].depth == depth)
return nformat;
formats[nformat].format = format;
formats[nformat].depth = depth;
return ++nformat;
}
#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n)) - 1))
Bool
xglPictureInit (ScreenPtr pScreen)
{
int f, nformats = 0;
PictFormatPtr pFormats;
xglFormatInitRec formats[64];
CARD32 format;
CARD8 depth;
VisualPtr pVisual;
int v;
int bpp;
int r, g, b;
int d;
DepthPtr pDepth;
/* formats required by protocol */
formats[nformats].format = PICT_a1;
formats[nformats].depth = 1;
nformats++;
formats[nformats].format = PICT_a4;
formats[nformats].depth = 4;
nformats++;
formats[nformats].format = PICT_a8;
formats[nformats].depth = 8;
nformats++;
formats[nformats].format = PICT_a8r8g8b8;
formats[nformats].depth = 32;
nformats++;
/* now look through the depths and visuals adding other formats */
for (v = 0; v < pScreen->numVisuals; v++)
{
pVisual = &pScreen->visuals[v];
depth = xglVisualDepth (pScreen, pVisual);
if (!depth)
continue;
bpp = BitsPerPixel (depth);
switch (pVisual->class) {
case DirectColor:
case TrueColor:
r = Ones (pVisual->redMask);
g = Ones (pVisual->greenMask);
b = Ones (pVisual->blueMask);
if (pVisual->offsetBlue == 0 &&
pVisual->offsetGreen == b &&
pVisual->offsetRed == b + g)
{
format = PICT_FORMAT (bpp, PICT_TYPE_ARGB, 0, r, g, b);
nformats = xglAddFormat (formats, nformats, format, depth);
}
break;
case StaticColor:
case PseudoColor:
case StaticGray:
case GrayScale:
break;
}
}
/* walk supported depths and add missing Direct formats */
for (d = 0; d < pScreen->numDepths; d++)
{
pDepth = &pScreen->allowedDepths[d];
bpp = BitsPerPixel (pDepth->depth);
format = 0;
switch (bpp) {
case 16:
if (pDepth->depth == 15)
nformats = xglAddFormat (formats, nformats,
PICT_x1r5g5b5, pDepth->depth);
if (pDepth->depth == 16)
nformats = xglAddFormat (formats, nformats,
PICT_r5g6b5, pDepth->depth);
break;
case 24:
if (pDepth->depth == 24)
nformats = xglAddFormat (formats, nformats,
PICT_r8g8b8, pDepth->depth);
break;
case 32:
if (pDepth->depth == 24)
nformats = xglAddFormat (formats, nformats,
PICT_x8r8g8b8, pDepth->depth);
break;
}
}
pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
if (!pFormats)
return 0;
memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
for (f = 0; f < nformats; f++)
{
pFormats[f].id = FakeClientID (0);
pFormats[f].depth = formats[f].depth;
format = formats[f].format;
pFormats[f].format = format;
pFormats[f].type = PictTypeDirect;
switch (PICT_FORMAT_TYPE (format)) {
case PICT_TYPE_ARGB:
pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format));
if (pFormats[f].direct.alphaMask)
pFormats[f].direct.alpha = (PICT_FORMAT_R (format) +
PICT_FORMAT_G (format) +
PICT_FORMAT_B (format));
pFormats[f].direct.redMask = Mask (PICT_FORMAT_R (format));
pFormats[f].direct.red = (PICT_FORMAT_G (format) +
PICT_FORMAT_B (format));
pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G (format));
pFormats[f].direct.green = PICT_FORMAT_B (format);
pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B (format));
pFormats[f].direct.blue = 0;
break;
case PICT_TYPE_A:
pFormats[f].direct.alpha = 0;
pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format));
break;
case PICT_TYPE_COLOR:
case PICT_TYPE_GRAY:
break;
}
}
if (!fbPictureInit (pScreen, pFormats, nformats))
return FALSE;
if (PictureAddFilter (pScreen,
FilterConvolution,
miFilterValidateParams) < 0)
return FALSE;
return TRUE;
}
#endif

View File

@ -1,149 +0,0 @@
/*
* 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 names 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@freedesktop.org>
*/
#include "xgl.h"
#include "fb.h"
Bool
xglSetPixels (DrawablePtr pDrawable,
char *src,
int stride,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox)
{
glitz_pixel_format_t format;
glitz_surface_t *surface;
FbBits *srcBits, *dstBits;
FbStride srcStride, dstStride;
BoxPtr pDstBox;
int nDstBox;
int dstXoff, dstYoff, dstBpp;
int x1, y1, x2, y2;
XGL_DRAWABLE_PIXMAP (pDrawable);
XGL_PIXMAP_PRIV (pPixmap);
if (!nBox)
return TRUE;
if (!xglSyncSurface (pDrawable))
return FALSE;
XGL_GET_DRAWABLE (pDrawable, surface, dstXoff, dstYoff);
if (!xglMapPixmapBits (pPixmap))
return FALSE;
dstBpp = pDrawable->bitsPerPixel;
srcBits = (FbBits *) src;
dstBits = (FbBits *) pPixmap->devPrivate.ptr;
srcStride = stride / sizeof (FbBits);
dstStride = pPixmapPriv->stride / sizeof (FbBits);
pDstBox = xalloc (nBox);
if (!pDstBox)
return FALSE;
nDstBox = 0;
while (nBox--)
{
x1 = x;
y1 = y;
x2 = x + width;
y2 = y + height;
if (x1 < pBox->x1)
x1 = pBox->x1;
if (y1 < pBox->y1)
y1 = pBox->y1;
if (x2 > pBox->x2)
x2 = pBox->x2;
if (y2 > pBox->y2)
y2 = pBox->y2;
if (x1 < x2 && y1 < y2)
{
fbBlt (srcBits + (y1 - y) * srcStride,
srcStride,
(x1 - x) * dstBpp,
dstBits + (y1 + dstYoff) * dstStride,
dstStride,
(x1 + dstXoff) * dstBpp,
(x2 - x1) * dstBpp,
y2 - y1,
GXcopy,
FB_ALLONES,
dstBpp,
FALSE,
FALSE);
pDstBox[nDstBox].x1 = x1;
pDstBox[nDstBox].y1 = y1;
pDstBox[nDstBox].x2 = x2;
pDstBox[nDstBox].y2 = y2;
nDstBox++;
}
pBox++;
}
xglUnmapPixmapBits (pPixmap);
format.masks = pPixmapPriv->pPixel->masks;
format.bytes_per_line = pPixmapPriv->stride;
format.scanline_order = XGL_INTERNAL_SCANLINE_ORDER;
pBox = pDstBox;
while (nDstBox--)
{
format.xoffset = pBox->x1 + dstXoff;
format.skip_lines = pBox->y1 + dstYoff;
glitz_set_pixels (surface,
pBox->x1 + dstXoff,
pBox->y1 + dstYoff,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
&format,
pPixmapPriv->buffer);
pBox++;
}
xfree (pDstBox);
return TRUE;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -32,7 +32,7 @@ xglPixmapDamageReport (DamagePtr pDamage,
void *closure)
{
PixmapPtr pPixmap = (PixmapPtr) closure;
BoxPtr pExt;
BoxPtr pExt;
XGL_PIXMAP_PRIV (pPixmap);
@ -104,10 +104,9 @@ xglPixmapSurfaceInit (PixmapPtr pPixmap,
pPixmapPriv->target = xglPixmapTargetOut;
/*
* Don't allow depth 8 pixmaps into offscreen drawables as
* no trapezoid acceleration is hooked up yet.
* Do not allow accelerated drawing to bitmaps.
*/
if (pPixmap->drawable.depth <= 8)
if (pPixmap->drawable.depth == 1)
pPixmapPriv->target = xglPixmapTargetNo;
/*
@ -165,10 +164,11 @@ xglCreatePixmap (ScreenPtr pScreen,
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;
@ -189,7 +189,7 @@ xglDestroyPixmap (PixmapPtr pPixmap)
return TRUE;
if (pPixmapPriv->pArea)
xglWithdrawOffscreenArea (pPixmapPriv->pArea);
xglWithdrawArea (pPixmapPriv->pArea);
if (pPixmap->devPrivate.ptr)
{
@ -197,6 +197,9 @@ xglDestroyPixmap (PixmapPtr pPixmap)
glitz_buffer_unmap (pPixmapPriv->buffer);
}
if (pPixmapPriv->pGeometry)
GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer);
@ -265,7 +268,6 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
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)))
@ -283,7 +285,7 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->drawable.height != oldHeight)
{
if (pPixmapPriv->pArea)
xglWithdrawOffscreenArea (pPixmapPriv->pArea);
xglWithdrawArea (pPixmapPriv->pArea);
if (pPixmapPriv->surface)
glitz_surface_destroy (pPixmapPriv->surface);
@ -304,6 +306,12 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->devPrivate.ptr = 0;
}
if (pPixmapPriv->pGeometry)
{
GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
pPixmapPriv->pGeometry = NULL;
}
if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer);
@ -374,6 +382,63 @@ xglPixmapToRegion (PixmapPtr pPixmap)
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))
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)
{
@ -390,7 +455,8 @@ xglCreatePixmapSurface (PixmapPtr pPixmap)
glitz_surface_create (pScreenPriv->drawable,
pPixmapPriv->format,
pPixmap->drawable.width,
pPixmap->drawable.height);
pPixmap->drawable.height,
0, NULL);
if (!pPixmapPriv->surface)
{
pPixmapPriv->format = NULL;
@ -415,8 +481,6 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
pPixmapPriv->stride = stride;
if (stride)
{
pPixmapPriv->bits = xalloc (height * stride);
@ -432,6 +496,9 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
return FALSE;
}
}
/* XXX: pPixmapPriv->stride = -stride */
pPixmapPriv->stride = stride;
return TRUE;
}
@ -454,15 +521,14 @@ xglMapPixmapBits (PixmapPtr pPixmap)
if (!bits)
return FALSE;
if (XGL_INTERNAL_SCANLINE_ORDER_UPSIDE_DOWN && pPixmapPriv->format)
pPixmap->devKind = pPixmapPriv->stride;
if (pPixmapPriv->stride < 0)
{
pPixmap->devKind = -pPixmapPriv->stride;
pPixmap->devPrivate.ptr =
bits + (pPixmap->drawable.height - 1) * pPixmapPriv->stride;
pPixmap->devPrivate.ptr = bits +
(pPixmap->drawable.height - 1) * -pPixmapPriv->stride;
}
else
{
pPixmap->devKind = pPixmapPriv->stride;
pPixmap->devPrivate.ptr = bits;
}
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -28,6 +28,12 @@
#include "mipointer.h"
#include "damage.h"
#include "fb.h"
#ifdef MITSHM
#include "shmint.h"
#endif
#ifdef RENDER
#include "glyphstr.h"
#endif
int xglScreenGeneration = -1;
int xglScreenPrivateIndex;
@ -35,12 +41,13 @@ int xglGCPrivateIndex;
int xglPixmapPrivateIndex;
int xglWinPrivateIndex;
#ifdef RENDER
int xglGlyphPrivateIndex;
#endif
#define xglQueryBestSize (void *) NoopDDA
#define xglSaveScreen (void *) NoopDDA
#define xglRealizeFont (void *) NoopDDA
#define xglUnrealizeFont (void *) NoopDDA
#define xglConstrainCursor (void *) NoopDDA
#define xglCursorLimits (void *) NoopDDA
#define xglDisplayCursor (void *) NoopDDA
@ -49,14 +56,6 @@ int xglWinPrivateIndex;
#define xglRecolorCursor (void *) NoopDDA
#define xglSetCursorPosition (void *) NoopDDA
#define xglCreateColormap (void *) NoopDDA
#define xglDestroyColormap (void *) NoopDDA
#define xglInstallColormap (void *) NoopDDA
#define xglUninstallColormap (void *) NoopDDA
#define xglListInstalledColormaps (void *) NoopDDA
#define xglStoreColors (void *) NoopDDA
#define xglResolveColor (void *) NoopDDA
static PixmapPtr
xglGetWindowPixmap (WindowPtr pWin)
{
@ -100,7 +99,13 @@ xglAllocatePrivates (ScreenPtr pScreen)
xglWinPrivateIndex = AllocateWindowPrivateIndex ();
if (xglWinPrivateIndex < 0)
return FALSE;
#ifdef RENDER
xglGlyphPrivateIndex = AllocateGlyphPrivateIndex ();
if (xglGlyphPrivateIndex < 0)
return FALSE;
#endif
xglScreenGeneration = serverGeneration;
}
@ -114,7 +119,7 @@ xglAllocatePrivates (ScreenPtr pScreen)
if (!AllocateWindowPrivate (pScreen, xglWinPrivateIndex,
sizeof (xglWinRec)))
return FALSE;
pScreenPriv = xalloc (sizeof (xglScreenRec));
if (!pScreenPriv)
return FALSE;
@ -128,7 +133,7 @@ Bool
xglScreenInit (ScreenPtr pScreen,
xglScreenInfoPtr pScreenInfo)
{
xglScreenPtr pScreenPriv;
xglScreenPtr pScreenPriv;
#ifdef RENDER
PictureScreenPtr pPictureScreen;
@ -152,11 +157,19 @@ xglScreenInit (ScreenPtr pScreen,
xglInitPixmapFormats (pScreen);
if (!pScreenPriv->pixmapFormats[32].format)
return FALSE;
pScreenPriv->geometryDataType = pScreenInfo->geometryDataType;
pScreenPriv->geometryUsage = pScreenInfo->geometryUsage;
GEOMETRY_INIT (pScreen, &pScreenPriv->scratchGeometry,
GLITZ_GEOMETRY_TYPE_VERTEX,
pScreenPriv->geometryUsage, 0);
pScreenPriv->surface =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[32].format,
pScreenInfo->width, pScreenInfo->height);
pScreenInfo->width, pScreenInfo->height,
0, NULL);
if (!pScreenPriv->surface)
return FALSE;
@ -167,7 +180,7 @@ xglScreenInit (ScreenPtr pScreen,
if (monitorResolution == 0)
monitorResolution = XGL_DEFAULT_DPI;
if (!fbSetupScreen (pScreen, NULL,
pScreenInfo->width, pScreenInfo->height,
monitorResolution, monitorResolution,
@ -187,8 +200,12 @@ xglScreenInit (ScreenPtr pScreen,
pScreenPriv->pVisual->pPixel->masks.bpp))
return FALSE;
#ifdef MITSHM
ShmRegisterFuncs (pScreen, NULL);
#endif
#ifdef RENDER
if (!fbPictureInit (pScreen, 0, 0))
if (!xglPictureInit (pScreen))
return FALSE;
#endif
@ -197,14 +214,10 @@ xglScreenInit (ScreenPtr pScreen,
XGL_SCREEN_WRAP (CopyWindow, xglCopyWindow);
XGL_SCREEN_WRAP (CreateWindow, xglCreateWindow);
XGL_SCREEN_WRAP (ChangeWindowAttributes, xglChangeWindowAttributes);
XGL_SCREEN_WRAP (PaintWindowBackground, xglPaintWindowBackground);
XGL_SCREEN_WRAP (PaintWindowBorder, xglPaintWindowBorder);
/*
pScreen->RealizeFont = xglRealizeFont;
pScreen->UnrealizeFont = xglUnrealizeFont;
*/
XGL_SCREEN_WRAP (CreateGC, xglCreateGC);
pScreen->ConstrainCursor = xglConstrainCursor;
@ -215,16 +228,6 @@ xglScreenInit (ScreenPtr pScreen,
pScreen->RecolorCursor = xglRecolorCursor;
pScreen->SetCursorPosition = xglSetCursorPosition;
/*
pScreen->CreateColormap = miInitializeColormap;
pScreen->DestroyColormap = xglDestroyColormap;
pScreen->InstallColormap = miInstallColormap;
pScreen->UninstallColormap = miUninstallColormap;
pScreen->ListInstalledColormaps = miListInstalledColormaps;
pScreen->StoreColors = xglStoreColors;
pScreen->ResolveColor = miResolveColor;
*/
pScreen->ModifyPixmapHeader = xglModifyPixmapHeader;
XGL_SCREEN_WRAP (BitmapToRegion, xglPixmapToRegion);
@ -235,10 +238,19 @@ xglScreenInit (ScreenPtr pScreen,
#ifdef RENDER
pPictureScreen = GetPictureScreenIfSet (pScreen);
if (pPictureScreen) {
if (pPictureScreen)
{
if (!AllocateGlyphPrivate (pScreen, xglGlyphPrivateIndex,
sizeof (xglGlyphRec)))
return FALSE;
XGL_PICTURE_SCREEN_WRAP (RealizeGlyph, xglRealizeGlyph);
XGL_PICTURE_SCREEN_WRAP (UnrealizeGlyph, xglUnrealizeGlyph);
XGL_PICTURE_SCREEN_WRAP (Composite, xglComposite);
XGL_PICTURE_SCREEN_WRAP (Glyphs, xglGlyphs);
XGL_PICTURE_SCREEN_WRAP (RasterizeTrapezoid, xglRasterizeTrapezoid);
XGL_PICTURE_SCREEN_WRAP (Trapezoids, xglTrapezoids);
XGL_PICTURE_SCREEN_WRAP (AddTraps, xglAddTraps);
XGL_PICTURE_SCREEN_WRAP (AddTriangles, xglAddTriangles);
XGL_PICTURE_SCREEN_WRAP (ChangePicture, xglChangePicture);
XGL_PICTURE_SCREEN_WRAP (ChangePictureTransform,
xglChangePictureTransform);
@ -260,6 +272,14 @@ xglScreenInit (ScreenPtr pScreen,
Bool
xglFinishScreenInit (ScreenPtr pScreen)
{
#ifdef RENDER
glitz_vertex_format_t *format;
static glitz_color_t clearBlack = { 0x0, 0x0, 0x0, 0x0 };
static glitz_color_t solidWhite = { 0xffff, 0xffff, 0xffff, 0xffff };
int i;
#endif
XGL_SCREEN_PRIV (pScreen);
miInitializeBackingStore (pScreen);
@ -270,11 +290,54 @@ xglFinishScreenInit (ScreenPtr pScreen)
pScreenPriv->solid =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[32].format,
1, 1);
1, 1, 0, NULL);
if (!pScreenPriv->solid)
return FALSE;
glitz_surface_set_fill (pScreenPriv->solid, GLITZ_FILL_REPEAT);
#ifdef RENDER
for (i = 0; i < 33; i++)
pScreenPriv->glyphCache[i].pScreen = NULL;
pScreenPriv->pSolidAlpha = NULL;
pScreenPriv->trapInfo.mask =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[8].format,
2, 1, 0, NULL);
if (!pScreenPriv->trapInfo.mask)
return FALSE;
glitz_set_rectangle (pScreenPriv->trapInfo.mask, &clearBlack, 0, 0, 1, 1);
glitz_set_rectangle (pScreenPriv->trapInfo.mask, &solidWhite, 1, 0, 1, 1);
glitz_surface_set_fill (pScreenPriv->trapInfo.mask, GLITZ_FILL_NEAREST);
glitz_surface_set_filter (pScreenPriv->trapInfo.mask,
GLITZ_FILTER_BILINEAR,
NULL, 0);
format = &pScreenPriv->trapInfo.format.vertex;
format->primitive = GLITZ_PRIMITIVE_QUADS;
format->attributes = GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK;
format->mask.type = GLITZ_DATA_TYPE_FLOAT;
format->mask.size = GLITZ_COORDINATE_SIZE_X;
format->bytes_per_vertex = sizeof (glitz_float_t);
if (pScreenPriv->geometryDataType)
{
format->type = GLITZ_DATA_TYPE_FLOAT;
format->bytes_per_vertex += 2 * sizeof (glitz_float_t);
format->mask.offset = 2 * sizeof (glitz_float_t);
}
else
{
format->type = GLITZ_DATA_TYPE_SHORT;
format->bytes_per_vertex += 2 * sizeof (glitz_short_t);
format->mask.offset = 2 * sizeof (glitz_short_t);
}
#endif
return TRUE;
}
@ -285,6 +348,19 @@ xglCloseScreen (int index,
{
XGL_SCREEN_PRIV (pScreen);
#ifdef RENDER
int i;
for (i = 0; i < 33; i++)
xglFiniGlyphCache (&pScreenPriv->glyphCache[i]);
if (pScreenPriv->pSolidAlpha)
FreePicture ((pointer) pScreenPriv->pSolidAlpha, 0);
if (pScreenPriv->trapInfo.mask)
glitz_surface_destroy (pScreenPriv->trapInfo.mask);
#endif
if (pScreenPriv->solid)
glitz_surface_destroy (pScreenPriv->solid);
@ -292,9 +368,59 @@ xglCloseScreen (int index,
glitz_surface_destroy (pScreenPriv->surface);
xglFiniOffscreen (pScreen);
GEOMETRY_UNINIT (&pScreenPriv->scratchGeometry);
XGL_SCREEN_UNWRAP (CloseScreen);
xfree (pScreenPriv);
return (*pScreen->CloseScreen) (index, pScreen);
}
#ifdef RENDER
void
xglCreateSolidAlphaPicture (ScreenPtr pScreen)
{
static xRenderColor solidWhite = { 0xffff, 0xffff, 0xffff, 0xffff };
static xRectangle one = { 0, 0, 1, 1 };
PixmapPtr pPixmap;
PictFormatPtr pFormat;
int error;
Pixel pixel;
GCPtr pGC;
CARD32 tmpval[2];
XGL_SCREEN_PRIV (pScreen);
pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
if (!pFormat)
return;
pGC = GetScratchGC (pFormat->depth, pScreen);
if (!pGC)
return;
pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, pFormat->depth);
if (!pPixmap)
return;
miRenderColorToPixel (pFormat, &solidWhite, &pixel);
tmpval[0] = GXcopy;
tmpval[1] = pixel;
ChangeGC (pGC, GCFunction | GCForeground, tmpval);
ValidateGC (&pPixmap->drawable, pGC);
(*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
FreeScratchGC (pGC);
tmpval[0] = xTrue;
pScreenPriv->pSolidAlpha =
CreatePicture (0, &pPixmap->drawable, pFormat,
CPRepeat, tmpval, 0, &error);
(*pScreen->DestroyPixmap) (pPixmap);
if (pScreenPriv->pSolidAlpha)
ValidatePicture (pScreenPriv->pSolidAlpha);
}
#endif

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,16 +20,23 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "gcstruct.h"
#include "fontstruct.h"
#include "dixfontstr.h"
Bool
xglSolid (DrawablePtr pDrawable,
glitz_operator_t op,
glitz_color_t *color,
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox)
{
@ -38,6 +45,9 @@ xglSolid (DrawablePtr pDrawable,
XGL_SCREEN_PRIV (pDrawable->pScreen);
if (nBox < 1)
return TRUE;
if (!xglPrepareTarget (pDrawable))
return FALSE;
@ -45,26 +55,108 @@ xglSolid (DrawablePtr pDrawable,
glitz_set_rectangle (pScreenPriv->solid, color, 0, 0, 1, 1);
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE_ALL_VERTICES (pGeometry, surface))
return FALSE;
while (nBox--)
if (pGeometry)
{
glitz_composite (op,
pScreenPriv->solid, NULL, surface,
0, 0,
0, 0,
pBox->x1 + xOff,
pBox->y1 + yOff,
pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
pBox++;
glitz_surface_set_clip_region (surface, xOff, yOff,
(glitz_box_t *) pBox, nBox);
}
else
{
pGeometry = xglGetScratchVertexGeometry (pDrawable->pScreen, 4 * nBox);
GEOMETRY_ADD_BOX (pDrawable->pScreen, pGeometry, pBox, nBox);
}
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE (pGeometry, surface))
return FALSE;
glitz_composite (op,
pScreenPriv->solid, NULL, surface,
0, 0,
0, 0,
x + xOff,
y + yOff,
width, height);
glitz_surface_set_clip_region (surface, 0, 0, NULL, 0);
if (glitz_surface_get_status (surface))
return FALSE;
return TRUE;
}
Bool
xglSolidGlyph (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nGlyph,
CharInfoPtr *ppci,
pointer pglyphBase)
{
xglGeometryRec geometry;
int xBack, widthBack;
int yBack, heightBack;
XGL_GC_PRIV (pGC);
x += pDrawable->x;
y += pDrawable->y;
GEOMETRY_INIT (pDrawable->pScreen, &geometry,
GLITZ_GEOMETRY_TYPE_BITMAP,
GEOMETRY_USAGE_SYSMEM, 0);
GEOMETRY_FOR_GLYPH (pDrawable->pScreen,
&geometry,
nGlyph,
ppci,
pglyphBase);
GEOMETRY_TRANSLATE (&geometry, x, y);
widthBack = 0;
while (nGlyph--)
widthBack += (*ppci++)->metrics.characterWidth;
xBack = x;
if (widthBack < 0)
{
xBack += widthBack;
widthBack = -widthBack;
}
yBack = y - FONTASCENT (pGC->font);
heightBack = FONTASCENT (pGC->font) + FONTDESCENT (pGC->font);
if (xglSolid (pDrawable,
pGCPriv->op,
&pGCPriv->bg,
NULL,
xBack,
yBack,
widthBack,
heightBack,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
{
if (xglSolid (pDrawable,
pGCPriv->op,
&pGCPriv->fg,
&geometry,
xBack,
yBack,
widthBack,
heightBack,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
{
GEOMETRY_UNINIT (&geometry);
return TRUE;
}
}
GEOMETRY_UNINIT (&geometry);
return FALSE;
}

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@ -152,39 +152,56 @@ xglSyncBits (DrawablePtr pDrawable,
if (!pPixmapPriv->buffer)
if (!xglAllocatePixmapBits (pPixmap))
return FALSE;
if (REGION_NOTEMPTY (pDrawable->pScreen, &region))
if (pPixmapPriv->pDamage)
{
if (pPixmapPriv->surface)
{
glitz_pixel_format_t format;
BoxPtr pBox;
int nBox;
RegionPtr pRegion;
xglUnmapPixmapBits (pPixmap);
pRegion = DamageRegion (pPixmapPriv->pDamage);
REGION_SUBTRACT (pDrawable->pScreen, &region, &region, pRegion);
}
if (REGION_NOTEMPTY (pDrawable->pScreen, &region) && pPixmapPriv->surface)
{
glitz_pixel_format_t format;
BoxPtr pBox;
int nBox;
if (!xglSyncSurface (pDrawable))
FatalError (XGL_SW_FAILURE_STRING);
xglUnmapPixmapBits (pPixmap);
pBox = REGION_RECTS (&region);
nBox = REGION_NUM_RECTS (&region);
pBox = REGION_RECTS (&region);
nBox = REGION_NUM_RECTS (&region);
format.masks = pPixmapPriv->pPixel->masks;
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 = XGL_INTERNAL_SCANLINE_ORDER;
while (nBox--)
{
format.xoffset = pBox->x1;
format.skip_lines = pBox->y1;
glitz_get_pixels (pPixmapPriv->surface,
pBox->x1,
pBox->y1,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
&format,
pPixmapPriv->buffer);
pBox++;
}
format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
}
while (nBox--)
{
format.xoffset = pBox->x1;
format.skip_lines = pBox->y1;
glitz_get_pixels (pPixmapPriv->surface,
pBox->x1,
pBox->y1,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
&format,
pPixmapPriv->buffer);
pBox++;
}
}
@ -234,16 +251,25 @@ xglSyncSurface (DrawablePtr pDrawable)
nBox = REGION_NUM_RECTS (pRegion);
pBox = REGION_RECTS (pRegion);
format.masks = pPixmapPriv->pPixel->masks;
format.masks = pPixmapPriv->pPixel->masks;
format.bytes_per_line = pPixmapPriv->stride;
format.scanline_order = XGL_INTERNAL_SCANLINE_ORDER;
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;
glitz_set_pixels (pPixmapPriv->surface,
pBox->x1,
pBox->y1,
@ -288,7 +314,34 @@ xglPrepareTarget (DrawablePtr pDrawable)
}
void
xglAddSurfaceDamage (DrawablePtr pDrawable)
xglAddSurfaceDamage (DrawablePtr pDrawable,
RegionPtr pRegion)
{
RegionPtr pDamageRegion;
glitz_surface_t *surface;
int xOff, yOff;
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
pPixmapPriv->damageBox = miEmptyBox;
if (!pPixmapPriv->format)
return;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
if (xOff || yOff)
REGION_TRANSLATE (pDrawable->pScreen, pRegion, xOff, yOff);
pDamageRegion = DamageRegion (pPixmapPriv->pDamage);
REGION_UNION (pDrawable->pScreen, pDamageRegion, pDamageRegion, pRegion);
if (xOff || yOff)
REGION_TRANSLATE (pDrawable->pScreen, pRegion, -xOff, -yOff);
}
void
xglAddCurrentSurfaceDamage (DrawablePtr pDrawable)
{
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
@ -310,18 +363,12 @@ xglAddSurfaceDamage (DrawablePtr pDrawable)
pDamageRegion, pDamageRegion, &region);
REGION_UNINIT (pDrawable->pScreen, &region);
if (pPixmapPriv->target == xglPixmapTargetIn)
{
if (!xglSyncSurface (pDrawable))
FatalError (XGL_SW_FAILURE_STRING);
}
pPixmapPriv->damageBox = miEmptyBox;
}
}
void
xglAddBitDamage (DrawablePtr pDrawable)
xglAddCurrentBitDamage (DrawablePtr pDrawable)
{
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,11 +20,146 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
static glitz_geometry_format_t tileGeometryFormat = {
{
GLITZ_PRIMITIVE_QUADS,
GLITZ_DATA_TYPE_FLOAT,
sizeof (glitz_float_t) * 4,
GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK, {
GLITZ_DATA_TYPE_FLOAT,
GLITZ_COORDINATE_SIZE_XY,
sizeof (glitz_float_t) * 2,
}, {
0, 0, 0
}
}
};
xglGeometryPtr
xglTiledBoxGeometry (PixmapPtr pTile,
int tileX,
int tileY,
BoxPtr pBox,
int nBox)
{
ScreenPtr pScreen = pTile->drawable.pScreen;
glitz_point_fixed_t p1, p2;
xglGeometryPtr pGeometry;
glitz_float_t x1, x2, y1, y2;
int x, y, width, height, i;
int xTile, yTile;
int widthTile, heightTile;
int widthTmp, xTmp, yTmp, xTileTmp;
int tileWidth, tileHeight;
int size = 0;
glitz_float_t *data;
XGL_PIXMAP_PRIV (pTile);
tileWidth = pTile->drawable.width;
tileHeight = pTile->drawable.height;
for (i = 0; i < nBox; i++)
size +=
(((pBox[i].x2 - pBox[i].x1) / tileWidth) + 2) *
(((pBox[i].y2 - pBox[i].y1) / tileHeight) + 2);
pGeometry = xglGetScratchVertexGeometryWithType (pScreen,
GEOMETRY_DATA_TYPE_FLOAT,
8 * size);
data = glitz_buffer_map (pGeometry->buffer,
GLITZ_BUFFER_ACCESS_WRITE_ONLY);
while (nBox--)
{
x = pBox->x1;
y = pBox->y1;
width = pBox->x2 - pBox->x1;
height = pBox->y2 - pBox->y1;
xTile = MOD (tileX + x, tileWidth);
yTile = MOD (tileY + y, tileHeight);
yTmp = y;
while (height)
{
heightTile = MIN (tileHeight - yTile, height);
xTileTmp = xTile;
widthTmp = width;
xTmp = x;
while (widthTmp)
{
widthTile = MIN (tileWidth - xTileTmp, widthTmp);
p1.x = xTileTmp << 16;
p1.y = yTile << 16;
p2.x = (xTileTmp + widthTile) << 16;
p2.y = (yTile + heightTile) << 16;
glitz_surface_translate_point (pPixmapPriv->surface, &p1, &p1);
glitz_surface_translate_point (pPixmapPriv->surface, &p2, &p2);
x1 = FIXED_TO_FLOAT (p1.x);
y1 = FIXED_TO_FLOAT (p1.y);
x2 = FIXED_TO_FLOAT (p2.x);
y2 = FIXED_TO_FLOAT (p2.y);
*data++ = (glitz_float_t) xTmp;
*data++ = (glitz_float_t) yTmp;
*data++ = x1;
*data++ = y1;
*data++ = (glitz_float_t) (xTmp + widthTile);
*data++ = (glitz_float_t) yTmp;
*data++ = x2;
*data++ = y1;
*data++ = (glitz_float_t) (xTmp + widthTile);
*data++ = (glitz_float_t) (yTmp + heightTile);
*data++ = x2;
*data++ = y2;
*data++ = (glitz_float_t) xTmp;
*data++ = (glitz_float_t) (yTmp + heightTile);
*data++ = x1;
*data++ = y2;
pGeometry->endOffset += sizeof (glitz_float_t) * 16;
xTileTmp = 0;
xTmp += widthTile;
widthTmp -= widthTile;
}
yTile = 0;
yTmp += heightTile;
height -= heightTile;
}
pBox++;
}
if (glitz_buffer_unmap (pGeometry->buffer))
return NULL;
pGeometry->f = tileGeometryFormat;
pGeometry->count =
pGeometry->endOffset / tileGeometryFormat.vertex.bytes_per_vertex;
pPixmapPriv->pictureMask |= xglPCFillMask;
glitz_surface_set_fill (pPixmapPriv->surface, GLITZ_FILL_TRANSPARENT);
return pGeometry;
}
Bool
xglTile (DrawablePtr pDrawable,
@ -33,6 +168,10 @@ xglTile (DrawablePtr pDrawable,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox)
{
@ -40,161 +179,90 @@ xglTile (DrawablePtr pDrawable,
glitz_surface_t *surface;
int xOff, yOff;
if (!xglSyncSurface (&pTile->drawable))
return FALSE;
if (nBox < 1)
return TRUE;
if (!xglPrepareTarget (pDrawable))
return FALSE;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE_ALL_VERTICES (pGeometry, surface))
if (!xglSyncSurface (&pTile->drawable))
return FALSE;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
pTilePriv = XGL_GET_PIXMAP_PRIV (pTile);
pTilePriv->pictureMask |=
xglPCFillMask | xglPCFilterMask | xglPCTransformMask;
glitz_surface_set_filter (pTilePriv->surface, GLITZ_FILTER_NEAREST,
pTilePriv->pictureMask |= xglPCFilterMask | xglPCTransformMask;
glitz_surface_set_filter (pTilePriv->surface,
GLITZ_FILTER_NEAREST,
NULL, 0);
glitz_surface_set_transform (pTilePriv->surface, NULL);
if (pTilePriv->acceleratedTile)
{
glitz_surface_set_fill (pTilePriv->surface, GLITZ_FILL_REPEAT);
while (nBox--)
if (pGeometry)
{
glitz_composite (op,
pTilePriv->surface, NULL, surface,
pBox->x1 + tileX,
pBox->y1 + tileY,
0, 0,
pBox->x1 + xOff,
pBox->y1 + yOff,
pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
pBox++;
glitz_surface_set_clip_region (surface, xOff, yOff,
(glitz_box_t *) pBox, nBox);
nBox = 0;
}
else
{
pGeometry = xglGetScratchVertexGeometry (pDrawable->pScreen,
4 * nBox);
GEOMETRY_ADD_BOX (pDrawable->pScreen, pGeometry, pBox, nBox);
}
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE (pGeometry, surface))
return FALSE;
pTilePriv->pictureMask |= xglPCFillMask;
glitz_surface_set_fill (pTilePriv->surface, GLITZ_FILL_REPEAT);
glitz_composite (op,
pTilePriv->surface, NULL, surface,
x + tileX,
y + tileY,
0, 0,
x + xOff,
y + yOff,
width, height);
glitz_surface_set_clip_region (surface, 0, 0, NULL, 0);
if (!glitz_surface_get_status (surface))
return TRUE;
}
glitz_surface_set_fill (pTilePriv->surface, GLITZ_FILL_TRANSPARENT);
/*
* Don't allow software tile with really small pixmaps.
*/
if (pTile->drawable.width < 8 && pTile->drawable.height < 8)
if (!nBox)
return FALSE;
}
else
{
if (pGeometry)
return FALSE;
}
pGeometry = xglTiledBoxGeometry (pTile, tileX, tileY, pBox, nBox);
if (!pGeometry)
return FALSE;
xglSwTile (op,
pTilePriv->surface, NULL, surface,
tileX - xOff, tileY - yOff,
0, 0,
TILE_SOURCE,
pBox, nBox,
xOff, yOff);
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE (pGeometry, surface))
return FALSE;
glitz_composite (op,
pTilePriv->surface, NULL, surface,
0, 0,
0, 0,
x + xOff,
y + yOff,
width, height);
if (glitz_surface_get_status (surface))
return FALSE;
return TRUE;
}
void
xglSwTile (glitz_operator_t op,
glitz_surface_t *srcSurface,
glitz_surface_t *maskSurface,
glitz_surface_t *dstSurface,
int xSrc,
int ySrc,
int xMask,
int yMask,
int what,
BoxPtr pBox,
int nBox,
int xOff,
int yOff)
{
int tileX, tileY;
int tileWidth, tileHeight;
if (what == TILE_MASK) {
tileX = xMask;
tileY = yMask;
tileWidth = glitz_surface_get_width (maskSurface);
tileHeight = glitz_surface_get_height (maskSurface);
} else {
tileX = xSrc;
tileY = ySrc;
tileWidth = glitz_surface_get_width (srcSurface);
tileHeight = glitz_surface_get_height (srcSurface);
}
while (nBox--)
{
int x, y, width, height;
int xTile, yTile;
int widthTile, heightTile;
int widthTmp, xTmp, yTmp, xTileTmp;
x = pBox->x1 + xOff;
y = pBox->y1 + yOff;
width = pBox->x2 - pBox->x1;
height = pBox->y2 - pBox->y1;
xTile = MOD (tileX + x, tileWidth);
yTile = MOD (tileY + y, tileHeight);
yTmp = y;
while (height)
{
heightTile = MIN (tileHeight - yTile, height);
xTileTmp = xTile;
widthTmp = width;
xTmp = x;
while (widthTmp)
{
widthTile = MIN (tileWidth - xTileTmp, widthTmp);
if (what == TILE_MASK)
{
glitz_composite (op,
srcSurface, maskSurface, dstSurface,
xSrc + xTmp, ySrc + yTmp,
xTileTmp, yTile,
xTmp, yTmp,
widthTile, heightTile);
}
else
{
glitz_composite (op,
srcSurface, maskSurface, dstSurface,
xTileTmp, yTile,
xMask + xTmp, yMask + yTmp,
xTmp, yTmp,
widthTile, heightTile);
}
xTileTmp = 0;
xTmp += widthTile;
widthTmp -= widthTile;
}
yTile = 0;
yTmp += heightTile;
height -= heightTile;
}
pBox++;
}
}

520
hw/xgl/xgltrap.c Normal file
View File

@ -0,0 +1,520 @@
/*
* Copyright © 2005 Novell, Inc.
*
* 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
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. 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 "gcstruct.h"
#include "damage.h"
#ifdef RENDER
#define XGL_TRAP_FALLBACK_PROLOGUE(pPicture, func) \
xglSyncDamageBoxBits (pPicture->pDrawable); \
XGL_PICTURE_SCREEN_UNWRAP (func)
#define XGL_TRAP_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \
XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \
xglAddCurrentSurfaceDamage (pPicture->pDrawable)
/* just a guess */
#define SMOOTH_TRAPS_ESTIMATE_RECTS(nTrap) (30 * nTrap)
static PicturePtr
xglCreateMaskPicture (ScreenPtr pScreen,
PicturePtr pDst,
PictFormatPtr pPictFormat,
CARD16 width,
CARD16 height,
Bool accelerate)
{
PixmapPtr pPixmap;
PicturePtr pPicture;
GCPtr pGC;
int error;
xRectangle rect;
if (width > 32767 || height > 32767)
return 0;
pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height,
pPictFormat->depth);
if (!pPixmap)
return 0;
if (!accelerate)
{
XGL_PIXMAP_PRIV (pPixmap);
if (!xglAllocatePixmapBits (pPixmap))
{
(*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);
if (!pGC)
{
(*pScreen->DestroyPixmap) (pPixmap);
return 0;
}
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
ValidateGC (&pPixmap->drawable, pGC);
(*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &rect);
FreeScratchGC (pGC);
pPicture = CreatePicture (0, &pPixmap->drawable, pPictFormat,
0, 0, serverClient, &error);
(*pScreen->DestroyPixmap) (pPixmap);
return pPicture;
}
#define LINE_FIXED_X(l, _y, v) \
dx = (l)->p2.x - (l)->p1.x; \
ex = (xFixed_32_32) ((_y) - (l)->p1.y) * dx; \
dy = (l)->p2.y - (l)->p1.y; \
(v) = (l)->p1.x + (xFixed) (ex / dy)
#define LINE_FIXED_X_CEIL(l, _y, v) \
dx = (l)->p2.x - (l)->p1.x; \
ex = (xFixed_32_32) ((_y) - (l)->p1.y) * dx; \
dy = (l)->p2.y - (l)->p1.y; \
(v) = (l)->p1.x + (xFixed) ((ex + (dy - 1)) / dy)
static Bool
xglTrapezoidBounds (int ntrap,
xTrapezoid *traps,
BoxPtr box)
{
Bool x_overlap, overlap = FALSE;
xFixed dx, dy, top, bottom;
xFixed_32_32 ex;
if (!ntrap)
{
box->x1 = MAXSHORT;
box->x2 = MINSHORT;
box->y1 = MAXSHORT;
box->y2 = MINSHORT;
return FALSE;
}
box->y1 = xFixedToInt (traps->top);
box->y2 = xFixedToInt (xFixedCeil (traps->bottom));
LINE_FIXED_X (&traps->left, traps->top, top);
LINE_FIXED_X (&traps->left, traps->bottom, bottom);
box->x1 = xFixedToInt (MIN (top, bottom));
LINE_FIXED_X_CEIL (&traps->right, traps->top, top);
LINE_FIXED_X_CEIL (&traps->right, traps->bottom, bottom);
box->x2 = xFixedToInt (xFixedCeil (MAX (top, bottom)));
ntrap--;
traps++;
for (; ntrap; ntrap--, traps++)
{
INT16 x1, y1, x2, y2;
if (!xTrapezoidValid (traps))
continue;
y1 = xFixedToInt (traps->top);
y2 = xFixedToInt (xFixedCeil (traps->bottom));
LINE_FIXED_X (&traps->left, traps->top, top);
LINE_FIXED_X (&traps->left, traps->bottom, bottom);
x1 = xFixedToInt (MIN (top, bottom));
LINE_FIXED_X_CEIL (&traps->right, traps->top, top);
LINE_FIXED_X_CEIL (&traps->right, traps->bottom, bottom);
x2 = xFixedToInt (xFixedCeil (MAX (top, bottom)));
x_overlap = FALSE;
if (x1 >= box->x2)
box->x2 = x2;
else if (x2 <= box->x1)
box->x1 = x1;
else
{
x_overlap = TRUE;
if (x1 < box->x1)
box->x1 = x1;
if (x2 > box->x2)
box->x2 = x2;
}
if (y1 >= box->y2)
box->y2 = y2;
else if (y2 <= box->y1)
box->y1 = y1;
else
{
if (y1 < box->y1)
box->y1 = y1;
if (y2 > box->y2)
box->y2 = y2;
if (x_overlap)
overlap = TRUE;
}
}
return overlap;
}
void
xglTrapezoids (CARD8 op,
PicturePtr pSrc,
PicturePtr pDst,
PictFormatPtr maskFormat,
INT16 xSrc,
INT16 ySrc,
int nTrap,
xTrapezoid *traps)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
PicturePtr pMask = NULL, pSrcPicture, pDstPicture;
xglGeometryPtr pGeometry = NULL;
glitz_surface_t *mask = NULL;
unsigned int polyEdge = pDst->polyEdge;
INT16 xDst, yDst;
INT16 xOff, yOff;
BoxRec bounds;
Bool overlap;
XGL_SCREEN_PRIV (pScreen);
xDst = traps[0].left.p1.x >> 16;
yDst = traps[0].left.p1.y >> 16;
overlap = xglTrapezoidBounds (nTrap, traps, &bounds);
if (bounds.y1 >= bounds.y2 || bounds.x1 >= bounds.x2)
return;
if (nTrap > 1 && op != PictOpAdd && maskFormat &&
(overlap || op != PictOpOver))
{
xglPixmapPtr pPixmapPriv;
int width, height;
Bool accelerate;
if (!pScreenPriv->pSolidAlpha)
{
xglCreateSolidAlphaPicture (pScreen);
if (!pScreenPriv->pSolidAlpha)
return;
}
accelerate = TRUE;
width = bounds.x2 - bounds.x1;
height = bounds.y2 - bounds.y1;
if (maskFormat->depth > 1)
{
/* Avoid acceleration if the estimated amount of vertex data
is likely to exceed the size of the mask. */
if ((SMOOTH_TRAPS_ESTIMATE_RECTS (nTrap) * 4) > (width * height))
accelerate = FALSE;
accelerate = FALSE;
}
pMask = xglCreateMaskPicture (pScreen, pDst, maskFormat,
width, height, accelerate);
if (!pMask)
return;
ValidatePicture (pMask);
/* all will be damaged */
pPixmapPriv = XGL_GET_DRAWABLE_PIXMAP_PRIV (pMask->pDrawable);
pPixmapPriv->damageBox.x1 = 0;
pPixmapPriv->damageBox.y1 = 0;
pPixmapPriv->damageBox.x2 = pMask->pDrawable->width;
pPixmapPriv->damageBox.y2 = pMask->pDrawable->height;
xOff = -bounds.x1;
yOff = -bounds.y1;
pSrcPicture = pScreenPriv->pSolidAlpha;
pDstPicture = pMask;
}
else
{
if (maskFormat)
{
if (maskFormat->depth == 1)
polyEdge = PolyEdgeSharp;
else
polyEdge = PolyEdgeSmooth;
}
xOff = 0;
yOff = 0;
pSrcPicture = pSrc;
pDstPicture = pDst;
}
if (xglPrepareTarget (pDstPicture->pDrawable))
{
if (maskFormat || polyEdge == PolyEdgeSmooth)
{
glitz_vertex_format_t *format;
xTrapezoid *pTrap = traps;
int nAddedTrap, n = nTrap;
int offset = 0;
int size = SMOOTH_TRAPS_ESTIMATE_RECTS (n);
mask = pScreenPriv->trapInfo.mask;
format = &pScreenPriv->trapInfo.format.vertex;
size *= format->bytes_per_vertex;
pGeometry = xglGetScratchGeometryWithSize (pScreen, size);
while (n)
{
if (pGeometry->size < size)
GEOMETRY_RESIZE (pScreen, pGeometry, size);
if (!pGeometry->buffer)
{
if (pMask)
FreePicture (pMask, 0);
return;
}
offset +=
glitz_add_trapezoids (pGeometry->buffer,
offset, size - offset, format->type,
mask, (glitz_trapezoid_t *) pTrap, n,
&nAddedTrap);
n -= nAddedTrap;
pTrap += nAddedTrap;
size *= 2;
}
pGeometry->f = pScreenPriv->trapInfo.format;
pGeometry->count = offset / format->bytes_per_vertex;
}
else
{
pGeometry =
xglGetScratchVertexGeometryWithType (pScreen,
GEOMETRY_DATA_TYPE_FLOAT,
4 * nTrap);
if (!pGeometry->buffer)
{
if (pMask)
FreePicture (pMask, 0);
return;
}
GEOMETRY_ADD_TRAPEZOID (pScreen, pGeometry, traps, nTrap);
}
GEOMETRY_TRANSLATE (pGeometry,
pDstPicture->pDrawable->x + xOff,
pDstPicture->pDrawable->y + yOff);
}
if (pGeometry &&
xglComp (pMask ? PictOpAdd : op,
pSrcPicture,
NULL,
pDstPicture,
bounds.x1 + xOff + xSrc - xDst,
bounds.y1 + yOff + ySrc - yDst,
0, 0,
pDstPicture->pDrawable->x + bounds.x1 + xOff,
pDstPicture->pDrawable->y + bounds.y1 + yOff,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1,
pGeometry,
mask))
{
/* no intermediate mask? we need to register damage from here as
CompositePicture will never be called. */
if (!pMask)
{
RegionRec region;
REGION_INIT (pScreen, &region, &bounds, 1);
REGION_TRANSLATE (pScreen, &region,
pDst->pDrawable->x, pDst->pDrawable->y);
DamageDamageRegion (pDst->pDrawable, &region);
REGION_UNINIT (pScreen, &region);
}
xglAddCurrentBitDamage (pDstPicture->pDrawable);
}
else
{
XGL_DRAWABLE_PIXMAP_PRIV (pDstPicture->pDrawable);
pPixmapPriv->damageBox.x1 = bounds.x1 + xOff;
pPixmapPriv->damageBox.y1 = bounds.y1 + yOff;
pPixmapPriv->damageBox.x2 = bounds.x2 + xOff;
pPixmapPriv->damageBox.y2 = bounds.y2 + yOff;
xglSyncDamageBoxBits (pDstPicture->pDrawable);
if (pMask || (polyEdge == PolyEdgeSmooth &&
op == PictOpAdd && miIsSolidAlpha (pSrc)))
{
PictureScreenPtr ps = GetPictureScreen (pScreen);
for (; nTrap; nTrap--, traps++)
(*ps->RasterizeTrapezoid) (pDstPicture, traps, xOff, yOff);
xglAddCurrentSurfaceDamage (pDstPicture->pDrawable);
} else
miTrapezoids (op, pSrc, pDstPicture, NULL,
xSrc, ySrc, nTrap, traps);
}
if (pMask)
{
xglLeaveOffscreenArea ((PixmapPtr) pMask->pDrawable);
CompositePicture (op, pSrc, pMask, pDst,
bounds.x1 + xSrc - xDst,
bounds.y1 + ySrc - yDst,
0, 0,
bounds.x1, bounds.y1,
bounds.x2 - bounds.x1,
bounds.y2 - bounds.y1);
FreePicture (pMask, 0);
}
}
void
xglAddTraps (PicturePtr pDst,
INT16 xOff,
INT16 yOff,
int nTrap,
xTrap *traps)
{
PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen);
XGL_DRAWABLE_PIXMAP_PRIV (pDst->pDrawable);
if (!pScreenPriv->pSolidAlpha)
{
xglCreateSolidAlphaPicture (pScreen);
if (!pScreenPriv->pSolidAlpha)
return;
}
pPixmapPriv->damageBox.x1 = 0;
pPixmapPriv->damageBox.y1 = 0;
pPixmapPriv->damageBox.x2 = pDst->pDrawable->width;
pPixmapPriv->damageBox.y2 = pDst->pDrawable->height;
if (xglPrepareTarget (pDst->pDrawable))
{
glitz_vertex_format_t *format;
xglGeometryPtr pGeometry;
xTrap *pTrap = traps;
int nAddedTrap, n = nTrap;
int offset = 0;
int size = SMOOTH_TRAPS_ESTIMATE_RECTS (n);
format = &pScreenPriv->trapInfo.format.vertex;
size *= format->bytes_per_vertex;
pGeometry = xglGetScratchGeometryWithSize (pScreen, size);
while (n)
{
if (pGeometry->size < size)
GEOMETRY_RESIZE (pScreen, pGeometry, size);
if (!pGeometry->buffer)
return;
offset +=
glitz_add_traps (pGeometry->buffer,
offset, size - offset, format->type,
pScreenPriv->trapInfo.mask,
(glitz_trap_t *) pTrap, n,
&nAddedTrap);
n -= nAddedTrap;
pTrap += nAddedTrap;
size *= 2;
}
pGeometry->f = pScreenPriv->trapInfo.format;
pGeometry->count = offset / format->bytes_per_vertex;
GEOMETRY_TRANSLATE (pGeometry,
pDst->pDrawable->x + xOff,
pDst->pDrawable->y + yOff);
if (xglComp (PictOpAdd,
pScreenPriv->pSolidAlpha,
NULL,
pDst,
0, 0,
0, 0,
pDst->pDrawable->x, pDst->pDrawable->y,
pDst->pDrawable->width, pDst->pDrawable->height,
pGeometry,
pScreenPriv->trapInfo.mask))
{
xglAddCurrentBitDamage (pDst->pDrawable);
return;
}
}
pPictureScreen = GetPictureScreen (pScreen);
XGL_TRAP_FALLBACK_PROLOGUE (pDst, AddTraps);
(*pPictureScreen->AddTraps) (pDst, xOff, yOff, nTrap, traps);
XGL_TRAP_FALLBACK_EPILOGUE (pDst, AddTraps, xglAddTraps);
}
#endif

View File

@ -5,7 +5,7 @@
* 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 names of
* 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
@ -20,19 +20,20 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@freedesktop.org>
* Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "fb.h"
#define XGL_WINDOW_FALLBACK_PROLOGUE(pWin, func) \
xglSyncDamageBoxBits (&pWin->drawable); \
#define XGL_WINDOW_FALLBACK_PROLOGUE(pWin, func) \
if (!xglMapPixmapBits (XGL_GET_DRAWABLE_PIXMAP (&pWin->drawable))) \
FatalError (XGL_SW_FAILURE_STRING); \
XGL_SCREEN_UNWRAP (func)
#define XGL_WINDOW_FALLBACK_EPILOGUE(pWin, func, xglfunc) \
XGL_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (&pWin->drawable)
#define XGL_WINDOW_FALLBACK_EPILOGUE(pWin, pRegion, func, xglfunc) \
XGL_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (&pWin->drawable, pRegion)
Bool
xglCreateWindow (WindowPtr pWin)
@ -52,96 +53,119 @@ xglCreateWindow (WindowPtr pWin)
return ret;
}
Bool
xglChangeWindowAttributes (WindowPtr pWin,
unsigned long mask)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pPixmap;
Bool ret;
XGL_SCREEN_PRIV (pScreen);
if (mask & CWBackPixmap)
{
if (pWin->backgroundState == BackgroundPixmap)
{
pPixmap = pWin->background.pixmap;
if (FbEvenTile (pPixmap->drawable.width *
pPixmap->drawable.bitsPerPixel))
xglSyncBits (&pPixmap->drawable, NULL);
}
}
if (mask & CWBorderPixmap)
{
if (pWin->borderIsPixel == FALSE)
{
pPixmap = pWin->border.pixmap;
if (FbEvenTile (pPixmap->drawable.width *
pPixmap->drawable.bitsPerPixel))
xglSyncBits (&pPixmap->drawable, NULL);
}
}
XGL_SCREEN_UNWRAP (ChangeWindowAttributes);
ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
XGL_SCREEN_WRAP (ChangeWindowAttributes, xglChangeWindowAttributes);
return ret;
}
void
xglCopyWindow (WindowPtr pWin,
DDXPointRec ptOldOrg,
RegionPtr prgnSrc)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
PixmapPtr pPixmap;
RegionRec rgnDst;
int dx, dy;
BoxPtr pExtent = REGION_EXTENTS (pWin->drawable.pScreen, prgnSrc);
BoxRec box;
XGL_SCREEN_PRIV (pScreen);
pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (&pWin->drawable)->target)
{
PixmapPtr pPixmap;
RegionRec rgnDst;
int dx, dy;
Bool ret;
pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
box.x1 = pWin->drawable.x + pExtent->x1;
box.y1 = pWin->drawable.y + pExtent->y1;
box.x2 = pWin->drawable.x + pExtent->x2;
box.y2 = pWin->drawable.y + pExtent->y2;
dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y;
dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y;
REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
REGION_INIT (pScreen, &rgnDst, NullBox, 0);
REGION_INTERSECT (pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
REGION_TRANSLATE (pWin->drawable.pScreen, prgnSrc, -dx, -dy);
REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
REGION_INTERSECT (pWin->drawable.pScreen,
&rgnDst, &pWin->borderClip, prgnSrc);
#ifdef COMPOSITE
if (pPixmap->screen_x || pPixmap->screen_y)
REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
-pPixmap->screen_x, -pPixmap->screen_y);
#endif
if (pPixmap->screen_x || pPixmap->screen_y)
{
REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
-pPixmap->screen_x, -pPixmap->screen_y);
ret = TRUE;
fbCopyRegion (&pWin->drawable, &pWin->drawable,
0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &ret);
REGION_UNINIT (pScreen, &rgnDst);
if (ret)
{
xglAddBitDamage (&pWin->drawable);
return;
}
#ifdef COMPOSITE
if (pPixmap->screen_x || pPixmap->screen_y)
REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
pPixmap->screen_x, pPixmap->screen_y);
#endif
REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
box.x1 -= pPixmap->screen_x;
box.y1 -= pPixmap->screen_y;
box.x2 -= pPixmap->screen_x;
box.y2 -= pPixmap->screen_y;
}
if (!xglSyncBits (&pWin->drawable, NullBox))
FatalError (XGL_SW_FAILURE_STRING);
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, CopyWindow);
(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, CopyWindow, xglCopyWindow);
#endif
fbCopyRegion (&pWin->drawable, &pWin->drawable,
0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &box);
REGION_UNINIT (pWin->drawable.pScreen, &rgnDst);
}
static Bool
xglFillRegionSolid (DrawablePtr pDrawable,
RegionPtr pRegion,
Pixel pixel)
xglFillRegionSolid (DrawablePtr pDrawable,
RegionPtr pRegion,
Pixel pixel)
{
ScreenPtr pScreen = pDrawable->pScreen;
xglGeometryRec geometry;
glitz_color_t color;
glitz_color_t color;
BoxPtr pExtent;
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
if (!pPixmapPriv->target)
return FALSE;
xglPixelToColor (pPixmapPriv->pPixel, pixel, &color);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (pRegion) << 3);
GEOMETRY_ADD_REGION (pScreen, &geometry, pRegion);
xglPixelToColor (pPixmapPriv->pPixel, pixel, &color);
if (xglSolid (pDrawable,
GLITZ_OPERATOR_SRC,
&color,
&geometry,
REGION_EXTENTS (pScreen, pRegion), 1))
{
GEOMETRY_UNINIT (&geometry);
NULL,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pRegion),
REGION_NUM_RECTS (pRegion)))
return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@ -152,27 +176,26 @@ xglFillRegionTiled (DrawablePtr pDrawable,
int tileX,
int tileY)
{
ScreenPtr pScreen = pDrawable->pScreen;
xglGeometryRec geometry;
BoxPtr pExtent;
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
if (!XGL_GET_DRAWABLE_PIXMAP_PRIV (pDrawable)->target)
if (!pPixmapPriv->target)
return FALSE;
GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (pRegion) << 3);
GEOMETRY_ADD_REGION (pScreen, &geometry, pRegion);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
if (xglTile (pDrawable,
GLITZ_OPERATOR_SRC,
pTile,
tileX, tileY,
&geometry,
REGION_EXTENTS (pScreen, pRegion), 1))
{
GEOMETRY_UNINIT (&geometry);
NULL,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pRegion),
REGION_NUM_RECTS (pRegion)))
return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@ -202,7 +225,7 @@ xglPaintWindowBackground (WindowPtr pWin,
-pWin->drawable.x,
-pWin->drawable.y))
{
xglAddBitDamage (&pWin->drawable);
xglAddCurrentBitDamage (&pWin->drawable);
return;
}
@ -214,7 +237,7 @@ xglPaintWindowBackground (WindowPtr pWin,
pRegion,
pWin->background.pixel))
{
xglAddBitDamage (&pWin->drawable);
xglAddCurrentBitDamage (&pWin->drawable);
return;
}
break;
@ -222,7 +245,7 @@ xglPaintWindowBackground (WindowPtr pWin,
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBackground);
(*pScreen->PaintWindowBackground) (pWin, pRegion, what);
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, PaintWindowBackground,
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBackground,
xglPaintWindowBackground);
}
@ -241,7 +264,7 @@ xglPaintWindowBorder (WindowPtr pWin,
pRegion,
pWin->border.pixel))
{
xglAddBitDamage (&pWin->drawable);
xglAddCurrentBitDamage (&pWin->drawable);
return;
}
}
@ -258,7 +281,7 @@ xglPaintWindowBorder (WindowPtr pWin,
-pBgWin->drawable.x,
-pBgWin->drawable.y))
{
xglAddBitDamage (&pWin->drawable);
xglAddCurrentBitDamage (&pWin->drawable);
return;
}
@ -268,6 +291,6 @@ xglPaintWindowBorder (WindowPtr pWin,
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBorder);
(*pScreen->PaintWindowBorder) (pWin, pRegion, what);
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, PaintWindowBorder,
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBorder,
xglPaintWindowBorder);
}