summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/xgl/Makefile.am6
-rw-r--r--hw/xgl/glx/xglx.c28
-rw-r--r--hw/xgl/xgl.h672
-rw-r--r--hw/xgl/xglarea.c318
-rw-r--r--hw/xgl/xglbstore.c10
-rw-r--r--hw/xgl/xglcmap.c34
-rw-r--r--hw/xgl/xglcomp.c271
-rw-r--r--hw/xgl/xglcopy.c163
-rw-r--r--hw/xgl/xglfill.c312
-rw-r--r--hw/xgl/xglgc.c198
-rw-r--r--hw/xgl/xglgeometry.c616
-rw-r--r--hw/xgl/xglget.c18
-rw-r--r--hw/xgl/xglglyph.c1080
-rw-r--r--hw/xgl/xglinput.c4
-rw-r--r--hw/xgl/xgloffscreen.c428
-rw-r--r--hw/xgl/xgloutput.c4
-rw-r--r--hw/xgl/xglparse.c35
-rw-r--r--hw/xgl/xglpict.c282
-rw-r--r--hw/xgl/xglpixel.c149
-rw-r--r--hw/xgl/xglpixmap.c102
-rw-r--r--hw/xgl/xglscreen.c202
-rw-r--r--hw/xgl/xglsolid.c122
-rw-r--r--hw/xgl/xglsync.c129
-rw-r--r--hw/xgl/xgltile.c336
-rw-r--r--hw/xgl/xgltrap.c520
-rw-r--r--hw/xgl/xglwindow.c193
26 files changed, 4594 insertions, 1638 deletions
diff --git a/hw/xgl/Makefile.am b/hw/xgl/Makefile.am
index 2471758a8..8ae1a47fd 100644
--- a/hw/xgl/Makefile.am
+++ b/hw/xgl/Makefile.am
@@ -13,13 +13,13 @@ libxgl_a_SOURCES = \
xglcmap.c \
xglparse.c \
xglscreen.c \
+ xglarea.c \
xgloffscreen.c \
xglgeometry.c \
xglpixmap.c \
xglsync.c \
xglsolid.c \
xgltile.c \
- xglpixel.c \
xglcopy.c \
xglfill.c \
xglwindow.c \
@@ -27,4 +27,6 @@ libxgl_a_SOURCES = \
xglget.c \
xglgc.c \
xglcomp.c \
- xglpict.c
+ xglpict.c \
+ xglglyph.c \
+ xgltrap.c
diff --git a/hw/xgl/glx/xglx.c b/hw/xgl/glx/xglx.c
index c013317e3..cda3e96bc 100644
--- a/hw/xgl/glx/xglx.c
+++ b/hw/xgl/glx/xglx.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include <X11/Xlib.h>
@@ -64,7 +64,11 @@ int xscreen;
glitz_format_t *xglxCurrentFormat;
CARD32 lastEventTime = 0;
ScreenPtr currentScreen = NULL;
-xglScreenInfoRec xglScreenInfo = { 0, 0, 0, 0, FALSE };
+xglScreenInfoRec xglScreenInfo = {
+ NULL, 0, 0, 0, 0, FALSE,
+ DEFAULT_GEOMETRY_DATA_TYPE,
+ DEFAULT_GEOMETRY_USAGE
+};
static Bool
xglxAllocatePrivates (ScreenPtr pScreen)
@@ -386,9 +390,15 @@ xglxBlockHandler (pointer blockData,
OSTimePtr pTimeout,
pointer pReadMask)
{
- glitz_surface_flush (XGL_GET_SCREEN_PRIV (currentScreen)->surface);
- glitz_drawable_flush (XGL_GET_SCREEN_PRIV (currentScreen)->drawable);
- XFlush (xdisplay);
+ XGL_SCREEN_PRIV (currentScreen);
+
+ if (!xglSyncSurface (&pScreenPriv->pScreenPixmap->drawable))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ glitz_surface_flush (pScreenPriv->surface);
+ glitz_drawable_finish (pScreenPriv->drawable);
+
+ XSync (xdisplay, FALSE);
}
static void
@@ -397,8 +407,8 @@ xglxWakeupHandler (pointer blockData,
pointer pReadMask)
{
ScreenPtr pScreen = currentScreen;
- XEvent X;
- xEvent x;
+ XEvent X;
+ xEvent x;
while (XPending (xdisplay)) {
XNextEvent (xdisplay, &X);
@@ -578,7 +588,7 @@ InitInput (int argc, char **argv)
void
ddxUseMsg (void)
{
- ErrorF ("\nXglx Usage:\n");
+ ErrorF ("\nXglx usage:\n");
ErrorF ("-display string display name of the real server\n");
xglUseMsg ();
diff --git a/hw/xgl/xgl.h b/hw/xgl/xgl.h
index 3f1616af5..930f3d038 100644
--- a/hw/xgl/xgl.h
+++ b/hw/xgl/xgl.h
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#ifndef _XGL_H_
@@ -61,6 +61,8 @@ typedef struct _xglScreenInfo {
unsigned int widthMm;
unsigned int heightMm;
Bool fullscreen;
+ int geometryDataType;
+ int geometryUsage;
} xglScreenInfoRec, *xglScreenInfoPtr;
typedef struct _xglPixelFormat {
@@ -85,29 +87,123 @@ extern int nxglVisuals;
extern xglVisualPtr xglPbufferVisuals;
extern int nxglPbufferVisuals;
-#define xglOffscreenAreaAvailable 0
-#define xglOffscreenAreaDivided 1
-#define xglOffscreenAreaOccupied 2
+#define xglAreaAvailable 0
+#define xglAreaDivided 1
+#define xglAreaOccupied 2
+
+typedef struct _xglRootArea *xglRootAreaPtr;
+
+typedef struct _xglArea {
+ int state;
+ int level;
+ int x, y;
+ int width, height;
+ struct _xglArea *pArea[4];
+ xglRootAreaPtr pRoot;
+ pointer closure;
+ DevUnion devPrivate;
+} xglAreaRec, *xglAreaPtr;
+
+typedef struct _xglAreaFuncs {
+ Bool (*Create) (xglAreaPtr pArea);
+
+ Bool (*MoveIn) (xglAreaPtr pArea,
+ pointer closure);
+
+ void (*MoveOut) (xglAreaPtr pArea,
+ pointer closure);
+
+ int (*CompareScore) (xglAreaPtr pArea,
+ pointer closure1,
+ pointer closure2);
+
+} xglAreaFuncsRec, *xglAreaFuncsPtr;
+
+typedef struct _xglRootArea {
+ int maxLevel;
+ int width, height;
+ xglAreaPtr pArea;
+ xglAreaFuncsPtr funcs;
+ int devPrivateSize;
+ pointer closure;
+} xglRootAreaRec;
+
+typedef struct xglGeometry {
+ glitz_buffer_t *buffer;
+ pointer *data;
+ Bool broken;
+ glitz_fixed16_16_t xOff, yOff;
+ int dataType;
+ int usage;
+ int size, endOffset;
+ glitz_geometry_type_t type;
+ glitz_geometry_format_t f;
+ int first, width, count;
+ glitz_multi_array_t *array;
+} xglGeometryRec, *xglGeometryPtr;
-typedef struct _xglOffscreen *xglOffscreenPtr;
-typedef struct _xglPixmap *xglPixmapPtr;
+#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
-typedef struct _xglOffscreenArea {
- int level;
- int state;
- int x, y;
- xglPixmapPtr pPixmapPriv;
- struct _xglOffscreenArea *pArea[4];
- xglOffscreenPtr pOffscreen;
-} xglOffscreenAreaRec, *xglOffscreenAreaPtr;
+#define XGL_MAX_OFFSCREEN_AREAS 8
typedef struct _xglOffscreen {
+ xglRootAreaRec rootArea;
glitz_drawable_t *drawable;
glitz_drawable_format_t *format;
glitz_drawable_buffer_t buffer;
- int width, height;
- xglOffscreenAreaPtr pArea;
-} xglOffscreenRec;
+} xglOffscreenRec, *xglOffscreenPtr;
typedef struct _xglScreen {
xglVisualPtr pVisual;
@@ -117,12 +213,26 @@ typedef struct _xglScreen {
glitz_surface_t *solid;
PixmapPtr pScreenPixmap;
unsigned long features;
- xglOffscreenPtr pOffscreen;
+ xglOffscreenRec pOffscreen[XGL_MAX_OFFSCREEN_AREAS];
int nOffscreen;
+ int geometryUsage;
+ int geometryDataType;
+ xglGeometryRec scratchGeometry;
+
+#ifdef RENDER
+ xglGlyphCacheRec glyphCache[33];
+ PicturePtr pSolidAlpha;
+ struct _trapInfo {
+ PicturePtr pMask;
+ glitz_surface_t *mask;
+ glitz_geometry_format_t format;
+ } trapInfo;
+#endif
GetImageProcPtr GetImage;
GetSpansProcPtr GetSpans;
CreateWindowProcPtr CreateWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
PaintWindowBackgroundProcPtr PaintWindowBackground;
PaintWindowBorderProcPtr PaintWindowBorder;
CopyWindowProcPtr CopyWindow;
@@ -133,11 +243,16 @@ typedef struct _xglScreen {
#ifdef RENDER
CompositeProcPtr Composite;
- RasterizeTrapezoidProcPtr RasterizeTrapezoid;
GlyphsProcPtr Glyphs;
+ TrapezoidsProcPtr Trapezoids;
+ AddTrapsProcPtr AddTraps;
+ AddTrianglesProcPtr AddTriangles;
ChangePictureProcPtr ChangePicture;
ChangePictureTransformProcPtr ChangePictureTransform;
ChangePictureFilterProcPtr ChangePictureFilter;
+
+ RealizeGlyphProcPtr RealizeGlyph;
+ UnrealizeGlyphProcPtr UnrealizeGlyph;
#endif
BSFuncRec BackingStoreFuncs;
@@ -213,22 +328,23 @@ extern int xglGCPrivateIndex;
#define xglPixmapTargetIn 2
typedef struct _xglPixmap {
- xglPixelFormatPtr pPixel;
- glitz_format_t *format;
- glitz_surface_t *surface;
- glitz_buffer_t *buffer;
- int target;
- xglOffscreenAreaPtr pArea;
- int score;
- Bool acceleratedTile;
- pointer bits;
- unsigned int stride;
- DamagePtr pDamage;
- BoxRec damageBox;
- BoxRec bitBox;
- Bool allBits;
- unsigned long pictureMask;
-} xglPixmapRec;
+ xglPixelFormatPtr pPixel;
+ glitz_format_t *format;
+ glitz_surface_t *surface;
+ glitz_buffer_t *buffer;
+ int target;
+ xglAreaPtr pArea;
+ int score;
+ Bool acceleratedTile;
+ pointer bits;
+ unsigned int stride;
+ DamagePtr pDamage;
+ BoxRec damageBox;
+ BoxRec bitBox;
+ Bool allBits;
+ unsigned long pictureMask;
+ xglGeometryPtr pGeometry;
+} xglPixmapRec, *xglPixmapPtr;
extern int xglPixmapPrivateIndex;
@@ -271,19 +387,6 @@ extern int xglWinPrivateIndex;
#define XGL_DRAWABLE_PIXMAP_PRIV(pDrawable) \
xglPixmapPtr pPixmapPriv = XGL_GET_DRAWABLE_PIXMAP_PRIV (pDrawable)
-
-typedef struct xglGeometry {
- glitz_buffer_t *buffer;
- pointer *data;
- glitz_geometry_primitive_t primitive;
- Bool broken;
- glitz_fixed16_16_t xOff, yOff;
- int dataType;
- int usage;
- int size, endOffset;
-} xglGeometryRec, *xglGeometryPtr;
-
-
#ifdef COMPOSITE
#define __XGL_OFF_X_WIN(pPix) (-(pPix)->screen_x)
#define __XGL_OFF_Y_WIN(pPix) (-(pPix)->screen_y)
@@ -308,11 +411,6 @@ typedef struct xglGeometry {
#define XGL_DEFAULT_DPI 96
-#define XGL_INTERNAL_SCANLINE_ORDER GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN
-
-#define XGL_INTERNAL_SCANLINE_ORDER_UPSIDE_DOWN \
- (XGL_INTERNAL_SCANLINE_ORDER == GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP)
-
#define XGL_SW_FAILURE_STRING "software fall-back failure"
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -322,32 +420,13 @@ typedef struct xglGeometry {
#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
+#define FIXED_TO_FLOAT(f) (((glitz_float_t) (f)) / 65536)
+#define FLOAT_TO_FIXED(f) ((int) ((f) * 65536))
+
#define BOX_NOTEMPTY(pBox) \
(((pBox)->x2 - (pBox)->x1) > 0 && \
((pBox)->y2 - (pBox)->y1) > 0)
-#define BOX_EXTENTS(pBox, nBox, pExt) \
- { \
- int i; \
- (pExt)->x1 = (pExt)->y1 = 32767; \
- (pExt)->x2 = (pExt)->y2 = -32767; \
- for (i = 0; i < (nBox); i++) \
- { \
- if ((pBox)[i].x1 < (pExt)->x1) \
- (pExt)->x1 = (pBox)[i].x1; \
- if ((pBox)[i].y1 < (pExt)->y1) \
- (pExt)->y1 = (pBox)[i].y1; \
- if ((pBox)[i].x2 > (pExt)->x2) \
- (pExt)->x2 = (pBox)[i].x2; \
- if ((pBox)[i].y2 > (pExt)->y2) \
- (pExt)->y2 = (pBox)[i].y2; \
- } \
- if (((pExt)->x2 - (pExt)->x1) < 0) \
- (pExt)->x1 = (pExt)->x2 = 0; \
- if (((pExt)->y2 - (pExt)->y1) < 0) \
- (pExt)->y1 = (pExt)->y2 = 0; \
- }
-
#define XGL_MAX_PIXMAP_SCORE 32768
#define XGL_MIN_PIXMAP_SCORE -32768
@@ -453,6 +532,37 @@ Bool
xglCloseScreen (int index,
ScreenPtr pScreen);
+void
+xglCreateSolidAlphaPicture (ScreenPtr pScreen);
+
+
+/* xglarea.c */
+
+Bool
+xglRootAreaInit (xglRootAreaPtr pRoot,
+ int maxLevel,
+ int width,
+ int height,
+ int devPrivateSize,
+ xglAreaFuncsPtr funcs,
+ pointer closure);
+
+void
+xglRootAreaFini (xglRootAreaPtr pRoot);
+
+void
+xglLeaveArea (xglAreaPtr pArea);
+
+void
+xglWithdrawArea (xglAreaPtr pArea);
+
+Bool
+xglFindArea (xglAreaPtr pArea,
+ int width,
+ int height,
+ Bool kickOut,
+ pointer closure);
+
/* xgloffscreen.c */
@@ -468,7 +578,7 @@ xglFindOffscreenArea (ScreenPtr pScreen,
PixmapPtr pPixmap);
void
-xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
+xglLeaveOffscreenArea (PixmapPtr pPixmap);
/* xglgeometry.c */
@@ -476,40 +586,101 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
#define GEOMETRY_DATA_TYPE_SHORT 0
#define GEOMETRY_DATA_TYPE_FLOAT 1
+typedef struct _xglDataTypeInfo {
+ glitz_data_type_t type;
+ int size;
+} xglDataTypeInfoRec, *xglDataTypeInfoPtr;
+
+extern xglDataTypeInfoRec xglGeometryDataTypes[2];
+
+#define DEFAULT_GEOMETRY_DATA_TYPE GEOMETRY_DATA_TYPE_FLOAT
+
#define GEOMETRY_USAGE_STREAM 0
#define GEOMETRY_USAGE_STATIC 1
#define GEOMETRY_USAGE_DYNAMIC 2
-#define GEOMETRY_USAGE_USERMEM 3
-
-#define GEOMETRY_INIT(pScreen, pGeometry, _size) \
- { \
- (pGeometry)->dataType = GEOMETRY_DATA_TYPE_FLOAT; \
- (pGeometry)->usage = GEOMETRY_USAGE_USERMEM; \
- (pGeometry)->primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; \
- (pGeometry)->size = 0; \
- (pGeometry)->endOffset = 0; \
- (pGeometry)->data = (pointer) 0; \
- (pGeometry)->buffer = NULL; \
- (pGeometry)->broken = FALSE; \
- (pGeometry)->xOff = 0; \
- (pGeometry)->yOff = 0; \
- xglGeometryResize (pScreen, pGeometry, _size); \
+#define GEOMETRY_USAGE_SYSMEM 3
+
+#define DEFAULT_GEOMETRY_USAGE GEOMETRY_USAGE_SYSMEM
+
+#define GEOMETRY_INIT(pScreen, pGeometry, _type, _usage, _size) \
+ { \
+ (pGeometry)->type = _type; \
+ (pGeometry)->usage = _usage; \
+ (pGeometry)->dataType = DEFAULT_GEOMETRY_DATA_TYPE; \
+ (pGeometry)->usage = _usage; \
+ (pGeometry)->size = 0; \
+ (pGeometry)->endOffset = 0; \
+ (pGeometry)->data = (pointer) 0; \
+ (pGeometry)->buffer = NULL; \
+ (pGeometry)->broken = FALSE; \
+ (pGeometry)->xOff = 0; \
+ (pGeometry)->yOff = 0; \
+ (pGeometry)->array = NULL; \
+ (pGeometry)->first = 0; \
+ (pGeometry)->count = 0; \
+ if (_type == GLITZ_GEOMETRY_TYPE_VERTEX) \
+ { \
+ (pGeometry)->width = 2; \
+ (pGeometry)->f.vertex.type = \
+ xglGeometryDataTypes[(pGeometry)->dataType].type; \
+ (pGeometry)->f.vertex.bytes_per_vertex = (pGeometry)->width * \
+ xglGeometryDataTypes[(pGeometry)->dataType].size; \
+ (pGeometry)->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS; \
+ (pGeometry)->f.vertex.attributes = 0; \
+ (pGeometry)->f.vertex.src.type = GLITZ_DATA_TYPE_FLOAT; \
+ (pGeometry)->f.vertex.src.size = GLITZ_COORDINATE_SIZE_X; \
+ (pGeometry)->f.vertex.src.offset = 0; \
+ (pGeometry)->f.vertex.mask.type = GLITZ_DATA_TYPE_FLOAT; \
+ (pGeometry)->f.vertex.mask.size = GLITZ_COORDINATE_SIZE_X; \
+ (pGeometry)->f.vertex.mask.offset = 0; \
+ } \
+ else \
+ { \
+ (pGeometry)->width = 0; \
+ (pGeometry)->f.bitmap.scanline_order = \
+ GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN; \
+ (pGeometry)->f.bitmap.bytes_per_line = 0; \
+ (pGeometry)->f.bitmap.pad = GLYPHPADBYTES; \
+ } \
+ if (_size) \
+ xglGeometryResize (pScreen, pGeometry, _size); \
}
-#define GEOMETRY_UNINIT(pGeometry) \
+#define GEOMETRY_UNINIT(pGeometry) \
+ { \
+ if ((pGeometry)->array) \
+ glitz_multi_array_destroy ((pGeometry)->array); \
+ if ((pGeometry)->buffer) \
+ glitz_buffer_destroy ((pGeometry)->buffer); \
+ if ((pGeometry)->data) \
+ xfree ((pGeometry)->data); \
+ }
+
+#define GEOMETRY_SET_BUFFER(pGeometry, _buffer) \
{ \
+ glitz_buffer_reference (_buffer); \
if ((pGeometry)->buffer) \
glitz_buffer_destroy ((pGeometry)->buffer); \
- if ((pGeometry)->data) \
- xfree ((pGeometry)->data); \
+ (pGeometry)->buffer = _buffer; \
}
-#define GEOMETRY_SET_PRIMITIVE(pScreen, pGeometry, _primitive) \
- (pGeometry)->primitive = _primitive
+#define GEOMETRY_SET_MULTI_ARRAY(pGeometry, _array) \
+ { \
+ glitz_multi_array_reference (_array); \
+ if ((pGeometry)->array) \
+ glitz_multi_array_destroy ((pGeometry)->array); \
+ (pGeometry)->array = _array; \
+ }
#define GEOMETRY_RESIZE(pScreen, pGeometry, size) \
xglGeometryResize (pScreen, pGeometry, size)
+#define GEOMETRY_SET_TRANSLATE(pGeometry, _x, _y) \
+ { \
+ (pGeometry)->xOff = (_x) << 16; \
+ (pGeometry)->yOff = (_y) << 16; \
+ }
+
#define GEOMETRY_TRANSLATE(pGeometry, tx, ty) \
{ \
(pGeometry)->xOff += (tx) << 16; \
@@ -522,34 +693,64 @@ xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea);
(pGeometry)->yOff += (fty); \
}
-#define GEOMETRY_ADD_RECT(pScreen, pGeometry, pRect, nRect) \
- xglGeometryAddRect (pScreen, pGeometry, pRect, nRect)
+#define GEOMETRY_SET_VERTEX_PRIMITIVE(pGeometry, _primitive) \
+ (pGeometry)->f.vertex.primitive = _primitive
+
+#define GEOMETRY_SET_VERTEX_DATA_TYPE(pGeometry, _type) \
+ { \
+ (pGeometry)->dataType = _type; \
+ (pGeometry)->f.vertex.type = xglGeometryDataTypes[_type].type; \
+ (pGeometry)->f.vertex.bytes_per_vertex = (pGeometry)->width * \
+ xglGeometryDataTypes[_type].size; \
+ }
#define GEOMETRY_ADD_BOX(pScreen, pGeometry, pBox, nBox) \
- xglGeometryAddBox (pScreen, pGeometry, pBox, nBox)
+ xglGeometryAddBox (pScreen, pGeometry, pBox, nBox, \
+ (pGeometry)->endOffset)
+
+#define GEOMETRY_ADD_REGION_AT(pScreen, pGeometry, pRegion, offset) \
+ xglGeometryAddBox (pScreen, pGeometry, \
+ REGION_RECTS (pRegion), \
+ REGION_NUM_RECTS (pRegion), \
+ offset)
#define GEOMETRY_ADD_REGION(pScreen, pGeometry, pRegion) \
xglGeometryAddBox (pScreen, pGeometry, \
REGION_RECTS (pRegion), \
- REGION_NUM_RECTS (pRegion))
+ REGION_NUM_RECTS (pRegion), \
+ (pGeometry)->endOffset)
#define GEOMETRY_ADD_SPAN(pScreen, pGeometry, ppt, pwidth, n) \
- xglGeometryAddSpan (pScreen, pGeometry, ppt, pwidth, n)
+ xglGeometryAddSpan (pScreen, pGeometry, ppt, pwidth, n, \
+ (pGeometry)->endOffset)
#define GEOMETRY_ADD_LINE(pScreen, pGeometry, loop, mode, npt, ppt) \
- xglGeometryAddLine (pScreen, pGeometry, loop, mode, npt, ppt)
+ xglGeometryAddLine (pScreen, pGeometry, loop, mode, npt, ppt, \
+ (pGeometry)->endOffset)
#define GEOMETRY_ADD_SEGMENT(pScreen, pGeometry, nsegInit, pSegInit) \
- xglGeometryAddSegment (pScreen, pGeometry, nsegInit, pSegInit)
+ xglGeometryAddSegment (pScreen, pGeometry, nsegInit, pSegInit, \
+ (pGeometry)->endOffset)
-#define GEOMETRY_ENABLE(pGeometry, surface, first, count) \
- xglSetGeometry (pGeometry, surface, first, count);
+#define GEOMETRY_FOR_GLYPH(pScreen, pGeometry, nGlyph, ppciInit, pglyphBase) \
+ xglGeometryForGlyph (pScreen, pGeometry, nGlyph, ppciInit, pglyphBase);
-#define GEOMETRY_ENABLE_ALL_VERTICES(pGeometry, surface) \
- xglSetGeometry (pGeometry, surface, 0, (pGeometry)->endOffset / 2)
+#define GEOMETRY_ADD_TRAPEZOID(pScreen, pGeometry, pTrap, nTrap) \
+ xglGeometryAddTrapezoid (pScreen, pGeometry, pTrap, nTrap, \
+ (pGeometry)->endOffset)
-#define GEOMETRY_DISABLE(surface) \
- glitz_set_geometry (surface, 0, 0, NULL, NULL)
+#define GEOMETRY_ADD_TRAP(pScreen, pGeometry, pTrap, nTrap) \
+ xglGeometryAddTrap (pScreen, pGeometry, pTrap, nTrap, \
+ (pGeometry)->endOffset)
+
+#define GEOMETRY_GET_FORMAT(pGeometry, format) \
+ xglGeometryGetFormat (pGeometry, format)
+
+#define GEOMETRY_ENABLE(pGeometry, surface) \
+ xglSetGeometry (pGeometry, surface)
+
+#define GEOMETRY_DISABLE(surface) \
+ glitz_set_geometry (surface, GLITZ_GEOMETRY_TYPE_NONE, NULL, NULL)
void
xglGeometryResize (ScreenPtr pScreen,
@@ -557,23 +758,19 @@ xglGeometryResize (ScreenPtr pScreen,
int size);
void
-xglGeometryAddRect (ScreenPtr pScreen,
- xglGeometryPtr pGeometry,
- xRectangle *pRect,
- int nRect);
-
-void
xglGeometryAddBox (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
BoxPtr pBox,
- int nBox);
+ int nBox,
+ int offset);
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
- int n);
+ int n,
+ int offset);
void
xglGeometryAddLine (ScreenPtr pScreen,
@@ -581,19 +778,53 @@ xglGeometryAddLine (ScreenPtr pScreen,
int loop,
int mode,
int npt,
- DDXPointPtr ppt);
+ DDXPointPtr ppt,
+ int offset);
void
xglGeometryAddSegment (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
int nsegInit,
- xSegment *pSegInit);
+ xSegment *pSegInit,
+ int offset);
+
+void
+xglGeometryForGlyph (ScreenPtr pScreen,
+ xglGeometryPtr pGeometry,
+ unsigned int nGlyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase);
+
+void
+xglGeometryAddTrapezoid (ScreenPtr pScreen,
+ xglGeometryPtr pGeometry,
+ xTrapezoid *pTrap,
+ int nTrap,
+ int offset);
+
+void
+xglGeometryAddTrap (ScreenPtr pScreen,
+ xglGeometryPtr pGeometry,
+ xTrap *pTrap,
+ int nTrap,
+ int offset);
+
+xglGeometryPtr
+xglGetScratchGeometryWithSize (ScreenPtr pScreen,
+ int size);
+
+xglGeometryPtr
+xglGetScratchVertexGeometryWithType (ScreenPtr pScreen,
+ int type,
+ int count);
+
+xglGeometryPtr
+xglGetScratchVertexGeometry (ScreenPtr pScreen,
+ int count);
Bool
xglSetGeometry (xglGeometryPtr pGeometry,
- glitz_surface_t *surface,
- int first,
- int count);
+ glitz_surface_t *surface);
/* xglpixmap.c */
@@ -619,6 +850,11 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
RegionPtr
xglPixmapToRegion (PixmapPtr pPixmap);
+xglGeometryPtr
+xglPixmapToGeometry (PixmapPtr pPixmap,
+ int xOff,
+ int yOff);
+
Bool
xglCreatePixmapSurface (PixmapPtr pPixmap);
@@ -648,10 +884,14 @@ Bool
xglPrepareTarget (DrawablePtr pDrawable);
void
-xglAddSurfaceDamage (DrawablePtr pDrawable);
+xglAddSurfaceDamage (DrawablePtr pDrawable,
+ RegionPtr pRegion);
+
+void
+xglAddCurrentSurfaceDamage (DrawablePtr pDrawable);
void
-xglAddBitDamage (DrawablePtr pDrawable);
+xglAddCurrentBitDamage (DrawablePtr pDrawable);
/* xglsolid.c */
@@ -661,12 +901,32 @@ xglSolid (DrawablePtr pDrawable,
glitz_operator_t op,
glitz_color_t *color,
xglGeometryPtr pGeometry,
+ int x,
+ int y,
+ int width,
+ int height,
BoxPtr pBox,
int nBox);
+Bool
+xglSolidGlyph (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase);
+
/* xgltile.c */
+xglGeometryPtr
+xglTiledBoxGeometry (PixmapPtr pTile,
+ int tileX,
+ int tileY,
+ BoxPtr pBox,
+ int nBox);
+
Bool
xglTile (DrawablePtr pDrawable,
glitz_operator_t op,
@@ -674,41 +934,13 @@ xglTile (DrawablePtr pDrawable,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
+ int x,
+ int y,
+ int width,
+ int height,
BoxPtr pBox,
int nBox);
-#define TILE_SOURCE 0
-#define TILE_MASK 1
-
-void
-xglSwTile (glitz_operator_t op,
- glitz_surface_t *srcSurface,
- glitz_surface_t *maskSurface,
- glitz_surface_t *dstSurface,
- int xSrc,
- int ySrc,
- int xMask,
- int yMask,
- int what,
- BoxPtr pBox,
- int nBox,
- int xOff,
- int yOff);
-
-
-/* xglpixel.c */
-
-Bool
-xglSetPixels (DrawablePtr pDrawable,
- char *src,
- int stride,
- int x,
- int y,
- int width,
- int height,
- BoxPtr pBox,
- int nBox);
-
/* xglcopy.c */
@@ -737,9 +969,15 @@ xglCopyProc (DrawablePtr pSrc,
/* xglfill.c */
Bool
-xglFill (DrawablePtr pDrawable,
- GCPtr pGC,
- xglGeometryPtr pGeometry);
+xglFill (DrawablePtr pDrawable,
+ GCPtr pGC,
+ xglGeometryPtr pGeometry,
+ int x,
+ int y,
+ int width,
+ int height,
+ BoxPtr pBox,
+ int nBox);
Bool
xglFillSpan (DrawablePtr pDrawable,
@@ -748,7 +986,7 @@ xglFillSpan (DrawablePtr pDrawable,
DDXPointPtr ppt,
int *pwidth);
-Bool
+void
xglFillRect (DrawablePtr pDrawable,
GCPtr pGC,
int nrect,
@@ -767,12 +1005,25 @@ xglFillSegment (DrawablePtr pDrawable,
int nsegInit,
xSegment *pSegInit);
+Bool
+xglFillGlyph (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nglyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase);
+
/* xglwindow.c */
Bool
xglCreateWindow (WindowPtr pWin);
+Bool
+xglChangeWindowAttributes (WindowPtr pWin,
+ unsigned long mask);
+
void
xglCopyWindow (WindowPtr pWin,
DDXPointRec ptOldOrg,
@@ -959,18 +1210,20 @@ xglPushPixels (GCPtr pGC,
/* xglcomp.c */
Bool
-xglComp (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
+xglComp (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height,
+ xglGeometryPtr pGeometry,
+ glitz_surface_t *mask);
/* xglpict.c */
@@ -990,21 +1243,11 @@ xglComposite (CARD8 op,
CARD16 height);
void
-xglGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
-
-void
-xglRasterizeTrapezoid (PicturePtr pDst,
- xTrapezoid *trap,
- int xOff,
- int yOff);
+xglAddTriangles (PicturePtr pDst,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris);
void
xglChangePicture (PicturePtr pPicture,
@@ -1023,6 +1266,59 @@ xglChangePictureFilter (PicturePtr pPicture,
void
xglUpdatePicture (PicturePtr pPicture);
+Bool
+xglPictureInit (ScreenPtr pScreen);
+
+
+/* xglglyph.c */
+
+Bool
+xglRealizeGlyph (ScreenPtr pScreen,
+ GlyphPtr pGlyph);
+
+void
+xglUnrealizeGlyph (ScreenPtr pScreen,
+ GlyphPtr pGlyph);
+
+Bool
+xglInitGlyphCache (xglGlyphCachePtr pCache,
+ ScreenPtr pScreen,
+ PictFormatPtr format);
+
+void
+xglFiniGlyphCache (xglGlyphCachePtr pCache);
+
+void
+xglGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+
+/* xgltrap.c */
+
+void
+xglTrapezoids (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nTrap,
+ xTrapezoid *traps);
+
+void
+xglAddTraps (PicturePtr pDst,
+ INT16 xOff,
+ INT16 yOff,
+ int nTrap,
+ xTrap *traps);
+
#endif
#endif /* _XGL_H_ */
diff --git a/hw/xgl/xglarea.c b/hw/xgl/xglarea.c
new file mode 100644
index 000000000..b09e454ba
--- /dev/null
+++ b/hw/xgl/xglarea.c
@@ -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);
+}
diff --git a/hw/xgl/xglbstore.c b/hw/xgl/xglbstore.c
index 8760efaec..65b4bbf5c 100644
--- a/hw/xgl/xglbstore.c
+++ b/hw/xgl/xglbstore.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -31,7 +31,7 @@
#define XGL_BSTORE_FALLBACK_EPILOGUE(pDrawable, func, xglfunc) \
XGL_SCREEN_WRAP (func, xglfunc); \
- xglAddSurfaceDamage (pDrawable)
+ xglAddCurrentSurfaceDamage (pDrawable)
/*
* The follwong functions are not yet tested so we can assume that they
@@ -61,7 +61,7 @@ xglSaveAreas (PixmapPtr pPixmap,
REGION_RECTS (prgnSave),
REGION_NUM_RECTS (prgnSave)))
{
- xglAddBitDamage (&pPixmap->drawable);
+ xglAddCurrentBitDamage (&pPixmap->drawable);
return;
}
@@ -101,7 +101,7 @@ xglRestoreAreas (PixmapPtr pPixmap,
REGION_RECTS (prgnRestore),
REGION_NUM_RECTS (prgnRestore)))
{
- xglAddBitDamage (&pPixmap->drawable);
+ xglAddCurrentBitDamage (&pPixmap->drawable);
return;
}
diff --git a/hw/xgl/xglcmap.c b/hw/xgl/xglcmap.c
index be383a103..3c7a9747c 100644
--- a/hw/xgl/xglcmap.c
+++ b/hw/xgl/xglcmap.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -257,7 +257,7 @@ xglClearVisualTypes (void)
void
xglInitPixmapFormats (ScreenPtr pScreen)
{
- glitz_format_t *format;
+ glitz_format_t *format, **best;
int i, j;
XGL_SCREEN_PRIV (pScreen);
@@ -275,6 +275,7 @@ xglInitPixmapFormats (ScreenPtr pScreen)
pScreenPriv->pixmapFormats[i].pPixel = &xglPixelFormats[j];
pScreenPriv->pixmapFormats[i].format = NULL;
+ best = &pScreenPriv->pixmapFormats[i].format;
rs = Ones (xglPixelFormats[j].masks.red_mask);
gs = Ones (xglPixelFormats[j].masks.green_mask);
@@ -287,13 +288,28 @@ xglInitPixmapFormats (ScreenPtr pScreen)
0, NULL, k++);
if (format && format->type == GLITZ_FORMAT_TYPE_COLOR)
{
- if (rs == format->color.red_size &&
- gs == format->color.green_size &&
- bs == format->color.blue_size &&
- as == format->color.alpha_size)
+ /* formats must have an alpha channel, otherwise
+ filtering wont match the render spec. */
+ if (!format->color.alpha_size)
+ continue;
+
+ /* find best matching sufficient format */
+ if (format->color.red_size >= rs &&
+ format->color.green_size >= gs &&
+ format->color.blue_size >= bs &&
+ format->color.alpha_size >= as)
{
- pScreenPriv->pixmapFormats[i].format = format;
- break;
+ if (*best)
+ {
+ if (((format->color.red_size - rs) +
+ (format->color.green_size - gs) +
+ (format->color.blue_size - bs)) <
+ (((*best)->color.red_size - rs) +
+ ((*best)->color.green_size - gs) +
+ ((*best)->color.blue_size - bs)))
+ *best = format;
+ } else
+ *best = format;
}
}
} while (format);
diff --git a/hw/xgl/xglcomp.c b/hw/xgl/xglcomp.c
index edae5d3ad..320221c8a 100644
--- a/hw/xgl/xglcomp.c
+++ b/hw/xgl/xglcomp.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -49,22 +49,24 @@ static glitz_operator_t xglOperators[] = {
#define XGL_OPERATOR(op) (xglOperators[op])
Bool
-xglComp (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
+xglComp (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height,
+ xglGeometryPtr pGeometry,
+ glitz_surface_t *mask)
{
ScreenPtr pScreen = pDst->pDrawable->pScreen;
- xglPixmapPtr pSrcPriv, pMaskPriv;
- glitz_surface_t *dst;
+ xglPixmapPtr pSrcPriv;
+ glitz_surface_t *src, *dst;
int dstXoff, dstYoff;
RegionRec region;
BoxPtr pBox;
@@ -78,24 +80,21 @@ xglComp (CARD8 op,
if (op >= NUM_XGL_OPERATORS)
return FALSE;
-
+
if (pSrc->pDrawable->type != DRAWABLE_PIXMAP)
return FALSE;
+ if (pSrc->pDrawable->bitsPerPixel == 1)
+ return FALSE;
+
if (pMask)
{
if (pMask->pDrawable->type != DRAWABLE_PIXMAP)
return FALSE;
- /*
- * Why?
- */
- if (pSrc->pDrawable == pMask->pDrawable)
+ if (pSrc->pDrawable == pMask->pDrawable && pSrc != pMask)
return FALSE;
}
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask,
@@ -105,29 +104,6 @@ xglComp (CARD8 op,
pBox = REGION_RECTS (&region);
nBox = REGION_NUM_RECTS (&region);
- /*
- * Simple copy
- */
- if (op == PictOpSrc && !pMask &&
- !pSrc->transform && !pSrc->repeat && pSrc->filter <= 1)
- {
- if (xglCopy (pSrc->pDrawable,
- pDst->pDrawable,
- xSrc - xDst,
- ySrc - yDst,
- pBox,
- nBox))
- {
- REGION_UNINIT (pScreen, &region);
- xglAddBitDamage (pDst->pDrawable);
-
- return TRUE;
- }
-
- REGION_UNINIT (pScreen, &region);
- return FALSE;
- }
-
if (!xglPrepareTarget (pDst->pDrawable))
{
REGION_UNINIT (pScreen, &region);
@@ -135,116 +111,159 @@ xglComp (CARD8 op,
}
XGL_GET_DRAWABLE (pDst->pDrawable, dst, dstXoff, dstYoff);
-
+
if (!xglSyncSurface (pSrc->pDrawable))
{
REGION_UNINIT (pScreen, &region);
return FALSE;
}
-
+
pSrcPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable);
if (XGL_PICTURE_CHANGES (pSrcPriv->pictureMask))
xglUpdatePicture (pSrc);
+ src = pSrcPriv->surface;
+
if (pMask)
{
- if (!xglSyncSurface (pMask->pDrawable))
+ xglPixmapPtr pMaskPriv;
+
+ /* bitmap as mask */
+ if (pMask->pDrawable->bitsPerPixel == 1)
{
- REGION_UNINIT (pScreen, &region);
- return FALSE;
+ 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;
+ }
+ }
- pMaskPriv = XGL_GET_PIXMAP_PRIV ((PixmapPtr) pMask->pDrawable);
- if (XGL_PICTURE_CHANGES (pMaskPriv->pictureMask))
- xglUpdatePicture (pMask);
- } else
- pMaskPriv = NULL;
-
- if (nBox > 1)
+ if (!pGeometry)
{
- xglGeometryRec geometry;
-
- GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (&region) << 3);
- GEOMETRY_ADD_BOX (pScreen, &geometry, pBox, nBox);
- GEOMETRY_TRANSLATE (&geometry, dstXoff, dstYoff);
-
- if (!GEOMETRY_ENABLE_ALL_VERTICES (&geometry, dst))
+ if (!pSrc->transform && pSrc->filter != PictFilterConvolution)
{
- GEOMETRY_UNINIT (&geometry);
- return FALSE;
+ 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;
+ }
+ }
+ }
}
- pBox = REGION_EXTENTS (pScreen, &region);
- } else
- GEOMETRY_DISABLE (dst);
+ if (nBox > 1)
+ {
+ pGeometry = xglGetScratchVertexGeometry (pScreen, 4 * nBox);
+
+ GEOMETRY_ADD_BOX (pScreen, pGeometry, pBox, nBox);
+
+ pBox = REGION_EXTENTS (pScreen, &region);
+ }
- xSrc += pBox->x1 - xDst;
- ySrc += pBox->y1 - yDst;
+ xSrc += pBox->x1 - xDst;
+ ySrc += pBox->y1 - yDst;
- if (pMask)
- {
- xMask += pBox->x1 - xDst;
- yMask += pBox->y1 - yDst;
- }
+ if (pMask)
+ {
+ xMask += pBox->x1 - xDst;
+ yMask += pBox->y1 - yDst;
+ }
- xDst = pBox->x1;
- yDst = pBox->y1;
+ xDst = pBox->x1;
+ yDst = pBox->y1;
- width = pBox->x2 - pBox->x1;
- height = pBox->y2 - pBox->y1;
-
- REGION_UNINIT (pScreen, &region);
+ width = pBox->x2 - pBox->x1;
+ height = pBox->y2 - pBox->y1;
+ }
+ else
+ {
+ glitz_surface_set_clip_region (dst,
+ dstXoff, dstYoff,
+ (glitz_box_t *) pBox, nBox);
+ }
- /*
- * Do software tile instead if hardware can't do it.
- */
- if (pSrc->repeat && !pSrcPriv->acceleratedTile)
+ if (pGeometry)
{
- BoxRec box;
+ GEOMETRY_TRANSLATE (pGeometry, dstXoff, dstYoff);
- if (pSrc->transform || pSrc->filter > 1)
- return FALSE;
-
- /*
- * Don't allow software tile with really small pixmaps.
- */
- if (pSrc->pDrawable->width < 8 && pSrc->pDrawable->height < 8)
+ if (!GEOMETRY_ENABLE (pGeometry, dst))
+ {
+ REGION_UNINIT (pScreen, &region);
return FALSE;
+ }
+ } else
+ GEOMETRY_DISABLE (dst);
- box.x1 = xDst + dstXoff;
- box.y1 = yDst + dstYoff;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- glitz_surface_set_fill (pSrcPriv->surface, GLITZ_FILL_TRANSPARENT);
-
- xglSwTile (XGL_OPERATOR (op),
- pSrcPriv->surface,
- (pMaskPriv)? pMaskPriv->surface: NULL,
- dst,
- xSrc - box.x1, ySrc - box.y1,
- xMask - box.x1, yMask - box.y1,
- TILE_SOURCE,
- &box, 1,
- 0, 0);
- }
- else
- {
- glitz_composite (XGL_OPERATOR (op),
- pSrcPriv->surface,
- (pMaskPriv)? pMaskPriv->surface: NULL,
- dst,
- xSrc, ySrc,
- xMask, yMask,
- xDst + dstXoff, yDst + dstYoff,
- width, height);
- }
+ glitz_composite (XGL_OPERATOR (op),
+ src, mask, dst,
+ xSrc, ySrc,
+ xMask, yMask,
+ xDst + dstXoff, yDst + dstYoff,
+ width, height);
+
+ glitz_surface_set_clip_region (dst, 0, 0, NULL, 0);
+
+ REGION_UNINIT (pScreen, &region);
if (glitz_surface_get_status (dst))
return FALSE;
- xglAddBitDamage (pDst->pDrawable);
-
return TRUE;
}
diff --git a/hw/xgl/xglcopy.c b/hw/xgl/xglcopy.c
index aca4ea418..c34459b5a 100644
--- a/hw/xgl/xglcopy.c
+++ b/hw/xgl/xglcopy.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,10 +20,11 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
+#include "fb.h"
Bool
xglCopy (DrawablePtr pSrc,
@@ -33,101 +34,59 @@ xglCopy (DrawablePtr pSrc,
BoxPtr pBox,
int nBox)
{
- glitz_surface_t *srcSurface;
- glitz_surface_t *dstSurface;
+ glitz_surface_t *src, *dst;
int srcXoff, srcYoff;
int dstXoff, dstYoff;
+ if (!nBox)
+ return TRUE;
+
if (xglPrepareTarget (pDst))
{
- glitz_drawable_t *srcDrawable;
- glitz_drawable_t *dstDrawable;
-
XGL_SCREEN_PRIV (pDst->pScreen);
- XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
-
+
if (!xglSyncSurface (pSrc))
return FALSE;
- XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff);
- XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
-
- /*
- * Blit to screen.
- */
- if (dstSurface == pScreenPriv->surface)
- XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 5000);
+ XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
- srcDrawable = glitz_surface_get_attached_drawable (srcSurface);
- dstDrawable = glitz_surface_get_attached_drawable (dstSurface);
-
- if (srcDrawable != dstDrawable && nBox > 1)
+ /* blit to screen */
+ if (dst == pScreenPriv->surface)
{
- xglGeometryRec geometry;
- BoxRec extents;
-
- BOX_EXTENTS (pBox, nBox, &extents);
-
- GEOMETRY_INIT (pDst->pScreen, &geometry, nBox << 3);
- GEOMETRY_ADD_BOX (pDst->pScreen, &geometry, pBox, nBox);
- GEOMETRY_TRANSLATE (&geometry, dstXoff, dstYoff);
-
- if (!GEOMETRY_ENABLE_ALL_VERTICES (&geometry, dstSurface))
- return FALSE;
+ XGL_DRAWABLE_PIXMAP_PRIV (pSrc);
- pPixmapPriv->pictureMask |=
- xglPCFillMask | xglPCFilterMask | xglPCTransformMask;
-
- glitz_surface_set_fill (srcSurface, GLITZ_FILL_TRANSPARENT);
- glitz_surface_set_filter (srcSurface, GLITZ_FILTER_NEAREST,
- NULL, 0);
- glitz_surface_set_transform (srcSurface, NULL);
-
- glitz_composite (GLITZ_OPERATOR_SRC,
- srcSurface, NULL, dstSurface,
- extents.x1 + dx + srcXoff,
- extents.y1 + dy + srcYoff,
- 0, 0,
- extents.x1 + dstXoff,
- extents.y1 + dstYoff,
- extents.x2 - extents.x1,
- extents.y2 - extents.y1);
-
- GEOMETRY_UNINIT (&geometry);
-
- if (glitz_surface_get_status (dstSurface))
- return FALSE;
-
- return TRUE;
+ XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 5000);
}
}
else
{
if (!xglPrepareTarget (pSrc))
return FALSE;
-
+
if (!xglSyncSurface (pDst))
return FALSE;
-
- XGL_GET_DRAWABLE (pSrc, srcSurface, srcXoff, srcYoff);
- XGL_GET_DRAWABLE (pDst, dstSurface, dstXoff, dstYoff);
+
+ XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
}
- while (nBox--)
- {
- glitz_copy_area (srcSurface,
- dstSurface,
- pBox->x1 + dx + srcXoff,
- pBox->y1 + dy + srcYoff,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- pBox->x1 + dstXoff,
- pBox->y1 + dstYoff);
+ XGL_GET_DRAWABLE (pSrc, src, srcXoff, srcYoff);
- pBox++;
- }
+ glitz_surface_set_clip_region (dst,
+ dstXoff, dstYoff,
+ (glitz_box_t *) pBox, nBox);
+
+ glitz_copy_area (src,
+ dst,
+ pDst->x + srcXoff + dx,
+ pDst->y + srcYoff + dy,
+ pDst->width,
+ pDst->height,
+ pDst->x + dstXoff,
+ pDst->y + dstYoff);
- if (glitz_surface_get_status (dstSurface))
+ glitz_surface_set_clip_region (dst, 0, 0, NULL, 0);
+
+ if (glitz_surface_get_status (dst))
return FALSE;
return TRUE;
@@ -146,7 +105,59 @@ xglCopyProc (DrawablePtr pSrc,
Pixel bitplane,
void *closure)
{
- Bool *pRet = (Bool *) closure;
-
- *pRet = xglCopy (pSrc, pDst, dx, dy, pBox, nBox);
+ BoxPtr pSrcBox = (BoxPtr) closure;
+
+ if (!xglCopy (pSrc, pDst, dx, dy, pBox, nBox))
+ {
+ RegionPtr pDamageRegion;
+ glitz_surface_t *dst;
+ int dstXoff, dstYoff;
+ RegionRec region;
+ BoxRec box;
+
+ XGL_DRAWABLE_PIXMAP (pDst);
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ XGL_GET_DRAWABLE (pDst, dst, dstXoff, dstYoff);
+
+ pDamageRegion = DamageRegion (pPixmapPriv->pDamage);
+
+ if (!xglMapPixmapBits (pPixmap))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ if (!xglSyncBits (pSrc, pSrcBox))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ fbCopyNtoN (pSrc, pDst, pGC,
+ pBox, nBox,
+ dx, dy,
+ reverse, upsidedown, bitplane,
+ (void *) 0);
+
+ pPixmapPriv->damageBox = miEmptyBox;
+ if (!pPixmapPriv->format)
+ return;
+
+ while (nBox--)
+ {
+ box.x1 = pBox->x1 + dstXoff;
+ box.y1 = pBox->y1 + dstYoff;
+ box.x2 = pBox->x2 + dstXoff;
+ box.y2 = pBox->y2 + dstYoff;
+
+ REGION_INIT (pDst->pScreen, &region, &box, 1);
+ REGION_UNION (pDst->pScreen,
+ pDamageRegion, pDamageRegion, &region);
+ REGION_UNINIT (pDst->pScreen, &region);
+
+ pBox++;
+ }
+
+ if (pPixmapPriv->target == xglPixmapTargetIn)
+ {
+ if (!xglSyncSurface (pDst))
+ FatalError (XGL_SW_FAILURE_STRING);
+ }
+ } else
+ xglAddCurrentBitDamage (pDst);
}
diff --git a/hw/xgl/xglfill.c b/hw/xgl/xglfill.c
index 7bb2c8d4d..7832df27e 100644
--- a/hw/xgl/xglfill.c
+++ b/hw/xgl/xglfill.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,36 +20,48 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "gcstruct.h"
+#include "fb.h"
Bool
xglFill (DrawablePtr pDrawable,
GCPtr pGC,
- xglGeometryPtr pGeometry)
+ xglGeometryPtr pGeometry,
+ int x,
+ int y,
+ int width,
+ int height,
+ BoxPtr pBox,
+ int nBox)
{
XGL_GC_PRIV (pGC);
switch (pGC->fillStyle) {
case FillSolid:
- if (xglSolid (pDrawable, pGCPriv->op, &pGCPriv->fg,
+ if (xglSolid (pDrawable,
+ pGCPriv->op, &pGCPriv->fg,
pGeometry,
- REGION_RECTS (pGC->pCompositeClip),
- REGION_NUM_RECTS (pGC->pCompositeClip)))
+ x, y,
+ width, height,
+ pBox, nBox))
return TRUE;
break;
case FillStippled:
case FillOpaqueStippled:
break;
case FillTiled:
- if (xglTile (pDrawable, pGCPriv->op, pGC->tile.pixmap,
- -pGC->patOrg.x, -pGC->patOrg.y,
+ if (xglTile (pDrawable,
+ pGCPriv->op, pGC->tile.pixmap,
+ -(pGC->patOrg.x + pDrawable->x),
+ -(pGC->patOrg.y + pDrawable->y),
pGeometry,
- REGION_RECTS (pGC->pCompositeClip),
- REGION_NUM_RECTS (pGC->pCompositeClip)))
+ x, y,
+ width, height,
+ pBox, nBox))
return TRUE;
break;
}
@@ -57,26 +69,163 @@ xglFill (DrawablePtr pDrawable,
return FALSE;
}
-Bool
+#define N_STACK_BOX 1024
+
+static BoxPtr
+xglMoreBoxes (BoxPtr stackBox,
+ BoxPtr heapBox,
+ int nBoxes)
+{
+ Bool stack = !heapBox;
+
+ heapBox = xrealloc (heapBox, sizeof (BoxRec) * nBoxes);
+ if (!heapBox)
+ return NULL;
+
+ if (stack)
+ memcpy (heapBox, stackBox, sizeof (BoxRec) * N_STACK_BOX);
+
+ return heapBox;
+}
+
+#define ADD_BOX(pBox, nBox, stackBox, heapBox, size, box) \
+ { \
+ if ((nBox) == (size)) \
+ { \
+ (size) *= 2; \
+ (heapBox) = xglMoreBoxes (stackBox, heapBox, size); \
+ if (!(heapBox)) \
+ return; \
+ (pBox) = (heapBox) + (nBox); \
+ } \
+ *(pBox)++ = (box); \
+ (nBox)++; \
+ }
+
+void
xglFillRect (DrawablePtr pDrawable,
GCPtr pGC,
int nrect,
xRectangle *prect)
{
- xglGeometryRec geometry;
+ RegionPtr pClip = pGC->pCompositeClip;
+ BoxPtr pClipBox;
+ BoxPtr pExtent = REGION_EXTENTS (pGC->pScreen, pClip);
+ BoxRec full, part;
+ BoxPtr heapBox = NULL;
+ BoxRec stackBox[N_STACK_BOX];
+ int size = N_STACK_BOX;
+ BoxPtr pBox = stackBox;
+ int n, nBox = 0;
- GEOMETRY_INIT (pGC->pScreen, &geometry, nrect << 3);
- GEOMETRY_ADD_RECT (pGC->pScreen, &geometry, prect, nrect);
- GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
-
- if (xglFill (pDrawable, pGC, &geometry))
+ while (nrect--)
{
- GEOMETRY_UNINIT (&geometry);
- return TRUE;
- }
+ full.x1 = prect->x + pDrawable->x;
+ full.y1 = prect->y + pDrawable->y;
+ full.x2 = full.x1 + (int) prect->width;
+ full.y2 = full.y1 + (int) prect->height;
+
+ prect++;
+
+ if (full.x1 < pExtent->x1)
+ full.x1 = pExtent->x1;
+
+ if (full.y1 < pExtent->y1)
+ full.y1 = pExtent->y1;
+
+ if (full.x2 > pExtent->x2)
+ full.x2 = pExtent->x2;
+
+ if (full.y2 > pExtent->y2)
+ full.y2 = pExtent->y2;
+
+ if (full.x1 >= full.x2 || full.y1 >= full.y2)
+ continue;
+
+ n = REGION_NUM_RECTS (pClip);
+
+ if (n == 1)
+ {
+ ADD_BOX (pBox, nBox, stackBox, heapBox, size, full);
+ }
+ else
+ {
+ pClipBox = REGION_RECTS (pClip);
+
+ while (n--)
+ {
+ part.x1 = pClipBox->x1;
+ if (part.x1 < full.x1)
+ part.x1 = full.x1;
+
+ part.y1 = pClipBox->y1;
+ if (part.y1 < full.y1)
+ part.y1 = full.y1;
+
+ part.x2 = pClipBox->x2;
+ if (part.x2 > full.x2)
+ part.x2 = full.x2;
+
+ part.y2 = pClipBox->y2;
+ if (part.y2 > full.y2)
+ part.y2 = full.y2;
- GEOMETRY_UNINIT (&geometry);
- return FALSE;
+ pClipBox++;
+
+ if (part.x1 < part.x2 && part.y1 < part.y2)
+ ADD_BOX (pBox, nBox, stackBox, heapBox, size, part);
+ }
+ }
+ }
+
+ pBox = (heapBox) ? heapBox : stackBox;
+
+ if (!xglFill (pDrawable, pGC, NULL,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ pBox, nBox))
+ {
+ RegionRec region;
+ Bool overlap;
+
+ XGL_DRAWABLE_PIXMAP (pDrawable);
+
+ if (!xglMapPixmapBits (pPixmap))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ switch (pGC->fillStyle) {
+ case FillSolid:
+ break;
+ case FillStippled:
+ case FillOpaqueStippled:
+ if (!xglSyncBits (&pGC->stipple->drawable, NullBox))
+ FatalError (XGL_SW_FAILURE_STRING);
+ break;
+ case FillTiled:
+ if (!xglSyncBits (&pGC->tile.pixmap->drawable, NullBox))
+ FatalError (XGL_SW_FAILURE_STRING);
+ break;
+ }
+
+ REGION_INIT (pGC->pScreen, &region, pBox, nBox);
+
+ while (nBox--)
+ {
+ fbFill (pDrawable, pGC,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ /* hmm, overlap can't be good, don't know what to do about that */
+ REGION_VALIDATE (pGC->pScreen, &region, &overlap);
+ xglAddSurfaceDamage (pDrawable, &region);
+ REGION_UNINIT (pGC->pScreen, &region);
+ } else
+ xglAddCurrentBitDamage (pDrawable);
+
+ if (heapBox)
+ xfree (heapBox);
}
Bool
@@ -86,23 +235,26 @@ xglFillSpan (DrawablePtr pDrawable,
DDXPointPtr ppt,
int *pwidth)
{
- xglGeometryRec geometry;
+ BoxPtr pExtent;
+ xglGeometryPtr pGeometry;
- GEOMETRY_INIT (pGC->pScreen, &geometry, n << 2);
- GEOMETRY_ADD_SPAN (pGC->pScreen, &geometry, ppt, pwidth, n);
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
+
+ pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * n);
+
+ GEOMETRY_ADD_SPAN (pGC->pScreen, pGeometry, ppt, pwidth, n);
/* Spans are treated as lines so they need a 0.5 translate */
- GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15);
- GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
- GLITZ_GEOMETRY_PRIMITIVE_LINES);
+ GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
+ GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
- if (xglFill (pDrawable, pGC, &geometry))
- {
- GEOMETRY_UNINIT (&geometry);
+ if (xglFill (pDrawable, pGC, pGeometry,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ REGION_RECTS (pGC->pCompositeClip),
+ REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE;
- }
- GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@@ -113,9 +265,12 @@ xglFillLine (DrawablePtr pDrawable,
int npt,
DDXPointPtr ppt)
{
- xglGeometryRec geometry;
+ BoxPtr pExtent;
+ xglGeometryPtr pGeometry;
Bool coincident_endpoints;
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
+
coincident_endpoints = FALSE;
if (mode == CoordModePrevious)
{
@@ -148,29 +303,30 @@ xglFillLine (DrawablePtr pDrawable,
if (coincident_endpoints)
npt--;
- GEOMETRY_INIT (pGC->pScreen, &geometry, npt << 1);
- GEOMETRY_ADD_LINE (pGC->pScreen, &geometry,
+ pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, npt);
+
+ GEOMETRY_ADD_LINE (pGC->pScreen, pGeometry,
coincident_endpoints, mode, npt, ppt);
if (coincident_endpoints)
- GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
- GLITZ_GEOMETRY_PRIMITIVE_LINE_LOOP);
+ GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_LOOP);
else
- GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
- GLITZ_GEOMETRY_PRIMITIVE_LINE_STRIP);
+ GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINE_STRIP);
/* Lines need a 0.5 translate */
- GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15);
+ GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
- GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
+ GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
+
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
- if (xglFill (pDrawable, pGC, &geometry))
- {
- GEOMETRY_UNINIT (&geometry);
+ if (xglFill (pDrawable, pGC, pGeometry,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ REGION_RECTS (pGC->pCompositeClip),
+ REGION_NUM_RECTS (pGC->pCompositeClip)))
return TRUE;
- }
- GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@@ -180,19 +336,65 @@ xglFillSegment (DrawablePtr pDrawable,
int nsegInit,
xSegment *pSegInit)
{
- xglGeometryRec geometry;
+ BoxPtr pExtent;
+ xglGeometryPtr pGeometry;
- GEOMETRY_INIT (pGC->pScreen, &geometry, nsegInit << 2);
- GEOMETRY_ADD_SEGMENT (pGC->pScreen, &geometry, nsegInit, pSegInit);
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
+
+ pGeometry = xglGetScratchVertexGeometry (pGC->pScreen, 2 * nsegInit);
+
+ GEOMETRY_ADD_SEGMENT (pGC->pScreen, pGeometry, nsegInit, pSegInit);
/* Line segments need 0.5 translate */
- GEOMETRY_TRANSLATE_FIXED (&geometry, 1 << 15, 1 << 15);
- GEOMETRY_SET_PRIMITIVE (pGC->pScreen, &geometry,
- GLITZ_GEOMETRY_PRIMITIVE_LINES);
+ GEOMETRY_TRANSLATE_FIXED (pGeometry, 1 << 15, 1 << 15);
+ GEOMETRY_SET_VERTEX_PRIMITIVE (pGeometry, GLITZ_PRIMITIVE_LINES);
- GEOMETRY_TRANSLATE (&geometry, pDrawable->x, pDrawable->y);
+ GEOMETRY_TRANSLATE (pGeometry, pDrawable->x, pDrawable->y);
- if (xglFill (pDrawable, pGC, &geometry))
+ if (xglFill (pDrawable, pGC, pGeometry,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ REGION_RECTS (pGC->pCompositeClip),
+ REGION_NUM_RECTS (pGC->pCompositeClip)))
+ return TRUE;
+
+ return FALSE;
+}
+
+Bool
+xglFillGlyph (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ BoxPtr pExtent;
+ xglGeometryRec geometry;
+
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pGC->pCompositeClip);
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ GEOMETRY_INIT (pDrawable->pScreen, &geometry,
+ GLITZ_GEOMETRY_TYPE_BITMAP,
+ GEOMETRY_USAGE_SYSMEM, 0);
+
+ GEOMETRY_FOR_GLYPH (pDrawable->pScreen,
+ &geometry,
+ nGlyph,
+ ppci,
+ pglyphBase);
+
+ GEOMETRY_TRANSLATE (&geometry, x, y);
+
+ if (xglFill (pDrawable, pGC, &geometry,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ REGION_RECTS (pGC->pCompositeClip),
+ REGION_NUM_RECTS (pGC->pCompositeClip)))
{
GEOMETRY_UNINIT (&geometry);
return TRUE;
diff --git a/hw/xgl/xglgc.c b/hw/xgl/xglgc.c
index 971edb43b..bfe6cdaa2 100644
--- a/hw/xgl/xglgc.c
+++ b/hw/xgl/xglgc.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -36,7 +36,7 @@
#define XGL_GC_OP_FALLBACK_EPILOGUE(pDrawable) \
XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs); \
XGL_GC_WRAP (ops, (GCOps *) &xglGCOps); \
- xglAddSurfaceDamage (pDrawable)
+ xglAddCurrentSurfaceDamage (pDrawable)
#define XGL_GC_FILL_OP_FALLBACK_PROLOGUE(pDrawable) \
switch (pGC->fillStyle) { \
@@ -104,7 +104,7 @@ xglFillSpans (DrawablePtr pDrawable,
{
if (xglFillSpan (pDrawable, pGC, nspans, ppt, pwidth))
{
- xglAddBitDamage (pDrawable);
+ xglAddCurrentBitDamage (pDrawable);
return;
}
}
@@ -144,38 +144,45 @@ xglPutImage (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
- switch (format) {
- case XYBitmap:
- break;
- case XYPixmap:
- case ZPixmap:
- if (!pGCPriv->flags)
- {
- XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
+ if (pGC->alu != GXcopy || (pGCPriv->flags & xglGCPlaneMaskFlag))
+ {
+ XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
+ (*pGC->ops->PutImage) (pDrawable, pGC, depth,
+ x, y, w, h, leftPad, format, bits);
+ XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
+ }
+ else
+ {
+ RegionPtr pClip = pGC->pCompositeClip;
+ RegionRec region;
+ BoxRec box;
- if (!pPixmapPriv->allBits &&
- pPixmapPriv->target == xglPixmapTargetIn)
- {
- if (xglSetPixels (pDrawable,
- bits,
- PixmapBytePad (w, pDrawable->depth),
- x + pDrawable->x, y + pDrawable->y,
- w, h,
- REGION_RECTS (pGC->pCompositeClip),
- REGION_NUM_RECTS (pGC->pCompositeClip)))
- {
- xglAddBitDamage (pDrawable);
- return;
- }
- }
- }
- break;
+ XGL_DRAWABLE_PIXMAP (pDrawable);
+
+ if (!xglMapPixmapBits (pPixmap))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ XGL_GC_UNWRAP (funcs);
+ XGL_GC_UNWRAP (ops);
+
+ (*pGC->ops->PutImage) (pDrawable, pGC, depth,
+ x, y, w, h, leftPad, format, bits);
+
+ XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
+ XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);
+
+ box.x1 = pDrawable->x + x;
+ box.y1 = pDrawable->y + y;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+
+ REGION_INIT (pDrawable->pScreen, &region, &box, 1);
+ REGION_INTERSECT (pDrawable->pScreen, &region, pClip, &region);
+
+ xglAddSurfaceDamage (pDrawable, &region);
+
+ REGION_UNINIT (pDrawable->pScreen, &region);
}
-
- XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
- (*pGC->ops->PutImage) (pDrawable, pGC, depth,
- x, y, w, h, leftPad, format, bits);
- XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
RegionPtr
@@ -195,45 +202,37 @@ xglCopyArea (DrawablePtr pSrc,
XGL_GC_PRIV (pGC);
+ box.x1 = pSrc->x + srcX;
+ box.y1 = pSrc->y + srcY;
+ box.x2 = box.x1 + w;
+ box.y2 = box.y1 + h;
+
flags = pGCPriv->flags;
if (XGL_GET_DRAWABLE_PIXMAP_PRIV (pSrc)->target == xglPixmapTargetIn)
flags &= ~xglGCReadOnlyDrawableFlag;
-
- if (!flags)
+
+ if (flags)
{
- Bool ret;
-
- ret = TRUE;
+ if (!xglSyncBits (pSrc, &box))
+ FatalError (XGL_SW_FAILURE_STRING);
+
+ XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
+ pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
+ srcX, srcY, w, h, dstX, dstY);
+ XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
+ }
+ else
+ {
+ /* xglCopyProc handles fall-back */
pRegion = fbDoCopy (pSrc, pDst, pGC,
srcX, srcY,
w, h,
dstX, dstY,
xglCopyProc, 0,
- (void *) &ret);
- if (ret)
- {
- xglAddBitDamage (pDst);
- return pRegion;
- }
-
- if (pRegion)
- REGION_DESTROY (pDst->pScreen, pRegion);
+ (void *) &box);
}
- box.x1 = pSrc->x + srcX;
- box.y1 = pSrc->y + srcY;
- box.x2 = box.x1 + w;
- box.y2 = box.y1 + h;
-
- if (!xglSyncBits (pSrc, &box))
- FatalError (XGL_SW_FAILURE_STRING);
-
- XGL_GC_OP_FALLBACK_PROLOGUE (pDst);
- pRegion = (*pGC->ops->CopyArea) (pSrc, pDst, pGC,
- srcX, srcY, w, h, dstX, dstY);
- XGL_GC_OP_FALLBACK_EPILOGUE (pDst);
-
return pRegion;
}
@@ -302,13 +301,13 @@ xglPolylines (DrawablePtr pDrawable,
{
if (xglFillLine (pDrawable, pGC, mode, npt, ppt))
{
- xglAddBitDamage (pDrawable);
+ xglAddCurrentBitDamage (pDrawable);
return;
}
}
}
- XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
+ XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->Polylines) (pDrawable, pGC, mode, npt, ppt);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
@@ -337,13 +336,13 @@ xglPolySegment (DrawablePtr pDrawable,
{
if (xglFillSegment (pDrawable, pGC, nsegInit, pSegInit))
{
- xglAddBitDamage (pDrawable);
+ xglAddCurrentBitDamage (pDrawable);
return;
}
}
}
- XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
+ XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolySegment) (pDrawable, pGC, nsegInit, pSegInit);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} else
@@ -360,7 +359,7 @@ xglPolyArc (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
- XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
+ XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyArc) (pDrawable, pGC, narcs, pArcs);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
} else
@@ -375,18 +374,17 @@ xglPolyFillRect (DrawablePtr pDrawable,
{
XGL_GC_PRIV (pGC);
- if (!pGCPriv->flags)
+ if (pGCPriv->flags || pGC->fillStyle == FillStippled)
{
- if (xglFillRect (pDrawable, pGC, nrect, prect))
- {
- xglAddBitDamage (pDrawable);
- return;
- }
+ XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
+ (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
+ XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
+ }
+ else
+ {
+ /* xglFillRect handles fall-back */
+ xglFillRect (pDrawable, pGC, nrect, prect);
}
-
- XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
- (*pGC->ops->PolyFillRect) (pDrawable, pGC, nrect, prect);
- XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
void
@@ -412,7 +410,22 @@ xglImageGlyphBlt (DrawablePtr pDrawable,
pointer pglyphBase)
{
XGL_GC_PRIV (pGC);
-
+
+ if (!(pGCPriv->flags & ~xglGCBadFunctionFlag))
+ {
+ if (xglSolidGlyph (pDrawable,
+ pGC,
+ x,
+ y,
+ nglyph,
+ ppci,
+ pglyphBase))
+ {
+ xglAddCurrentBitDamage (pDrawable);
+ return;
+ }
+ }
+
XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
@@ -429,8 +442,23 @@ xglPolyGlyphBlt (DrawablePtr pDrawable,
pointer pglyphBase)
{
XGL_GC_PRIV (pGC);
+
+ if (!pGCPriv->flags)
+ {
+ if (xglFillGlyph (pDrawable,
+ pGC,
+ x,
+ y,
+ nglyph,
+ ppci,
+ pglyphBase))
+ {
+ xglAddCurrentBitDamage (pDrawable);
+ return;
+ }
+ }
- XGL_GC_OP_FALLBACK_PROLOGUE (pDrawable);
+ XGL_GC_FILL_OP_FALLBACK_PROLOGUE (pDrawable);
(*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
XGL_GC_OP_FALLBACK_EPILOGUE (pDrawable);
}
@@ -486,6 +514,20 @@ xglValidateGC (GCPtr pGC,
{
XGL_GC_PRIV (pGC);
+ if (changes & GCTile)
+ {
+ if (!pGC->tileIsPixel &&
+ FbEvenTile (pGC->tile.pixmap->drawable.width *
+ pDrawable->bitsPerPixel))
+ xglSyncBits (&pGC->tile.pixmap->drawable, NULL);
+ }
+
+ if (changes & GCStipple)
+ {
+ if (pGC->stipple)
+ xglSyncBits (&pGC->stipple->drawable, NULL);
+ }
+
XGL_GC_UNWRAP (funcs);
XGL_GC_UNWRAP (ops);
(*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
diff --git a/hw/xgl/xglgeometry.c b/hw/xgl/xglgeometry.c
index 6b2ebd3a7..7c46e31ca 100644
--- a/hw/xgl/xglgeometry.c
+++ b/hw/xgl/xglgeometry.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,15 +20,14 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
-struct xglDataTypeInfo {
- glitz_data_type_t type;
- int size;
-} dataTypes[] = {
+xglDataTypeInfoRec xglGeometryDataTypes[2] = {
{ GLITZ_DATA_TYPE_SHORT, sizeof (glitz_short_t) },
{ GLITZ_DATA_TYPE_FLOAT, sizeof (glitz_float_t) }
};
@@ -45,19 +44,17 @@ xglGeometryResize (ScreenPtr pScreen,
int size)
{
XGL_SCREEN_PRIV (pScreen);
-
- if (pGeometry->broken)
- return;
if (size == pGeometry->size)
return;
- if (pGeometry->usage == GEOMETRY_USAGE_USERMEM)
- {
- pGeometry->data =
- xrealloc (pGeometry->data,
- size * dataTypes[pGeometry->dataType].size);
+ if (pGeometry->broken)
+ return;
+ if (pGeometry->usage == GEOMETRY_USAGE_SYSMEM)
+ {
+ pGeometry->data = xrealloc (pGeometry->data, size);
+
if (pGeometry->buffer)
glitz_buffer_destroy (pGeometry->buffer);
@@ -81,16 +78,11 @@ xglGeometryResize (ScreenPtr pScreen,
else
{
glitz_buffer_t *newBuffer;
- int dataTypeSize;
-
- dataTypeSize = dataTypes[pGeometry->dataType].size;
-
if (size)
{
newBuffer =
- glitz_geometry_buffer_create (pScreenPriv->drawable, NULL,
- size * dataTypeSize,
- usageTypes[pGeometry->usage]);
+ glitz_vertex_buffer_create (pScreenPriv->drawable, NULL, size,
+ usageTypes[pGeometry->usage]);
if (!newBuffer)
{
pGeometry->broken = TRUE;
@@ -109,8 +101,7 @@ xglGeometryResize (ScreenPtr pScreen,
GLITZ_BUFFER_ACCESS_WRITE_ONLY);
if (oldData && newData)
- memcpy (newData, oldData,
- MIN (size, pGeometry->size) * dataTypeSize);
+ memcpy (newData, oldData, MIN (size, pGeometry->size));
glitz_buffer_unmap (pGeometry->buffer);
glitz_buffer_unmap (newBuffer);
@@ -126,103 +117,39 @@ xglGeometryResize (ScreenPtr pScreen,
pGeometry->endOffset = size;
}
-/*
- * Storage for 100 extra vertices are always allocated if
- * buffer size is to small. Geometry should be initialized
- * to desired size prior to calling this function when size
- * is known.
- */
-#define RESIZE_GEOMETRY_FOR_VERTICES(pScreen, pGeometry, nvertices) \
- if (((pGeometry)->size - (pGeometry)->endOffset) < ((nvertices) << 1)) \
+#define MAP_GEOMETRY(pScreen, pGeometry, offset, units, ptr, _size) \
+ if ((pGeometry)->broken) \
+ return; \
+ (_size) = (units) * xglGeometryDataTypes[(pGeometry)->dataType].size; \
+ if (((pGeometry)->size - (offset)) < (_size)) \
+ { \
+ xglGeometryResize (pScreen, pGeometry, \
+ (pGeometry)->endOffset + (_size) + 500); \
+ if ((pGeometry)->broken) \
+ return; \
+ } \
+ (ptr) = glitz_buffer_map ((pGeometry)->buffer, \
+ GLITZ_BUFFER_ACCESS_WRITE_ONLY); \
+ if (!(ptr)) \
+ { \
+ (pGeometry)->broken = TRUE; \
+ return; \
+ } \
+ (ptr) += (offset)
+
+#define UNMAP_GEOMETRY(pGeometry, offset, _size) \
+ if (glitz_buffer_unmap ((pGeometry)->buffer)) \
{ \
- xglGeometryResize (pScreen, pGeometry, \
- (pGeometry)->endOffset + \
- ((nvertices) << 1) + 200); \
- if ((pGeometry)->broken) \
- return; \
- }
-
-/*
- * Adds a number of rectangles as GL_QUAD primitives
- */
-void
-xglGeometryAddRect (ScreenPtr pScreen,
- xglGeometryPtr pGeometry,
- xRectangle *pRect,
- int nRect)
-{
- int nvertices;
- void *ptr;
-
- if (pGeometry->broken)
- return;
-
- if (nRect < 1)
- return;
-
- nvertices = nRect << 2;
-
- RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
-
- ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
- if (!ptr)
- {
- pGeometry->broken = TRUE;
- return;
- }
-
- switch (pGeometry->dataType) {
- case GEOMETRY_DATA_TYPE_SHORT:
- {
- glitz_short_t *data = (glitz_short_t *) ptr;
-
- data += pGeometry->endOffset;
-
- while (nRect--)
- {
- *data++ = pRect->x;
- *data++ = pRect->y;
- *data++ = pRect->x + pRect->width;
- *data++ = pRect->y;
- *data++ = pRect->x + pRect->width;
- *data++ = pRect->y + pRect->height;
- *data++ = pRect->x;
- *data++ = pRect->y + pRect->height;
-
- pRect++;
- }
- } break;
- case GEOMETRY_DATA_TYPE_FLOAT:
- {
- glitz_float_t *data = (glitz_float_t *) ptr;
-
- data += pGeometry->endOffset;
-
- while (nRect--)
- {
- *data++ = (glitz_float_t) pRect->x;
- *data++ = (glitz_float_t) pRect->y;
- *data++ = (glitz_float_t) pRect->x + pRect->width;
- *data++ = (glitz_float_t) pRect->y;
- *data++ = (glitz_float_t) pRect->x + pRect->width;
- *data++ = (glitz_float_t) pRect->y + pRect->height;
- *data++ = (glitz_float_t) pRect->x;
- *data++ = (glitz_float_t) pRect->y + pRect->height;
-
- pRect++;
- }
- } break;
+ (pGeometry)->broken = TRUE; \
+ return; \
+ } \
+ if (((offset) + (_size)) > (pGeometry)->endOffset) \
+ { \
+ (pGeometry)->endOffset = (offset) + (_size); \
+ (pGeometry)->count = (pGeometry)->endOffset / \
+ (2 * xglGeometryDataTypes[(pGeometry)->dataType].size); \
}
- if (glitz_buffer_unmap (pGeometry->buffer))
- {
- pGeometry->broken = TRUE;
- return;
- }
-
- pGeometry->endOffset += (nvertices << 1);
-}
-
/*
* Adds a number of boxes as GL_QUAD primitives
*/
@@ -230,35 +157,22 @@ void
xglGeometryAddBox (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
BoxPtr pBox,
- int nBox)
+ int nBox,
+ int offset)
{
- int nvertices;
- void *ptr;
-
- if (pGeometry->broken)
- return;
+ int size;
+ char *ptr;
if (nBox < 1)
return;
- nvertices = nBox << 2;
-
- RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
-
- ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
- if (!ptr)
- {
- pGeometry->broken = TRUE;
- return;
- }
-
+ MAP_GEOMETRY (pScreen, pGeometry, offset, nBox * 8, ptr, size);
+
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
- data += pGeometry->endOffset;
-
while (nBox--)
{
*data++ = (glitz_short_t) pBox->x1;
@@ -277,8 +191,6 @@ xglGeometryAddBox (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
- data += pGeometry->endOffset;
-
while (nBox--)
{
*data++ = (glitz_float_t) pBox->x1;
@@ -295,59 +207,38 @@ xglGeometryAddBox (ScreenPtr pScreen,
} break;
}
- if (glitz_buffer_unmap (pGeometry->buffer))
- {
- pGeometry->broken = TRUE;
- return;
- }
-
- pGeometry->endOffset += (nvertices << 1);
+ UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
* Adds a number of spans as GL_LINE primitives
- *
- * An extra 1 is added to *pwidth as OpenGL line segments are half-opened.
*/
void
xglGeometryAddSpan (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
DDXPointPtr ppt,
int *pwidth,
- int n)
+ int n,
+ int offset)
{
- int nvertices;
- void *ptr;
-
- if (pGeometry->broken)
- return;
+ int size;
+ char *ptr;
if (n < 1)
return;
- nvertices = n << 1;
-
- RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
-
- ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
- if (!ptr)
- {
- pGeometry->broken = TRUE;
- return;
- }
+ MAP_GEOMETRY (pScreen, pGeometry, offset, n * 4, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
- data += pGeometry->endOffset;
-
while (n--)
{
*data++ = (glitz_short_t) ppt->x;
*data++ = (glitz_short_t) ppt->y;
- *data++ = (glitz_short_t) (ppt->x + *pwidth + 1);
+ *data++ = (glitz_short_t) (ppt->x + *pwidth);
*data++ = (glitz_short_t) ppt->y;
ppt++;
@@ -358,13 +249,11 @@ xglGeometryAddSpan (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
- data += pGeometry->endOffset;
-
while (n--)
{
*data++ = (glitz_float_t) ppt->x;
*data++ = (glitz_float_t) ppt->y;
- *data++ = (glitz_float_t) (ppt->x + *pwidth + 1);
+ *data++ = (glitz_float_t) (ppt->x + *pwidth);
*data++ = (glitz_float_t) ppt->y;
ppt++;
@@ -372,14 +261,8 @@ xglGeometryAddSpan (ScreenPtr pScreen,
}
} break;
}
-
- if (glitz_buffer_unmap (pGeometry->buffer))
- {
- pGeometry->broken = TRUE;
- return;
- }
-
- pGeometry->endOffset += (nvertices << 1);
+
+ UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
@@ -401,28 +284,17 @@ xglGeometryAddLine (ScreenPtr pScreen,
int loop,
int mode,
int npt,
- DDXPointPtr ppt)
+ DDXPointPtr ppt,
+ int offset)
{
DDXPointRec pt;
- int nvertices;
- void *ptr;
-
- if (pGeometry->broken)
- return;
+ int size;
+ char *ptr;
if (npt < 2)
return;
- nvertices = npt;
-
- RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
-
- ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
- if (!ptr)
- {
- pGeometry->broken = TRUE;
- return;
- }
+ MAP_GEOMETRY (pScreen, pGeometry, offset, npt * 2, ptr, size);
pt.x = 0;
pt.y = 0;
@@ -432,8 +304,6 @@ xglGeometryAddLine (ScreenPtr pScreen,
{
glitz_short_t *data = (glitz_short_t *) ptr;
- data += pGeometry->endOffset;
-
while (npt--)
{
if (mode == CoordModePrevious)
@@ -447,19 +317,17 @@ xglGeometryAddLine (ScreenPtr pScreen,
pt.y = ppt->y;
}
- *data++ = pt.x;
- *data++ = pt.y;
-
if (npt || loop)
{
- *data++ = pt.x;
- *data++ = pt.y;
+ *data++ = (glitz_short_t) pt.x;
+ *data++ = (glitz_short_t) pt.y;
}
else
{
ppt--;
- *data++ = ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
- *data++ = ADJUST_END_POINT (ppt->y, pt.y, 0);
+ *data++ = (glitz_short_t)
+ ADJUST_END_POINT (ppt->x, pt.x, ppt->y == pt.y);
+ *data++ = (glitz_short_t) ADJUST_END_POINT (ppt->y, pt.y, 0);
}
ppt++;
@@ -469,8 +337,6 @@ xglGeometryAddLine (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
- data += pGeometry->endOffset;
-
while (npt--)
{
if (mode == CoordModePrevious)
@@ -501,14 +367,8 @@ xglGeometryAddLine (ScreenPtr pScreen,
}
} break;
}
-
- if (glitz_buffer_unmap (pGeometry->buffer))
- {
- pGeometry->broken = TRUE;
- return;
- }
- pGeometry->endOffset += (nvertices << 1);
+ UNMAP_GEOMETRY (pGeometry, offset, size);
}
/*
@@ -518,42 +378,31 @@ void
xglGeometryAddSegment (ScreenPtr pScreen,
xglGeometryPtr pGeometry,
int nsegInit,
- xSegment *pSegInit)
+ xSegment *pSegInit,
+ int offset)
{
- int nvertices;
- void *ptr;
-
- if (pGeometry->broken)
- return;
+ int size;
+ char *ptr;
if (nsegInit < 1)
return;
- nvertices = nsegInit << 1;
-
- RESIZE_GEOMETRY_FOR_VERTICES (pScreen, pGeometry, nvertices);
-
- ptr = glitz_buffer_map (pGeometry->buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);
- if (!ptr)
- {
- pGeometry->broken = TRUE;
- return;
- }
+ MAP_GEOMETRY (pScreen, pGeometry, offset, nsegInit * 4, ptr, size);
switch (pGeometry->dataType) {
case GEOMETRY_DATA_TYPE_SHORT:
{
glitz_short_t *data = (glitz_short_t *) ptr;
- data += pGeometry->endOffset;
-
while (nsegInit--)
{
- *data++ = pSegInit->x1;
- *data++ = pSegInit->y1;
- *data++ = ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
- pSegInit->y1 == pSegInit->y2);
- *data++ = ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
+ *data++ = (glitz_short_t) pSegInit->x1;
+ *data++ = (glitz_short_t) pSegInit->y1;
+ *data++ = (glitz_short_t)
+ ADJUST_END_POINT (pSegInit->x1, pSegInit->x2,
+ pSegInit->y1 == pSegInit->y2);
+ *data++ = (glitz_short_t)
+ ADJUST_END_POINT (pSegInit->y1, pSegInit->y2, 0);
pSegInit++;
}
@@ -562,8 +411,6 @@ xglGeometryAddSegment (ScreenPtr pScreen,
{
glitz_float_t *data = (glitz_float_t *) ptr;
- data += pGeometry->endOffset;
-
while (nsegInit--)
{
*data++ = (glitz_float_t) pSegInit->x1;
@@ -578,38 +425,299 @@ xglGeometryAddSegment (ScreenPtr pScreen,
}
} break;
}
-
- if (glitz_buffer_unmap (pGeometry->buffer))
+
+ UNMAP_GEOMETRY (pGeometry, offset, size);
+}
+
+void
+xglGeometryForGlyph (ScreenPtr pScreen,
+ xglGeometryPtr pGeometry,
+ unsigned int nGlyph,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase)
+{
+ CharInfoPtr *ppci;
+ CharInfoPtr pci;
+ unsigned char *glyphbase = (pointer) ~0;
+ unsigned char *pglyph;
+ int x = 0;
+ int gx, gy;
+ int gWidth, gHeight;
+ int n, lastX = 0, lastY = 0;
+ glitz_multi_array_t *array;
+ glitz_buffer_t *buffer;
+
+ ppci = ppciInit;
+ n = nGlyph;
+
+ while (n--)
+ {
+ pglyph = FONTGLYPHBITS (pglyphBase, *ppci++);
+ if (pglyph < glyphbase)
+ glyphbase = pglyph;
+ }
+
+ buffer = glitz_buffer_create_for_data (glyphbase);
+ if (!buffer)
+ {
+ pGeometry->broken = TRUE;
+ return;
+ }
+
+ 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;
- pGeometry->endOffset += (nvertices << 1);
+ stride = 2 * xglGeometryDataTypes[type].size;
+
+ pGeometry = xglGetScratchGeometryWithSize (pScreen, count * stride);
+
+ pGeometry->type = GLITZ_GEOMETRY_TYPE_VERTEX;
+ pGeometry->dataType = type;
+
+ pGeometry->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS;
+ pGeometry->f.vertex.type = xglGeometryDataTypes[type].type;
+ pGeometry->f.vertex.bytes_per_vertex = stride;
+ pGeometry->f.vertex.attributes = 0;
+
+ return pGeometry;
+}
+
+xglGeometryPtr
+xglGetScratchVertexGeometry (ScreenPtr pScreen,
+ int count)
+{
+ xglGeometryPtr pGeometry;
+ int type, stride;
+
+ XGL_SCREEN_PRIV (pScreen);
+
+ type = pScreenPriv->geometryDataType;
+ stride = 2 * xglGeometryDataTypes[type].size;
+
+ pGeometry = xglGetScratchGeometryWithSize (pScreen, count * stride);
+
+ pGeometry->type = GLITZ_GEOMETRY_TYPE_VERTEX;
+ pGeometry->dataType = type;
+
+ pGeometry->f.vertex.primitive = GLITZ_PRIMITIVE_QUADS;
+ pGeometry->f.vertex.type = xglGeometryDataTypes[type].type;
+ pGeometry->f.vertex.bytes_per_vertex = stride;
+ pGeometry->f.vertex.attributes = 0;
+
+ return pGeometry;
}
Bool
xglSetGeometry (xglGeometryPtr pGeometry,
- glitz_surface_t *surface,
- int first,
- int count)
+ glitz_surface_t *surface)
{
- glitz_geometry_format_t format;
-
if (pGeometry->broken)
return FALSE;
- format.first = first;
- format.count = count;
- format.primitive = pGeometry->primitive;
- format.type = dataTypes[pGeometry->dataType].type;
- format.mode = GLITZ_GEOMETRY_MODE_DIRECT;
- format.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_SHARP;
-
- glitz_set_geometry (surface,
- pGeometry->xOff, pGeometry->yOff,
- &format,
+ glitz_set_geometry (surface, pGeometry->type, &pGeometry->f,
pGeometry->buffer);
+ if (pGeometry->array)
+ glitz_set_multi_array (surface, pGeometry->array,
+ pGeometry->xOff, pGeometry->yOff);
+ else
+ glitz_set_array (surface,
+ pGeometry->first, pGeometry->width, pGeometry->count,
+ pGeometry->xOff, pGeometry->yOff);
+
return TRUE;
}
diff --git a/hw/xgl/xglget.c b/hw/xgl/xglget.c
index c13be9f30..70f29e2e5 100644
--- a/hw/xgl/xglget.c
+++ b/hw/xgl/xglget.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -35,8 +35,10 @@ xglGetImage (DrawablePtr pDrawable,
unsigned long planeMask,
char *d)
{
- ScreenPtr pScreen = pDrawable->pScreen;
- BoxRec box;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ glitz_surface_t *surface;
+ int xOff, yOff;
+ BoxRec box;
XGL_SCREEN_PRIV (pScreen);
@@ -44,11 +46,13 @@ xglGetImage (DrawablePtr pDrawable,
if (pDrawable->type == DRAWABLE_WINDOW)
{
glitz_surface_flush (pScreenPriv->surface);
- glitz_drawable_flush (pScreenPriv->drawable);
+ glitz_drawable_finish (pScreenPriv->drawable);
}
- box.x1 = x + pDrawable->x;
- box.y1 = y + pDrawable->y;
+ XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
+
+ box.x1 = pDrawable->x + xOff + x;
+ box.y1 = pDrawable->y + yOff + y;
box.x2 = box.x1 + w;
box.y2 = box.y1 + h;
diff --git a/hw/xgl/xglglyph.c b/hw/xgl/xglglyph.c
new file mode 100644
index 000000000..157dfb6af
--- /dev/null
+++ b/hw/xgl/xglglyph.c
@@ -0,0 +1,1080 @@
+/*
+ * 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"
+
+#ifdef RENDER
+#include "gcstruct.h"
+#include "picturestr.h"
+
+#define BITMAP_CACHE_SIZE 256000
+#define BITMAP_CACHE_MAX_LEVEL ~0
+#define BITMAP_CACHE_MAX_SIZE 512
+
+#define TEXTURE_CACHE_SIZE 512
+#define TEXTURE_CACHE_MAX_LEVEL 64
+#define TEXTURE_CACHE_MAX_HEIGHT 72
+#define TEXTURE_CACHE_MAX_WIDTH 72
+
+#define NEXT_GLYPH_SERIAL_NUMBER ((++glyphSerialNumber) > MAX_SERIAL_NUM ? \
+ (glyphSerialNumber = 1): glyphSerialNumber)
+
+#define GLYPH_GET_AREA_PRIV(pArea) \
+ ((xglGlyphAreaPtr) (pArea)->devPrivate.ptr)
+
+#define GLYPH_AREA_PRIV(pArea) \
+ xglGlyphAreaPtr pAreaPriv = GLYPH_GET_AREA_PRIV (pArea)
+
+#define NEEDS_COMPONENT(f) (PICT_FORMAT_A (f) != 0 && PICT_FORMAT_RGB (f) != 0)
+
+#define WRITE_VEC2(ptr, _x, _y) \
+ *(ptr)++ = (_x); \
+ *(ptr)++ = (_y)
+
+#define WRITE_BOX(ptr, _vx1, _vy1, _vx2, _vy2, box) \
+ WRITE_VEC2 (ptr, _vx1, _vy1); \
+ WRITE_VEC2 (ptr, (box).x1, (box).y2); \
+ WRITE_VEC2 (ptr, _vx2, _vy1); \
+ WRITE_VEC2 (ptr, (box).x2, (box).y2); \
+ WRITE_VEC2 (ptr, _vx2, _vy2); \
+ WRITE_VEC2 (ptr, (box).x2, (box).y1); \
+ WRITE_VEC2 (ptr, _vx1, _vy2); \
+ WRITE_VEC2 (ptr, (box).x1, (box).y1)
+
+typedef union _xglGlyphList {
+ glitz_short_t *s;
+ glitz_float_t *f;
+} xglGlyphListRec, *xglGlyphListPtr;
+
+typedef struct _xglGlyphArray {
+ int lastX, lastY;
+} xglGlyphArrayRec, *xglGlyphArrayPtr;
+
+typedef union _xglGlyphVertexData {
+ xglGlyphArrayRec array;
+ xglGlyphListRec list;
+} xglGlyphVertexDataRec, *xglGlyphVertexDataPtr;
+
+typedef struct _xglGlyphOp {
+ GlyphListPtr pLists;
+ int listLen;
+ GlyphPtr *ppGlyphs;
+ int nGlyphs;
+ int xOff;
+ int yOff;
+ Bool noCache;
+} xglGlyphOpRec, *xglGlyphOpPtr;
+
+unsigned long glyphSerialNumber = 0;
+
+xglAreaRec zeroSizeArea = {
+ 0, 0,
+ 0, 0,
+ 0, 0,
+ { NULL, NULL, NULL, NULL }, NULL,
+ (pointer) 0,
+ { 0 }
+};
+
+static Bool
+xglGlyphCreate (xglAreaPtr pArea)
+{
+ return TRUE;
+}
+
+static Bool
+xglGlyphMoveIn (xglAreaPtr pArea,
+ pointer closure)
+{
+ xglGlyphCachePtr pCache = (xglGlyphCachePtr) pArea->pRoot->closure;
+ GlyphPtr pGlyph = (GlyphPtr) closure;
+
+ XGL_GLYPH_PRIV (pCache->pScreen, pGlyph);
+
+ pGlyphPriv->pArea = pArea;
+
+ return TRUE;
+}
+
+static void
+xglGlyphMoveOut (xglAreaPtr pArea,
+ pointer closure)
+{
+ xglGlyphCachePtr pCache = (xglGlyphCachePtr) pArea->pRoot->closure;
+ GlyphPtr pGlyph = (GlyphPtr) closure;
+
+ XGL_GLYPH_PRIV (pCache->pScreen, pGlyph);
+
+ pGlyphPriv->pArea = NULL;
+}
+
+static int
+xglGlyphCompareScore (xglAreaPtr pArea,
+ pointer closure1,
+ pointer closure2)
+{
+ xglGlyphCachePtr pCache = (xglGlyphCachePtr) pArea->pRoot->closure;
+ GlyphPtr pGlyph = (GlyphPtr) closure2;
+
+ XGL_GLYPH_PRIV (pCache->pScreen, pGlyph);
+ GLYPH_AREA_PRIV (pGlyphPriv->pArea);
+
+ if (pAreaPriv->serial != glyphSerialNumber)
+ return 1;
+
+ return -1;
+}
+
+static const xglAreaFuncsRec xglGlyphAreaFuncs = {
+ xglGlyphCreate,
+ xglGlyphMoveIn,
+ xglGlyphMoveOut,
+ xglGlyphCompareScore
+};
+
+Bool
+xglRealizeGlyph (ScreenPtr pScreen,
+ GlyphPtr pGlyph)
+{
+ PictureScreenPtr pPictureScreen = GetPictureScreen (pScreen);
+ Bool ret;
+
+ XGL_SCREEN_PRIV (pScreen);
+ XGL_GLYPH_PRIV (pScreen, pGlyph);
+
+ XGL_PICTURE_SCREEN_UNWRAP (RealizeGlyph);
+ ret = (*pPictureScreen->RealizeGlyph) (pScreen, pGlyph);
+ XGL_PICTURE_SCREEN_WRAP (RealizeGlyph, xglRealizeGlyph);
+
+ pGlyphPriv->pArea = NULL;
+
+ return ret;
+}
+
+void
+xglUnrealizeGlyph (ScreenPtr pScreen,
+ GlyphPtr pGlyph)
+{
+ PictureScreenPtr pPictureScreen = GetPictureScreen (pScreen);
+
+ XGL_SCREEN_PRIV (pScreen);
+ XGL_GLYPH_PRIV (pScreen, pGlyph);
+
+ XGL_PICTURE_SCREEN_UNWRAP (UnrealizeGlyph);
+ (*pPictureScreen->UnrealizeGlyph) (pScreen, pGlyph);
+ XGL_PICTURE_SCREEN_WRAP (UnrealizeGlyph, xglUnrealizeGlyph);
+
+ if (pGlyphPriv->pArea && pGlyphPriv->pArea->width)
+ xglWithdrawArea (pGlyphPriv->pArea);
+}
+
+Bool
+xglInitGlyphCache (xglGlyphCachePtr pCache,
+ ScreenPtr pScreen,
+ PictFormatPtr format)
+{
+ XGL_SCREEN_PRIV (pScreen);
+
+ pCache->depth = format->depth;
+
+ if (!pScreenPriv->pSolidAlpha)
+ {
+ xglCreateSolidAlphaPicture (pScreen);
+ if (!pScreenPriv->pSolidAlpha)
+ return FALSE;
+ }
+
+ if (pCache->depth == 1)
+ {
+ int stride;
+
+ GEOMETRY_INIT (pScreen, &pCache->u.geometry,
+ GLITZ_GEOMETRY_TYPE_VERTEX,
+ GEOMETRY_USAGE_STATIC, BITMAP_CACHE_SIZE);
+ GEOMETRY_SET_VERTEX_DATA_TYPE (&pCache->u.geometry,
+ pScreenPriv->geometryDataType);
+
+ stride = pCache->u.geometry.f.vertex.bytes_per_vertex;
+ if (!xglRootAreaInit (&pCache->rootArea,
+ BITMAP_CACHE_MAX_LEVEL,
+ BITMAP_CACHE_SIZE / (stride * 4),
+ 0, sizeof (xglGlyphAreaRec),
+ (xglAreaFuncsPtr) &xglGlyphAreaFuncs,
+ (pointer) pCache))
+ {
+ GEOMETRY_UNINIT (&pCache->u.geometry);
+ return FALSE;
+ }
+ }
+ else
+ {
+
+ xglGlyphTexturePtr pTexture = &pCache->u.texture;
+ glitz_surface_attributes_t attr;
+ xglPixmapFormatPtr pFormat;
+ glitz_vertex_format_t *vertex;
+
+ if (!xglRootAreaInit (&pCache->rootArea,
+ TEXTURE_CACHE_MAX_LEVEL,
+ TEXTURE_CACHE_SIZE, TEXTURE_CACHE_SIZE,
+ sizeof (xglGlyphAreaRec),
+ (xglAreaFuncsPtr) &xglGlyphAreaFuncs,
+ (pointer) pCache))
+ return FALSE;
+
+ pFormat = &pScreenPriv->pixmapFormats[format->depth];
+
+ if (pScreenPriv->geometryDataType == GEOMETRY_DATA_TYPE_SHORT)
+ {
+ attr.unnormalized = 1;
+ pTexture->mask =
+ glitz_surface_create (pScreenPriv->drawable, pFormat->format,
+ TEXTURE_CACHE_SIZE, TEXTURE_CACHE_SIZE,
+ GLITZ_SURFACE_UNNORMALIZED_MASK, &attr);
+ } else
+ pTexture->mask = NULL;
+
+ if (!pTexture->mask)
+ {
+ pTexture->mask =
+ glitz_surface_create (pScreenPriv->drawable, pFormat->format,
+ TEXTURE_CACHE_SIZE, TEXTURE_CACHE_SIZE,
+ 0, NULL);
+ if (!pTexture->mask)
+ return FALSE;
+
+ pTexture->geometryDataType = GEOMETRY_DATA_TYPE_FLOAT;
+ } else
+ pTexture->geometryDataType = GEOMETRY_DATA_TYPE_SHORT;
+
+ if (NEEDS_COMPONENT (format->format))
+ glitz_surface_set_component_alpha (pTexture->mask, 1);
+
+ vertex = &pCache->u.texture.format.vertex;
+ vertex->primitive = GLITZ_PRIMITIVE_QUADS;
+ vertex->mask.size = GLITZ_COORDINATE_SIZE_XY;
+ vertex->attributes = GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK;
+
+ if (pTexture->geometryDataType == GEOMETRY_DATA_TYPE_FLOAT)
+ {
+ vertex->type = GLITZ_DATA_TYPE_FLOAT;
+ vertex->bytes_per_vertex = sizeof (glitz_float_t) * 4;
+ vertex->mask.offset = sizeof (glitz_float_t) * 2;
+ vertex->mask.type = GLITZ_DATA_TYPE_FLOAT;
+ }
+ else
+ {
+ vertex->type = GLITZ_DATA_TYPE_SHORT;
+ vertex->bytes_per_vertex = sizeof (glitz_short_t) * 4;
+ vertex->mask.offset = sizeof (glitz_short_t) * 2;
+ vertex->mask.type = GLITZ_DATA_TYPE_SHORT;
+ }
+
+ pTexture->pixel.masks = pFormat->pPixel->masks;
+ pTexture->pixel.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
+ pTexture->pixel.bytes_per_line = 0;
+ pTexture->pixel.xoffset = 0;
+ pTexture->pixel.skip_lines = 0;
+ }
+
+ pCache->pScreen = pScreen;
+
+ return TRUE;
+}
+
+void
+xglFiniGlyphCache (xglGlyphCachePtr pCache)
+{
+ if (pCache->pScreen)
+ {
+ xglRootAreaFini (&pCache->rootArea);
+
+ if (pCache->depth == 1)
+ {
+ GEOMETRY_UNINIT (&pCache->u.geometry);
+ }
+ else
+ {
+ if (pCache->u.texture.mask)
+ glitz_surface_destroy (pCache->u.texture.mask);
+ }
+
+ pCache->pScreen = NULL;
+ }
+}
+
+static xglAreaPtr
+xglCacheGlyph (xglGlyphCachePtr pCache,
+ GlyphPtr pGlyph)
+{
+ ScreenPtr pScreen = pCache->pScreen;
+
+ XGL_GLYPH_PRIV (pScreen, pGlyph);
+
+ if (pCache->depth == 1)
+ {
+ PixmapPtr pPixmap;
+ RegionPtr pRegion;
+ int nBox;
+
+ pPixmap = GetScratchPixmapHeader (pScreen,
+ pGlyph->info.width,
+ pGlyph->info.height,
+ pCache->depth, pCache->depth, 0,
+ (pointer) (pGlyph + 1));
+ if (!pPixmap)
+ return NULL;
+
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ pGlyph->info.width,
+ pGlyph->info.height,
+ 0, 0, -1, (pointer) (pGlyph + 1));
+
+ pRegion = (*pScreen->BitmapToRegion) (pPixmap);
+ FreeScratchPixmapHeader (pPixmap);
+
+ if (!pRegion)
+ return NULL;
+
+ nBox = REGION_NUM_RECTS (pRegion);
+ if (nBox > BITMAP_CACHE_MAX_SIZE)
+ {
+ REGION_DESTROY (pScreen, pRegion);
+ return NULL;
+ }
+
+ if (nBox > 0)
+ {
+ /* Find available area */
+ if (!xglFindArea (pCache->rootArea.pArea, nBox, 0,
+ FALSE, (pointer) pGlyph))
+ {
+ /* Kicking out area with lower score */
+ xglFindArea (pCache->rootArea.pArea, nBox, 0,
+ TRUE, (pointer) pGlyph);
+ }
+
+ if (pGlyphPriv->pArea)
+ {
+ int stride;
+
+ GLYPH_AREA_PRIV (pGlyphPriv->pArea);
+
+ pAreaPriv->u.range.first = pGlyphPriv->pArea->x * 4;
+ pAreaPriv->u.range.count = nBox * 4;
+
+ stride = pCache->u.geometry.f.vertex.bytes_per_vertex;
+ GEOMETRY_ADD_REGION_AT (pScreen, &pCache->u.geometry, pRegion,
+ pGlyphPriv->pArea->x * stride * 4);
+ }
+ } else
+ pGlyphPriv->pArea = &zeroSizeArea;
+
+ REGION_DESTROY (pScreen, pRegion);
+ }
+ else
+ {
+ xglGlyphTexturePtr pTexture = &pCache->u.texture;
+
+ if (pGlyph->info.width > TEXTURE_CACHE_MAX_WIDTH ||
+ pGlyph->info.height > TEXTURE_CACHE_MAX_HEIGHT)
+ return NULL;
+
+ if (pGlyph->info.width > 0 && pGlyph->info.height > 0)
+ {
+ glitz_buffer_t *buffer;
+
+ buffer = glitz_buffer_create_for_data (pGlyph + 1);
+ if (!buffer)
+ return NULL;
+
+ /* Find available area */
+ if (!xglFindArea (pCache->rootArea.pArea,
+ pGlyph->info.width, pGlyph->info.height,
+ FALSE, (pointer) pGlyph))
+ {
+ /* Kicking out area with lower score */
+ xglFindArea (pCache->rootArea.pArea,
+ pGlyph->info.width, pGlyph->info.height,
+ TRUE, (pointer) pGlyph);
+ }
+
+ if (pGlyphPriv->pArea)
+ {
+ glitz_point_fixed_t p1, p2;
+ glitz_pixel_format_t pixel;
+
+ GLYPH_AREA_PRIV (pGlyphPriv->pArea);
+
+ pixel = pTexture->pixel;
+ pixel.bytes_per_line =
+ PixmapBytePad (pGlyph->info.width, pCache->depth);
+
+ glitz_set_pixels (pTexture->mask,
+ pGlyphPriv->pArea->x,
+ pGlyphPriv->pArea->y,
+ pGlyph->info.width,
+ pGlyph->info.height,
+ &pixel,
+ buffer);
+
+ p1.x = pGlyphPriv->pArea->x << 16;
+ p1.y = pGlyphPriv->pArea->y << 16;
+ p2.x = (pGlyphPriv->pArea->x + pGlyph->info.width) << 16;
+ p2.y = (pGlyphPriv->pArea->y + pGlyph->info.height) << 16;
+
+ glitz_surface_translate_point (pTexture->mask, &p1, &p1);
+ glitz_surface_translate_point (pTexture->mask, &p2, &p2);
+
+ if (pTexture->geometryDataType)
+ {
+ pAreaPriv->u.box.fBox.x1 = FIXED_TO_FLOAT (p1.x);
+ pAreaPriv->u.box.fBox.y1 = FIXED_TO_FLOAT (p1.y);
+ pAreaPriv->u.box.fBox.x2 = FIXED_TO_FLOAT (p2.x);
+ pAreaPriv->u.box.fBox.y2 = FIXED_TO_FLOAT (p2.y);
+ }
+ else
+ {
+ pAreaPriv->u.box.sBox.x1 = p1.x >> 16;
+ pAreaPriv->u.box.sBox.y1 = p1.y >> 16;
+ pAreaPriv->u.box.sBox.x2 = p2.x >> 16;
+ pAreaPriv->u.box.sBox.y2 = p2.y >> 16;
+ }
+ }
+ glitz_buffer_destroy (buffer);
+ } else
+ pGlyphPriv->pArea = &zeroSizeArea;
+ }
+
+ return pGlyphPriv->pArea;
+}
+
+static void
+xglUncachedGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ xglGlyphOpPtr pOp)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PicturePtr pPicture = NULL;
+ PixmapPtr pPixmap = NULL;
+ xglGlyphCachePtr pCache;
+ int depth = pOp->pLists->format->depth;
+ GlyphPtr glyph;
+ INT16 xOff, yOff;
+ xglGlyphPtr pGlyphPriv;
+ xglAreaPtr pArea;
+ Bool usingCache = !pOp->noCache;
+
+ XGL_SCREEN_PRIV (pScreen);
+
+ pCache = &pScreenPriv->glyphCache[depth];
+
+ while (pOp->nGlyphs)
+ {
+ glyph = *pOp->ppGlyphs;
+
+ if (!pOp->listLen)
+ {
+ pOp->pLists++;
+ pOp->listLen = pOp->pLists->len;
+ pOp->xOff += pOp->pLists->xOff;
+ pOp->yOff += pOp->pLists->yOff;
+ }
+
+ xOff = pOp->xOff;
+ yOff = pOp->yOff;
+
+ if (usingCache)
+ {
+ pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, glyph);
+ if (pSrc)
+ {
+ pArea = pGlyphPriv->pArea;
+ if (pArea)
+ break;
+
+ if (pCache->pScreen ||
+ xglInitGlyphCache (pCache, pScreen, pOp->pLists->format))
+ {
+ if (xglCacheGlyph (pCache, glyph))
+ break;
+ }
+ }
+ else
+ {
+ pArea = pGlyphPriv->pArea;
+ }
+ } else
+ pArea = NULL;
+
+ pOp->listLen--;
+ pOp->nGlyphs--;
+ pOp->ppGlyphs++;
+
+ pOp->xOff += glyph->info.xOff;
+ pOp->yOff += glyph->info.yOff;
+
+ if (pArea)
+ continue;
+
+ if (!pPicture)
+ {
+ CARD32 componentAlpha;
+ int error;
+
+ pPixmap = GetScratchPixmapHeader (pScreen,
+ glyph->info.width,
+ glyph->info.height,
+ pOp->pLists->format->depth,
+ pOp->pLists->format->depth,
+ 0, (pointer) (glyph + 1));
+ if (!pPixmap)
+ return;
+
+ componentAlpha = NEEDS_COMPONENT (pOp->pLists->format->format);
+ pPicture = CreatePicture (0, &pPixmap->drawable,
+ pOp->pLists->format,
+ CPComponentAlpha, &componentAlpha,
+ serverClient, &error);
+ if (!pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ return;
+ }
+ }
+
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ glyph->info.width, glyph->info.height,
+ 0, 0, -1, (pointer) (glyph + 1));
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if (pSrc)
+ CompositePicture (op,
+ pSrc,
+ pPicture,
+ pDst,
+ xSrc + (xOff - glyph->info.x),
+ ySrc + (yOff - glyph->info.y),
+ 0, 0,
+ xOff - glyph->info.x,
+ yOff - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ else
+ CompositePicture (PictOpAdd,
+ pPicture,
+ NULL,
+ pDst,
+ 0, 0,
+ 0, 0,
+ xOff - glyph->info.x,
+ yOff - glyph->info.y,
+ glyph->info.width,
+ glyph->info.height);
+ }
+
+ if (pPicture)
+ {
+ FreeScratchPixmapHeader (pPixmap);
+ FreePicture ((pointer) pPicture, 0);
+ }
+}
+
+static Bool
+xglCachedGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ xglGlyphOpPtr pOp)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ xglGlyphOpRec opSave = *pOp;
+ xglGlyphCachePtr pCache;
+ xglGlyphVertexDataRec vData;
+ xglGeometryPtr pGeometry;
+ GlyphPtr glyph;
+ xglGlyphPtr pGlyphPriv;
+ xglAreaPtr pArea;
+ xglGlyphAreaPtr pGlyphArea;
+ BoxRec extents;
+ INT16 xOff, yOff, x1, x2, y1, y2;
+ int depth = pOp->pLists->format->depth;
+ int n, count = 0, remaining = pOp->nGlyphs;
+ glitz_surface_t *mask = NULL;
+
+ XGL_SCREEN_PRIV (pScreen);
+
+ pCache = &pScreenPriv->glyphCache[depth];
+ if (!pCache->pScreen)
+ {
+ if (!xglInitGlyphCache (pCache, pScreen, pOp->pLists->format))
+ return 1;
+ }
+
+ if (depth == 1)
+ {
+ glitz_multi_array_t *multiArray;
+
+ pGeometry = &pCache->u.geometry;
+ pGeometry->xOff = pGeometry->yOff = 0;
+
+ multiArray = glitz_multi_array_create (pOp->nGlyphs);
+ if (!multiArray)
+ return 1;
+
+ GEOMETRY_SET_MULTI_ARRAY (pGeometry, multiArray);
+ glitz_multi_array_destroy (multiArray);
+
+ vData.array.lastX = 0;
+ vData.array.lastY = 0;
+ }
+ else
+ {
+ n = pCache->u.texture.format.vertex.bytes_per_vertex;
+ pGeometry = xglGetScratchGeometryWithSize (pScreen, 4 * n * remaining);
+
+ pGeometry->f = pCache->u.texture.format;
+ pGeometry->type = GLITZ_GEOMETRY_TYPE_VERTEX;
+ mask = pCache->u.texture.mask;
+
+ vData.list.s = glitz_buffer_map (pGeometry->buffer,
+ GLITZ_BUFFER_ACCESS_WRITE_ONLY);
+ }
+
+ NEXT_GLYPH_SERIAL_NUMBER;
+
+ while (pOp->nGlyphs)
+ {
+ glyph = *pOp->ppGlyphs;
+
+ if (!pOp->listLen)
+ {
+ pOp->pLists++;
+ pOp->listLen = pOp->pLists->len;
+ pOp->xOff += pOp->pLists->xOff;
+ pOp->yOff += pOp->pLists->yOff;
+ }
+
+ xOff = pOp->xOff;
+ yOff = pOp->yOff;
+
+ pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, glyph);
+ pArea = pGlyphPriv->pArea;
+ if (!pArea)
+ {
+ n = pOp->nGlyphs;
+ while (n--)
+ {
+ pGlyphPriv = XGL_GET_GLYPH_PRIV (pScreen, pOp->ppGlyphs[n]);
+ pArea = pGlyphPriv->pArea;
+ if (pArea && pArea->width)
+ GLYPH_GET_AREA_PRIV (pArea)->serial = glyphSerialNumber;
+ }
+
+ pArea = xglCacheGlyph (pCache, glyph);
+ if (!pArea && pSrc)
+ break;
+ }
+
+ pOp->listLen--;
+ pOp->nGlyphs--;
+ pOp->ppGlyphs++;
+
+ pOp->xOff += glyph->info.xOff;
+ pOp->yOff += glyph->info.yOff;
+
+ if (!pArea)
+ continue;
+
+ x1 = xOff - glyph->info.x;
+ x2 = x1 + glyph->info.width;
+ if (x1 < extents.x1)
+ extents.x1 = x1;
+ if (x2 > extents.x2)
+ extents.x2 = x2;
+
+ y1 = yOff - glyph->info.y;
+ y2 = y1 + glyph->info.height;
+ if (y1 < extents.y1)
+ extents.y1 = y1;
+ if (y2 > extents.y2)
+ extents.y2 = y2;
+
+ if (pArea->width)
+ {
+ pGlyphArea = GLYPH_GET_AREA_PRIV (pArea);
+ if (depth == 1)
+ {
+ glitz_multi_array_add (pGeometry->array,
+ pGlyphArea->u.range.first, 2,
+ pGlyphArea->u.range.count,
+ (x1 - vData.array.lastX) << 16,
+ (y1 - vData.array.lastY) << 16);
+ vData.array.lastX = x1;
+ vData.array.lastY = y1;
+ }
+ else
+ {
+ if (pCache->u.texture.geometryDataType)
+ {
+ WRITE_BOX (vData.list.f, x1, y1, x2, y2,
+ pGlyphArea->u.box.fBox);
+ }
+ else
+ {
+ WRITE_BOX (vData.list.s, x1, y1, x2, y2,
+ pGlyphArea->u.box.sBox);
+ }
+ }
+ count++;
+ }
+ remaining--;
+ }
+
+ if (depth != 1)
+ {
+ glitz_buffer_unmap (pGeometry->buffer);
+ pGeometry->count = count * 4;
+ }
+
+ if (count)
+ {
+ xSrc += extents.x1;
+ ySrc += extents.y1;
+
+ if (!pSrc)
+ {
+ op = PictOpAdd;
+ pSrc = pScreenPriv->pSolidAlpha;
+
+ if (remaining)
+ *pOp = opSave;
+ }
+
+ GEOMETRY_TRANSLATE (pGeometry,
+ pDst->pDrawable->x,
+ pDst->pDrawable->y);
+
+ if (xglComp (op,
+ pSrc,
+ NULL,
+ pDst,
+ xSrc, ySrc,
+ 0, 0,
+ pDst->pDrawable->x + extents.x1,
+ pDst->pDrawable->y + extents.y1,
+ extents.x2 - extents.x1,
+ extents.y2 - extents.y1,
+ pGeometry,
+ mask))
+ {
+ xglAddCurrentBitDamage (pDst->pDrawable);
+ return remaining;
+ }
+
+ remaining = ~0;
+ pOp->noCache = TRUE;
+ *pOp = opSave;
+ }
+ else
+ {
+ if (remaining)
+ {
+ pOp->noCache = TRUE;
+ *pOp = opSave;
+ }
+ }
+
+ return remaining;
+}
+
+static Bool
+xglGlyphExtents (int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs,
+ BoxPtr extents)
+{
+ GlyphPtr glyph;
+ int x1, x2, y1, y2;
+ int n;
+ int x;
+ int y;
+ Bool x_overlap, overlap = FALSE;
+
+ x = 0;
+ y = 0;
+
+ while (!list->len)
+ {
+ if (--nlist)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ list++;
+ }
+ else
+ {
+ extents->x1 = MAXSHORT;
+ extents->x2 = MINSHORT;
+ extents->y1 = MAXSHORT;
+ extents->y2 = MINSHORT;
+
+ return FALSE;
+ }
+ }
+
+ glyph = *glyphs;
+ x1 = (x + list->xOff) - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = (y + list->yOff) - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+
+ extents->x1 = x1;
+ extents->x2 = x1;
+ extents->y1 = y1;
+ extents->y2 = y1;
+
+ while (nlist--)
+ {
+ x += list->xOff;
+ y += list->yOff;
+ n = list->len;
+ list++;
+
+ while (n--)
+ {
+ glyph = *glyphs++;
+ x1 = x - glyph->info.x;
+ if (x1 < MINSHORT)
+ x1 = MINSHORT;
+ y1 = y - glyph->info.y;
+ if (y1 < MINSHORT)
+ y1 = MINSHORT;
+ x2 = x1 + glyph->info.width;
+ if (x2 > MAXSHORT)
+ x2 = MAXSHORT;
+ y2 = y1 + glyph->info.height;
+ if (y2 > MAXSHORT)
+ y2 = MAXSHORT;
+
+ x_overlap = FALSE;
+ if (x1 >= extents->x2)
+ extents->x2 = x2;
+ else if (x2 <= extents->x1)
+ extents->x1 = x1;
+ else
+ {
+ x_overlap = TRUE;
+ if (x1 < extents->x1)
+ extents->x1 = x1;
+ if (x2 > extents->x2)
+ extents->x2 = x2;
+ }
+
+ if (y1 >= extents->y2)
+ extents->y2 = y2;
+ else if (y2 <= extents->y1)
+ extents->y1 = y1;
+ else
+ {
+ if (y1 < extents->y1)
+ extents->y1 = y1;
+ if (y2 > extents->y2)
+ extents->y2 = y2;
+
+ if (x_overlap)
+ overlap = TRUE;
+ }
+
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+ }
+
+ return overlap;
+}
+
+/* returns 0 if all glyph lists don't have the same format */
+static CARD32
+xglGlyphListFormatId (GlyphListPtr list,
+ int nlist)
+{
+ CARD32 id = list->format->id;
+
+ nlist--;
+ list++;
+
+ while (nlist--)
+ {
+ if (list->format->id != id)
+ return 0;
+
+ list++;
+ }
+
+ return id;
+}
+
+void
+xglGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PicturePtr pMask = NULL, pSrcPicture, pDstPicture;
+ BoxRec extents;
+ xglGlyphOpRec glyphOp;
+ int xDst = list->xOff, yDst = list->yOff;
+
+ if (op != PictOpAdd && maskFormat &&
+ (xglGlyphExtents (nlist, list, glyphs, &extents) || op != PictOpOver ||
+ xglGlyphListFormatId (list, nlist) != maskFormat->id))
+ {
+ PixmapPtr pPixmap;
+ xglPixmapPtr pPixmapPriv;
+ CARD32 componentAlpha;
+ GCPtr pGC;
+ xRectangle rect;
+ int error;
+
+ if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
+ return;
+
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = extents.x2 - extents.x1;
+ rect.height = extents.y2 - extents.y1;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen,
+ rect.width, rect.height,
+ maskFormat->depth);
+ if (!pPixmap)
+ return;
+
+ componentAlpha = NEEDS_COMPONENT (maskFormat->format);
+ pMask = CreatePicture (0, &pPixmap->drawable,
+ maskFormat, CPComponentAlpha, &componentAlpha,
+ serverClient, &error);
+ if (!pMask)
+ return;
+
+ ValidatePicture (pMask);
+ pGC = GetScratchGC (pPixmap->drawable.depth, pScreen);
+ ValidateGC (&pPixmap->drawable, pGC);
+ (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &rect);
+ FreeScratchGC (pGC);
+
+ /* all will be damaged */
+ pPixmapPriv = XGL_GET_PIXMAP_PRIV (pPixmap);
+ pPixmapPriv->damageBox.x1 = 0;
+ pPixmapPriv->damageBox.y1 = 0;
+ pPixmapPriv->damageBox.x2 = pMask->pDrawable->width;
+ pPixmapPriv->damageBox.y2 = pMask->pDrawable->height;
+
+ (*pScreen->DestroyPixmap) (pPixmap);
+
+ glyphOp.xOff = -extents.x1;
+ glyphOp.yOff = -extents.y1;
+ pSrcPicture = NULL;
+ pDstPicture = pMask;
+ }
+ else
+ {
+ glyphOp.xOff = 0;
+ glyphOp.yOff = 0;
+ pSrcPicture = pSrc;
+ pDstPicture = pDst;
+ }
+
+ glyphOp.ppGlyphs = glyphs;
+
+ if (xglPrepareTarget (pDstPicture->pDrawable))
+ glyphOp.noCache = FALSE;
+ else
+ glyphOp.noCache = TRUE;
+
+ while (nlist--)
+ {
+ glyphOp.xOff += list->xOff;
+ glyphOp.yOff += list->yOff;
+ glyphOp.listLen = list->len;
+ glyphOp.nGlyphs = list->len;
+ glyphOp.pLists = list++;
+
+ for (; nlist; nlist--, list++)
+ {
+ if (list->format->id != glyphOp.pLists->format->id)
+ break;
+
+ glyphOp.nGlyphs += list->len;
+ }
+
+ while (glyphOp.nGlyphs)
+ {
+ if (glyphOp.noCache || xglCachedGlyphs (op,
+ pSrcPicture,
+ pDstPicture,
+ xSrc - xDst, ySrc - yDst,
+ &glyphOp))
+ xglUncachedGlyphs (op,
+ pSrcPicture,
+ pDstPicture,
+ xSrc - xDst, ySrc - yDst,
+ &glyphOp);
+ }
+ }
+
+ if (pMask)
+ {
+ xglLeaveOffscreenArea ((PixmapPtr) pMask->pDrawable);
+
+ CompositePicture (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc + extents.x1 - xDst,
+ ySrc + extents.y1 - yDst,
+ 0, 0,
+ extents.x1, extents.y1,
+ extents.x2 - extents.x1,
+ extents.y2 - extents.y1);
+
+ FreePicture ((pointer) pMask, (XID) 0);
+ }
+}
+
+#endif
diff --git a/hw/xgl/xglinput.c b/hw/xgl/xglinput.c
index 6790d4bf2..91becc3c1 100644
--- a/hw/xgl/xglinput.c
+++ b/hw/xgl/xglinput.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
diff --git a/hw/xgl/xgloffscreen.c b/hw/xgl/xgloffscreen.c
index 7018c054a..b19c3ce21 100644
--- a/hw/xgl/xgloffscreen.c
+++ b/hw/xgl/xgloffscreen.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,278 +20,98 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
-/*
- * This offscreen memory manager is horrible and needs some serious work.
- *
- * It's a recursive memory manager. It's quite fast but wastes huge
- * amounts of memory. A simple scoring mechanism is used and pixmaps
- * that blit to screen get high scores which makes a compositing
- * manager run fast.
- *
- * NOTE: With GL_ARB_uber_buffer or GL_EXT_render_target we probably
- * wont need this offscreen management at all.
- */
-
static glitz_drawable_buffer_t _buffers[] = {
GLITZ_DRAWABLE_BUFFER_BACK_COLOR,
GLITZ_DRAWABLE_BUFFER_FRONT_COLOR
};
-#define MAX_LEVEL 6
+#define MAX_OFFSCREEN_LEVEL 8
+
+static Bool
+xglOffscreenCreate (xglAreaPtr pArea)
+{
+ return TRUE;
+}
static Bool
-xglOffscreenMoveIn (xglOffscreenAreaPtr pArea,
- PixmapPtr pPixmap)
+xglOffscreenMoveIn (xglAreaPtr pArea,
+ pointer closure)
{
+ xglOffscreenPtr pOffscreen = (xglOffscreenPtr) pArea->pRoot->closure;
+ PixmapPtr pPixmap = (PixmapPtr) closure;
+
XGL_PIXMAP_PRIV (pPixmap);
if (!xglSyncSurface (&pPixmap->drawable))
FatalError (XGL_SW_FAILURE_STRING);
- pArea->pPixmapPriv = pPixmapPriv;
- pArea->state = xglOffscreenAreaOccupied;
-
pPixmapPriv->pArea = pArea;
pPixmapPriv->target = xglPixmapTargetIn;
glitz_surface_attach (pPixmapPriv->surface,
- pArea->pOffscreen->drawable,
- pArea->pOffscreen->buffer,
+ pOffscreen->drawable, pOffscreen->buffer,
pArea->x, pArea->y);
- XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 500);
+ XGL_INCREMENT_PIXMAP_SCORE (pPixmapPriv, 100);
return TRUE;
}
static void
-xglOffscreenMoveOut (xglOffscreenAreaPtr pArea)
+xglOffscreenMoveOut (xglAreaPtr pArea,
+ pointer closure)
{
- glitz_surface_detach (pArea->pPixmapPriv->surface);
-
- pArea->pPixmapPriv->pArea = NULL;
- pArea->pPixmapPriv->target = xglPixmapTargetOut;
- pArea->pPixmapPriv = NULL;
- pArea->state = xglOffscreenAreaAvailable;
-}
+ PixmapPtr pPixmap = (PixmapPtr) closure;
-static xglOffscreenAreaPtr
-xglCreateOffscreenArea (xglOffscreenPtr pOffscreen,
- int level,
- int x,
- int y)
-{
- xglOffscreenAreaPtr pArea;
- int i;
-
- pArea = xalloc (sizeof (xglOffscreenAreaRec));
- if (!pArea)
- return NULL;
-
- pArea->level = level;
- pArea->x = x;
- pArea->y = y;
- pArea->pOffscreen = pOffscreen;
- pArea->pPixmapPriv = NULL;
- pArea->state = xglOffscreenAreaAvailable;
-
- for (i = 0; i < 4; i++)
- pArea->pArea[i] = NULL;
-
- return pArea;
-}
-
-static void
-xglDestroyOffscreenArea (xglOffscreenAreaPtr pArea)
-{
- if (!pArea)
- return;
-
- if (pArea->pPixmapPriv)
- {
- xglOffscreenMoveOut (pArea);
- }
- else
- {
- int i;
+ XGL_PIXMAP_PRIV (pPixmap);
- for (i = 0; i < 4; i++)
- xglDestroyOffscreenArea (pArea->pArea[i]);
- }
+ glitz_surface_detach (pPixmapPriv->surface);
- xfree (pArea);
+ 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)
+static int
+xglOffscreenCompareScore (xglAreaPtr pArea,
+ pointer closure1,
+ pointer closure2)
{
- 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;
+ int s1, s2;
- return TRUE;
-}
+ XGL_PIXMAP_PRIV ((PixmapPtr) closure1);
-static void
-xglOffscreenFini (xglOffscreenPtr pOffscreen)
-{
- xglDestroyOffscreenArea (pOffscreen->pArea);
- glitz_drawable_destroy (pOffscreen->drawable);
-}
-
-static int
-xglOffscreenAreaGetTopScore (xglOffscreenAreaPtr pArea)
-{
- int topScore;
+ s1 = pPixmapPriv->score;
+ s2 = XGL_GET_PIXMAP_PRIV ((PixmapPtr) closure2)->score;
- if (pArea->pPixmapPriv)
- {
- topScore = pArea->pPixmapPriv->score;
- XGL_DECREMENT_PIXMAP_SCORE (pArea->pPixmapPriv, 5);
-
- return topScore;
- }
- else
- {
- int topScore, score, i;
-
- topScore = 0;
- for (i = 0; i < 4; i++)
- {
- if (pArea->pArea[i])
- {
- score = xglOffscreenAreaGetTopScore (pArea->pArea[i]);
- if (score > topScore)
- topScore = score;
- }
- }
- return topScore;
- }
+ if (s1 > s2)
+ XGL_DECREMENT_PIXMAP_SCORE (pPixmapPriv, 10);
+
+ return s1 - s2;
}
-
-static Bool
-xglOffscreenFindArea (xglOffscreenAreaPtr pArea,
- PixmapPtr pPixmap,
- int level)
-{
- if (pArea->level > level)
- return FALSE;
-
- switch (pArea->state) {
- case xglOffscreenAreaOccupied:
- {
- XGL_PIXMAP_PRIV (pPixmap);
-
- if (pPixmapPriv->score < pArea->pPixmapPriv->score)
- {
- XGL_DECREMENT_PIXMAP_SCORE (pArea->pPixmapPriv, 10);
-
- return FALSE;
- }
-
- xglOffscreenMoveOut (pArea);
- }
- /* fall-through */
- case xglOffscreenAreaAvailable:
- {
- if (pArea->level == level || pArea->level == MAX_LEVEL)
- {
- if (xglOffscreenMoveIn (pArea, pPixmap))
- return TRUE;
- }
- else
- {
- int dx[4], dy[4], i;
-
- dx[0] = dx[2] = dy[0] = dy[1] = 0;
- dx[1] = dx[3] = pArea->pOffscreen->width >> (pArea->level + 1);
- dy[2] = dy[3] = pArea->pOffscreen->height >> (pArea->level + 1);
-
- for (i = 0; i < 4; i++)
- {
- pArea->pArea[i] =
- xglCreateOffscreenArea (pArea->pOffscreen,
- pArea->level + 1,
- pArea->x + dx[i],
- pArea->y + dy[i]);
- }
-
- pArea->state = xglOffscreenAreaDivided;
-
- if (xglOffscreenFindArea (pArea->pArea[0], pPixmap, level))
- return TRUE;
- }
- } break;
- case xglOffscreenAreaDivided:
- {
- int i;
-
- if (pArea->level == level)
- {
- int topScore;
-
- XGL_PIXMAP_PRIV (pPixmap);
-
- topScore = xglOffscreenAreaGetTopScore (pArea);
-
- if (pPixmapPriv->score >= topScore)
- {
- /*
- * Kick out old pixmaps
- */
- for (i = 0; i < 4; i++)
- {
- xglDestroyOffscreenArea (pArea->pArea[i]);
- pArea->pArea[i] = NULL;
- }
-
- if (xglOffscreenMoveIn (pArea, pPixmap))
- return TRUE;
- }
- }
- else
- {
- for (i = 0; i < 4; i++)
- {
- if (xglOffscreenFindArea (pArea->pArea[i], pPixmap, level))
- return TRUE;
- }
- }
- } break;
- }
-
- return FALSE;
-}
+static const xglAreaFuncsRec xglOffscreenAreaFuncs = {
+ xglOffscreenCreate,
+ xglOffscreenMoveIn,
+ xglOffscreenMoveOut,
+ xglOffscreenCompareScore
+};
Bool
xglInitOffscreen (ScreenPtr pScreen,
xglScreenInfoPtr pScreenInfo)
{
xglOffscreenPtr pOffscreen;
- int nOffscreen;
glitz_drawable_format_t *format;
XGL_SCREEN_PRIV (pScreen);
- pScreenPriv->pOffscreen = NULL;
+ pOffscreen = pScreenPriv->pOffscreen;
+
pScreenPriv->nOffscreen = 0;
format = glitz_drawable_get_format (pScreenPriv->drawable);
@@ -301,33 +121,32 @@ xglInitOffscreen (ScreenPtr pScreen,
*/
if (format->doublebuffer)
{
- pScreenPriv->pOffscreen =
- xrealloc (pScreenPriv->pOffscreen,
- sizeof (xglOffscreenRec) *
- (pScreenPriv->nOffscreen + 1));
- if (pScreenPriv->pOffscreen)
+ pOffscreen->drawable = pScreenPriv->drawable;
+ pOffscreen->format = format;
+ pOffscreen->buffer = GLITZ_DRAWABLE_BUFFER_BACK_COLOR;
+
+ if (xglRootAreaInit (&pOffscreen->rootArea,
+ MAX_OFFSCREEN_LEVEL,
+ pScreenInfo->width,
+ pScreenInfo->height, 0,
+ (xglAreaFuncsPtr) &xglOffscreenAreaFuncs,
+ (pointer) pOffscreen))
{
- pOffscreen = &pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
+ glitz_drawable_reference (pOffscreen->drawable);
- if (xglOffscreenInit (pOffscreen,
- pScreenPriv->drawable,
- GLITZ_DRAWABLE_BUFFER_BACK_COLOR,
- pScreenInfo->width, pScreenInfo->height))
- {
- pScreenPriv->nOffscreen++;
- ErrorF ("Initialized %dx%d back buffer offscreen area\n",
- pScreenInfo->width, pScreenInfo->height);
- }
+ pScreenPriv->nOffscreen++;
+ pOffscreen++;
+ ErrorF ("Initialized %dx%d back buffer offscreen area\n",
+ pScreenInfo->width, pScreenInfo->height);
}
}
if (nxglPbufferVisuals)
{
- glitz_pbuffer_attributes_t attributes;
- unsigned long mask;
- glitz_drawable_t *pbuffer;
- int i;
-
+ glitz_drawable_t *pbuffer;
+ unsigned int width, height;
+ int i;
+
for (i = 0; i < nxglPbufferVisuals; i++)
{
/*
@@ -338,26 +157,25 @@ xglInitOffscreen (ScreenPtr pScreen,
* supports accelerated pbuffers but offscreen drawing is really
* slow, try decrementing these values.
*/
- attributes.width = 2048;
- attributes.height = 2048;
-
- mask = GLITZ_PBUFFER_WIDTH_MASK | GLITZ_PBUFFER_HEIGHT_MASK;
-
- pbuffer =
- glitz_create_pbuffer_drawable (pScreenPriv->drawable,
- xglPbufferVisuals[i].format,
- &attributes, mask);
+ width = 2048;
+ height = 2048;
+
+ do {
+ pbuffer =
+ glitz_create_pbuffer_drawable (pScreenPriv->drawable,
+ xglPbufferVisuals[i].format,
+ width, height);
+ width >>= 1;
+ height >>= 1;
+ } while (!pbuffer && width);
if (pbuffer)
{
- unsigned long width, height;
- int j;
+ int j = 0;
width = glitz_drawable_get_width (pbuffer);
height = glitz_drawable_get_height (pbuffer);
- j = 0;
-
/*
* No back buffer? only add front buffer.
*/
@@ -366,23 +184,23 @@ xglInitOffscreen (ScreenPtr pScreen,
while (j < 2)
{
- pScreenPriv->pOffscreen =
- xrealloc (pScreenPriv->pOffscreen,
- sizeof (xglOffscreenRec) *
- (pScreenPriv->nOffscreen + 1));
- if (pScreenPriv->pOffscreen)
+ pOffscreen->drawable = pbuffer;
+ pOffscreen->format = xglPbufferVisuals[i].format;
+ pOffscreen->buffer = _buffers[j];
+
+ if (xglRootAreaInit (&pOffscreen->rootArea,
+ MAX_OFFSCREEN_LEVEL,
+ width, height, 0,
+ (xglAreaFuncsPtr)
+ &xglOffscreenAreaFuncs,
+ (pointer) pOffscreen))
{
- pOffscreen =
- &pScreenPriv->pOffscreen[pScreenPriv->nOffscreen];
-
- if (xglOffscreenInit (pOffscreen,
- pbuffer, _buffers[j],
- width, height))
- {
- pScreenPriv->nOffscreen++;
- ErrorF ("Initialized %dx%d pbuffer offscreen "
- "area\n", width, height);
- }
+ glitz_drawable_reference (pbuffer);
+
+ pScreenPriv->nOffscreen++;
+ pOffscreen++;
+ ErrorF ("Initialized %dx%d pbuffer offscreen area\n",
+ width, height);
}
j++;
}
@@ -390,18 +208,6 @@ xglInitOffscreen (ScreenPtr pScreen,
}
}
}
-
- pOffscreen = pScreenPriv->pOffscreen;
- nOffscreen = pScreenPriv->nOffscreen;
-
- /*
- * Update offscreen pointers in root offscreen areas
- */
- while (nOffscreen--)
- {
- pOffscreen->pArea->pOffscreen = pOffscreen;
- pOffscreen++;
- }
return TRUE;
}
@@ -409,13 +215,18 @@ xglInitOffscreen (ScreenPtr pScreen,
void
xglFiniOffscreen (ScreenPtr pScreen)
{
- XGL_SCREEN_PRIV (pScreen);
-
- while (pScreenPriv->nOffscreen--)
- xglOffscreenFini (&pScreenPriv->pOffscreen[pScreenPriv->nOffscreen]);
+ int n;
- if (pScreenPriv->pOffscreen)
- xfree (pScreenPriv->pOffscreen);
+ XGL_SCREEN_PRIV (pScreen);
+
+ n = pScreenPriv->nOffscreen;
+ while (n--)
+ {
+ xglRootAreaFini (&pScreenPriv->pOffscreen[n].rootArea);
+ glitz_drawable_destroy (pScreenPriv->pOffscreen[n].drawable);
+ }
+
+ pScreenPriv->nOffscreen = 0;
}
Bool
@@ -439,34 +250,41 @@ xglFindOffscreenArea (ScreenPtr pScreen,
while (nOffscreen--)
{
- int level;
-
if (pOffscreen->format->color.red_size >= pColor->red_size &&
pOffscreen->format->color.green_size >= pColor->green_size &&
pOffscreen->format->color.blue_size >= pColor->blue_size &&
pOffscreen->format->color.alpha_size >= pColor->alpha_size)
{
+ /* Find available area */
+ if (xglFindArea (pOffscreen->rootArea.pArea,
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ FALSE,
+ (pointer) pPixmap))
+ return TRUE;
- level = 0;
- while ((pOffscreen->width >> level) >= pPixmap->drawable.width &&
- (pOffscreen->height >> level) >= pPixmap->drawable.height)
- level++;
-
- if (!level)
- continue;
-
- if (xglOffscreenFindArea (pOffscreen->pArea, pPixmap, level - 1))
+ /* Kicking out area with lower score */
+ if (xglFindArea (pOffscreen->rootArea.pArea,
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ TRUE,
+ (pointer) pPixmap))
return TRUE;
}
+
pOffscreen++;
}
-
+
return FALSE;
}
void
-xglWithdrawOffscreenArea (xglOffscreenAreaPtr pArea)
+xglLeaveOffscreenArea (PixmapPtr pPixmap)
{
- pArea->pPixmapPriv = NULL;
- pArea->state = xglOffscreenAreaAvailable;
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (pPixmapPriv->pArea)
+ xglLeaveArea (pPixmapPriv->pArea);
+
+ pPixmapPriv->pArea = NULL;
}
diff --git a/hw/xgl/xgloutput.c b/hw/xgl/xgloutput.c
index 09a09c77f..788dafb43 100644
--- a/hw/xgl/xgloutput.c
+++ b/hw/xgl/xgloutput.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
diff --git a/hw/xgl/xglparse.c b/hw/xgl/xglparse.c
index 185a842a2..ed95680d1 100644
--- a/hw/xgl/xglparse.c
+++ b/hw/xgl/xglparse.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -100,8 +100,11 @@ void
xglUseMsg (void)
{
ErrorF ("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM] "
- "Specify screen characteristics\n");
- ErrorF ("-fullscreen Run fullscreen\n");
+ "specify screen characteristics\n");
+ ErrorF ("-fullscreen run fullscreen\n");
+ ErrorF ("-vertextype [short|float] set vertex data type\n");
+ ErrorF ("-vbostream "
+ "use vertex buffer objects for streaming of vertex data\n");
}
int
@@ -121,12 +124,30 @@ xglProcessArgument (xglScreenInfoPtr pScreenInfo,
return 2;
}
-
- if (!strcmp (argv[i], "-fullscreen"))
+ else if (!strcmp (argv[i], "-fullscreen"))
{
pScreenInfo->fullscreen = TRUE;
return 1;
}
-
+ else if (!strcmp (argv[i], "-vertextype"))
+ {
+ if ((i + 1) < argc)
+ {
+ if (!strcasecmp (argv[i + 1], "short"))
+ pScreenInfo->geometryDataType = GEOMETRY_DATA_TYPE_SHORT;
+ else if (!strcasecmp (argv[i + 1], "float"))
+ pScreenInfo->geometryDataType = GEOMETRY_DATA_TYPE_FLOAT;
+ }
+ else
+ return 1;
+
+ return 2;
+ }
+ else if (!strcmp (argv[i], "-vbostream"))
+ {
+ pScreenInfo->geometryUsage = GEOMETRY_USAGE_STREAM;
+ return 1;
+ }
+
return 0;
}
diff --git a/hw/xgl/xglpict.c b/hw/xgl/xglpict.c
index 7bfbcd398..90f1c900e 100644
--- a/hw/xgl/xglpict.c
+++ b/hw/xgl/xglpict.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,10 +20,11 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
+#include "fb.h"
#ifdef RENDER
@@ -33,7 +34,7 @@
#define XGL_PICTURE_FALLBACK_EPILOGUE(pPicture, func, xglfunc) \
XGL_PICTURE_SCREEN_WRAP (func, xglfunc); \
- xglAddSurfaceDamage (pPicture->pDrawable)
+ xglAddCurrentSurfaceDamage (pPicture->pDrawable)
void
xglComposite (CARD8 op,
@@ -49,7 +50,7 @@ xglComposite (CARD8 op,
CARD16 width,
CARD16 height)
{
- PictureScreenPtr pPictureScreen;
+ PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen);
@@ -58,9 +59,13 @@ xglComposite (CARD8 op,
pSrc, pMask, pDst,
xSrc, ySrc,
xMask, yMask,
- xDst, yDst,
- width, height))
+ xDst + pDst->pDrawable->x, yDst + pDst->pDrawable->y,
+ width, height,
+ NULL, NULL))
+ {
+ xglAddCurrentBitDamage (pDst->pDrawable);
return;
+ }
pPictureScreen = GetPictureScreen (pScreen);
@@ -73,46 +78,74 @@ xglComposite (CARD8 op,
FatalError (XGL_SW_FAILURE_STRING);
}
- XGL_PICTURE_FALLBACK_PROLOGUE (pDst, Composite);
+ if (op == PictOpSrc)
+ {
+ XGL_DRAWABLE_PIXMAP (pDst->pDrawable);
+
+ if (!xglMapPixmapBits (pPixmap))
+ FatalError (XGL_SW_FAILURE_STRING);
+ } else
+ xglSyncDamageBoxBits (pDst->pDrawable);
+
+ XGL_PICTURE_SCREEN_UNWRAP (Composite);
(*pPictureScreen->Composite) (op, pSrc, pMask, pDst,
xSrc, ySrc, xMask, yMask, xDst, yDst,
width, height);
- XGL_PICTURE_FALLBACK_EPILOGUE (pDst, Composite, xglComposite);
-}
+ XGL_PICTURE_SCREEN_WRAP (Composite, xglComposite);
-void
-xglGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
-{
- miGlyphs (op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ 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
-xglRasterizeTrapezoid (PicturePtr pDst,
- xTrapezoid *trap,
- int xOff,
- int yOff)
+xglAddTriangles (PicturePtr pDst,
+ INT16 xOff,
+ INT16 yOff,
+ int ntri,
+ xTriangle *tris)
{
PictureScreenPtr pPictureScreen;
ScreenPtr pScreen = pDst->pDrawable->pScreen;
XGL_SCREEN_PRIV (pScreen);
+ XGL_DRAWABLE_PIXMAP_PRIV (pDst->pDrawable);
pPictureScreen = GetPictureScreen (pScreen);
- XGL_PICTURE_FALLBACK_PROLOGUE (pDst, RasterizeTrapezoid);
- (*pPictureScreen->RasterizeTrapezoid) (pDst, trap, xOff, yOff);
- XGL_PICTURE_FALLBACK_EPILOGUE (pDst, RasterizeTrapezoid,
- xglRasterizeTrapezoid);
+ pPixmapPriv->damageBox.x1 = 0;
+ pPixmapPriv->damageBox.y1 = 0;
+ pPixmapPriv->damageBox.x2 = pDst->pDrawable->width;
+ pPixmapPriv->damageBox.y2 = pDst->pDrawable->height;
+
+ XGL_PICTURE_FALLBACK_PROLOGUE (pDst, AddTriangles);
+ (*pPictureScreen->AddTriangles) (pDst, xOff, yOff, ntri, tris);
+ XGL_PICTURE_FALLBACK_EPILOGUE (pDst, AddTriangles, xglAddTriangles);
}
+
void
xglChangePicture (PicturePtr pPicture,
Mask mask)
@@ -207,16 +240,18 @@ xglUpdatePicture (PicturePtr pPicture)
case PictFilterNearest:
case PictFilterFast:
glitz_surface_set_filter (surface, GLITZ_FILTER_NEAREST, NULL, 0);
- pPixmapPriv->pictureMask &= ~xglPFFilterMask;
break;
case PictFilterGood:
case PictFilterBest:
case PictFilterBilinear:
glitz_surface_set_filter (surface, GLITZ_FILTER_BILINEAR, NULL, 0);
- pPixmapPriv->pictureMask &= ~xglPFFilterMask;
break;
- default:
- pPixmapPriv->pictureMask |= xglPFFilterMask;
+ case PictFilterConvolution:
+ glitz_surface_set_filter (surface, GLITZ_FILTER_CONVOLUTION,
+ (glitz_fixed16_16_t *)
+ pPicture->filter_params,
+ pPicture->filter_nparams);
+ break;
}
}
@@ -237,4 +272,185 @@ xglUpdatePicture (PicturePtr pPicture)
pPixmapPriv->pictureMask &= ~XGL_PICTURE_CHANGES (~0);
}
+static int
+xglVisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
+{
+ DepthPtr pDepth;
+ int d, v;
+
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ for (v = 0; v < pDepth->numVids; v++)
+ if (pDepth->vids[v] == pVisual->vid)
+ return pDepth->depth;
+ }
+
+ return 0;
+}
+
+typedef struct _xglformatInit {
+ CARD32 format;
+ CARD8 depth;
+} xglFormatInitRec, *xglFormatInitPtr;
+
+static int
+xglAddFormat (xglFormatInitPtr formats,
+ int nformat,
+ CARD32 format,
+ CARD8 depth)
+{
+ int n;
+
+ for (n = 0; n < nformat; n++)
+ if (formats[n].format == format && formats[n].depth == depth)
+ return nformat;
+
+ formats[nformat].format = format;
+ formats[nformat].depth = depth;
+
+ return ++nformat;
+}
+
+#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n)) - 1))
+
+Bool
+xglPictureInit (ScreenPtr pScreen)
+{
+ int f, nformats = 0;
+ PictFormatPtr pFormats;
+ xglFormatInitRec formats[64];
+ CARD32 format;
+ CARD8 depth;
+ VisualPtr pVisual;
+ int v;
+ int bpp;
+ int r, g, b;
+ int d;
+ DepthPtr pDepth;
+
+ /* formats required by protocol */
+ formats[nformats].format = PICT_a1;
+ formats[nformats].depth = 1;
+ nformats++;
+ formats[nformats].format = PICT_a4;
+ formats[nformats].depth = 4;
+ nformats++;
+ formats[nformats].format = PICT_a8;
+ formats[nformats].depth = 8;
+ nformats++;
+ formats[nformats].format = PICT_a8r8g8b8;
+ formats[nformats].depth = 32;
+ nformats++;
+
+ /* now look through the depths and visuals adding other formats */
+ for (v = 0; v < pScreen->numVisuals; v++)
+ {
+ pVisual = &pScreen->visuals[v];
+ depth = xglVisualDepth (pScreen, pVisual);
+ if (!depth)
+ continue;
+
+ bpp = BitsPerPixel (depth);
+ switch (pVisual->class) {
+ case DirectColor:
+ case TrueColor:
+ r = Ones (pVisual->redMask);
+ g = Ones (pVisual->greenMask);
+ b = Ones (pVisual->blueMask);
+ if (pVisual->offsetBlue == 0 &&
+ pVisual->offsetGreen == b &&
+ pVisual->offsetRed == b + g)
+ {
+ format = PICT_FORMAT (bpp, PICT_TYPE_ARGB, 0, r, g, b);
+ nformats = xglAddFormat (formats, nformats, format, depth);
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case StaticGray:
+ case GrayScale:
+ break;
+ }
+ }
+
+ /* walk supported depths and add missing Direct formats */
+ for (d = 0; d < pScreen->numDepths; d++)
+ {
+ pDepth = &pScreen->allowedDepths[d];
+ bpp = BitsPerPixel (pDepth->depth);
+ format = 0;
+ switch (bpp) {
+ case 16:
+ if (pDepth->depth == 15)
+ nformats = xglAddFormat (formats, nformats,
+ PICT_x1r5g5b5, pDepth->depth);
+ if (pDepth->depth == 16)
+ nformats = xglAddFormat (formats, nformats,
+ PICT_r5g6b5, pDepth->depth);
+ break;
+ case 24:
+ if (pDepth->depth == 24)
+ nformats = xglAddFormat (formats, nformats,
+ PICT_r8g8b8, pDepth->depth);
+ break;
+ case 32:
+ if (pDepth->depth == 24)
+ nformats = xglAddFormat (formats, nformats,
+ PICT_x8r8g8b8, pDepth->depth);
+ break;
+ }
+ }
+
+ pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
+ if (!pFormats)
+ return 0;
+
+ memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
+ for (f = 0; f < nformats; f++)
+ {
+ pFormats[f].id = FakeClientID (0);
+ pFormats[f].depth = formats[f].depth;
+ format = formats[f].format;
+ pFormats[f].format = format;
+ pFormats[f].type = PictTypeDirect;
+ switch (PICT_FORMAT_TYPE (format)) {
+ case PICT_TYPE_ARGB:
+ pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format));
+ if (pFormats[f].direct.alphaMask)
+ pFormats[f].direct.alpha = (PICT_FORMAT_R (format) +
+ PICT_FORMAT_G (format) +
+ PICT_FORMAT_B (format));
+
+ pFormats[f].direct.redMask = Mask (PICT_FORMAT_R (format));
+ pFormats[f].direct.red = (PICT_FORMAT_G (format) +
+ PICT_FORMAT_B (format));
+
+ pFormats[f].direct.greenMask = Mask (PICT_FORMAT_G (format));
+ pFormats[f].direct.green = PICT_FORMAT_B (format);
+
+ pFormats[f].direct.blueMask = Mask (PICT_FORMAT_B (format));
+ pFormats[f].direct.blue = 0;
+ break;
+ case PICT_TYPE_A:
+ pFormats[f].direct.alpha = 0;
+ pFormats[f].direct.alphaMask = Mask (PICT_FORMAT_A (format));
+ break;
+ case PICT_TYPE_COLOR:
+ case PICT_TYPE_GRAY:
+ break;
+ }
+ }
+
+ if (!fbPictureInit (pScreen, pFormats, nformats))
+ return FALSE;
+
+ if (PictureAddFilter (pScreen,
+ FilterConvolution,
+ miFilterValidateParams) < 0)
+ return FALSE;
+
+ return TRUE;
+}
+
#endif
diff --git a/hw/xgl/xglpixel.c b/hw/xgl/xglpixel.c
deleted file mode 100644
index f6ecf0a41..000000000
--- a/hw/xgl/xglpixel.c
+++ /dev/null
@@ -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;
-}
diff --git a/hw/xgl/xglpixmap.c b/hw/xgl/xglpixmap.c
index 099ded652..52ae1ead1 100644
--- a/hw/xgl/xglpixmap.c
+++ b/hw/xgl/xglpixmap.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -32,7 +32,7 @@ xglPixmapDamageReport (DamagePtr pDamage,
void *closure)
{
PixmapPtr pPixmap = (PixmapPtr) closure;
- BoxPtr pExt;
+ BoxPtr pExt;
XGL_PIXMAP_PRIV (pPixmap);
@@ -104,10 +104,9 @@ xglPixmapSurfaceInit (PixmapPtr pPixmap,
pPixmapPriv->target = xglPixmapTargetOut;
/*
- * Don't allow depth 8 pixmaps into offscreen drawables as
- * no trapezoid acceleration is hooked up yet.
+ * Do not allow accelerated drawing to bitmaps.
*/
- if (pPixmap->drawable.depth <= 8)
+ if (pPixmap->drawable.depth == 1)
pPixmapPriv->target = xglPixmapTargetNo;
/*
@@ -165,10 +164,11 @@ xglCreatePixmap (ScreenPtr pScreen,
if (!xglPixmapSurfaceInit (pPixmap, pScreenPriv->features, width, height))
return NullPixmap;
-
+
pPixmapPriv->buffer = NULL;
pPixmapPriv->bits = (pointer) 0;
pPixmapPriv->stride = 0;
+ pPixmapPriv->pGeometry = NULL;
pPixmapPriv->allBits = TRUE;
pPixmapPriv->bitBox.x1 = 0;
@@ -189,7 +189,7 @@ xglDestroyPixmap (PixmapPtr pPixmap)
return TRUE;
if (pPixmapPriv->pArea)
- xglWithdrawOffscreenArea (pPixmapPriv->pArea);
+ xglWithdrawArea (pPixmapPriv->pArea);
if (pPixmap->devPrivate.ptr)
{
@@ -197,6 +197,9 @@ xglDestroyPixmap (PixmapPtr pPixmap)
glitz_buffer_unmap (pPixmapPriv->buffer);
}
+ if (pPixmapPriv->pGeometry)
+ GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
+
if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer);
@@ -265,7 +268,6 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
else if ((bitsPerPixel < 0) && (depth > 0))
pPixmap->drawable.bitsPerPixel = BitsPerPixel (depth);
-
if (devKind > 0)
pPixmapPriv->stride = devKind;
else if ((devKind < 0) && ((width > 0) || (depth > 0)))
@@ -283,7 +285,7 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->drawable.height != oldHeight)
{
if (pPixmapPriv->pArea)
- xglWithdrawOffscreenArea (pPixmapPriv->pArea);
+ xglWithdrawArea (pPixmapPriv->pArea);
if (pPixmapPriv->surface)
glitz_surface_destroy (pPixmapPriv->surface);
@@ -304,6 +306,12 @@ xglModifyPixmapHeader (PixmapPtr pPixmap,
pPixmap->devPrivate.ptr = 0;
}
+
+ if (pPixmapPriv->pGeometry)
+ {
+ GEOMETRY_UNINIT (pPixmapPriv->pGeometry);
+ pPixmapPriv->pGeometry = NULL;
+ }
if (pPixmapPriv->buffer)
glitz_buffer_destroy (pPixmapPriv->buffer);
@@ -374,6 +382,63 @@ xglPixmapToRegion (PixmapPtr pPixmap)
return pRegion;
}
+xglGeometryPtr
+xglPixmapToGeometry (PixmapPtr pPixmap,
+ int xOff,
+ int yOff)
+{
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (pPixmap->devPrivate.ptr)
+ xglUnmapPixmapBits (pPixmap);
+
+ if (!pPixmapPriv->pGeometry)
+ {
+ xglGeometryPtr pGeometry;
+
+ if (!pPixmapPriv->buffer)
+ {
+ if (!xglAllocatePixmapBits (pPixmap))
+ return NULL;
+ }
+
+ pGeometry = xalloc (sizeof (xglGeometryRec));
+ if (!pGeometry)
+ return NULL;
+
+ GEOMETRY_INIT (pPixmap->drawable.pScreen, pGeometry,
+ GLITZ_GEOMETRY_TYPE_BITMAP,
+ GEOMETRY_USAGE_DYNAMIC, 0);
+
+ GEOMETRY_SET_BUFFER (pGeometry, pPixmapPriv->buffer);
+
+ if (pPixmapPriv->stride < 0)
+ {
+ pGeometry->f.bitmap.bytes_per_line = -pPixmapPriv->stride;
+ pGeometry->f.bitmap.scanline_order =
+ GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
+ }
+ else
+ {
+ pGeometry->f.bitmap.bytes_per_line = pPixmapPriv->stride;
+ pGeometry->f.bitmap.scanline_order =
+ GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+ }
+
+ pGeometry->f.bitmap.pad = ((1 + FB_MASK) >> FB_SHIFT) *
+ sizeof (FbBits);
+ pGeometry->width = pPixmap->drawable.width;
+ pGeometry->count = pPixmap->drawable.height;
+
+ pPixmapPriv->pGeometry = pGeometry;
+ }
+
+ pPixmapPriv->pGeometry->xOff = xOff << 16;
+ pPixmapPriv->pGeometry->yOff = yOff << 16;
+
+ return pPixmapPriv->pGeometry;
+}
+
Bool
xglCreatePixmapSurface (PixmapPtr pPixmap)
{
@@ -390,7 +455,8 @@ xglCreatePixmapSurface (PixmapPtr pPixmap)
glitz_surface_create (pScreenPriv->drawable,
pPixmapPriv->format,
pPixmap->drawable.width,
- pPixmap->drawable.height);
+ pPixmap->drawable.height,
+ 0, NULL);
if (!pPixmapPriv->surface)
{
pPixmapPriv->format = NULL;
@@ -415,8 +481,6 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
stride = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
- pPixmapPriv->stride = stride;
-
if (stride)
{
pPixmapPriv->bits = xalloc (height * stride);
@@ -432,6 +496,9 @@ xglAllocatePixmapBits (PixmapPtr pPixmap)
return FALSE;
}
}
+
+ /* XXX: pPixmapPriv->stride = -stride */
+ pPixmapPriv->stride = stride;
return TRUE;
}
@@ -454,15 +521,14 @@ xglMapPixmapBits (PixmapPtr pPixmap)
if (!bits)
return FALSE;
- if (XGL_INTERNAL_SCANLINE_ORDER_UPSIDE_DOWN && pPixmapPriv->format)
+ pPixmap->devKind = pPixmapPriv->stride;
+ if (pPixmapPriv->stride < 0)
{
- pPixmap->devKind = -pPixmapPriv->stride;
- pPixmap->devPrivate.ptr =
- bits + (pPixmap->drawable.height - 1) * pPixmapPriv->stride;
+ pPixmap->devPrivate.ptr = bits +
+ (pPixmap->drawable.height - 1) * -pPixmapPriv->stride;
}
else
{
- pPixmap->devKind = pPixmapPriv->stride;
pPixmap->devPrivate.ptr = bits;
}
}
diff --git a/hw/xgl/xglscreen.c b/hw/xgl/xglscreen.c
index b2e1e1f48..7ce02c1b1 100644
--- a/hw/xgl/xglscreen.c
+++ b/hw/xgl/xglscreen.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -28,6 +28,12 @@
#include "mipointer.h"
#include "damage.h"
#include "fb.h"
+#ifdef MITSHM
+#include "shmint.h"
+#endif
+#ifdef RENDER
+#include "glyphstr.h"
+#endif
int xglScreenGeneration = -1;
int xglScreenPrivateIndex;
@@ -35,12 +41,13 @@ int xglGCPrivateIndex;
int xglPixmapPrivateIndex;
int xglWinPrivateIndex;
+#ifdef RENDER
+int xglGlyphPrivateIndex;
+#endif
+
#define xglQueryBestSize (void *) NoopDDA
#define xglSaveScreen (void *) NoopDDA
-#define xglRealizeFont (void *) NoopDDA
-#define xglUnrealizeFont (void *) NoopDDA
-
#define xglConstrainCursor (void *) NoopDDA
#define xglCursorLimits (void *) NoopDDA
#define xglDisplayCursor (void *) NoopDDA
@@ -49,14 +56,6 @@ int xglWinPrivateIndex;
#define xglRecolorCursor (void *) NoopDDA
#define xglSetCursorPosition (void *) NoopDDA
-#define xglCreateColormap (void *) NoopDDA
-#define xglDestroyColormap (void *) NoopDDA
-#define xglInstallColormap (void *) NoopDDA
-#define xglUninstallColormap (void *) NoopDDA
-#define xglListInstalledColormaps (void *) NoopDDA
-#define xglStoreColors (void *) NoopDDA
-#define xglResolveColor (void *) NoopDDA
-
static PixmapPtr
xglGetWindowPixmap (WindowPtr pWin)
{
@@ -100,7 +99,13 @@ xglAllocatePrivates (ScreenPtr pScreen)
xglWinPrivateIndex = AllocateWindowPrivateIndex ();
if (xglWinPrivateIndex < 0)
return FALSE;
-
+
+#ifdef RENDER
+ xglGlyphPrivateIndex = AllocateGlyphPrivateIndex ();
+ if (xglGlyphPrivateIndex < 0)
+ return FALSE;
+#endif
+
xglScreenGeneration = serverGeneration;
}
@@ -114,7 +119,7 @@ xglAllocatePrivates (ScreenPtr pScreen)
if (!AllocateWindowPrivate (pScreen, xglWinPrivateIndex,
sizeof (xglWinRec)))
return FALSE;
-
+
pScreenPriv = xalloc (sizeof (xglScreenRec));
if (!pScreenPriv)
return FALSE;
@@ -128,7 +133,7 @@ Bool
xglScreenInit (ScreenPtr pScreen,
xglScreenInfoPtr pScreenInfo)
{
- xglScreenPtr pScreenPriv;
+ xglScreenPtr pScreenPriv;
#ifdef RENDER
PictureScreenPtr pPictureScreen;
@@ -152,11 +157,19 @@ xglScreenInit (ScreenPtr pScreen,
xglInitPixmapFormats (pScreen);
if (!pScreenPriv->pixmapFormats[32].format)
return FALSE;
+
+ pScreenPriv->geometryDataType = pScreenInfo->geometryDataType;
+ pScreenPriv->geometryUsage = pScreenInfo->geometryUsage;
+ GEOMETRY_INIT (pScreen, &pScreenPriv->scratchGeometry,
+ GLITZ_GEOMETRY_TYPE_VERTEX,
+ pScreenPriv->geometryUsage, 0);
+
pScreenPriv->surface =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[32].format,
- pScreenInfo->width, pScreenInfo->height);
+ pScreenInfo->width, pScreenInfo->height,
+ 0, NULL);
if (!pScreenPriv->surface)
return FALSE;
@@ -167,7 +180,7 @@ xglScreenInit (ScreenPtr pScreen,
if (monitorResolution == 0)
monitorResolution = XGL_DEFAULT_DPI;
-
+
if (!fbSetupScreen (pScreen, NULL,
pScreenInfo->width, pScreenInfo->height,
monitorResolution, monitorResolution,
@@ -187,8 +200,12 @@ xglScreenInit (ScreenPtr pScreen,
pScreenPriv->pVisual->pPixel->masks.bpp))
return FALSE;
+#ifdef MITSHM
+ ShmRegisterFuncs (pScreen, NULL);
+#endif
+
#ifdef RENDER
- if (!fbPictureInit (pScreen, 0, 0))
+ if (!xglPictureInit (pScreen))
return FALSE;
#endif
@@ -197,14 +214,10 @@ xglScreenInit (ScreenPtr pScreen,
XGL_SCREEN_WRAP (CopyWindow, xglCopyWindow);
XGL_SCREEN_WRAP (CreateWindow, xglCreateWindow);
+ XGL_SCREEN_WRAP (ChangeWindowAttributes, xglChangeWindowAttributes);
XGL_SCREEN_WRAP (PaintWindowBackground, xglPaintWindowBackground);
XGL_SCREEN_WRAP (PaintWindowBorder, xglPaintWindowBorder);
- /*
- pScreen->RealizeFont = xglRealizeFont;
- pScreen->UnrealizeFont = xglUnrealizeFont;
- */
-
XGL_SCREEN_WRAP (CreateGC, xglCreateGC);
pScreen->ConstrainCursor = xglConstrainCursor;
@@ -215,16 +228,6 @@ xglScreenInit (ScreenPtr pScreen,
pScreen->RecolorCursor = xglRecolorCursor;
pScreen->SetCursorPosition = xglSetCursorPosition;
- /*
- pScreen->CreateColormap = miInitializeColormap;
- pScreen->DestroyColormap = xglDestroyColormap;
- pScreen->InstallColormap = miInstallColormap;
- pScreen->UninstallColormap = miUninstallColormap;
- pScreen->ListInstalledColormaps = miListInstalledColormaps;
- pScreen->StoreColors = xglStoreColors;
- pScreen->ResolveColor = miResolveColor;
- */
-
pScreen->ModifyPixmapHeader = xglModifyPixmapHeader;
XGL_SCREEN_WRAP (BitmapToRegion, xglPixmapToRegion);
@@ -235,10 +238,19 @@ xglScreenInit (ScreenPtr pScreen,
#ifdef RENDER
pPictureScreen = GetPictureScreenIfSet (pScreen);
- if (pPictureScreen) {
+ if (pPictureScreen)
+ {
+ if (!AllocateGlyphPrivate (pScreen, xglGlyphPrivateIndex,
+ sizeof (xglGlyphRec)))
+ return FALSE;
+
+ XGL_PICTURE_SCREEN_WRAP (RealizeGlyph, xglRealizeGlyph);
+ XGL_PICTURE_SCREEN_WRAP (UnrealizeGlyph, xglUnrealizeGlyph);
XGL_PICTURE_SCREEN_WRAP (Composite, xglComposite);
XGL_PICTURE_SCREEN_WRAP (Glyphs, xglGlyphs);
- XGL_PICTURE_SCREEN_WRAP (RasterizeTrapezoid, xglRasterizeTrapezoid);
+ XGL_PICTURE_SCREEN_WRAP (Trapezoids, xglTrapezoids);
+ XGL_PICTURE_SCREEN_WRAP (AddTraps, xglAddTraps);
+ XGL_PICTURE_SCREEN_WRAP (AddTriangles, xglAddTriangles);
XGL_PICTURE_SCREEN_WRAP (ChangePicture, xglChangePicture);
XGL_PICTURE_SCREEN_WRAP (ChangePictureTransform,
xglChangePictureTransform);
@@ -260,6 +272,14 @@ xglScreenInit (ScreenPtr pScreen,
Bool
xglFinishScreenInit (ScreenPtr pScreen)
{
+
+#ifdef RENDER
+ glitz_vertex_format_t *format;
+ static glitz_color_t clearBlack = { 0x0, 0x0, 0x0, 0x0 };
+ static glitz_color_t solidWhite = { 0xffff, 0xffff, 0xffff, 0xffff };
+ int i;
+#endif
+
XGL_SCREEN_PRIV (pScreen);
miInitializeBackingStore (pScreen);
@@ -270,11 +290,54 @@ xglFinishScreenInit (ScreenPtr pScreen)
pScreenPriv->solid =
glitz_surface_create (pScreenPriv->drawable,
pScreenPriv->pixmapFormats[32].format,
- 1, 1);
+ 1, 1, 0, NULL);
if (!pScreenPriv->solid)
return FALSE;
glitz_surface_set_fill (pScreenPriv->solid, GLITZ_FILL_REPEAT);
+
+#ifdef RENDER
+ for (i = 0; i < 33; i++)
+ pScreenPriv->glyphCache[i].pScreen = NULL;
+
+ pScreenPriv->pSolidAlpha = NULL;
+
+ pScreenPriv->trapInfo.mask =
+ glitz_surface_create (pScreenPriv->drawable,
+ pScreenPriv->pixmapFormats[8].format,
+ 2, 1, 0, NULL);
+ if (!pScreenPriv->trapInfo.mask)
+ return FALSE;
+
+ glitz_set_rectangle (pScreenPriv->trapInfo.mask, &clearBlack, 0, 0, 1, 1);
+ glitz_set_rectangle (pScreenPriv->trapInfo.mask, &solidWhite, 1, 0, 1, 1);
+
+ glitz_surface_set_fill (pScreenPriv->trapInfo.mask, GLITZ_FILL_NEAREST);
+ glitz_surface_set_filter (pScreenPriv->trapInfo.mask,
+ GLITZ_FILTER_BILINEAR,
+ NULL, 0);
+
+ format = &pScreenPriv->trapInfo.format.vertex;
+ format->primitive = GLITZ_PRIMITIVE_QUADS;
+ format->attributes = GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK;
+
+ format->mask.type = GLITZ_DATA_TYPE_FLOAT;
+ format->mask.size = GLITZ_COORDINATE_SIZE_X;
+ format->bytes_per_vertex = sizeof (glitz_float_t);
+
+ if (pScreenPriv->geometryDataType)
+ {
+ format->type = GLITZ_DATA_TYPE_FLOAT;
+ format->bytes_per_vertex += 2 * sizeof (glitz_float_t);
+ format->mask.offset = 2 * sizeof (glitz_float_t);
+ }
+ else
+ {
+ format->type = GLITZ_DATA_TYPE_SHORT;
+ format->bytes_per_vertex += 2 * sizeof (glitz_short_t);
+ format->mask.offset = 2 * sizeof (glitz_short_t);
+ }
+#endif
return TRUE;
}
@@ -285,6 +348,19 @@ xglCloseScreen (int index,
{
XGL_SCREEN_PRIV (pScreen);
+#ifdef RENDER
+ int i;
+
+ for (i = 0; i < 33; i++)
+ xglFiniGlyphCache (&pScreenPriv->glyphCache[i]);
+
+ if (pScreenPriv->pSolidAlpha)
+ FreePicture ((pointer) pScreenPriv->pSolidAlpha, 0);
+
+ if (pScreenPriv->trapInfo.mask)
+ glitz_surface_destroy (pScreenPriv->trapInfo.mask);
+#endif
+
if (pScreenPriv->solid)
glitz_surface_destroy (pScreenPriv->solid);
@@ -292,9 +368,59 @@ xglCloseScreen (int index,
glitz_surface_destroy (pScreenPriv->surface);
xglFiniOffscreen (pScreen);
-
+
+ GEOMETRY_UNINIT (&pScreenPriv->scratchGeometry);
+
XGL_SCREEN_UNWRAP (CloseScreen);
xfree (pScreenPriv);
return (*pScreen->CloseScreen) (index, pScreen);
}
+
+#ifdef RENDER
+void
+xglCreateSolidAlphaPicture (ScreenPtr pScreen)
+{
+ static xRenderColor solidWhite = { 0xffff, 0xffff, 0xffff, 0xffff };
+ static xRectangle one = { 0, 0, 1, 1 };
+ PixmapPtr pPixmap;
+ PictFormatPtr pFormat;
+ int error;
+ Pixel pixel;
+ GCPtr pGC;
+ CARD32 tmpval[2];
+
+ XGL_SCREEN_PRIV (pScreen);
+
+ pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8);
+ if (!pFormat)
+ return;
+
+ pGC = GetScratchGC (pFormat->depth, pScreen);
+ if (!pGC)
+ return;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, 1, 1, pFormat->depth);
+ if (!pPixmap)
+ return;
+
+ miRenderColorToPixel (pFormat, &solidWhite, &pixel);
+
+ tmpval[0] = GXcopy;
+ tmpval[1] = pixel;
+
+ ChangeGC (pGC, GCFunction | GCForeground, tmpval);
+ ValidateGC (&pPixmap->drawable, pGC);
+ (*pGC->ops->PolyFillRect) (&pPixmap->drawable, pGC, 1, &one);
+ FreeScratchGC (pGC);
+
+ tmpval[0] = xTrue;
+ pScreenPriv->pSolidAlpha =
+ CreatePicture (0, &pPixmap->drawable, pFormat,
+ CPRepeat, tmpval, 0, &error);
+ (*pScreen->DestroyPixmap) (pPixmap);
+
+ if (pScreenPriv->pSolidAlpha)
+ ValidatePicture (pScreenPriv->pSolidAlpha);
+}
+#endif
diff --git a/hw/xgl/xglsolid.c b/hw/xgl/xglsolid.c
index 2892978e5..789c9dd12 100644
--- a/hw/xgl/xglsolid.c
+++ b/hw/xgl/xglsolid.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,16 +20,23 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
+#include "gcstruct.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
Bool
xglSolid (DrawablePtr pDrawable,
glitz_operator_t op,
glitz_color_t *color,
xglGeometryPtr pGeometry,
+ int x,
+ int y,
+ int width,
+ int height,
BoxPtr pBox,
int nBox)
{
@@ -38,6 +45,9 @@ xglSolid (DrawablePtr pDrawable,
XGL_SCREEN_PRIV (pDrawable->pScreen);
+ if (nBox < 1)
+ return TRUE;
+
if (!xglPrepareTarget (pDrawable))
return FALSE;
@@ -45,26 +55,108 @@ xglSolid (DrawablePtr pDrawable,
glitz_set_rectangle (pScreenPriv->solid, color, 0, 0, 1, 1);
+ if (pGeometry)
+ {
+ glitz_surface_set_clip_region (surface, xOff, yOff,
+ (glitz_box_t *) pBox, nBox);
+ }
+ else
+ {
+ pGeometry = xglGetScratchVertexGeometry (pDrawable->pScreen, 4 * nBox);
+ GEOMETRY_ADD_BOX (pDrawable->pScreen, pGeometry, pBox, nBox);
+ }
+
GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
- if (!GEOMETRY_ENABLE_ALL_VERTICES (pGeometry, surface))
+ if (!GEOMETRY_ENABLE (pGeometry, surface))
return FALSE;
-
- while (nBox--)
- {
- glitz_composite (op,
- pScreenPriv->solid, NULL, surface,
- 0, 0,
- 0, 0,
- pBox->x1 + xOff,
- pBox->y1 + yOff,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
- pBox++;
- }
+ glitz_composite (op,
+ pScreenPriv->solid, NULL, surface,
+ 0, 0,
+ 0, 0,
+ x + xOff,
+ y + yOff,
+ width, height);
+ glitz_surface_set_clip_region (surface, 0, 0, NULL, 0);
+
if (glitz_surface_get_status (surface))
return FALSE;
return TRUE;
}
+
+Bool
+xglSolidGlyph (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x,
+ int y,
+ unsigned int nGlyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ xglGeometryRec geometry;
+ int xBack, widthBack;
+ int yBack, heightBack;
+
+ XGL_GC_PRIV (pGC);
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ GEOMETRY_INIT (pDrawable->pScreen, &geometry,
+ GLITZ_GEOMETRY_TYPE_BITMAP,
+ GEOMETRY_USAGE_SYSMEM, 0);
+
+ GEOMETRY_FOR_GLYPH (pDrawable->pScreen,
+ &geometry,
+ nGlyph,
+ ppci,
+ pglyphBase);
+
+ GEOMETRY_TRANSLATE (&geometry, x, y);
+
+ widthBack = 0;
+ while (nGlyph--)
+ widthBack += (*ppci++)->metrics.characterWidth;
+
+ xBack = x;
+ if (widthBack < 0)
+ {
+ xBack += widthBack;
+ widthBack = -widthBack;
+ }
+ yBack = y - FONTASCENT (pGC->font);
+ heightBack = FONTASCENT (pGC->font) + FONTDESCENT (pGC->font);
+
+ if (xglSolid (pDrawable,
+ pGCPriv->op,
+ &pGCPriv->bg,
+ NULL,
+ xBack,
+ yBack,
+ widthBack,
+ heightBack,
+ REGION_RECTS (pGC->pCompositeClip),
+ REGION_NUM_RECTS (pGC->pCompositeClip)))
+ {
+ if (xglSolid (pDrawable,
+ pGCPriv->op,
+ &pGCPriv->fg,
+ &geometry,
+ xBack,
+ yBack,
+ widthBack,
+ heightBack,
+ REGION_RECTS (pGC->pCompositeClip),
+ REGION_NUM_RECTS (pGC->pCompositeClip)))
+ {
+ GEOMETRY_UNINIT (&geometry);
+ return TRUE;
+ }
+ }
+
+ GEOMETRY_UNINIT (&geometry);
+ return FALSE;
+}
diff --git a/hw/xgl/xglsync.c b/hw/xgl/xglsync.c
index 2837a86a9..15d328aeb 100644
--- a/hw/xgl/xglsync.c
+++ b/hw/xgl/xglsync.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,7 +20,7 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
@@ -152,39 +152,56 @@ xglSyncBits (DrawablePtr pDrawable,
if (!pPixmapPriv->buffer)
if (!xglAllocatePixmapBits (pPixmap))
return FALSE;
+
+ if (pPixmapPriv->pDamage)
+ {
+ RegionPtr pRegion;
+
+ pRegion = DamageRegion (pPixmapPriv->pDamage);
+ REGION_SUBTRACT (pDrawable->pScreen, &region, &region, pRegion);
+ }
- if (REGION_NOTEMPTY (pDrawable->pScreen, &region))
+ if (REGION_NOTEMPTY (pDrawable->pScreen, &region) && pPixmapPriv->surface)
{
- if (pPixmapPriv->surface)
- {
- glitz_pixel_format_t format;
- BoxPtr pBox;
- int nBox;
+ glitz_pixel_format_t format;
+ BoxPtr pBox;
+ int nBox;
+
+ if (!xglSyncSurface (pDrawable))
+ FatalError (XGL_SW_FAILURE_STRING);
- xglUnmapPixmapBits (pPixmap);
+ xglUnmapPixmapBits (pPixmap);
- pBox = REGION_RECTS (&region);
- nBox = REGION_NUM_RECTS (&region);
+ pBox = REGION_RECTS (&region);
+ nBox = REGION_NUM_RECTS (&region);
- format.masks = pPixmapPriv->pPixel->masks;
+ format.masks = pPixmapPriv->pPixel->masks;
+
+ if (pPixmapPriv->stride < 0)
+ {
+ format.bytes_per_line = -pPixmapPriv->stride;
+ format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
+ }
+ else
+ {
format.bytes_per_line = pPixmapPriv->stride;
- format.scanline_order = XGL_INTERNAL_SCANLINE_ORDER;
-
- while (nBox--)
- {
- format.xoffset = pBox->x1;
- format.skip_lines = pBox->y1;
-
- glitz_get_pixels (pPixmapPriv->surface,
- pBox->x1,
- pBox->y1,
- pBox->x2 - pBox->x1,
- pBox->y2 - pBox->y1,
- &format,
- pPixmapPriv->buffer);
-
- pBox++;
- }
+ format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+ }
+
+ while (nBox--)
+ {
+ format.xoffset = pBox->x1;
+ format.skip_lines = pBox->y1;
+
+ glitz_get_pixels (pPixmapPriv->surface,
+ pBox->x1,
+ pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ &format,
+ pPixmapPriv->buffer);
+
+ pBox++;
}
}
@@ -234,16 +251,25 @@ xglSyncSurface (DrawablePtr pDrawable)
nBox = REGION_NUM_RECTS (pRegion);
pBox = REGION_RECTS (pRegion);
+
+ format.masks = pPixmapPriv->pPixel->masks;
- format.masks = pPixmapPriv->pPixel->masks;
- format.bytes_per_line = pPixmapPriv->stride;
- format.scanline_order = XGL_INTERNAL_SCANLINE_ORDER;
+ if (pPixmapPriv->stride < 0)
+ {
+ format.bytes_per_line = -pPixmapPriv->stride;
+ format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;
+ }
+ else
+ {
+ format.bytes_per_line = pPixmapPriv->stride;
+ format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_TOP_DOWN;
+ }
while (nBox--)
{
format.xoffset = pBox->x1;
format.skip_lines = pBox->y1;
-
+
glitz_set_pixels (pPixmapPriv->surface,
pBox->x1,
pBox->y1,
@@ -288,7 +314,34 @@ xglPrepareTarget (DrawablePtr pDrawable)
}
void
-xglAddSurfaceDamage (DrawablePtr pDrawable)
+xglAddSurfaceDamage (DrawablePtr pDrawable,
+ RegionPtr pRegion)
+{
+ RegionPtr pDamageRegion;
+ glitz_surface_t *surface;
+ int xOff, yOff;
+
+ XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
+
+ pPixmapPriv->damageBox = miEmptyBox;
+ if (!pPixmapPriv->format)
+ return;
+
+ XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
+
+ if (xOff || yOff)
+ REGION_TRANSLATE (pDrawable->pScreen, pRegion, xOff, yOff);
+
+ pDamageRegion = DamageRegion (pPixmapPriv->pDamage);
+
+ REGION_UNION (pDrawable->pScreen, pDamageRegion, pDamageRegion, pRegion);
+
+ if (xOff || yOff)
+ REGION_TRANSLATE (pDrawable->pScreen, pRegion, -xOff, -yOff);
+}
+
+void
+xglAddCurrentSurfaceDamage (DrawablePtr pDrawable)
{
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
@@ -310,18 +363,12 @@ xglAddSurfaceDamage (DrawablePtr pDrawable)
pDamageRegion, pDamageRegion, &region);
REGION_UNINIT (pDrawable->pScreen, &region);
- if (pPixmapPriv->target == xglPixmapTargetIn)
- {
- if (!xglSyncSurface (pDrawable))
- FatalError (XGL_SW_FAILURE_STRING);
- }
-
pPixmapPriv->damageBox = miEmptyBox;
}
}
void
-xglAddBitDamage (DrawablePtr pDrawable)
+xglAddCurrentBitDamage (DrawablePtr pDrawable)
{
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
diff --git a/hw/xgl/xgltile.c b/hw/xgl/xgltile.c
index 60840ae66..d2a440f92 100644
--- a/hw/xgl/xgltile.c
+++ b/hw/xgl/xgltile.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,11 +20,146 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
+static glitz_geometry_format_t tileGeometryFormat = {
+ {
+ GLITZ_PRIMITIVE_QUADS,
+ GLITZ_DATA_TYPE_FLOAT,
+ sizeof (glitz_float_t) * 4,
+ GLITZ_VERTEX_ATTRIBUTE_SRC_COORD_MASK, {
+ GLITZ_DATA_TYPE_FLOAT,
+ GLITZ_COORDINATE_SIZE_XY,
+ sizeof (glitz_float_t) * 2,
+ }, {
+ 0, 0, 0
+ }
+ }
+};
+
+xglGeometryPtr
+xglTiledBoxGeometry (PixmapPtr pTile,
+ int tileX,
+ int tileY,
+ BoxPtr pBox,
+ int nBox)
+{
+ ScreenPtr pScreen = pTile->drawable.pScreen;
+ glitz_point_fixed_t p1, p2;
+ xglGeometryPtr pGeometry;
+ glitz_float_t x1, x2, y1, y2;
+ int x, y, width, height, i;
+ int xTile, yTile;
+ int widthTile, heightTile;
+ int widthTmp, xTmp, yTmp, xTileTmp;
+ int tileWidth, tileHeight;
+ int size = 0;
+ glitz_float_t *data;
+
+ XGL_PIXMAP_PRIV (pTile);
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ for (i = 0; i < nBox; i++)
+ size +=
+ (((pBox[i].x2 - pBox[i].x1) / tileWidth) + 2) *
+ (((pBox[i].y2 - pBox[i].y1) / tileHeight) + 2);
+
+ pGeometry = xglGetScratchVertexGeometryWithType (pScreen,
+ GEOMETRY_DATA_TYPE_FLOAT,
+ 8 * size);
+
+ data = glitz_buffer_map (pGeometry->buffer,
+ GLITZ_BUFFER_ACCESS_WRITE_ONLY);
+
+ while (nBox--)
+ {
+ x = pBox->x1;
+ y = pBox->y1;
+ width = pBox->x2 - pBox->x1;
+ height = pBox->y2 - pBox->y1;
+
+ xTile = MOD (tileX + x, tileWidth);
+ yTile = MOD (tileY + y, tileHeight);
+
+ yTmp = y;
+
+ while (height)
+ {
+ heightTile = MIN (tileHeight - yTile, height);
+
+ xTileTmp = xTile;
+ widthTmp = width;
+ xTmp = x;
+
+ while (widthTmp)
+ {
+ widthTile = MIN (tileWidth - xTileTmp, widthTmp);
+
+ p1.x = xTileTmp << 16;
+ p1.y = yTile << 16;
+ p2.x = (xTileTmp + widthTile) << 16;
+ p2.y = (yTile + heightTile) << 16;
+
+ glitz_surface_translate_point (pPixmapPriv->surface, &p1, &p1);
+ glitz_surface_translate_point (pPixmapPriv->surface, &p2, &p2);
+
+ x1 = FIXED_TO_FLOAT (p1.x);
+ y1 = FIXED_TO_FLOAT (p1.y);
+ x2 = FIXED_TO_FLOAT (p2.x);
+ y2 = FIXED_TO_FLOAT (p2.y);
+
+ *data++ = (glitz_float_t) xTmp;
+ *data++ = (glitz_float_t) yTmp;
+ *data++ = x1;
+ *data++ = y1;
+
+ *data++ = (glitz_float_t) (xTmp + widthTile);
+ *data++ = (glitz_float_t) yTmp;
+ *data++ = x2;
+ *data++ = y1;
+
+ *data++ = (glitz_float_t) (xTmp + widthTile);
+ *data++ = (glitz_float_t) (yTmp + heightTile);
+ *data++ = x2;
+ *data++ = y2;
+
+ *data++ = (glitz_float_t) xTmp;
+ *data++ = (glitz_float_t) (yTmp + heightTile);
+ *data++ = x1;
+ *data++ = y2;
+
+ pGeometry->endOffset += sizeof (glitz_float_t) * 16;
+
+ xTileTmp = 0;
+ xTmp += widthTile;
+ widthTmp -= widthTile;
+ }
+
+ yTile = 0;
+ yTmp += heightTile;
+ height -= heightTile;
+ }
+
+ pBox++;
+ }
+
+ if (glitz_buffer_unmap (pGeometry->buffer))
+ return NULL;
+
+ pGeometry->f = tileGeometryFormat;
+ pGeometry->count =
+ pGeometry->endOffset / tileGeometryFormat.vertex.bytes_per_vertex;
+
+ pPixmapPriv->pictureMask |= xglPCFillMask;
+ glitz_surface_set_fill (pPixmapPriv->surface, GLITZ_FILL_TRANSPARENT);
+
+ return pGeometry;
+}
Bool
xglTile (DrawablePtr pDrawable,
@@ -33,6 +168,10 @@ xglTile (DrawablePtr pDrawable,
int tileX,
int tileY,
xglGeometryPtr pGeometry,
+ int x,
+ int y,
+ int width,
+ int height,
BoxPtr pBox,
int nBox)
{
@@ -40,161 +179,90 @@ xglTile (DrawablePtr pDrawable,
glitz_surface_t *surface;
int xOff, yOff;
- if (!xglSyncSurface (&pTile->drawable))
- return FALSE;
+ if (nBox < 1)
+ return TRUE;
if (!xglPrepareTarget (pDrawable))
return FALSE;
-
- XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
- GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
-
- if (!GEOMETRY_ENABLE_ALL_VERTICES (pGeometry, surface))
+ if (!xglSyncSurface (&pTile->drawable))
return FALSE;
+ XGL_GET_DRAWABLE (pDrawable, surface, xOff, yOff);
+
pTilePriv = XGL_GET_PIXMAP_PRIV (pTile);
- pTilePriv->pictureMask |=
- xglPCFillMask | xglPCFilterMask | xglPCTransformMask;
-
- glitz_surface_set_filter (pTilePriv->surface, GLITZ_FILTER_NEAREST,
+ pTilePriv->pictureMask |= xglPCFilterMask | xglPCTransformMask;
+ glitz_surface_set_filter (pTilePriv->surface,
+ GLITZ_FILTER_NEAREST,
NULL, 0);
glitz_surface_set_transform (pTilePriv->surface, NULL);
if (pTilePriv->acceleratedTile)
{
- glitz_surface_set_fill (pTilePriv->surface, GLITZ_FILL_REPEAT);
-
- while (nBox--)
+ if (pGeometry)
{
- glitz_composite (op,
- pTilePriv->surface, NULL, surface,
- pBox->x1 + tileX,
- pBox->y1 + tileY,
- 0, 0,
- pBox->x1 + xOff,
- pBox->y1 + yOff,
- pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
-
- pBox++;
+ glitz_surface_set_clip_region (surface, xOff, yOff,
+ (glitz_box_t *) pBox, nBox);
+ nBox = 0;
+ }
+ else
+ {
+ pGeometry = xglGetScratchVertexGeometry (pDrawable->pScreen,
+ 4 * nBox);
+ GEOMETRY_ADD_BOX (pDrawable->pScreen, pGeometry, pBox, nBox);
}
- if (!glitz_surface_get_status (surface))
- return TRUE;
- }
+ GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
- glitz_surface_set_fill (pTilePriv->surface, GLITZ_FILL_TRANSPARENT);
+ if (!GEOMETRY_ENABLE (pGeometry, surface))
+ return FALSE;
- /*
- * Don't allow software tile with really small pixmaps.
- */
- if (pTile->drawable.width < 8 && pTile->drawable.height < 8)
- return FALSE;
-
- xglSwTile (op,
- pTilePriv->surface, NULL, surface,
- tileX - xOff, tileY - yOff,
- 0, 0,
- TILE_SOURCE,
- pBox, nBox,
- xOff, yOff);
+ pTilePriv->pictureMask |= xglPCFillMask;
+ glitz_surface_set_fill (pTilePriv->surface, GLITZ_FILL_REPEAT);
- if (glitz_surface_get_status (surface))
- return FALSE;
+ glitz_composite (op,
+ pTilePriv->surface, NULL, surface,
+ x + tileX,
+ y + tileY,
+ 0, 0,
+ x + xOff,
+ y + yOff,
+ width, height);
- return TRUE;
-}
+ glitz_surface_set_clip_region (surface, 0, 0, NULL, 0);
+
+ if (!glitz_surface_get_status (surface))
+ 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);
+ if (!nBox)
+ return FALSE;
}
-
- while (nBox--)
+ else
{
- 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 (pGeometry)
+ return FALSE;
+ }
- 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;
-
- }
+ pGeometry = xglTiledBoxGeometry (pTile, tileX, tileY, pBox, nBox);
+ if (!pGeometry)
+ return FALSE;
- yTile = 0;
- yTmp += heightTile;
- height -= heightTile;
- }
-
- pBox++;
- }
+ GEOMETRY_TRANSLATE (pGeometry, xOff, yOff);
+
+ if (!GEOMETRY_ENABLE (pGeometry, surface))
+ return FALSE;
+
+ glitz_composite (op,
+ pTilePriv->surface, NULL, surface,
+ 0, 0,
+ 0, 0,
+ x + xOff,
+ y + yOff,
+ width, height);
+
+ if (glitz_surface_get_status (surface))
+ return FALSE;
+
+ return TRUE;
}
diff --git a/hw/xgl/xgltrap.c b/hw/xgl/xgltrap.c
new file mode 100644
index 000000000..723a43225
--- /dev/null
+++ b/hw/xgl/xgltrap.c
@@ -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
diff --git a/hw/xgl/xglwindow.c b/hw/xgl/xglwindow.c
index 361a204f5..2a4bb9ae1 100644
--- a/hw/xgl/xglwindow.c
+++ b/hw/xgl/xglwindow.c
@@ -5,7 +5,7 @@
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
- * appear in supporting documentation, and that the names of
+ * appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
@@ -20,19 +20,20 @@
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
- * Author: David Reveman <davidr@freedesktop.org>
+ * Author: David Reveman <davidr@novell.com>
*/
#include "xgl.h"
#include "fb.h"
-#define XGL_WINDOW_FALLBACK_PROLOGUE(pWin, func) \
- xglSyncDamageBoxBits (&pWin->drawable); \
+#define XGL_WINDOW_FALLBACK_PROLOGUE(pWin, func) \
+ if (!xglMapPixmapBits (XGL_GET_DRAWABLE_PIXMAP (&pWin->drawable))) \
+ FatalError (XGL_SW_FAILURE_STRING); \
XGL_SCREEN_UNWRAP (func)
-#define XGL_WINDOW_FALLBACK_EPILOGUE(pWin, func, xglfunc) \
- XGL_SCREEN_WRAP (func, xglfunc); \
- xglAddSurfaceDamage (&pWin->drawable)
+#define XGL_WINDOW_FALLBACK_EPILOGUE(pWin, pRegion, func, xglfunc) \
+ XGL_SCREEN_WRAP (func, xglfunc); \
+ xglAddSurfaceDamage (&pWin->drawable, pRegion)
Bool
xglCreateWindow (WindowPtr pWin)
@@ -52,96 +53,119 @@ xglCreateWindow (WindowPtr pWin)
return ret;
}
-void
-xglCopyWindow (WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc)
+Bool
+xglChangeWindowAttributes (WindowPtr pWin,
+ unsigned long mask)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
-
+ PixmapPtr pPixmap;
+ Bool ret;
+
XGL_SCREEN_PRIV (pScreen);
-
- if (XGL_GET_DRAWABLE_PIXMAP_PRIV (&pWin->drawable)->target)
+
+ if (mask & CWBackPixmap)
{
- PixmapPtr pPixmap;
- RegionRec rgnDst;
- int dx, dy;
- Bool ret;
+ if (pWin->backgroundState == BackgroundPixmap)
+ {
+ pPixmap = pWin->background.pixmap;
- pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
+ if (FbEvenTile (pPixmap->drawable.width *
+ pPixmap->drawable.bitsPerPixel))
+ xglSyncBits (&pPixmap->drawable, NULL);
+ }
+ }
- REGION_TRANSLATE (pScreen, prgnSrc, -dx, -dy);
- REGION_INIT (pScreen, &rgnDst, NullBox, 0);
- REGION_INTERSECT (pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
-
-#ifdef COMPOSITE
- if (pPixmap->screen_x || pPixmap->screen_y)
- REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
- -pPixmap->screen_x, -pPixmap->screen_y);
-#endif
-
- ret = TRUE;
- fbCopyRegion (&pWin->drawable, &pWin->drawable,
- 0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &ret);
-
- REGION_UNINIT (pScreen, &rgnDst);
-
- if (ret)
+ if (mask & CWBorderPixmap)
+ {
+ if (pWin->borderIsPixel == FALSE)
{
- xglAddBitDamage (&pWin->drawable);
- return;
+ pPixmap = pWin->border.pixmap;
+
+ if (FbEvenTile (pPixmap->drawable.width *
+ pPixmap->drawable.bitsPerPixel))
+ xglSyncBits (&pPixmap->drawable, NULL);
}
+ }
-#ifdef COMPOSITE
- if (pPixmap->screen_x || pPixmap->screen_y)
- REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
- pPixmap->screen_x, pPixmap->screen_y);
-#endif
+ XGL_SCREEN_UNWRAP (ChangeWindowAttributes);
+ ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+ XGL_SCREEN_WRAP (ChangeWindowAttributes, xglChangeWindowAttributes);
+
+ return ret;
+}
+
+void
+xglCopyWindow (WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ PixmapPtr pPixmap;
+ RegionRec rgnDst;
+ int dx, dy;
+ BoxPtr pExtent = REGION_EXTENTS (pWin->drawable.pScreen, prgnSrc);
+ BoxRec box;
+
+ pPixmap = XGL_GET_WINDOW_PIXMAP (pWin);
+
+ box.x1 = pWin->drawable.x + pExtent->x1;
+ box.y1 = pWin->drawable.y + pExtent->y1;
+ box.x2 = pWin->drawable.x + pExtent->x2;
+ box.y2 = pWin->drawable.y + pExtent->y2;
- REGION_TRANSLATE (pScreen, prgnSrc, dx, dy);
- }
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+
+ REGION_TRANSLATE (pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+ REGION_INTERSECT (pWin->drawable.pScreen,
+ &rgnDst, &pWin->borderClip, prgnSrc);
- if (!xglSyncBits (&pWin->drawable, NullBox))
- FatalError (XGL_SW_FAILURE_STRING);
+#ifdef COMPOSITE
+ if (pPixmap->screen_x || pPixmap->screen_y)
+ {
+ REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
+ -pPixmap->screen_x, -pPixmap->screen_y);
- XGL_WINDOW_FALLBACK_PROLOGUE (pWin, CopyWindow);
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- XGL_WINDOW_FALLBACK_EPILOGUE (pWin, CopyWindow, xglCopyWindow);
+ box.x1 -= pPixmap->screen_x;
+ box.y1 -= pPixmap->screen_y;
+ box.x2 -= pPixmap->screen_x;
+ box.y2 -= pPixmap->screen_y;
+ }
+#endif
+
+ fbCopyRegion (&pWin->drawable, &pWin->drawable,
+ 0, &rgnDst, dx, dy, xglCopyProc, 0, (void *) &box);
+
+ REGION_UNINIT (pWin->drawable.pScreen, &rgnDst);
}
static Bool
-xglFillRegionSolid (DrawablePtr pDrawable,
- RegionPtr pRegion,
- Pixel pixel)
+xglFillRegionSolid (DrawablePtr pDrawable,
+ RegionPtr pRegion,
+ Pixel pixel)
{
- ScreenPtr pScreen = pDrawable->pScreen;
- xglGeometryRec geometry;
- glitz_color_t color;
+ glitz_color_t color;
+ BoxPtr pExtent;
XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
if (!pPixmapPriv->target)
return FALSE;
- xglPixelToColor (pPixmapPriv->pPixel, pixel, &color);
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
- GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (pRegion) << 3);
- GEOMETRY_ADD_REGION (pScreen, &geometry, pRegion);
+ xglPixelToColor (pPixmapPriv->pPixel, pixel, &color);
if (xglSolid (pDrawable,
GLITZ_OPERATOR_SRC,
&color,
- &geometry,
- REGION_EXTENTS (pScreen, pRegion), 1))
- {
- GEOMETRY_UNINIT (&geometry);
+ NULL,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ REGION_RECTS (pRegion),
+ REGION_NUM_RECTS (pRegion)))
return TRUE;
- }
- GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@@ -152,27 +176,26 @@ xglFillRegionTiled (DrawablePtr pDrawable,
int tileX,
int tileY)
{
- ScreenPtr pScreen = pDrawable->pScreen;
- xglGeometryRec geometry;
+ BoxPtr pExtent;
+
+ XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);
- if (!XGL_GET_DRAWABLE_PIXMAP_PRIV (pDrawable)->target)
+ if (!pPixmapPriv->target)
return FALSE;
- GEOMETRY_INIT (pScreen, &geometry, REGION_NUM_RECTS (pRegion) << 3);
- GEOMETRY_ADD_REGION (pScreen, &geometry, pRegion);
+ pExtent = REGION_EXTENTS (pDrawable->pScreen, pRegion);
if (xglTile (pDrawable,
GLITZ_OPERATOR_SRC,
pTile,
tileX, tileY,
- &geometry,
- REGION_EXTENTS (pScreen, pRegion), 1))
- {
- GEOMETRY_UNINIT (&geometry);
+ NULL,
+ pExtent->x1, pExtent->y1,
+ pExtent->x2 - pExtent->x1, pExtent->y2 - pExtent->y1,
+ REGION_RECTS (pRegion),
+ REGION_NUM_RECTS (pRegion)))
return TRUE;
- }
- GEOMETRY_UNINIT (&geometry);
return FALSE;
}
@@ -202,7 +225,7 @@ xglPaintWindowBackground (WindowPtr pWin,
-pWin->drawable.x,
-pWin->drawable.y))
{
- xglAddBitDamage (&pWin->drawable);
+ xglAddCurrentBitDamage (&pWin->drawable);
return;
}
@@ -214,7 +237,7 @@ xglPaintWindowBackground (WindowPtr pWin,
pRegion,
pWin->background.pixel))
{
- xglAddBitDamage (&pWin->drawable);
+ xglAddCurrentBitDamage (&pWin->drawable);
return;
}
break;
@@ -222,7 +245,7 @@ xglPaintWindowBackground (WindowPtr pWin,
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBackground);
(*pScreen->PaintWindowBackground) (pWin, pRegion, what);
- XGL_WINDOW_FALLBACK_EPILOGUE (pWin, PaintWindowBackground,
+ XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBackground,
xglPaintWindowBackground);
}
@@ -241,7 +264,7 @@ xglPaintWindowBorder (WindowPtr pWin,
pRegion,
pWin->border.pixel))
{
- xglAddBitDamage (&pWin->drawable);
+ xglAddCurrentBitDamage (&pWin->drawable);
return;
}
}
@@ -258,7 +281,7 @@ xglPaintWindowBorder (WindowPtr pWin,
-pBgWin->drawable.x,
-pBgWin->drawable.y))
{
- xglAddBitDamage (&pWin->drawable);
+ xglAddCurrentBitDamage (&pWin->drawable);
return;
}
@@ -268,6 +291,6 @@ xglPaintWindowBorder (WindowPtr pWin,
XGL_WINDOW_FALLBACK_PROLOGUE (pWin, PaintWindowBorder);
(*pScreen->PaintWindowBorder) (pWin, pRegion, what);
- XGL_WINDOW_FALLBACK_EPILOGUE (pWin, PaintWindowBorder,
+ XGL_WINDOW_FALLBACK_EPILOGUE (pWin, pRegion, PaintWindowBorder,
xglPaintWindowBorder);
}