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
@ -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;
typedef struct _xglArea {
int state;
int level;
int x, y;
xglPixmapPtr pPixmapPriv;
struct _xglOffscreenArea *pArea[4];
xglOffscreenPtr pOffscreen;
} xglOffscreenAreaRec, *xglOffscreenAreaPtr;
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;
@ -218,7 +333,7 @@ typedef struct _xglPixmap {
glitz_surface_t *surface;
glitz_buffer_t *buffer;
int target;
xglOffscreenAreaPtr pArea;
xglAreaPtr pArea;
int score;
Bool acceleratedTile;
pointer bits;
@ -228,7 +343,8 @@ typedef struct _xglPixmap {
BoxRec bitBox;
Bool allBits;
unsigned long pictureMask;
} xglPixmapRec;
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,16 +586,28 @@ 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) \
#define DEFAULT_GEOMETRY_USAGE GEOMETRY_USAGE_SYSMEM
#define GEOMETRY_INIT(pScreen, pGeometry, _type, _usage, _size) \
{ \
(pGeometry)->dataType = GEOMETRY_DATA_TYPE_FLOAT; \
(pGeometry)->usage = GEOMETRY_USAGE_USERMEM; \
(pGeometry)->primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; \
(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; \
@ -493,23 +615,72 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
(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) \
{ \
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_PRIMITIVE(pScreen, pGeometry, _primitive) \
(pGeometry)->primitive = _primitive
#define GEOMETRY_SET_BUFFER(pGeometry, _buffer) \
{ \
glitz_buffer_reference (_buffer); \
if ((pGeometry)->buffer) \
glitz_buffer_destroy ((pGeometry)->buffer); \
(pGeometry)->buffer = _buffer; \
}
#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_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, 0, 0, NULL, NULL)
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,34 +934,6 @@ xglTile (DrawablePtr pDrawable,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
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,
@ -739,7 +971,13 @@ xglCopyProc (DrawablePtr pSrc,
Bool
xglFill (DrawablePtr pDrawable,
GCPtr pGC,
xglGeometryPtr pGeometry);
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,
@ -970,7 +1221,9 @@ xglComp (CARD8 op,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height);
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"
@ -60,11 +60,13 @@ xglComp (CARD8 op,
INT16 xDst,
INT16 yDst,
CARD16 width,
CARD16 height)
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;
@ -82,21 +84,18 @@ xglComp (CARD8 op,
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,
xDst, yDst, width, height))
@ -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);
@ -146,7 +122,32 @@ xglComp (CARD8 op,
if (XGL_PICTURE_CHANGES (pSrcPriv->pictureMask))
xglUpdatePicture (pSrc);
src = pSrcPriv->surface;
if (pMask)
{
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))
{
@ -157,26 +158,63 @@ xglComp (CARD8 op,
pMaskPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pMask->pDrawable);
if (XGL_PICTURE_CHANGES (pMaskPriv->pictureMask))
xglUpdatePicture (pMask);
} else
pMaskPriv = NULL;
if (nBox > 1)
mask = pMaskPriv->surface;
}
}
if (!pGeometry)
{
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))
if (!pSrc->transform && pSrc->filter != PictFilterConvolution)
{
GEOMETRY_UNINIT (&geometry);
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);
} else
GEOMETRY_DISABLE (dst);
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 (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;
@ -192,59 +230,40 @@ xglComp (CARD8 op,
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)
{
BoxRec box;
if (pSrc->transform || pSrc->filter > 1)
return FALSE;
/*
* 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);
}
else
{
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),
pSrcPriv->surface,
(pMaskPriv)? pMaskPriv->surface: NULL,
dst,
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,72 +34,28 @@ 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;
XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
BOX_EXTENTS (pBox, nBox, &extents);
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
@ -109,25 +66,27 @@ xglCopy (DrawablePtr pSrc,
if (!xglSyncSurface (pDst))
return FALSE;
XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff);
XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
XGL_GET_DRAWABLE (pDst, dst, 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);
XGL_GET_DRAWABLE (pSrc, src, srcXoff, srcYoff);
pBox++;
}
glitz_surface_set_clip_region (dst,
dstXoff, dstYoff,
(glitz_box_t *) pBox, nBox);
if (glitz_surface_get_status (dstSurface))
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;
BoxPtr pSrcBox = (BoxPtr) closure;
*pRet = xglCopy (pSrc, pDst, dx, dy, pBox, nBox);
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;
pClipBox++;
if (part.x1 < part.x2 && part.y1 < part.y2)
ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
}
}
}
GEOMETRY_UNINIT (&geometry);
return FALSE;
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);
if (xglFill (pDrawable, pGC, &geometry))
{
GEOMETRY_UNINIT (&geometry);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
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)
if (pGC->alu != GXcopy || (pGCPriv->flags & xglGCPlaneMaskFlag))
{
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;
}
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);
}
}
RegionPtr
@ -195,37 +202,18 @@ xglCopyArea (DrawablePtr pSrc,
XGL_GC_PRIV (pGC);
flags = pGCPriv->flags;
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (pSrc)->target == xglPixmapTargetIn)
flags &= ~xglGCReadOnlyDrawableFlag;
if (!flags)
{
Bool ret;
ret = TRUE;
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);
}
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 (!xglSyncBits (pSrc, &box))
FatalError (XGL_SW_FAILURE_STRING);
@ -233,6 +221,17 @@ xglCopyArea (DrawablePtr pSrc,
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 *) &box);
}
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);
}
}
void
@ -413,6 +411,21 @@ xglImageGlyphBlt (DrawablePtr pDrawable,
{
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);
@ -430,7 +443,22 @@ xglPolyGlyphBlt (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
if (!pGCPriv->flags)
{
if (xglFillGlyph (pDrawable,
pGC,
x,
y,
nglyph,
ppci,
pglyphBase))
{
xglAddCurrentBitDamage (pDrawable);
return;
}
}
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) }
};
@ -46,17 +45,15 @@ xglGeometryResize (ScreenPtr pScreen,
{
XGL_SCREEN_PRIV (pScreen);
if (pGeometry->broken)
return;
if (size == pGeometry->size)
return;
if (pGeometry->usage == GEOMETRY_USAGE_USERMEM)
if (pGeometry->broken)
return;
if (pGeometry->usage == GEOMETRY_USAGE_SYSMEM)
{
pGeometry->data =
xrealloc (pGeometry->data,
size * dataTypes[pGeometry->dataType].size);
pGeometry->data = xrealloc (pGeometry->data, size);
if (pGeometry->buffer)
glitz_buffer_destroy (pGeometry->buffer);
@ -81,15 +78,10 @@ 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,
glitz_vertex_buffer_create (pScreenPriv->drawable, NULL, size,
usageTypes[pGeometry->usage]);
if (!newBuffer)
{
@ -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)) \
{ \
xglGeometryResize (pScreen, pGeometry, \
(pGeometry)->endOffset + \
((nvertices) << 1) + 200); \
#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)) \
{ \
(pGeometry)->broken = TRUE; \
return; \
} \
if (((offset) + (_size)) > (pGeometry)->endOffset) \
{ \
(pGeometry)->endOffset = (offset) + (_size); \
(pGeometry)->count = (pGeometry)->endOffset / \
(2 * xglGeometryDataTypes[(pGeometry)->dataType].size); \
}
/*
* 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;
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
}
/*
* Adds a number of boxes as GL_QUAD primitives
*/
@ -230,35 +157,22 @@ 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;
}
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;
@ -277,8 +191,6 @@ xglGeometryAddBox (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (nBox--)
{
*data++ = (glitz_float_t) pBox->x1;
@ -295,59 +207,38 @@ xglGeometryAddBox (ScreenPtr pScreen,
} break;
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
* 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 n,
int offset)
{
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
int size;
char *ptr;
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, n * 4, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
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++;
@ -373,13 +262,7 @@ 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)
@ -502,13 +368,7 @@ 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,
*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++ = ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
*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;
@ -579,37 +426,298 @@ 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"
@ -36,6 +36,8 @@ xglGetImage (DrawablePtr pDrawable,
char *d)
{
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;
}
XGL_PIXMAP_PRIV (pPixmap);
static xglOffscreenAreaPtr
xglCreateOffscreenArea (xglOffscreenPtr pOffscreen,
int level,
int x,
int y)
{
xglOffscreenAreaPtr pArea;
int i;
glitz_surface_detach (pPixmapPriv->surface);
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;
for (i = 0; i < 4; i++)
xglDestroyOffscreenArea (pArea->pArea[i]);
}
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);
XGL_PIXMAP_PRIV ((PixmapPtr) closure1);
return topScore;
}
else
{
int topScore, score, i;
s1 = pPixmapPriv->score;
s2 = XGL_GET_PIXMAP_PRIV ((PixmapPtr) closure2)->score;
topScore = 0;
for (i = 0; i < 4; i++)
{
if (pArea->pArea[i])
{
score = xglOffscreenAreaGetTopScore (pArea->pArea[i]);
if (score > topScore)
topScore = score;
}
}
return topScore;
}
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,31 +121,30 @@ xglInitOffscreen (ScreenPtr pScreen,
*/
if (format->doublebuffer)
{
pScreenPriv->pOffscreen =
xrealloc (pScreenPriv->pOffscreen,
sizeof (xglOffscreenRec) *
(pScreenPriv->nOffscreen + 1));
if (pScreenPriv->pOffscreen)
{
pOffscreen = &pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
pOffscreen->drawable = pScreenPriv->drawable;
pOffscreen->format = format;
pOffscreen->buffer = GLITZ_DRAWABLE_BUFFER_BACK_COLOR;
if (xglOffscreenInit (pOffscreen,
pScreenPriv->drawable,
GLITZ_DRAWABLE_BUFFER_BACK_COLOR,
pScreenInfo->width, pScreenInfo->height))
if (xglRootAreaInit (&pOffscreen->rootArea,
MAX_OFFSCREEN_LEVEL,
pScreenInfo->width,
pScreenInfo->height, 0,
(xglAreaFuncsPtr) &xglOffscreenAreaFuncs,
(pointer) pOffscreen))
{
glitz_drawable_reference (pOffscreen->drawable);
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;
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;
do {
pbuffer =
glitz_create_pbuffer_drawable (pScreenPriv->drawable,
xglPbufferVisuals[i].format,
&attributes, mask);
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 =
&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
pOffscreen->drawable = pbuffer;
pOffscreen->format = xglPbufferVisuals[i].format;
pOffscreen->buffer = _buffers[j];
if (xglOffscreenInit (pOffscreen,
pbuffer, _buffers[j],
width, height))
if (xglRootAreaInit (&pOffscreen->rootArea,
MAX_OFFSCREEN_LEVEL,
width, height, 0,
(xglAreaFuncsPtr)
&xglOffscreenAreaFuncs,
(pointer) pOffscreen))
{
glitz_drawable_reference (pbuffer);
pScreenPriv->nOffscreen++;
ErrorF ("Initialized %dx%d pbuffer offscreen "
"area\n", width, height);
}
pOffscreen++;
ErrorF ("Initialized %dx%d pbuffer offscreen area\n",
width, height);
}
j++;
}
@ -391,31 +209,24 @@ 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;
}
void
xglFiniOffscreen (ScreenPtr pScreen)
{
int n;
XGL_SCREEN_PRIV (pScreen);
while (pScreenPriv->nOffscreen--)
xglOffscreenFini (&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen]);
n = pScreenPriv->nOffscreen;
while (n--)
{
xglRootAreaFini (&pScreenPriv->pOffscreen[n].rootArea);
glitz_drawable_destroy (pScreenPriv->pOffscreen[n].drawable);
}
if (pScreenPriv->pOffscreen)
xfree (pScreenPriv->pOffscreen);
pScreenPriv->nOffscreen = 0;
}
Bool
@ -439,25 +250,28 @@ 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++;
}
@ -465,8 +279,12 @@ xglFindOffscreenArea (ScreenPtr pScreen,
}
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,
@ -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"
@ -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;
/*
@ -169,6 +168,7 @@ xglCreatePixmap (ScreenPtr pScreen,
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);
@ -305,6 +307,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);
@ -433,6 +497,9 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
}
}
/* 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)
{
@ -101,6 +100,12 @@ xglAllocatePrivates (ScreenPtr pScreen)
if (xglWinPrivateIndex < 0)
return FALSE;
#ifdef RENDER
xglGlyphPrivateIndex = AllocateGlyphPrivateIndex ();
if (xglGlyphPrivateIndex < 0)
return FALSE;
#endif
xglScreenGeneration = serverGeneration;
}
@ -153,10 +158,18 @@ xglScreenInit (ScreenPtr 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;
@ -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,12 +290,55 @@ 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);
@ -293,8 +369,58 @@ xglCloseScreen (int index,
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);
if (pGeometry)
{
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_ALL_VERTICES (pGeometry, surface))
if (!GEOMETRY_ENABLE (pGeometry, surface))
return FALSE;
while (nBox--)
{
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);
x + xOff,
y + yOff,
width, height);
pBox++;
}
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"
@ -153,22 +153,40 @@ xglSyncBits (DrawablePtr pDrawable,
if (!xglAllocatePixmapBits (pPixmap))
return FALSE;
if (REGION_NOTEMPTY (pDrawable->pScreen, &region))
if (pPixmapPriv->pDamage)
{
if (pPixmapPriv->surface)
RegionPtr pRegion;
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);
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;
format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
}
while (nBox--)
{
@ -186,7 +204,6 @@ xglSyncBits (DrawablePtr pDrawable,
pBox++;
}
}
}
REGION_UNINIT (pDrawable->pScreen, &region);
@ -236,8 +253,17 @@ xglSyncSurface (DrawablePtr pDrawable)
pBox = REGION_RECTS (pRegion);
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;
format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
}
while (nBox--)
{
@ -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,131 +20,66 @@
* 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
}
}
};
Bool
xglTile (DrawablePtr pDrawable,
glitz_operator_t op,
PixmapPtr pTile,
xglGeometryPtr
xglTiledBoxGeometry (PixmapPtr pTile,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
BoxPtr pBox,
int nBox)
{
xglPixmapPtr pTilePriv;
glitz_surface_t *surface;
int xOff, yOff;
if (!xglSyncSurface (&pTile->drawable))
return FALSE;
if (!xglPrepareTarget (pDrawable))
return FALSE;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE_ALL_VERTICES (pGeometry, surface))
return FALSE;
pTilePriv = XGL_GET_PIXMAP_PRIV (pTile);
pTilePriv->pictureMask |=
xglPCFillMask | 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--)
{
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++;
}
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)
return FALSE;
xglSwTile (op,
pTilePriv->surface, NULL, surface,
tileX - xOff, tileY - yOff,
0, 0,
TILE_SOURCE,
pBox, nBox,
xOff, yOff);
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;
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;
x = pBox->x1 + xOff;
y = pBox->y1 + yOff;
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;
@ -165,29 +100,44 @@ xglSwTile (glitz_operator_t op,
{
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);
}
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;
@ -197,4 +147,122 @@ xglSwTile (glitz_operator_t op,
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,
glitz_operator_t op,
PixmapPtr pTile,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox)
{
xglPixmapPtr pTilePriv;
glitz_surface_t *surface;
int xOff, yOff;
if (nBox < 1)
return TRUE;
if (!xglPrepareTarget (pDrawable))
return FALSE;
if (!xglSyncSurface (&pTile->drawable))
return FALSE;
XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
pTilePriv = XGL_GET_PIXMAP_PRIV (pTile);
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)
{
if (pGeometry)
{
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;
if (!nBox)
return FALSE;
}
else
{
if (pGeometry)
return FALSE;
}
pGeometry = xglTiledBoxGeometry (pTile, tileX, tileY, pBox, nBox);
if (!pGeometry)
return FALSE;
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;
}

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); \
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) \
#define XGL_WINDOW_FALLBACK_EPILOGUE(pWin, pRegion, func, xglfunc) \
XGL_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (&pWin->drawable)
xglAddSurfaceDamage (&pWin->drawable, pRegion)
Bool
xglCreateWindow (WindowPtr pWin)
@ -52,64 +53,90 @@ 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;
XGL_SCREEN_PRIV (pScreen);
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (&pWin->drawable)->target)
{
PixmapPtr pPixmap;
RegionRec rgnDst;
int dx, dy;
Bool ret;
BoxPtr pExtent = REGION_EXTENTS (pWin->drawable.pScreen, prgnSrc);
BoxRec box;
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;
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);
box.x1 -= pPixmap->screen_x;
box.y1 -= pPixmap->screen_y;
box.x2 -= pPixmap->screen_x;
box.y2 -= pPixmap->screen_y;
}
#endif
ret = TRUE;
fbCopyRegion (&pWin->drawable, &pWin->drawable,
0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &ret);
0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &box);
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);
}
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);
REGION_UNINIT (pWin->drawable.pScreen, &rgnDst);
}
static Bool
@ -117,31 +144,28 @@ xglFillRegionSolid (DrawablePtr pDrawable,
RegionPtr pRegion,
Pixel pixel)
{
ScreenPtr pScreen = pDrawable->pScreen;
xglGeometryRec geometry;
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;
if (!XGL_GET_DRAWABLE_PIXMAP_PRIV (pDrawable)->target)
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
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);
}