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 \ xglcmap.c \
xglparse.c \ xglparse.c \
xglscreen.c \ xglscreen.c \
xglarea.c \
xgloffscreen.c \ xgloffscreen.c \
xglgeometry.c \ xglgeometry.c \
xglpixmap.c \ xglpixmap.c \
xglsync.c \ xglsync.c \
xglsolid.c \ xglsolid.c \
xgltile.c \ xgltile.c \
xglpixel.c \
xglcopy.c \ xglcopy.c \
xglfill.c \ xglfill.c \
xglwindow.c \ xglwindow.c \
@ -27,4 +27,6 @@ libxgl_a_SOURCES = \
xglget.c \ xglget.c \
xglgc.c \ xglgc.c \
xglcomp.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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include <X11/Xlib.h> #include <X11/Xlib.h>
@ -64,7 +64,11 @@ int xscreen;
glitz_format_t *xglxCurrentFormat; glitz_format_t *xglxCurrentFormat;
CARD32 lastEventTime = 0; CARD32 lastEventTime = 0;
ScreenPtr currentScreen = NULL; 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 static Bool
xglxAllocatePrivates (ScreenPtr pScreen) xglxAllocatePrivates (ScreenPtr pScreen)
@ -386,9 +390,15 @@ xglxBlockHandler (pointer blockData,
OSTimePtr pTimeout, OSTimePtr pTimeout,
pointer pReadMask) pointer pReadMask)
{ {
glitz_surface_flush (XGL_GET_SCREEN_PRIV (currentScreen)->surface); XGL_SCREEN_PRIV (currentScreen);
glitz_drawable_flush (XGL_GET_SCREEN_PRIV (currentScreen)->drawable);
XFlush (xdisplay); 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 static void
@ -397,8 +407,8 @@ xglxWakeupHandler (pointer blockData,
pointer pReadMask) pointer pReadMask)
{ {
ScreenPtr pScreen = currentScreen; ScreenPtr pScreen = currentScreen;
XEvent X; XEvent X;
xEvent x; xEvent x;
while (XPending (xdisplay)) { while (XPending (xdisplay)) {
XNextEvent (xdisplay, &X); XNextEvent (xdisplay, &X);
@ -578,7 +588,7 @@ InitInput (int argc, char **argv)
void void
ddxUseMsg (void) ddxUseMsg (void)
{ {
ErrorF ("\nXglx Usage:\n"); ErrorF ("\nXglx usage:\n");
ErrorF ("-display string display name of the real server\n"); ErrorF ("-display string display name of the real server\n");
xglUseMsg (); xglUseMsg ();

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#ifndef _XGL_H_ #ifndef _XGL_H_
@ -61,6 +61,8 @@ typedef struct _xglScreenInfo {
unsigned int widthMm; unsigned int widthMm;
unsigned int heightMm; unsigned int heightMm;
Bool fullscreen; Bool fullscreen;
int geometryDataType;
int geometryUsage;
} xglScreenInfoRec, *xglScreenInfoPtr; } xglScreenInfoRec, *xglScreenInfoPtr;
typedef struct _xglPixelFormat { typedef struct _xglPixelFormat {
@ -85,29 +87,123 @@ extern int nxglVisuals;
extern xglVisualPtr xglPbufferVisuals; extern xglVisualPtr xglPbufferVisuals;
extern int nxglPbufferVisuals; extern int nxglPbufferVisuals;
#define xglOffscreenAreaAvailable 0 #define xglAreaAvailable 0
#define xglOffscreenAreaDivided 1 #define xglAreaDivided 1
#define xglOffscreenAreaOccupied 2 #define xglAreaOccupied 2
typedef struct _xglOffscreen *xglOffscreenPtr; typedef struct _xglRootArea *xglRootAreaPtr;
typedef struct _xglPixmap *xglPixmapPtr;
typedef struct _xglOffscreenArea { typedef struct _xglArea {
int level; int state;
int state; int level;
int x, y; int x, y;
xglPixmapPtr pPixmapPriv; int width, height;
struct _xglOffscreenArea *pArea[4]; struct _xglArea *pArea[4];
xglOffscreenPtr pOffscreen; xglRootAreaPtr pRoot;
} xglOffscreenAreaRec, *xglOffscreenAreaPtr; 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 { typedef struct _xglOffscreen {
xglRootAreaRec rootArea;
glitz_drawable_t *drawable; glitz_drawable_t *drawable;
glitz_drawable_format_t *format; glitz_drawable_format_t *format;
glitz_drawable_buffer_t buffer; glitz_drawable_buffer_t buffer;
int width, height; } xglOffscreenRec, *xglOffscreenPtr;
xglOffscreenAreaPtr pArea;
} xglOffscreenRec;
typedef struct _xglScreen { typedef struct _xglScreen {
xglVisualPtr pVisual; xglVisualPtr pVisual;
@ -117,12 +213,26 @@ typedef struct _xglScreen {
glitz_surface_t *solid; glitz_surface_t *solid;
PixmapPtr pScreenPixmap; PixmapPtr pScreenPixmap;
unsigned long features; unsigned long features;
xglOffscreenPtr pOffscreen; xglOffscreenRec pOffscreen[XGL_MAX_OFFSCREEN_AREAS];
int nOffscreen; 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; GetImageProcPtr GetImage;
GetSpansProcPtr GetSpans; GetSpansProcPtr GetSpans;
CreateWindowProcPtr CreateWindow; CreateWindowProcPtr CreateWindow;
ChangeWindowAttributesProcPtr ChangeWindowAttributes;
PaintWindowBackgroundProcPtr PaintWindowBackground; PaintWindowBackgroundProcPtr PaintWindowBackground;
PaintWindowBorderProcPtr PaintWindowBorder; PaintWindowBorderProcPtr PaintWindowBorder;
CopyWindowProcPtr CopyWindow; CopyWindowProcPtr CopyWindow;
@ -133,11 +243,16 @@ typedef struct _xglScreen {
#ifdef RENDER #ifdef RENDER
CompositeProcPtr Composite; CompositeProcPtr Composite;
RasterizeTrapezoidProcPtr RasterizeTrapezoid;
GlyphsProcPtr Glyphs; GlyphsProcPtr Glyphs;
TrapezoidsProcPtr Trapezoids;
AddTrapsProcPtr AddTraps;
AddTrianglesProcPtr AddTriangles;
ChangePictureProcPtr ChangePicture; ChangePictureProcPtr ChangePicture;
ChangePictureTransformProcPtr ChangePictureTransform; ChangePictureTransformProcPtr ChangePictureTransform;
ChangePictureFilterProcPtr ChangePictureFilter; ChangePictureFilterProcPtr ChangePictureFilter;
RealizeGlyphProcPtr RealizeGlyph;
UnrealizeGlyphProcPtr UnrealizeGlyph;
#endif #endif
BSFuncRec BackingStoreFuncs; BSFuncRec BackingStoreFuncs;
@ -213,22 +328,23 @@ extern int xglGCPrivateIndex;
#define xglPixmapTargetIn 2 #define xglPixmapTargetIn 2
typedef struct _xglPixmap { typedef struct _xglPixmap {
xglPixelFormatPtr pPixel; xglPixelFormatPtr pPixel;
glitz_format_t *format; glitz_format_t *format;
glitz_surface_t *surface; glitz_surface_t *surface;
glitz_buffer_t *buffer; glitz_buffer_t *buffer;
int target; int target;
xglOffscreenAreaPtr pArea; xglAreaPtr pArea;
int score; int score;
Bool acceleratedTile; Bool acceleratedTile;
pointer bits; pointer bits;
unsigned int stride; unsigned int stride;
DamagePtr pDamage; DamagePtr pDamage;
BoxRec damageBox; BoxRec damageBox;
BoxRec bitBox; BoxRec bitBox;
Bool allBits; Bool allBits;
unsigned long pictureMask; unsigned long pictureMask;
} xglPixmapRec; xglGeometryPtr pGeometry;
} xglPixmapRec, *xglPixmapPtr;
extern int xglPixmapPrivateIndex; extern int xglPixmapPrivateIndex;
@ -271,19 +387,6 @@ extern int xglWinPrivateIndex;
#define XGL_DRAWABLE_PIXMAP_PRIV(pDrawable) \ #define XGL_DRAWABLE_PIXMAP_PRIV(pDrawable) \
xglPixmapPtr pPixmapPriv = XGL_GET_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 #ifdef COMPOSITE
#define __XGL_OFF_X_WIN(pPix) (-(pPix)->screen_x) #define __XGL_OFF_X_WIN(pPix) (-(pPix)->screen_x)
#define __XGL_OFF_Y_WIN(pPix) (-(pPix)->screen_y) #define __XGL_OFF_Y_WIN(pPix) (-(pPix)->screen_y)
@ -308,11 +411,6 @@ typedef struct xglGeometry {
#define XGL_DEFAULT_DPI 96 #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 XGL_SW_FAILURE_STRING "software fall-back failure"
#define MIN(a,b) ((a) < (b) ? (a) : (b)) #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 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) \ #define BOX_NOTEMPTY(pBox) \
(((pBox)->x2 - (pBox)->x1) > 0 && \ (((pBox)->x2 - (pBox)->x1) > 0 && \
((pBox)->y2 - (pBox)->y1) > 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_MAX_PIXMAP_SCORE 32768
#define XGL_MIN_PIXMAP_SCORE -32768 #define XGL_MIN_PIXMAP_SCORE -32768
@ -453,6 +532,37 @@ Bool
xglCloseScreen (int index, xglCloseScreen (int index,
ScreenPtr pScreen); 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 */ /* xgloffscreen.c */
@ -468,7 +578,7 @@ xglFindOffscreenArea (ScreenPtr pScreen,
PixmapPtr pPixmap); PixmapPtr pPixmap);
void void
xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea); xglLeaveOffscreenArea (PixmapPtr pPixmap);
/* xglgeometry.c */ /* xglgeometry.c */
@ -476,40 +586,101 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
#define GEOMETRY_DATA_TYPE_SHORT 0 #define GEOMETRY_DATA_TYPE_SHORT 0
#define GEOMETRY_DATA_TYPE_FLOAT 1 #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_STREAM 0
#define GEOMETRY_USAGE_STATIC 1 #define GEOMETRY_USAGE_STATIC 1
#define GEOMETRY_USAGE_DYNAMIC 2 #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
{ \
(pGeometry)->dataType = GEOMETRY_DATA_TYPE_FLOAT; \ #define GEOMETRY_INIT(pScreen, pGeometry, _type, _usage, _size) \
(pGeometry)->usage = GEOMETRY_USAGE_USERMEM; \ { \
(pGeometry)->primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; \ (pGeometry)->type = _type; \
(pGeometry)->size = 0; \ (pGeometry)->usage = _usage; \
(pGeometry)->endOffset = 0; \ (pGeometry)->dataType = DEFAULT_GEOMETRY_DATA_TYPE; \
(pGeometry)->data = (pointer) 0; \ (pGeometry)->usage = _usage; \
(pGeometry)->buffer = NULL; \ (pGeometry)->size = 0; \
(pGeometry)->broken = FALSE; \ (pGeometry)->endOffset = 0; \
(pGeometry)->xOff = 0; \ (pGeometry)->data = (pointer) 0; \
(pGeometry)->yOff = 0; \ (pGeometry)->buffer = NULL; \
xglGeometryResize (pScreen, pGeometry, _size); \ (pGeometry)->broken = FALSE; \
(pGeometry)->xOff = 0; \
(pGeometry)->yOff = 0; \
(pGeometry)->array = NULL; \
(pGeometry)->first = 0; \
(pGeometry)->count = 0; \
if (_type == GLITZ_GEOMETRY_TYPE_VERTEX) \
{ \
(pGeometry)->width = 2; \
(pGeometry)->f.vertex.type = \
xglGeometryDataTypes[(pGeometry)->dataType].type; \
(pGeometry)->f.vertex.bytes_per_vertex = (pGeometry)->width * \
xglGeometryDataTypes[(pGeometry)->dataType].size; \
(pGeometry)->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS; \
(pGeometry)->f.vertex.attributes = 0; \
(pGeometry)->f.vertex.src.type = GLITZ_DATA_TYPE_FLOAT; \
(pGeometry)->f.vertex.src.size = GLITZ_COORDINATE_SIZE_X; \
(pGeometry)->f.vertex.src.offset = 0; \
(pGeometry)->f.vertex.mask.type = GLITZ_DATA_TYPE_FLOAT; \
(pGeometry)->f.vertex.mask.size = GLITZ_COORDINATE_SIZE_X; \
(pGeometry)->f.vertex.mask.offset = 0; \
} \
else \
{ \
(pGeometry)->width = 0; \
(pGeometry)->f.bitmap.scanline_order = \
GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; \
(pGeometry)->f.bitmap.bytes_per_line = 0; \
(pGeometry)->f.bitmap.pad = GLYPHPADBYTES; \
} \
if (_size) \
xglGeometryResize (pScreen, pGeometry, _size); \
} }
#define GEOMETRY_UNINIT(pGeometry) \ #define GEOMETRY_UNINIT(pGeometry) \
{ \
if ((pGeometry)->array) \
glitz_multi_array_destroy ((pGeometry)->array); \
if ((pGeometry)->buffer) \
glitz_buffer_destroy ((pGeometry)->buffer); \
if ((pGeometry)->data) \
xfree ((pGeometry)->data); \
}
#define GEOMETRY_SET_BUFFER(pGeometry, _buffer) \
{ \ { \
glitz_buffer_reference (_buffer); \
if ((pGeometry)->buffer) \ if ((pGeometry)->buffer) \
glitz_buffer_destroy ((pGeometry)->buffer); \ glitz_buffer_destroy ((pGeometry)->buffer); \
if ((pGeometry)->data) \ (pGeometry)->buffer = _buffer; \
xfree ((pGeometry)->data); \
} }
#define GEOMETRY_SET_PRIMITIVE(pScreen, pGeometry, _primitive) \ #define GEOMETRY_SET_MULTI_ARRAY(pGeometry, _array) \
(pGeometry)->primitive = _primitive { \
glitz_multi_array_reference (_array); \
if ((pGeometry)->array) \
glitz_multi_array_destroy ((pGeometry)->array); \
(pGeometry)->array = _array; \
}
#define GEOMETRY_RESIZE(pScreen, pGeometry, size) \ #define GEOMETRY_RESIZE(pScreen, pGeometry, size) \
xglGeometryResize (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) \ #define GEOMETRY_TRANSLATE(pGeometry, tx, ty) \
{ \ { \
(pGeometry)->xOff += (tx) << 16; \ (pGeometry)->xOff += (tx) << 16; \
@ -522,58 +693,84 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
(pGeometry)->yOff += (fty); \ (pGeometry)->yOff += (fty); \
} }
#define GEOMETRY_ADD_RECT(pScreen, pGeometry, pRect, nRect) \ #define GEOMETRY_SET_VERTEX_PRIMITIVE(pGeometry, _primitive) \
xglGeometryAddRect (pScreen, pGeometry, pRect, nRect) (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) \ #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) \ #define GEOMETRY_ADD_REGION(pScreen, pGeometry, pRegion) \
xglGeometryAddBox (pScreen, pGeometry, \ xglGeometryAddBox (pScreen, pGeometry, \
REGION_RECTS (pRegion), \ REGION_RECTS (pRegion), \
REGION_NUM_RECTS (pRegion)) REGION_NUM_RECTS (pRegion), \
(pGeometry)->endOffset)
#define GEOMETRY_ADD_SPAN(pScreen, pGeometry, ppt, pwidth, n) \ #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) \ #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) \ #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) \ #define GEOMETRY_FOR_GLYPH(pScreen, pGeometry, nGlyph, ppciInit, pglyphBase) \
xglSetGeometry (pGeometry, surface, first, count); xglGeometryForGlyph (pScreen, pGeometry, nGlyph, ppciInit, pglyphBase);
#define GEOMETRY_ENABLE_ALL_VERTICES(pGeometry, surface) \ #define GEOMETRY_ADD_TRAPEZOID(pScreen, pGeometry, pTrap, nTrap) \
xglSetGeometry (pGeometry, surface, 0, (pGeometry)->endOffset / 2) xglGeometryAddTrapezoid (pScreen, pGeometry, pTrap, nTrap, \
(pGeometry)->endOffset)
#define GEOMETRY_DISABLE(surface) \ #define GEOMETRY_ADD_TRAP(pScreen, pGeometry, pTrap, nTrap) \
glitz_set_geometry (surface, 0, 0, NULL, NULL) xglGeometryAddTrap (pScreen, pGeometry, pTrap, nTrap, \
(pGeometry)->endOffset)
#define GEOMETRY_GET_FORMAT(pGeometry, format) \
xglGeometryGetFormat (pGeometry, format)
#define GEOMETRY_ENABLE(pGeometry, surface) \
xglSetGeometry (pGeometry, surface)
#define GEOMETRY_DISABLE(surface) \
glitz_set_geometry (surface, GLITZ_GEOMETRY_TYPE_NONE, NULL, NULL)
void void
xglGeometryResize (ScreenPtr pScreen, xglGeometryResize (ScreenPtr pScreen,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
int size); int size);
void
xglGeometryAddRect (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
xRectangle *pRect,
int nRect);
void void
xglGeometryAddBox (ScreenPtr pScreen, xglGeometryAddBox (ScreenPtr pScreen,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
BoxPtr pBox, BoxPtr pBox,
int nBox); int nBox,
int offset);
void void
xglGeometryAddSpan (ScreenPtr pScreen, xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
DDXPointPtr ppt, DDXPointPtr ppt,
int *pwidth, int *pwidth,
int n); int n,
int offset);
void void
xglGeometryAddLine (ScreenPtr pScreen, xglGeometryAddLine (ScreenPtr pScreen,
@ -581,19 +778,53 @@ xglGeometryAddLine (ScreenPtr pScreen,
int loop, int loop,
int mode, int mode,
int npt, int npt,
DDXPointPtr ppt); DDXPointPtr ppt,
int offset);
void void
xglGeometryAddSegment (ScreenPtr pScreen, xglGeometryAddSegment (ScreenPtr pScreen,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
int nsegInit, 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 Bool
xglSetGeometry (xglGeometryPtr pGeometry, xglSetGeometry (xglGeometryPtr pGeometry,
glitz_surface_t *surface, glitz_surface_t *surface);
int first,
int count);
/* xglpixmap.c */ /* xglpixmap.c */
@ -619,6 +850,11 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
RegionPtr RegionPtr
xglPixmapToRegion (PixmapPtr pPixmap); xglPixmapToRegion (PixmapPtr pPixmap);
xglGeometryPtr
xglPixmapToGeometry (PixmapPtr pPixmap,
int xOff,
int yOff);
Bool Bool
xglCreatePixmapSurface (PixmapPtr pPixmap); xglCreatePixmapSurface (PixmapPtr pPixmap);
@ -648,10 +884,14 @@ Bool
xglPrepareTarget (DrawablePtr pDrawable); xglPrepareTarget (DrawablePtr pDrawable);
void void
xglAddSurfaceDamage (DrawablePtr pDrawable); xglAddSurfaceDamage (DrawablePtr pDrawable,
RegionPtr pRegion);
void void
xglAddBitDamage (DrawablePtr pDrawable); xglAddCurrentSurfaceDamage (DrawablePtr pDrawable);
void
xglAddCurrentBitDamage (DrawablePtr pDrawable);
/* xglsolid.c */ /* xglsolid.c */
@ -661,12 +901,32 @@ xglSolid (DrawablePtr pDrawable,
glitz_operator_t op, glitz_operator_t op,
glitz_color_t *color, glitz_color_t *color,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox, BoxPtr pBox,
int nBox); int nBox);
Bool
xglSolidGlyph (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nGlyph,
CharInfoPtr *ppci,
pointer pglyphBase);
/* xgltile.c */ /* xgltile.c */
xglGeometryPtr
xglTiledBoxGeometry (PixmapPtr pTile,
int tileX,
int tileY,
BoxPtr pBox,
int nBox);
Bool Bool
xglTile (DrawablePtr pDrawable, xglTile (DrawablePtr pDrawable,
glitz_operator_t op, glitz_operator_t op,
@ -674,41 +934,13 @@ xglTile (DrawablePtr pDrawable,
int tileX, int tileX,
int tileY, int tileY,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox, BoxPtr pBox,
int nBox); int nBox);
#define TILE_SOURCE 0
#define TILE_MASK 1
void
xglSwTile (glitz_operator_t op,
glitz_surface_t *srcSurface,
glitz_surface_t *maskSurface,
glitz_surface_t *dstSurface,
int xSrc,
int ySrc,
int xMask,
int yMask,
int what,
BoxPtr pBox,
int nBox,
int xOff,
int yOff);
/* xglpixel.c */
Bool
xglSetPixels (DrawablePtr pDrawable,
char *src,
int stride,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox);
/* xglcopy.c */ /* xglcopy.c */
@ -737,9 +969,15 @@ xglCopyProc (DrawablePtr pSrc,
/* xglfill.c */ /* xglfill.c */
Bool Bool
xglFill (DrawablePtr pDrawable, xglFill (DrawablePtr pDrawable,
GCPtr pGC, GCPtr pGC,
xglGeometryPtr pGeometry); xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox);
Bool Bool
xglFillSpan (DrawablePtr pDrawable, xglFillSpan (DrawablePtr pDrawable,
@ -748,7 +986,7 @@ xglFillSpan (DrawablePtr pDrawable,
DDXPointPtr ppt, DDXPointPtr ppt,
int *pwidth); int *pwidth);
Bool void
xglFillRect (DrawablePtr pDrawable, xglFillRect (DrawablePtr pDrawable,
GCPtr pGC, GCPtr pGC,
int nrect, int nrect,
@ -767,12 +1005,25 @@ xglFillSegment (DrawablePtr pDrawable,
int nsegInit, int nsegInit,
xSegment *pSegInit); xSegment *pSegInit);
Bool
xglFillGlyph (DrawablePtr pDrawable,
GCPtr pGC,
int x,
int y,
unsigned int nglyph,
CharInfoPtr *ppciInit,
pointer pglyphBase);
/* xglwindow.c */ /* xglwindow.c */
Bool Bool
xglCreateWindow (WindowPtr pWin); xglCreateWindow (WindowPtr pWin);
Bool
xglChangeWindowAttributes (WindowPtr pWin,
unsigned long mask);
void void
xglCopyWindow (WindowPtr pWin, xglCopyWindow (WindowPtr pWin,
DDXPointRec ptOldOrg, DDXPointRec ptOldOrg,
@ -959,18 +1210,20 @@ xglPushPixels (GCPtr pGC,
/* xglcomp.c */ /* xglcomp.c */
Bool Bool
xglComp (CARD8 op, xglComp (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
PicturePtr pMask, PicturePtr pMask,
PicturePtr pDst, PicturePtr pDst,
INT16 xSrc, INT16 xSrc,
INT16 ySrc, INT16 ySrc,
INT16 xMask, INT16 xMask,
INT16 yMask, INT16 yMask,
INT16 xDst, INT16 xDst,
INT16 yDst, INT16 yDst,
CARD16 width, CARD16 width,
CARD16 height); CARD16 height,
xglGeometryPtr pGeometry,
glitz_surface_t *mask);
/* xglpict.c */ /* xglpict.c */
@ -990,21 +1243,11 @@ xglComposite (CARD8 op,
CARD16 height); CARD16 height);
void void
xglGlyphs (CARD8 op, xglAddTriangles (PicturePtr pDst,
PicturePtr pSrc, INT16 xOff,
PicturePtr pDst, INT16 yOff,
PictFormatPtr maskFormat, int ntri,
INT16 xSrc, xTriangle *tris);
INT16 ySrc,
int nlist,
GlyphListPtr list,
GlyphPtr *glyphs);
void
xglRasterizeTrapezoid (PicturePtr pDst,
xTrapezoid *trap,
int xOff,
int yOff);
void void
xglChangePicture (PicturePtr pPicture, xglChangePicture (PicturePtr pPicture,
@ -1023,6 +1266,59 @@ xglChangePictureFilter (PicturePtr pPicture,
void void
xglUpdatePicture (PicturePtr pPicture); 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
#endif /* _XGL_H_ */ #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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -31,7 +31,7 @@
#define XGL_BSTORE_FALLBACK_EPILOGUE(pDrawable, func, xglfunc) \ #define XGL_BSTORE_FALLBACK_EPILOGUE(pDrawable, func, xglfunc) \
XGL_SCREEN_WRAP (func, xglfunc); \ XGL_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (pDrawable) xglAddCurrentSurfaceDamage (pDrawable)
/* /*
* The follwong functions are not yet tested so we can assume that they * The follwong functions are not yet tested so we can assume that they
@ -61,7 +61,7 @@ xglSaveAreas (PixmapPtr pPixmap,
REGION_RECTS (prgnSave), REGION_RECTS (prgnSave),
REGION_NUM_RECTS (prgnSave))) REGION_NUM_RECTS (prgnSave)))
{ {
xglAddBitDamage (&pPixmap->drawable); xglAddCurrentBitDamage (&pPixmap->drawable);
return; return;
} }
@ -101,7 +101,7 @@ xglRestoreAreas (PixmapPtr pPixmap,
REGION_RECTS (prgnRestore), REGION_RECTS (prgnRestore),
REGION_NUM_RECTS (prgnRestore))) REGION_NUM_RECTS (prgnRestore)))
{ {
xglAddBitDamage (&pPixmap->drawable); xglAddCurrentBitDamage (&pPixmap->drawable);
return; return;
} }

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -257,7 +257,7 @@ xglClearVisualTypes (void)
void void
xglInitPixmapFormats (ScreenPtr pScreen) xglInitPixmapFormats (ScreenPtr pScreen)
{ {
glitz_format_t *format; glitz_format_t *format, **best;
int i, j; int i, j;
XGL_SCREEN_PRIV (pScreen); XGL_SCREEN_PRIV (pScreen);
@ -275,6 +275,7 @@ xglInitPixmapFormats (ScreenPtr pScreen)
pScreenPriv->pixmapFormats[i].pPixel = &xglPixelFormats[j]; pScreenPriv->pixmapFormats[i].pPixel = &xglPixelFormats[j];
pScreenPriv->pixmapFormats[i].format = NULL; pScreenPriv->pixmapFormats[i].format = NULL;
best = &pScreenPriv->pixmapFormats[i].format;
rs = Ones (xglPixelFormats[j].masks.red_mask); rs = Ones (xglPixelFormats[j].masks.red_mask);
gs = Ones (xglPixelFormats[j].masks.green_mask); gs = Ones (xglPixelFormats[j].masks.green_mask);
@ -287,13 +288,28 @@ xglInitPixmapFormats (ScreenPtr pScreen)
0, NULL, k++); 0, NULL, k++);
if (format && format->type == GLITZ_FORMAT_TYPE_COLOR) if (format && format->type == GLITZ_FORMAT_TYPE_COLOR)
{ {
if (rs == format->color.red_size && /* formats must have an alpha channel, otherwise
gs == format->color.green_size && filtering wont match the render spec. */
bs == format->color.blue_size && if (!format->color.alpha_size)
as == 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; if (*best)
break; {
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); } while (format);

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -49,22 +49,24 @@ static glitz_operator_t xglOperators[] = {
#define XGL_OPERATOR(op) (xglOperators[op]) #define XGL_OPERATOR(op) (xglOperators[op])
Bool Bool
xglComp (CARD8 op, xglComp (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
PicturePtr pMask, PicturePtr pMask,
PicturePtr pDst, PicturePtr pDst,
INT16 xSrc, INT16 xSrc,
INT16 ySrc, INT16 ySrc,
INT16 xMask, INT16 xMask,
INT16 yMask, INT16 yMask,
INT16 xDst, INT16 xDst,
INT16 yDst, INT16 yDst,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height,
xglGeometryPtr pGeometry,
glitz_surface_t *mask)
{ {
ScreenPtr pScreen = pDst->pDrawable->pScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen;
xglPixmapPtr pSrcPriv, pMaskPriv; xglPixmapPtr pSrcPriv;
glitz_surface_t *dst; glitz_surface_t *src, *dst;
int dstXoff, dstYoff; int dstXoff, dstYoff;
RegionRec region; RegionRec region;
BoxPtr pBox; BoxPtr pBox;
@ -78,24 +80,21 @@ xglComp (CARD8 op,
if (op >= NUM_XGL_OPERATORS) if (op >= NUM_XGL_OPERATORS)
return FALSE; return FALSE;
if (pSrc->pDrawable->type != DRAWABLE_PIXMAP) if (pSrc->pDrawable->type != DRAWABLE_PIXMAP)
return FALSE; return FALSE;
if (pSrc->pDrawable->bitsPerPixel == 1)
return FALSE;
if (pMask) if (pMask)
{ {
if (pMask->pDrawable->type != DRAWABLE_PIXMAP) if (pMask->pDrawable->type != DRAWABLE_PIXMAP)
return FALSE; return FALSE;
/* if (pSrc->pDrawable == pMask->pDrawable && pSrc != pMask)
* Why?
*/
if (pSrc->pDrawable == pMask->pDrawable)
return FALSE; return FALSE;
} }
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xSrc, ySrc, xMask, yMask,
@ -105,29 +104,6 @@ xglComp (CARD8 op,
pBox = REGION_RECTS (&region); pBox = REGION_RECTS (&region);
nBox = REGION_NUM_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)) if (!xglPrepareTarget (pDst->pDrawable))
{ {
REGION_UNINIT (pScreen, &region); REGION_UNINIT (pScreen, &region);
@ -135,116 +111,159 @@ xglComp (CARD8 op,
} }
XGL_GET_DRAWABLE (pDst->pDrawable, dst, dstXoff, dstYoff); XGL_GET_DRAWABLE (pDst->pDrawable, dst, dstXoff, dstYoff);
if (!xglSyncSurface (pSrc->pDrawable)) if (!xglSyncSurface (pSrc->pDrawable))
{ {
REGION_UNINIT (pScreen, &region); REGION_UNINIT (pScreen, &region);
return FALSE; return FALSE;
} }
pSrcPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable); pSrcPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable);
if (XGL_PICTURE_CHANGES (pSrcPriv->pictureMask)) if (XGL_PICTURE_CHANGES (pSrcPriv->pictureMask))
xglUpdatePicture (pSrc); xglUpdatePicture (pSrc);
if (pMask) src = pSrcPriv->surface;
{
if (!xglSyncSurface (pMask->pDrawable))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pMaskPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pMask->pDrawable);
if (XGL_PICTURE_CHANGES (pMaskPriv->pictureMask))
xglUpdatePicture (pMask);
} else
pMaskPriv = NULL;
if (nBox > 1)
{
xglGeometryRec geometry;
GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (&region) << 3);
GEOMETRY_ADD_BOX (pScreen, &geometry, pBox, nBox);
GEOMETRY_TRANSLATE (&geometry, dstXoff, dstYoff);
if (!GEOMETRY_ENABLE_ALL_VERTICES (&geometry, dst))
{
GEOMETRY_UNINIT (&geometry);
return FALSE;
}
pBox = REGION_EXTENTS (pScreen, &region);
} else
GEOMETRY_DISABLE (dst);
xSrc += pBox->x1 - xDst;
ySrc += pBox->y1 - yDst;
if (pMask) if (pMask)
{ {
xMask += pBox->x1 - xDst; xglPixmapPtr pMaskPriv;
yMask += pBox->y1 - yDst;
/* bitmap as mask */
if (pMask->pDrawable->bitsPerPixel == 1)
{
if (pGeometry)
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pGeometry =
xglPixmapToGeometry ((PixmapPtr) pMask->pDrawable,
xDst - xMask,
yDst - yMask);
if (!pGeometry)
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
}
else
{
if (!xglSyncSurface (pMask->pDrawable))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pMaskPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pMask->pDrawable);
if (XGL_PICTURE_CHANGES (pMaskPriv->pictureMask))
xglUpdatePicture (pMask);
mask = pMaskPriv->surface;
}
} }
xDst = pBox->x1;
yDst = pBox->y1;
width = pBox->x2 - pBox->x1;
height = pBox->y2 - pBox->y1;
REGION_UNINIT (pScreen, &region); if (!pGeometry)
/*
* Do software tile instead if hardware can't do it.
*/
if (pSrc->repeat && !pSrcPriv->acceleratedTile)
{ {
BoxRec box; if (!pSrc->transform && pSrc->filter != PictFilterConvolution)
{
if (pSrc->repeat)
{
/* tile */
if (!pSrcPriv->acceleratedTile &&
(pSrc->pDrawable->width > 1 ||
pSrc->pDrawable->height > 1))
{
pGeometry =
xglTiledBoxGeometry ((PixmapPtr) pSrc->pDrawable,
xSrc - xDst, ySrc - yDst,
pBox, nBox);
if (!pGeometry)
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
pBox = REGION_EXTENTS (pScreen, &region);
nBox = 1;
}
}
else
{
/* copy */
if (op == PictOpSrc && !mask)
{
if (xglCopy (pSrc->pDrawable,
pDst->pDrawable,
xSrc - xDst,
ySrc - yDst,
pBox,
nBox))
{
REGION_UNINIT (pScreen, &region);
return TRUE;
}
}
}
}
if (pSrc->transform || pSrc->filter > 1) if (nBox > 1)
return FALSE; {
pGeometry = xglGetScratchVertexGeometry (pScreen, 4 * nBox);
GEOMETRY_ADD_BOX (pScreen, pGeometry, pBox, nBox);
pBox = REGION_EXTENTS (pScreen, &region);
}
xSrc += pBox->x1 - xDst;
ySrc += pBox->y1 - yDst;
if (pMask)
{
xMask += pBox->x1 - xDst;
yMask += pBox->y1 - yDst;
}
/* xDst = pBox->x1;
* Don't allow software tile with really small pixmaps. yDst = pBox->y1;
*/
if (pSrc->pDrawable->width < 8 && pSrc->pDrawable->height < 8) width = pBox->x2 - pBox->x1;
return FALSE; height = pBox->y2 - pBox->y1;
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 else
{ {
glitz_composite (XGL_OPERATOR (op), glitz_surface_set_clip_region (dst,
pSrcPriv->surface, dstXoff, dstYoff,
(pMaskPriv)? pMaskPriv->surface: NULL, (glitz_box_t *) pBox, nBox);
dst,
xSrc, ySrc,
xMask, yMask,
xDst + dstXoff, yDst + dstYoff,
width, height);
} }
if (pGeometry)
{
GEOMETRY_TRANSLATE (pGeometry, dstXoff, dstYoff);
if (!GEOMETRY_ENABLE (pGeometry, dst))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
} else
GEOMETRY_DISABLE (dst);
glitz_composite (XGL_OPERATOR (op),
src, mask, dst,
xSrc, ySrc,
xMask, yMask,
xDst + dstXoff, yDst + dstYoff,
width, height);
glitz_surface_set_clip_region (dst, 0, 0, NULL, 0);
REGION_UNINIT (pScreen, &region);
if (glitz_surface_get_status (dst)) if (glitz_surface_get_status (dst))
return FALSE; return FALSE;
xglAddBitDamage (pDst->pDrawable);
return TRUE; return TRUE;
} }

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
#include "fb.h"
Bool Bool
xglCopy (DrawablePtr pSrc, xglCopy (DrawablePtr pSrc,
@ -33,101 +34,59 @@ xglCopy (DrawablePtr pSrc,
BoxPtr pBox, BoxPtr pBox,
int nBox) int nBox)
{ {
glitz_surface_t *srcSurface; glitz_surface_t *src, *dst;
glitz_surface_t *dstSurface;
int srcXoff, srcYoff; int srcXoff, srcYoff;
int dstXoff, dstYoff; int dstXoff, dstYoff;
if (!nBox)
return TRUE;
if (xglPrepareTarget (pDst)) if (xglPrepareTarget (pDst))
{ {
glitz_drawable_t *srcDrawable;
glitz_drawable_t *dstDrawable;
XGL_SCREEN_PRIV (pDst->pScreen); XGL_SCREEN_PRIV (pDst->pScreen);
XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
if (!xglSyncSurface (pSrc)) if (!xglSyncSurface (pSrc))
return FALSE; return FALSE;
XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff); XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
/* /* blit to screen */
* Blit to screen. if (dst == pScreenPriv->surface)
*/
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)
{ {
xglGeometryRec geometry; XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
BoxRec extents;
BOX_EXTENTS (pBox, nBox, &extents);
GEOMETRY_INIT (pDst->pScreen, &geometry, nBox << 3); XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 5000);
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;
} }
} }
else else
{ {
if (!xglPrepareTarget (pSrc)) if (!xglPrepareTarget (pSrc))
return FALSE; return FALSE;
if (!xglSyncSurface (pDst)) if (!xglSyncSurface (pDst))
return FALSE; return FALSE;
XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff);
XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
}
while (nBox--)
{
glitz_copy_area (srcSurface,
dstSurface,
pBox->x1 + dx + srcXoff,
pBox->y1 + dy + srcYoff,
pBox->x2 - pBox->x1,
pBox->y2 - pBox->y1,
pBox->x1 + dstXoff,
pBox->y1 + dstYoff);
pBox++; XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
} }
if (glitz_surface_get_status (dstSurface)) XGL_GET_DRAWABLE (pSrc, src, srcXoff, srcYoff);
glitz_surface_set_clip_region (dst,
dstXoff, dstYoff,
(glitz_box_t *) pBox, nBox);
glitz_copy_area (src,
dst,
pDst->x + srcXoff + dx,
pDst->y + srcYoff + dy,
pDst->width,
pDst->height,
pDst->x + dstXoff,
pDst->y + dstYoff);
glitz_surface_set_clip_region (dst, 0, 0, NULL, 0);
if (glitz_surface_get_status (dst))
return FALSE; return FALSE;
return TRUE; return TRUE;
@ -146,7 +105,59 @@ xglCopyProc (DrawablePtr pSrc,
Pixel bitplane, Pixel bitplane,
void *closure) 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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
#include "gcstruct.h" #include "gcstruct.h"
#include "fb.h"
Bool Bool
xglFill (DrawablePtr pDrawable, xglFill (DrawablePtr pDrawable,
GCPtr pGC, GCPtr pGC,
xglGeometryPtr pGeometry) xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox,
int nBox)
{ {
XGL_GC_PRIV (pGC); XGL_GC_PRIV (pGC);
switch (pGC->fillStyle) { switch (pGC->fillStyle) {
case FillSolid: case FillSolid:
if (xglSolid (pDrawable, pGCPriv->op, &pGCPriv->fg, if (xglSolid (pDrawable,
pGCPriv->op, &pGCPriv->fg,
pGeometry, pGeometry,
REGION_RECTS (pGC->pCompositeClip), x, y,
REGION_NUM_RECTS (pGC->pCompositeClip))) width, height,
pBox, nBox))
return TRUE; return TRUE;
break; break;
case FillStippled: case FillStippled:
case FillOpaqueStippled: case FillOpaqueStippled:
break; break;
case FillTiled: case FillTiled:
if (xglTile (pDrawable, pGCPriv->op, pGC->tile.pixmap, if (xglTile (pDrawable,
-pGC->patOrg.x, -pGC->patOrg.y, pGCPriv->op, pGC->tile.pixmap,
-(pGC->patOrg.x + pDrawable->x),
-(pGC->patOrg.y + pDrawable->y),
pGeometry, pGeometry,
REGION_RECTS (pGC->pCompositeClip), x, y,
REGION_NUM_RECTS (pGC->pCompositeClip))) width, height,
pBox, nBox))
return TRUE; return TRUE;
break; break;
} }
@ -57,26 +69,163 @@ xglFill (DrawablePtr pDrawable,
return FALSE; 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, xglFillRect (DrawablePtr pDrawable,
GCPtr pGC, GCPtr pGC,
int nrect, int nrect,
xRectangle *prect) 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); while (nrect--)
GEOMETRY_ADD_RECT (pGC->pScreen, &geometry, prect, nrect);
GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
if (xglFill (pDrawable, pGC, &geometry))
{ {
GEOMETRY_UNINIT (&geometry); full.x1 = prect->x + pDrawable->x;
return TRUE; full.y1 = prect->y + pDrawable->y;
} full.x2 = full.x1 + (int) prect->width;
full.y2 = full.y1 + (int) prect->height;
prect++;
if (full.x1 < pExtent->x1)
full.x1 = pExtent->x1;
if (full.y1 < pExtent->y1)
full.y1 = pExtent->y1;
if (full.x2 > pExtent->x2)
full.x2 = pExtent->x2;
if (full.y2 > pExtent->y2)
full.y2 = pExtent->y2;
if (full.x1 >= full.x2 || full.y1 >= full.y2)
continue;
n = REGION_NUM_RECTS (pClip);
if (n == 1)
{
ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
}
else
{
pClipBox = REGION_RECTS (pClip);
while (n--)
{
part.x1 = pClipBox->x1;
if (part.x1 < full.x1)
part.x1 = full.x1;
part.y1 = pClipBox->y1;
if (part.y1 < full.y1)
part.y1 = full.y1;
part.x2 = pClipBox->x2;
if (part.x2 > full.x2)
part.x2 = full.x2;
part.y2 = pClipBox->y2;
if (part.y2 > full.y2)
part.y2 = full.y2;
GEOMETRY_UNINIT (&geometry); pClipBox++;
return FALSE;
if (part.x1 < part.x2 && part.y1 < part.y2)
ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
}
}
}
pBox = (heapBox) ? heapBox : stackBox;
if (!xglFill (pDrawable, pGC, NULL,
pExtent->x1, pExtent->y1,
pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
pBox, nBox))
{
RegionRec region;
Bool overlap;
XGL_DRAWABLE_PIXMAP (pDrawable);
if (!xglMapPixmapBits (pPixmap))
FatalError (XGL_SW_FAILURE_STRING);
switch (pGC->fillStyle) {
case FillSolid:
break;
case FillStippled:
case FillOpaqueStippled:
if (!xglSyncBits (&pGC->stipple->drawable, NullBox))
FatalError (XGL_SW_FAILURE_STRING);
break;
case FillTiled:
if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox))
FatalError (XGL_SW_FAILURE_STRING);
break;
}
REGION_INIT (pGC->pScreen, &region, pBox, nBox);
while (nBox--)
{
fbFill (pDrawable, pGC,
pBox->x1, pBox->y1,
pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
pBox++;
}
/* hmm, overlap can't be good, don't know what to do about that */
REGION_VALIDATE (pGC->pScreen, &region, &overlap);
xglAddSurfaceDamage (pDrawable, &region);
REGION_UNINIT (pGC->pScreen, &region);
} else
xglAddCurrentBitDamage (pDrawable);
if (heapBox)
xfree (heapBox);
} }
Bool Bool
@ -86,23 +235,26 @@ xglFillSpan (DrawablePtr pDrawable,
DDXPointPtr ppt, DDXPointPtr ppt,
int *pwidth) int *pwidth)
{ {
xglGeometryRec geometry; BoxPtr pExtent;
xglGeometryPtr pGeometry;
GEOMETRY_INIT (pGC->pScreen, &geometry, n << 2); pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
GEOMETRY_ADD_SPAN (pGC->pScreen, &geometry, ppt, pwidth, n);
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 */ /* Spans are treated as lines so they need a 0.5 translate */
GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15); GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry, GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
GLITZ_GEOMETRY_PRIMITIVE_LINES);
if (xglFill (pDrawable, pGC, &geometry)) if (xglFill (pDrawable, pGC, pGeometry,
{ pExtent->x1, pExtent->y1,
GEOMETRY_UNINIT (&geometry); pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE; return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE; return FALSE;
} }
@ -113,9 +265,12 @@ xglFillLine (DrawablePtr pDrawable,
int npt, int npt,
DDXPointPtr ppt) DDXPointPtr ppt)
{ {
xglGeometryRec geometry; BoxPtr pExtent;
xglGeometryPtr pGeometry;
Bool coincident_endpoints; Bool coincident_endpoints;
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
coincident_endpoints = FALSE; coincident_endpoints = FALSE;
if (mode == CoordModePrevious) if (mode == CoordModePrevious)
{ {
@ -148,29 +303,30 @@ xglFillLine (DrawablePtr pDrawable,
if (coincident_endpoints) if (coincident_endpoints)
npt--; npt--;
GEOMETRY_INIT (pGC->pScreen, &geometry, npt << 1); pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, npt);
GEOMETRY_ADD_LINE (pGC->pScreen, &geometry,
GEOMETRY_ADD_LINE (pGC->pScreen, pGeometry,
coincident_endpoints, mode, npt, ppt); coincident_endpoints, mode, npt, ppt);
if (coincident_endpoints) if (coincident_endpoints)
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry, GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_LOOP);
GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP);
else else
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry, GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_STRIP);
GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP);
/* Lines need a 0.5 translate */ /* Lines need a 0.5 translate */
GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15); GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y); GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
if (xglFill (pDrawable, pGC, &geometry)) if (xglFill (pDrawable, pGC, pGeometry,
{ pExtent->x1, pExtent->y1,
GEOMETRY_UNINIT (&geometry); pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE; return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE; return FALSE;
} }
@ -180,19 +336,65 @@ xglFillSegment (DrawablePtr pDrawable,
int nsegInit, int nsegInit,
xSegment *pSegInit) xSegment *pSegInit)
{ {
xglGeometryRec geometry; BoxPtr pExtent;
xglGeometryPtr pGeometry;
GEOMETRY_INIT (pGC->pScreen, &geometry, nsegInit << 2); pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
GEOMETRY_ADD_SEGMENT (pGC->pScreen, &geometry, nsegInit, pSegInit);
pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * nsegInit);
GEOMETRY_ADD_SEGMENT (pGC->pScreen, pGeometry, nsegInit, pSegInit);
/* Line segments need 0.5 translate */ /* Line segments need 0.5 translate */
GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15); GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry, GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
GLITZ_GEOMETRY_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); GEOMETRY_UNINIT (&geometry);
return TRUE; return TRUE;

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -36,7 +36,7 @@
#define XGL_GC_OP_FALLBACK_EPILOGUE(pDrawable) \ #define XGL_GC_OP_FALLBACK_EPILOGUE(pDrawable) \
XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs); \ XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs); \
XGL_GC_WRAP (ops, (GCOps *) &xglGCOps); \ XGL_GC_WRAP (ops, (GCOps *) &xglGCOps); \
xglAddSurfaceDamage (pDrawable) xglAddCurrentSurfaceDamage (pDrawable)
#define XGL_GC_FILL_OP_FALLBACK_PROLOGUE(pDrawable) \ #define XGL_GC_FILL_OP_FALLBACK_PROLOGUE(pDrawable) \
switch (pGC->fillStyle) { \ switch (pGC->fillStyle) { \
@ -104,7 +104,7 @@ xglFillSpans (DrawablePtr pDrawable,
{ {
if (xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth)) if (xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth))
{ {
xglAddBitDamage (pDrawable); xglAddCurrentBitDamage (pDrawable);
return; return;
} }
} }
@ -144,38 +144,45 @@ xglPutImage (DrawablePtr pDrawable,
{ {
XGL_GC_PRIV (pGC); XGL_GC_PRIV (pGC);
switch (format) { if (pGC->alu != GXcopy || (pGCPriv->flags & xglGCPlaneMaskFlag))
case XYBitmap: {
break; XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
case XYPixmap: (*pGC->ops->PutImage) (pDrawable, pGC, depth,
case ZPixmap: x, y, w, h, leftPad, format, bits);
if (!pGCPriv->flags) XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
{ }
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable); else
{
if (!pPixmapPriv->allBits && RegionPtr pClip = pGC->pCompositeClip;
pPixmapPriv->target == xglPixmapTargetIn) RegionRec region;
{ BoxRec box;
if (xglSetPixels (pDrawable,
bits, XGL_DRAWABLE_PIXMAP (pDrawable);
PixmapBytePad (w, pDrawable->depth),
x + pDrawable->x, y + pDrawable->y, if (!xglMapPixmapBits (pPixmap))
w, h, FatalError (XGL_SW_FAILURE_STRING);
REGION_RECTS (pGC->pCompositeClip),
REGION_NUM_RECTS (pGC->pCompositeClip))) XGL_GC_UNWRAP (funcs);
{ XGL_GC_UNWRAP (ops);
xglAddBitDamage (pDrawable);
return; (*pGC->ops->PutImage) (pDrawable, pGC, depth,
} x, y, w, h, leftPad, format, bits);
}
} XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
break; XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
box.x1 = pDrawable->x + x;
box.y1 = pDrawable->y + y;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
REGION_INIT (pDrawable->pScreen, &region, &box, 1);
REGION_INTERSECT (pDrawable->pScreen, &region, pClip, &region);
xglAddSurfaceDamage (pDrawable, &region);
REGION_UNINIT (pDrawable->pScreen, &region);
} }
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PutImage) (pDrawable, pGC, depth,
x, y, w, h, leftPad, format, bits);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} }
RegionPtr RegionPtr
@ -195,45 +202,37 @@ xglCopyArea (DrawablePtr pSrc,
XGL_GC_PRIV (pGC); XGL_GC_PRIV (pGC);
box.x1 = pSrc->x + srcX;
box.y1 = pSrc->y + srcY;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
flags = pGCPriv->flags; flags = pGCPriv->flags;
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (pSrc)->target == xglPixmapTargetIn) if (XGL_GET_DRAWABLE_PIXMAP_PRIV (pSrc)->target == xglPixmapTargetIn)
flags &= ~xglGCReadOnlyDrawableFlag; flags &= ~xglGCReadOnlyDrawableFlag;
if (!flags) if (flags)
{ {
Bool ret; if (!xglSyncBits (pSrc, &box))
FatalError (XGL_SW_FAILURE_STRING);
ret = TRUE;
XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
srcX, srcY, w, h, dstX, dstY);
XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
}
else
{
/* xglCopyProc handles fall-back */
pRegion = fbDoCopy (pSrc, pDst, pGC, pRegion = fbDoCopy (pSrc, pDst, pGC,
srcX, srcY, srcX, srcY,
w, h, w, h,
dstX, dstY, dstX, dstY,
xglCopyProc, 0, xglCopyProc, 0,
(void *) &ret); (void *) &box);
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;
if (!xglSyncBits (pSrc, &box))
FatalError (XGL_SW_FAILURE_STRING);
XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
srcX, srcY, w, h, dstX, dstY);
XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
return pRegion; return pRegion;
} }
@ -302,13 +301,13 @@ xglPolylines (DrawablePtr pDrawable,
{ {
if (xglFillLine (pDrawable, pGC, mode, npt, ppt)) if (xglFillLine (pDrawable, pGC, mode, npt, ppt))
{ {
xglAddBitDamage (pDrawable); xglAddCurrentBitDamage (pDrawable);
return; return;
} }
} }
} }
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable); XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppt); (*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppt);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable); XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} }
@ -337,13 +336,13 @@ xglPolySegment (DrawablePtr pDrawable,
{ {
if (xglFillSegment (pDrawable, pGC, nsegInit, pSegInit)) if (xglFillSegment (pDrawable, pGC, nsegInit, pSegInit))
{ {
xglAddBitDamage (pDrawable); xglAddCurrentBitDamage (pDrawable);
return; return;
} }
} }
} }
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable); XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolySegment) (pDrawable, pGC, nsegInit, pSegInit); (*pGC->ops->PolySegment) (pDrawable, pGC, nsegInit, pSegInit);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable); XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} else } else
@ -360,7 +359,7 @@ xglPolyArc (DrawablePtr pDrawable,
{ {
XGL_GC_PRIV (pGC); XGL_GC_PRIV (pGC);
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable); XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyArc) (pDrawable, pGC, narcs, pArcs); (*pGC->ops->PolyArc) (pDrawable, pGC, narcs, pArcs);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable); XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} else } else
@ -375,18 +374,17 @@ xglPolyFillRect (DrawablePtr pDrawable,
{ {
XGL_GC_PRIV (pGC); XGL_GC_PRIV (pGC);
if (!pGCPriv->flags) if (pGCPriv->flags || pGC->fillStyle == FillStippled)
{ {
if (xglFillRect (pDrawable, pGC, nrect, prect)) XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
{ (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
xglAddBitDamage (pDrawable); XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
return; }
} else
{
/* xglFillRect handles fall-back */
xglFillRect (pDrawable, pGC, nrect, prect);
} }
XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} }
void void
@ -412,7 +410,22 @@ xglImageGlyphBlt (DrawablePtr pDrawable,
pointer pglyphBase) pointer pglyphBase)
{ {
XGL_GC_PRIV (pGC); 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); XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase); pglyphBase);
@ -429,8 +442,23 @@ xglPolyGlyphBlt (DrawablePtr pDrawable,
pointer pglyphBase) pointer pglyphBase)
{ {
XGL_GC_PRIV (pGC); XGL_GC_PRIV (pGC);
if (!pGCPriv->flags)
{
if (xglFillGlyph (pDrawable,
pGC,
x,
y,
nglyph,
ppci,
pglyphBase))
{
xglAddCurrentBitDamage (pDrawable);
return;
}
}
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable); XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable); XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} }
@ -486,6 +514,20 @@ xglValidateGC (GCPtr pGC,
{ {
XGL_GC_PRIV (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 (funcs);
XGL_GC_UNWRAP (ops); XGL_GC_UNWRAP (ops);
(*pGC->funcs->ValidateGC) (pGC, changes, pDrawable); (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
#include "fontstruct.h"
#include "dixfontstr.h"
struct xglDataTypeInfo { xglDataTypeInfoRec xglGeometryDataTypes[2] = {
glitz_data_type_t type;
int size;
} dataTypes[] = {
{ GLITZ_DATA_TYPE_SHORT, sizeof (glitz_short_t) }, { GLITZ_DATA_TYPE_SHORT, sizeof (glitz_short_t) },
{ GLITZ_DATA_TYPE_FLOAT, sizeof (glitz_float_t) } { GLITZ_DATA_TYPE_FLOAT, sizeof (glitz_float_t) }
}; };
@ -45,19 +44,17 @@ xglGeometryResize (ScreenPtr pScreen,
int size) int size)
{ {
XGL_SCREEN_PRIV (pScreen); XGL_SCREEN_PRIV (pScreen);
if (pGeometry->broken)
return;
if (size == pGeometry->size) if (size == pGeometry->size)
return; return;
if (pGeometry->usage == GEOMETRY_USAGE_USERMEM) if (pGeometry->broken)
{ return;
pGeometry->data =
xrealloc (pGeometry->data,
size * dataTypes[pGeometry->dataType].size);
if (pGeometry->usage == GEOMETRY_USAGE_SYSMEM)
{
pGeometry->data = xrealloc (pGeometry->data, size);
if (pGeometry->buffer) if (pGeometry->buffer)
glitz_buffer_destroy (pGeometry->buffer); glitz_buffer_destroy (pGeometry->buffer);
@ -81,16 +78,11 @@ xglGeometryResize (ScreenPtr pScreen,
else else
{ {
glitz_buffer_t *newBuffer; glitz_buffer_t *newBuffer;
int dataTypeSize;
dataTypeSize = dataTypes[pGeometry->dataType].size;
if (size) if (size)
{ {
newBuffer = newBuffer =
glitz_geometry_buffer_create (pScreenPriv->drawable, NULL, glitz_vertex_buffer_create (pScreenPriv->drawable, NULL, size,
size * dataTypeSize, usageTypes[pGeometry->usage]);
usageTypes[pGeometry->usage]);
if (!newBuffer) if (!newBuffer)
{ {
pGeometry->broken = TRUE; pGeometry->broken = TRUE;
@ -109,8 +101,7 @@ xglGeometryResize (ScreenPtr pScreen,
GLITZ_BUFFER_ACCESS_WRITE_ONLY); GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (oldData && newData) if (oldData && newData)
memcpy (newData, oldData, memcpy (newData, oldData, MIN (size, pGeometry->size));
MIN (size, pGeometry->size) * dataTypeSize);
glitz_buffer_unmap (pGeometry->buffer); glitz_buffer_unmap (pGeometry->buffer);
glitz_buffer_unmap (newBuffer); glitz_buffer_unmap (newBuffer);
@ -126,103 +117,39 @@ xglGeometryResize (ScreenPtr pScreen,
pGeometry->endOffset = size; pGeometry->endOffset = size;
} }
/* #define MAP_GEOMETRY(pScreen, pGeometry, offset, units, ptr, _size) \
* Storage for 100 extra vertices are always allocated if if ((pGeometry)->broken) \
* buffer size is to small. Geometry should be initialized return; \
* to desired size prior to calling this function when size (_size) = (units) * xglGeometryDataTypes[(pGeometry)->dataType].size; \
* is known. if (((pGeometry)->size - (offset)) < (_size)) \
*/ { \
#define RESIZE_GEOMETRY_FOR_VERTICES(pScreen, pGeometry, nvertices) \ xglGeometryResize (pScreen, pGeometry, \
if (((pGeometry)->size - (pGeometry)->endOffset) < ((nvertices) << 1)) \ (pGeometry)->endOffset + (_size) + 500); \
if ((pGeometry)->broken) \
return; \
} \
(ptr) = glitz_buffer_map ((pGeometry)->buffer, \
GLITZ_BUFFER_ACCESS_WRITE_ONLY); \
if (!(ptr)) \
{ \
(pGeometry)->broken = TRUE; \
return; \
} \
(ptr) += (offset)
#define UNMAP_GEOMETRY(pGeometry, offset, _size) \
if (glitz_buffer_unmap ((pGeometry)->buffer)) \
{ \ { \
xglGeometryResize (pScreen, pGeometry, \ (pGeometry)->broken = TRUE; \
(pGeometry)->endOffset + \ return; \
((nvertices) << 1) + 200); \ } \
if ((pGeometry)->broken) \ if (((offset) + (_size)) > (pGeometry)->endOffset) \
return; \ { \
} (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 * Adds a number of boxes as GL_QUAD primitives
*/ */
@ -230,124 +157,88 @@ void
xglGeometryAddBox (ScreenPtr pScreen, xglGeometryAddBox (ScreenPtr pScreen,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
BoxPtr pBox, BoxPtr pBox,
int nBox) int nBox,
int offset)
{ {
int nvertices; int size;
void *ptr; char *ptr;
if (pGeometry->broken)
return;
if (nBox < 1) if (nBox < 1)
return; return;
nvertices = nBox << 2; MAP_GEOMETRY (pScreen, pGeometry, offset, nBox * 8, ptr, size);
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (nBox--)
{
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y2;
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y2;
pBox++;
}
} break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (nBox--)
{
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y2;
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y2;
pBox++;
}
} break;
}
if (glitz_buffer_unmap (pGeometry->buffer))
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
}
/*
* Adds a number of spans as GL_LINE primitives
*
* An extra 1 is added to *pwidth as OpenGL line segments are half-opened.
*/
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
int n)
{
int nvertices;
void *ptr;
if (pGeometry->broken)
return;
if (n < 1)
return;
nvertices = n << 1;
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
switch (pGeometry->dataType) { switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT: case GEOMETRY_DATA_TYPE_SHORT:
{ {
glitz_short_t *data = (glitz_short_t *) ptr; glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset; while (nBox--)
{
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y1;
*data++ = (glitz_short_t) pBox->x2;
*data++ = (glitz_short_t) pBox->y2;
*data++ = (glitz_short_t) pBox->x1;
*data++ = (glitz_short_t) pBox->y2;
pBox++;
}
} break;
case GEOMETRY_DATA_TYPE_FLOAT:
{
glitz_float_t *data = (glitz_float_t *) ptr;
while (nBox--)
{
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y1;
*data++ = (glitz_float_t) pBox->x2;
*data++ = (glitz_float_t) pBox->y2;
*data++ = (glitz_float_t) pBox->x1;
*data++ = (glitz_float_t) pBox->y2;
pBox++;
}
} break;
}
UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
* Adds a number of spans as GL_LINE primitives
*/
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
int n,
int offset)
{
int size;
char *ptr;
if (n < 1)
return;
MAP_GEOMETRY (pScreen, pGeometry, offset, n * 4, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
while (n--) while (n--)
{ {
*data++ = (glitz_short_t) ppt->x; *data++ = (glitz_short_t) ppt->x;
*data++ = (glitz_short_t) ppt->y; *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; *data++ = (glitz_short_t) ppt->y;
ppt++; ppt++;
@ -358,13 +249,11 @@ xglGeometryAddSpan (ScreenPtr pScreen,
{ {
glitz_float_t *data = (glitz_float_t *) ptr; glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (n--) while (n--)
{ {
*data++ = (glitz_float_t) ppt->x; *data++ = (glitz_float_t) ppt->x;
*data++ = (glitz_float_t) ppt->y; *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; *data++ = (glitz_float_t) ppt->y;
ppt++; ppt++;
@ -372,14 +261,8 @@ xglGeometryAddSpan (ScreenPtr pScreen,
} }
} break; } break;
} }
if (glitz_buffer_unmap (pGeometry->buffer)) UNMAP_GEOMETRY (pGeometry, offset, size);
{
pGeometry->broken = TRUE;
return;
}
pGeometry->endOffset += (nvertices << 1);
} }
/* /*
@ -401,28 +284,17 @@ xglGeometryAddLine (ScreenPtr pScreen,
int loop, int loop,
int mode, int mode,
int npt, int npt,
DDXPointPtr ppt) DDXPointPtr ppt,
int offset)
{ {
DDXPointRec pt; DDXPointRec pt;
int nvertices; int size;
void *ptr; char *ptr;
if (pGeometry->broken)
return;
if (npt < 2) if (npt < 2)
return; return;
nvertices = npt; MAP_GEOMETRY (pScreen, pGeometry, offset, npt * 2, ptr, size);
RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (!ptr)
{
pGeometry->broken = TRUE;
return;
}
pt.x = 0; pt.x = 0;
pt.y = 0; pt.y = 0;
@ -432,8 +304,6 @@ xglGeometryAddLine (ScreenPtr pScreen,
{ {
glitz_short_t *data = (glitz_short_t *) ptr; glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (npt--) while (npt--)
{ {
if (mode == CoordModePrevious) if (mode == CoordModePrevious)
@ -447,19 +317,17 @@ xglGeometryAddLine (ScreenPtr pScreen,
pt.y = ppt->y; pt.y = ppt->y;
} }
*data++ = pt.x;
*data++ = pt.y;
if (npt || loop) if (npt || loop)
{ {
*data++ = pt.x; *data++ = (glitz_short_t) pt.x;
*data++ = pt.y; *data++ = (glitz_short_t) pt.y;
} }
else else
{ {
ppt--; ppt--;
*data++ = ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y); *data++ = (glitz_short_t)
*data++ = ADJUST_END_POINT (ppt->y, pt.y, 0); ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
*data++ = (glitz_short_t) ADJUST_END_POINT (ppt->y, pt.y, 0);
} }
ppt++; ppt++;
@ -469,8 +337,6 @@ xglGeometryAddLine (ScreenPtr pScreen,
{ {
glitz_float_t *data = (glitz_float_t *) ptr; glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (npt--) while (npt--)
{ {
if (mode == CoordModePrevious) if (mode == CoordModePrevious)
@ -501,14 +367,8 @@ xglGeometryAddLine (ScreenPtr pScreen,
} }
} break; } 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, xglGeometryAddSegment (ScreenPtr pScreen,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
int nsegInit, int nsegInit,
xSegment *pSegInit) xSegment *pSegInit,
int offset)
{ {
int nvertices; int size;
void *ptr; char *ptr;
if (pGeometry->broken)
return;
if (nsegInit < 1) if (nsegInit < 1)
return; return;
nvertices = nsegInit << 1; MAP_GEOMETRY (pScreen, pGeometry, offset, nsegInit * 4, ptr, size);
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) { switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT: case GEOMETRY_DATA_TYPE_SHORT:
{ {
glitz_short_t *data = (glitz_short_t *) ptr; glitz_short_t *data = (glitz_short_t *) ptr;
data += pGeometry->endOffset;
while (nsegInit--) while (nsegInit--)
{ {
*data++ = pSegInit->x1; *data++ = (glitz_short_t) pSegInit->x1;
*data++ = pSegInit->y1; *data++ = (glitz_short_t) pSegInit->y1;
*data++ = ADJUST_END_POINT (pSegInit->x1, pSegInit->x2, *data++ = (glitz_short_t)
pSegInit->y1 == pSegInit->y2); ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
*data++ = ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0); pSegInit->y1 == pSegInit->y2);
*data++ = (glitz_short_t)
ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
pSegInit++; pSegInit++;
} }
@ -562,8 +411,6 @@ xglGeometryAddSegment (ScreenPtr pScreen,
{ {
glitz_float_t *data = (glitz_float_t *) ptr; glitz_float_t *data = (glitz_float_t *) ptr;
data += pGeometry->endOffset;
while (nsegInit--) while (nsegInit--)
{ {
*data++ = (glitz_float_t) pSegInit->x1; *data++ = (glitz_float_t) pSegInit->x1;
@ -578,38 +425,299 @@ xglGeometryAddSegment (ScreenPtr pScreen,
} }
} break; } 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; pGeometry->broken = TRUE;
return; 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 Bool
xglSetGeometry (xglGeometryPtr pGeometry, xglSetGeometry (xglGeometryPtr pGeometry,
glitz_surface_t *surface, glitz_surface_t *surface)
int first,
int count)
{ {
glitz_geometry_format_t format;
if (pGeometry->broken) if (pGeometry->broken)
return FALSE; return FALSE;
format.first = first; glitz_set_geometry (surface, pGeometry->type, &pGeometry->f,
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,
pGeometry->buffer); 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; return TRUE;
} }

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -35,8 +35,10 @@ xglGetImage (DrawablePtr pDrawable,
unsigned long planeMask, unsigned long planeMask,
char *d) char *d)
{ {
ScreenPtr pScreen = pDrawable->pScreen; ScreenPtr pScreen = pDrawable->pScreen;
BoxRec box; glitz_surface_t *surface;
int xOff, yOff;
BoxRec box;
XGL_SCREEN_PRIV (pScreen); XGL_SCREEN_PRIV (pScreen);
@ -44,11 +46,13 @@ xglGetImage (DrawablePtr pDrawable,
if (pDrawable->type == DRAWABLE_WINDOW) if (pDrawable->type == DRAWABLE_WINDOW)
{ {
glitz_surface_flush (pScreenPriv->surface); glitz_surface_flush (pScreenPriv->surface);
glitz_drawable_flush (pScreenPriv->drawable); glitz_drawable_finish (pScreenPriv->drawable);
} }
box.x1 = x + pDrawable->x; XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
box.y1 = y + pDrawable->y;
box.x1 = pDrawable->x + xOff + x;
box.y1 = pDrawable->y + yOff + y;
box.x2 = box.x1 + w; box.x2 = box.x1 + w;
box.y2 = box.y1 + h; 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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #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[] = { static glitz_drawable_buffer_t _buffers[] = {
GLITZ_DRAWABLE_BUFFER_BACK_COLOR, GLITZ_DRAWABLE_BUFFER_BACK_COLOR,
GLITZ_DRAWABLE_BUFFER_FRONT_COLOR GLITZ_DRAWABLE_BUFFER_FRONT_COLOR
}; };
#define MAX_LEVEL 6 #define MAX_OFFSCREEN_LEVEL 8
static Bool static Bool
xglOffscreenMoveIn (xglOffscreenAreaPtr pArea, xglOffscreenCreate (xglAreaPtr pArea)
PixmapPtr pPixmap)
{ {
return TRUE;
}
static Bool
xglOffscreenMoveIn (xglAreaPtr pArea,
pointer closure)
{
xglOffscreenPtr pOffscreen = (xglOffscreenPtr) pArea->pRoot->closure;
PixmapPtr pPixmap = (PixmapPtr) closure;
XGL_PIXMAP_PRIV (pPixmap); XGL_PIXMAP_PRIV (pPixmap);
if (!xglSyncSurface (&pPixmap->drawable)) if (!xglSyncSurface (&pPixmap->drawable))
FatalError (XGL_SW_FAILURE_STRING); FatalError (XGL_SW_FAILURE_STRING);
pArea->pPixmapPriv = pPixmapPriv;
pArea->state = xglOffscreenAreaOccupied;
pPixmapPriv->pArea = pArea; pPixmapPriv->pArea = pArea;
pPixmapPriv->target = xglPixmapTargetIn; pPixmapPriv->target = xglPixmapTargetIn;
glitz_surface_attach (pPixmapPriv->surface, glitz_surface_attach (pPixmapPriv->surface,
pArea->pOffscreen->drawable, pOffscreen->drawable, pOffscreen->buffer,
pArea->pOffscreen->buffer,
pArea->x, pArea->y); pArea->x, pArea->y);
XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 500); XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 100);
return TRUE; return TRUE;
} }
static void static void
xglOffscreenMoveOut (xglOffscreenAreaPtr pArea) xglOffscreenMoveOut (xglAreaPtr pArea,
pointer closure)
{ {
glitz_surface_detach (pArea->pPixmapPriv->surface); PixmapPtr pPixmap = (PixmapPtr) closure;
pArea->pPixmapPriv->pArea = NULL; XGL_PIXMAP_PRIV (pPixmap);
pArea->pPixmapPriv->target = xglPixmapTargetOut;
pArea->pPixmapPriv = NULL;
pArea->state = xglOffscreenAreaAvailable;
}
static xglOffscreenAreaPtr
xglCreateOffscreenArea (xglOffscreenPtr pOffscreen,
int level,
int x,
int y)
{
xglOffscreenAreaPtr pArea;
int i;
pArea = xalloc (sizeof (xglOffscreenAreaRec));
if (!pArea)
return NULL;
pArea->level = level;
pArea->x = x;
pArea->y = y;
pArea->pOffscreen = pOffscreen;
pArea->pPixmapPriv = NULL;
pArea->state = xglOffscreenAreaAvailable;
for (i = 0; i < 4; i++)
pArea->pArea[i] = NULL;
return pArea;
}
static void
xglDestroyOffscreenArea (xglOffscreenAreaPtr pArea)
{
if (!pArea)
return;
if (pArea->pPixmapPriv)
{
xglOffscreenMoveOut (pArea);
}
else
{
int i;
for (i = 0; i < 4; i++) glitz_surface_detach (pPixmapPriv->surface);
xglDestroyOffscreenArea (pArea->pArea[i]);
}
xfree (pArea); pPixmapPriv->pArea = NULL;
} pPixmapPriv->target = xglPixmapTargetOut;
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);
} }
static int static int
xglOffscreenAreaGetTopScore (xglOffscreenAreaPtr pArea) xglOffscreenCompareScore (xglAreaPtr pArea,
pointer closure1,
pointer closure2)
{ {
int topScore; int s1, s2;
if (pArea->pPixmapPriv) XGL_PIXMAP_PRIV ((PixmapPtr) closure1);
{
topScore = pArea->pPixmapPriv->score; s1 = pPixmapPriv->score;
XGL_DECREMENT_PIXMAP_SCORE (pArea->pPixmapPriv, 5); s2 = XGL_GET_PIXMAP_PRIV ((PixmapPtr) closure2)->score;
return topScore; if (s1 > s2)
} XGL_DECREMENT_PIXMAP_SCORE (pPixmapPriv, 10);
else
{ return s1 - s2;
int topScore, score, i;
topScore = 0;
for (i = 0; i < 4; i++)
{
if (pArea->pArea[i])
{
score = xglOffscreenAreaGetTopScore (pArea->pArea[i]);
if (score > topScore)
topScore = score;
}
}
return topScore;
}
} }
static const xglAreaFuncsRec xglOffscreenAreaFuncs = {
static Bool xglOffscreenCreate,
xglOffscreenFindArea (xglOffscreenAreaPtr pArea, xglOffscreenMoveIn,
PixmapPtr pPixmap, xglOffscreenMoveOut,
int level) xglOffscreenCompareScore
{ };
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;
}
Bool Bool
xglInitOffscreen (ScreenPtr pScreen, xglInitOffscreen (ScreenPtr pScreen,
xglScreenInfoPtr pScreenInfo) xglScreenInfoPtr pScreenInfo)
{ {
xglOffscreenPtr pOffscreen; xglOffscreenPtr pOffscreen;
int nOffscreen;
glitz_drawable_format_t *format; glitz_drawable_format_t *format;
XGL_SCREEN_PRIV (pScreen); XGL_SCREEN_PRIV (pScreen);
pScreenPriv->pOffscreen = NULL; pOffscreen = pScreenPriv->pOffscreen;
pScreenPriv->nOffscreen = 0; pScreenPriv->nOffscreen = 0;
format = glitz_drawable_get_format (pScreenPriv->drawable); format = glitz_drawable_get_format (pScreenPriv->drawable);
@ -301,33 +121,32 @@ xglInitOffscreen (ScreenPtr pScreen,
*/ */
if (format->doublebuffer) if (format->doublebuffer)
{ {
pScreenPriv->pOffscreen = pOffscreen->drawable = pScreenPriv->drawable;
xrealloc (pScreenPriv->pOffscreen, pOffscreen->format = format;
sizeof (xglOffscreenRec) * pOffscreen->buffer = GLITZ_DRAWABLE_BUFFER_BACK_COLOR;
(pScreenPriv->nOffscreen + 1));
if (pScreenPriv->pOffscreen) if (xglRootAreaInit (&pOffscreen->rootArea,
MAX_OFFSCREEN_LEVEL,
pScreenInfo->width,
pScreenInfo->height, 0,
(xglAreaFuncsPtr) &xglOffscreenAreaFuncs,
(pointer) pOffscreen))
{ {
pOffscreen = &pScreenPriv->pOffscreen[pScreenPriv->nOffscreen]; glitz_drawable_reference (pOffscreen->drawable);
if (xglOffscreenInit (pOffscreen, pScreenPriv->nOffscreen++;
pScreenPriv->drawable, pOffscreen++;
GLITZ_DRAWABLE_BUFFER_BACK_COLOR, ErrorF ("Initialized %dx%d back buffer offscreen area\n",
pScreenInfo->width, pScreenInfo->height)) pScreenInfo->width, pScreenInfo->height);
{
pScreenPriv->nOffscreen++;
ErrorF ("Initialized %dx%d back buffer offscreen area\n",
pScreenInfo->width, pScreenInfo->height);
}
} }
} }
if (nxglPbufferVisuals) if (nxglPbufferVisuals)
{ {
glitz_pbuffer_attributes_t attributes; glitz_drawable_t *pbuffer;
unsigned long mask; unsigned int width, height;
glitz_drawable_t *pbuffer; int i;
int i;
for (i = 0; i < nxglPbufferVisuals; i++) for (i = 0; i < nxglPbufferVisuals; i++)
{ {
/* /*
@ -338,26 +157,25 @@ xglInitOffscreen (ScreenPtr pScreen,
* supports accelerated pbuffers but offscreen drawing is really * supports accelerated pbuffers but offscreen drawing is really
* slow, try decrementing these values. * slow, try decrementing these values.
*/ */
attributes.width = 2048; width = 2048;
attributes.height = 2048; height = 2048;
mask = GLITZ_PBUFFER_WIDTH_MASK | GLITZ_PBUFFER_HEIGHT_MASK;
pbuffer = do {
glitz_create_pbuffer_drawable (pScreenPriv->drawable, pbuffer =
xglPbufferVisuals[i].format, glitz_create_pbuffer_drawable (pScreenPriv->drawable,
&attributes, mask); xglPbufferVisuals[i].format,
width, height);
width >>= 1;
height >>= 1;
} while (!pbuffer && width);
if (pbuffer) if (pbuffer)
{ {
unsigned long width, height; int j = 0;
int j;
width = glitz_drawable_get_width (pbuffer); width = glitz_drawable_get_width (pbuffer);
height = glitz_drawable_get_height (pbuffer); height = glitz_drawable_get_height (pbuffer);
j = 0;
/* /*
* No back buffer? only add front buffer. * No back buffer? only add front buffer.
*/ */
@ -366,23 +184,23 @@ xglInitOffscreen (ScreenPtr pScreen,
while (j < 2) while (j < 2)
{ {
pScreenPriv->pOffscreen = pOffscreen->drawable = pbuffer;
xrealloc (pScreenPriv->pOffscreen, pOffscreen->format = xglPbufferVisuals[i].format;
sizeof (xglOffscreenRec) * pOffscreen->buffer = _buffers[j];
(pScreenPriv->nOffscreen + 1));
if (pScreenPriv->pOffscreen) if (xglRootAreaInit (&pOffscreen->rootArea,
MAX_OFFSCREEN_LEVEL,
width, height, 0,
(xglAreaFuncsPtr)
&xglOffscreenAreaFuncs,
(pointer) pOffscreen))
{ {
pOffscreen = glitz_drawable_reference (pbuffer);
&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
pScreenPriv->nOffscreen++;
if (xglOffscreenInit (pOffscreen, pOffscreen++;
pbuffer, _buffers[j], ErrorF ("Initialized %dx%d pbuffer offscreen area\n",
width, height)) width, height);
{
pScreenPriv->nOffscreen++;
ErrorF ("Initialized %dx%d pbuffer offscreen "
"area\n", width, height);
}
} }
j++; j++;
} }
@ -390,18 +208,6 @@ xglInitOffscreen (ScreenPtr pScreen,
} }
} }
} }
pOffscreen = pScreenPriv->pOffscreen;
nOffscreen = pScreenPriv->nOffscreen;
/*
* Update offscreen pointers in root offscreen areas
*/
while (nOffscreen--)
{
pOffscreen->pArea->pOffscreen = pOffscreen;
pOffscreen++;
}
return TRUE; return TRUE;
} }
@ -409,13 +215,18 @@ xglInitOffscreen (ScreenPtr pScreen,
void void
xglFiniOffscreen (ScreenPtr pScreen) xglFiniOffscreen (ScreenPtr pScreen)
{ {
XGL_SCREEN_PRIV (pScreen); int n;
while (pScreenPriv->nOffscreen--)
xglOffscreenFini (&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen]);
if (pScreenPriv->pOffscreen) XGL_SCREEN_PRIV (pScreen);
xfree (pScreenPriv->pOffscreen);
n = pScreenPriv->nOffscreen;
while (n--)
{
xglRootAreaFini (&pScreenPriv->pOffscreen[n].rootArea);
glitz_drawable_destroy (pScreenPriv->pOffscreen[n].drawable);
}
pScreenPriv->nOffscreen = 0;
} }
Bool Bool
@ -439,34 +250,41 @@ xglFindOffscreenArea (ScreenPtr pScreen,
while (nOffscreen--) while (nOffscreen--)
{ {
int level;
if (pOffscreen->format->color.red_size >= pColor->red_size && if (pOffscreen->format->color.red_size >= pColor->red_size &&
pOffscreen->format->color.green_size >= pColor->green_size && pOffscreen->format->color.green_size >= pColor->green_size &&
pOffscreen->format->color.blue_size >= pColor->blue_size && pOffscreen->format->color.blue_size >= pColor->blue_size &&
pOffscreen->format->color.alpha_size >= pColor->alpha_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; /* Kicking out area with lower score */
while ((pOffscreen->width >> level) >= pPixmap->drawable.width && if (xglFindArea (pOffscreen->rootArea.pArea,
(pOffscreen->height >> level) >= pPixmap->drawable.height) pPixmap->drawable.width,
level++; pPixmap->drawable.height,
TRUE,
if (!level) (pointer) pPixmap))
continue;
if (xglOffscreenFindArea (pOffscreen->pArea, pPixmap, level - 1))
return TRUE; return TRUE;
} }
pOffscreen++; pOffscreen++;
} }
return FALSE; return FALSE;
} }
void void
xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea) xglLeaveOffscreenArea (PixmapPtr pPixmap)
{ {
pArea->pPixmapPriv = NULL; XGL_PIXMAP_PRIV (pPixmap);
pArea->state = xglOffscreenAreaAvailable;
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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -100,8 +100,11 @@ void
xglUseMsg (void) xglUseMsg (void)
{ {
ErrorF ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM] " ErrorF ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM] "
"Specify screen characteristics\n"); "specify screen characteristics\n");
ErrorF ("-fullscreen Run fullscreen\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 int
@ -121,12 +124,30 @@ xglProcessArgument (xglScreenInfoPtr pScreenInfo,
return 2; return 2;
} }
else if (!strcmp (argv[i], "-fullscreen"))
if (!strcmp (argv[i], "-fullscreen"))
{ {
pScreenInfo->fullscreen = TRUE; pScreenInfo->fullscreen = TRUE;
return 1; 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; return 0;
} }

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
#include "fb.h"
#ifdef RENDER #ifdef RENDER
@ -33,7 +34,7 @@
#define XGL_PICTURE_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \ #define XGL_PICTURE_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \
XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \ XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (pPicture->pDrawable) xglAddCurrentSurfaceDamage (pPicture->pDrawable)
void void
xglComposite (CARD8 op, xglComposite (CARD8 op,
@ -49,7 +50,7 @@ xglComposite (CARD8 op,
CARD16 width, CARD16 width,
CARD16 height) CARD16 height)
{ {
PictureScreenPtr pPictureScreen; PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen); XGL_SCREEN_PRIV (pScreen);
@ -58,9 +59,13 @@ xglComposite (CARD8 op,
pSrc, pMask, pDst, pSrc, pMask, pDst,
xSrc, ySrc, xSrc, ySrc,
xMask, yMask, xMask, yMask,
xDst, yDst, xDst + pDst->pDrawable->x, yDst + pDst->pDrawable->y,
width, height)) width, height,
NULL, NULL))
{
xglAddCurrentBitDamage (pDst->pDrawable);
return; return;
}
pPictureScreen = GetPictureScreen (pScreen); pPictureScreen = GetPictureScreen (pScreen);
@ -73,46 +78,74 @@ xglComposite (CARD8 op,
FatalError (XGL_SW_FAILURE_STRING); 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, (*pPictureScreen->Composite) (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst, xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height); 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 void
xglGlyphs (CARD8 op, xglAddTriangles (PicturePtr pDst,
PicturePtr pSrc, INT16 xOff,
PicturePtr pDst, INT16 yOff,
PictFormatPtr maskFormat, int ntri,
INT16 xSrc, xTriangle *tris)
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)
{ {
PictureScreenPtr pPictureScreen; PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen); XGL_SCREEN_PRIV (pScreen);
XGL_DRAWABLE_PIXMAP_PRIV (pDst->pDrawable);
pPictureScreen = GetPictureScreen (pScreen); pPictureScreen = GetPictureScreen (pScreen);
XGL_PICTURE_FALLBACK_PROLOGUE (pDst, RasterizeTrapezoid); pPixmapPriv->damageBox.x1 = 0;
(*pPictureScreen->RasterizeTrapezoid) (pDst, trap, xOff, yOff); pPixmapPriv->damageBox.y1 = 0;
XGL_PICTURE_FALLBACK_EPILOGUE (pDst, RasterizeTrapezoid, pPixmapPriv->damageBox.x2 = pDst->pDrawable->width;
xglRasterizeTrapezoid); 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 void
xglChangePicture (PicturePtr pPicture, xglChangePicture (PicturePtr pPicture,
Mask mask) Mask mask)
@ -207,16 +240,18 @@ xglUpdatePicture (PicturePtr pPicture)
case PictFilterNearest: case PictFilterNearest:
case PictFilterFast: case PictFilterFast:
glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0); glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0);
pPixmapPriv->pictureMask &= ~xglPFFilterMask;
break; break;
case PictFilterGood: case PictFilterGood:
case PictFilterBest: case PictFilterBest:
case PictFilterBilinear: case PictFilterBilinear:
glitz_surface_set_filter (surface, GLITZ_FILTER_BILINEAR, NULL, 0); glitz_surface_set_filter (surface, GLITZ_FILTER_BILINEAR, NULL, 0);
pPixmapPriv->pictureMask &= ~xglPFFilterMask;
break; break;
default: case PictFilterConvolution:
pPixmapPriv->pictureMask |= xglPFFilterMask; 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); 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 #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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -32,7 +32,7 @@ xglPixmapDamageReport (DamagePtr pDamage,
void *closure) void *closure)
{ {
PixmapPtr pPixmap = (PixmapPtr) closure; PixmapPtr pPixmap = (PixmapPtr) closure;
BoxPtr pExt; BoxPtr pExt;
XGL_PIXMAP_PRIV (pPixmap); XGL_PIXMAP_PRIV (pPixmap);
@ -104,10 +104,9 @@ xglPixmapSurfaceInit (PixmapPtr pPixmap,
pPixmapPriv->target = xglPixmapTargetOut; pPixmapPriv->target = xglPixmapTargetOut;
/* /*
* Don't allow depth 8 pixmaps into offscreen drawables as * Do not allow accelerated drawing to bitmaps.
* no trapezoid acceleration is hooked up yet.
*/ */
if (pPixmap->drawable.depth <= 8) if (pPixmap->drawable.depth == 1)
pPixmapPriv->target = xglPixmapTargetNo; pPixmapPriv->target = xglPixmapTargetNo;
/* /*
@ -165,10 +164,11 @@ xglCreatePixmap (ScreenPtr pScreen,
if (!xglPixmapSurfaceInit (pPixmap, pScreenPriv->features, width, height)) if (!xglPixmapSurfaceInit (pPixmap, pScreenPriv->features, width, height))
return NullPixmap; return NullPixmap;
pPixmapPriv->buffer = NULL; pPixmapPriv->buffer = NULL;
pPixmapPriv->bits = (pointer) 0; pPixmapPriv->bits = (pointer) 0;
pPixmapPriv->stride = 0; pPixmapPriv->stride = 0;
pPixmapPriv->pGeometry = NULL;
pPixmapPriv->allBits = TRUE; pPixmapPriv->allBits = TRUE;
pPixmapPriv->bitBox.x1 = 0; pPixmapPriv->bitBox.x1 = 0;
@ -189,7 +189,7 @@ xglDestroyPixmap (PixmapPtr pPixmap)
return TRUE; return TRUE;
if (pPixmapPriv->pArea) if (pPixmapPriv->pArea)
xglWithdrawOffscreenArea (pPixmapPriv->pArea); xglWithdrawArea (pPixmapPriv->pArea);
if (pPixmap->devPrivate.ptr) if (pPixmap->devPrivate.ptr)
{ {
@ -197,6 +197,9 @@ xglDestroyPixmap (PixmapPtr pPixmap)
glitz_buffer_unmap (pPixmapPriv->buffer); glitz_buffer_unmap (pPixmapPriv->buffer);
} }
if (pPixmapPriv->pGeometry)
GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
if (pPixmapPriv->buffer) if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer); glitz_buffer_destroy (pPixmapPriv->buffer);
@ -265,7 +268,6 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
else if ((bitsPerPixel < 0) && (depth > 0)) else if ((bitsPerPixel < 0) && (depth > 0))
pPixmap->drawable.bitsPerPixel = BitsPerPixel (depth); pPixmap->drawable.bitsPerPixel = BitsPerPixel (depth);
if (devKind > 0) if (devKind > 0)
pPixmapPriv->stride = devKind; pPixmapPriv->stride = devKind;
else if ((devKind < 0) && ((width > 0) || (depth > 0))) else if ((devKind < 0) && ((width > 0) || (depth > 0)))
@ -283,7 +285,7 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->drawable.height != oldHeight) pPixmap->drawable.height != oldHeight)
{ {
if (pPixmapPriv->pArea) if (pPixmapPriv->pArea)
xglWithdrawOffscreenArea (pPixmapPriv->pArea); xglWithdrawArea (pPixmapPriv->pArea);
if (pPixmapPriv->surface) if (pPixmapPriv->surface)
glitz_surface_destroy (pPixmapPriv->surface); glitz_surface_destroy (pPixmapPriv->surface);
@ -304,6 +306,12 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->devPrivate.ptr = 0; pPixmap->devPrivate.ptr = 0;
} }
if (pPixmapPriv->pGeometry)
{
GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
pPixmapPriv->pGeometry = NULL;
}
if (pPixmapPriv->buffer) if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer); glitz_buffer_destroy (pPixmapPriv->buffer);
@ -374,6 +382,63 @@ xglPixmapToRegion (PixmapPtr pPixmap)
return pRegion; 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 Bool
xglCreatePixmapSurface (PixmapPtr pPixmap) xglCreatePixmapSurface (PixmapPtr pPixmap)
{ {
@ -390,7 +455,8 @@ xglCreatePixmapSurface (PixmapPtr pPixmap)
glitz_surface_create (pScreenPriv->drawable, glitz_surface_create (pScreenPriv->drawable,
pPixmapPriv->format, pPixmapPriv->format,
pPixmap->drawable.width, pPixmap->drawable.width,
pPixmap->drawable.height); pPixmap->drawable.height,
0, NULL);
if (!pPixmapPriv->surface) if (!pPixmapPriv->surface)
{ {
pPixmapPriv->format = NULL; pPixmapPriv->format = NULL;
@ -415,8 +481,6 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits); stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
pPixmapPriv->stride = stride;
if (stride) if (stride)
{ {
pPixmapPriv->bits = xalloc (height * stride); pPixmapPriv->bits = xalloc (height * stride);
@ -432,6 +496,9 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
return FALSE; return FALSE;
} }
} }
/* XXX: pPixmapPriv->stride = -stride */
pPixmapPriv->stride = stride;
return TRUE; return TRUE;
} }
@ -454,15 +521,14 @@ xglMapPixmapBits (PixmapPtr pPixmap)
if (!bits) if (!bits)
return FALSE; 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->devPrivate.ptr = (pPixmap->drawable.height - 1) * -pPixmapPriv->stride;
bits + (pPixmap->drawable.height - 1) * pPixmapPriv->stride;
} }
else else
{ {
pPixmap->devKind = pPixmapPriv->stride;
pPixmap->devPrivate.ptr = bits; pPixmap->devPrivate.ptr = bits;
} }
} }

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -28,6 +28,12 @@
#include "mipointer.h" #include "mipointer.h"
#include "damage.h" #include "damage.h"
#include "fb.h" #include "fb.h"
#ifdef MITSHM
#include "shmint.h"
#endif
#ifdef RENDER
#include "glyphstr.h"
#endif
int xglScreenGeneration = -1; int xglScreenGeneration = -1;
int xglScreenPrivateIndex; int xglScreenPrivateIndex;
@ -35,12 +41,13 @@ int xglGCPrivateIndex;
int xglPixmapPrivateIndex; int xglPixmapPrivateIndex;
int xglWinPrivateIndex; int xglWinPrivateIndex;
#ifdef RENDER
int xglGlyphPrivateIndex;
#endif
#define xglQueryBestSize (void *) NoopDDA #define xglQueryBestSize (void *) NoopDDA
#define xglSaveScreen (void *) NoopDDA #define xglSaveScreen (void *) NoopDDA
#define xglRealizeFont (void *) NoopDDA
#define xglUnrealizeFont (void *) NoopDDA
#define xglConstrainCursor (void *) NoopDDA #define xglConstrainCursor (void *) NoopDDA
#define xglCursorLimits (void *) NoopDDA #define xglCursorLimits (void *) NoopDDA
#define xglDisplayCursor (void *) NoopDDA #define xglDisplayCursor (void *) NoopDDA
@ -49,14 +56,6 @@ int xglWinPrivateIndex;
#define xglRecolorCursor (void *) NoopDDA #define xglRecolorCursor (void *) NoopDDA
#define xglSetCursorPosition (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 static PixmapPtr
xglGetWindowPixmap (WindowPtr pWin) xglGetWindowPixmap (WindowPtr pWin)
{ {
@ -100,7 +99,13 @@ xglAllocatePrivates (ScreenPtr pScreen)
xglWinPrivateIndex = AllocateWindowPrivateIndex (); xglWinPrivateIndex = AllocateWindowPrivateIndex ();
if (xglWinPrivateIndex < 0) if (xglWinPrivateIndex < 0)
return FALSE; return FALSE;
#ifdef RENDER
xglGlyphPrivateIndex = AllocateGlyphPrivateIndex ();
if (xglGlyphPrivateIndex < 0)
return FALSE;
#endif
xglScreenGeneration = serverGeneration; xglScreenGeneration = serverGeneration;
} }
@ -114,7 +119,7 @@ xglAllocatePrivates (ScreenPtr pScreen)
if (!AllocateWindowPrivate (pScreen, xglWinPrivateIndex, if (!AllocateWindowPrivate (pScreen, xglWinPrivateIndex,
sizeof (xglWinRec))) sizeof (xglWinRec)))
return FALSE; return FALSE;
pScreenPriv = xalloc (sizeof (xglScreenRec)); pScreenPriv = xalloc (sizeof (xglScreenRec));
if (!pScreenPriv) if (!pScreenPriv)
return FALSE; return FALSE;
@ -128,7 +133,7 @@ Bool
xglScreenInit (ScreenPtr pScreen, xglScreenInit (ScreenPtr pScreen,
xglScreenInfoPtr pScreenInfo) xglScreenInfoPtr pScreenInfo)
{ {
xglScreenPtr pScreenPriv; xglScreenPtr pScreenPriv;
#ifdef RENDER #ifdef RENDER
PictureScreenPtr pPictureScreen; PictureScreenPtr pPictureScreen;
@ -152,11 +157,19 @@ xglScreenInit (ScreenPtr pScreen,
xglInitPixmapFormats (pScreen); xglInitPixmapFormats (pScreen);
if (!pScreenPriv->pixmapFormats[32].format) if (!pScreenPriv->pixmapFormats[32].format)
return FALSE; return FALSE;
pScreenPriv->geometryDataType = pScreenInfo->geometryDataType;
pScreenPriv->geometryUsage = pScreenInfo->geometryUsage;
GEOMETRY_INIT (pScreen, &pScreenPriv->scratchGeometry,
GLITZ_GEOMETRY_TYPE_VERTEX,
pScreenPriv->geometryUsage, 0);
pScreenPriv->surface = pScreenPriv->surface =
glitz_surface_create (pScreenPriv->drawable, glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[32].format, pScreenPriv->pixmapFormats[32].format,
pScreenInfo->width, pScreenInfo->height); pScreenInfo->width, pScreenInfo->height,
0, NULL);
if (!pScreenPriv->surface) if (!pScreenPriv->surface)
return FALSE; return FALSE;
@ -167,7 +180,7 @@ xglScreenInit (ScreenPtr pScreen,
if (monitorResolution == 0) if (monitorResolution == 0)
monitorResolution = XGL_DEFAULT_DPI; monitorResolution = XGL_DEFAULT_DPI;
if (!fbSetupScreen (pScreen, NULL, if (!fbSetupScreen (pScreen, NULL,
pScreenInfo->width, pScreenInfo->height, pScreenInfo->width, pScreenInfo->height,
monitorResolution, monitorResolution, monitorResolution, monitorResolution,
@ -187,8 +200,12 @@ xglScreenInit (ScreenPtr pScreen,
pScreenPriv->pVisual->pPixel->masks.bpp)) pScreenPriv->pVisual->pPixel->masks.bpp))
return FALSE; return FALSE;
#ifdef MITSHM
ShmRegisterFuncs (pScreen, NULL);
#endif
#ifdef RENDER #ifdef RENDER
if (!fbPictureInit (pScreen, 0, 0)) if (!xglPictureInit (pScreen))
return FALSE; return FALSE;
#endif #endif
@ -197,14 +214,10 @@ xglScreenInit (ScreenPtr pScreen,
XGL_SCREEN_WRAP (CopyWindow, xglCopyWindow); XGL_SCREEN_WRAP (CopyWindow, xglCopyWindow);
XGL_SCREEN_WRAP (CreateWindow, xglCreateWindow); XGL_SCREEN_WRAP (CreateWindow, xglCreateWindow);
XGL_SCREEN_WRAP (ChangeWindowAttributes, xglChangeWindowAttributes);
XGL_SCREEN_WRAP (PaintWindowBackground, xglPaintWindowBackground); XGL_SCREEN_WRAP (PaintWindowBackground, xglPaintWindowBackground);
XGL_SCREEN_WRAP (PaintWindowBorder, xglPaintWindowBorder); XGL_SCREEN_WRAP (PaintWindowBorder, xglPaintWindowBorder);
/*
pScreen->RealizeFont = xglRealizeFont;
pScreen->UnrealizeFont = xglUnrealizeFont;
*/
XGL_SCREEN_WRAP (CreateGC, xglCreateGC); XGL_SCREEN_WRAP (CreateGC, xglCreateGC);
pScreen->ConstrainCursor = xglConstrainCursor; pScreen->ConstrainCursor = xglConstrainCursor;
@ -215,16 +228,6 @@ xglScreenInit (ScreenPtr pScreen,
pScreen->RecolorCursor = xglRecolorCursor; pScreen->RecolorCursor = xglRecolorCursor;
pScreen->SetCursorPosition = xglSetCursorPosition; 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; pScreen->ModifyPixmapHeader = xglModifyPixmapHeader;
XGL_SCREEN_WRAP (BitmapToRegion, xglPixmapToRegion); XGL_SCREEN_WRAP (BitmapToRegion, xglPixmapToRegion);
@ -235,10 +238,19 @@ xglScreenInit (ScreenPtr pScreen,
#ifdef RENDER #ifdef RENDER
pPictureScreen = GetPictureScreenIfSet (pScreen); 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 (Composite, xglComposite);
XGL_PICTURE_SCREEN_WRAP (Glyphs, xglGlyphs); 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 (ChangePicture, xglChangePicture);
XGL_PICTURE_SCREEN_WRAP (ChangePictureTransform, XGL_PICTURE_SCREEN_WRAP (ChangePictureTransform,
xglChangePictureTransform); xglChangePictureTransform);
@ -260,6 +272,14 @@ xglScreenInit (ScreenPtr pScreen,
Bool Bool
xglFinishScreenInit (ScreenPtr pScreen) 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); XGL_SCREEN_PRIV (pScreen);
miInitializeBackingStore (pScreen); miInitializeBackingStore (pScreen);
@ -270,11 +290,54 @@ xglFinishScreenInit (ScreenPtr pScreen)
pScreenPriv->solid = pScreenPriv->solid =
glitz_surface_create (pScreenPriv->drawable, glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[32].format, pScreenPriv->pixmapFormats[32].format,
1, 1); 1, 1, 0, NULL);
if (!pScreenPriv->solid) if (!pScreenPriv->solid)
return FALSE; return FALSE;
glitz_surface_set_fill (pScreenPriv->solid, GLITZ_FILL_REPEAT); 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; return TRUE;
} }
@ -285,6 +348,19 @@ xglCloseScreen (int index,
{ {
XGL_SCREEN_PRIV (pScreen); 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) if (pScreenPriv->solid)
glitz_surface_destroy (pScreenPriv->solid); glitz_surface_destroy (pScreenPriv->solid);
@ -292,9 +368,59 @@ xglCloseScreen (int index,
glitz_surface_destroy (pScreenPriv->surface); glitz_surface_destroy (pScreenPriv->surface);
xglFiniOffscreen (pScreen); xglFiniOffscreen (pScreen);
GEOMETRY_UNINIT (&pScreenPriv->scratchGeometry);
XGL_SCREEN_UNWRAP (CloseScreen); XGL_SCREEN_UNWRAP (CloseScreen);
xfree (pScreenPriv); xfree (pScreenPriv);
return (*pScreen->CloseScreen) (index, pScreen); 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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
#include "gcstruct.h"
#include "fontstruct.h"
#include "dixfontstr.h"
Bool Bool
xglSolid (DrawablePtr pDrawable, xglSolid (DrawablePtr pDrawable,
glitz_operator_t op, glitz_operator_t op,
glitz_color_t *color, glitz_color_t *color,
xglGeometryPtr pGeometry, xglGeometryPtr pGeometry,
int x,
int y,
int width,
int height,
BoxPtr pBox, BoxPtr pBox,
int nBox) int nBox)
{ {
@ -38,6 +45,9 @@ xglSolid (DrawablePtr pDrawable,
XGL_SCREEN_PRIV (pDrawable->pScreen); XGL_SCREEN_PRIV (pDrawable->pScreen);
if (nBox < 1)
return TRUE;
if (!xglPrepareTarget (pDrawable)) if (!xglPrepareTarget (pDrawable))
return FALSE; return FALSE;
@ -45,26 +55,108 @@ xglSolid (DrawablePtr pDrawable,
glitz_set_rectangle (pScreenPriv->solid, color, 0, 0, 1, 1); glitz_set_rectangle (pScreenPriv->solid, color, 0, 0, 1, 1);
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff); if (pGeometry)
if (!GEOMETRY_ENABLE_ALL_VERTICES (pGeometry, surface))
return FALSE;
while (nBox--)
{ {
glitz_composite (op, glitz_surface_set_clip_region (surface, xOff, yOff,
pScreenPriv->solid, NULL, surface, (glitz_box_t *) pBox, nBox);
0, 0, }
0, 0, else
pBox->x1 + xOff, {
pBox->y1 + yOff, pGeometry = xglGetScratchVertexGeometry (pDrawable->pScreen, 4 * nBox);
pBox->x2 - pBox->x1, pBox->y2 - pBox->y1); GEOMETRY_ADD_BOX (pDrawable->pScreen, pGeometry, pBox, nBox);
pBox++;
} }
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
if (!GEOMETRY_ENABLE (pGeometry, surface))
return FALSE;
glitz_composite (op,
pScreenPriv->solid, NULL, surface,
0, 0,
0, 0,
x + xOff,
y + yOff,
width, height);
glitz_surface_set_clip_region (surface, 0, 0, NULL, 0);
if (glitz_surface_get_status (surface)) if (glitz_surface_get_status (surface))
return FALSE; return FALSE;
return TRUE; 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 * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
@ -152,39 +152,56 @@ xglSyncBits (DrawablePtr pDrawable,
if (!pPixmapPriv->buffer) if (!pPixmapPriv->buffer)
if (!xglAllocatePixmapBits (pPixmap)) if (!xglAllocatePixmapBits (pPixmap))
return FALSE; return FALSE;
if (REGION_NOTEMPTY (pDrawable->pScreen, &region)) if (pPixmapPriv->pDamage)
{ {
if (pPixmapPriv->surface) RegionPtr pRegion;
{
glitz_pixel_format_t format;
BoxPtr pBox;
int nBox;
xglUnmapPixmapBits (pPixmap); pRegion = DamageRegion (pPixmapPriv->pDamage);
REGION_SUBTRACT (pDrawable->pScreen, &region, &region, pRegion);
}
if (REGION_NOTEMPTY (pDrawable->pScreen, &region) && pPixmapPriv->surface)
{
glitz_pixel_format_t format;
BoxPtr pBox;
int nBox;
if (!xglSyncSurface (pDrawable))
FatalError (XGL_SW_FAILURE_STRING);
xglUnmapPixmapBits (pPixmap);
pBox = REGION_RECTS (&region); pBox = REGION_RECTS (&region);
nBox = REGION_NUM_RECTS (&region); nBox = REGION_NUM_RECTS (&region);
format.masks = pPixmapPriv->pPixel->masks; format.masks = pPixmapPriv->pPixel->masks;
if (pPixmapPriv->stride < 0)
{
format.bytes_per_line = -pPixmapPriv->stride;
format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
}
else
{
format.bytes_per_line = pPixmapPriv->stride; format.bytes_per_line = pPixmapPriv->stride;
format.scanline_order = XGL_INTERNAL_SCANLINE_ORDER; format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
}
while (nBox--)
{ while (nBox--)
format.xoffset = pBox->x1; {
format.skip_lines = pBox->y1; format.xoffset = pBox->x1;
format.skip_lines = pBox->y1;
glitz_get_pixels (pPixmapPriv->surface,
pBox->x1, glitz_get_pixels (pPixmapPriv->surface,
pBox->y1, pBox->x1,
pBox->x2 - pBox->x1, pBox->y1,
pBox->y2 - pBox->y1, pBox->x2 - pBox->x1,
&format, pBox->y2 - pBox->y1,
pPixmapPriv->buffer); &format,
pPixmapPriv->buffer);
pBox++;
} pBox++;
} }
} }
@ -234,16 +251,25 @@ xglSyncSurface (DrawablePtr pDrawable)
nBox = REGION_NUM_RECTS (pRegion); nBox = REGION_NUM_RECTS (pRegion);
pBox = REGION_RECTS (pRegion); pBox = REGION_RECTS (pRegion);
format.masks = pPixmapPriv->pPixel->masks;
format.masks = pPixmapPriv->pPixel->masks; if (pPixmapPriv->stride < 0)
format.bytes_per_line = pPixmapPriv->stride; {
format.scanline_order = XGL_INTERNAL_SCANLINE_ORDER; format.bytes_per_line = -pPixmapPriv->stride;
format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
}
else
{
format.bytes_per_line = pPixmapPriv->stride;
format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
}
while (nBox--) while (nBox--)
{ {
format.xoffset = pBox->x1; format.xoffset = pBox->x1;
format.skip_lines = pBox->y1; format.skip_lines = pBox->y1;
glitz_set_pixels (pPixmapPriv->surface, glitz_set_pixels (pPixmapPriv->surface,
pBox->x1, pBox->x1,
pBox->y1, pBox->y1,
@ -288,7 +314,34 @@ xglPrepareTarget (DrawablePtr pDrawable)
} }
void 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); XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
@ -310,18 +363,12 @@ xglAddSurfaceDamage (DrawablePtr pDrawable)
pDamageRegion, pDamageRegion, &region); pDamageRegion, pDamageRegion, &region);
REGION_UNINIT (pDrawable->pScreen, &region); REGION_UNINIT (pDrawable->pScreen, &region);
if (pPixmapPriv->target == xglPixmapTargetIn)
{
if (!xglSyncSurface (pDrawable))
FatalError (XGL_SW_FAILURE_STRING);
}
pPixmapPriv->damageBox = miEmptyBox; pPixmapPriv->damageBox = miEmptyBox;
} }
} }
void void
xglAddBitDamage (DrawablePtr pDrawable) xglAddCurrentBitDamage (DrawablePtr pDrawable)
{ {
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable); XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

View File

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

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

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

View File

@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without * and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies * fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice * 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 * David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission. * distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this * 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 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* *
* Author: David Reveman <davidr@freedesktop.org> * Author: David Reveman <davidr@novell.com>
*/ */
#include "xgl.h" #include "xgl.h"
#include "fb.h" #include "fb.h"
#define XGL_WINDOW_FALLBACK_PROLOGUE(pWin, func) \ #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) 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); \ XGL_SCREEN_WRAP (func, xglfunc); \
xglAddSurfaceDamage (&pWin->drawable) xglAddSurfaceDamage (&pWin->drawable, pRegion)
Bool Bool
xglCreateWindow (WindowPtr pWin) xglCreateWindow (WindowPtr pWin)
@ -52,96 +53,119 @@ xglCreateWindow (WindowPtr pWin)
return ret; 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 void
xglCopyWindow (WindowPtr pWin, xglCopyWindow (WindowPtr pWin,
DDXPointRec ptOldOrg, DDXPointRec ptOldOrg,
RegionPtr prgnSrc) RegionPtr prgnSrc)
{ {
ScreenPtr pScreen = pWin->drawable.pScreen; PixmapPtr pPixmap;
RegionRec rgnDst;
int dx, dy;
BoxPtr pExtent = REGION_EXTENTS (pWin->drawable.pScreen, prgnSrc);
BoxRec box;
XGL_SCREEN_PRIV (pScreen); pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (&pWin->drawable)->target) box.x1 = pWin->drawable.x + pExtent->x1;
{ box.y1 = pWin->drawable.y + pExtent->y1;
PixmapPtr pPixmap; box.x2 = pWin->drawable.x + pExtent->x2;
RegionRec rgnDst; box.y2 = pWin->drawable.y + pExtent->y2;
int dx, dy;
Bool ret;
pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
dx = ptOldOrg.x - pWin->drawable.x; dx = ptOldOrg.x - pWin->drawable.x;
dy = ptOldOrg.y - pWin->drawable.y; dy = ptOldOrg.y - pWin->drawable.y;
REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy); REGION_TRANSLATE (pWin->drawable.pScreen, prgnSrc, -dx, -dy);
REGION_INIT (pScreen, &rgnDst, NullBox, 0); REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
REGION_INTERSECT (pScreen, &rgnDst, &pWin->borderClip, prgnSrc); REGION_INTERSECT (pWin->drawable.pScreen,
&rgnDst, &pWin->borderClip, prgnSrc);
#ifdef COMPOSITE #ifdef COMPOSITE
if (pPixmap->screen_x || pPixmap->screen_y) if (pPixmap->screen_x || pPixmap->screen_y)
REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst, {
-pPixmap->screen_x, -pPixmap->screen_y); REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
#endif -pPixmap->screen_x, -pPixmap->screen_y);
ret = TRUE; box.x1 -= pPixmap->screen_x;
fbCopyRegion (&pWin->drawable, &pWin->drawable, box.y1 -= pPixmap->screen_y;
0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &ret); box.x2 -= pPixmap->screen_x;
box.y2 -= pPixmap->screen_y;
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);
} }
#endif
if (!xglSyncBits (&pWin->drawable, NullBox))
FatalError (XGL_SW_FAILURE_STRING); fbCopyRegion (&pWin->drawable, &pWin->drawable,
0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &box);
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, CopyWindow);
(*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); REGION_UNINIT (pWin->drawable.pScreen, &rgnDst);
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, CopyWindow, xglCopyWindow);
} }
static Bool static Bool
xglFillRegionSolid (DrawablePtr pDrawable, xglFillRegionSolid (DrawablePtr pDrawable,
RegionPtr pRegion, RegionPtr pRegion,
Pixel pixel) Pixel pixel)
{ {
ScreenPtr pScreen = pDrawable->pScreen; glitz_color_t color;
xglGeometryRec geometry; BoxPtr pExtent;
glitz_color_t color;
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable); XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
if (!pPixmapPriv->target) if (!pPixmapPriv->target)
return FALSE; return FALSE;
xglPixelToColor (pPixmapPriv->pPixel, pixel, &color); pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (pRegion) << 3); xglPixelToColor (pPixmapPriv->pPixel, pixel, &color);
GEOMETRY_ADD_REGION (pScreen, &geometry, pRegion);
if (xglSolid (pDrawable, if (xglSolid (pDrawable,
GLITZ_OPERATOR_SRC, GLITZ_OPERATOR_SRC,
&color, &color,
&geometry, NULL,
REGION_EXTENTS (pScreen, pRegion), 1)) pExtent->x1, pExtent->y1,
{ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
GEOMETRY_UNINIT (&geometry); REGION_RECTS (pRegion),
REGION_NUM_RECTS (pRegion)))
return TRUE; return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE; return FALSE;
} }
@ -152,27 +176,26 @@ xglFillRegionTiled (DrawablePtr pDrawable,
int tileX, int tileX,
int tileY) int tileY)
{ {
ScreenPtr pScreen = pDrawable->pScreen; BoxPtr pExtent;
xglGeometryRec geometry;
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
if (!XGL_GET_DRAWABLE_PIXMAP_PRIV (pDrawable)->target) if (!pPixmapPriv->target)
return FALSE; return FALSE;
GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (pRegion) << 3); pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
GEOMETRY_ADD_REGION (pScreen, &geometry, pRegion);
if (xglTile (pDrawable, if (xglTile (pDrawable,
GLITZ_OPERATOR_SRC, GLITZ_OPERATOR_SRC,
pTile, pTile,
tileX, tileY, tileX, tileY,
&geometry, NULL,
REGION_EXTENTS (pScreen, pRegion), 1)) pExtent->x1, pExtent->y1,
{ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
GEOMETRY_UNINIT (&geometry); REGION_RECTS (pRegion),
REGION_NUM_RECTS (pRegion)))
return TRUE; return TRUE;
}
GEOMETRY_UNINIT (&geometry);
return FALSE; return FALSE;
} }
@ -202,7 +225,7 @@ xglPaintWindowBackground (WindowPtr pWin,
-pWin->drawable.x, -pWin->drawable.x,
-pWin->drawable.y)) -pWin->drawable.y))
{ {
xglAddBitDamage (&pWin->drawable); xglAddCurrentBitDamage (&pWin->drawable);
return; return;
} }
@ -214,7 +237,7 @@ xglPaintWindowBackground (WindowPtr pWin,
pRegion, pRegion,
pWin->background.pixel)) pWin->background.pixel))
{ {
xglAddBitDamage (&pWin->drawable); xglAddCurrentBitDamage (&pWin->drawable);
return; return;
} }
break; break;
@ -222,7 +245,7 @@ xglPaintWindowBackground (WindowPtr pWin,
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBackground); XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBackground);
(*pScreen->PaintWindowBackground) (pWin, pRegion, what); (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, PaintWindowBackground, XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBackground,
xglPaintWindowBackground); xglPaintWindowBackground);
} }
@ -241,7 +264,7 @@ xglPaintWindowBorder (WindowPtr pWin,
pRegion, pRegion,
pWin->border.pixel)) pWin->border.pixel))
{ {
xglAddBitDamage (&pWin->drawable); xglAddCurrentBitDamage (&pWin->drawable);
return; return;
} }
} }
@ -258,7 +281,7 @@ xglPaintWindowBorder (WindowPtr pWin,
-pBgWin->drawable.x, -pBgWin->drawable.x,
-pBgWin->drawable.y)) -pBgWin->drawable.y))
{ {
xglAddBitDamage (&pWin->drawable); xglAddCurrentBitDamage (&pWin->drawable);
return; return;
} }
@ -268,6 +291,6 @@ xglPaintWindowBorder (WindowPtr pWin,
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBorder); XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBorder);
(*pScreen->PaintWindowBorder) (pWin, pRegion, what); (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
XGL_WINDOW_FALLBACK_EPILOGUE (pWin, PaintWindowBorder, XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBorder,
xglPaintWindowBorder); xglPaintWindowBorder);
} }