summaryrefslogtreecommitdiff
path: root/hw/xfree86/xaa
diff options
context:
space:
mode:
authorKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
committerKaleb Keithley <kaleb@freedesktop.org>2003-11-14 16:48:57 +0000
commit9508a382f8a9f241dab097d921b6d290c1c3a776 (patch)
treefa456480bae7040c3f971a70b390f2d091c680b5 /hw/xfree86/xaa
parentded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff)
Initial revision
Diffstat (limited to 'hw/xfree86/xaa')
-rw-r--r--hw/xfree86/xaa/XAA.HOWTO1427
-rw-r--r--hw/xfree86/xaa/xaa.h1362
-rw-r--r--hw/xfree86/xaa/xaaBitBlt.c219
-rw-r--r--hw/xfree86/xaa/xaaBitOrder.c13
-rw-r--r--hw/xfree86/xaa/xaaBitmap.c475
-rw-r--r--hw/xfree86/xaa/xaaCpyArea.c385
-rw-r--r--hw/xfree86/xaa/xaaCpyPlane.c206
-rw-r--r--hw/xfree86/xaa/xaaCpyWin.c80
-rw-r--r--hw/xfree86/xaa/xaaDashLine.c329
-rw-r--r--hw/xfree86/xaa/xaaFallback.c352
-rw-r--r--hw/xfree86/xaa/xaaFillArc.c213
-rw-r--r--hw/xfree86/xaa/xaaFillPoly.c956
-rw-r--r--hw/xfree86/xaa/xaaFillRect.c1093
-rw-r--r--hw/xfree86/xaa/xaaGC.c653
-rw-r--r--hw/xfree86/xaa/xaaGCmisc.c426
-rw-r--r--hw/xfree86/xaa/xaaImage.c520
-rw-r--r--hw/xfree86/xaa/xaaInit.c762
-rw-r--r--hw/xfree86/xaa/xaaInitAccel.c1513
-rw-r--r--hw/xfree86/xaa/xaaLine.c390
-rw-r--r--hw/xfree86/xaa/xaaLineMisc.c148
-rw-r--r--hw/xfree86/xaa/xaaNonTEGlyph.c198
-rw-r--r--hw/xfree86/xaa/xaaNonTEText.c588
-rw-r--r--hw/xfree86/xaa/xaaOffscreen.c160
-rw-r--r--hw/xfree86/xaa/xaaOverlay.c306
-rw-r--r--hw/xfree86/xaa/xaaOverlayDF.c1154
-rw-r--r--hw/xfree86/xaa/xaaPCache.c2366
-rw-r--r--hw/xfree86/xaa/xaaPaintWin.c198
-rw-r--r--hw/xfree86/xaa/xaaPict.c683
-rw-r--r--hw/xfree86/xaa/xaaROP.c164
-rw-r--r--hw/xfree86/xaa/xaaRect.c134
-rw-r--r--hw/xfree86/xaa/xaaSpans.c880
-rw-r--r--hw/xfree86/xaa/xaaStateChange.c1677
-rw-r--r--hw/xfree86/xaa/xaaStipple.c843
-rw-r--r--hw/xfree86/xaa/xaaTEGlyph.c1072
-rw-r--r--hw/xfree86/xaa/xaaTEGlyphBlt.S964
-rw-r--r--hw/xfree86/xaa/xaaTEText.c293
-rw-r--r--hw/xfree86/xaa/xaaTables.c88
-rw-r--r--hw/xfree86/xaa/xaaWideLine.c941
-rw-r--r--hw/xfree86/xaa/xaacexp.h124
-rw-r--r--hw/xfree86/xaa/xaalocal.h1756
-rw-r--r--hw/xfree86/xaa/xaarop.h307
-rw-r--r--hw/xfree86/xaa/xaawrap.h78
42 files changed, 26496 insertions, 0 deletions
diff --git a/hw/xfree86/xaa/XAA.HOWTO b/hw/xfree86/xaa/XAA.HOWTO
new file mode 100644
index 000000000..95d9d6100
--- /dev/null
+++ b/hw/xfree86/xaa/XAA.HOWTO
@@ -0,0 +1,1427 @@
+
+
+ XAA.HOWTO
+
+ This file describes how to add basic XAA support to a chipset driver.
+
+0) What is XAA
+1) XAA Initialization and Shutdown
+2) The Primitives
+ 2.0 Generic Flags
+ 2.1 Screen to Screen Copies
+ 2.2 Solid Fills
+ 2.3 Solid Lines
+ 2.4 Dashed Lines
+ 2.5 Color Expand Fills
+ 2.5.1 Screen to Screen Color Expansion
+ 2.5.2 CPU to Screen Color Expansion
+ 2.5.2.1 The Direct Method
+ 2.5.2.2 The Indirect Method
+ 2.6 8x8 Mono Pattern Fills
+ 2.7 8x8 Color Pattern Fills
+ 2.8 Image Writes
+ 2.8.1 The Direct Method
+ 2.8.2 The Indirect Method
+ 2.9 Clipping
+3) The Pixmap Cache
+4) Offscreen Pixmaps
+
+/********************************************************************/
+
+0) WHAT IS XAA
+
+ XAA (the XFree86 Acceleration Architecture) is a device dependent
+layer that encapsulates the unaccelerated framebuffer rendering layer,
+intercepting rendering commands sent to it from higher levels of the
+server. For rendering tasks where hardware acceleration is not
+possible, XAA allows the requests to proceed to the software rendering
+code. Otherwise, XAA breaks the sometimes complicated X primitives
+into simpler primitives more suitable for hardware acceleration and
+will use accelerated functions exported by the chipset driver to
+render these.
+
+ XAA provides a simple, easy to use driver interface that allows
+the driver to communicate its acceleration capabilities and restrictions
+back to XAA. XAA will use the information provided by the driver
+to determine whether or not acceleration will be possible for a
+particular X primitive.
+
+
+
+1) XAA INITIALIZATION AND SHUTDOWN
+
+ All relevant prototypes and defines are in xaa.h.
+
+ To Initialize the XAA layer, the driver should allocate an XAAInfoRec
+via XAACreateInfoRec(), fill it out as described in this document
+and pass it to XAAInit(). XAAInit() must be called _after_ the
+framebuffer initialization (usually cfb?ScreenInit or similar) since
+it is "wrapping" that layer. XAAInit() should be called _before_ the
+cursor initialization (usually miDCInitialize) since the cursor
+layer needs to "wrap" all the rendering code including XAA.
+
+ When shutting down, the driver should free the XAAInfoRec
+structure in its CloseScreen function via XAADestroyInfoRec().
+The prototypes for the functions mentioned above are as follows:
+
+ XAAInfoRecPtr XAACreateInfoRec(void);
+ Bool XAAInit(ScreenPtr, XAAInfoRecPtr);
+ void XAADestroyInfoRec(XAAInfoRec);
+
+ The driver informs XAA of it's acceleration capablities by
+filling out an XAAInfoRec structure and passing it to XAAInit().
+The XAAInfoRec structure contains many fields, most of which are
+function pointers and flags. Each primitive will typically have
+two functions and a set of flags associated with it, but it may
+have more. These two functions are the "SetupFor" and "Subsequent"
+functions. The "SetupFor" function tells the driver that the
+hardware should be initialized for a particular type of graphics
+operation. After the "SetupFor" function, one or more calls to the
+"Subsequent" function will be made to indicate that an instance
+of the particular primitive should be rendered by the hardware.
+The details of each instance (width, height, etc...) are given
+with each "Subsequent" function. The set of flags associated
+with each primitive lets the driver tell XAA what its hardware
+limitations are (eg. It doesn't support a planemask, it can only
+do one of the raster-ops, etc...).
+
+ Of the XAAInfoRec fields, one is required. This is the
+Sync function. XAA initialization will fail if this function
+is not provided.
+
+void Sync(ScrnInfoPtr pScrn) /* Required */
+
+ Sync will be called when XAA needs to be certain that all
+ graphics coprocessor operations are finished, such as when
+ the framebuffer must be written to or read from directly
+ and it must be certain that the accelerator will not be
+ overwriting the area of interest.
+
+ One needs to make certain that the Sync function not only
+ waits for the accelerator fifo to empty, but that it waits for
+ the rendering of that last operation to complete.
+
+ It is guaranteed that no direct framebuffer access will
+ occur after a "SetupFor" or "Subsequent" function without
+ the Sync function being called first.
+
+
+
+2) THE PRIMITIVES
+
+2.0 Generic Flags
+
+ Each primitive type has a set of flags associated with it which
+allow the driver to tell XAA what the hardware limitations are.
+The common ones are as follows:
+
+/* Foreground, Background, rop and planemask restrictions */
+
+ GXCOPY_ONLY
+
+ This indicates that the accelerator only supports GXcopy
+ for the particular primitive.
+
+ ROP_NEEDS_SOURCE
+
+ This indicates that the accelerator doesn't supports a
+ particular primitive with rops that don't involve the source.
+ These rops are GXclear, GXnoop, GXinvert and GXset. If neither
+ this flag nor GXCOPY_ONLY is defined, it is assumed that the
+ accelerator supports all 16 raster operations (rops) for that
+ primitive.
+
+ NO_PLANEMASK
+
+ This indicates that the accelerator does not support a hardware
+ write planemask for the particular primitive.
+
+ RGB_EQUAL
+
+ This indicates that the particular primitive requires the red,
+ green and blue bytes of the foreground color (and background color,
+ if applicable) to be equal. This is useful for 24bpp when a graphics
+ coprocessor is used in 8bpp mode, which is not uncommon in older
+ hardware since some have no support for or only limited support for
+ acceleration at 24bpp. This way, many operations will be accelerated
+ for the common case of "grayscale" colors. This flag should only
+ be used in 24bpp.
+
+ In addition to the common ones listed above which are possible for
+nearly all primitives, each primitive may have its own flags specific
+to that primitive. If such flags exist they are documented in the
+descriptions of those primitives below.
+
+
+
+
+2.1 Screen to Screen Copies
+
+ The SetupFor and Subsequent ScreenToScreenCopy functions provide
+ an interface for copying rectangular areas from video memory to
+ video memory. To accelerate this primitive the driver should
+ provide both the SetupFor and Subsequent functions and indicate
+ the hardware restrictions via the ScreenToScreenCopyFlags. The
+ NO_PLANEMASK, GXCOPY_ONLY and ROP_NEEDS_SOURCE flags as described
+ in Section 2.0 are valid as well as the following:
+
+ NO_TRANSPARENCY
+
+ This indicates that the accelerator does not support skipping
+ of color keyed pixels when copying from the source to the destination.
+
+ TRANSPARENCY_GXCOPY_ONLY
+
+ This indicates that the accelerator supports skipping of color keyed
+ pixels only when the rop is GXcopy.
+
+ ONLY_LEFT_TO_RIGHT_BITBLT
+
+ This indicates that the hardware only accepts blitting when the
+ x direction is positive.
+
+ ONLY_TWO_BITBLT_DIRECTIONS
+
+ This indicates that the hardware can only cope with blitting when
+ the direction of x is the same as the direction in y.
+
+
+void SetupForScreenToScreenCopy( ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color )
+
+ When this is called, SubsequentScreenToScreenCopy will be called
+ one or more times directly after. If ydir is 1, then the accelerator
+ should copy starting from the top (minimum y) of the source and
+ proceed downward. If ydir is -1, then the accelerator should copy
+ starting from the bottom of the source (maximum y) and proceed
+ upward. If xdir is 1, then the accelerator should copy each
+ y scanline starting from the leftmost pixel of the source. If
+ xdir is -1, it should start from the rightmost pixel.
+ If trans_color is not -1 then trans_color indicates that the
+ accelerator should not copy pixels with the color trans_color
+ from the source to the destination, but should skip them.
+ Trans_color is always -1 if the NO_TRANSPARENCY flag is set.
+
+
+void SubsequentScreenToScreenCopy(ScrnInfoPtr pScrn,
+ int x1, int y1,
+ int x2, int y2,
+ int width, int height)
+
+ Copy a rectangle "width" x "height" from the source (x1,y1) to the
+ destination (x2,y2) using the parameters passed by the last
+ SetupForScreenToScreenCopy call. (x1,y1) and (x2,y2) always denote
+ the upper left hand corners of the source and destination regardless
+ of which xdir and ydir values are given by SetupForScreenToScreenCopy.
+
+
+
+2.2 Solid Fills
+
+ The SetupFor and Subsequent SolidFill(Rect/Trap) functions provide
+ an interface for filling rectangular areas of the screen with a
+ foreground color. To accelerate this primitive the driver should
+ provide both the SetupForSolidFill and SubsequentSolidFillRect
+ functions and indicate the hardware restrictions via the SolidFillFlags.
+ The driver may optionally provide a SubsequentSolidFillTrap if
+ it is capable of rendering the primitive correctly.
+ The GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags
+ as described in Section 2.0 are valid.
+
+
+void SetupForSolidFill(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+
+ SetupForSolidFill indicates that any combination of the following
+ may follow it.
+
+ SubsequentSolidFillRect
+ SubsequentSolidFillTrap
+
+
+
+void SubsequentSolidFillRect(ScrnInfoPtr pScrn, int x, int y, int w, int h)
+
+ Fill a rectangle of dimensions "w" by "h" with origin at (x,y)
+ using the color, rop and planemask given by the last
+ SetupForSolidFill call.
+
+void SubsequentSolidFillTrap(ScrnInfoPtr pScrn, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR)
+
+ These parameters describe a trapezoid via a version of
+ Bresenham's parameters. "y" is the top line. "h" is the
+ number of spans to be filled in the positive Y direction.
+ "left" and "right" indicate the starting X values of the
+ left and right edges. dy/dx describes the edge slope.
+ These are not the deltas between the beginning and ending
+ points on an edge. They merely describe the slope. "e" is
+ the initial error term. It's the relationships between dx,
+ dy and e that define the edge.
+ If your engine does not do bresenham trapezoids or does
+ not allow the programmer to specify the error term then
+ you are not expected to be able to accelerate them.
+
+
+2.3 Solid Lines
+
+ XAA provides an interface for drawing thin lines. In order to
+ draw X lines correctly a high degree of accuracy is required.
+ This usually limits line acceleration to hardware which has a
+ Bresenham line engine, though depending on the algorithm used,
+ other line engines may come close if they accept 16 bit line
+ deltas. XAA has both a Bresenham line interface and a two-point
+ line interface for drawing lines of arbitrary orientation.
+ Additionally there is a SubsequentSolidHorVertLine which will
+ be used for all horizontal and vertical lines. Horizontal and
+ vertical lines are handled separately since hardware that doesn't
+ have a line engine (or has one that is unusable due to precision
+ problems) can usually draw these lines by some other method such
+ as drawing them as thin rectangles. Even for hardware that can
+ draw arbitrary lines via the Bresenham or two-point interfaces,
+ the SubsequentSolidHorVertLine is used for horizontal and vertical
+ lines since most hardware is able to render the horizontal lines
+ and sometimes the vertical lines faster by other methods (Hint:
+ try rendering horizontal lines as flattened rectangles). If you have
+ not provided a SubsequentSolidHorVertLine but you have provided
+ Bresenham or two-point lines, a SubsequentSolidHorVertLine function
+ will be supplied for you.
+
+ The flags field associated with Solid Lines is SolidLineFlags and
+ the GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags as
+ described in Section 2.0 are valid restrictions.
+
+ Some line engines have line biases hardcoded to comply with
+ Microsoft line biasing rules. A tell-tale sign of this is the
+ hardware lines not matching the software lines in the zeroth and
+ fourth octants. The driver can set the flag:
+
+ MICROSOFT_ZERO_LINE_BIAS
+
+ in the AccelInfoRec.Flags field to adjust the software lines to
+ match the hardware lines. This is in the generic flags field
+ rather than the SolidLineFlags since this flag applies to all
+ software zero-width lines on the screen and not just the solid ones.
+
+
+void SetupForSolidLine(ScrnInfoPtr pScrn,
+ int color, int rop, unsigned int planemask)
+
+ SetupForSolidLine indicates that any combination of the following
+ may follow it.
+
+ SubsequentSolidBresenhamLine
+ SubsequentSolidTwoPointLine
+ SubsequentSolidHorVertLine
+
+
+void SubsequentSolidHorVertLine( ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir )
+
+ All vertical and horizontal solid thin lines are rendered with
+ this function. The line starts at coordinate (x,y) and extends
+ "len" pixels inclusive. In the direction indicated by "dir."
+ The direction is either DEGREES_O or DEGREES_270. That is, it
+ always extends to the right or down.
+
+
+
+void SubsequentSolidTwoPointLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags)
+
+ Draw a line from (x1,y1) to (x2,y2). If the flags field contains
+ the flag OMIT_LAST, the last pixel should not be drawn. Otherwise,
+ the pixel at (x2,y2) should be drawn.
+
+ If you use the TwoPoint line interface there is a good possibility
+ that your line engine has hard-coded line biases that do not match
+ the default X zero-width lines. If so, you may need to set the
+ MICROSOFT_ZERO_LINE_BIAS flag described above. Note that since
+ any vertex in the 16-bit signed coordinate system is valid, your
+ line engine is expected to handle 16-bit values if you have hardware
+ line clipping enabled. If your engine cannot handle 16-bit values,
+ you should not use hardware line clipping.
+
+
+void SubsequentSolidBresenhamLine(ScrnInfoPtr pScrn,
+ int x, int y, int major, int minor, int err, int len, int octant)
+
+ "X" and "y" are the starting point of the line. "Major" and "minor"
+ are the major and minor step constants. "Err" is the initial error
+ term. "Len" is the number of pixels to be drawn (inclusive). "Octant"
+ can be any combination of the following flags OR'd together:
+
+ Y_MAJOR Y is the major axis (X otherwise)
+ X_DECREASING The line is drawn from right to left
+ Y_DECREASING The line is drawn from bottom to top
+
+ The major, minor and err terms are the "raw" Bresenham parameters
+ consistent with a line engine that does:
+
+ e = err;
+ while(len--) {
+ DRAW_POINT(x,y);
+ e += minor;
+ if(e >= 0) {
+ e -= major;
+ TAKE_ONE_STEP_ALONG_MINOR_AXIS;
+ }
+ TAKE_ONE_STEP_ALONG_MAJOR_AXIS;
+ }
+
+ IBM 8514 style Bresenham line interfaces require their parameters
+ modified in the following way:
+
+ Axial = minor;
+ Diagonal = minor - major;
+ Error = minor + err;
+
+SolidBresenhamLineErrorTermBits
+
+ This field allows the driver to tell XAA how many bits large its
+ Bresenham parameter registers are. Many engines have registers that
+ only accept 12 or 13 bit Bresenham parameters, and the parameters
+ for clipped lines may overflow these if they are not scaled down.
+ If this field is not set, XAA will assume the engine can accomodate
+ 16 bit parameters, otherwise, it will scale the parameters to the
+ size specified.
+
+
+2.4 Dashed Lines
+
+ The same degree of accuracy required by the solid lines is required
+ for drawing dashed lines as well. The dash pattern itself is a
+ buffer of binary data where ones are expanded into the foreground
+ color and zeros either correspond to the background color or
+ indicate transparency depending on whether or not DoubleDash or
+ OnOffDashes are being drawn.
+
+ The flags field associated with dashed Lines is DashedLineFlags and
+ the GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags as
+ described in Section 2.0 are valid restrictions. Additionally, the
+ following flags are valid:
+
+ NO_TRANSPARENCY
+
+ This indicates that the driver cannot support dashed lines
+ with transparent backgrounds (OnOffDashes).
+
+ TRANSPARENCY_ONLY
+
+ This indicates that the driver cannot support dashes with
+ both a foreground and background color (DoubleDashes).
+
+ LINE_PATTERN_POWER_OF_2_ONLY
+
+ This indicates that only patterns with a power of 2 length
+ can be accelerated.
+
+ LINE_PATTERN_LSBFIRST_MSBJUSTIFIED
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED
+ LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
+ LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
+
+ These describe how the line pattern should be packed.
+ The pattern buffer is DWORD padded. LSBFIRST indicates
+ that the pattern runs from the LSB end to the MSB end.
+ MSBFIRST indicates that the pattern runs from the MSB end
+ to the LSB end. When the pattern does not completely fill
+ the DWORD padded buffer, the pattern will be justified
+ towards the MSB or LSB end based on the flags above.
+
+
+ The following field indicates the maximum length dash pattern that
+ should be accelerated.
+
+ int DashPatternMaxLength
+
+
+void SetupForDashedLine(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop, unsigned int planemask,
+ int length, unsigned char *pattern)
+
+
+ SetupForDashedLine indicates that any combination of the following
+ may follow it.
+
+ SubsequentDashedBresenhamLine
+ SubsequentDashedTwoPointLine
+
+ If "bg" is -1, then the background (pixels corresponding to clear
+ bits in the pattern) should remain unmodified. "Bg" indicates the
+ background color otherwise. "Length" indicates the length of
+ the pattern in bits and "pattern" points to the DWORD padded buffer
+ holding the pattern which has been packed according to the flags
+ set above.
+
+
+void SubsequentDashedTwoPointLine( ScrnInfoPtr pScrn,
+ int x1, int y1, int x2, int y2, int flags, int phase)
+
+void SubsequentDashedBresenhamLine(ScrnInfoPtr pScrn,
+ int x1, int y1, int major, int minor, int err, int len, int octant,
+ int phase)
+
+ These are the same as the SubsequentSolidTwoPointLine and
+ SubsequentBresenhamLine functions except for the addition
+ of the "phase" field which indicates the offset into the dash
+ pattern that the pixel at (x1,y1) corresponds to.
+
+ As with the SubsequentBresenhamLine, there is an
+
+ int DashedBresenhamLineErrorTermBits
+
+ field which indicates the size of the error term registers
+ used with dashed lines. This is usually the same value as
+ the field for the solid lines (because it's usually the same
+ register).
+
+
+
+2.5 Color Expansion Fills
+
+ When filling a color expansion rectangle, the accelerator
+ paints each pixel depending on whether or not a bit in a
+ corresponding bitmap is set or clear. Opaque expansions are
+ when a set bit corresponds to the foreground color and a clear
+ bit corresponds to the background color. A transparent expansion
+ is when a set bit corresponds to the foreground color and a
+ clear bit indicates that the pixel should remain unmodified.
+
+ The graphics accelerator usually has access to the source
+ bitmap in one of two ways: 1) the bitmap data is sent serially
+ to the accelerator by the CPU through some memory mapped aperture
+ or 2) the accelerator reads the source bitmap out of offscreen
+ video memory. Some types of primitives are better suited towards
+ one method or the other. Type 2 is useful for reusable patterns
+ such as stipples which can be cached in offscreen memory. The
+ aperature method can be used for stippling but the CPU must pass
+ the data across the bus each time a stippled fill is to be performed.
+ For expanding 1bpp client pixmaps or text strings to the screen,
+ the aperature method is usually superior because the intermediate
+ copy in offscreen memory needed by the second method would only be
+ used once. Unfortunately, many accelerators can only do one of these
+ methods and not both.
+
+ XAA provides both ScreenToScreen and CPUToScreen color expansion
+ interfaces for doing color expansion fills. The ScreenToScreen
+ functions can only be used with hardware that supports reading
+ of source bitmaps from offscreen video memory, and these are only
+ used for cacheable patterns such as stipples. There are two
+ variants of the CPUToScreen routines - a direct method intended
+ for hardware that has a transfer aperature, and an indirect method
+ intended for hardware without transfer aperatures or hardware
+ with unusual transfer requirements. Hardware that can only expand
+ bitmaps from video memory should supply ScreenToScreen routines
+ but also ScanlineCPUToScreen (indirect) routines to optimize transfers
+ of non-cacheable data. Hardware that can only accept source bitmaps
+ through an aperature should supply CPUToScreen (or ScanlineCPUToScreen)
+ routines. Hardware that can do both should provide both ScreenToScreen
+ and CPUToScreen routines.
+
+ For both ScreenToScreen and CPUToScreen interfaces, the GXCOPY_ONLY,
+ ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags described in
+ Section 2.0 are valid as well as the following:
+
+ /* bit order requirements (one of these must be set) */
+
+ BIT_ORDER_IN_BYTE_LSBFIRST
+
+ This indicates that least significant bit in each byte of the source
+ data corresponds to the leftmost of that block of 8 pixels. This
+ is the prefered format.
+
+ BIT_ORDER_IN_BYTE_MSBFIRST
+
+ This indicates that most significant bit in each byte of the source
+ data corresponds to the leftmost of that block of 8 pixels.
+
+ /* transparency restrictions */
+
+ NO_TRANSPARENCY
+
+ This indicates that the accelerator cannot do a transparent expansion.
+
+ TRANSPARENCY_ONLY
+
+ This indicates that the accelerator cannot do an opaque expansion.
+ In cases where where the background needs to be filled, XAA will
+ render the primitive in two passes when using the CPUToScreen
+ interface, but will not do so with the ScreenToScreen interface
+ since that would require caching of two patterns. Some
+ ScreenToScreen hardware may be able to render two passes at the
+ driver level and remove the TRANSPARENCY_ONLY restriction if
+ it can render pixels corresponding to the zero bits.
+
+
+
+2.5.1 Screen To Screen Color Expansion
+
+ The ScreenToScreenColorExpandFill routines provide an interface
+ for doing expansion blits from source patterns stored in offscreen
+ video memory.
+
+ void SetupForScreenToScreenColorExpandFill (ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop, unsigned int planemask)
+
+
+ Ones in the source bitmap will correspond to the fg color.
+ Zeros in the source bitmap will correspond to the bg color
+ unless bg = -1. In that case the pixels corresponding to the
+ zeros in the bitmap shall be left unmodified by the accelerator.
+
+ For hardware that doesn't allow an easy implementation of skipleft, the
+ driver can replace CacheMonoStipple function with one that stores multiple
+ rotated copies of the stipple and select between them. In this case the
+ driver should set CacheColorExpandDensity to tell XAA how many copies of
+ the pattern are stored in the width of a cache slot. For instance if the
+ hardware can specify the starting address in bytes, then 8 rotated copies
+ of the stipple are needed and CacheColorExpandDensity should be set to 8.
+
+ void SubsequentScreenToScreenColorExpandFill( ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int offset )
+
+
+ Fill a rectangle "w" x "h" at location (x,y). The source pitch
+ between scanlines is the framebuffer pitch (pScrn->displayWidth
+ pixels) and srcx and srcy indicate the start of the source pattern
+ in units of framebuffer pixels. "Offset" indicates the bit offset
+ into the pattern that corresponds to the pixel being painted at
+ "x" on the screen. Some hardware accepts source coordinates in
+ units of bits which makes implementation of the offset trivial.
+ In that case, the bit address of the source bit corresponding to
+ the pixel painted at (x,y) would be:
+
+ (srcy * pScrn->displayWidth + srcx) * pScrn->bitsPerPixel + offset
+
+ It should be noted that the offset assumes LSBFIRST hardware.
+ For MSBFIRST hardware, the driver may need to implement the
+ offset by bliting only from byte boundaries and hardware clipping.
+
+
+
+2.5.2 CPU To Screen Color Expansion
+
+
+ The CPUToScreenColorExpandFill routines provide an interface for
+ doing expansion blits from source patterns stored in system memory.
+ There are two varieties of this primitive, a CPUToScreenColorExpandFill
+ and a ScanlineCPUToScreenColorExpandFill. With the
+ CPUToScreenColorExpandFill method, the source data is sent serially
+ through a memory mapped aperature. With the Scanline version, the
+ data is rendered scanline at a time into intermediate buffers with
+ a call to SubsequentColorExpandScanline following each scanline.
+
+ These two methods have separate flags fields, the
+ CPUToScreenColorExpandFillFlags and ScanlineCPUToScreenColorExpandFillFlags
+ respectively. Flags specific to one method or the other are described
+ in sections 2.5.2.1 and 2.5.2.2 but for both cases the bit order and
+ transparency restrictions listed at the beginning of section 2.5 are
+ valid as well as the following:
+
+ /* clipping (optional) */
+
+ LEFT_EDGE_CLIPPING
+
+ This indicates that the accelerator supports omission of up to
+ 31 pixels on the left edge of the rectangle to be filled. This
+ is beneficial since it allows transfer of the source bitmap to
+ always occur from DWORD boundaries.
+
+ LEFT_EDGE_CLIPPING_NEGATIVE_X
+
+ This flag indicates that the accelerator can render color expansion
+ rectangles even if the value of x origin is negative (off of
+ the screen on the left edge).
+
+ /* misc */
+
+ TRIPLE_BITS_24BPP
+
+ When enabled (must be in 24bpp mode), color expansion functions
+ are expected to require three times the amount of bits to be
+ transferred so that 24bpp grayscale colors can be used with color
+ expansion in 8bpp coprocessor mode. Each bit is expanded to 3
+ bits when writing the monochrome data.
+
+
+ 2.5.1 The Direct Method
+
+
+ Using the direct method of color expansion XAA will send all
+ bitmap data to the accelerator serially through an memory mapped
+ transfer window defined by the following two fields:
+
+ unsigned char *ColorExpandBase
+
+ This indicates the memory address of the beginning of the aperture.
+
+ int ColorExpandRange
+
+ This indicates the size in bytes of the aperture.
+
+ The driver should specify how the transfered data should be padded.
+ There are options for both the padding of each Y scanline and for the
+ total transfer to the aperature.
+ One of the following two flags must be set:
+
+ CPU_TRANSFER_PAD_DWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be DWORD padded. This is the default behavior.
+
+ CPU_TRANSFER_PAD_QWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be QWORD padded. With this set, XAA will send
+ an extra DWORD to the aperature when needed to ensure that only
+ an even number of DWORDs are sent.
+
+ And then there are the flags for padding of each scanline:
+
+ SCANLINE_PAD_DWORD
+
+ This indicates that each Y scanline should be DWORD padded.
+ This is the only option available and is the default.
+
+ Finally, there is the CPU_TRANSFER_BASE_FIXED flag which indicates
+ that the aperture is a single register rather than a range of
+ registers, and XAA should write all of the data to the first DWORD.
+ If the ColorExpandRange is not large enough to accomodate scanlines
+ the width of the screen, this option will be forced. That is, the
+ ColorExpandRange must be:
+
+ ((virtualX + 31)/32) * 4 bytes or more.
+
+ ((virtualX + 62)/32 * 4) if LEFT_EDGE_CLIPPING_NEGATIVE_X is set.
+
+ If the TRIPLE_BITS_24BPP flag is set, the required area should be
+ multiplied by three.
+
+
+void SetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+
+
+
+ Ones in the source bitmap will correspond to the fg color.
+ Zeros in the source bitmap will correspond to the bg color
+ unless bg = -1. In that case the pixels corresponding to the
+ zeros in the bitmap shall be left unmodified by the accelerator.
+
+
+void SubsequentCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft )
+
+ When this function is called, the accelerator should be setup
+ to fill a rectangle of dimension "w" by "h" with origin at (x,y)
+ in the fill style prescribed by the last call to
+ SetupForCPUToScreenColorExpandFill. XAA will pass the data to
+ the aperture immediately after this function is called. If the
+ skipleft is non-zero (and LEFT_EDGE_CLIPPING has been enabled), then
+ the accelerator _should_not_ render skipleft pixels on the leftmost
+ edge of the rectangle. Some engines have an alignment feature
+ like this built in, some others can do this using a clipping
+ window.
+
+ It can be arranged for XAA to call Sync() after it is through
+ calling the Subsequent function by setting SYNC_AFTER_COLOR_EXPAND
+ in the CPUToScreenColorExpandFillFlags. This can provide the driver
+ with an oportunity to reset a clipping window if needed.
+
+
+2.5.2 The Indirect Method
+
+ Using the indirect method, XAA will render the bitmap data scanline
+ at a time to one or more buffers. These buffers may be memory
+ mapped apertures or just intermediate storage.
+
+ int NumScanlineColorExpandBuffers
+
+ This indicates the number of buffers available.
+
+ unsigned char **ScanlineColorExpandBuffers
+
+ This is an array of pointers to the memory locations of each buffer.
+ Each buffer is expected to be large enough to accommodate scanlines
+ the width of the screen. That is:
+
+ ((virtualX + 31)/32) * 4 bytes or more.
+
+ ((virtualX + 62)/32 * 4) if LEFT_EDGE_CLIPPING_NEGATIVE_X is set.
+
+ Scanlines are always DWORD padded.
+ If the TRIPLE_BITS_24BPP flag is set, the required area should be
+ multiplied by three.
+
+
+void SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+
+ Ones in the source bitmap will correspond to the fg color.
+ Zeros in the source bitmap will correspond to the bg color
+ unless bg = -1. In that case the pixels corresponding to the
+ zeros in the bitmap shall be left unmodified by the accelerator.
+
+
+void SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft )
+
+void SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
+
+
+ When SubsequentScanlineCPUToScreenColorExpandFill is called, XAA
+ will begin transfering the source data scanline at a time, calling
+ SubsequentColorExpandScanline after each scanline. If more than
+ one buffer is available, XAA will cycle through the buffers.
+ Subsequent scanlines will use the next buffer and go back to the
+ buffer 0 again when the last buffer is reached. The index into
+ the ScanlineColorExpandBuffers array is presented as "bufno"
+ with each SubsequentColorExpandScanline call.
+
+ The skipleft field is the same as for the direct method.
+
+ The indirect method can be use to send the source data directly
+ to a memory mapped aperture represented by a single color expand
+ buffer, scanline at a time, but more commonly it is used to place
+ the data into offscreen video memory so that the accelerator can
+ blit it to the visible screen from there. In the case where the
+ accelerator permits rendering into offscreen video memory while
+ the accelerator is active, several buffers can be used so that
+ XAA can be placing source data into the next buffer while the
+ accelerator is blitting the current buffer. For cases where
+ the accelerator requires some special manipulation of the source
+ data first, the buffers can be in system memory. The CPU can
+ manipulate these buffers and then send the data to the accelerator.
+
+
+
+2.6 8x8 Mono Pattern Fills
+
+ XAA provides support for two types of 8x8 hardware patterns -
+ "Mono" patterns and "Color" patterns. Mono pattern data is
+ 64 bits of color expansion data with ones indicating the
+ foreground color and zeros indicating the background color.
+ The source bitmaps for the 8x8 mono patterns can be presented
+ to the graphics accelerator in one of two ways. They can be
+ passed as two DWORDS to the 8x8 mono pattern functions or
+ they can be cached in offscreen memory and their locations
+ passed to the 8x8 mono pattern functions. In addition to the
+ GXCOPY_ONLY, ROP_NEEDS_SOURCE, NO_PLANEMASK and RGB_EQUAL flags
+ defined in Section 2.0, the following are defined for the
+ Mono8x8PatternFillFlags:
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS
+
+ This indicates that the 8x8 patterns should be packed into two
+ DWORDS and passed to the 8x8 mono pattern functions. The default
+ behavior is to cache the patterns in offscreen video memory and
+ pass the locations of these patterns to the functions instead.
+ The pixmap cache must be enabled for the default behavior (8x8
+ pattern caching) to work. See Section 3 for how to enable the
+ pixmap cache. The pixmap cache is not necessary for
+ HARDWARE_PATTERN_PROGRAMMED_BITS.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ If the hardware supports programmable pattern offsets then
+ this option should be set. See the table below for further
+ infomation.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ Some hardware wants the pattern offset specified with respect to the
+ upper left-hand corner of the primitive being drawn. Other hardware
+ needs the option HARDWARE_PATTERN_SCREEN_ORIGIN set to indicate that
+ all pattern offsets should be referenced to the upper left-hand
+ corner of the screen. HARDWARE_PATTERN_SCREEN_ORIGIN is preferable
+ since this is more natural for the X-Window system and offsets will
+ have to be recalculated for each Subsequent function otherwise.
+
+ BIT_ORDER_IN_BYTE_MSBFIRST
+ BIT_ORDER_IN_BYTE_LSBFIRST
+
+ As with other color expansion routines this indicates whether the
+ most or the least significant bit in each byte from the pattern is
+ the leftmost on the screen.
+
+ TRANSPARENCY_ONLY
+ NO_TRANSPARENCY
+
+ This means the same thing as for the color expansion rect routines
+ except that for TRANSPARENCY_ONLY XAA will not render the primitive
+ in two passes since this is more easily handled by the driver.
+ It is recommended that TRANSPARENCY_ONLY hardware handle rendering
+ of opaque patterns in two passes (the background can be filled as
+ a rectangle in GXcopy) in the Subsequent function so that the
+ TRANSPARENCY_ONLY restriction can be removed.
+
+
+
+ Additional information about cached patterns...
+ For the case where HARDWARE_PATTERN_PROGRAMMED_BITS is not set and
+ the pattern must be cached in offscreen memory, the first pattern
+ starts at the cache slot boundary which is set by the
+ CachePixelGranularity field used to configure the pixmap cache.
+ One should ensure that the CachePixelGranularity reflects any
+ alignment restrictions that the accelerator may put on 8x8 pattern
+ storage locations. When HARDWARE_PATTERN_PROGRAMMED_ORIGIN is set
+ there is only one pattern stored. When this flag is not set,
+ all 64 pre-rotated copies of the pattern are cached in offscreen memory.
+ The MonoPatternPitch field can be used to specify the X position pixel
+ granularity that each of these patterns must align on. If the
+ MonoPatternPitch is not supplied, the patterns will be densely packed
+ within the cache slot. The behavior of the default XAA 8x8 pattern
+ caching mechanism to store all 8x8 patterns linearly in video memory.
+ If the accelerator needs the patterns stored in a more unusual fashion,
+ the driver will need to provide its own 8x8 mono pattern caching
+ routines for XAA to use.
+
+ The following table describes the meanings of the "patx" and "paty"
+ fields in both the SetupFor and Subsequent functions.
+
+ With HARDWARE_PATTERN_SCREEN_ORIGIN
+ -----------------------------------
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS and HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ SetupFor: patx and paty are the first and second DWORDS of the
+ 8x8 mono pattern.
+
+ Subsequent: patx and paty are the x,y offset into that pattern.
+ All Subsequent calls will have the same offset in
+ the case of HARDWARE_PATTERN_SCREEN_ORIGIN so only
+ the offset specified by the first Subsequent call
+ after a SetupFor call will need to be observed.
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS only
+
+ SetupFor: patx and paty hold the first and second DWORDS of
+ the 8x8 mono pattern pre-rotated to match the desired
+ offset.
+
+ Subsequent: These just hold the same patterns and can be ignored.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN only
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the 8x8 pattern is stored. The
+ bits are stored linearly in memory at that location.
+
+ Subsequent: patx and paty hold the offset into the pattern.
+ All Subsequent calls will have the same offset in
+ the case of HARDWARE_PATTERN_SCREEN_ORIGIN so only
+ the offset specified by the first Subsequent call
+ after a SetupFor call will need to be observed.
+
+ Neither programmed bits or origin
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the pre-rotated 8x8 pattern is
+ stored.
+
+ Subsequent: patx and paty are the same as in the SetupFor function
+ and can be ignored.
+
+
+ Without HARDWARE_PATTERN_SCREEN_ORIGIN
+ --------------------------------------
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS and HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ SetupFor: patx and paty are the first and second DWORDS of the
+ 8x8 mono pattern.
+
+ Subsequent: patx and paty are the x,y offset into that pattern.
+
+ HARDWARE_PATTERN_PROGRAMMED_BITS only
+
+ SetupFor: patx and paty holds the first and second DWORDS of
+ the unrotated 8x8 mono pattern. This can be ignored.
+
+ Subsequent: patx and paty hold the rotated 8x8 pattern to be
+ rendered.
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN only
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the 8x8 pattern is stored. The
+ bits are stored linearly in memory at that location.
+
+ Subsequent: patx and paty hold the offset into the pattern.
+
+ Neither programmed bits or origin
+
+ SetupFor: patx and paty hold the x,y coordinates of the offscreen
+ memory location where the unrotated 8x8 pattern is
+ stored. This can be ignored.
+
+ Subsequent: patx and paty hold the x,y coordinates of the
+ rotated 8x8 pattern to be rendered.
+
+
+
+void SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop, unsigned int planemask)
+
+ SetupForMono8x8PatternFill indicates that any combination of the
+ following may follow it.
+
+ SubsequentMono8x8PatternFillRect
+ SubsequentMono8x8PatternFillTrap
+
+ The fg, bg, rop and planemask fields have the same meaning as the
+ ones used for the other color expansion routines. Patx's and paty's
+ meaning can be determined from the table above.
+
+
+void SubsequentMono8x8PatternFillRect( ScrnInfoPtr pScrn,
+ int patx, int paty, int x, int y, int w, int h)
+
+ Fill a rectangle of dimensions "w" by "h" with origin at (x,y)
+ using the parameters give by the last SetupForMono8x8PatternFill
+ call. The meanings of patx and paty can be determined by the
+ table above.
+
+void SubsequentMono8x8PatternFillTrap( ScrnInfoPtr pScrn,
+ int patx, int paty, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+
+ The meanings of patx and paty can be determined by the table above.
+ The rest of the fields have the same meanings as those in the
+ SubsequentSolidFillTrap function.
+
+
+
+2.7 8x8 Color Pattern Fills
+
+ 8x8 color pattern data is 64 pixels of full color data that
+ is stored linearly in offscreen video memory. 8x8 color patterns
+ are useful as a substitute for 8x8 mono patterns when tiling,
+ doing opaque stipples, or in the case where transperency is
+ supported, regular stipples. 8x8 color pattern fills also have
+ the additional benefit of being able to tile full color 8x8
+ patterns instead of just 2 color ones like the mono patterns.
+ However, full color 8x8 patterns aren't used very often in the
+ X Window system so you might consider passing this primitive
+ by if you already can do mono patterns, especially if they
+ require alot of cache area. Color8x8PatternFillFlags is
+ the flags field for this primitive and the GXCOPY_ONLY,
+ ROP_NEEDS_SOURCE and NO_PLANEMASK flags as described in
+ Section 2.0 are valid as well as the following:
+
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+
+ If the hardware supports programmable pattern offsets then
+ this option should be set.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ Some hardware wants the pattern offset specified with respect to the
+ upper left-hand corner of the primitive being drawn. Other hardware
+ needs the option HARDWARE_PATTERN_SCREEN_ORIGIN set to indicate that
+ all pattern offsets should be referenced to the upper left-hand
+ corner of the screen. HARDWARE_PATTERN_SCREEN_ORIGIN is preferable
+ since this is more natural for the X-Window system and offsets will
+ have to be recalculated for each Subsequent function otherwise.
+
+ NO_TRANSPARENCY
+ TRANSPARENCY_GXCOPY_ONLY
+
+ These mean the same as for the ScreenToScreenCopy functions.
+
+
+ The following table describes the meanings of patx and paty passed
+ to the SetupFor and Subsequent fields:
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN && HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ SetupFor: patx and paty hold the x,y location of the unrotated
+ pattern.
+
+ Subsequent: patx and paty hold the pattern offset. For the case
+ of HARDWARE_PATTERN_SCREEN_ORIGIN all Subsequent calls
+ have the same offset so only the first call will need
+ to be observed.
+
+
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN only
+
+ SetupFor: patx and paty hold the x,y location of the unrotated
+ pattern.
+
+ Subsequent: patx and paty hold the pattern offset.
+
+ HARDWARE_PATTERN_SCREEN_ORIGIN
+
+ SetupFor: patx and paty hold the x,y location of the rotated pattern.
+
+ Subsequent: patx and paty hold the same location as the SetupFor
+ function so these can be ignored.
+
+ neither flag
+
+ SetupFor: patx and paty hold the x,y location of the unrotated
+ pattern. This can be ignored.
+
+ Subsequent: patx and paty hold the x,y location of the rotated
+ pattern.
+
+ Additional information about cached patterns...
+ All 8x8 color patterns are cached in offscreen video memory so
+ the pixmap cache must be enabled to use them. The first pattern
+ starts at the cache slot boundary which is set by the
+ CachePixelGranularity field used to configure the pixmap cache.
+ One should ensure that the CachePixelGranularity reflects any
+ alignment restrictions that the accelerator may put on 8x8 pattern
+ storage locations. When HARDWARE_PATTERN_PROGRAMMED_ORIGIN is set
+ there is only one pattern stored. When this flag is not set,
+ all 64 rotations off the pattern are accessible but it is assumed
+ that the accelerator is capable of accessing data stored on 8
+ pixel boundaries. If the accelerator has stricter alignment
+ requirements than this the dirver will need to provide its own
+ 8x8 color pattern caching routines.
+
+
+void SetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask, int trans_color)
+
+ SetupForColor8x8PatternFill indicates that any combination of the
+ following may follow it.
+
+ SubsequentColor8x8PatternFillRect
+ SubsequentColor8x8PatternFillTrap (not implemented yet)
+
+ For the meanings of patx and paty, see the table above. Trans_color
+ means the same as for the ScreenToScreenCopy functions.
+
+
+
+void SubsequentColor8x8PatternFillRect( ScrnInfoPtr pScrn,
+ int patx, int paty, int x, int y, int w, int h)
+
+ Fill a rectangle of dimensions "w" by "h" with origin at (x,y)
+ using the parameters give by the last SetupForColor8x8PatternFill
+ call. The meanings of patx and paty can be determined by the
+ table above.
+
+void SubsequentColor8x8PatternFillTrap( ScrnInfoPtr pScrn,
+ int patx, int paty, int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR )
+
+ For the meanings of patx and paty, see the table above.
+ The rest of the fields have the same meanings as those in the
+ SubsequentSolidFillTrap function.
+
+
+
+2.8 Image Writes
+
+ XAA provides a mechanism for transfering full color pixel data from
+ system memory to video memory through the accelerator. This is
+ useful for dealing with alignment issues and performing raster ops
+ on the data when writing it to the framebuffer. As with color
+ expansion rectangles, there is a direct and indirect method. The
+ direct method sends all data through a memory mapped aperature.
+ The indirect method sends the data to an intermediated buffer scanline
+ at a time.
+
+ The direct and indirect methods have separate flags fields, the
+ ImageWriteFlags and ScanlineImageWriteFlags respectively.
+ Flags specific to one method or the other are described in sections
+ 2.8.1 and 2.8.2 but for both cases the GXCOPY_ONLY, ROP_NEEDS_SOURCE
+ and NO_PLANEMASK flags described in Section 2.0 are valid as well as
+ the following:
+
+ NO_GXCOPY
+
+ In order to have accelerated image transfers faster than the
+ software versions for GXcopy, the engine needs to support clipping,
+ be using the direct method and have a large enough image transfer
+ range so that CPU_TRANSFER_BASE_FIXED doesn't need to be set.
+ If these are not supported, then it is unlikely that transfering
+ the data through the accelerator will be of any advantage for the
+ simple case of GXcopy. In fact, it may be much slower. For such
+ cases it's probably best to set the NO_GXCOPY flag so that
+ Image writes will only be used for the more complicated rops.
+
+ /* transparency restrictions */
+
+ NO_TRANSPARENCY
+
+ This indicates that the accelerator does not support skipping
+ of color keyed pixels when copying from the source to the destination.
+
+ TRANSPARENCY_GXCOPY_ONLY
+
+ This indicates that the accelerator supports skipping of color keyed
+ pixels only when the rop is GXcopy.
+
+ /* clipping (optional) */
+
+ LEFT_EDGE_CLIPPING
+
+ This indicates that the accelerator supports omission of up to
+ 3 pixels on the left edge of the rectangle to be filled. This
+ is beneficial since it allows transfer from the source pixmap to
+ always occur from DWORD boundaries.
+
+ LEFT_EDGE_CLIPPING_NEGATIVE_X
+
+ This flag indicates that the accelerator can fill areas with
+ image write data even if the value of x origin is negative (off of
+ the screen on the left edge).
+
+
+2.8.1 The Direct Method
+
+ Using the direct method of ImageWrite XAA will send all
+ bitmap data to the accelerator serially through an memory mapped
+ transfer window defined by the following two fields:
+
+ unsigned char *ImageWriteBase
+
+ This indicates the memory address of the beginning of the aperture.
+
+ int ImageWriteRange
+
+ This indicates the size in bytes of the aperture.
+
+ The driver should specify how the transfered data should be padded.
+ There are options for both the padding of each Y scanline and for the
+ total transfer to the aperature.
+ One of the following two flags must be set:
+
+ CPU_TRANSFER_PAD_DWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be DWORD padded. This is the default behavior.
+
+ CPU_TRANSFER_PAD_QWORD
+
+ This indicates that the total transfer (sum of all scanlines) sent
+ to the aperature must be QWORD padded. With this set, XAA will send
+ an extra DWORD to the aperature when needed to ensure that only
+ an even number of DWORDs are sent.
+
+ And then there are the flags for padding of each scanline:
+
+ SCANLINE_PAD_DWORD
+
+ This indicates that each Y scanline should be DWORD padded.
+ This is the only option available and is the default.
+
+ Finally, there is the CPU_TRANSFER_BASE_FIXED flag which indicates
+ that the aperture is a single register rather than a range of
+ registers, and XAA should write all of the data to the first DWORD.
+ XAA will automatically select CPU_TRANSFER_BASE_FIXED if the
+ ImageWriteRange is not large enough to accomodate an entire scanline.
+
+
+void SetupForImageWrite(ScrnInfoPtr pScrn, int rop, unsigned int planemask,
+ int trans_color, int bpp, int depth)
+
+ If trans_color is not -1 then trans_color indicates the transparency
+ color key and pixels with color trans_color passed through the
+ aperature should not be transfered to the screen but should be
+ skipped. Bpp and depth indicate the bits per pixel and depth of
+ the source pixmap. Trans_color is always -1 if the NO_TRANSPARENCY
+ flag is set.
+
+
+void SubsequentImageWriteRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+
+
+ Data passed through the aperature should be copied to a rectangle
+ of width "w" and height "h" with origin (x,y). If LEFT_EDGE_CLIPPING
+ has been enabled, skipleft will correspond to the number of pixels
+ on the left edge that should not be drawn. Skipleft is zero
+ otherwise.
+
+ It can be arranged for XAA to call Sync() after it is through
+ calling the Subsequent functions by setting SYNC_AFTER_IMAGE_WRITE
+ in the ImageWriteFlags. This can provide the driver with an
+ oportunity to reset a clipping window if needed.
+
+2.8.2 The Indirect Method
+
+ Using the indirect method, XAA will render the pixel data scanline
+ at a time to one or more buffers. These buffers may be memory
+ mapped apertures or just intermediate storage.
+
+ int NumScanlineImageWriteBuffers
+
+ This indicates the number of buffers available.
+
+ unsigned char **ScanlineImageWriteBuffers
+
+ This is an array of pointers to the memory locations of each buffer.
+ Each buffer is expected to be large enough to accommodate scanlines
+ the width of the screen. That is:
+
+ pScrn->VirtualX * pScreen->bitsPerPixel/8 bytes or more.
+
+ If LEFT_EDGE_CLIPPING_NEGATIVE_X is set, add an additional 4
+ bytes to that requirement in 8 and 16bpp, 12 bytes in 24bpp.
+
+ Scanlines are always DWORD padded.
+
+void SetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int trans_color,
+ int bpp, int depth)
+
+ If trans_color is not -1 then trans_color indicates the transparency
+ color key and pixels with color trans_color in the buffer should not
+ be transfered to the screen but should be skipped. Bpp and depth
+ indicate the bits per pixel and depth of the source bitmap.
+ Trans_color is always -1 if the NO_TRANSPARENCY flag is set.
+
+
+void SubsequentImageWriteRect(ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft)
+
+
+void SubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno)
+
+
+ When SubsequentImageWriteRect is called, XAA will begin
+ transfering the source data scanline at a time, calling
+ SubsequentImageWriteScanline after each scanline. If more than
+ one buffer is available, XAA will cycle through the buffers.
+ Subsequent scanlines will use the next buffer and go back to the
+ buffer 0 again when the last buffer is reached. The index into
+ the ScanlineImageWriteBuffers array is presented as "bufno"
+ with each SubsequentImageWriteScanline call.
+
+ The skipleft field is the same as for the direct method.
+
+ The indirect method can be use to send the source data directly
+ to a memory mapped aperture represented by a single image write
+ buffer, scanline at a time, but more commonly it is used to place
+ the data into offscreen video memory so that the accelerator can
+ blit it to the visible screen from there. In the case where the
+ accelerator permits rendering into offscreen video memory while
+ the accelerator is active, several buffers can be used so that
+ XAA can be placing source data into the next buffer while the
+ accelerator is blitting the current buffer. For cases where
+ the accelerator requires some special manipulation of the source
+ data first, the buffers can be in system memory. The CPU can
+ manipulate these buffers and then send the data to the accelerator.
+
+
+2.9 Clipping
+
+ XAA supports hardware clipping rectangles. To use clipping
+ in this way it is expected that the graphics accelerator can
+ clip primitives with verticies anywhere in the 16 bit signed
+ coordinate system.
+
+void SetClippingRectangle ( ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom)
+
+void DisableClipping (ScrnInfoPtr pScrn)
+
+ When SetClippingRectangle is called, all hardware rendering
+ following it should be clipped to the rectangle specified
+ until DisableClipping is called.
+
+ The ClippingFlags field indicates which operations this sort
+ of Set/Disable pairing can be used with. Any of the following
+ flags may be OR'd together.
+
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
+ HARDWARE_CLIP_MONO_8x8_FILL
+ HARDWARE_CLIP_COLOR_8x8_FILL
+ HARDWARE_CLIP_SOLID_FILL
+ HARDWARE_CLIP_DASHED_LINE
+ HARDWARE_CLIP_SOLID_LINE
+
+
+
+3) XAA PIXMAP CACHE
+
+ /* NOTE: XAA has no knowledge of framebuffer particulars so until
+ the framebuffer is able to render into offscreen memory, usage
+ of the pixmap cache requires that the driver provide ImageWrite
+ routines or a WritePixmap or WritePixmapToCache replacement so
+ that patterns can even be placed in the cache.
+
+ ADDENDUM: XAA can now load the pixmap cache without requiring
+ that the driver supply an ImageWrite function, but this can
+ only be done on linear framebuffers. If you have a linear
+ framebuffer, set LINEAR_FRAMEBUFFER in the XAAInfoRec.Flags
+ field and XAA will then be able to upload pixmaps into the
+ cache without the driver providing functions to do so.
+ */
+
+
+ The XAA pixmap cache provides a mechanism for caching of patterns
+ in offscreen video memory so that tiled fills and in some cases
+ stippling can be done by blitting the source patterns from offscreen
+ video memory. The pixmap cache also provides the mechanism for caching
+ of 8x8 color and mono hardware patterns. Any unused offscreen video
+ memory gets used for the pixmap cache and that information is
+ provided by the XFree86 Offscreen Memory Manager. XAA registers a
+ callback with the manager so that it can be informed of any changes
+ in the offscreen memory configuration. The driver writer does not
+ need to deal with any of this since it is all automatic. The driver
+ merely needs to initialize the Offscreen Memory Manager as described
+ in the DESIGN document and set the PIXMAP_CACHE flag in the
+ XAAInfoRec.Flags field. The Offscreen Memory Manager initialization
+ must occur before XAA is initialized or else pixmap cache
+ initialization will fail.
+
+ PixmapCacheFlags is an XAAInfoRec field which allows the driver to
+ control pixmap cache behavior to some extent. Currently only one
+ flag is defined:
+
+ DO_NOT_BLIT_STIPPLES
+
+ This indicates that the stippling should not be done by blitting
+ from the pixmap cache. This does not apply to 8x8 pattern fills.
+
+
+ CachePixelGranularity is an optional field. If the hardware requires
+ that a 8x8 patterns have some particular pixel alignment it should
+ be reflected in this field. Ignoring this field or setting it to
+ zero or one means there are no alignment issues.
+
+
+4) OFFSCREEN PIXMAPS
+
+ XAA has the ability to store pixmap drawables in offscreen video
+ memory and render into them with full hardware acceleration. Placement
+ of pixmaps in the cache is done automatically on a first-come basis and
+ only if there is room. To enable this feature, set the OFFSCREEN_PIXMAPS
+ flag in the XAAInfoRec.Flags field. This is only available when a
+ ScreenToScreenCopy function is provided, when the Offscreen memory
+ manager has been initialized and when the LINEAR_FRAMEBUFFER flag is
+ also set.
+
+ int maxOffPixWidth
+ int maxOffPixHeight
+
+ These two fields allow the driver to limit the maximum dimensions
+ of an offscreen pixmap. If one of these is not set, it is assumed
+ that there is no limit on that dimension. Note that if an offscreen
+ pixmap with a particular dimension is allowed, then your driver will be
+ expected to render primitives as large as that pixmap.
+
+$XFree86: xc/programs/Xserver/hw/xfree86/xaa/XAA.HOWTO,v 1.13 2001/05/22 18:51:09 mvojkovi Exp $
diff --git a/hw/xfree86/xaa/xaa.h b/hw/xfree86/xaa/xaa.h
new file mode 100644
index 000000000..f183f8f02
--- /dev/null
+++ b/hw/xfree86/xaa/xaa.h
@@ -0,0 +1,1362 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaa.h,v 1.39 2002/10/30 12:52:43 alanh Exp $ */
+
+#ifndef _XAA_H
+#define _XAA_H
+
+/*
+
+ ******** OPERATION SPECIFIC FLAGS *********
+
+ **** solid/dashed line flags ****
+
+--------- --------
+23 LINE_PATTERN_LSBFIRST_MSBJUSTIFIED
+22 LINE_PATTERN_LSBFIRST_LSBJUSTIFIED
+21 LINE_PATTERN_MSBFIRST_MSBJUSTIFIED
+20 LINE_PATTERN_MSBFIRST_LSBJUSTIFIED
+19 LINE_PATTERN_POWER_OF_2_ONLY
+18 LINE_LIMIT_COORDS
+17 .
+16 .
+--------- -------
+
+ **** screen to screen copy flags ****
+
+--------- --------
+23 ONLY_LEFT_TO_RIGHT_BITBLT
+22 ONLY_TWO_BITBLT_DIRECTIONS
+21 .
+20 .
+19 .
+18 .
+17 .
+16 .
+--------- -------
+
+ **** clipping flags ****
+
+--------- --------
+23 .
+22 HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND
+21 HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY
+20 HARDWARE_CLIP_MONO_8x8_FILL
+19 HARDWARE_CLIP_COLOR_8x8_FILL
+18 HARDWARE_CLIP_SOLID_FILL
+17 HARDWARE_CLIP_DASHED_LINE
+16 HARDWARE_CLIP_SOLID_LINE
+--------- -------
+
+
+ **** hardware pattern flags ****
+
+--------- --------
+23 .
+22 .
+21 HARDWARE_PATTERN_SCREEN_ORIGIN
+20 .
+19 .
+18 .
+17 HARDWARE_PATTERN_PROGRAMMED_ORIGIN
+16 HARDWARE_PATTERN_PROGRAMMED_BITS
+--------- -------
+
+ **** write pixmap flags ****
+
+--------- --------
+23 .
+22 .
+21 .
+20 .
+19 .
+18 .
+17 .
+16 CONVERT_32BPP_TO_24BPP
+--------- -------
+
+
+ ******** GENERIC FLAGS *********
+
+--------- -------
+15 SYNC_AFTER_COLOR_EXPAND
+14 CPU_TRANSFER_PAD_QWORD
+13 .
+12 LEFT_EDGE_CLIPPING_NEGATIVE_X
+11 LEFT_EDGE_CLIPPING
+10 CPU_TRANSFER_BASE_FIXED
+ 9 BIT_ORDER_IN_BYTE_MSBFIRST
+ 8 TRANSPARENCY_GXCOPY_ONLY
+--------- -------
+ 7 NO_TRANSPARENCY
+ 6 TRANSPARENCY_ONLY
+ 5 ROP_NEEDS_SOURCE
+ 4 TRIPLE_BITS_24BPP
+ 3 RGB_EQUAL
+ 2 NO_PLANEMASK
+ 1 NO_GXCOPY
+ 0 GXCOPY_ONLY
+--------- -------
+
+
+*/
+
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
+/* Flags */
+#define PIXMAP_CACHE 0x00000001
+#define MICROSOFT_ZERO_LINE_BIAS 0x00000002
+#define OFFSCREEN_PIXMAPS 0x00000004
+#define LINEAR_FRAMEBUFFER 0x00000008
+
+
+/* GC fg, bg, and planemask restrictions */
+#define GXCOPY_ONLY 0x00000001
+#define NO_GXCOPY 0x00000002
+#define NO_PLANEMASK 0x00000004
+#define RGB_EQUAL 0x00000008
+#define TRIPLE_BITS_24BPP 0x00000010
+#define ROP_NEEDS_SOURCE 0x00000020
+
+/* transparency restrictions */
+#define TRANSPARENCY_ONLY 0x00000040
+#define NO_TRANSPARENCY 0x00000080
+#define TRANSPARENCY_GXCOPY_ONLY 0x00000100
+
+/* bit order restrictions */
+#define BIT_ORDER_IN_BYTE_MSBFIRST 0x00000200
+#define BIT_ORDER_IN_BYTE_LSBFIRST 0x00000000
+
+/* transfer base restriction */
+#define CPU_TRANSFER_BASE_FIXED 0x00000400
+
+/* skipleft restrictions */
+#define LEFT_EDGE_CLIPPING 0x00000800
+#define LEFT_EDGE_CLIPPING_NEGATIVE_X 0x00001000
+
+/* data padding */
+#define CPU_TRANSFER_PAD_DWORD 0x00000000
+#define CPU_TRANSFER_PAD_QWORD 0x00004000
+#define SCANLINE_PAD_DWORD 0x00000000
+
+#define SYNC_AFTER_COLOR_EXPAND 0x00008000
+#define SYNC_AFTER_IMAGE_WRITE SYNC_AFTER_COLOR_EXPAND
+
+/* hardware pattern */
+#define HARDWARE_PATTERN_PROGRAMMED_BITS 0x00010000
+#define HARDWARE_PATTERN_PROGRAMMED_ORIGIN 0x00020000
+#define HARDWARE_PATTERN_SCREEN_ORIGIN 0x00200000
+
+/* copyarea flags */
+#define ONLY_TWO_BITBLT_DIRECTIONS 0x00400000
+#define ONLY_LEFT_TO_RIGHT_BITBLT 0x00800000
+
+/* line flags */
+#define LINE_PATTERN_LSBFIRST_MSBJUSTIFIED 0x00800000
+#define LINE_PATTERN_LSBFIRST_LSBJUSTIFIED 0x00400000
+#define LINE_PATTERN_MSBFIRST_MSBJUSTIFIED 0x00200000
+#define LINE_PATTERN_MSBFIRST_LSBJUSTIFIED 0x00100000
+#define LINE_PATTERN_POWER_OF_2_ONLY 0x00080000
+#define LINE_LIMIT_COORDS 0x00040000
+
+/* clipping flags */
+#define HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND 0x00400000
+#define HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY 0x00200000
+#define HARDWARE_CLIP_MONO_8x8_FILL 0x00100000
+#define HARDWARE_CLIP_COLOR_8x8_FILL 0x00080000
+#define HARDWARE_CLIP_SOLID_FILL 0x00040000
+#define HARDWARE_CLIP_DASHED_LINE 0x00020000
+#define HARDWARE_CLIP_SOLID_LINE 0x00010000
+
+#define HARDWARE_CLIP_LINE 0x00000000
+
+
+/* image write flags */
+#define CONVERT_32BPP_TO_24BPP 0x00010000
+
+/* pixmap cache flags */
+#define CACHE_MONO_8x8 0x00000001
+#define CACHE_COLOR_8x8 0x00000002
+#define DO_NOT_BLIT_STIPPLES 0x00000004
+#define DO_NOT_TILE_MONO_DATA 0x00000008
+#define DO_NOT_TILE_COLOR_DATA 0x00000010
+
+
+#define DEGREES_0 0
+#define DEGREES_90 1
+#define DEGREES_180 2
+#define DEGREES_270 3
+
+#define OMIT_LAST 1
+
+/* render flags */
+
+#define XAA_RENDER_POWER_OF_2_TILE_ONLY 0x00000008
+#define XAA_RENDER_NO_SRC_ALPHA 0x00000004
+#define XAA_RENDER_IMPRECISE_ONLY 0x00000002
+#define XAA_RENDER_NO_TILE 0x00000001
+
+#define XAA_RENDER_REPEAT 0x00000001
+
+typedef void (* ValidateGCProcPtr)(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+typedef struct {
+ unsigned char *bits;
+ int width;
+ int height;
+ int yoff;
+ int srcwidth;
+ int start;
+ int end;
+} NonTEGlyphInfo, *NonTEGlyphPtr;
+
+
+typedef struct {
+ int x;
+ int y;
+ int w;
+ int h;
+ int orig_w;
+ int orig_h;
+ unsigned long serialNumber;
+ int pat0;
+ int pat1;
+ int fg;
+ int bg;
+ int trans_color;
+ DDXPointPtr offsets;
+ DevUnion devPrivate;
+} XAACacheInfoRec, *XAACacheInfoPtr;
+
+
+typedef struct _PixmapLink {
+ PixmapPtr pPix;
+ struct _PixmapLink *next;
+ FBAreaPtr area;
+} PixmapLink, *PixmapLinkPtr;
+
+typedef struct _XAAInfoRec {
+ ScrnInfoPtr pScrn;
+ int Flags;
+
+ void (*Sync)(
+ ScrnInfoPtr pScrn
+ );
+
+ /* Restore Accel State is a driver callback that is used
+ * when another screen on the same device has been active.
+ * This allows multihead on a single device to work.
+ * If The entityProp has IS_SHARED_ACCEL defined then this
+ * function is required.
+ */
+
+ void (*RestoreAccelState)(
+ ScrnInfoPtr pScrn
+ );
+
+ /***************** Low Level *****************/
+
+/* Blits */
+ void (*SetupForScreenToScreenCopy)(
+ ScrnInfoPtr pScrn,
+ int xdir, int ydir,
+ int rop,
+ unsigned int planemask,
+ int trans_color
+ );
+ int ScreenToScreenCopyFlags;
+
+ void (*SubsequentScreenToScreenCopy)(
+ ScrnInfoPtr pScrn,
+ int xsrc, int ysrc,
+ int xdst, int ydst,
+ int w, int h
+ );
+
+
+/* Solid fills */
+ void (*SetupForSolidFill)(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask
+ );
+ int SolidFillFlags;
+
+ void (*SubsequentSolidFillRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h
+ );
+
+ void (*SubsequentSolidFillTrap)(
+ ScrnInfoPtr pScrn,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+ );
+
+
+/* Solid lines */
+
+ void (*SetupForSolidLine)(
+ ScrnInfoPtr pScrn,
+ int color,
+ int rop,
+ unsigned int planemask
+ );
+ int SolidLineFlags;
+
+ void (*SubsequentSolidTwoPointLine)(
+ ScrnInfoPtr pScrn,
+ int xa, int ya, int xb, int yb, int flags
+ );
+
+ void (*SubsequentSolidBresenhamLine)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int absmaj, int absmin, int err, int len, int octant
+ );
+ int SolidBresenhamLineErrorTermBits;
+
+ void (*SubsequentSolidHorVertLine)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+ );
+
+/* Dashed lines */
+
+ void (*SetupForDashedLine)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask,
+ int length,
+ unsigned char *pattern
+ );
+ int DashedLineFlags;
+ int DashPatternMaxLength;
+
+ void (*SubsequentDashedTwoPointLine)(
+ ScrnInfoPtr pScrn,
+ int xa, int ya, int xb, int yb, int flags, int phase
+ );
+
+ void (*SubsequentDashedBresenhamLine)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int absmaj, int absmin, int err, int len, int flags,
+ int phase
+ );
+ int DashedBresenhamLineErrorTermBits;
+
+/* Clipper */
+
+ void (*SetClippingRectangle) (
+ ScrnInfoPtr pScrn,
+ int left, int top, int right, int bottom
+ );
+ int ClippingFlags;
+
+ void (*DisableClipping)(ScrnInfoPtr pScrn);
+
+/* 8x8 mono pattern fills */
+ void (*SetupForMono8x8PatternFill)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int Mono8x8PatternFillFlags;
+
+ void (*SubsequentMono8x8PatternFillRect)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h
+ );
+
+ void (*SubsequentMono8x8PatternFillTrap)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+ );
+
+/* 8x8 color pattern fills */
+
+ void (*SetupForColor8x8PatternFill)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int rop,
+ unsigned int planemask,
+ int transparency_color
+ );
+ int Color8x8PatternFillFlags;
+
+ void (*SubsequentColor8x8PatternFillRect)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int x, int y, int w, int h
+ );
+
+ void (*SubsequentColor8x8PatternFillTrap)(
+ ScrnInfoPtr pScrn,
+ int patx, int paty,
+ int y, int h,
+ int left, int dxL, int dyL, int eL,
+ int right, int dxR, int dyR, int eR
+ );
+
+
+/* Color expansion */
+
+ void (*SetupForCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int CPUToScreenColorExpandFillFlags;
+
+ void (*SubsequentCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+
+ unsigned char *ColorExpandBase;
+ int ColorExpandRange;
+
+
+/* Scanline color expansion */
+
+ void (*SetupForScanlineCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int ScanlineCPUToScreenColorExpandFillFlags;
+
+ void (*SubsequentScanlineCPUToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+
+ void (*SubsequentColorExpandScanline)(
+ ScrnInfoPtr pScrn,
+ int bufno
+ );
+
+ int NumScanlineColorExpandBuffers;
+ unsigned char **ScanlineColorExpandBuffers;
+
+/* Screen to screen color expansion */
+
+ void (*SetupForScreenToScreenColorExpandFill) (
+ ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int ScreenToScreenColorExpandFillFlags;
+
+ void (*SubsequentScreenToScreenColorExpandFill)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int srcx, int srcy, int skipleft
+ );
+
+
+/* Image transfers */
+
+ void (*SetupForImageWrite)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+ );
+ int ImageWriteFlags;
+
+ void (*SubsequentImageWriteRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+ unsigned char *ImageWriteBase;
+ int ImageWriteRange;
+
+/* Scanline Image transfers */
+
+ void (*SetupForScanlineImageWrite)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+ );
+ int ScanlineImageWriteFlags;
+
+ void (*SubsequentScanlineImageWriteRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int skipleft
+ );
+
+ void (*SubsequentImageWriteScanline) (
+ ScrnInfoPtr pScrn,
+ int bufno
+ );
+
+ int NumScanlineImageWriteBuffers;
+ unsigned char **ScanlineImageWriteBuffers;
+
+ /* Image Reads - OBSOLETE AND NOT USED */
+
+ void (*SetupForImageRead) (
+ ScrnInfoPtr pScrn,
+ int bpp, int depth
+ );
+ int ImageReadFlags;
+
+ unsigned char *ImageReadBase;
+ int ImageReadRange;
+
+ void (*SubsequentImageReadRect)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h
+ );
+
+
+ /***************** Mid Level *****************/
+ void (*ScreenToScreenBitBlt)(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir,
+ int alu,
+ unsigned int planmask
+ );
+ int ScreenToScreenBitBltFlags;
+
+ void (*WriteBitmap) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+ );
+ int WriteBitmapFlags;
+
+ void (*FillSolidRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox
+ );
+ int FillSolidRectsFlags;
+
+ void (*FillMono8x8PatternRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+ );
+ int FillMono8x8PatternRectsFlags;
+
+ void (*FillColor8x8PatternRects)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+ );
+ int FillColor8x8PatternRectsFlags;
+
+ void (*FillCacheBltRects)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+ );
+ int FillCacheBltRectsFlags;
+
+ void (*FillColorExpandRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillColorExpandRectsFlags;
+
+ void (*FillCacheExpandRects)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillCacheExpandRectsFlags;
+
+ void (*FillImageWriteRects)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillImageWriteRectsFlags;
+
+
+ void (*FillSolidSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted
+ );
+ int FillSolidSpansFlags;
+
+ void (*FillMono8x8PatternSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ int pat0, int pat1,
+ int xorg, int yorg
+ );
+ int FillMono8x8PatternSpansFlags;
+
+ void (*FillColor8x8PatternSpans)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+ );
+ int FillColor8x8PatternSpansFlags;
+
+ void (*FillCacheBltSpans)(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+ );
+ int FillCacheBltSpansFlags;
+
+ void (*FillColorExpandSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillColorExpandSpansFlags;
+
+ void (*FillCacheExpandSpans)(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+ );
+ int FillCacheExpandSpansFlags;
+
+ void (*TEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+ );
+ int TEGlyphRendererFlags;
+
+ void (*NonTEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+ );
+ int NonTEGlyphRendererFlags;
+
+ void (*WritePixmap) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+ );
+ int WritePixmapFlags;
+
+ void (*ReadPixmap) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *dst,
+ int dstwidth,
+ int bpp, int depth
+ );
+ int ReadPixmapFlags;
+
+ /***************** GC Level *****************/
+ RegionPtr (*CopyArea)(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+ );
+ int CopyAreaFlags;
+
+ RegionPtr (*CopyPlane)(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+ );
+ int CopyPlaneFlags;
+
+ void (*PushPixelsSolid) (
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx, int dy,
+ int xOrg, int yOrg
+ );
+ int PushPixelsFlags;
+
+ /** PolyFillRect **/
+
+ void (*PolyFillRectSolid)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectSolidFlags;
+
+ void (*PolyFillRectStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectStippledFlags;
+
+ void (*PolyFillRectOpaqueStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectOpaqueStippledFlags;
+
+ void (*PolyFillRectTiled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+ );
+ int PolyFillRectTiledFlags;
+
+ /** FillSpans **/
+
+ void (*FillSpansSolid)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansSolidFlags;
+
+ void (*FillSpansStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansStippledFlags;
+
+ void (*FillSpansOpaqueStippled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansOpaqueStippledFlags;
+
+ void (*FillSpansTiled)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+ );
+ int FillSpansTiledFlags;
+
+ int (*PolyText8TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int PolyText8TEFlags;
+
+ int (*PolyText16TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int PolyText16TEFlags;
+
+ void (*ImageText8TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int ImageText8TEFlags;
+
+ void (*ImageText16TE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int ImageText16TEFlags;
+
+ void (*ImageGlyphBltTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int ImageGlyphBltTEFlags;
+
+ void (*PolyGlyphBltTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int PolyGlyphBltTEFlags;
+
+ int (*PolyText8NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int PolyText8NonTEFlags;
+
+ int (*PolyText16NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int PolyText16NonTEFlags;
+
+ void (*ImageText8NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+ );
+ int ImageText8NonTEFlags;
+
+ void (*ImageText16NonTE) (
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+ );
+ int ImageText16NonTEFlags;
+
+ void (*ImageGlyphBltNonTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int ImageGlyphBltNonTEFlags;
+
+ void (*PolyGlyphBltNonTE) (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+ );
+ int PolyGlyphBltNonTEFlags;
+
+ void (*PolyRectangleThinSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+ );
+ int PolyRectangleThinSolidFlags;
+
+ void (*PolylinesWideSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+ );
+ int PolylinesWideSolidFlags;
+
+ void (*PolylinesThinSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+ );
+ int PolylinesThinSolidFlags;
+
+ void (*PolySegmentThinSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+ );
+ int PolySegmentThinSolidFlags;
+
+ void (*PolylinesThinDashed)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+ );
+ int PolylinesThinDashedFlags;
+
+ void (*PolySegmentThinDashed)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+ );
+ int PolySegmentThinDashedFlags;
+
+ void (*FillPolygonSolid)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonSolidFlags;
+
+ void (*FillPolygonStippled)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonStippledFlags;
+
+ void (*FillPolygonOpaqueStippled)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonOpaqueStippledFlags;
+
+ void (*FillPolygonTiled)(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+ );
+ int FillPolygonTiledFlags;
+
+ void (*PolyFillArcSolid)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+ );
+ int PolyFillArcSolidFlags;
+
+ void (*PutImage)(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+ );
+ int PutImageFlags;
+
+ /* Validation masks */
+
+ unsigned long FillSpansMask;
+ ValidateGCProcPtr ValidateFillSpans;
+ unsigned long SetSpansMask;
+ ValidateGCProcPtr ValidateSetSpans;
+ unsigned long PutImageMask;
+ ValidateGCProcPtr ValidatePutImage;
+ unsigned long CopyAreaMask;
+ ValidateGCProcPtr ValidateCopyArea;
+ unsigned long CopyPlaneMask;
+ ValidateGCProcPtr ValidateCopyPlane;
+ unsigned long PolyPointMask;
+ ValidateGCProcPtr ValidatePolyPoint;
+ unsigned long PolylinesMask;
+ ValidateGCProcPtr ValidatePolylines;
+ unsigned long PolySegmentMask;
+ ValidateGCProcPtr ValidatePolySegment;
+ unsigned long PolyRectangleMask;
+ ValidateGCProcPtr ValidatePolyRectangle;
+ unsigned long PolyArcMask;
+ ValidateGCProcPtr ValidatePolyArc;
+ unsigned long FillPolygonMask;
+ ValidateGCProcPtr ValidateFillPolygon;
+ unsigned long PolyFillRectMask;
+ ValidateGCProcPtr ValidatePolyFillRect;
+ unsigned long PolyFillArcMask;
+ ValidateGCProcPtr ValidatePolyFillArc;
+ unsigned long PolyText8Mask;
+ ValidateGCProcPtr ValidatePolyText8;
+ unsigned long PolyText16Mask;
+ ValidateGCProcPtr ValidatePolyText16;
+ unsigned long ImageText8Mask;
+ ValidateGCProcPtr ValidateImageText8;
+ unsigned long ImageText16Mask;
+ ValidateGCProcPtr ValidateImageText16;
+ unsigned long PolyGlyphBltMask;
+ ValidateGCProcPtr ValidatePolyGlyphBlt;
+ unsigned long ImageGlyphBltMask;
+ ValidateGCProcPtr ValidateImageGlyphBlt;
+ unsigned long PushPixelsMask;
+ ValidateGCProcPtr ValidatePushPixels;
+
+ void (*ComputeDash)(GCPtr pGC);
+
+ /* Pixmap Cache */
+
+ int PixmapCacheFlags;
+ Bool UsingPixmapCache;
+ Bool CanDoMono8x8;
+ Bool CanDoColor8x8;
+
+ void (*InitPixmapCache)(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+ );
+ void (*ClosePixmapCache)(
+ ScreenPtr pScreen
+ );
+
+ int (*StippledFillChooser)(GCPtr pGC);
+ int (*OpaqueStippledFillChooser)(GCPtr pGC);
+ int (*TiledFillChooser)(GCPtr pGC);
+
+ int CachePixelGranularity;
+ int MaxCacheableTileWidth;
+ int MaxCacheableTileHeight;
+ int MaxCacheableStippleWidth;
+ int MaxCacheableStippleHeight;
+
+ XAACacheInfoPtr (*CacheTile)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix
+ );
+ XAACacheInfoPtr (*CacheStipple)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix,
+ int fg, int bg
+ );
+ XAACacheInfoPtr (*CacheMonoStipple)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix
+ );
+ XAACacheInfoPtr (*CacheMono8x8Pattern)(
+ ScrnInfoPtr Scrn, int pat0, int pat1
+ );
+ XAACacheInfoPtr (*CacheColor8x8Pattern)(
+ ScrnInfoPtr Scrn, PixmapPtr pPix,
+ int fg, int bg
+ );
+
+
+ int MonoPatternPitch;
+ int CacheWidthMono8x8Pattern;
+ int CacheHeightMono8x8Pattern;
+
+ int ColorPatternPitch;
+ int CacheWidthColor8x8Pattern;
+ int CacheHeightColor8x8Pattern;
+
+ int CacheColorExpandDensity;
+
+ void (*WriteBitmapToCache) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+ );
+ void (*WritePixmapToCache) (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+ );
+ void (*WriteMono8x8PatternToCache)(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache
+ );
+ void (*WriteColor8x8PatternToCache)(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+ );
+
+ char* PixmapCachePrivate;
+
+ /* Miscellaneous */
+
+ GC ScratchGC;
+ int PreAllocSize;
+ unsigned char *PreAllocMem;
+
+ CharInfoPtr CharInfo[255];
+ NonTEGlyphInfo GlyphInfo[255];
+
+ unsigned int FullPlanemask; /* deprecated */
+
+ PixmapLinkPtr OffscreenPixmaps;
+ int maxOffPixWidth;
+ int maxOffPixHeight;
+
+ XAACacheInfoRec ScratchCacheInfoRec;
+
+ BoxPtr ClipBox;
+
+ Bool NeedToSync;
+
+ char *dgaSaves;
+
+ /* These can be supplied to override the defaults */
+
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ BackingStoreSaveAreasProcPtr SaveAreas;
+ BackingStoreRestoreAreasProcPtr RestoreAreas;
+
+ unsigned int offscreenDepths;
+ Bool offscreenDepthsInitialized;
+
+ CARD32 FullPlanemasks[32];
+
+#ifdef RENDER
+ Bool (*Composite) (
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height
+ );
+
+ Bool (*Glyphs) (
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs
+ );
+
+ Bool (*SetupForCPUToScreenAlphaTexture) (
+ ScrnInfoPtr pScrn,
+ int op,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ int alphaType,
+ CARD8 *alphaPtr,
+ int alphaPitch,
+ int width,
+ int height,
+ int flags
+ );
+ void (*SubsequentCPUToScreenAlphaTexture) (
+ ScrnInfoPtr pScrn,
+ int dstx,
+ int dsty,
+ int srcx,
+ int srcy,
+ int width,
+ int height
+ );
+ int CPUToScreenAlphaTextureFlags;
+ CARD32 * CPUToScreenAlphaTextureFormats;
+
+ Bool (*SetupForCPUToScreenTexture) (
+ ScrnInfoPtr pScrn,
+ int op,
+ int texType,
+ CARD8 *texPtr,
+ int texPitch,
+ int width,
+ int height,
+ int flags
+ );
+ void (*SubsequentCPUToScreenTexture) (
+ ScrnInfoPtr pScrn,
+ int dstx,
+ int dsty,
+ int srcx,
+ int srcy,
+ int width,
+ int height
+ );
+ int CPUToScreenTextureFlags;
+ CARD32 * CPUToScreenTextureFormats;
+
+
+#endif
+
+ /* these were added for 4.3.0 */
+ BoxRec SolidLineLimits;
+ BoxRec DashedLineLimits;
+
+} XAAInfoRec, *XAAInfoRecPtr;
+
+#define SET_SYNC_FLAG(infoRec) (infoRec)->NeedToSync = TRUE
+
+
+Bool
+XAAInit(
+ ScreenPtr pScreen,
+ XAAInfoRecPtr infoRec
+);
+
+XAAInfoRecPtr XAACreateInfoRec(void);
+
+void
+XAADestroyInfoRec(
+ XAAInfoRecPtr infoRec
+);
+
+typedef void (*DepthChangeFuncPtr) (ScrnInfoPtr pScrn, int depth);
+
+Bool
+XAAInitDualFramebufferOverlay(
+ ScreenPtr pScreen,
+ DepthChangeFuncPtr callback
+);
+
+#endif /* _XAA_H */
diff --git a/hw/xfree86/xaa/xaaBitBlt.c b/hw/xfree86/xaa/xaaBitBlt.c
new file mode 100644
index 000000000..015b539e5
--- /dev/null
+++ b/hw/xfree86/xaa/xaaBitBlt.c
@@ -0,0 +1,219 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitBlt.c,v 1.3 1998/12/06 06:08:39 dawes Exp $ */
+
+/*
+ This is a lighter version of cfbBitBlt. We calculate the boxes
+ when accelerating pixmap->screen and screen->screen copies.
+ We also pass the GC to the doBitBlt function so that it has access
+ to the fg and bg so CopyPlane can use this.
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "xaalocal.h"
+
+
+RegionPtr
+XAABitBlt(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
+ unsigned long bitPlane )
+{
+
+ RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
+ RegionPtr prgnExposed;
+ Bool freeSrcClip = FALSE;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc, ppt;
+ DDXPointRec origDest;
+ BoxPtr pbox;
+ BoxRec fastBox;
+ int i, dx, dy, numRects;
+ xRectangle origSource;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate) {
+ (*pSrcDrawable->pScreen->SourceValidate) (
+ pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
+ if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else
+ fastClip = 1;
+ } else { /* Window */
+ if (pGC->subWindowMode == IncludeInferiors) {
+ if (!((WindowPtr) pSrcDrawable)->parent) {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ } else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE)) {
+ prgnSrcClip = pGC->pCompositeClip;
+ } else {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ } else {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip) {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x) {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y) {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW) {
+ if (!((WindowPtr)pDstDrawable)->realized) {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip) {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ cclip = pGC->pCompositeClip;
+ if (REGION_NUM_RECTS(cclip) == 1) {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
+ REGION_INIT(pGC->pScreen, &rgnDst, NullBox, 0);
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ } else {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ } else {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip) {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
+ pGC->pCompositeClip);
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height) {
+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL(numRects *
+ sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose) {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, bitPlane);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
diff --git a/hw/xfree86/xaa/xaaBitOrder.c b/hw/xfree86/xaa/xaaBitOrder.c
new file mode 100644
index 000000000..d7f3ba2a3
--- /dev/null
+++ b/hw/xfree86/xaa/xaaBitOrder.c
@@ -0,0 +1,13 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitOrder.c,v 1.8 2003/02/17 16:08:29 dawes Exp $ */
+
+#include "Xmd.h"
+CARD32 XAAReverseBitOrder(CARD32 v);
+
+CARD32
+XAAReverseBitOrder(CARD32 v)
+{
+ return (((0x01010101 & v) << 7) | ((0x02020202 & v) << 5) |
+ ((0x04040404 & v) << 3) | ((0x08080808 & v) << 1) |
+ ((0x10101010 & v) >> 1) | ((0x20202020 & v) >> 3) |
+ ((0x40404040 & v) >> 5) | ((0x80808080 & v) >> 7));
+}
diff --git a/hw/xfree86/xaa/xaaBitmap.c b/hw/xfree86/xaa/xaaBitmap.c
new file mode 100644
index 000000000..9a8749dbf
--- /dev/null
+++ b/hw/xfree86/xaa/xaaBitmap.c
@@ -0,0 +1,475 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaBitmap.c,v 1.10 2000/09/01 05:49:45 mvojkovi Exp $ */
+
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+
+
+/********** byte swapping ***************/
+
+
+#ifdef FIXEDBASE
+# define DEST(i) *dest
+# define RETURN(i) return(dest)
+#else
+# define DEST(i) dest[i]
+# define RETURN(i) return(dest + i)
+#endif
+
+#ifdef MSBFIRST
+# define SOURCE(i) SWAP_BITS_IN_BYTES(src[i])
+#else
+# define SOURCE(i) src[i]
+#endif
+
+
+typedef CARD32 *(* BitmapScanlineProcPtr)(CARD32 *, CARD32 *, int, int);
+
+#ifdef TRIPLE_BITS
+static CARD32*
+BitmapScanline(
+ CARD32 *src, CARD32 *base,
+ int count, int skipleft )
+{
+ CARD32 bits;
+
+ while(count >= 3) {
+ bits = *src;
+ WRITE_BITS3(bits);
+ src++;
+ count -= 3;
+ }
+ if (count == 2) {
+ bits = *src;
+ WRITE_BITS2(bits);
+ } else if (count == 1) {
+ bits = *src;
+ WRITE_BITS1(bits);
+ }
+
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Inverted(
+ CARD32 *src, CARD32 *base,
+ int count, int skipleft )
+{
+ CARD32 bits;
+
+ while(count >= 3) {
+ bits = ~(*src);
+ WRITE_BITS3(bits);
+ src++;
+ count -= 3;
+ }
+ if (count == 2) {
+ bits = ~(*src);
+ WRITE_BITS2(bits);
+ } else if (count == 1) {
+ bits = ~(*src);
+ WRITE_BITS1(bits);
+ }
+
+ return base;
+}
+
+
+static CARD32*
+BitmapScanline_Shifted(
+ CARD32 *src, CARD32 *base,
+ int count, int skipleft )
+{
+ CARD32 bits;
+
+ while(count >= 3) {
+ bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
+ WRITE_BITS3(bits);
+ src++;
+ count -= 3;
+ }
+ if (count == 2) {
+ bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
+ WRITE_BITS2(bits);
+ } else if (count == 1) {
+ bits = SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft));
+ WRITE_BITS1(bits);
+ }
+
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Shifted_Inverted(
+ CARD32 *src, CARD32 *base,
+ int count, int skipleft )
+{
+ CARD32 bits;
+
+ while(count >= 3) {
+ bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
+ WRITE_BITS3(bits);
+ src++;
+ count -= 3;
+ }
+ if (count == 2) {
+ bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
+ WRITE_BITS2(bits);
+ } else if (count == 1) {
+ bits = ~(SHIFT_R(*src,skipleft) | SHIFT_L(*(src + 1),(32 - skipleft)));
+ WRITE_BITS1(bits);
+ }
+
+ return base;
+}
+
+#define BitmapScanline_Shifted_Careful BitmapScanline_Shifted
+#define BitmapScanline_Shifted_Inverted_Careful BitmapScanline_Shifted_Inverted
+
+#else
+static CARD32*
+BitmapScanline(
+ CARD32 *src, CARD32 *dest,
+ int count, int skipleft )
+{
+ while(count >= 4) {
+ DEST(0) = SOURCE(0);
+ DEST(1) = SOURCE(1);
+ DEST(2) = SOURCE(2);
+ DEST(3) = SOURCE(3);
+ count -= 4;
+ src += 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!count) return dest;
+ DEST(0) = SOURCE(0);
+ if(count == 1) RETURN(1);
+ DEST(1) = SOURCE(1);
+ if(count == 2) RETURN(2);
+ DEST(2) = SOURCE(2);
+ RETURN(3);
+}
+
+static CARD32*
+BitmapScanline_Inverted(
+ CARD32 *src, CARD32 *dest,
+ int count, int skipleft )
+{
+ while(count >= 4) {
+ DEST(0) = ~SOURCE(0);
+ DEST(1) = ~SOURCE(1);
+ DEST(2) = ~SOURCE(2);
+ DEST(3) = ~SOURCE(3);
+ count -= 4;
+ src += 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!count) return dest;
+ DEST(0) = ~SOURCE(0);
+ if(count == 1) RETURN(1);
+ DEST(1) = ~SOURCE(1);
+ if(count == 2) RETURN(2);
+ DEST(2) = ~SOURCE(2);
+ RETURN(3);
+}
+
+
+static CARD32*
+BitmapScanline_Shifted(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count--) {
+ register CARD32 tmp = SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft));
+ WRITE_BITS(tmp);
+ bits++;
+ }
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Shifted_Inverted(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ while(count--) {
+ register CARD32 tmp = ~(SHIFT_R(*bits,skipleft) |
+ SHIFT_L(*(bits + 1),(32 - skipleft)));
+ WRITE_BITS(tmp);
+ bits++;
+ }
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Shifted_Careful(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ register CARD32 tmp;
+ while(--count) {
+ tmp = SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft));
+ WRITE_BITS(tmp);
+ bits++;
+ }
+ tmp = SHIFT_R(*bits,skipleft);
+ WRITE_BITS(tmp);
+
+ return base;
+}
+
+static CARD32*
+BitmapScanline_Shifted_Inverted_Careful(
+ CARD32 *bits, CARD32 *base,
+ int count, int skipleft )
+{
+ register CARD32 tmp;
+ while(--count) {
+ tmp = ~(SHIFT_R(*bits,skipleft) | SHIFT_L(*(bits + 1),(32 - skipleft)));
+ WRITE_BITS(tmp);
+ bits++;
+ }
+ tmp = ~(SHIFT_R(*bits,skipleft));
+ WRITE_BITS(tmp);
+ return base;
+}
+
+#endif
+
+/*
+ When the accelerator is TRANSPARENCY_ONLY, WriteBitmap can do
+ the fill in two passes, inverting the source on the second pass.
+ For GXcopy we can fill the backing rectangle as a solid rect and
+ avoid the invert.
+*/
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAWriteBitmapColorExpand3)(
+#else
+EXPNAME(XAAWriteBitmapColorExpand)(
+#endif
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int H,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ unsigned char *srcp = src;
+ int SecondPassColor = -1;
+ int shift = 0, dwords;
+ BitmapScanlineProcPtr firstFunc;
+ BitmapScanlineProcPtr secondFunc;
+ int flag;
+ int h = H;
+
+#ifdef TRIPLE_BITS
+ if((bg != -1) &&
+ ((infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg != -1) &&
+ (infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ if((rop == GXcopy) && infoRec->SetupForSolidFill) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ } else SecondPassColor = bg;
+ bg = -1;
+ }
+
+#ifdef TRIPLE_BITS
+ if(skipleft) {
+#else
+ if(skipleft &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+#endif
+ if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) {
+ /* don't read past the end */
+ firstFunc = BitmapScanline_Shifted_Careful;
+ secondFunc = BitmapScanline_Shifted_Inverted_Careful;
+ } else {
+ firstFunc = BitmapScanline_Shifted;
+ secondFunc = BitmapScanline_Shifted_Inverted;
+ }
+ shift = skipleft;
+ skipleft = 0;
+ } else {
+ firstFunc = BitmapScanline;
+ secondFunc = BitmapScanline_Inverted;
+ w += skipleft;
+ x -= skipleft;
+ }
+
+#ifdef TRIPLE_BITS
+ dwords = (3 * w + 31) >> 5;
+#else
+ dwords = (w + 31) >> 5;
+#endif
+
+SECOND_PASS:
+
+ flag = (infoRec->CPUToScreenColorExpandFillFlags
+ & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+#ifndef FIXEDBASE
+ if((dwords * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ base = (*firstFunc)((CARD32*)srcp, base, dwords, shift);
+ srcp += srcwidth;
+ }
+ else
+#endif
+ while(h--) {
+ (*firstFunc)((CARD32*)srcp, base, dwords, shift);
+ srcp += srcwidth;
+ }
+
+ if(flag){
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(SecondPassColor != -1) {
+ h = H; /* Reset height */
+ fg = SecondPassColor;
+ SecondPassColor = -1;
+ firstFunc = secondFunc;
+ srcp = src;
+ goto SECOND_PASS;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+#ifndef FIXEDBASE
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAWriteBitmapScanlineColorExpand3)(
+#else
+EXPNAME(XAAWriteBitmapScanlineColorExpand)(
+#endif
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ unsigned char *srcp = src;
+ int SecondPassColor = -1;
+ int shift = 0, dwords, bufferNo;
+ BitmapScanlineProcPtr firstFunc;
+ BitmapScanlineProcPtr secondFunc;
+
+#ifdef TRIPLE_BITS
+ if((bg != -1) &&
+ ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)
+ || ((infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg != -1) &&
+ (infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)){
+#endif
+ if((rop == GXcopy) && infoRec->SetupForSolidFill) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ } else SecondPassColor = bg;
+ bg = -1;
+ }
+
+#ifdef TRIPLE_BITS
+ if(skipleft) {
+#else
+ if(skipleft &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X) && (skipleft > x)))) {
+#endif
+ if((skipleft + ((w + 31) & ~31)) > ((skipleft + w + 31) & ~31)) {
+ /* don't read past the end */
+ firstFunc = BitmapScanline_Shifted_Careful;
+ secondFunc = BitmapScanline_Shifted_Inverted_Careful;
+ } else {
+ firstFunc = BitmapScanline_Shifted;
+ secondFunc = BitmapScanline_Shifted_Inverted;
+ }
+ shift = skipleft;
+ skipleft = 0;
+ } else {
+ firstFunc = BitmapScanline;
+ secondFunc = BitmapScanline_Inverted;
+ w += skipleft;
+ x -= skipleft;
+ }
+
+#ifdef TRIPLE_BITS
+ dwords = (3 * w + 31) >> 5;
+#else
+ dwords = (w + 31) >> 5;
+#endif
+
+SECOND_PASS:
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*firstFunc)((CARD32*)srcp, base, dwords, shift);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ srcp += srcwidth;
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ if(SecondPassColor != -1) {
+ fg = SecondPassColor;
+ SecondPassColor = -1;
+ firstFunc = secondFunc;
+ srcp = src;
+ goto SECOND_PASS;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
diff --git a/hw/xfree86/xaa/xaaCpyArea.c b/hw/xfree86/xaa/xaaCpyArea.c
new file mode 100644
index 000000000..497c3e7a1
--- /dev/null
+++ b/hw/xfree86/xaa/xaaCpyArea.c
@@ -0,0 +1,385 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyArea.c,v 1.13 2001/02/19 22:19:49 mvojkovi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+/*
+ Written mostly by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+
+
+RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(pDstDrawable->type == DRAWABLE_WINDOW) {
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ } else {
+ if(infoRec->WritePixmap &&
+ ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) ||
+ ((pDstDrawable->bitsPerPixel == 24) &&
+ (pSrcDrawable->bitsPerPixel == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
+ CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoImageWrite, 0L));
+ }
+ } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ }
+ }
+
+ return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty));
+}
+
+
+void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int nbox, careful;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1) {
+ DEALLOCATE_LOCAL(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2) {
+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox,
+ xdir, ydir, pGC->alu, pGC->planemask);
+
+ if (pboxNew2) {
+ DEALLOCATE_LOCAL(pptNew2);
+ DEALLOCATE_LOCAL(pboxNew2);
+ }
+ if (pboxNew1) {
+ DEALLOCATE_LOCAL(pptNew1);
+ DEALLOCATE_LOCAL(pboxNew1);
+ }
+
+}
+
+void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int srcwidth;
+ unsigned char* psrcBase; /* start of image */
+ unsigned char* srcPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3;
+
+ psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr;
+ srcwidth = (int)((PixmapPtr)pSrc)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp);
+
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth,
+ pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+
+void
+XAADoImageRead(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int dstwidth;
+ unsigned char* pdstBase; /* start of image */
+ unsigned char* dstPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3; /* wouldn't get here unless both
+ src and dst have same bpp */
+
+ pdstBase = (unsigned char *)((PixmapPtr)pDst)->devPrivate.ptr;
+ dstwidth = (int)((PixmapPtr)pDst)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ dstPntr = pdstBase + (pbox->y1 * dstwidth) + (pbox->x1 * Bpp);
+
+ (*infoRec->ReadPixmap)(infoRec->pScrn, pptSrc->x, pptSrc->y,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, dstPntr, dstwidth,
+ pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+
+void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir,
+ int alu,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dirsetup;
+
+ if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS)
+ || (xdir == ydir)) &&
+ (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT)
+ || (xdir == 1))) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ xdir, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) {
+ /*
+ * This is the case of a chip that only supports xdir = 1,
+ * with ydir = 1 or ydir = -1, but we have xdir = -1.
+ */
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1)
+ /* No problem. Do a xdir = 1 blit instead. */
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ else
+ {
+ /*
+ * This is the difficult case. Needs striping into
+ * non-overlapping horizontal chunks.
+ */
+ int stripeWidth, w, fullStripes, extra, i;
+ stripeWidth = 16;
+ w = pbox->x2 - pbox->x1;
+ if (pbox->x1 - pptSrc->x < stripeWidth)
+ stripeWidth = pbox->x1 - pptSrc->x;
+ fullStripes = w / stripeWidth;
+ extra = w % stripeWidth;
+
+ /* First, take care of the little bit on the far right */
+ if (extra)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + fullStripes * stripeWidth, pptSrc->y,
+ pbox->x1 + fullStripes * stripeWidth, pbox->y1,
+ extra, pbox->y2 - pbox->y1);
+
+ /* Now, take care of the rest of the blit */
+ for (i = fullStripes - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + i * stripeWidth, pptSrc->y,
+ pbox->x1 + i * stripeWidth, pbox->y1,
+ stripeWidth, pbox->y2 - pbox->y1);
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ /*
+ * Now the case of a chip that only supports xdir = ydir = 1 or
+ * xdir = ydir = -1, but we have xdir != ydir.
+ */
+ dirsetup = 0; /* No direction set up yet. */
+ for (; nbox; pbox++, pptSrc++, nbox--) {
+ if (xdir == 1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = -1 blit instead. */
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else if (xdir == -1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = 1 blit instead. */
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else
+ if (xdir == 1) {
+ /*
+ * xdir = 1, ydir = -1.
+ * Perform line-by-line xdir = ydir = 1 blits, going up.
+ */
+ int i;
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ else {
+ /*
+ * xdir = -1, ydir = 1.
+ * Perform line-by-line xdir = ydir = -1 blits, going down.
+ */
+ int i;
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ for (i = 0; i < pbox->y2 - pbox->y1; i++)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ } /* next box */
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/hw/xfree86/xaa/xaaCpyPlane.c b/hw/xfree86/xaa/xaaCpyPlane.c
new file mode 100644
index 000000000..74dcdfd31
--- /dev/null
+++ b/hw/xfree86/xaa/xaaCpyPlane.c
@@ -0,0 +1,206 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyPlane.c,v 1.13 2001/10/01 13:44:15 eich Exp $ */
+
+/*
+ A CopyPlane function that handles bitmap->screen copies and
+ sends anything else to the Fallback.
+
+ Also, a PushPixels for solid fill styles.
+
+ Written by Mark Vojkovich (markv@valinux.com)
+
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr rgnDst,
+ DDXPointPtr pptSrc);
+static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr rgnDst,
+ DDXPointPtr pptSrc);
+
+
+static unsigned long TmpBitPlane;
+
+RegionPtr
+XAACopyPlaneColorExpansion(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ if((pSrc->type == DRAWABLE_PIXMAP) && !XAA_DEPTH_BUG(pGC)) {
+ if(pSrc->bitsPerPixel == 1) {
+ return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty,
+ XAACopyPlane1toNColorExpand, bitPlane));
+ } else if(bitPlane < (1 << pDst->depth)){
+ TmpBitPlane = bitPlane;
+ return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty,
+ XAACopyPlaneNtoNColorExpand, bitPlane));
+ }
+ }
+
+ return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane));
+}
+
+
+static void
+XAACopyPlane1toNColorExpand(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ RegionPtr rgnDst,
+ DDXPointPtr pptSrc )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pbox = REGION_RECTS(rgnDst);
+ int numrects = REGION_NUM_RECTS(rgnDst);
+ unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
+ int srcwidth = ((PixmapPtr)pSrc)->devKind;
+
+ while(numrects--) {
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2),
+ srcwidth, pptSrc->x & 31,
+ pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
+ pbox++; pptSrc++;
+ }
+}
+
+
+static void
+XAACopyPlaneNtoNColorExpand(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ RegionPtr rgnDst,
+ DDXPointPtr pptSrc
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pbox = REGION_RECTS(rgnDst);
+ int numrects = REGION_NUM_RECTS(rgnDst);
+ unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
+ unsigned char *data, *srcPtr, *dataPtr;
+ int srcwidth = ((PixmapPtr)pSrc)->devKind;
+ int pitch, width, height, h, i, index, offset;
+ int Bpp = pSrc->bitsPerPixel >> 3;
+ unsigned long mask = TmpBitPlane;
+
+ if(TmpBitPlane < 8) {
+ offset = 0;
+ } else if(TmpBitPlane < 16) {
+ offset = 1;
+ mask >>= 8;
+ } else if(TmpBitPlane < 24) {
+ offset = 2;
+ mask >>= 16;
+ } else {
+ offset = 3;
+ mask >>= 24;
+ }
+
+ if(IS_OFFSCREEN_PIXMAP(pSrc))
+ SYNC_CHECK(pSrc);
+
+ while(numrects--) {
+ width = pbox->x2 - pbox->x1;
+ h = height = pbox->y2 - pbox->y1;
+ pitch = BitmapBytePad(width);
+
+ if(!(data = xalloc(height * pitch)))
+ goto ALLOC_FAILED;
+
+ bzero(data, height * pitch);
+
+ dataPtr = data;
+ srcPtr = ((pptSrc->y) * srcwidth) + src +
+ ((pptSrc->x) * Bpp) + offset;
+
+ while(h--) {
+ for(i = index = 0; i < width; i++, index += Bpp) {
+ if(mask & srcPtr[index])
+ dataPtr[i >> 3] |= (1 << (i & 7));
+ }
+ dataPtr += pitch;
+ srcPtr += srcwidth;
+ }
+
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pbox->x1, pbox->y1, width, height, data, pitch, 0,
+ pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
+
+ xfree(data);
+
+ALLOC_FAILED:
+
+ pbox++; pptSrc++;
+ }
+}
+
+void
+XAAPushPixelsSolidColorExpansion(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy,
+ int xOrg, int yOrg )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
+ BoxPtr pbox, pClipBoxes;
+ int nboxes, srcx, srcy;
+ xRectangle TheRect;
+ unsigned char *src = pBitMap->devPrivate.ptr;
+ int srcwidth = pBitMap->devKind;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ TheRect.x = xOrg;
+ TheRect.y = yOrg;
+ TheRect.width = dx;
+ TheRect.height = dy;
+
+ if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
+ pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
+ if(!pClipBoxes) return;
+ } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
+
+ nboxes = XAAGetRectClipBoxes(pGC->pCompositeClip, pClipBoxes, 1, &TheRect);
+ pbox = pClipBoxes;
+
+ while(nboxes--) {
+ srcx = pbox->x1 - xOrg;
+ srcy = pbox->y1 - yOrg;
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ src + (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31,
+ pGC->fgPixel, -1, pGC->alu, pGC->planemask);
+ pbox++;
+ }
+
+ if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
+ xfree(pClipBoxes);
+}
+
diff --git a/hw/xfree86/xaa/xaaCpyWin.c b/hw/xfree86/xaa/xaaCpyWin.c
new file mode 100644
index 000000000..1c5ecf38e
--- /dev/null
+++ b/hw/xfree86/xaa/xaaCpyWin.c
@@ -0,0 +1,80 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaCpyWin.c,v 1.3 2003/02/17 16:08:29 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+/*
+ Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+*/
+
+void
+XAACopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc )
+{
+ DDXPointPtr pptSrc, ppt;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int dx, dy, nbox;
+ WindowPtr pwinRoot;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+
+ if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow);
+ return;
+ }
+
+ pwinRoot = WindowTable[pScreen->myNum];
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox ||
+ !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ while(nbox--) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ ppt++; pbox++;
+ }
+
+ infoRec->ScratchGC.planemask = ~0L;
+ infoRec->ScratchGC.alu = GXcopy;
+
+ XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+}
diff --git a/hw/xfree86/xaa/xaaDashLine.c b/hw/xfree86/xaa/xaaDashLine.c
new file mode 100644
index 000000000..212116ae4
--- /dev/null
+++ b/hw/xfree86/xaa/xaaDashLine.c
@@ -0,0 +1,329 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaDashLine.c,v 1.5 2002/09/18 18:14:59 martin Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+#ifdef POLYSEGMENT
+XAAPolySegmentDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+#else
+XAAPolyLinesDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit
+#endif
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+ BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
+ int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ int nbox;
+ BoxPtr pbox;
+#ifndef POLYSEGMENT
+ DDXPointPtr ppt;
+#endif
+ unsigned int oc1, oc2;
+ int dmin, dmaj, e, octant;
+ int x1, x2, y1, y2, tmp, len, offset;
+ int PatternLength, PatternOffset;
+
+ if(!nboxInit)
+ return;
+
+ if (infoRec->DashedLineFlags & LINE_LIMIT_COORDS) {
+ int minValX = infoRec->DashedLineLimits.x1;
+ int maxValX = infoRec->DashedLineLimits.x2;
+ int minValY = infoRec->DashedLineLimits.y1;
+ int maxValY = infoRec->DashedLineLimits.y2;
+#ifdef POLYSEGMENT
+ int n = nseg;
+ xSegment *s = pSeg;
+
+ while (n--)
+#else
+ int n = npt;
+ int xorgtmp = xorg;
+ int yorgtmp = yorg;
+
+ ppt = pptInit;
+ x2 = ppt->x + xorgtmp;
+ y2 = ppt->y + yorgtmp;
+ while (--n)
+#endif
+ {
+#ifdef POLYSEGMENT
+ x1 = s->x1 + xorg;
+ y1 = s->y1 + yorg;
+ x2 = s->x2 + xorg;
+ y2 = s->y2 + yorg;
+ s++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorgtmp = x1;
+ yorgtmp = y1;
+ }
+ x2 = ppt->x + xorgtmp;
+ y2 = ppt->y + yorgtmp;
+#endif
+ if (x1 > maxValX || x1 < minValX ||
+ x2 > maxValX || x2 < minValX ||
+ y1 > maxValY || y1 < minValY ||
+ y2 > maxValY || y2 < minValY) {
+#ifdef POLYSEGMENT
+ XAAFallbackOps.PolySegment(pDrawable, pGC, nseg, pSeg);
+#else
+ XAAFallbackOps.Polylines(pDrawable, pGC, mode, npt, pptInit);
+#endif
+ return;
+ }
+ }
+ }
+
+ PatternLength = pGCPriv->DashLength;
+ PatternOffset = pGC->dashOffset % PatternLength;
+
+ (*infoRec->SetupForDashedLine)(infoRec->pScrn, pGC->fgPixel,
+ (pGC->lineStyle == LineDoubleDash) ? pGC->bgPixel : -1,
+ pGC->alu, pGC->planemask, PatternLength, pGCPriv->DashPattern);
+
+
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+
+ if (infoRec->SubsequentDashedBresenhamLine) {
+ if((dmaj = x2 - x1) < 0) {
+ dmaj = -dmaj;
+ octant = XDECREASING;
+ } else octant = 0;
+
+ if((dmin = y2 - y1) < 0) {
+ dmin = -dmin;
+ octant |= YDECREASING;
+ }
+
+ if(dmin >= dmaj){
+ tmp = dmin; dmin = dmaj; dmaj = tmp;
+ octant |= YMAJOR;
+ }
+
+ e = -dmaj - ((bias >> octant) & 1);
+ len = dmaj;
+ dmin <<= 1;
+ dmaj <<= 1;
+ } else { /* Muffle compiler */
+ dmin = dmaj = e = octant = len = 0;
+ }
+
+ while(nbox--) {
+ oc1 = oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if (!(oc1 | oc2)) { /* uncliped */
+ if(infoRec->SubsequentDashedTwoPointLine) {
+ (*infoRec->SubsequentDashedTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST, PatternOffset);
+ } else {
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant, PatternOffset);
+ }
+ break;
+ } else if (oc1 & oc2) { /* completely clipped */
+ pbox++;
+ } else if (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE) {
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
+
+ if(infoRec->SubsequentDashedBresenhamLine) {
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant, PatternOffset);
+ } else {
+ (*infoRec->SubsequentDashedTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST, PatternOffset
+ );
+ }
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+ pbox++;
+ } else {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int err, adx, ady;
+
+ if(octant & YMAJOR) {
+ ady = dmaj >> 1;
+ adx = dmin >> 1;
+ } else {
+ ady = dmin >> 1;
+ adx = dmaj >> 1;
+ }
+
+ if (miZeroClipLine(pbox->x1, pbox->y1,
+ pbox->x2 - 1, pbox->y2 - 1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (octant & YMAJOR)
+ len = abs(new_y2 - new_y1);
+ else
+ len = abs(new_x2 - new_x1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ int abserr, clipdx, clipdy;
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+
+ if (octant & YMAJOR)
+ err = e + clipdy*dmin - clipdx*dmaj;
+ else
+ err = e + clipdx*dmin - clipdy*dmaj;
+ } else
+ err = e;
+
+#define range infoRec->DashedBresenhamLineErrorTermBits
+ abserr = abs(err);
+ while((abserr & range) ||
+ (dmaj & range) ||
+ (dmin & range)) {
+ dmin >>= 1;
+ dmaj >>= 1;
+ abserr >>= 1;
+ err /= 2;
+ }
+
+ if(octant & YMAJOR)
+ offset = abs(new_y1 - y1);
+ else
+ offset = abs(new_x1 - x1);
+
+ offset += PatternOffset;
+ offset %= PatternLength;
+
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, new_x1, new_y1,
+ dmaj, dmin, err, len, octant, offset);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+#ifndef POLYSEGMENT
+ len = abs(y2 - y1);
+ tmp = abs(x2 - x1);
+ PatternOffset += (len > tmp) ? len : tmp;
+ PatternOffset %= PatternLength;
+#endif
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--) {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) && (y2 < pbox->y2))
+ {
+ if(infoRec->SubsequentDashedTwoPointLine) {
+ (*infoRec->SubsequentDashedTwoPointLine)(
+ infoRec->pScrn, x2, y2, x2, y2, 0,
+ PatternOffset);
+ } else {
+ (*infoRec->SubsequentDashedBresenhamLine)(
+ infoRec->pScrn, x2, y2, 2, 0, -1,
+ 1, 0, PatternOffset);
+ }
+ break;
+ } else
+ pbox++;
+ }
+ }
+#endif
+
+ SET_SYNC_FLAG(infoRec);
+}
+
diff --git a/hw/xfree86/xaa/xaaFallback.c b/hw/xfree86/xaa/xaaFallback.c
new file mode 100644
index 000000000..01b4bb408
--- /dev/null
+++ b/hw/xfree86/xaa/xaaFallback.c
@@ -0,0 +1,352 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFallback.c,v 1.5 1999/05/30 03:03:31 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+
+
+static void
+XAAFillSpansFallback(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAASetSpansFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPutImageFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+XAACopyAreaFallback(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ RegionPtr ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ if((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrc) || IS_OFFSCREEN_PIXMAP(pDst)) {
+ SYNC_CHECK(pGC);
+ }
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static RegionPtr
+XAACopyPlaneFallback(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane )
+{
+ RegionPtr ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ if((pSrc->type == DRAWABLE_WINDOW) || (pDst->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrc) || IS_OFFSCREEN_PIXMAP(pDst)) {
+ SYNC_CHECK(pGC);
+ }
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAPolyPointFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolylinesFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolySegmentFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyRectangleFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyArcFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAFillPolygonFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillRectFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillArcFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static int
+XAAPolyText8Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ int ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ SYNC_CHECK(pGC);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+XAAPolyText16Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ int ret;
+
+ XAA_GC_OP_PROLOGUE(pGC);
+ SYNC_CHECK(pGC);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAImageText8Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAImageText16Fallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAImageGlyphBltFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyGlyphBltFallback(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPushPixelsFallback(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg )
+{
+ XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC);
+ SYNC_CHECK(pGC);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ XAA_GC_OP_EPILOGUE(pGC);
+}
+
+GCOps XAAFallbackOps = {
+ XAAFillSpansFallback, XAASetSpansFallback,
+ XAAPutImageFallback, XAACopyAreaFallback,
+ XAACopyPlaneFallback, XAAPolyPointFallback,
+ XAAPolylinesFallback, XAAPolySegmentFallback,
+ XAAPolyRectangleFallback, XAAPolyArcFallback,
+ XAAFillPolygonFallback, XAAPolyFillRectFallback,
+ XAAPolyFillArcFallback, XAAPolyText8Fallback,
+ XAAPolyText16Fallback, XAAImageText8Fallback,
+ XAAImageText16Fallback, XAAImageGlyphBltFallback,
+ XAAPolyGlyphBltFallback, XAAPushPixelsFallback,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
+
+
+
+
diff --git a/hw/xfree86/xaa/xaaFillArc.c b/hw/xfree86/xaa/xaaFillArc.c
new file mode 100644
index 000000000..352d8e084
--- /dev/null
+++ b/hw/xfree86/xaa/xaaFillArc.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright 1996 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillArc.c,v 1.4 1999/05/30 03:03:31 dawes Exp $ */
+
+/*
+ * Filled solid arcs, based on cfbfillarc.c.
+ *
+ * Fill arc using calls to low-level span fill. Because the math for
+ * each span can be done concurrently with the drawing of the span
+ * with a graphics coprocessor operation, this is faster than just
+ * using miPolyFillArc, which first calculates all the spans and then
+ * calls FillSpans.
+ *
+ * Clipped arcs are dispatched to FillSpans.
+ */
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "mifillarc.h"
+#include "mi.h"
+
+/*
+ * This is based on the integer-math versions from mi. Perhaps on a
+ * Pentium, the floating-point (double)-math version is faster.
+ */
+
+static void
+XAAFillEllipseSolid(DrawablePtr pDraw, GCPtr pGC, xArc *arc)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ register int x, y, e;
+ int yk, xk, ym, xm, dx, dy, xorg, yorg;
+ int slw;
+ miFillArcRec info;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ miFillArcSetup(arc, &info);
+ MIFILLARCSETUP();
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ }
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ if (slw > 0) {
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn, xorg - x,
+ yorg - y, slw, 1);
+ if (miFillArcLower(slw))
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ xorg - x, yorg + y + dy, slw, 1);
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+#define ADDSPAN(l,r) \
+ if (r >= l) \
+ (*infoRec->SubsequentSolidFillRect)( \
+ infoRec->pScrn, l, ya, r - l + 1, 1);
+
+#define ADDSLICESPANS(flip) \
+ if (!flip) \
+ { \
+ ADDSPAN(xl, xr); \
+ } \
+ else \
+ { \
+ xc = xorg - x; \
+ ADDSPAN(xc, xr); \
+ xc += slw - 1; \
+ ADDSPAN(xl, xc); \
+ }
+
+static void
+XAAFillArcSliceSolid(DrawablePtr pDraw, GCPtr pGC, xArc *arc)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
+ register int x, y, e;
+ miFillArcRec info;
+ miArcSliceRec slice;
+ int ya, xl, xr, xc;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ miFillArcSetup(arc, &info);
+ miFillArcSliceSetup(arc, &slice, pGC);
+ MIFILLARCSETUP();
+ slw = arc->height;
+ if (slice.flip_top || slice.flip_bot)
+ slw += (arc->height >> 1) + 1;
+ if (pGC->miTranslate)
+ {
+ xorg += pDraw->x;
+ yorg += pDraw->y;
+ slice.edge1.x += pDraw->x;
+ slice.edge2.x += pDraw->x;
+ }
+ while (y > 0)
+ {
+ MIFILLARCSTEP(slw);
+ MIARCSLICESTEP(slice.edge1);
+ MIARCSLICESTEP(slice.edge2);
+ if (miFillSliceUpper(slice))
+ {
+ ya = yorg - y;
+ MIARCSLICEUPPER(xl, xr, slice, slw);
+
+ ADDSLICESPANS(slice.flip_top);
+ }
+ if (miFillSliceLower(slice))
+ {
+ ya = yorg + y + dy;
+ MIARCSLICELOWER(xl, xr, slice, slw);
+ ADDSLICESPANS(slice.flip_bot);
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAPolyFillArcSolid(pDraw, pGC, narcs, parcs)
+ DrawablePtr pDraw;
+ GCPtr pGC;
+ int narcs;
+ xArc *parcs;
+{
+ register xArc *arc;
+ register int i;
+ int x2, y2;
+ BoxRec box;
+ RegionPtr cclip;
+
+ cclip = pGC->pCompositeClip;
+
+ if(!REGION_NUM_RECTS(cclip))
+ return;
+
+ for (arc = parcs, i = narcs; --i >= 0; arc++)
+ {
+ if (miFillArcEmpty(arc))
+ continue;
+ if (miCanFillArc(arc))
+ {
+ box.x1 = arc->x + pDraw->x;
+ box.y1 = arc->y + pDraw->y;
+ /*
+ * Because box.x2 and box.y2 get truncated to 16 bits, and the
+ * RECT_IN_REGION test treats the resulting number as a signed
+ * integer, the RECT_IN_REGION test alone can go the wrong way.
+ * This can result in a server crash because the rendering
+ * routines in this file deal directly with cpu addresses
+ * of pixels to be stored, and do not clip or otherwise check
+ * that all such addresses are within their respective pixmaps.
+ * So we only allow the RECT_IN_REGION test to be used for
+ * values that can be expressed correctly in a signed short.
+ */
+ x2 = box.x1 + (int)arc->width + 1;
+ box.x2 = x2;
+ y2 = box.y1 + (int)arc->height + 1;
+ box.y2 = y2;
+ if ( (x2 <= MAXSHORT) && (y2 <= MAXSHORT) &&
+ (RECT_IN_REGION(pDraw->pScreen, cclip, &box) == rgnIN) )
+ {
+ if ((arc->angle2 >= FULLCIRCLE) ||
+ (arc->angle2 <= -FULLCIRCLE))
+ XAAFillEllipseSolid(pDraw, pGC, arc);
+ else
+ XAAFillArcSliceSolid(pDraw, pGC, arc);
+ continue;
+ }
+ }
+ miPolyFillArc(pDraw, pGC, 1, arc);
+ }
+}
diff --git a/hw/xfree86/xaa/xaaFillPoly.c b/hw/xfree86/xaa/xaaFillPoly.c
new file mode 100644
index 000000000..164887afe
--- /dev/null
+++ b/hw/xfree86/xaa/xaaFillPoly.c
@@ -0,0 +1,956 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillPoly.c,v 1.15 2001/10/28 03:34:04 tsi Exp $ */
+
+/*
+ * Copyright 1996 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+/*
+ * Written by Mark Vojkovich. Loosly based on an original version
+ * written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net) which
+ * only did solid rectangles and didn't have trapezoid support.
+ *
+ */
+
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "micoord.h"
+
+#include "xaa.h"
+#include "xaalocal.h"
+
+#define POLY_USE_MI 0
+#define POLY_FULLY_CLIPPED 1
+#define POLY_IS_EASY 2
+
+
+#define Setup(c,x,vertex,dx,dy,e,sign,step,DX) {\
+ x = intToX(vertex); \
+ if ((dy = intToY(c) - y)) { \
+ DX = dx = intToX(c) - x; \
+ step = 0; \
+ if (dx >= 0) \
+ { \
+ e = 0; \
+ sign = 1; \
+ if (dx >= dy) {\
+ step = dx / dy; \
+ dx %= dy; \
+ } \
+ } \
+ else \
+ { \
+ e = 1 - dy; \
+ sign = -1; \
+ dx = -dx; \
+ if (dx >= dy) { \
+ step = - (dx / dy); \
+ dx %= dy; \
+ } \
+ } \
+ } \
+ x += origin; \
+ vertex = c; \
+}
+
+#define Step(x,dx,dy,e,sign,step) {\
+ x += step; \
+ if ((e += dx) > 0) \
+ { \
+ x += sign; \
+ e -= dy; \
+ } \
+}
+
+#define FixError(x, dx, dy, e, sign, step, h) { \
+ e += (h) * dx; \
+ x += (h) * step; \
+ if(e > 0) { \
+ x += e * sign/dy; \
+ e %= dy; \
+ if(e) { \
+ x += sign; \
+ e -= dy; \
+ } \
+ } \
+}
+
+
+/*
+ XAAIsEasyPoly -
+
+ Checks CoordModeOrigin one rect polygons to see if we need
+ to use Mi.
+ Returns: POLY_USE_MI, POLY_FULLY_CLIPPED or POLY_IS_EASY
+ as well as the pointer to the "top" point and the y
+ extents.
+*/
+
+int
+XAAIsEasyPolygon(
+ DDXPointPtr ptsIn,
+ int count,
+ BoxPtr extents,
+ int origin,
+ DDXPointPtr *topPoint, /* return */
+ int *topY, int *bottomY, /* return */
+ int shape
+){
+ int c = 0, vertex1, vertex2;
+
+ *topY = 32767;
+ *bottomY = 0;
+
+ origin -= (origin & 0x8000) << 1;
+ vertex1 = *((int *) &extents->x1) - origin;
+ vertex2 = *((int *) &extents->x2) - origin /* - 0x00010001 */;
+ /* I think this was an error in cfb ^ */
+
+ if (shape == Convex) {
+ while (count--) {
+ c = *((int*)ptsIn);
+ if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
+ return POLY_USE_MI;
+
+ c = intToY(c);
+ if (c < *topY) {
+ *topY = c;
+ *topPoint = ptsIn;
+ }
+ ptsIn++;
+ if (c > *bottomY) *bottomY = c;
+ }
+ } else {
+ int yFlip = 0;
+ int dx2, dx1, x1, x2;
+
+ x2 = x1 = -1;
+ dx2 = dx1 = 1;
+
+ while (count--) {
+ c = *((int*)ptsIn);
+ if (((c - vertex1) | (vertex2 - c)) & 0x80008000)
+ return POLY_USE_MI;
+ c = intToY(c);
+ if (c < *topY) {
+ *topY = c;
+ *topPoint = ptsIn;
+ }
+ ptsIn++;
+ if (c > *bottomY) *bottomY = c;
+ if (c == x1)
+ continue;
+ if (dx1 > 0) {
+ if (x2 < 0) x2 = c;
+ else dx2 = dx1 = (c - x1) >> 31;
+ } else if ((c - x1) >> 31 != dx1) {
+ dx1 = ~dx1;
+ yFlip++;
+ }
+ x1 = c;
+ }
+ x1 = (x2 - c) >> 31;
+ if (x1 != dx1) yFlip++;
+ if (x1 != dx2) yFlip++;
+ if (yFlip != 2) {
+ if(*topY == *bottomY)
+ return POLY_FULLY_CLIPPED;
+ else
+ return POLY_USE_MI;
+ }
+ }
+ if (*topY == *bottomY)
+ return POLY_FULLY_CLIPPED;
+
+ return POLY_IS_EASY;
+}
+
+void
+XAAFillPolygonSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int origin, vertex1, vertex2;
+ int *vertex1p, *vertex2p, *endp;
+ int x1 = 0, x2 = 0;
+ int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
+ int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
+ int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
+ int c, y, maxy, h, yoffset;
+ DDXPointPtr topPoint;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if (mode == CoordModePrevious) {
+ register DDXPointPtr ppt = ptsIn + 1;
+
+ for (origin = 1; origin < count; origin++, ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ mode = CoordModeOrigin;
+ }
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ origin = coordToInt(pDraw->x, pDraw->y);
+
+ switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
+ origin, &topPoint, &y, &maxy, shape) ) {
+ case POLY_USE_MI:
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ case POLY_FULLY_CLIPPED:
+ return;
+ }
+
+ endp = (int*)ptsIn + count;
+ vertex2p = vertex1p = (int *)topPoint;
+ origin = pDraw->x;
+ yoffset = pDraw->y;
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ while(1) {
+ if (y == intToY(vertex1)) {
+ do {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ } else {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2)) {
+ do {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ } else {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+
+ /* fill spans for this segment */
+ if(DX1 | DX2) {
+ if(infoRec->SubsequentSolidFillTrap && (h > 6)) {
+ if(x1 == x2) {
+ while(x1 == x2) {
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if(y == maxy) break;
+ if(!h) continue;
+ }
+
+ if(x1 < x2)
+ (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
+ y + yoffset, h,
+ x1, DX1, dy1, e1,
+ x2 - 1, DX2, dy2, e2);
+ else
+ (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn,
+ y + yoffset, h,
+ x2, DX2, dy2, e2,
+ x1 - 1, DX1, dy1, e1);
+ y += h;
+ if(--h) {
+ FixError(x1,dx1,dy1,e1,sign1,step1,h);
+ FixError(x2,dx2,dy2,e2,sign2,step2,h);
+ h = 0;
+ }
+ } else {
+ while(1) {
+ if (x2 > x1)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x1, y + yoffset, x2 - x1, 1);
+ else if (x1 > x2)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x2, y + yoffset, x1 - x2, 1);
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ }
+ } else {
+ if (x2 > x1)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x1, y + yoffset, x2 - x1, h);
+ else if (x1 > x2)
+ (*infoRec->SubsequentSolidFillRect)(infoRec->pScrn,
+ x2, y + yoffset, x1 - x2, h);
+
+ y += h;
+ h = 0;
+ }
+ if (y == maxy) break;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+void
+XAAFillPolygonHelper(
+ ScrnInfoPtr pScrn,
+ DDXPointPtr ptsIn,
+ int count,
+ DDXPointPtr topPoint,
+ int y,
+ int maxy,
+ int origin,
+ RectFuncPtr RectFunc,
+ TrapFuncPtr TrapFunc,
+ int xorg,
+ int yorg,
+ XAACacheInfoPtr pCache
+){
+ int *vertex1p, *vertex2p, *endp;
+ int vertex1, vertex2;
+ int x1 = 0, x2 = 0;
+ int dx1 = 0, dx2 = 0, dy1 = 0, dy2 = 0;
+ int DX1 = 0, DX2 = 0, e1 = 0, e2 = 0;
+ int step1 = 0, step2 = 0, sign1 = 0, sign2 = 0;
+ int c, h, yoffset;
+
+
+ endp = (int*)ptsIn + count;
+ vertex2p = vertex1p = (int *)topPoint;
+ yoffset = intToY(origin);
+ origin = intToX(origin);
+ vertex2 = vertex1 = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *)ptsIn;
+
+ while(1) {
+ if (y == intToY(vertex1)) {
+ do {
+ if (vertex1p == (int *) ptsIn)
+ vertex1p = endp;
+ c = *--vertex1p;
+ Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1,DX1)
+ } while (y >= intToY(vertex1));
+ h = dy1;
+ } else {
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ h = intToY(vertex1) - y;
+ }
+ if (y == intToY(vertex2)) {
+ do {
+ c = *vertex2p++;
+ if (vertex2p == endp)
+ vertex2p = (int *) ptsIn;
+ Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2,DX2)
+ } while (y >= intToY(vertex2));
+ if (dy2 < h)
+ h = dy2;
+ } else {
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ if ((c = (intToY(vertex2) - y)) < h)
+ h = c;
+ }
+
+ /* fill spans for this segment */
+ if(DX1 | DX2) {
+ if(TrapFunc && (h > 6)) {
+ if(x1 == x2) {
+ while(x1 == x2) {
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ if(y == maxy) break;
+ if(!h) continue;
+ }
+
+ if(x1 < x2)
+ (*TrapFunc)(pScrn, y + yoffset, h,
+ x1, DX1, dy1, e1,
+ x2 - 1, DX2, dy2, e2, xorg, yorg, pCache);
+ else
+ (*TrapFunc)(pScrn, y + yoffset, h,
+ x2, DX2, dy2, e2,
+ x1 - 1, DX1, dy1, e1, xorg, yorg, pCache);
+ y += h;
+ if(--h) {
+ FixError(x1,dx1,dy1,e1,sign1,step1,h);
+ FixError(x2,dx2,dy2,e2,sign2,step2,h);
+ h = 0;
+ }
+ } else {
+ while(1) {
+ if (x2 > x1)
+ (*RectFunc)(pScrn,
+ x1, y + yoffset, x2 - x1, 1, xorg, yorg, pCache);
+ else if (x1 > x2)
+ (*RectFunc)(pScrn,
+ x2, y + yoffset, x1 - x2, 1, xorg, yorg, pCache);
+ y++;
+ if (!--h) break;
+ Step(x1,dx1,dy1,e1,sign1,step1)
+ Step(x2,dx2,dy2,e2,sign2,step2)
+ }
+ }
+ } else {
+ if (x2 > x1)
+ (*RectFunc)(pScrn,
+ x1, y + yoffset, x2 - x1, h, xorg, yorg, pCache);
+ else if (x1 > x2)
+ (*RectFunc)(pScrn,
+ x2, y + yoffset, x1 - x2, h, xorg, yorg, pCache);
+
+ y += h;
+ h = 0;
+ }
+ if (y == maxy) break;
+ }
+}
+
+ /*****************\
+ | Solid Helpers |
+ \*****************/
+
+static void
+SolidTrapHelper(
+ ScrnInfoPtr pScrn,
+ int y, int h,
+ int x1, int dx1, int dy1, int e1,
+ int x2, int dx2, int dy2, int e2,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentSolidFillTrap) (pScrn,
+ y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
+}
+
+static void
+SolidRectHelper (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentSolidFillRect) (pScrn, x, y, w, h);
+}
+
+
+ /*********************\
+ | Mono 8x8 Patterns |
+ \*********************/
+
+static void
+Mono8x8PatternTrapHelper_ScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int y, int h,
+ int x1, int dx1, int dy1, int e1,
+ int x2, int dx2, int dy2, int e2,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentMono8x8PatternFillTrap) (pScrn, xorg, yorg,
+ y, h, x1, dx1, dy1, e1, x2, dx2, dy2, e2);
+}
+
+static void
+Mono8x8PatternRectHelper_ScreenOrigin (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
+ x, y, w, h);
+}
+
+static void
+Mono8x8PatternRectHelper (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ xorg = (x - xorg) & 0x07;
+ yorg = (y - yorg) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ int patx = pCache->pat0;
+ int paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ int slot = (yorg << 3) + xorg;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ }
+ }
+
+
+ (*infoRec->SubsequentMono8x8PatternFillRect) (pScrn, xorg, yorg,
+ x, y, w, h);
+}
+
+
+
+ /****************\
+ | Cache Expand |
+ \****************/
+
+
+static void
+CacheExpandRectHelper (
+ ScrnInfoPtr pScrn,
+ int X, int Y, int Width, int Height,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
+ int cacheWidth;
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ phaseY = (Y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (X - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+
+ while(1) {
+ w = Width; skipleft = phaseX; x = X;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > Height) blit_h = Height;
+
+ while(1) {
+ blit_w = cacheWidth - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, Y, blit_w, blit_h,
+ pCache->x, pCache->y + phaseY, skipleft);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ Height -= blit_h;
+ if(!Height) break;
+ Y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+}
+
+
+
+ /**************\
+ | Cache Blit |
+ \**************/
+
+
+static void
+CacheBltRectHelper (
+ ScrnInfoPtr pScrn,
+ int X, int Y, int Width, int Height,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, skipleft, w, blit_w, blit_h;
+
+ phaseY = (Y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (X - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+
+ while(1) {
+ w = Width; skipleft = phaseX; x = X;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > Height) blit_h = Height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, Y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ Height -= blit_h;
+ if(!Height) break;
+ Y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+}
+
+
+ /**********************\
+ | Stippled Polygons |
+ \**********************/
+
+
+void
+XAAFillPolygonStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ int origin, type, patx, paty, fg, bg;
+ int y, maxy, xorg, yorg;
+ DDXPointPtr topPoint;
+ XAACacheInfoPtr pCache = NULL;
+ RectFuncPtr RectFunc = NULL;
+ TrapFuncPtr TrapFunc = NULL;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if (mode == CoordModePrevious) {
+ register DDXPointPtr ppt = ptsIn + 1;
+
+ for (origin = 1; origin < count; origin++, ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ mode = CoordModeOrigin;
+ }
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+
+ if(pGC->fillStyle == FillStippled) {
+ type = (*infoRec->StippledFillChooser)(pGC);
+ fg = pGC->fgPixel; bg = -1;
+ } else {
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ }
+
+
+ if(!type) {
+ (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ if((type == DO_COLOR_EXPAND) || (type == DO_COLOR_8x8)) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ origin = *((int *)&pDraw->x);
+
+ switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
+ origin, &topPoint, &y, &maxy, shape) ) {
+ case POLY_USE_MI:
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ case POLY_FULLY_CLIPPED:
+ return;
+ }
+
+ xorg = (pDraw->x + pGC->patOrg.x);
+ yorg = (pDraw->y + pGC->patOrg.y);
+
+
+ if((fg == bg) && (bg != -1) && infoRec->SetupForSolidFill) {
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, fg,
+ pGC->alu, pGC->planemask);
+
+ RectFunc = SolidRectHelper;
+ TrapFunc = infoRec->SubsequentSolidFillTrap ? SolidTrapHelper : NULL;
+ } else
+ switch(type) {
+ case DO_MONO_8x8:
+ patx = pPriv->pattern0; paty = pPriv->pattern1;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_SCREEN_ORIGIN) {
+ xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+ RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
+ if(infoRec->SubsequentMono8x8PatternFillTrap)
+ TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
+ } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ }
+ RectFunc = Mono8x8PatternRectHelper;
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
+ patx, paty, fg, bg, pGC->alu, pGC->planemask);
+ break;
+ case DO_CACHE_EXPAND:
+ pCache = (*infoRec->CacheMonoStipple)(infoRec->pScrn, pGC->stipple);
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(
+ infoRec->pScrn, fg, bg, pGC->alu, pGC->planemask);
+
+ RectFunc = CacheExpandRectHelper;
+ break;
+ case DO_CACHE_BLT:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ fg, bg);
+ (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
+ pGC->alu, pGC->planemask, pCache->trans_color);
+
+ RectFunc = CacheBltRectHelper;
+ break;
+ default:
+ return;
+ }
+
+
+ XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
+ y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*******************\
+ | Tiled Polygons |
+ \*******************/
+
+
+void
+XAAFillPolygonTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ int origin, type, patx, paty;
+ int y, maxy, xorg, yorg;
+ DDXPointPtr topPoint;
+ XAACacheInfoPtr pCache = NULL;
+ RectFuncPtr RectFunc = NULL;
+ TrapFuncPtr TrapFunc = NULL;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if (mode == CoordModePrevious) {
+ register DDXPointPtr ppt = ptsIn + 1;
+
+ for (origin = 1; origin < count; origin++, ppt++) {
+ ppt->x += (ppt-1)->x;
+ ppt->y += (ppt-1)->y;
+ }
+ mode = CoordModeOrigin;
+ }
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+
+ type = (*infoRec->TiledFillChooser)(pGC);
+
+ if(!type || (type == DO_IMAGE_WRITE)) {
+ (*XAAFallbackOps.FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ if(type == DO_COLOR_8x8) {
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ return;
+ }
+
+ origin = *((int *)&pDraw->x);
+
+ switch( XAAIsEasyPolygon(ptsIn, count, &pGC->pCompositeClip->extents,
+ origin, &topPoint, &y, &maxy, shape) ) {
+ case POLY_USE_MI:
+ miFillPolygon (pDraw, pGC, shape, mode, count, ptsIn);
+ case POLY_FULLY_CLIPPED:
+ return;
+ }
+
+ xorg = (pDraw->x + pGC->patOrg.x);
+ yorg = (pDraw->y + pGC->patOrg.y);
+
+ switch(type) {
+ case DO_MONO_8x8:
+ patx = pPriv->pattern0; paty = pPriv->pattern1;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_SCREEN_ORIGIN) {
+ xorg = (-xorg) & 0x07; yorg = (-yorg) & 0x07;
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+ RectFunc = Mono8x8PatternRectHelper_ScreenOrigin;
+ if(infoRec->SubsequentMono8x8PatternFillTrap)
+ TrapFunc = Mono8x8PatternTrapHelper_ScreenOrigin;
+ } else { /* !HARDWARE_PATTERN_SCREEN_ORIGIN */
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(
+ infoRec->pScrn, patx, paty);
+ patx = pCache->x; paty = pCache->y;
+ }
+ else {
+ pCache = &(infoRec->ScratchCacheInfoRec);
+ pCache->pat0 = patx;
+ pCache->pat1 = paty;
+ }
+ RectFunc = Mono8x8PatternRectHelper;
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(infoRec->pScrn,
+ patx, paty, pPriv->fg, pPriv->bg, pGC->alu, pGC->planemask);
+ break;
+ case DO_CACHE_BLT:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
+ pGC->alu, pGC->planemask, -1);
+
+ RectFunc = CacheBltRectHelper;
+ break;
+ case DO_PIXMAP_COPY:
+ pCache = &(infoRec->ScratchCacheInfoRec);
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+
+ (*infoRec->SetupForScreenToScreenCopy)(infoRec->pScrn, 1, 1,
+ pGC->alu, pGC->planemask, -1);
+
+ RectFunc = CacheBltRectHelper;
+ break;
+ default:
+ return;
+ }
+
+ XAAFillPolygonHelper(infoRec->pScrn, ptsIn, count, topPoint,
+ y, maxy, origin, RectFunc, TrapFunc, xorg, yorg, pCache);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
diff --git a/hw/xfree86/xaa/xaaFillRect.c b/hw/xfree86/xaa/xaaFillRect.c
new file mode 100644
index 000000000..1d9cd54c1
--- /dev/null
+++ b/hw/xfree86/xaa/xaaFillRect.c
@@ -0,0 +1,1093 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaFillRect.c,v 1.15 2001/12/13 18:01:51 eich Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+static void XAARenderSolidRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderColor8x8Rects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderMono8x8Rects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderColorExpandRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderCacheExpandRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderCacheBltRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderImageWriteRects(GCPtr, int, BoxPtr, int, int);
+static void XAARenderPixmapCopyRects(GCPtr, int, BoxPtr, int, int);
+
+void
+XAAPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill, /* number of rectangles to fill */
+ xRectangle *prectInit /* Pointer to first rectangle to fill */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int xorg = pDraw->x;
+ int yorg = pDraw->y;
+ int type = 0;
+ ClipAndRenderRectsFunc function;
+
+ if((nrectFill <= 0) || !pGC->planemask)
+ return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ switch(pGC->fillStyle) {
+ case FillSolid:
+ type = DO_SOLID;
+ break;
+ case FillStippled:
+ type = (*infoRec->StippledFillChooser)(pGC);
+ break;
+ case FillOpaqueStippled:
+ if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSolidRects &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSolidRectsFlags) &&
+ CHECK_FG(pGC,infoRec->FillSolidRectsFlags))
+ type = DO_SOLID;
+ else
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ break;
+ case FillTiled:
+ type = (*infoRec->TiledFillChooser)(pGC);
+ break;
+ }
+
+ switch(type) {
+ case DO_SOLID:
+ function = XAARenderSolidRects;
+ break;
+ case DO_COLOR_8x8:
+ function = XAARenderColor8x8Rects;
+ break;
+ case DO_MONO_8x8:
+ function = XAARenderMono8x8Rects;
+ break;
+ case DO_CACHE_BLT:
+ function = XAARenderCacheBltRects;
+ break;
+ case DO_COLOR_EXPAND:
+ function = XAARenderColorExpandRects;
+ break;
+ case DO_CACHE_EXPAND:
+ function = XAARenderCacheExpandRects;
+ break;
+ case DO_IMAGE_WRITE:
+ function = XAARenderImageWriteRects;
+ break;
+ case DO_PIXMAP_COPY:
+ function = XAARenderPixmapCopyRects;
+ break;
+ default:
+ (*XAAFallbackOps.PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ return;
+ }
+
+ if(xorg | yorg) {
+ int n = nrectFill;
+ xRectangle *prect = prectInit;
+
+ while(n--) {
+ prect->x += xorg;
+ prect->y += yorg;
+ prect++;
+ }
+ }
+
+
+ XAAClipAndRenderRects(pGC, function, nrectFill, prectInit, xorg, yorg);
+}
+
+
+
+ /*********************\
+ | Solid Rects |
+ \*********************/
+
+static void
+XAARenderSolidRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillSolidRects) (infoRec->pScrn,
+ pGC->fgPixel, pGC->alu, pGC->planemask, nboxes, pClipBoxes);
+}
+
+
+ /************************\
+ | Mono 8x8 Rects |
+ \************************/
+
+static void
+XAARenderMono8x8Rects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ fg = pPriv->fg; bg = pPriv->bg;
+ break;
+ default: /* Muffle compiler */
+ pPriv = NULL; /* Kaboom */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillMono8x8PatternRects) (infoRec->pScrn,
+ fg, bg, pGC->alu, pGC->planemask,
+ nboxes, pClipBoxes, pPriv->pattern0, pPriv->pattern1,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+ /*************************\
+ | Color 8x8 Rects |
+ \*************************/
+
+static void
+XAARenderColor8x8Rects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+ PixmapPtr pPix;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPix = pGC->stipple;
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPix = pGC->stipple;
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPix = pGC->tile.pixmap;
+ fg = -1; bg = -1;
+ break;
+ default: /* Muffle compiler */
+ pPix = NULL;
+ fg = -1; bg = -1;
+ break;
+ }
+
+ pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);
+ (*infoRec->FillColor8x8PatternRects) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
+}
+
+
+ /****************************\
+ | Color Expand Rects |
+ \****************************/
+
+static void
+XAARenderColorExpandRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ default: /* Muffle compiler */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillColorExpandRects) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+ /*************************\
+ | Cache Blt Rects |
+ \*************************/
+
+static void
+XAARenderCacheBltRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, -1);
+ break;
+ case FillOpaqueStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, pGC->bgPixel);
+ break;
+ case FillTiled:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ break;
+ default: /* Muffle compiler */
+ pCache = NULL;
+ break;
+ }
+
+ (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y), pCache);
+}
+
+
+ /****************************\
+ | Cache Expand Rects |
+ \****************************/
+
+static void
+XAARenderCacheExpandRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ default: /* Muffle compiler */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillCacheExpandRects) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+
+ /***************************\
+ | Image Write Rects |
+ \***************************/
+
+static void
+XAARenderImageWriteRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->tile.pixmap);
+}
+
+
+
+ /***************************\
+ | Pixmap Copy Rects |
+ \***************************/
+
+static void
+XAARenderPixmapCopyRects(
+ GCPtr pGC,
+ int nboxes,
+ BoxPtr pClipBoxes,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+ pCache->trans_color = -1;
+
+ (*infoRec->FillCacheBltRects) (infoRec->pScrn, pGC->alu,
+ pGC->planemask, nboxes, pClipBoxes,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pCache);
+}
+
+
+
+ /************\
+ | Solid |
+ \************/
+
+void
+XAAFillSolidRects(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox, /* number of rectangles to fill */
+ BoxPtr pBox /* Pointer to first rectangle to fill */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+ while(nBox--) {
+ (*infoRec->SubsequentSolidFillRect)(pScrn, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*********************\
+ | 8x8 Mono Patterns |
+ \*********************/
+
+
+void
+XAAFillMono8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ while(nBox--) {
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAAFillMono8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg, yorg;
+ XAACacheInfoPtr pCache = NULL;
+
+
+ if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ }
+
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+
+ while(nBox--) {
+ xorg = (pBox->x1 - xorigin) & 0x07;
+ yorg = (pBox->y1 - yorigin) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ patx = pattern0; paty = pattern1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ int slot = (yorg << 3) + xorg;
+ xorg = patx + pCache->offsets[slot].x;
+ yorg = paty + pCache->offsets[slot].y;
+ }
+ }
+
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /**********************\
+ | 8x8 Color Patterns |
+ \**********************/
+
+
+void
+XAAFillColor8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pCache->x, paty = pCache->y;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ paty += pCache->offsets[slot].y;
+ patx += pCache->offsets[slot].x;
+ xorg = patx; yorg = paty;
+ }
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
+ rop, planemask, pCache->trans_color);
+
+ while(nBox--) {
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAAFillColor8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int xorg, yorg;
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
+ rop, planemask, pCache->trans_color);
+
+ while(nBox--) {
+ xorg = (pBox->x1 - xorigin) & 0x07;
+ yorg = (pBox->y1 - yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ }
+
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, pBox->y2 - pBox->y1);
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /***************\
+ | Cache Blits |
+ \***************/
+
+void
+XAAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
+ pCache->trans_color);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+
+#if 0
+ if (rop == GXcopy) {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ if(blit_w >= pCache->orig_w) break;
+ }
+
+ /* Expand horizontally */
+ if (w) {
+ skipleft -= phaseX;
+ if (skipleft < 0) skipleft += pCache->orig_w;
+ blit_w = x - pBox->x1 - skipleft;
+ while(w) {
+ if (blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pBox->x1 + skipleft, y, x, y, blit_w, blit_h);
+ w -= blit_w;
+ x += blit_w;
+ blit_w <<= 1;
+ }
+ }
+
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ if(blit_h >= pCache->orig_h) break;
+ }
+
+ /* Expand vertically */
+ if (height) {
+ blit_w = pBox->x2 - pBox->x1;
+ phaseY -= (pBox->y1 - yorg) % pCache->orig_h;
+ if (phaseY < 0) phaseY += pCache->orig_h;
+ blit_h = y - pBox->y1 - phaseY;
+ while(height) {
+ if (blit_h > height) blit_h = height;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pBox->x1,
+ pBox->y1 + phaseY, pBox->x1, y, blit_w, blit_h);
+ height -= blit_h;
+ y += blit_h;
+ blit_h <<= 1;
+ }
+ }
+ } else
+#endif
+ {
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = pCache->w - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + skipleft, pCache->y + phaseY,
+ x, y, blit_w, blit_h);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+ /*******************\
+ | Cache Expansion |
+ \*******************/
+
+
+
+void
+XAAFillCacheExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, y, phaseY, phaseX, skipleft, height, width, w, blit_w, blit_h;
+ int cacheWidth;
+ XAACacheInfoPtr pCache;
+
+ pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+
+ while(nBox--) {
+ y = pBox->y1;
+ phaseY = (y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+ phaseX = (pBox->x1 - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ height = pBox->y2 - y;
+ width = pBox->x2 - pBox->x1;
+
+ while(1) {
+ w = width; skipleft = phaseX; x = pBox->x1;
+ blit_h = pCache->h - phaseY;
+ if(blit_h > height) blit_h = height;
+
+ while(1) {
+ blit_w = cacheWidth - skipleft;
+ if(blit_w > w) blit_w = w;
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, y, blit_w, blit_h,
+ pCache->x, pCache->y + phaseY, skipleft);
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ skipleft = (skipleft + blit_w) % pCache->orig_w;
+ }
+ height -= blit_h;
+ if(!height) break;
+ y += blit_h;
+ phaseY = (phaseY + blit_h) % pCache->orig_h;
+ }
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /******************\
+ | Image Writes |
+ \******************/
+
+
+
+/* This requires all LEFT_EDGE clipping. You get too many problems
+ with reading past the edge of the pattern otherwise */
+
+static void
+WriteColumn(
+ ScrnInfoPtr pScrn,
+ unsigned char *pSrc,
+ int x, int y, int w, int h,
+ int xoff, int yoff,
+ int pHeight,
+ int srcwidth,
+ int Bpp
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ unsigned char *src;
+ Bool PlusOne = FALSE;
+ int skipleft, dwords;
+
+ pSrc += (Bpp * xoff);
+
+ if((skipleft = (long)pSrc & 0x03L)) {
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ pSrc -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ pSrc = (unsigned char*)((long)pSrc & ~0x03L);
+ }
+
+ src = pSrc + (yoff * srcwidth);
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(dwords > infoRec->ImageWriteRange) {
+ while(h--) {
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ yoff++;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ }
+ } else {
+ if(srcwidth == (dwords << 2)) {
+ int maxLines = infoRec->ImageWriteRange/dwords;
+ int step;
+
+ while(h) {
+ step = pHeight - yoff;
+ if(step > maxLines) step = maxLines;
+ if(step > h) step = h;
+
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * step);
+
+ src += (srcwidth * step);
+ yoff += step;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ h -= step;
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ yoff++;
+ if(yoff >= pHeight) {
+ yoff = 0;
+ src = pSrc;
+ }
+ }
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+}
+
+void
+XAAFillImageWriteRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, phaseY, phaseX, height, width, blit_w;
+ int pHeight = pPix->drawable.height;
+ int pWidth = pPix->drawable.width;
+ int Bpp = pPix->drawable.bitsPerPixel >> 3;
+ int srcwidth = pPix->devKind;
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, -1,
+ pPix->drawable.bitsPerPixel, pPix->drawable.depth);
+
+ while(nBox--) {
+ x = pBox->x1;
+ phaseY = (pBox->y1 - yorg) % pHeight;
+ if(phaseY < 0) phaseY += pHeight;
+ phaseX = (x - xorg) % pWidth;
+ if(phaseX < 0) phaseX += pWidth;
+ height = pBox->y2 - pBox->y1;
+ width = pBox->x2 - x;
+
+ while(1) {
+ blit_w = pWidth - phaseX;
+ if(blit_w > width) blit_w = width;
+
+ WriteColumn(pScrn, pPix->devPrivate.ptr, x, pBox->y1,
+ blit_w, height, phaseX, phaseY, pHeight, srcwidth, Bpp);
+
+ width -= blit_w;
+ if(!width) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pWidth;
+ }
+ pBox++;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+ /*************\
+ | Utilities |
+ \*************/
+
+
+void
+XAAClipAndRenderRects(
+ GCPtr pGC,
+ ClipAndRenderRectsFunc BoxFunc,
+ int nrectFill,
+ xRectangle *prect,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Right, Bottom, MaxBoxes;
+ BoxPtr pextent, pboxClipped, pboxClippedBase;
+
+ MaxBoxes = infoRec->PreAllocSize/sizeof(BoxRec);
+ pboxClippedBase = (BoxPtr)infoRec->PreAllocMem;
+ pboxClipped = pboxClippedBase;
+
+ if (REGION_NUM_RECTS(pGC->pCompositeClip) == 1) {
+ pextent = REGION_RECTS(pGC->pCompositeClip);
+ while (nrectFill--) {
+ pboxClipped->x1 = max(pextent->x1, prect->x);
+ pboxClipped->y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ pboxClipped->x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ pboxClipped->y2 = min(pextent->y2, Bottom);
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
+ (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
+ pboxClipped = pboxClippedBase;
+ }
+ }
+ }
+ } else {
+ pextent = REGION_EXTENTS(pGC->pScreen, pGC->pCompositeClip);
+ while (nrectFill--) {
+ int n;
+ BoxRec box, *pbox;
+
+ box.x1 = max(pextent->x1, prect->x);
+ box.y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ box.x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ box.y2 = min(pextent->y2, Bottom);
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (pGC->pCompositeClip);
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2) {
+ pboxClipped++;
+ if(pboxClipped >= (pboxClippedBase + MaxBoxes)) {
+ (*BoxFunc)(pGC, MaxBoxes, pboxClippedBase, xorg, yorg);
+ pboxClipped = pboxClippedBase;
+ }
+ }
+ }
+ }
+ }
+
+ if(pboxClipped != pboxClippedBase)
+ (*BoxFunc)(pGC, pboxClipped - pboxClippedBase, pboxClippedBase,
+ xorg, yorg);
+}
+
+
+int
+XAAGetRectClipBoxes(
+ RegionPtr prgnClip,
+ BoxPtr pboxClippedBase,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ int Right, Bottom;
+ BoxPtr pextent, pboxClipped = pboxClippedBase;
+ xRectangle *prect = prectInit;
+
+
+ if (REGION_NUM_RECTS(prgnClip) == 1) {
+ pextent = REGION_RECTS(prgnClip);
+ while (nrectFill--) {
+ pboxClipped->x1 = max(pextent->x1, prect->x);
+ pboxClipped->y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ pboxClipped->x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ pboxClipped->y2 = min(pextent->y2, Bottom);
+
+ prect++;
+ if ((pboxClipped->x1 < pboxClipped->x2) &&
+ (pboxClipped->y1 < pboxClipped->y2)) {
+ pboxClipped++;
+ }
+ }
+ } else {
+ pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
+ while (nrectFill--) {
+ int n;
+ BoxRec box, *pbox;
+
+ box.x1 = max(pextent->x1, prect->x);
+ box.y1 = max(pextent->y1, prect->y);
+
+ Right = (int)prect->x + (int)prect->width;
+ box.x2 = min(pextent->x2, Right);
+
+ Bottom = (int)prect->y + (int)prect->height;
+ box.y2 = min(pextent->y2, Bottom);
+
+ prect++;
+
+ if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
+ continue;
+
+ n = REGION_NUM_RECTS (prgnClip);
+ pbox = REGION_RECTS(prgnClip);
+
+ /* clip the rectangle to each box in the clip region
+ this is logically equivalent to calling Intersect()
+ */
+ while(n--) {
+ pboxClipped->x1 = max(box.x1, pbox->x1);
+ pboxClipped->y1 = max(box.y1, pbox->y1);
+ pboxClipped->x2 = min(box.x2, pbox->x2);
+ pboxClipped->y2 = min(box.y2, pbox->y2);
+ pbox++;
+
+ /* see if clipping left anything */
+ if(pboxClipped->x1 < pboxClipped->x2 &&
+ pboxClipped->y1 < pboxClipped->y2) {
+ pboxClipped++;
+ }
+ }
+ }
+ }
+
+ return(pboxClipped - pboxClippedBase);
+}
+
diff --git a/hw/xfree86/xaa/xaaGC.c b/hw/xfree86/xaa/xaaGC.c
new file mode 100644
index 000000000..c9ef93a1b
--- /dev/null
+++ b/hw/xfree86/xaa/xaaGC.c
@@ -0,0 +1,653 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaGC.c,v 1.19 2001/02/19 22:19:50 mvojkovi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+static void XAAValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
+static void XAAChangeGC(GCPtr pGC, unsigned long mask);
+static void XAACopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void XAADestroyGC(GCPtr pGC);
+static void XAAChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+static void XAADestroyClip(GCPtr pGC);
+static void XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+GCFuncs XAAGCFuncs = {
+ XAAValidateGC, XAAChangeGC, XAACopyGC, XAADestroyGC,
+ XAAChangeClip, XAADestroyClip, XAACopyClip
+};
+
+extern GCOps XAAPixmapOps;
+
+Bool
+XAACreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);
+ Bool ret;
+
+ XAA_SCREEN_PROLOGUE(pScreen,CreateGC);
+
+ if((ret = (*pScreen->CreateGC)(pGC))) {
+ pGCPriv->wrapOps = NULL;
+ pGCPriv->wrapFuncs = pGC->funcs;
+ pGCPriv->XAAOps = &XAAFallbackOps;
+ pGCPriv->flags = 0;
+ pGCPriv->DashLength = 0;
+ pGCPriv->DashPattern = NULL;
+ pGCPriv->changes = 0;
+ /* initialize any other private fields here */
+ pGC->funcs = &XAAGCFuncs;
+ }
+
+ XAA_SCREEN_EPILOGUE(pScreen,CreateGC,XAACreateGC);
+
+ return ret;
+}
+
+
+static void
+XAAValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAA_GC_FUNC_PROLOGUE(pGC);
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+
+ if((changes & GCPlaneMask) &&
+ ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) ==
+ infoRec->FullPlanemasks[pGC->depth - 1]))
+ {
+ pGC->planemask = ~0;
+ }
+
+ if(pGC->depth != 32) {
+ if(pGC->bgPixel == -1) /* -1 is reserved for transparency */
+ pGC->bgPixel = 0x7fffffff;
+ if(pGC->fgPixel == -1) /* -1 is reserved for transparency */
+ pGC->fgPixel = 0x7fffffff;
+ }
+
+ if((pDraw->type == DRAWABLE_PIXMAP) && !IS_OFFSCREEN_PIXMAP(pDraw)){
+ pGCPriv->flags = OPS_ARE_PIXMAP;
+ pGCPriv->changes |= changes;
+
+ /* make sure we're not using videomemory pixmaps to render
+ onto system memory drawables */
+
+ if((pGC->fillStyle == FillTiled) &&
+ IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
+ !OFFSCREEN_PIXMAP_LOCKED(pGC->tile.pixmap)) {
+
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ FBAreaPtr area = pPriv->offscreenArea;
+
+ XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
+ xf86FreeOffscreenArea(area);
+ }
+ }
+ else if(!infoRec->pScrn->vtSema && (pDraw->type == DRAWABLE_WINDOW)) {
+ pGCPriv->flags = 0;
+ pGCPriv->changes |= changes;
+ }
+ else {
+ if(!(pGCPriv->flags & OPS_ARE_ACCEL)) {
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = 0;
+ }
+ pGCPriv->flags = OPS_ARE_ACCEL;
+
+#if 1
+ /* Ugh. If we can't use the blitter on offscreen pixmaps used
+ as tiles, then we need to move them out as cfb can't handle
+ tiles with non-zero origins */
+
+ if((pGC->fillStyle == FillTiled) &&
+ IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
+ (DO_PIXMAP_COPY != (*infoRec->TiledFillChooser)(pGC))) {
+
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ FBAreaPtr area = pPriv->offscreenArea;
+
+ XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
+ xf86FreeOffscreenArea(area);
+ }
+#endif
+ }
+
+ XAA_GC_FUNC_EPILOGUE(pGC);
+
+ if(!(pGCPriv->flags & OPS_ARE_ACCEL)) return;
+
+ if((changes & GCTile) && !pGC->tileIsPixel && pGC->tile.pixmap){
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ if(pixPriv->flags & DIRTY) {
+ pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pGC->tile.pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+ if((changes & GCStipple) && pGC->stipple){
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+
+ if(pixPriv->flags & DIRTY) {
+ pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pGC->stipple->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+
+ /* If our Ops are still the default ones we need to allocate new ones */
+ if(pGC->ops == &XAAFallbackOps) {
+ if(!(pGCPriv->XAAOps = xalloc(sizeof(GCOps)))) {
+ pGCPriv->XAAOps = &XAAFallbackOps;
+ return;
+ }
+ /* make a modifiable copy of the default ops */
+ memcpy(pGCPriv->XAAOps, &XAAFallbackOps, sizeof(GCOps));
+ pGC->ops = pGCPriv->XAAOps;
+ changes = ~0;
+ }
+
+ if(!changes) return;
+
+ if((changes & GCDashList) && infoRec->ComputeDash)
+ infoRec->ComputeDash(pGC);
+
+ if(changes & infoRec->FillSpansMask)
+ (*infoRec->ValidateFillSpans)(pGC, changes, pDraw);
+
+ if(changes & infoRec->SetSpansMask)
+ (*infoRec->ValidateSetSpans)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PutImageMask)
+ (*infoRec->ValidatePutImage)(pGC, changes, pDraw);
+
+ if(changes & infoRec->CopyAreaMask)
+ (*infoRec->ValidateCopyArea)(pGC, changes, pDraw);
+
+ if(changes & infoRec->CopyPlaneMask)
+ (*infoRec->ValidateCopyPlane)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyPointMask)
+ (*infoRec->ValidatePolyPoint)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolylinesMask)
+ (*infoRec->ValidatePolylines)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolySegmentMask)
+ (*infoRec->ValidatePolySegment)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyRectangleMask)
+ (*infoRec->ValidatePolyRectangle)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyArcMask)
+ (*infoRec->ValidatePolyArc)(pGC, changes, pDraw);
+
+ if(changes & infoRec->FillPolygonMask)
+ (*infoRec->ValidateFillPolygon)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyFillRectMask)
+ (*infoRec->ValidatePolyFillRect)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyFillArcMask)
+ (*infoRec->ValidatePolyFillArc)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyGlyphBltMask)
+ (*infoRec->ValidatePolyGlyphBlt)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageGlyphBltMask)
+ (*infoRec->ValidateImageGlyphBlt)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyText8Mask)
+ (*infoRec->ValidatePolyText8)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyText16Mask)
+ (*infoRec->ValidatePolyText16)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageText8Mask)
+ (*infoRec->ValidateImageText8)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageText16Mask)
+ (*infoRec->ValidateImageText16)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PushPixelsMask)
+ (*infoRec->ValidatePushPixels)(pGC, changes, pDraw);
+}
+
+
+static void
+XAADestroyGC(GCPtr pGC)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+
+ if(pGCPriv->XAAOps != &XAAFallbackOps)
+ xfree(pGCPriv->XAAOps);
+
+ if(pGCPriv->DashPattern)
+ xfree(pGCPriv->DashPattern);
+
+ (*pGC->funcs->DestroyGC)(pGC);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XAAChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+
+ /* we have to assume that shared memory pixmaps are dirty
+ because we can't wrap all operations on them */
+
+ if((mask & GCTile) && !pGC->tileIsPixel &&
+ PIXMAP_IS_SHARED(pGC->tile.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+
+ if((mask & GCStipple) && PIXMAP_IS_SHARED(pGC->stipple)){
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ pPixPriv->flags |= DIRTY;
+ }
+}
+
+static void
+XAACopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ XAA_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ XAA_GC_FUNC_EPILOGUE (pGCDst);
+}
+static void
+XAAChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects )
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ XAA_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ XAA_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+XAADestroyClip(GCPtr pGC)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+/**** Pixmap Wrappers ****/
+
+
+
+static void
+XAAFillSpansPixmap(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAASetSpansPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPutImagePixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+XAACopyAreaPixmap(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ RegionPtr ret;
+
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc)))
+ {
+ if(infoRec->ReadPixmap && (pGC->alu == GXcopy) &&
+ (pSrc->bitsPerPixel == pDst->bitsPerPixel) &&
+ ((pGC->planemask & infoRec->FullPlanemasks[pSrc->depth - 1])
+ == infoRec->FullPlanemasks[pSrc->depth - 1]))
+ {
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst));
+ pixPriv->flags |= DIRTY;
+
+ return (XAABitBlt( pSrc, pDst, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+ XAADoImageRead, 0L));
+ } else
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ {
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ }
+ return ret;
+}
+
+static RegionPtr
+XAACopyPlanePixmap(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ RegionPtr ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
+
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))){
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAPolyPointPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolylinesPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolySegmentPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyRectanglePixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyArcPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAFillPolygonPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillRectPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillArcPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static int
+XAAPolyText8Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+XAAPolyText16Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAImageText8Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+static void
+XAAImageText16Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAImageGlyphBltPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyGlyphBltPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPushPixelsPixmap(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+GCOps XAAPixmapOps = {
+ XAAFillSpansPixmap, XAASetSpansPixmap,
+ XAAPutImagePixmap, XAACopyAreaPixmap,
+ XAACopyPlanePixmap, XAAPolyPointPixmap,
+ XAAPolylinesPixmap, XAAPolySegmentPixmap,
+ XAAPolyRectanglePixmap, XAAPolyArcPixmap,
+ XAAFillPolygonPixmap, XAAPolyFillRectPixmap,
+ XAAPolyFillArcPixmap, XAAPolyText8Pixmap,
+ XAAPolyText16Pixmap, XAAImageText8Pixmap,
+ XAAImageText16Pixmap, XAAImageGlyphBltPixmap,
+ XAAPolyGlyphBltPixmap, XAAPushPixelsPixmap,
+#ifdef NEED_LINEHELPER
+ NULL,
+#endif
+ {NULL} /* devPrivate */
+};
diff --git a/hw/xfree86/xaa/xaaGCmisc.c b/hw/xfree86/xaa/xaaGCmisc.c
new file mode 100644
index 000000000..ab6cb9a24
--- /dev/null
+++ b/hw/xfree86/xaa/xaaGCmisc.c
@@ -0,0 +1,426 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaGCmisc.c,v 1.15 2000/09/25 23:56:14 mvojkovi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "fontstruct.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "mi.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+void
+XAAValidateCopyArea(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->CopyArea &&
+ CHECK_PLANEMASK(pGC,infoRec->CopyAreaFlags) &&
+ CHECK_ROP(pGC,infoRec->CopyAreaFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->CopyAreaFlags)
+ )
+ pGC->ops->CopyArea = infoRec->CopyArea;
+ else
+ pGC->ops->CopyArea = XAAFallbackOps.CopyArea;
+}
+
+void
+XAAValidatePutImage(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->PutImage &&
+ CHECK_PLANEMASK(pGC,infoRec->PutImageFlags) &&
+ CHECK_ROP(pGC,infoRec->PutImageFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PutImageFlags) &&
+ CHECK_COLORS(pGC,infoRec->PutImageFlags)
+ )
+ pGC->ops->PutImage = infoRec->PutImage;
+ else
+ pGC->ops->PutImage = XAAFallbackOps.PutImage;
+}
+
+void
+XAAValidateCopyPlane(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->CopyPlane &&
+ CHECK_PLANEMASK(pGC,infoRec->CopyPlaneFlags) &&
+ CHECK_ROP(pGC,infoRec->CopyPlaneFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->CopyPlaneFlags) &&
+ CHECK_COLORS(pGC,infoRec->CopyPlaneFlags)
+ )
+ pGC->ops->CopyPlane = infoRec->CopyPlane;
+ else
+ pGC->ops->CopyPlane = XAAFallbackOps.CopyPlane;
+}
+
+void
+XAAValidatePushPixels(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(infoRec->PushPixelsSolid &&
+ (pGC->fillStyle == FillSolid) &&
+ CHECK_PLANEMASK(pGC,infoRec->PushPixelsFlags) &&
+ CHECK_ROP(pGC,infoRec->PushPixelsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PushPixelsFlags) &&
+ CHECK_FG(pGC,infoRec->PushPixelsFlags) &&
+ (!(infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY) ||
+ (pGC->alu == GXcopy))
+ )
+ pGC->ops->PushPixels = infoRec->PushPixelsSolid;
+ else
+ pGC->ops->PushPixels = XAAFallbackOps.PushPixels;
+
+}
+
+
+/* We make the assumption that the FillSpans, PolyFillRect, FillPolygon
+ and PolyFillArc functions are linked in a way that they all have
+ the same rop/color/planemask restrictions. If the driver provides
+ a GC level replacement for these, it will need to supply a new
+ Validate functions if it breaks this assumption */
+
+
+void
+XAAValidateFillSpans(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(pGC->fillStyle != FillTiled) changes &= ~GCTile;
+ if((pGC->fillStyle == FillTiled) || (pGC->fillStyle == FillSolid))
+ changes &= ~GCStipple;
+ if(!changes) return;
+
+
+ pGC->ops->FillSpans = XAAFallbackOps.FillSpans;
+ pGC->ops->PolyFillRect = XAAFallbackOps.PolyFillRect;
+ pGC->ops->FillPolygon = XAAFallbackOps.FillPolygon;
+ pGC->ops->PolyFillArc = XAAFallbackOps.PolyFillArc;
+
+ switch(pGC->fillStyle){
+ case FillSolid:
+ if(infoRec->FillSpansSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_FG(pGC,infoRec->FillSpansSolidFlags)
+ ) {
+ pGC->ops->FillSpans = infoRec->FillSpansSolid;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectSolid;
+ pGC->ops->FillPolygon = infoRec->FillPolygonSolid;
+ pGC->ops->PolyFillArc = infoRec->PolyFillArcSolid;
+ }
+ break;
+ /* The [Stippled/OpaqueStippled/Tiled]FillChooser
+ functions do the validating */
+ case FillStippled:
+ if(infoRec->FillSpansStippled) {
+ pGC->ops->FillSpans = infoRec->FillSpansStippled;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectStippled;
+ if(infoRec->FillPolygonStippled)
+ pGC->ops->FillPolygon = infoRec->FillPolygonStippled;
+ else pGC->ops->FillPolygon = miFillPolygon;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ }
+ break;
+ case FillOpaqueStippled:
+ if(infoRec->FillSpansOpaqueStippled) {
+ pGC->ops->FillSpans = infoRec->FillSpansOpaqueStippled;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectOpaqueStippled;
+ if(infoRec->FillPolygonOpaqueStippled)
+ pGC->ops->FillPolygon = infoRec->FillPolygonOpaqueStippled;
+ else pGC->ops->FillPolygon = miFillPolygon;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ }
+ break;
+ case FillTiled:
+ if(infoRec->FillSpansTiled) {
+ pGC->ops->FillSpans = infoRec->FillSpansTiled;
+ pGC->ops->PolyFillRect = infoRec->PolyFillRectTiled;
+ if(infoRec->FillPolygonTiled)
+ pGC->ops->FillPolygon = infoRec->FillPolygonTiled;
+ else pGC->ops->FillPolygon = miFillPolygon;
+ pGC->ops->PolyFillArc = miPolyFillArc;
+ }
+ break;
+ default: return;
+ }
+}
+
+
+/* We make the assumption that these Text8/16 and GlyphBlt functions
+ are linked in a way that they all have the same rop/color/planemask
+ restrictions. If the driver provides a GC level replacement for
+ these, it will need to supply a new Validate functions if it breaks
+ this assumption */
+
+void
+XAAValidatePolyGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool BigFont = FALSE;
+
+ pGC->ops->PolyText8 = XAAFallbackOps.PolyText8;
+ pGC->ops->PolyText16 = XAAFallbackOps.PolyText16;
+ pGC->ops->PolyGlyphBlt = XAAFallbackOps.PolyGlyphBlt;
+
+ if(!pGC->font) return;
+ if(pGC->fillStyle != FillSolid) return;
+
+ if((FONTMAXBOUNDS(pGC->font, rightSideBearing) -
+ FONTMINBOUNDS(pGC->font, leftSideBearing) > 32))
+ BigFont = TRUE;
+
+ /* no funny business */
+ if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) ||
+ ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0))
+ return;
+
+ /* Check for TE Fonts */
+ if(!TERMINALFONT(pGC->font) || BigFont) {
+ if(infoRec->PolyGlyphBltNonTE &&
+ CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_ROP(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_FG(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ (!(infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY) ||
+ (pGC->alu == GXcopy))
+ ) {
+ pGC->ops->PolyText8 = infoRec->PolyText8NonTE;
+ pGC->ops->PolyText16 = infoRec->PolyText16NonTE;
+ pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltNonTE;
+ }
+ } else {
+ if(infoRec->PolyGlyphBltTE &&
+ CHECK_PLANEMASK(pGC,infoRec->PolyGlyphBltTEFlags) &&
+ CHECK_ROP(pGC,infoRec->PolyGlyphBltTEFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolyGlyphBltNonTEFlags) &&
+ CHECK_FG(pGC,infoRec->PolyGlyphBltTEFlags) &&
+ (!(infoRec->PolyGlyphBltTEFlags & TRANSPARENCY_GXCOPY_ONLY) ||
+ (pGC->alu == GXcopy))
+ ) {
+ pGC->ops->PolyText8 = infoRec->PolyText8TE;
+ pGC->ops->PolyText16 = infoRec->PolyText16TE;
+ pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltTE;
+ }
+ }
+}
+
+void
+XAAValidateImageGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool BigFont = FALSE;
+
+ pGC->ops->ImageText8 = XAAFallbackOps.ImageText8;
+ pGC->ops->ImageText16 = XAAFallbackOps.ImageText16;
+ pGC->ops->ImageGlyphBlt = XAAFallbackOps.ImageGlyphBlt;
+
+ if(!pGC->font) return;
+
+ if((FONTMAXBOUNDS(pGC->font, rightSideBearing) -
+ FONTMINBOUNDS(pGC->font, leftSideBearing) > 32))
+ BigFont = TRUE;
+
+ /* no funny business */
+ if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) ||
+ ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0))
+ return;
+
+
+ /* Check for TE Fonts */
+ if(!TERMINALFONT(pGC->font) || BigFont || (pGC->depth == 32)) {
+ if(infoRec->ImageGlyphBltNonTE &&
+ CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltNonTEFlags) &&
+ CHECK_FG(pGC,infoRec->ImageGlyphBltNonTEFlags) &&
+ infoRec->SetupForSolidFill &&
+ CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) &&
+ CHECK_BG(pGC,infoRec->SolidFillFlags))
+ {
+ pGC->ops->ImageText8 = infoRec->ImageText8NonTE;
+ pGC->ops->ImageText16 = infoRec->ImageText16NonTE;
+ pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltNonTE;
+ }
+ } else if(infoRec->ImageGlyphBltTE &&
+ CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltTEFlags)){
+ if(!(infoRec->ImageGlyphBltTEFlags & TRANSPARENCY_ONLY) &&
+ CHECK_COLORS(pGC,infoRec->ImageGlyphBltTEFlags))
+ {
+ pGC->ops->ImageText8 = infoRec->ImageText8TE;
+ pGC->ops->ImageText16 = infoRec->ImageText16TE;
+ pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE;
+ } else {
+ if(CHECK_FG(pGC,infoRec->ImageGlyphBltTEFlags) &&
+ infoRec->SetupForSolidFill &&
+ CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) &&
+ CHECK_BG(pGC,infoRec->SolidFillFlags))
+ {
+ pGC->ops->ImageText8 = infoRec->ImageText8TE;
+ pGC->ops->ImageText16 = infoRec->ImageText16TE;
+ pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE;
+ }
+ }
+ }
+}
+
+
+void
+XAAValidatePolylines(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+
+ if(pGC->lineStyle == LineSolid) changes &= ~GCDashList;
+ if(!changes) return;
+
+ pGC->ops->PolySegment = XAAFallbackOps.PolySegment;
+ pGC->ops->Polylines = XAAFallbackOps.Polylines;
+ pGC->ops->PolyRectangle = XAAFallbackOps.PolyRectangle;
+ pGC->ops->PolyArc = XAAFallbackOps.PolyArc;
+
+ if((pGC->ops->FillSpans != XAAFallbackOps.FillSpans) &&
+ (pGC->lineWidth > 0)){
+
+ pGC->ops->PolyArc = miPolyArc;
+ pGC->ops->PolySegment = miPolySegment;
+ pGC->ops->PolyRectangle = miPolyRectangle;
+ if(pGC->lineStyle == LineSolid)
+ pGC->ops->Polylines = miWideLine;
+ else
+ pGC->ops->Polylines = miWideDash;
+ }
+
+ if((pGC->lineWidth == 0) && (pGC->fillStyle == FillSolid)) {
+
+ if(pGC->lineStyle == LineSolid) {
+
+ if(infoRec->PolyRectangleThinSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->PolyRectangleThinSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolyRectangleThinSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolyRectangleThinSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolyRectangleThinSolidFlags)) {
+
+ pGC->ops->PolyRectangle = infoRec->PolyRectangleThinSolid;
+ }
+
+ if(infoRec->PolySegmentThinSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolySegmentThinSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolySegmentThinSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolySegmentThinSolidFlags)) {
+
+ pGC->ops->PolySegment = infoRec->PolySegmentThinSolid;
+ }
+
+ if(infoRec->PolylinesThinSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesThinSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesThinSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesThinSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolylinesThinSolidFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesThinSolid;
+ }
+ } else if((pGC->lineStyle == LineOnOffDash) && pGCPriv->DashPattern){
+
+ if(infoRec->PolySegmentThinDashed &&
+ !(infoRec->PolySegmentThinDashedFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->PolySegmentThinDashedFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_FG(pGC,infoRec->PolySegmentThinDashedFlags)) {
+
+ pGC->ops->PolySegment = infoRec->PolySegmentThinDashed;
+ }
+
+ if(infoRec->PolylinesThinDashed &&
+ !(infoRec->PolylinesThinDashedFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->PolylinesThinDashedFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_FG(pGC,infoRec->PolylinesThinDashedFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesThinDashed;
+ }
+
+ if(pGC->ops->Polylines != XAAFallbackOps.Polylines)
+ pGC->ops->PolyRectangle = miPolyRectangle;
+
+ } else if(pGCPriv->DashPattern && (pGC->depth != 32)) {
+ /* LineDoubleDash */
+ if(infoRec->PolySegmentThinDashed &&
+ !(infoRec->PolySegmentThinDashedFlags & TRANSPARENCY_ONLY) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolySegmentThinDashedFlags) &&
+ CHECK_COLORS(pGC,infoRec->PolySegmentThinDashedFlags)) {
+
+ pGC->ops->PolySegment = infoRec->PolySegmentThinDashed;
+ }
+
+ if(infoRec->PolylinesThinDashed &&
+ !(infoRec->PolylinesThinDashedFlags & TRANSPARENCY_ONLY) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesThinDashedFlags) &&
+ CHECK_COLORS(pGC,infoRec->PolylinesThinDashedFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesThinDashed;
+ }
+
+ if(pGC->ops->Polylines != XAAFallbackOps.Polylines)
+ pGC->ops->PolyRectangle = miPolyRectangle;
+
+ }
+ }
+
+ if(infoRec->PolylinesWideSolid &&
+ (pGC->lineWidth > 0) &&
+ (pGC->fillStyle == FillSolid) &&
+ (pGC->lineStyle == LineSolid) &&
+ CHECK_PLANEMASK(pGC,infoRec->PolylinesWideSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->PolylinesWideSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->PolylinesWideSolidFlags) &&
+ CHECK_FG(pGC,infoRec->PolylinesWideSolidFlags)) {
+
+ pGC->ops->Polylines = infoRec->PolylinesWideSolid;
+ }
+}
diff --git a/hw/xfree86/xaa/xaaImage.c b/hw/xfree86/xaa/xaaImage.c
new file mode 100644
index 000000000..6da601faf
--- /dev/null
+++ b/hw/xfree86/xaa/xaaImage.c
@@ -0,0 +1,520 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaImage.c,v 1.20 2000/09/25 23:56:14 mvojkovi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+void XAAMoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *dest = *(src + 1);
+ *dest = *(src + 2);
+ *dest = *(src + 3);
+ dwords -= 4;
+ src += 4;
+ }
+
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *dest = *(src + 1);
+ if(dwords == 2) return;
+ *dest = *(src + 2);
+}
+
+void XAAMoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if(dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+void XAAMoveDWORDS_FixedSrc(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *src;
+ *(dest + 2) = *src;
+ *(dest + 3) = *src;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *src;
+ if(dwords == 2) return;
+ *(dest + 2) = *src;
+}
+
+static void
+XAAWritePixmap32To24(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *srcInit,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int count, dwords = ((w * 3) + 3) >> 2;
+ CARD32 *src, *dst;
+ Bool PlusOne = FALSE;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
+
+ if(dwords > infoRec->ImageWriteRange) {
+ dst = (CARD32*)infoRec->ImageWriteBase;
+ while(h--) {
+ src = (CARD32*)srcInit;
+ count = w;
+
+ while(count >= 4) {
+ *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
+ src += 4;
+ count -= 4;
+ }
+ switch(count) {
+ case 0: break;
+ case 1: *dst = src[0];
+ break;
+ case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = src[1] >> 8;
+ break;
+ default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ *dst = src[2] >> 16;
+ break;
+ }
+ srcInit += srcwidth;
+ }
+ } else {
+ while(h--) {
+ dst = (CARD32*)infoRec->ImageWriteBase;
+ src = (CARD32*)srcInit;
+ count = w;
+
+ while(count >= 4) {
+ dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
+ dst += 3;
+ src += 4;
+ count -= 4;
+ }
+ switch(count) {
+ case 0: break;
+ case 1: dst[0] = src[0];
+ break;
+ case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = src[1] >> 8;
+ break;
+ default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ dst[2] = src[2] >> 16;
+ break;
+ }
+ srcInit += srcwidth;
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+
+}
+
+void
+XAAWritePixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec;
+ int dwords, skipleft, Bpp;
+ Bool beCareful, PlusOne;
+
+ if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
+ XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth,
+ rop, planemask, trans);
+ return;
+ }
+
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ beCareful = PlusOne = FALSE;
+ Bpp = bpp >> 3;
+
+ if((skipleft = (long)src & 0x03L)) {
+ if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if((x < skipleft) && !(infoRec->ImageWriteFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ src -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ if(dwords > infoRec->ImageWriteRange) {
+ while(h--) {
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+ *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
+ }
+ } else {
+ if(srcwidth == (dwords << 2)) {
+ int decrement = infoRec->ImageWriteRange/dwords;
+
+ while(h > decrement) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * decrement);
+ src += (srcwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * h);
+ if(beCareful) src += (srcwidth * h);
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ }
+
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+
+ ((CARD32*)infoRec->ImageWriteBase)[dwords] =
+ *((CARD32*)src) >> shift;
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAWritePixmapScanline (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
+ Bool beCareful = FALSE;
+ CARD32* base;
+
+ if((skipleft = (long)src & 0x03L)) {
+ if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ src -= 3 * skipleft;
+ else
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = ((w * Bpp) + 3) >> 2;
+
+ (*infoRec->SetupForScanlineImageWrite)(
+ pScrn, rop, planemask, trans, bpp, depth);
+ (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
+ XAAMoveDWORDS(base, (CARD32*)src, dwords);
+ (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
+ src += srcwidth;
+ if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
+ bufferNo = 0;
+ }
+
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
+ if(--dwords)
+ XAAMoveDWORDS(base,(CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+
+ base[dwords] = *((CARD32*)src) >> shift;
+ (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int bpp = BitsPerPixel(depth);
+ Bool depthBug = FALSE;
+ if(!w || !h) return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ depthBug = XAA_DEPTH_BUG(pGC);
+
+ if(((format == ZPixmap) && infoRec->WritePixmap &&
+ ((pDraw->bitsPerPixel == bpp) ||
+ ((pDraw->bitsPerPixel == 24) && (bpp == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
+ CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
+ ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap &&
+ CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
+ ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap &&
+ CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
+ !(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){
+
+ int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
+ BoxPtr pbox, pClipBoxes;
+ int nboxes, srcx, srcy, srcwidth;
+ xRectangle TheRect;
+
+ TheRect.x = pDraw->x + x;
+ TheRect.y = pDraw->y + y;
+ TheRect.width = w;
+ TheRect.height = h;
+
+ if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
+ pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
+ if(!pClipBoxes) return;
+ } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
+
+ nboxes =
+ XAAGetRectClipBoxes(pGC->pCompositeClip, pClipBoxes, 1, &TheRect);
+ pbox = pClipBoxes;
+
+ if(format == XYBitmap) {
+ srcwidth = BitmapBytePad(leftPad + w);
+ while(nboxes--) {
+ srcx = pbox->x1 - TheRect.x + leftPad;
+ srcy = pbox->y1 - TheRect.y;
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
+ pGC->alu, pGC->planemask);
+ pbox++;
+ }
+ } else if(format == ZPixmap) {
+ int Bpp = bpp >> 3;
+ srcwidth = PixmapBytePad(leftPad + w, depth);
+ while(nboxes--) {
+ srcx = pbox->x1 - TheRect.x + leftPad;
+ srcy = pbox->y1 - TheRect.y;
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + (srcx * Bpp),
+ srcwidth, pGC->alu, pGC->planemask, -1,
+ Bpp << 3, depth);
+ pbox++;
+ }
+ } else { /* XYPixmap */
+ int depth = pGC->depth;
+ int numBox, increment;
+ unsigned long i, mask;
+ BoxPtr pntBox;
+
+ srcwidth = BitmapBytePad(w + leftPad);
+ increment = h * srcwidth;
+ i = 1 << (depth - 1);
+ mask = ~0;
+
+ if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pGC->depth == 8)){
+ i = 0x80000000; mask = 0xff000000;
+ }
+
+ for(; i & mask; i >>= 1, pImage += increment) {
+ if(i & pGC->planemask) {
+ pntBox = pbox;
+ numBox = nboxes;
+ while(numBox--) {
+ srcx = pntBox->x1 - TheRect.x + leftPad;
+ srcy = pntBox->y1 - TheRect.y;
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pntBox->x1, pntBox->y1,
+ pntBox->x2 - pntBox->x1,
+ pntBox->y2 - pntBox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
+ pntBox++;
+ }
+ }
+ }
+
+ }
+
+ if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
+ xfree(pClipBoxes);
+ } else
+ XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad,
+ format, pImage);
+}
diff --git a/hw/xfree86/xaa/xaaInit.c b/hw/xfree86/xaa/xaaInit.c
new file mode 100644
index 000000000..5237e8b2c
--- /dev/null
+++ b/hw/xfree86/xaa/xaaInit.c
@@ -0,0 +1,762 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaInit.c,v 1.35 2001/07/19 18:50:16 mvojkovi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */
+
+#define MIN_OFFPIX_SIZE (320*200)
+
+static Bool XAACloseScreen(int i, ScreenPtr pScreen);
+static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format, unsigned long planemask,
+ char *pdstLine);
+static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart);
+static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth);
+static Bool XAADestroyPixmap(PixmapPtr pPixmap);
+static void XAARestoreAreas (PixmapPtr pPixmap, RegionPtr prgnRestore,
+ int xorg, int yorg, WindowPtr pWin);
+static void XAASaveAreas (PixmapPtr pPixmap, RegionPtr prgnSave,
+ int xorg, int yorg, WindowPtr pWin);
+static Bool XAAEnterVT (int index, int flags);
+static void XAALeaveVT (int index, int flags);
+static int XAASetDGAMode(int index, int num, DGADevicePtr devRet);
+static void XAAEnableDisableFBAccess (int index, Bool enable);
+static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
+
+int XAAScreenIndex = -1;
+int XAAGCIndex = -1;
+int XAAPixmapIndex = -1;
+static unsigned long XAAGeneration = 0;
+
+/* temp kludge */
+static Bool SwitchedOut = FALSE;
+
+XAAInfoRecPtr
+XAACreateInfoRec()
+{
+ XAAInfoRecPtr infoRec;
+
+ infoRec = xcalloc(1, sizeof(XAAInfoRec));
+ if(infoRec)
+ infoRec->CachePixelGranularity = -1;
+
+ return infoRec;
+}
+
+void
+XAADestroyInfoRec(XAAInfoRecPtr infoRec)
+{
+ if(!infoRec) return;
+
+ if(infoRec->ClosePixmapCache)
+ (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen);
+
+ if(infoRec->PreAllocMem)
+ xfree(infoRec->PreAllocMem);
+
+ if(infoRec->PixmapCachePrivate)
+ xfree(infoRec->PixmapCachePrivate);
+
+ xfree(infoRec);
+}
+
+
+Bool
+XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAScreenPtr pScreenPriv;
+ int i;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+#endif
+
+ /* Return successfully if no acceleration wanted */
+ if (!infoRec)
+ return TRUE;
+
+ if (XAAGeneration != serverGeneration) {
+ if ( ((XAAScreenIndex = AllocateScreenPrivateIndex()) < 0) ||
+ ((XAAGCIndex = AllocateGCPrivateIndex()) < 0) ||
+ ((XAAPixmapIndex = AllocatePixmapPrivateIndex()) < 0))
+ return FALSE;
+
+ XAAGeneration = serverGeneration;
+ }
+
+ if (!AllocateGCPrivate(pScreen, XAAGCIndex, sizeof(XAAGCRec)))
+ return FALSE;
+
+ if (!AllocatePixmapPrivate(pScreen, XAAPixmapIndex, sizeof(XAAPixmapRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = xalloc(sizeof(XAAScreenRec))))
+ return FALSE;
+
+ pScreen->devPrivates[XAAScreenIndex].ptr = (pointer)pScreenPriv;
+
+ if(!xf86FBManagerRunning(pScreen))
+ infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS);
+ if(!(infoRec->Flags & LINEAR_FRAMEBUFFER))
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+
+ if(!infoRec->FullPlanemask) { /* for backwards compatibility */
+ infoRec->FullPlanemask = (1 << pScrn->depth) - 1;
+ infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask;
+ }
+
+ for(i = 0; i < 32; i++) {
+ if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */
+ infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1;
+ }
+
+ if(!XAAInitAccel(pScreen, infoRec)) return FALSE;
+ pScreenPriv->AccelInfoRec = infoRec;
+ infoRec->ScratchGC.pScreen = pScreen;
+
+
+ if(!infoRec->GetImage)
+ infoRec->GetImage = XAAGetImage;
+ if(!infoRec->GetSpans)
+ infoRec->GetSpans = XAAGetSpans;
+ if(!infoRec->PaintWindowBackground)
+ infoRec->PaintWindowBackground = XAAPaintWindow;
+ if(!infoRec->PaintWindowBorder)
+ infoRec->PaintWindowBorder = XAAPaintWindow;
+ if(!infoRec->CopyWindow)
+ infoRec->CopyWindow = XAACopyWindow;
+ if(!infoRec->SaveAreas)
+ infoRec->SaveAreas = XAASaveAreas;
+ if(!infoRec->RestoreAreas)
+ infoRec->RestoreAreas = XAARestoreAreas;
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreen->CreateGC = XAACreateGC;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = XAACloseScreen;
+ pScreenPriv->GetImage = pScreen->GetImage;
+ pScreen->GetImage = infoRec->GetImage;
+ pScreenPriv->GetSpans = pScreen->GetSpans;
+ pScreen->GetSpans = infoRec->GetSpans;
+ pScreenPriv->PaintWindowBackground = pScreen->PaintWindowBackground;
+ pScreen->PaintWindowBackground = infoRec->PaintWindowBackground;
+ pScreenPriv->PaintWindowBorder = pScreen->PaintWindowBorder;
+ pScreen->PaintWindowBorder = infoRec->PaintWindowBorder;
+ pScreenPriv->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = infoRec->CopyWindow;
+ pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
+ pScreen->CreatePixmap = XAACreatePixmap;
+ pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = XAADestroyPixmap;
+ pScreenPriv->BackingStoreFuncs.RestoreAreas =
+ pScreen->BackingStoreFuncs.RestoreAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = infoRec->RestoreAreas;
+ pScreenPriv->BackingStoreFuncs.SaveAreas =
+ pScreen->BackingStoreFuncs.SaveAreas;
+ pScreen->BackingStoreFuncs.SaveAreas = infoRec->SaveAreas;
+ pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes;
+
+ pScreenPriv->EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = XAAEnterVT;
+ pScreenPriv->LeaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = XAALeaveVT;
+ pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScrn->SetDGAMode = XAASetDGAMode;
+ pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
+ pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess;
+
+ pScreenPriv->WindowExposures = pScreen->WindowExposures;
+#ifdef RENDER
+ if (ps)
+ {
+ pScreenPriv->Composite = ps->Composite;
+ ps->Composite = XAAComposite;
+ pScreenPriv->Glyphs = ps->Glyphs;
+ ps->Glyphs = XAAGlyphs;
+ }
+#endif
+ if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
+ XAASetupOverlay8_32Planar(pScreen);
+
+ infoRec->PreAllocMem = xalloc(MAX_PREALLOC_MEM);
+ if(infoRec->PreAllocMem)
+ infoRec->PreAllocSize = MAX_PREALLOC_MEM;
+
+ if(infoRec->Flags & PIXMAP_CACHE)
+ xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache,
+ (pointer)infoRec);
+
+ if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS)
+ miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4);
+
+ return TRUE;
+}
+
+
+
+static Bool
+XAACloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+
+ pScrn->EnterVT = pScreenPriv->EnterVT;
+ pScrn->LeaveVT = pScreenPriv->LeaveVT;
+ pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess;
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->PaintWindowBackground = pScreenPriv->PaintWindowBackground;
+ pScreen->PaintWindowBorder = pScreenPriv->PaintWindowBorder;
+ pScreen->CopyWindow = pScreenPriv->CopyWindow;
+ pScreen->WindowExposures = pScreenPriv->WindowExposures;
+ pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
+ pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
+ pScreen->BackingStoreFuncs.RestoreAreas =
+ pScreenPriv->BackingStoreFuncs.RestoreAreas;
+ pScreen->BackingStoreFuncs.SaveAreas =
+ pScreenPriv->BackingStoreFuncs.SaveAreas;
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+
+ /* We leave it up to the client to free the XAAInfoRec */
+
+ xfree ((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+XAAGetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+
+ if(pScrn->vtSema &&
+ ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw)))
+ {
+ if(infoRec->ReadPixmap && (format == ZPixmap) &&
+ ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) ==
+ infoRec->FullPlanemasks[pDraw->depth - 1]) &&
+ (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth)))
+ {
+ (*infoRec->ReadPixmap)(pScrn,
+ sx + pDraw->x, sy + pDraw->y, w, h,
+ (unsigned char *)pdstLine,
+ PixmapBytePad(w, pDraw->depth),
+ pDraw->bitsPerPixel, pDraw->depth);
+ return;
+ }
+ SYNC_CHECK(pDraw);
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, GetImage);
+ (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
+}
+
+static void
+XAAGetSpans (
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart
+)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ XAA_SCREEN_PROLOGUE (pScreen, GetSpans);
+ if(xf86Screens[pScreen->myNum]->vtSema &&
+ ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
+ SYNC_CHECK(pDraw);
+ }
+ (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart);
+ XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans);
+}
+
+
+static void
+XAASaveAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap)) {
+ BoxPtr pbox = REGION_RECTS(prgnSave);
+ int nboxes = REGION_NUM_RECTS(prgnSave);
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
+ while(nboxes--) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pbox->x1 + xorg, pbox->y1 + yorg,
+ pPixmap->drawable.x + pbox->x1,
+ pPixmap->drawable.y + pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if(xf86Screens[pScreen->myNum]->vtSema && infoRec->ReadPixmap &&
+ (pWin->drawable.bitsPerPixel == pPixmap->drawable.bitsPerPixel)) {
+ BoxPtr pbox = REGION_RECTS(prgnSave);
+ int nboxes = REGION_NUM_RECTS(prgnSave);
+ int Bpp = pPixmap->drawable.bitsPerPixel >> 3;
+ unsigned char *dstp = (unsigned char*)pPixmap->devPrivate.ptr;
+
+ while(nboxes--) {
+ (*infoRec->ReadPixmap)(infoRec->pScrn,
+ pbox->x1 + xorg, pbox->y1 + yorg,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ dstp + (pPixmap->devKind * pbox->y1) + (pbox->x1 * Bpp),
+ pPixmap->devKind,
+ pPixmap->drawable.bitsPerPixel, pPixmap->drawable.depth);
+ pbox++;
+ }
+ return;
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, BackingStoreFuncs.SaveAreas);
+ if(pScrn->vtSema) {
+ SYNC_CHECK(&pWin->drawable);
+ }
+ (*pScreen->BackingStoreFuncs.SaveAreas) (
+ pPixmap, prgnSave, xorg, yorg, pWin);
+
+ XAA_SCREEN_EPILOGUE (pScreen, BackingStoreFuncs.SaveAreas,
+ XAASaveAreas);
+}
+
+static void
+XAARestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap)) {
+ BoxPtr pbox = REGION_RECTS(prgnRestore);
+ int nboxes = REGION_NUM_RECTS(prgnRestore);
+ int pm = ~0;
+
+ if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pWin->drawable.depth == 24))
+ pm = 0x00ffffff;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, pm, -1);
+ while(nboxes--) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pPixmap->drawable.x + pbox->x1 - xorg,
+ pPixmap->drawable.y + pbox->y1 - yorg,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if(pScrn->vtSema && infoRec->WritePixmap &&
+ !(infoRec->WritePixmapFlags & NO_GXCOPY) &&
+ ((pWin->drawable.bitsPerPixel == pPixmap->drawable.bitsPerPixel) ||
+ ((pWin->drawable.bitsPerPixel == 24) &&
+ (pPixmap->drawable.bitsPerPixel == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP)))) {
+ BoxPtr pbox = REGION_RECTS(prgnRestore);
+ int nboxes = REGION_NUM_RECTS(prgnRestore);
+ int Bpp = pPixmap->drawable.bitsPerPixel >> 3;
+ unsigned char *srcp = (unsigned char*)pPixmap->devPrivate.ptr;
+ int pm = ~0;
+
+ if((pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pWin->drawable.depth == 24))
+ pm = 0x00ffffff;
+
+ while(nboxes--) {
+ (*infoRec->WritePixmap)(pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ srcp + (pPixmap->devKind * (pbox->y1 - yorg)) +
+ ((pbox->x1 - xorg) * Bpp),
+ pPixmap->devKind, GXcopy, pm, -1,
+ pPixmap->drawable.bitsPerPixel, pPixmap->drawable.depth);
+ pbox++;
+ }
+ return;
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, BackingStoreFuncs.RestoreAreas);
+ if(pScrn->vtSema) {
+ SYNC_CHECK(&pWin->drawable);
+ }
+ (*pScreen->BackingStoreFuncs.RestoreAreas) (
+ pPixmap, prgnRestore, xorg, yorg, pWin);
+
+ XAA_SCREEN_EPILOGUE (pScreen, BackingStoreFuncs.RestoreAreas,
+ XAARestoreAreas);
+}
+
+static int
+XAAPixmapBPP (ScreenPtr pScreen, int depth)
+{
+ PixmapPtr pPix;
+ int bpp;
+ DestroyPixmapProcPtr destroyPixmap;
+
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+ if (!pPix)
+ return 0;
+ bpp = pPix->drawable.bitsPerPixel;
+ destroyPixmap = pScreen->DestroyPixmap;
+ XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPix);
+ XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap);
+ return bpp;
+}
+
+static void
+XAAInitializeOffscreenDepths (ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int d, dep;
+
+ infoRec->offscreenDepthsInitialized = TRUE;
+ infoRec->offscreenDepths = 0;
+ if (infoRec->Flags & OFFSCREEN_PIXMAPS) {
+ for (d = 0; d < pScreen->numDepths; d++) {
+ dep = pScreen->allowedDepths[d].depth;
+ if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel)
+ infoRec->offscreenDepths |= (1 << (dep - 1));
+ }
+ }
+}
+
+static PixmapPtr
+XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAPixmapPtr pPriv;
+ PixmapPtr pPix = NULL;
+ int size = w * h;
+
+ if (!infoRec->offscreenDepthsInitialized)
+ XAAInitializeOffscreenDepths (pScreen);
+
+ if(pScrn->vtSema && (infoRec->offscreenDepths & (1 << (depth - 1))) &&
+ (size >= MIN_OFFPIX_SIZE) && !SwitchedOut &&
+ (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) &&
+ (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) )
+ {
+ PixmapLinkPtr pLink;
+ PixmapPtr pScreenPix;
+ FBAreaPtr area;
+ int gran = 0;
+
+ switch(pScrn->bitsPerPixel) {
+ case 24:
+ case 8: gran = 4; break;
+ case 16: gran = 2; break;
+ case 32: gran = 1; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ gran *= 2;
+
+ if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0,
+ XAARemoveAreaCallback, NULL))) {
+ goto BAILOUT;
+ }
+
+ if(!(pLink = xalloc(sizeof(PixmapLink)))) {
+ xf86FreeOffscreenArea(area);
+ goto BAILOUT;
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+
+ if (!pPix) {
+ xfree (pLink);
+ xf86FreeOffscreenArea(area);
+ goto BAILOUT;
+ }
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ pPix->drawable.x = area->box.x1;
+ pPix->drawable.y = area->box.y1;
+ pPix->drawable.width = w;
+ pPix->drawable.height = h;
+ pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel;
+ pPix->devKind = pScreenPix->devKind;
+ pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
+ area->devPrivate.ptr = pPix;
+
+ pPriv->flags = OFFSCREEN;
+ pPriv->offscreenArea = area;
+ pPriv->freeData = FALSE;
+
+ pLink->next = infoRec->OffscreenPixmaps;
+ pLink->pPix = pPix;
+ infoRec->OffscreenPixmaps = pLink;
+ return pPix;
+ }
+BAILOUT:
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+
+ if(pPix) {
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ pPriv->flags = 0;
+ pPriv->offscreenArea = NULL;
+ pPriv->freeData = FALSE;
+ if(!w || !h) /* either scratch or shared memory */
+ pPriv->flags |= SHARED_PIXMAP;
+ }
+
+ return pPix;
+}
+
+static Bool
+XAADestroyPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ Bool ret;
+
+ if(pPix->refcnt == 1) {
+ if(pPriv->flags & OFFSCREEN) {
+ if(pPriv->flags & DGA_PIXMAP)
+ xfree(pPriv->offscreenArea);
+ else {
+ FBAreaPtr area = pPriv->offscreenArea;
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ PixmapLinkPtr prev = NULL;
+
+ while(pLink->pPix != pPix) {
+ prev = pLink;
+ pLink = pLink->next;
+ }
+
+ if(prev) prev->next = pLink->next;
+ else infoRec->OffscreenPixmaps = pLink->next;
+
+ if(!area) area = pLink->area;
+
+ xf86FreeOffscreenArea(area);
+ pPriv->offscreenArea = NULL;
+ xfree(pLink);
+ }
+ }
+
+ if(pPriv->freeData) { /* pixmaps that were once in video ram */
+ xfree(pPix->devPrivate.ptr);
+ pPix->devPrivate.ptr = NULL;
+ }
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
+ ret = (*pScreen->DestroyPixmap) (pPix);
+ XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
+
+ return ret;
+}
+
+static Bool
+XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool ret;
+
+ XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
+ ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+ XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes);
+
+ /* we have to assume that shared memory pixmaps are dirty
+ because we can't wrap operations on them */
+
+ if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) &&
+ PIXMAP_IS_SHARED(pWin->background.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+ if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) &&
+ PIXMAP_IS_SHARED(pWin->border.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+
+ return ret;
+}
+
+
+
+/* These two aren't really needed for anything */
+
+static Bool
+XAAEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+
+ return((*pScreenPriv->EnterVT)(index, flags));
+}
+
+static void
+XAALeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+ XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+ (*pScreenPriv->LeaveVT)(index, flags);
+}
+
+typedef struct {
+ Bool UsingPixmapCache;
+ Bool CanDoColor8x8;
+ Bool CanDoMono8x8;
+} SavedCacheState, *SavedCacheStatePtr;
+
+static int
+XAASetDGAMode(int index, int num, DGADevicePtr devRet)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+ int ret;
+
+ if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */
+ SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves;
+
+ infoRec->UsingPixmapCache = state->UsingPixmapCache;
+ infoRec->CanDoColor8x8 = state->CanDoColor8x8;
+ infoRec->CanDoMono8x8 = state->CanDoMono8x8;
+ xfree(infoRec->dgaSaves);
+ infoRec->dgaSaves = NULL;
+ }
+
+ ret = (*pScreenPriv->SetDGAMode)(index, num, devRet);
+ if(ret != Success) return ret;
+
+ if(num && devRet->pPix) { /* accelerate this pixmap */
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix);
+ FBAreaPtr area;
+
+ if((area = xalloc(sizeof(FBArea)))) {
+ area->pScreen = pScreen;
+ area->box.x1 = 0;
+ area->box.x2 = 0;
+ area->box.y1 = devRet->mode->pixmapWidth;
+ area->box.y2 = devRet->mode->pixmapHeight;
+ area->granularity = 0;
+ area->MoveAreaCallback = 0;
+ area->RemoveAreaCallback = 0;
+ area->devPrivate.ptr = 0;
+
+ pixPriv->flags |= OFFSCREEN | DGA_PIXMAP;
+ pixPriv->offscreenArea = area;
+
+ if(!infoRec->dgaSaves) { /* save pixmap cache state */
+ SavedCacheStatePtr state = xalloc(sizeof(SavedCacheState));
+
+ state->UsingPixmapCache = infoRec->UsingPixmapCache;
+ state->CanDoColor8x8 = infoRec->CanDoColor8x8;
+ state->CanDoMono8x8 = infoRec->CanDoMono8x8;
+ infoRec->dgaSaves = (char*)state;
+
+ infoRec->UsingPixmapCache = FALSE;
+ if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8)
+ infoRec->CanDoMono8x8 = FALSE;
+ if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8)
+ infoRec->CanDoColor8x8 = FALSE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+static void
+XAAEnableDisableFBAccess (int index, Bool enable)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr) pScreen->devPrivates[XAAScreenIndex].ptr;
+
+ if(!enable) {
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
+ XAAMoveOutOffscreenPixmaps(pScreen);
+ if(infoRec->Flags & PIXMAP_CACHE)
+ XAAInvalidatePixmapCache(pScreen);
+ SwitchedOut = TRUE;
+ }
+
+ (*pScreenPriv->EnableDisableFBAccess)(index, enable);
+
+ if(enable) {
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
+ XAAMoveInOffscreenPixmaps(pScreen);
+ SwitchedOut = FALSE;
+ }
+}
diff --git a/hw/xfree86/xaa/xaaInitAccel.c b/hw/xfree86/xaa/xaaInitAccel.c
new file mode 100644
index 000000000..1b1bc1830
--- /dev/null
+++ b/hw/xfree86/xaa/xaaInitAccel.c
@@ -0,0 +1,1513 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaInitAccel.c,v 1.36 2003/01/12 03:55:51 tsi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+#ifdef XFree86LOADER
+static const OptionInfoRec *XAAAvailableOptions(void *unused);
+#endif
+
+/*
+ * XAA Config options
+ */
+
+typedef enum {
+ XAAOPT_SCREEN_TO_SCREEN_COPY,
+ XAAOPT_SOLID_FILL_RECT,
+ XAAOPT_SOLID_FILL_TRAP,
+ XAAOPT_SOLID_TWO_POINT_LINE,
+ XAAOPT_SOLID_BRESENHAM_LINE,
+ XAAOPT_SOLID_HORVERT_LINE,
+ XAAOPT_DASHED_TWO_POINT_LINE,
+ XAAOPT_DASHED_BRESENHAM_LINE,
+ XAAOPT_MONO_8x8_PATTERN_FILL_RECT,
+ XAAOPT_MONO_8x8_PATTERN_FILL_TRAP,
+ XAAOPT_COL_8x8_PATTERN_FILL_RECT,
+ XAAOPT_COL_8x8_PATTERN_FILL_TRAP,
+ XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_IMAGE_WRITE_RECT,
+ XAAOPT_SCANLINE_IMAGE_WRITE_RECT,
+ XAAOPT_WRITE_BITMAP,
+ XAAOPT_WRITE_PIXMAP,
+ XAAOPT_PIXMAP_CACHE,
+ XAAOPT_OFFSCREEN_PIXMAPS
+} XAAOpts;
+
+static const OptionInfoRec XAAOptions[] = {
+ {XAAOPT_SCREEN_TO_SCREEN_COPY, "XaaNoScreenToScreenCopy",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_FILL_RECT, "XaaNoSolidFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_FILL_TRAP, "XaaNoSolidFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_TWO_POINT_LINE, "XaaNoSolidTwoPointLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_BRESENHAM_LINE, "XaaNoSolidBresenhamLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_HORVERT_LINE, "XaaNoSolidHorVertLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_DASHED_TWO_POINT_LINE, "XaaNoDashedTwoPointLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_DASHED_BRESENHAM_LINE, "XaaNoDashedBresenhamLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_MONO_8x8_PATTERN_FILL_RECT, "XaaNoMono8x8PatternFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_MONO_8x8_PATTERN_FILL_TRAP, "XaaNoMono8x8PatternFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_COL_8x8_PATTERN_FILL_RECT, "XaaNoColor8x8PatternFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_COL_8x8_PATTERN_FILL_TRAP, "XaaNoColor8x8PatternFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL, "XaaNoCPUToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,"XaaNoScanlineCPUToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL, "XaaNoScreenToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_IMAGE_WRITE_RECT, "XaaNoImageWriteRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCANLINE_IMAGE_WRITE_RECT, "XaaNoScanlineImageWriteRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_WRITE_BITMAP, "XaaNoWriteBitmap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_WRITE_PIXMAP, "XaaNoWritePixmap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_PIXMAP_CACHE, "XaaNoPixmapCache",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_OFFSCREEN_PIXMAPS, "XaaNoOffscreenPixmaps",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL,
+ OPTV_NONE, {0}, FALSE }
+};
+
+#ifdef XFree86LOADER
+static MODULESETUPPROTO(xaaSetup);
+
+static XF86ModuleVersionInfo xaaVersRec =
+{
+ "xaa",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XF86_VERSION_CURRENT,
+ 1, 1, 0,
+ ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+XF86ModuleData xaaModuleData = { &xaaVersRec, xaaSetup, NULL };
+
+ModuleInfoRec XAA = {
+ 1,
+ "XAA",
+ NULL,
+ 0,
+ XAAAvailableOptions,
+};
+
+/*ARGSUSED*/
+static pointer
+xaaSetup(pointer Module, pointer Options, int *ErrorMajor, int *ErrorMinor)
+{
+ static Bool Initialised = FALSE;
+
+ if (!Initialised) {
+ Initialised = TRUE;
+#ifndef REMOVE_LOADER_CHECK_MODULE_INFO
+ if (xf86LoaderCheckSymbol("xf86AddModuleInfo"))
+#endif
+ xf86AddModuleInfo(&XAA, Module);
+ }
+
+ return (pointer)TRUE;
+}
+
+/*ARGSUSED*/
+static const OptionInfoRec *
+XAAAvailableOptions(void *unused)
+{
+ return (XAAOptions);
+}
+#endif
+
+Bool
+XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ int index = pScreen->myNum;
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ Bool HaveScreenToScreenCopy = FALSE;
+ Bool HaveColorExpansion = FALSE;
+ Bool HaveScanlineColorExpansion = FALSE;
+ Bool HaveSolidFillRect = FALSE;
+ Bool HaveMono8x8PatternFillRect = FALSE;
+ Bool HaveColor8x8PatternFillRect = FALSE;
+ Bool HaveSolidFillTrap = FALSE;
+ Bool HaveMono8x8PatternFillTrap = FALSE;
+ Bool HaveColor8x8PatternFillTrap = FALSE;
+ Bool HaveSolidTwoPointLine = FALSE;
+ Bool HaveSolidBresenhamLine = FALSE;
+ Bool HaveSolidHorVertLine = FALSE;
+ Bool HaveDashedTwoPointLine = FALSE;
+ Bool HaveDashedBresenhamLine = FALSE;
+ Bool HaveImageWriteRect = FALSE;
+ Bool HaveScanlineImageWriteRect = FALSE;
+ Bool HaveScreenToScreenColorExpandFill = FALSE;
+ OptionInfoPtr options;
+ int is_shared = 0;
+ int i;
+
+ options = xnfalloc(sizeof(XAAOptions));
+ (void)memcpy(options, XAAOptions, sizeof(XAAOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ infoRec->pScrn = pScrn;
+ infoRec->NeedToSync = FALSE;
+
+ /* must have a Sync function */
+ if(!infoRec->Sync) return FALSE;
+ for(i = 0; i < pScrn->numEntities; i++) {
+ if(xf86IsEntityShared(pScrn->entityList[i])) is_shared = 1;
+ }
+
+ /* If this PCI entity has IS_SHARED_ACCEL set in entityProp
+ * then a RestoreAccelState function is required
+ */
+ if(!infoRec->RestoreAccelState && is_shared) return FALSE;
+
+ if(infoRec->RestoreAccelState) {
+ if(!XAAInitStateWrap(pScreen, infoRec)) return FALSE;
+ }
+
+ if (serverGeneration == 1)
+ xf86DrvMsg(index, X_INFO,
+ "Using XFree86 Acceleration Architecture (XAA)\n");
+
+
+ /************** Low Level *************/
+
+ if(!infoRec->SetClippingRectangle || !infoRec->DisableClipping) {
+ infoRec->ClippingFlags = 0;
+ infoRec->SetClippingRectangle = NULL;
+ infoRec->DisableClipping = NULL;
+ }
+
+ /**** CopyArea ****/
+
+ if(infoRec->SetupForScreenToScreenCopy &&
+ infoRec->SubsequentScreenToScreenCopy &&
+ !xf86IsOptionSet(options, XAAOPT_SCREEN_TO_SCREEN_COPY)) {
+ HaveScreenToScreenCopy = TRUE;
+ } else {
+ infoRec->ScreenToScreenCopyFlags = 0;
+ infoRec->SetupForScreenToScreenCopy = NULL;
+ infoRec->SubsequentScreenToScreenCopy = NULL;
+ }
+
+ /**** Solid Filled Rects ****/
+
+ if(infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect &&
+ !xf86IsOptionSet(options, XAAOPT_SOLID_FILL_RECT)) {
+ HaveSolidFillRect = TRUE;
+ if(infoRec->SubsequentSolidFillTrap &&
+ !xf86IsOptionSet(options, XAAOPT_SOLID_FILL_TRAP))
+ HaveSolidFillTrap = TRUE;
+ else
+ infoRec->SubsequentSolidFillTrap = NULL;
+ } else {
+ infoRec->SolidFillFlags = 0;
+ infoRec->SetupForSolidFill = NULL;
+ infoRec->SubsequentSolidFillRect = NULL;
+ infoRec->SubsequentSolidFillTrap = NULL;
+ }
+
+ /**** Solid lines ****/
+
+ if(infoRec->SetupForSolidLine) {
+ if(infoRec->SubsequentSolidTwoPointLine &&
+ !xf86IsOptionSet(options, XAAOPT_SOLID_TWO_POINT_LINE))
+ HaveSolidTwoPointLine = TRUE;
+ if(infoRec->SubsequentSolidBresenhamLine &&
+ !xf86IsOptionSet(options, XAAOPT_SOLID_BRESENHAM_LINE)) {
+ HaveSolidBresenhamLine = TRUE;
+
+ if(infoRec->SolidBresenhamLineErrorTermBits)
+ infoRec->SolidBresenhamLineErrorTermBits =
+ ~((1 << infoRec->SolidBresenhamLineErrorTermBits) - 1);
+ }
+
+ if(infoRec->SubsequentSolidHorVertLine &&
+ !xf86IsOptionSet(options, XAAOPT_SOLID_HORVERT_LINE))
+ HaveSolidHorVertLine = TRUE;
+ else if(HaveSolidTwoPointLine) {
+ infoRec->SubsequentSolidHorVertLine =
+ XAASolidHorVertLineAsTwoPoint;
+ HaveSolidHorVertLine = TRUE;
+ } else if(HaveSolidBresenhamLine) {
+ infoRec->SubsequentSolidHorVertLine =
+ XAASolidHorVertLineAsBresenham;
+ HaveSolidHorVertLine = TRUE;
+ }
+ }
+
+ /* XXX Should this also check for XAAOPT_SOLID_HORVERT_LINE? */
+ if (!HaveSolidTwoPointLine &&
+ !HaveSolidBresenhamLine &&
+ !HaveSolidHorVertLine &&
+ HaveSolidFillRect) {
+ infoRec->SetupForSolidLine = infoRec->SetupForSolidFill;
+ infoRec->SubsequentSolidHorVertLine = XAASolidHorVertLineAsRects;
+ infoRec->SolidLineFlags = infoRec->SolidFillFlags;
+ HaveSolidHorVertLine = TRUE;
+ }
+
+ if (!HaveSolidTwoPointLine)
+ infoRec->SubsequentSolidTwoPointLine = NULL;
+ if (!HaveSolidBresenhamLine)
+ infoRec->SubsequentSolidBresenhamLine = NULL;
+ if (!HaveSolidHorVertLine)
+ infoRec->SubsequentSolidHorVertLine = NULL;
+
+ /* Disable all if nothing left over */
+ if (!HaveSolidTwoPointLine &&
+ !HaveSolidBresenhamLine &&
+ !HaveSolidHorVertLine) {
+ infoRec->SolidLineFlags = 0;
+ infoRec->SetupForSolidLine = NULL;
+ }
+
+ /**** 8x8 Mono Pattern Filled Rects ****/
+
+ if(infoRec->SetupForMono8x8PatternFill &&
+ infoRec->SubsequentMono8x8PatternFillRect &&
+ !xf86IsOptionSet(options, XAAOPT_MONO_8x8_PATTERN_FILL_RECT)) {
+ HaveMono8x8PatternFillRect = TRUE;
+ if(infoRec->SubsequentMono8x8PatternFillTrap &&
+ !xf86IsOptionSet(options, XAAOPT_MONO_8x8_PATTERN_FILL_TRAP))
+ HaveMono8x8PatternFillTrap = TRUE;
+
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ infoRec->CanDoMono8x8 = TRUE;
+ } else { /* others require caching */
+ int min_pitch;
+ infoRec->PixmapCacheFlags |= CACHE_MONO_8x8;
+
+ switch(pScrn->bitsPerPixel) {
+ case 32: min_pitch = 2; break;
+ case 24: min_pitch = 3; break;
+ case 16: min_pitch = 4; break;
+ default: min_pitch = 8; break;
+ }
+
+ if(min_pitch > infoRec->MonoPatternPitch)
+ infoRec->MonoPatternPitch = min_pitch;
+
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ if(!infoRec->CacheWidthMono8x8Pattern ||
+ !infoRec->CacheHeightMono8x8Pattern) {
+ infoRec->CacheWidthMono8x8Pattern =
+ infoRec->MonoPatternPitch;
+ infoRec->CacheHeightMono8x8Pattern = 1;
+ }
+ } else {
+ int numPerLine = 128/infoRec->MonoPatternPitch;
+
+ if(!infoRec->CacheWidthMono8x8Pattern ||
+ !infoRec->CacheHeightMono8x8Pattern) {
+ infoRec->CacheWidthMono8x8Pattern =
+ numPerLine * infoRec->MonoPatternPitch;
+ infoRec->CacheHeightMono8x8Pattern =
+ (64 + numPerLine - 1)/numPerLine;
+ }
+ }
+ }
+ } else {
+ infoRec->Mono8x8PatternFillFlags = 0;
+ infoRec->SetupForMono8x8PatternFill = NULL;
+ infoRec->SubsequentMono8x8PatternFillRect = NULL;
+ }
+
+ /**** Dashed lines ****/
+
+ if(infoRec->SetupForDashedLine && infoRec->DashPatternMaxLength) {
+ if(infoRec->SubsequentDashedTwoPointLine &&
+ !xf86IsOptionSet(options, XAAOPT_DASHED_TWO_POINT_LINE))
+ HaveDashedTwoPointLine = TRUE;
+ if(infoRec->SubsequentDashedBresenhamLine &&
+ !xf86IsOptionSet(options, XAAOPT_DASHED_BRESENHAM_LINE)) {
+ HaveDashedBresenhamLine = TRUE;
+
+ if(infoRec->DashedBresenhamLineErrorTermBits)
+ infoRec->DashedBresenhamLineErrorTermBits =
+ ~((1 << infoRec->DashedBresenhamLineErrorTermBits) - 1);
+ }
+ }
+
+ if (!HaveDashedTwoPointLine)
+ infoRec->SubsequentDashedTwoPointLine = NULL;
+ if (!HaveDashedBresenhamLine)
+ infoRec->SubsequentDashedBresenhamLine = NULL;
+
+ /* Disable all if nothing left over */
+ if (!HaveDashedTwoPointLine && !HaveDashedBresenhamLine) {
+ infoRec->DashedLineFlags = 0;
+ infoRec->SetupForDashedLine = NULL;
+ }
+
+ /**** 8x8 Color Pattern Filled Rects ****/
+
+ if(infoRec->SetupForColor8x8PatternFill &&
+ infoRec->SubsequentColor8x8PatternFillRect &&
+ !xf86IsOptionSet(options, XAAOPT_COL_8x8_PATTERN_FILL_RECT)) {
+ HaveColor8x8PatternFillRect = TRUE;
+ if(infoRec->SubsequentColor8x8PatternFillTrap &&
+ !xf86IsOptionSet(options, XAAOPT_COL_8x8_PATTERN_FILL_TRAP))
+ HaveColor8x8PatternFillTrap = TRUE;
+ else
+ infoRec->SubsequentColor8x8PatternFillTrap = NULL;
+
+ infoRec->PixmapCacheFlags |= CACHE_COLOR_8x8;
+
+ if(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ if(!infoRec->CacheWidthColor8x8Pattern ||
+ !infoRec->CacheHeightColor8x8Pattern) {
+ infoRec->CacheWidthColor8x8Pattern = 64;
+ infoRec->CacheHeightColor8x8Pattern = 1;
+ }
+ } else {
+ if(!infoRec->CacheWidthColor8x8Pattern ||
+ !infoRec->CacheHeightColor8x8Pattern) {
+ infoRec->CacheWidthColor8x8Pattern = 128;
+ infoRec->CacheHeightColor8x8Pattern = 8;
+ }
+ }
+ } else {
+ infoRec->Color8x8PatternFillFlags = 0;
+ infoRec->SetupForColor8x8PatternFill = NULL;
+ infoRec->SubsequentColor8x8PatternFillRect = NULL;
+ infoRec->SubsequentColor8x8PatternFillTrap = NULL;
+ }
+
+ /**** Color Expansion ****/
+
+ if(infoRec->SetupForCPUToScreenColorExpandFill &&
+ infoRec->ColorExpandBase &&
+ infoRec->SubsequentCPUToScreenColorExpandFill &&
+ !xf86IsOptionSet(options, XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL)) {
+ int dwordsNeeded = pScrn->virtualX;
+
+ infoRec->ColorExpandRange >>= 2; /* convert to DWORDS */
+ HaveColorExpansion = TRUE;
+
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)
+ dwordsNeeded += 31;
+ dwordsNeeded = (dwordsNeeded + 31) >> 5;
+ if(dwordsNeeded > infoRec->ColorExpandRange)
+ infoRec->CPUToScreenColorExpandFillFlags |= CPU_TRANSFER_BASE_FIXED;
+ } else {
+ infoRec->CPUToScreenColorExpandFillFlags = 0;
+ infoRec->SetupForCPUToScreenColorExpandFill = NULL;
+ infoRec->SubsequentCPUToScreenColorExpandFill = NULL;
+ }
+
+ /**** Scanline Color Expansion ****/
+
+ if(infoRec->SetupForScanlineCPUToScreenColorExpandFill &&
+ infoRec->SubsequentScanlineCPUToScreenColorExpandFill &&
+ infoRec->SubsequentColorExpandScanline &&
+ infoRec->ScanlineColorExpandBuffers &&
+ (infoRec->NumScanlineColorExpandBuffers > 0) &&
+ !xf86IsOptionSet(options, XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL)) {
+ HaveScanlineColorExpansion = TRUE;
+ } else {
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags = 0;
+ infoRec->SetupForScanlineCPUToScreenColorExpandFill = NULL;
+ infoRec->SubsequentScanlineCPUToScreenColorExpandFill = NULL;
+ infoRec->SubsequentColorExpandScanline = NULL;
+ }
+
+ /**** Screen to Screen Color Expansion ****/
+
+ if(infoRec->SetupForScreenToScreenColorExpandFill &&
+ infoRec->SubsequentScreenToScreenColorExpandFill &&
+ !xf86IsOptionSet(options, XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL)) {
+ HaveScreenToScreenColorExpandFill = TRUE;
+ if (!infoRec->CacheColorExpandDensity)
+ infoRec->CacheColorExpandDensity = 1;
+ } else {
+ infoRec->ScreenToScreenColorExpandFillFlags = 0;
+ infoRec->SetupForScreenToScreenColorExpandFill = NULL;
+ infoRec->SubsequentScreenToScreenColorExpandFill = NULL;
+ }
+
+ /**** Image Writes ****/
+
+ if(infoRec->SetupForImageWrite && infoRec->ImageWriteBase &&
+ infoRec->SubsequentImageWriteRect &&
+ !xf86IsOptionSet(options, XAAOPT_IMAGE_WRITE_RECT)) {
+
+ infoRec->ImageWriteRange >>= 2; /* convert to DWORDS */
+ if(infoRec->ImageWriteFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->ImageWriteRange = 0;
+ HaveImageWriteRect = TRUE;
+ } else {
+ infoRec->ImageWriteFlags = 0;
+ infoRec->SetupForImageWrite = NULL;
+ infoRec->SubsequentImageWriteRect = NULL;
+ }
+
+ /**** Scanline Image Writes ****/
+
+ if(infoRec->SetupForScanlineImageWrite &&
+ infoRec->SubsequentScanlineImageWriteRect &&
+ infoRec->SubsequentImageWriteScanline &&
+ infoRec->ScanlineImageWriteBuffers &&
+ (infoRec->NumScanlineImageWriteBuffers > 0) &&
+ !xf86IsOptionSet(options, XAAOPT_SCANLINE_IMAGE_WRITE_RECT)) {
+ HaveScanlineImageWriteRect = TRUE;
+ } else {
+ infoRec->ScanlineImageWriteFlags = 0;
+ infoRec->SetupForScanlineImageWrite = NULL;
+ infoRec->SubsequentScanlineImageWriteRect = NULL;
+ infoRec->SubsequentImageWriteScanline = NULL;
+ }
+
+#ifndef __i386__
+ /* XAA makes some unaligned accesses when clipping is not available */
+# define CLIP_FLAGS (LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X)
+ if(HaveImageWriteRect &&
+ ((infoRec->ImageWriteFlags & CLIP_FLAGS) != CLIP_FLAGS))
+ {
+ HaveImageWriteRect = FALSE;
+ }
+ if(HaveScanlineImageWriteRect &&
+ ((infoRec->ScanlineImageWriteFlags & CLIP_FLAGS) != CLIP_FLAGS))
+ {
+ HaveScanlineImageWriteRect = FALSE;
+ }
+#endif
+
+ if (serverGeneration == 1) {
+ if(HaveScreenToScreenCopy)
+ xf86ErrorF("\tScreen to screen bit blits\n");
+ if(HaveSolidFillRect)
+ xf86ErrorF("\tSolid filled rectangles\n");
+ if(HaveSolidFillTrap)
+ xf86ErrorF("\tSolid filled trapezoids\n");
+ if(HaveMono8x8PatternFillRect)
+ xf86ErrorF("\t8x8 mono pattern filled rectangles\n");
+ if(HaveMono8x8PatternFillTrap)
+ xf86ErrorF("\t8x8 mono pattern filled trapezoids\n");
+ if(HaveColor8x8PatternFillRect)
+ xf86ErrorF("\t8x8 color pattern filled rectangles\n");
+ if(HaveColor8x8PatternFillTrap)
+ xf86ErrorF("\t8x8 color pattern filled trapezoids\n");
+
+ if(HaveColorExpansion)
+ xf86ErrorF("\tCPU to Screen color expansion\n");
+ else if(HaveScanlineColorExpansion)
+ xf86ErrorF("\tIndirect CPU to Screen color expansion\n");
+
+ if(HaveScreenToScreenColorExpandFill)
+ xf86ErrorF("\tScreen to Screen color expansion\n");
+
+ if(HaveSolidTwoPointLine || HaveSolidBresenhamLine)
+ xf86ErrorF("\tSolid Lines\n");
+ else if(HaveSolidHorVertLine)
+ xf86ErrorF("\tSolid Horizontal and Vertical Lines\n");
+
+ if(HaveDashedTwoPointLine || HaveDashedBresenhamLine)
+ xf86ErrorF("\tDashed Lines\n");
+
+ if(HaveImageWriteRect)
+ xf86ErrorF("\tImage Writes\n");
+ else if(HaveScanlineImageWriteRect)
+ xf86ErrorF("\tScanline Image Writes\n");
+
+ }
+
+#define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0)
+
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy &&
+ !xf86IsOptionSet(options, XAAOPT_OFFSCREEN_PIXMAPS)) {
+ XAAMSG("\tOffscreen Pixmaps\n");
+ } else {
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+ }
+
+
+ /************** Mid Level *************/
+
+ /**** ScreenToScreenBitBlt ****/
+
+ if(infoRec->ScreenToScreenBitBlt) {
+ XAAMSG("\tDriver provided ScreenToScreenBitBlt replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->ScreenToScreenBitBlt = XAAScreenToScreenBitBlt;
+ infoRec->ScreenToScreenBitBltFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillSolidRects ****/
+
+ if(infoRec->FillSolidRects) {
+ XAAMSG("\tDriver provided FillSolidRects replacement\n");
+ } else if(HaveSolidFillRect) {
+ infoRec->FillSolidRects = XAAFillSolidRects;
+ infoRec->FillSolidRectsFlags = infoRec->SolidFillFlags;
+ }
+
+ /**** FillSolidSpans ****/
+
+ if(infoRec->FillSolidSpans) {
+ XAAMSG("\tDriver provided FillSolidSpans replacement\n");
+ } else if(HaveSolidFillRect) {
+ infoRec->FillSolidSpans = XAAFillSolidSpans;
+ infoRec->FillSolidSpansFlags = infoRec->SolidFillFlags;
+ }
+
+ /**** FillMono8x8PatternRects ****/
+
+ if(infoRec->FillMono8x8PatternRects) {
+ XAAMSG("\tDriver provided FillMono8x8PatternRects replacement\n");
+ } else if(HaveMono8x8PatternFillRect) {
+ infoRec->FillMono8x8PatternRects =
+ (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillMono8x8PatternRectsScreenOrigin :
+ XAAFillMono8x8PatternRects;
+
+ infoRec->FillMono8x8PatternRectsFlags =
+ infoRec->Mono8x8PatternFillFlags;
+ }
+
+ /**** FillMono8x8PatternSpans ****/
+
+ if(infoRec->FillMono8x8PatternSpans) {
+ XAAMSG("\tDriver provided FillMono8x8PatternSpans replacement\n");
+ } else if(HaveMono8x8PatternFillRect) {
+ infoRec->FillMono8x8PatternSpans =
+ (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillMono8x8PatternSpansScreenOrigin:
+ XAAFillMono8x8PatternSpans;
+
+ infoRec->FillMono8x8PatternSpansFlags =
+ infoRec->Mono8x8PatternFillFlags;
+ }
+
+ /**** FillColor8x8Rects ****/
+
+ if(infoRec->FillColor8x8PatternRects) {
+ XAAMSG("\tDriver provided FillColor8x8PatternRects replacement\n");
+ } else if(HaveColor8x8PatternFillRect) {
+ infoRec->FillColor8x8PatternRects =
+ (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillColor8x8PatternRectsScreenOrigin :
+ XAAFillColor8x8PatternRects;
+
+ infoRec->FillColor8x8PatternRectsFlags =
+ infoRec->Color8x8PatternFillFlags;
+ }
+
+ /**** FillColor8x8Spans ****/
+
+ if(infoRec->FillColor8x8PatternSpans) {
+ XAAMSG("\tDriver provided FillColor8x8PatternSpans replacement\n");
+ } else if(HaveColor8x8PatternFillRect) {
+ infoRec->FillColor8x8PatternSpans =
+ (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillColor8x8PatternSpansScreenOrigin:
+ XAAFillColor8x8PatternSpans;
+
+ infoRec->FillColor8x8PatternSpansFlags =
+ infoRec->Color8x8PatternFillFlags;
+ }
+
+ /**** FillCacheBltRects ****/
+
+ if(infoRec->FillCacheBltRects) {
+ XAAMSG("\tDriver provided FillCacheBltRects replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->FillCacheBltRects = XAAFillCacheBltRects;
+ infoRec->FillCacheBltRectsFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillCacheBltSpans ****/
+
+ if(infoRec->FillCacheBltSpans) {
+ XAAMSG("\tDriver provided FillCacheBltSpans replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->FillCacheBltSpans = XAAFillCacheBltSpans;
+ infoRec->FillCacheBltSpansFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillCacheExpandRects ****/
+
+ if(infoRec->FillCacheExpandRects) {
+ XAAMSG("\tDriver provided FillCacheExpandRects replacement\n");
+ } else if(HaveScreenToScreenColorExpandFill) {
+ infoRec->FillCacheExpandRects = XAAFillCacheExpandRects;
+ infoRec->FillCacheExpandRectsFlags =
+ infoRec->ScreenToScreenColorExpandFillFlags;
+ }
+
+ /**** FillCacheExpandSpans ****/
+
+ if(infoRec->FillCacheExpandSpans) {
+ XAAMSG("\tDriver provided FillCacheExpandSpans replacement\n");
+ } else if(HaveScreenToScreenColorExpandFill) {
+ infoRec->FillCacheExpandSpans = XAAFillCacheExpandSpans;
+ infoRec->FillCacheExpandSpansFlags =
+ infoRec->ScreenToScreenColorExpandFillFlags;
+ }
+
+ /**** FillColorExpandRects ****/
+
+ if(infoRec->FillColorExpandRects) {
+ XAAMSG("\tDriver provided FillColorExpandRects replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsMSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsLSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsLSBFirst;
+ }
+ }
+ infoRec->FillColorExpandRectsFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRects3MSBFirst;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRects3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRectsMSBFirst;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRectsLSBFirst;
+ }
+ infoRec->FillColorExpandRectsFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+ /**** FillColorExpandSpans ****/
+
+ if(infoRec->FillColorExpandSpans) {
+ XAAMSG("\tDriver provided FillColorExpandSpans replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansMSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansLSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansLSBFirst;
+ }
+ }
+ infoRec->FillColorExpandSpansFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpans3MSBFirst;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpans3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpansMSBFirst;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpansLSBFirst;
+ }
+ infoRec->FillColorExpandSpansFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+ /**** FillImageWriteRects ****/
+
+ if(infoRec->FillImageWriteRects) {
+ XAAMSG("\tDriver provided FillImageWriteRects replacement\n");
+ } else if(HaveImageWriteRect &&
+ (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ infoRec->FillImageWriteRects = XAAFillImageWriteRects;
+ infoRec->FillImageWriteRectsFlags = infoRec->ImageWriteFlags;
+ }
+
+ /**** WriteBitmap ****/
+
+ if(infoRec->WriteBitmap &&
+ !xf86IsOptionSet(options, XAAOPT_WRITE_BITMAP)) {
+ XAAMSG("\tDriver provided WriteBitmap replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpand3MSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpand3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpand3LSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpand3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpandMSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpandMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpandLSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpandLSBFirst;
+ }
+ }
+ infoRec->WriteBitmapFlags = infoRec->CPUToScreenColorExpandFillFlags;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpand3MSBFirst;
+ else
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpand3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpandMSBFirst;
+ else
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpandLSBFirst;
+ }
+ infoRec->WriteBitmapFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ } else
+ infoRec->WriteBitmap = NULL;
+
+ /**** TE Glyphs ****/
+
+ if (infoRec->TEGlyphRenderer) {
+ XAAMSG("\tDriver provided TEGlyphRenderer replacement\n");
+ } else if (HaveColorExpansion) {
+ infoRec->TEGlyphRendererFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+
+ if (infoRec->TEGlyphRendererFlags & TRIPLE_BITS_24BPP) {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRenderer3MSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRenderer3MSBFirst;
+ } else {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRenderer3LSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRenderer3LSBFirst;
+ }
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & RGB_EQUAL)) {
+ infoRec->TEGlyphRendererFlags &= ~RGB_EQUAL;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support RGB_EQUAL"
+ " without solid fills\n");
+ }
+ } else {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererMSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererMSBFirst;
+ } else {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererLSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererLSBFirst;
+ }
+ }
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support TRANPARENCY_ONLY"
+ " without solid fills\n");
+ }
+
+ } else if (HaveScanlineColorExpansion) {
+ infoRec->TEGlyphRendererFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+
+ if (infoRec->TEGlyphRendererFlags & TRIPLE_BITS_24BPP) {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanline3MSBFirst;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanline3LSBFirst;
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & RGB_EQUAL)) {
+ infoRec->TEGlyphRendererFlags &= ~RGB_EQUAL;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support RGB_EQUAL"
+ " without solid fills\n");
+ }
+ } else {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanlineMSBFirst;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanlineLSBFirst;
+ }
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support TRANPARENCY_ONLY"
+ " without solid fills\n");
+ }
+ }
+
+ /**** NonTE Glyphs ****/
+
+ if(infoRec->NonTEGlyphRenderer) {
+ XAAMSG("\tDriver provided NonTEGlyphRenderer replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
+ infoRec->NonTEGlyphRenderer = XAANonTEGlyphRenderer;
+ infoRec->NonTEGlyphRendererFlags = infoRec->WriteBitmapFlags;
+ }
+
+ /**** WritePixmap ****/
+
+ if(infoRec->WritePixmap &&
+ !xf86IsOptionSet(options, XAAOPT_WRITE_PIXMAP)) {
+ XAAMSG("\tDriver provided WritePixmap replacement\n");
+ } else if(HaveImageWriteRect) {
+ infoRec->WritePixmap = XAAWritePixmap;
+ infoRec->WritePixmapFlags =
+ infoRec->ImageWriteFlags | CONVERT_32BPP_TO_24BPP;
+ } else if(HaveScanlineImageWriteRect) {
+ infoRec->WritePixmap = XAAWritePixmapScanline;
+ infoRec->WritePixmapFlags = infoRec->ScanlineImageWriteFlags;
+ } else
+ infoRec->WritePixmap = NULL;
+
+ /**** ReadPixmap ****/
+
+ if(infoRec->ReadPixmap) {
+ XAAMSG("\tDriver provided ReadPixmap replacement\n");
+ }
+
+
+ /************** GC Level *************/
+
+ /**** CopyArea ****/
+
+ if(infoRec->CopyArea) {
+ XAAMSG("\tDriver provided GC level CopyArea replacement\n");
+ } else if(infoRec->ScreenToScreenBitBlt) {
+ infoRec->CopyArea = XAACopyArea;
+ infoRec->CopyAreaFlags = infoRec->ScreenToScreenBitBltFlags;
+
+ /* most GC level primitives use one mid-level primitive so
+ the GC level primitive gets the mid-level primitive flag
+ and we use that at GC validation time. But CopyArea uses
+ more than one mid-level primitive so we have to essentially
+ do a GC validation every time that primitive is used.
+ The CopyAreaFlags would only be used for filtering out the
+ common denominators. Here we assume that if you don't do
+ ScreenToScreenBitBlt you aren't going to do the others.
+ We also assume that ScreenToScreenBitBlt has the least
+ restrictions. */
+ }
+
+ if(infoRec->CopyPlane) {
+ XAAMSG("\tDriver provided GC level CopyPlane replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) {
+ infoRec->CopyPlane = XAACopyPlaneColorExpansion;
+ infoRec->CopyPlaneFlags = infoRec->WriteBitmapFlags;
+ }
+
+ if(infoRec->PushPixelsSolid) {
+ XAAMSG("\tDriver provided GC level PushPixelsSolid replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
+ infoRec->PushPixelsSolid = XAAPushPixelsSolidColorExpansion;
+ infoRec->PushPixelsFlags = infoRec->WriteBitmapFlags;
+ }
+
+ if(infoRec->FillSolidRects) {
+ if(!infoRec->PolyFillRectSolid) {
+ infoRec->PolyFillRectSolid = XAAPolyFillRect;
+ infoRec->PolyFillRectSolidFlags = infoRec->FillSolidRectsFlags;
+ }
+ }
+ if(infoRec->FillSolidSpans) {
+ if(!infoRec->FillSpansSolid) {
+ infoRec->FillSpansSolid = XAAFillSpans;
+ infoRec->FillSpansSolidFlags = infoRec->FillSolidSpansFlags;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
+ infoRec->FillCacheExpandRects) {
+ if(!infoRec->PolyFillRectStippled) {
+
+ infoRec->PolyFillRectStippled = XAAPolyFillRect;
+ infoRec->PolyFillRectStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
+ infoRec->FillCacheExpandSpans) {
+ if(!infoRec->FillSpansStippled) {
+
+ infoRec->FillSpansStippled = XAAFillSpans;
+ infoRec->FillSpansStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
+ infoRec->FillCacheExpandRects) {
+ if(!infoRec->PolyFillRectOpaqueStippled) {
+
+ infoRec->PolyFillRectOpaqueStippled = XAAPolyFillRect;
+ infoRec->PolyFillRectOpaqueStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
+ infoRec->FillCacheExpandSpans) {
+ if(!infoRec->FillSpansOpaqueStippled) {
+
+ infoRec->FillSpansOpaqueStippled = XAAFillSpans;
+ infoRec->FillSpansOpaqueStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillImageWriteRects) {
+ if(!infoRec->PolyFillRectTiled) {
+
+ infoRec->PolyFillRectTiled = XAAPolyFillRect;
+ infoRec->PolyFillRectTiledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans) {
+ if(!infoRec->FillSpansTiled) {
+
+ infoRec->FillSpansTiled = XAAFillSpans;
+ infoRec->FillSpansTiledFlags = 0;
+ }
+ }
+
+ if(infoRec->TEGlyphRenderer &&
+ !(infoRec->TEGlyphRendererFlags & NO_TRANSPARENCY)) {
+
+ if(!infoRec->PolyText8TE) {
+ infoRec->PolyText8TE = XAAPolyText8TEColorExpansion;
+ infoRec->PolyText8TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyText16TE) {
+ infoRec->PolyText16TE = XAAPolyText16TEColorExpansion;
+ infoRec->PolyText16TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyGlyphBltTE) {
+ infoRec->PolyGlyphBltTE = XAAPolyGlyphBltTEColorExpansion;
+ infoRec->PolyGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->TEGlyphRenderer &&
+ !(infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+
+ if(!infoRec->ImageText8TE) {
+ infoRec->ImageText8TE = XAAImageText8TEColorExpansion;
+ infoRec->ImageText8TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageText16TE) {
+ infoRec->ImageText16TE = XAAImageText16TEColorExpansion;
+ infoRec->ImageText16TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageGlyphBltTE) {
+ infoRec->ImageGlyphBltTE = XAAImageGlyphBltTEColorExpansion;
+ infoRec->ImageGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->NonTEGlyphRenderer) {
+ if(!infoRec->PolyText8NonTE) {
+ infoRec->PolyText8NonTE = XAAPolyText8NonTEColorExpansion;
+ infoRec->PolyText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyText16NonTE) {
+ infoRec->PolyText16NonTE = XAAPolyText16NonTEColorExpansion;
+ infoRec->PolyText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ if(!infoRec->PolyGlyphBltNonTE) {
+ infoRec->PolyGlyphBltNonTE = XAAPolyGlyphBltNonTEColorExpansion;
+ infoRec->PolyGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->NonTEGlyphRenderer && HaveSolidFillRect) {
+ if(!infoRec->ImageText8NonTE) {
+ infoRec->ImageText8NonTE = XAAImageText8NonTEColorExpansion;
+ infoRec->ImageText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageText16NonTE) {
+ infoRec->ImageText16NonTE = XAAImageText16NonTEColorExpansion;
+ infoRec->ImageText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageGlyphBltNonTE) {
+ infoRec->ImageGlyphBltNonTE = XAAImageGlyphBltNonTEColorExpansion;
+ infoRec->ImageGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ }
+
+ if(!infoRec->PolyRectangleThinSolid && HaveSolidHorVertLine) {
+ infoRec->PolyRectangleThinSolid = XAAPolyRectangleThinSolid;
+ infoRec->PolyRectangleThinSolidFlags = infoRec->SolidLineFlags;
+ }
+
+ if(!infoRec->FillPolygonSolid && HaveSolidFillRect) {
+ infoRec->FillPolygonSolid = XAAFillPolygonSolid;
+ infoRec->FillPolygonSolidFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonStippled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonStippled = XAAFillPolygonStippled;
+ infoRec->FillPolygonStippledFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonOpaqueStippled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonOpaqueStippled = XAAFillPolygonStippled;
+ infoRec->FillPolygonOpaqueStippledFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonTiled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonTiled = XAAFillPolygonTiled;
+ infoRec->FillPolygonTiledFlags = infoRec->SolidFillFlags;
+ }
+
+
+ if(!infoRec->PolyFillArcSolid && HaveSolidFillRect) {
+ infoRec->PolyFillArcSolid = XAAPolyFillArcSolid;
+ infoRec->PolyFillArcSolidFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->PolylinesWideSolid && HaveSolidFillRect) {
+ infoRec->PolylinesWideSolid = XAAPolylinesWideSolid;
+ infoRec->PolylinesWideSolidFlags =
+ infoRec->SolidFillFlags | GXCOPY_ONLY;
+ }
+
+ if(!infoRec->PutImage && (infoRec->WritePixmap ||
+ (infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)))) {
+ infoRec->PutImage = XAAPutImage;
+
+ /* See comment for CopyArea above. But here we make fewer
+ assumptions. The driver can provide the PutImageFlags if
+ it wants too */
+ }
+
+ if(HaveSolidHorVertLine &&
+ (HaveSolidBresenhamLine || (HaveSolidTwoPointLine &&
+ (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE)))){
+ if(!infoRec->PolylinesThinSolid) {
+ infoRec->PolylinesThinSolid = XAAPolyLines;
+ infoRec->PolylinesThinSolidFlags = infoRec->SolidLineFlags;
+ }
+ if(!infoRec->PolySegmentThinSolid) {
+ infoRec->PolySegmentThinSolid = XAAPolySegment;
+ infoRec->PolySegmentThinSolidFlags = infoRec->SolidLineFlags;
+ }
+ }
+
+ if(HaveDashedBresenhamLine || (HaveDashedTwoPointLine &&
+ (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE))){
+ if(!infoRec->PolylinesThinDashed) {
+ infoRec->PolylinesThinDashed = XAAPolyLinesDashed;
+ infoRec->PolylinesThinDashedFlags = infoRec->DashedLineFlags;
+ }
+ if(!infoRec->PolySegmentThinDashed) {
+ infoRec->PolySegmentThinDashed = XAAPolySegmentDashed;
+ infoRec->PolySegmentThinDashedFlags = infoRec->DashedLineFlags;
+ }
+ }
+
+ if(infoRec->PolylinesThinDashed || infoRec->PolySegmentThinDashed) {
+ if(!infoRec->ComputeDash)
+ infoRec->ComputeDash = XAAComputeDash;
+ }
+
+#ifdef RENDER
+ {
+ Bool haveTexture = infoRec->CPUToScreenTextureFormats &&
+ infoRec->SetupForCPUToScreenTexture &&
+ infoRec->SubsequentCPUToScreenTexture;
+ Bool haveAlphaTexture = infoRec->CPUToScreenAlphaTextureFormats &&
+ infoRec->SetupForCPUToScreenAlphaTexture &&
+ infoRec->SubsequentCPUToScreenAlphaTexture;
+
+ if(!infoRec->Composite && (haveTexture || haveAlphaTexture))
+ infoRec->Composite = XAADoComposite;
+
+ if(!infoRec->Glyphs && infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY))
+ {
+ infoRec->Glyphs = XAADoGlyphs;
+ }
+ }
+#endif
+
+ /************ Validation Functions **************/
+
+ if(!infoRec->ValidateCopyArea && infoRec->CopyArea) {
+ infoRec->CopyAreaMask = GCWhenForced;
+ if((infoRec->CopyAreaFlags & GXCOPY_ONLY) ||
+ (infoRec->CopyAreaFlags & ROP_NEEDS_SOURCE))
+ infoRec->CopyAreaMask |= GCFunction;
+ if(infoRec->CopyAreaFlags & NO_PLANEMASK)
+ infoRec->CopyAreaMask |= GCPlaneMask;
+ infoRec->ValidateCopyArea = XAAValidateCopyArea;
+ }
+
+ if(!infoRec->ValidateCopyPlane && infoRec->CopyPlane) {
+ infoRec->CopyPlaneMask = GCWhenForced;
+ if((infoRec->CopyPlaneFlags & GXCOPY_ONLY) ||
+ (infoRec->CopyPlaneFlags & ROP_NEEDS_SOURCE))
+ infoRec->CopyPlaneMask |= GCFunction;
+ if(infoRec->CopyPlaneFlags & NO_PLANEMASK)
+ infoRec->CopyPlaneMask |= GCPlaneMask;
+ if(infoRec->CopyPlaneFlags & RGB_EQUAL)
+ infoRec->CopyPlaneMask |= GCForeground | GCBackground;
+ infoRec->ValidateCopyPlane = XAAValidateCopyPlane;
+ }
+
+ if(!infoRec->ValidatePutImage && infoRec->PutImage) {
+ infoRec->PutImageMask = GCWhenForced;
+ if((infoRec->PutImageFlags & GXCOPY_ONLY) ||
+ (infoRec->PutImageFlags & ROP_NEEDS_SOURCE))
+ infoRec->PutImageMask |= GCFunction;
+ if(infoRec->PutImageFlags & NO_PLANEMASK)
+ infoRec->PutImageMask |= GCPlaneMask;
+ if(infoRec->PutImageFlags & RGB_EQUAL)
+ infoRec->PutImageMask |= GCForeground | GCBackground;
+ infoRec->ValidatePutImage = XAAValidatePutImage;
+ }
+
+
+ if(!infoRec->ValidatePushPixels && infoRec->PushPixelsSolid) {
+ infoRec->PushPixelsMask = GCFillStyle;
+ if((infoRec->PushPixelsFlags & GXCOPY_ONLY) ||
+ (infoRec->PushPixelsFlags & ROP_NEEDS_SOURCE) ||
+ (infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY))
+ infoRec->PushPixelsMask |= GCFunction;
+ if(infoRec->PushPixelsFlags & NO_PLANEMASK)
+ infoRec->PushPixelsMask |= GCPlaneMask;
+ if(infoRec->PushPixelsFlags & RGB_EQUAL)
+ infoRec->PushPixelsMask |= GCForeground;
+ infoRec->ValidatePushPixels = XAAValidatePushPixels;
+ }
+
+ /* By default XAA assumes the FillSpans, PolyFillRects, FillPolygon
+ and PolyFillArcs have the same restrictions. If you supply GC
+ level replacements for any of these and alter this relationship
+ you may need to supply replacement validation routines */
+
+ if(!infoRec->ValidateFillSpans &&
+ (infoRec->FillSpansSolid || infoRec->FillSpansStippled ||
+ infoRec->FillSpansOpaqueStippled || infoRec->FillSpansTiled)) {
+
+ int compositeFlags = infoRec->FillSpansSolidFlags |
+ infoRec->FillSpansStippledFlags |
+ infoRec->FillSpansOpaqueStippledFlags |
+ infoRec->FillSpansTiledFlags;
+
+ infoRec->FillSpansMask = GCFillStyle | GCTile | GCStipple;
+
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE))
+ infoRec->FillSpansMask |= GCFunction;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->FillSpansMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->FillSpansMask |= GCForeground;
+ infoRec->ValidateFillSpans = XAAValidateFillSpans;
+ }
+
+ /* By default XAA only provides Validations for the GlyphBlt
+ functions and not the text higher up. This is because the
+ Text8/16 and GlyphBlt are linked. If you break this linkage,
+ you may need to have the driver supply its own Validation
+ routines */
+
+ if(!infoRec->ValidatePolyGlyphBlt &&
+ (infoRec->PolyGlyphBltTE || infoRec->PolyGlyphBltNonTE)) {
+ int compositeFlags = infoRec->PolyGlyphBltTEFlags |
+ infoRec->PolyGlyphBltNonTEFlags;
+
+ infoRec->PolyGlyphBltMask = GCFillStyle | GCFont;
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE) ||
+ (infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY))
+ infoRec->PolyGlyphBltMask |= GCFunction;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->PolyGlyphBltMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->PolyGlyphBltMask |= GCForeground;
+ infoRec->ValidatePolyGlyphBlt = XAAValidatePolyGlyphBlt;
+ }
+
+ if(!infoRec->ValidateImageGlyphBlt &&
+ (infoRec->ImageGlyphBltTE || infoRec->ImageGlyphBltNonTE)) {
+ int compositeFlags = infoRec->ImageGlyphBltTEFlags |
+ infoRec->ImageGlyphBltNonTEFlags;
+
+ if(infoRec->ImageGlyphBltNonTE)
+ compositeFlags |= infoRec->SolidFillFlags;
+
+ infoRec->ImageGlyphBltMask = GCFont;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->ImageGlyphBltMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->ImageGlyphBltMask |= GCForeground | GCBackground;
+ infoRec->ValidateImageGlyphBlt = XAAValidateImageGlyphBlt;
+ }
+
+ /* By default XAA only provides a Validation function for the
+ Polylines and does segments and polylines at the same time */
+
+ if(!infoRec->ValidatePolylines && infoRec->ValidateFillSpans) {
+ int compositeFlags = infoRec->PolyRectangleThinSolidFlags |
+ infoRec->PolylinesWideSolidFlags |
+ infoRec->PolylinesThinSolidFlags |
+ infoRec->PolySegmentThinSolidFlags |
+ infoRec->PolySegmentThinDashedFlags |
+ infoRec->PolylinesThinDashedFlags;
+
+ infoRec->ValidatePolylines = XAAValidatePolylines;
+ infoRec->PolylinesMask =
+ infoRec->FillSpansMask | GCLineStyle | GCLineWidth;
+
+ if(infoRec->PolySegmentThinDashed || infoRec->PolylinesThinDashed)
+ infoRec->PolylinesMask |= GCDashList;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->PolylinesMask |= GCPlaneMask;
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE))
+ infoRec->PolylinesMask |= GCFunction;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->PolylinesMask |= GCForeground;
+ }
+
+
+ /**** Fill choosers ****/
+
+ if(!infoRec->StippledFillChooser)
+ infoRec->StippledFillChooser = XAAStippledFillChooser;
+
+ if(!infoRec->OpaqueStippledFillChooser)
+ infoRec->OpaqueStippledFillChooser = XAAOpaqueStippledFillChooser;
+
+ if(!infoRec->TiledFillChooser)
+ infoRec->TiledFillChooser = XAATiledFillChooser;
+
+
+ /**** Setup the pixmap cache ****/
+
+ if(infoRec->WriteBitmapToCache) {}
+ else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))
+ infoRec->WriteBitmapToCache = XAAWriteBitmapToCache;
+ else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
+ infoRec->WriteBitmapToCache = XAAWriteBitmapToCacheLinear;
+ else
+ infoRec->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+
+ if(infoRec->WritePixmapToCache) {}
+ else if(infoRec->WritePixmap && !(infoRec->WritePixmapFlags & NO_GXCOPY))
+ infoRec->WritePixmapToCache = XAAWritePixmapToCache;
+ else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
+ infoRec->WritePixmapToCache = XAAWritePixmapToCacheLinear;
+ else
+ infoRec->Flags &= ~PIXMAP_CACHE;
+
+ if (xf86IsOptionSet(options, XAAOPT_PIXMAP_CACHE))
+ infoRec->Flags &= ~PIXMAP_CACHE;
+
+ if(infoRec->WriteMono8x8PatternToCache) {}
+ else if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) {
+ if(infoRec->WritePixmapToCache)
+ infoRec->WriteMono8x8PatternToCache = XAAWriteMono8x8PatternToCache;
+ else
+ infoRec->PixmapCacheFlags &= ~CACHE_MONO_8x8;
+ }
+
+ if(infoRec->WriteColor8x8PatternToCache) {}
+ else if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) {
+ if(infoRec->WritePixmapToCache && infoRec->WriteBitmapToCache)
+ infoRec->WriteColor8x8PatternToCache = XAAWriteColor8x8PatternToCache;
+ else
+ infoRec->PixmapCacheFlags &= ~CACHE_COLOR_8x8;
+ }
+
+ if(infoRec->CachePixelGranularity < 0) {
+ switch(pScrn->bitsPerPixel) {
+ case 24:
+ case 8: infoRec->CachePixelGranularity = 4; break;
+ case 16: infoRec->CachePixelGranularity = 2; break;
+ case 32: infoRec->CachePixelGranularity = 1; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ infoRec->CachePixelGranularity *= 2;
+ }
+
+ xfree(options);
+
+ if(!infoRec->CacheTile && infoRec->WritePixmapToCache)
+ infoRec->CacheTile = XAACacheTile;
+ if(!infoRec->CacheMonoStipple && infoRec->WritePixmapToCache)
+ infoRec->CacheMonoStipple = XAACacheMonoStipple;
+ if(!infoRec->CacheStipple && infoRec->WriteBitmapToCache)
+ infoRec->CacheStipple = XAACacheStipple;
+ if(!infoRec->CacheMono8x8Pattern && infoRec->WriteMono8x8PatternToCache)
+ infoRec->CacheMono8x8Pattern = XAACacheMono8x8Pattern;
+ if(!infoRec->CacheColor8x8Pattern && infoRec->WriteColor8x8PatternToCache)
+ infoRec->CacheColor8x8Pattern = XAACacheColor8x8Pattern;
+
+ if((infoRec->Flags & PIXMAP_CACHE) && !infoRec->InitPixmapCache) {
+ infoRec->InitPixmapCache = XAAInitPixmapCache;
+ infoRec->ClosePixmapCache = XAAClosePixmapCache;
+ }
+
+ return TRUE;
+}
diff --git a/hw/xfree86/xaa/xaaLine.c b/hw/xfree86/xaa/xaaLine.c
new file mode 100644
index 000000000..2084e8d61
--- /dev/null
+++ b/hw/xfree86/xaa/xaaLine.c
@@ -0,0 +1,390 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaLine.c,v 1.6 2002/09/18 18:15:00 martin Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+#ifdef POLYSEGMENT
+XAAPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+#else
+XAAPolyLines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode, /* Origin or Previous */
+ int npt, /* number of points */
+ DDXPointPtr pptInit
+#endif
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pboxInit = REGION_RECTS(pGC->pCompositeClip);
+ int nboxInit = REGION_NUM_RECTS(pGC->pCompositeClip);
+ unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ int nbox;
+ BoxPtr pbox;
+#ifndef POLYSEGMENT
+ DDXPointPtr ppt;
+#endif
+ int x1, x2, y1, y2, tmp, len;
+
+ if(!nboxInit)
+ return;
+
+ if (infoRec->SolidLineFlags & LINE_LIMIT_COORDS) {
+ int minValX = infoRec->SolidLineLimits.x1;
+ int maxValX = infoRec->SolidLineLimits.x2;
+ int minValY = infoRec->SolidLineLimits.y1;
+ int maxValY = infoRec->SolidLineLimits.y2;
+#ifdef POLYSEGMENT
+ int n = nseg;
+ xSegment *s = pSeg;
+
+ while (n--)
+#else
+ int n = npt;
+ int xorgtmp = xorg;
+ int yorgtmp = yorg;
+
+ ppt = pptInit;
+ x2 = ppt->x + xorgtmp;
+ y2 = ppt->y + yorgtmp;
+ while (--n)
+#endif
+ {
+#ifdef POLYSEGMENT
+ x1 = s->x1 + xorg;
+ y1 = s->y1 + yorg;
+ x2 = s->x2 + xorg;
+ y2 = s->y2 + yorg;
+ s++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorgtmp = x1;
+ yorgtmp = y1;
+ }
+ x2 = ppt->x + xorgtmp;
+ y2 = ppt->y + yorgtmp;
+#endif
+ if (x1 > maxValX || x1 < minValX ||
+ x2 > maxValX || x2 < minValX ||
+ y1 > maxValY || y1 < minValY ||
+ y2 > maxValY || y2 < minValY) {
+#ifdef POLYSEGMENT
+ XAAFallbackOps.PolySegment(pDrawable, pGC, nseg, pSeg);
+#else
+ XAAFallbackOps.Polylines(pDrawable, pGC, mode, npt, pptInit);
+#endif
+ return;
+ }
+ }
+ }
+
+ (*infoRec->SetupForSolidLine)(infoRec->pScrn, pGC->fgPixel,
+ pGC->alu, pGC->planemask);
+
+#ifdef POLYSEGMENT
+ while (nseg--)
+#else
+ ppt = pptInit;
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+ while(--npt)
+#endif
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+
+#ifdef POLYSEGMENT
+ x1 = pSeg->x1 + xorg;
+ y1 = pSeg->y1 + yorg;
+ x2 = pSeg->x2 + xorg;
+ y2 = pSeg->y2 + yorg;
+ pSeg++;
+#else
+ x1 = x2;
+ y1 = y2;
+ ++ppt;
+ if (mode == CoordModePrevious) {
+ xorg = x1;
+ yorg = y1;
+ }
+ x2 = ppt->x + xorg;
+ y2 = ppt->y + yorg;
+#endif
+
+ if (x1 == x2) { /* vertical line */
+ /* make the line go top to bottom of screen, keeping
+ endpoint semantics
+ */
+ if (y1 > y2) {
+ tmp = y2;
+ y2 = y1 + 1;
+ y1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast) y1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast) y2++;
+#endif
+ /* get to first band that might contain part of line */
+ while(nbox && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* stop when lower edge of box is beyond end of line */
+ while(nbox && (y2 >= pbox->y1)) {
+ if ((x1 >= pbox->x1) && (x1 < pbox->x2)) {
+ tmp = max(y1, pbox->y1);
+ len = min(y2, pbox->y2) - tmp;
+ if (len) (*infoRec->SubsequentSolidHorVertLine)(
+ infoRec->pScrn, x1, tmp, len, DEGREES_270);
+ }
+ nbox--;
+ pbox++;
+ }
+#ifndef POLYSEGMENT
+ y2 = ppt->y + yorg;
+#endif
+ } else if (y1 == y2) { /* horizontal line */
+ /* force line from left to right, keeping endpoint semantics */
+ if (x1 > x2) {
+ tmp = x2;
+ x2 = x1 + 1;
+ x1 = tmp + 1;
+#ifdef POLYSEGMENT
+ if (pGC->capStyle != CapNotLast) x1--;
+#endif
+ }
+#ifdef POLYSEGMENT
+ else if (pGC->capStyle != CapNotLast) x2++;
+#endif
+
+ /* find the correct band */
+ while(nbox && (pbox->y2 <= y1)) {
+ pbox++;
+ nbox--;
+ }
+
+ /* try to draw the line, if we haven't gone beyond it */
+ if (nbox && (pbox->y1 <= y1)) {
+ int orig_y = pbox->y1;
+ /* when we leave this band, we're done */
+ while(nbox && (orig_y == pbox->y1)) {
+ if (pbox->x2 <= x1) {
+ /* skip boxes until one might contain start point */
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ /* stop if left of box is beyond right of line */
+ if (pbox->x1 >= x2) {
+ nbox = 0;
+ break;
+ }
+
+ tmp = max(x1, pbox->x1);
+ len = min(x2, pbox->x2) - tmp;
+ if (len) (*infoRec->SubsequentSolidHorVertLine)(
+ infoRec->pScrn, tmp, y1, len, DEGREES_0);
+ nbox--;
+ pbox++;
+ }
+ }
+#ifndef POLYSEGMENT
+ x2 = ppt->x + xorg;
+#endif
+ } else{ /* sloped line */
+ unsigned int oc1, oc2;
+ int dmin, dmaj, e, octant;
+
+ if (infoRec->SubsequentSolidBresenhamLine) {
+ if((dmaj = x2 - x1) < 0) {
+ dmaj = -dmaj;
+ octant = XDECREASING;
+ } else octant = 0;
+
+ if((dmin = y2 - y1) < 0) {
+ dmin = -dmin;
+ octant |= YDECREASING;
+ }
+
+ if(dmin >= dmaj){
+ tmp = dmin; dmin = dmaj; dmaj = tmp;
+ octant |= YMAJOR;
+ }
+
+ e = -dmaj - ((bias >> octant) & 1);
+ len = dmaj;
+ dmin <<= 1;
+ dmaj <<= 1;
+ } else { /* Muffle compiler */
+ dmin = dmaj = e = octant = len = 0;
+ }
+
+ while(nbox--) {
+ oc1 = oc2 = 0;
+ OUTCODES(oc1, x1, y1, pbox);
+ OUTCODES(oc2, x2, y2, pbox);
+ if (!(oc1 | oc2)) { /* unclipped */
+ if(infoRec->SubsequentSolidTwoPointLine) {
+ (*infoRec->SubsequentSolidTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST
+ );
+ } else {
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant);
+ }
+ break;
+ } else if (oc1 & oc2) { /* completely clipped */
+ pbox++;
+ } else if (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE) {
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ pbox->x1, pbox->y1, pbox->x2 - 1, pbox->y2 - 1);
+
+ if(infoRec->SubsequentSolidBresenhamLine) {
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ infoRec->pScrn, x1, y1, dmaj, dmin, e,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? (len+1) :
+#endif
+ len, octant);
+ } else {
+ (*infoRec->SubsequentSolidTwoPointLine)(
+ infoRec->pScrn, x1, y1, x2, y2,
+#ifdef POLYSEGMENT
+ (pGC->capStyle != CapNotLast) ? 0 :
+#endif
+ OMIT_LAST
+ );
+ }
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+ pbox++;
+ } else {
+ int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
+ int clip1 = 0, clip2 = 0;
+ int err, adx, ady;
+
+ if(octant & YMAJOR) {
+ ady = dmaj >> 1;
+ adx = dmin >> 1;
+ } else {
+ ady = dmin >> 1;
+ adx = dmaj >> 1;
+ }
+
+ if (miZeroClipLine(pbox->x1, pbox->y1,
+ pbox->x2 - 1, pbox->y2 - 1,
+ &new_x1, &new_y1, &new_x2, &new_y2,
+ adx, ady, &clip1, &clip2,
+ octant, bias, oc1, oc2) == -1)
+ {
+ pbox++;
+ continue;
+ }
+
+ if (octant & YMAJOR)
+ len = abs(new_y2 - new_y1);
+ else
+ len = abs(new_x2 - new_x1);
+#ifdef POLYSEGMENT
+ if (clip2 != 0 || pGC->capStyle != CapNotLast)
+ len++;
+#else
+ len += (clip2 != 0);
+#endif
+ if (len) {
+ int abserr, clipdx, clipdy;
+ /* unwind bresenham error term to first point */
+ if (clip1) {
+ clipdx = abs(new_x1 - x1);
+ clipdy = abs(new_y1 - y1);
+
+ if (octant & YMAJOR)
+ err = e + clipdy*dmin - clipdx*dmaj;
+ else
+ err = e + clipdx*dmin - clipdy*dmaj;
+ } else
+ err = e;
+
+#define range infoRec->SolidBresenhamLineErrorTermBits
+ abserr = abs(err);
+ while((abserr & range) ||
+ (dmaj & range) ||
+ (dmin & range)) {
+ dmin >>= 1;
+ dmaj >>= 1;
+ abserr >>= 1;
+ err /= 2;
+ }
+
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ infoRec->pScrn, new_x1, new_y1,
+ dmaj, dmin, err, len, octant);
+ }
+ pbox++;
+ }
+ } /* while (nbox--) */
+ } /* sloped line */
+ } /* while (nline--) */
+
+#ifndef POLYSEGMENT
+ /* paint the last point if the end style isn't CapNotLast.
+ (Assume that a projecting, butt, or round cap that is one
+ pixel wide is the same as the single pixel of the endpoint.)
+ */
+
+ if ((pGC->capStyle != CapNotLast) &&
+ ((ppt->x + xorg != pptInit->x + pDrawable->x) ||
+ (ppt->y + yorg != pptInit->y + pDrawable->y) ||
+ (ppt == pptInit + 1)))
+ {
+ nbox = nboxInit;
+ pbox = pboxInit;
+ while (nbox--)
+ {
+ if ((x2 >= pbox->x1) && (y2 >= pbox->y1) &&
+ (x2 < pbox->x2) && (y2 < pbox->y2))
+ {
+ (*infoRec->SubsequentSolidHorVertLine)(
+ infoRec->pScrn, x2, y2, 1, DEGREES_0);
+ break;
+ }
+ else
+ pbox++;
+ }
+ }
+#endif
+
+ SET_SYNC_FLAG(infoRec);
+}
+
diff --git a/hw/xfree86/xaa/xaaLineMisc.c b/hw/xfree86/xaa/xaaLineMisc.c
new file mode 100644
index 000000000..370921002
--- /dev/null
+++ b/hw/xfree86/xaa/xaaLineMisc.c
@@ -0,0 +1,148 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaLineMisc.c,v 1.5 1999/01/14 13:05:27 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+XAASolidHorVertLineAsRects(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, len, 1);
+ else
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, len);
+}
+
+
+void
+XAASolidHorVertLineAsTwoPoint(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ len--;
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x + len, y, 0);
+ else
+ (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x, y + len, 0);
+}
+
+void
+XAASolidHorVertLineAsBresenham(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ pScrn, x, y, len << 1, 0, -len, len, 0);
+ else
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ pScrn, x, y, len << 1, 0, -len, len, YMAJOR);
+}
+
+
+void
+XAAComputeDash(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;
+ Bool EvenDash = (pGC->numInDashList & 0x01) ? FALSE : TRUE;
+ int PatternLength = 0;
+ unsigned char* DashPtr = (unsigned char*)pGC->dash;
+ CARD32 *ptr;
+ int count = pGC->numInDashList;
+ int shift, value, direction;
+ Bool set;
+
+ if(pGCPriv->DashPattern)
+ xfree(pGCPriv->DashPattern);
+
+ pGCPriv->DashPattern = NULL;
+ pGCPriv->DashLength = 0;
+
+ while(count--)
+ PatternLength += *(DashPtr++);
+
+ if(!EvenDash)
+ PatternLength <<= 1;
+
+ if(PatternLength > infoRec->DashPatternMaxLength)
+ return;
+
+ if((infoRec->DashedLineFlags & LINE_PATTERN_POWER_OF_2_ONLY) &&
+ (PatternLength & (PatternLength - 1)))
+ return;
+
+ pGCPriv->DashPattern = xcalloc((PatternLength + 31) >> 5, 4);
+ if(!pGCPriv->DashPattern) return;
+ pGCPriv->DashLength = PatternLength;
+
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED)) {
+ direction = 1;
+ set = TRUE;
+ DashPtr = (unsigned char*)pGC->dash;
+ } else {
+ direction = -1;
+ set = FALSE;
+ DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList - 1;
+ }
+
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_MSBFIRST_MSBJUSTIFIED))
+ shift = 32 - (PatternLength & 31);
+ else
+ shift = 0;
+
+ ptr = (CARD32*)(pGCPriv->DashPattern);
+
+CONCATENATE:
+
+ count = pGC->numInDashList;
+
+ while(count--) {
+ value = *DashPtr;
+ DashPtr += direction;
+ while(value) {
+ if(value < (32 - shift)) {
+ if(set) *ptr |= XAAShiftMasks[value] << shift;
+ shift += value;
+ break;
+ } else {
+ if(set) *ptr |= ~0L << shift;
+ value -= (32 - shift);
+ shift = 0;
+ ptr++;
+ }
+ }
+ if(set) set = FALSE;
+ else set = TRUE;
+ }
+
+ if(!EvenDash) {
+ EvenDash = TRUE;
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED))
+ DashPtr = (unsigned char*)pGC->dash;
+ else
+ DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList;
+ goto CONCATENATE;
+ }
+}
diff --git a/hw/xfree86/xaa/xaaNonTEGlyph.c b/hw/xfree86/xaa/xaaNonTEGlyph.c
new file mode 100644
index 000000000..234d242c4
--- /dev/null
+++ b/hw/xfree86/xaa/xaaNonTEGlyph.c
@@ -0,0 +1,198 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEGlyph.c,v 1.6 1999/11/06 23:14:46 mvojkovi Exp $ */
+
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+/* Not used anymore because the algorithm isn't correct. It doesn't
+ handle overlapping characters properly */
+
+#ifdef TRIPLE_BITS
+#define NonTEGlyphFunc EXPNAME(XAANonTEGlyphScanlineFunc3)
+#else
+#define NonTEGlyphFunc EXPNAME(XAANonTEGlyphScanlineFunc)
+#endif
+
+/********************************************************************
+
+ Here we have NonTEGlyphRenders for a bunch of different color
+ expansion types. The driver may provide its own renderer, but
+ this is the default one which renders using lower-level primitives
+ exported by the chipset driver.
+
+********************************************************************/
+
+/* Since the dimensions of the text string and the backing rectangle
+ do not always coincide, it is possible that wBack or wText
+ may be 0! The NonTEGlyphRender must always check for this. */
+
+/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not,
+ with TRIPLE_BITS or not. A total of 8 versions */
+
+/* if the backing rectangle and text are of the same dimensions
+ then we can draw in one pass */
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAANonTEGlyphRenderer3)(
+#else
+EXPNAME(XAANonTEGlyphRenderer)(
+#endif
+ ScrnInfoPtr pScrn,
+ int xText, int wText,
+ int y, int h, int skipleft, int startline,
+ NonTEGlyphInfo *glyphp,
+ int fg, int rop,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base = (CARD32*)infoRec->ColorExpandBase;
+#ifdef TRIPLE_BITS
+ int dwords = ((3 * wText + 31) >> 5) * h;
+#else
+ int dwords = ((wText + 31) >> 5) * h;
+#endif
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, -1, rop, planemask);
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, xText, y, wText, h, 0);
+
+#ifndef FIXEDBASE
+#ifdef TRIPLE_BITS
+ if((((3 * wText + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+#else
+ if((((wText + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+#endif
+ while(h--)
+ base = NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
+ else
+#endif
+ while(h--)
+ NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+#ifndef FIXEDBASE
+/* Scanline version of above gets built for LSBFIRST and MSBFIRST */
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAANonTEGlyphRendererScanline3)(
+#else
+EXPNAME(XAANonTEGlyphRendererScanline)(
+#endif
+ ScrnInfoPtr pScrn,
+ int xText, int wText,
+ int y, int h, int skipleft, int startline,
+ NonTEGlyphInfo *glyphp,
+ int fg, int rop,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo = 0;
+ CARD32* base;
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, -1, rop, planemask);
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, xText, y, wText, h, 0);
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ NonTEGlyphFunc(base, glyphp, startline++, wText, skipleft);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+/********************************************************************
+
+ Generic NonTE scanline rendering code.
+
+********************************************************************/
+
+
+CARD32*
+NonTEGlyphFunc(
+ CARD32 *base,
+ NonTEGlyphInfo *glyphp,
+ int line, int TotalWidth, int skipleft )
+{
+ CARD32 bits = 0;
+ int shift = glyphp->width;
+
+ if(skipleft) {
+ if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits = SHIFT_R(glyphp->bitsp[line], skipleft);
+ shift -= skipleft;
+ } else if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits = glyphp->bitsp[line];
+
+
+ while(TotalWidth > 32) {
+ while(shift < 32) {
+ glyphp++;
+ if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits |= SHIFT_L(glyphp->bitsp[line],shift);
+ shift += glyphp->width;
+ }
+#ifdef TRIPLE_BITS
+ WRITE_BITS3(bits);
+#else
+ WRITE_BITS(bits);
+#endif
+ shift &= 31;
+ if(shift &&
+ (line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits = SHIFT_R(glyphp->bitsp[line], glyphp->width - shift);
+ else bits = 0;
+ TotalWidth -= 32;
+ }
+
+ if(TotalWidth) {
+ TotalWidth -= shift;
+ while(TotalWidth > 0) {
+ glyphp++;
+ if((line >= glyphp->firstline) && (line <= glyphp->lastline))
+ bits |= SHIFT_L(glyphp->bitsp[line], shift);
+ shift += glyphp->width;
+ TotalWidth -= glyphp->width;
+ }
+#ifdef TRIPLE_BITS
+ if (shift >= 22) {
+ WRITE_BITS3(bits);
+ } else if (shift >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+ }
+
+
+ return base;
+}
+
+
+
+
diff --git a/hw/xfree86/xaa/xaaNonTEText.c b/hw/xfree86/xaa/xaaNonTEText.c
new file mode 100644
index 000000000..914631b58
--- /dev/null
+++ b/hw/xfree86/xaa/xaaNonTEText.c
@@ -0,0 +1,588 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaNonTEText.c,v 1.12 2000/04/07 19:11:10 mvojkovi Exp $ */
+
+/********************************************************************
+
+ In this file we have GC level replacements for PolyText8/16,
+ ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional)
+ fonts. The idea is that everything in this file is device independent.
+ The mentioned GCOps are merely wrappers for the
+ PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion
+ functions which calculate the boxes containing arbitrarily clipped
+ text and passes them to the NonTEGlyphRenderer which will usually
+ be a lower level XAA function which renders these clipped glyphs using
+ the basic color expansion functions exported by the chipset driver.
+ The NonTEGlyphRenderer itself may optionally be driver supplied to
+ facilitate work-arounds/optimizations at a higher level than usual.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+
+********************************************************************/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "font.h"
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaacexp.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+
+static void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
+ int xInit, int yInit, FontPtr font,
+ int fg, int bg, unsigned planemask,
+ RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+static int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
+ int xInit, int yInit, FontPtr font,
+ int fg, int rop, unsigned planemask,
+ RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+
+/********************************************************************
+
+ GC level replacements for PolyText8/16 and ImageText8/16
+ for NonTE fonts when using color expansion.
+
+********************************************************************/
+
+
+int
+XAAPolyText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+ int width = 0;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) {
+ width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
+ x + pDraw->x, y + pDraw->y, pGC->font,
+ pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
+ infoRec->CharInfo);
+ }
+
+ return (x + width);
+}
+
+
+int
+XAAPolyText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+ int width = 0;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) {
+ width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
+ x + pDraw->x, y + pDraw->y, pGC->font,
+ pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
+ infoRec->CharInfo);
+ }
+
+ return (x + width);
+}
+
+
+void
+XAAImageText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+void
+XAAImageText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+
+/********************************************************************
+
+ GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
+ NonTE fonts when using color expansion.
+
+********************************************************************/
+
+
+void
+XAAImageGlyphBltNonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci, /* array of character info */
+ pointer pglyphBase /* start of array of glyphs */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+void
+XAAPolyGlyphBltNonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci, /* array of character info */
+ pointer pglyphBase /* start of array of glyphs */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ PolyGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+
+
+
+/********************************************************************
+
+ ImageGlyphBltNonTEColorExpansion -
+ PolyGlyphBltNonTEColorExpansion -
+
+ These guys compute the clipped pieces of text and send it to
+ the lower-level function which will handle acceleration of
+ arbitrarily clipped text.
+
+********************************************************************/
+
+
+
+static int
+CollectCharacterInfo(
+ NonTEGlyphPtr glyphs,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ FontPtr pfont
+){
+ int i, w = 0;
+
+ for(i = 0; i < nglyph; i++, ppci++, glyphs++) {
+ glyphs->bits = (unsigned char*)((*ppci)->bits);
+ glyphs->start = w + (*ppci)->metrics.leftSideBearing;
+ glyphs->end = w + (*ppci)->metrics.rightSideBearing;
+ glyphs->yoff = (*ppci)->metrics.ascent;
+ glyphs->height = glyphs->yoff + (*ppci)->metrics.descent;
+ glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start);
+ w += (*ppci)->metrics.characterWidth;
+ }
+ return w;
+}
+
+
+static void
+PolyGlyphBltAsSingleBitmap (
+ ScrnInfoPtr pScrn,
+ int nglyph,
+ FontPtr font,
+ int xInit,
+ int yInit,
+ int nbox,
+ BoxPtr pbox,
+ int fg,
+ int rop,
+ unsigned planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *block, *pntr, *bits;
+ int pitch, topLine, botLine, top, bot, height;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge;
+ int bitPitch, shift, size, i, skippix;
+ NonTEGlyphPtr glyphs = infoRec->GlyphInfo;
+ Bool extra;
+
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ if(!nbox) return;
+
+ pitch = (Right - Left + 31) >> 5;
+ size = (pitch << 2) * (Bottom - Top);
+ block = (CARD32*)ALLOCATE_LOCAL(size);
+ bzero(block, size);
+
+ topLine = 10000; botLine = -10000;
+
+ while(nglyph--) {
+ top = -glyphs->yoff;
+ bot = top + glyphs->height;
+ if(top < topLine) topLine = top;
+ if(bot > botLine) botLine = bot;
+ skippix = glyphs->start - infoRec->GlyphInfo[0].start;
+ bits = (CARD32*)glyphs->bits;
+ bitPitch = glyphs->srcwidth >> 2;
+ pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) +
+ (skippix >> 5);
+ shift = skippix & 31;
+ extra = ((shift + glyphs->end - glyphs->start) > 32);
+
+ for(i = top; i < bot; i++) {
+ *pntr |= SHIFT_L(*bits, shift);
+ if(extra)
+ *(pntr + 1) |= SHIFT_R(*bits,32 - shift);
+ pntr += pitch;
+ bits += bitPitch;
+ }
+
+ glyphs++;
+ }
+
+ pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch);
+
+ Top = yInit + topLine;
+ Bottom = yInit + botLine;
+
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (Bottom > pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) {
+ skippix = LeftEdge - Left;
+ topLine = max(Top, pbox->y1);
+ botLine = min(Bottom, pbox->y2);
+ height = botLine - topLine;
+
+ if(height > 0)
+ (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine,
+ RightEdge - LeftEdge, height,
+ (unsigned char*)(pntr + ((topLine - Top) * pitch) +
+ (skippix >> 5)),
+ pitch << 2, skippix & 31, fg, -1, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+
+ DEALLOCATE_LOCAL(block);
+}
+
+static void
+ImageGlyphBltNonTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int bg,
+ unsigned planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyph, width, n, i;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge, ytop, ybot;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+ Bool AlreadySetup = FALSE;
+
+ width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
+
+ /* find our backing rectangle dimensions */
+ Left = xInit;
+ Right = Left + width;
+ Top = yInit - FONTASCENT(font);
+ Bottom = yInit + FONTDESCENT(font);
+
+ /* get into the first band that may contain part of our box */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (Bottom >= pbox->y1)) {
+ /* handle backing rect first */
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+ if(RightEdge > LeftEdge) {
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+
+ if(ybot > ytop) {
+ if(!AlreadySetup) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask);
+ AlreadySetup = TRUE;
+ }
+ (*infoRec->SubsequentSolidFillRect)(pScrn,
+ LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop);
+ }
+ }
+ nbox--; pbox++;
+ }
+
+ nbox = REGION_NUM_RECTS(cclip);
+ pbox = REGION_RECTS(cclip);
+
+ if(infoRec->WriteBitmap && (nglyph > 1) &&
+ ((FONTMAXBOUNDS(font, rightSideBearing) -
+ FONTMINBOUNDS(font, leftSideBearing)) <= 32))
+ {
+ PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
+ xInit, yInit, nbox, pbox,
+ fg, GXcopy, planemask);
+
+ return;
+ }
+
+ /* compute an approximate but covering bounding box */
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our box */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we're possibly drawing something */
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+ if(ybot > ytop) {
+ skippix = LeftEdge - xInit;
+ skipglyph = 0;
+ while(skippix >= infoRec->GlyphInfo[skipglyph].end)
+ skipglyph++;
+
+ skippix = RightEdge - xInit;
+ n = 0; i = skipglyph;
+ while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
+ i++; n++;
+ }
+
+ if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
+ xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
+ pbox, fg, GXcopy, planemask);
+ }
+ }
+
+ nbox--; pbox++;
+ }
+}
+
+
+static int
+PolyGlyphBltNonTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int rop,
+ unsigned planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyph, width, n, i;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+
+ width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
+
+ if(!nbox)
+ return width;
+
+ if((infoRec->WriteBitmap) && (rop == GXcopy) && (nglyph > 1) &&
+ ((FONTMAXBOUNDS(font, rightSideBearing) -
+ FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {
+
+ PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
+ xInit, yInit, nbox, pbox,
+ fg, rop, planemask);
+
+ return width;
+ }
+
+ /* compute an approximate but covering bounding box */
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we're possibly drawing something */
+
+ skippix = LeftEdge - xInit;
+ skipglyph = 0;
+ while(skippix >= infoRec->GlyphInfo[skipglyph].end)
+ skipglyph++;
+
+ skippix = RightEdge - xInit;
+ n = 0; i = skipglyph;
+ while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
+ i++; n++;
+ }
+
+ if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
+ xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
+ pbox, fg, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+ return width;
+}
+
+
+/* It is possible that the none of the glyphs passed to the
+ NonTEGlyphRenderer will be drawn. This function being called
+ indicates that part of the text string's bounding box is visible
+ but not necessarily that any of the characters are visible */
+
+void XAANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x1, x2, y1, y2, i, w, h, skipleft, skiptop;
+ unsigned char *src;
+
+ for(i = 0; i < n; i++, glyphs++) {
+ x1 = x + glyphs->start;
+ x2 = x + glyphs->end;
+ y1 = y - glyphs->yoff;
+ y2 = y1 + glyphs->height;
+
+ if(y1 < pbox->y1) {
+ skiptop = pbox->y1 - y1;
+ y1 = pbox->y1;
+ } else skiptop = 0;
+ if(y2 > pbox->y2) y2 = pbox->y2;
+ h = y2 - y1;
+ if(h <= 0) continue;
+
+ if(x1 < pbox->x1) {
+ skipleft = pbox->x1 - x1;
+ x1 = pbox->x1;
+ } else skipleft = 0;
+ if(x2 > pbox->x2) x2 = pbox->x2;
+
+ w = x2 - x1;
+
+ if(w > 0) {
+ src = glyphs->bits + (skiptop * glyphs->srcwidth);
+
+ if(skipleft) {
+ src += (skipleft >> 5) << 2;
+ skipleft &= 31;
+ }
+
+ (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src,
+ glyphs->srcwidth, skipleft, fg, -1, rop, planemask);
+ }
+ }
+
+}
diff --git a/hw/xfree86/xaa/xaaOffscreen.c b/hw/xfree86/xaa/xaaOffscreen.c
new file mode 100644
index 000000000..0fb1db365
--- /dev/null
+++ b/hw/xfree86/xaa/xaaOffscreen.c
@@ -0,0 +1,160 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOffscreen.c,v 1.6 2001/07/19 18:50:16 mvojkovi Exp $ */
+
+/*
+ Copyright (c) 1999 - The XFree86 Project Inc.
+
+ Written by Mark Vojkovich
+
+*/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+void
+XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ XAAPixmapPtr pPriv;
+
+ while(pLink) {
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pLink->pPix);
+ pLink->area = pPriv->offscreenArea;
+ XAAMoveOutOffscreenPixmap(pLink->pPix);
+ pLink = pLink->next;
+ }
+}
+
+
+
+void
+XAAMoveInOffscreenPixmaps(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ PixmapPtr pPix, pScreenPix, tmpPix;
+ pointer data;
+ XAAPixmapPtr pPriv;
+ GCPtr pGC;
+ FBAreaPtr area;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ while(pLink) {
+ pPix = pLink->pPix;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ area = pLink->area;
+
+ data = pPix->devPrivate.ptr;
+ tmpPix = GetScratchPixmapHeader(pScreen,
+ pPix->drawable.width, pPix->drawable.height,
+ pPix->drawable.depth, pPix->drawable.bitsPerPixel,
+ pPix->devKind, data);
+
+ pPriv->freeData = FALSE;
+
+ pPix->drawable.x = area->box.x1;
+ pPix->drawable.y = area->box.y1;
+ pPix->devKind = pScreenPix->devKind;
+ pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
+ pPix->drawable.bitsPerPixel = infoRec->pScrn->bitsPerPixel;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if(!tmpPix) {
+ pPriv->offscreenArea = area;
+ xfree(data);
+ pLink = pLink->next;
+ continue;
+ }
+
+ pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+ ValidateGC((DrawablePtr)pPix, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)tmpPix, (DrawablePtr)pPix, pGC,
+ 0, 0, pPix->drawable.width, pPix->drawable.height, 0, 0);
+
+ xfree(data);
+ tmpPix->devPrivate.ptr = NULL;
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(tmpPix);
+
+ pPriv->offscreenArea = area;
+ pLink->area = NULL;
+ pLink = pLink->next;
+ }
+}
+
+
+void
+XAARemoveAreaCallback(FBAreaPtr area)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(area->pScreen);
+ PixmapPtr pPix = (PixmapPtr)area->devPrivate.ptr;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+
+ XAAMoveOutOffscreenPixmap(pPix);
+
+ pPriv->flags &= ~OFFSCREEN;
+
+ DELIST_OFFSCREEN_PIXMAP(pPix);
+}
+
+void
+XAAMoveOutOffscreenPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int width, height, devKind, bitsPerPixel;
+ PixmapPtr tmpPix;
+ unsigned char *data;
+ GCPtr pGC;
+
+ width = pPix->drawable.width;
+ height = pPix->drawable.height;
+ bitsPerPixel = pPix->drawable.bitsPerPixel;
+
+ devKind = BitmapBytePad(width * bitsPerPixel);
+ if(!(data = xalloc(devKind * height)))
+ FatalError("Out of memory\n");
+
+ tmpPix = GetScratchPixmapHeader(pScreen, width, height,
+ pPix->drawable.depth, bitsPerPixel, devKind, data);
+ if(!tmpPix) {
+ xfree(data);
+ FatalError("Out of memory\n");
+ }
+
+ pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+ ValidateGC((DrawablePtr)tmpPix, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)tmpPix,
+ pGC, 0, 0, width, height, 0, 0);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(tmpPix);
+
+ pPix->drawable.x = 0;
+ pPix->drawable.y = 0;
+ pPix->devKind = devKind;
+ pPix->devPrivate.ptr = data;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pPriv->offscreenArea = NULL;
+ pPriv->freeData = TRUE;
+}
diff --git a/hw/xfree86/xaa/xaaOverlay.c b/hw/xfree86/xaa/xaaOverlay.c
new file mode 100644
index 000000000..9651ca6a3
--- /dev/null
+++ b/hw/xfree86/xaa/xaaOverlay.c
@@ -0,0 +1,306 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlay.c,v 1.14 2002/12/10 04:18:20 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mioverlay.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+static void
+XAACopyWindow8_32(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ DDXPointPtr pptSrc, ppt;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int dx, dy, nbox;
+ WindowPtr pwinRoot;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+ Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
+ RegionPtr borderClip = &pWin->borderClip;
+ Bool freeReg = FALSE;
+
+ if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
+ (infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK))
+ {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
+ return;
+ }
+
+ pwinRoot = WindowTable[pScreen->myNum];
+
+ if(doUnderlay)
+ freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox ||
+ !(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ while(nbox--) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ ppt++; pbox++;
+ }
+
+ infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
+ infoRec->ScratchGC.alu = GXcopy;
+
+ XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ DEALLOCATE_LOCAL(pptSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+ if(freeReg)
+ REGION_DESTROY(pScreen, borderClip);
+}
+
+
+
+
+static void
+XAAPaintWindow8_32(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+ int nBox = REGION_NUM_RECTS(prgn);
+ BoxPtr pBox = REGION_RECTS(prgn);
+ PixmapPtr pPix = NULL;
+ int depth = pWin->drawable.depth;
+ int fg = 0, pm;
+
+ if(!infoRec->pScrn->vtSema) goto BAILOUT;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch(pWin->backgroundState) {
+ case None: return;
+ case ParentRelative:
+ do { pWin = pWin->parent; }
+ while(pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
+ return;
+ case BackgroundPixel:
+ fg = pWin->background.pixel;
+ break;
+ case BackgroundPixmap:
+ pPix = pWin->background.pixmap;
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ fg = pWin->border.pixel;
+ else /* pixmap */
+ pPix = pWin->border.pixmap;
+ break;
+ default: return;
+ }
+
+ if(depth == 8) {
+ pm = 0xff000000;
+ fg <<= 24;
+ } else
+ pm = 0x00ffffff;
+
+ if(!pPix) {
+ if(infoRec->FillSolidRects &&
+ !(infoRec->FillSolidRectsFlags & NO_PLANEMASK) &&
+ (!(infoRec->FillSolidRectsFlags & RGB_EQUAL) ||
+ (depth == 8) || CHECK_RGB_EQUAL(fg)))
+ {
+ (*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy,
+ pm, nBox, pBox);
+ return;
+ }
+ } else { /* pixmap */
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ WindowPtr pBgWin = pWin;
+ int xorg, yorg;
+
+ if (what == PW_BORDER) {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ }
+
+ xorg = pBgWin->drawable.x;
+ yorg = pBgWin->drawable.y;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int index = pScreen->myNum;
+ if(WindowTable[index] == pBgWin) {
+ xorg -= panoramiXdataPtr[index].x;
+ yorg -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+
+ if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+ pCache->trans_color = -1;
+
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
+ nBox, pBox, xorg, yorg, pCache);
+
+ return;
+ }
+
+ if(pPriv->flags & DIRTY) {
+ pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
+ infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
+ !(infoRec->FillMono8x8PatternRectsFlags & NO_PLANEMASK) &&
+ !(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))))
+ {
+ (*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
+ pPriv->fg, pPriv->bg, GXcopy, pm, nBox, pBox,
+ pPriv->pattern0, pPriv->pattern1, xorg, yorg);
+ return;
+ }
+ if(infoRec->CanDoColor8x8 && infoRec->FillColor8x8PatternRects &&
+ !(infoRec->FillColor8x8PatternRectsFlags & NO_PLANEMASK))
+ {
+ XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
+ infoRec->pScrn, pPix, -1, -1);
+
+ (*infoRec->FillColor8x8PatternRects) (infoRec->pScrn,
+ GXcopy, pm, nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheBltRects &&
+ !(infoRec->FillCacheBltRectsFlags & NO_PLANEMASK) &&
+ (pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPix->drawable.width <= infoRec->MaxCacheableTileWidth))
+ {
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheTile)(infoRec->pScrn, pPix);
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, pm,
+ nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ !(infoRec->FillImageWriteRectsFlags & NO_PLANEMASK))
+ {
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy,
+ pm, nBox, pBox, xorg, yorg, pPix);
+ return;
+ }
+ }
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+BAILOUT:
+
+ if(what == PW_BACKGROUND) {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow8_32);
+ } else {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow8_32);
+ }
+}
+
+
+static void
+XAASetColorKey8_32(
+ ScreenPtr pScreen,
+ int nbox,
+ BoxPtr pbox
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+
+ /* I'm counting on writes being clipped away while switched away.
+ If this isn't going to be true then I need to be wrapping instead. */
+ if(!infoRec->pScrn->vtSema) return;
+
+ (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey << 24, GXcopy,
+ 0xff000000, nbox, pbox);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAASetupOverlay8_32Planar(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ int i;
+
+ pScreen->PaintWindowBackground = XAAPaintWindow8_32;
+ pScreen->PaintWindowBorder = XAAPaintWindow8_32;
+ pScreen->CopyWindow = XAACopyWindow8_32;
+
+ if(!(infoRec->FillSolidRectsFlags & NO_PLANEMASK))
+ miOverlaySetTransFunction(pScreen, XAASetColorKey8_32);
+
+ infoRec->FullPlanemask = ~0;
+ for(i = 0; i < 32; i++) /* haven't thought about this much */
+ infoRec->FullPlanemasks[i] = ~0;
+}
diff --git a/hw/xfree86/xaa/xaaOverlayDF.c b/hw/xfree86/xaa/xaaOverlayDF.c
new file mode 100644
index 000000000..82a2011a4
--- /dev/null
+++ b/hw/xfree86/xaa/xaaOverlayDF.c
@@ -0,0 +1,1154 @@
+/*
+ Copyright (c) 1999 - The XFree86 Project Inc.
+
+ Written by Mark Vojkovich
+*/
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaOverlayDF.c,v 1.1 1999/03/28 15:33:03 dawes Exp $ */
+
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "servermd.h"
+
+/* Screen funcs */
+
+static void XAAOverCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
+static void XAAOverPaintWindow(WindowPtr, RegionPtr, int);
+static void XAAOverWindowExposures(WindowPtr, RegionPtr, RegionPtr);
+static void XAAOverSaveAreas(PixmapPtr, RegionPtr, int, int, WindowPtr);
+static void XAAOverRestoreAreas(PixmapPtr, RegionPtr, int, int, WindowPtr);
+
+
+static int XAAOverStippledFillChooser(GCPtr);
+static int XAAOverOpaqueStippledFillChooser(GCPtr);
+static int XAAOverTiledFillChooser(GCPtr);
+
+/* GC funcs */
+
+static RegionPtr XAAOverCopyArea(DrawablePtr, DrawablePtr, GC *,
+ int, int, int, int, int, int);
+static RegionPtr XAAOverCopyPlane(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int, unsigned long);
+static void XAAOverPushPixelsSolid(GCPtr, PixmapPtr, DrawablePtr, int,
+ int, int, int);
+static void XAAOverPolyFillRectSolid(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolyFillRectStippled(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolyFillRectOpaqueStippled(DrawablePtr, GCPtr,
+ int, xRectangle*);
+static void XAAOverPolyFillRectTiled(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverFillSpansSolid(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static void XAAOverFillSpansStippled(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static void XAAOverFillSpansOpaqueStippled(DrawablePtr, GCPtr, int,
+ DDXPointPtr, int*, int);
+static void XAAOverFillSpansTiled(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static int XAAOverPolyText8TE(DrawablePtr, GCPtr, int, int, int, char *);
+static int XAAOverPolyText16TE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageText8TE(DrawablePtr, GCPtr, int, int, int, char*);
+static void XAAOverImageText16TE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageGlyphBltTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr*, pointer);
+static void XAAOverPolyGlyphBltTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr*, pointer);
+static int XAAOverPolyText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
+static int XAAOverPolyText16NonTE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
+static void XAAOverImageText16NonTE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void XAAOverPolyGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void XAAOverPolyRectangleThinSolid(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolylinesWideSolid(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolylinesThinSolid(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolySegmentThinSolid(DrawablePtr, GCPtr, int, xSegment*);
+static void XAAOverPolylinesThinDashed(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolySegmentThinDashed(DrawablePtr, GCPtr, int, xSegment*);
+static void XAAOverFillPolygonSolid(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonStippled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonOpaqueStippled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonTiled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverPolyFillArcSolid(DrawablePtr, GCPtr, int, xArc*);
+static void XAAOverPutImage(DrawablePtr, GCPtr, int, int, int, int, int,
+ int, int, char*);
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ DepthChangeFuncPtr callback;
+ int currentDepth;
+/* GC funcs */
+ RegionPtr (*CopyArea)(DrawablePtr, DrawablePtr, GC *,
+ int, int, int, int, int, int);
+ RegionPtr (*CopyPlane)(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int, unsigned long);
+ void (*PushPixelsSolid)(GCPtr, PixmapPtr, DrawablePtr, int, int, int, int);
+ void (*PolyFillRectSolid)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectStippled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectOpaqueStippled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectTiled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*FillSpansSolid)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ void (*FillSpansStippled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ void (*FillSpansOpaqueStippled)(DrawablePtr,GCPtr,int,DDXPointPtr,int*,int);
+ void (*FillSpansTiled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ int (*PolyText8TE)(DrawablePtr, GCPtr, int, int, int, char *);
+ int (*PolyText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageText8TE)(DrawablePtr, GCPtr, int, int, int, char*);
+ void (*ImageText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr*, pointer);
+ void (*PolyGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr*, pointer);
+ int (*PolyText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
+ int (*PolyText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
+ void (*ImageText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr *, pointer);
+ void (*PolyGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr *, pointer);
+ void (*PolyRectangleThinSolid)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolylinesWideSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+
+ void (*PolylinesThinSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+ void (*PolySegmentThinSolid)(DrawablePtr, GCPtr, int, xSegment*);
+ void (*PolylinesThinDashed)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+ void (*PolySegmentThinDashed)(DrawablePtr, GCPtr, int, xSegment*);
+ void (*FillPolygonSolid)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*FillPolygonStippled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*FillPolygonOpaqueStippled)(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+ void (*FillPolygonTiled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*PolyFillArcSolid)(DrawablePtr, GCPtr, int, xArc*);
+ void (*PutImage)(DrawablePtr, GCPtr, int, int, int, int, int, int,
+ int, char*);
+ int (*StippledFillChooser)(GCPtr);
+ int (*OpaqueStippledFillChooser)(GCPtr);
+ int (*TiledFillChooser)(GCPtr);
+} XAAOverlayRec, *XAAOverlayPtr;
+
+static int XAAOverlayIndex = -1;
+static unsigned long XAAOverlayGeneration = 0;
+
+#define GET_OVERLAY_PRIV(pScreen) \
+ ((XAAOverlayPtr)((pScreen)->devPrivates[XAAOverlayIndex].ptr))
+
+#define SWITCH_DEPTH(d) \
+ if(pOverPriv->currentDepth != d) { \
+ (*pOverPriv->callback)(pOverPriv->pScrn, d); \
+ pOverPriv->currentDepth = d; \
+ }
+
+
+Bool
+XAAInitDualFramebufferOverlay(
+ ScreenPtr pScreen,
+ DepthChangeFuncPtr callback
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAOverlayPtr pOverPriv;
+
+ if (XAAOverlayGeneration != serverGeneration) {
+ if((XAAOverlayIndex = AllocateScreenPrivateIndex()) < 0)
+ return FALSE;
+
+ XAAOverlayGeneration = serverGeneration;
+ }
+
+
+ if(!(pOverPriv = xalloc(sizeof(XAAOverlayRec))))
+ return FALSE;
+
+ pScreen->devPrivates[XAAOverlayIndex].ptr = (pointer)pOverPriv;
+
+ pOverPriv->pScrn = pScrn;
+ pOverPriv->callback = callback;
+ pOverPriv->currentDepth = -1;
+
+ /* Overwrite key screen functions. The XAA core will clean up */
+
+ pScreen->CopyWindow = XAAOverCopyWindow;
+ pScreen->PaintWindowBackground = XAAOverPaintWindow;
+ pScreen->PaintWindowBorder = XAAOverPaintWindow;
+ pScreen->WindowExposures = XAAOverWindowExposures;
+ pScreen->BackingStoreFuncs.SaveAreas = XAAOverSaveAreas;
+ pScreen->BackingStoreFuncs.RestoreAreas = XAAOverRestoreAreas;
+
+ pOverPriv->StippledFillChooser = infoRec->StippledFillChooser;
+ pOverPriv->OpaqueStippledFillChooser = infoRec->OpaqueStippledFillChooser;
+ pOverPriv->TiledFillChooser = infoRec->TiledFillChooser;
+
+ infoRec->StippledFillChooser = XAAOverStippledFillChooser;
+ infoRec->OpaqueStippledFillChooser = XAAOverOpaqueStippledFillChooser;
+ infoRec->TiledFillChooser = XAAOverTiledFillChooser;
+
+ /* wrap all XAA GC rendering */
+
+ pOverPriv->CopyArea = infoRec->CopyArea;
+ pOverPriv->CopyPlane = infoRec->CopyPlane;
+ pOverPriv->PushPixelsSolid = infoRec->PushPixelsSolid;
+ pOverPriv->PolyFillRectSolid = infoRec->PolyFillRectSolid;
+ pOverPriv->PolyFillRectStippled = infoRec->PolyFillRectStippled;
+ pOverPriv->PolyFillRectOpaqueStippled = infoRec->PolyFillRectOpaqueStippled;
+ pOverPriv->PolyFillRectTiled = infoRec->PolyFillRectTiled;
+ pOverPriv->FillSpansSolid = infoRec->FillSpansSolid;
+ pOverPriv->FillSpansStippled = infoRec->FillSpansStippled;
+ pOverPriv->FillSpansOpaqueStippled = infoRec->FillSpansOpaqueStippled;
+ pOverPriv->FillSpansTiled = infoRec->FillSpansTiled;
+ pOverPriv->PolyText8TE = infoRec->PolyText8TE;
+ pOverPriv->PolyText16TE = infoRec->PolyText16TE;
+ pOverPriv->ImageText8TE = infoRec->ImageText8TE;
+ pOverPriv->ImageText16TE = infoRec->ImageText16TE;
+ pOverPriv->ImageGlyphBltTE = infoRec->ImageGlyphBltTE;
+ pOverPriv->PolyGlyphBltTE = infoRec->PolyGlyphBltTE;
+ pOverPriv->PolyText8NonTE = infoRec->PolyText8NonTE;
+ pOverPriv->PolyText16NonTE = infoRec->PolyText16NonTE;
+ pOverPriv->ImageText8NonTE = infoRec->ImageText8NonTE;
+ pOverPriv->ImageText16NonTE = infoRec->ImageText16NonTE;
+ pOverPriv->ImageGlyphBltNonTE = infoRec->ImageGlyphBltNonTE;
+ pOverPriv->PolyGlyphBltNonTE = infoRec->PolyGlyphBltNonTE;
+ pOverPriv->PolyRectangleThinSolid = infoRec->PolyRectangleThinSolid;
+ pOverPriv->PolylinesWideSolid = infoRec->PolylinesWideSolid;
+ pOverPriv->PolylinesThinSolid = infoRec->PolylinesThinSolid;
+ pOverPriv->PolySegmentThinSolid = infoRec->PolySegmentThinSolid;
+ pOverPriv->PolylinesThinDashed = infoRec->PolylinesThinDashed;
+ pOverPriv->PolySegmentThinDashed = infoRec->PolySegmentThinDashed;
+ pOverPriv->FillPolygonSolid = infoRec->FillPolygonSolid;
+ pOverPriv->FillPolygonStippled = infoRec->FillPolygonStippled;
+ pOverPriv->FillPolygonOpaqueStippled = infoRec->FillPolygonOpaqueStippled;
+ pOverPriv->FillPolygonTiled = infoRec->FillPolygonTiled;
+ pOverPriv->PolyFillArcSolid = infoRec->PolyFillArcSolid;
+ pOverPriv->PutImage = infoRec->PutImage;
+
+
+ if(infoRec->CopyArea)
+ infoRec->CopyArea = XAAOverCopyArea;
+ if(infoRec->CopyPlane)
+ infoRec->CopyPlane = XAAOverCopyPlane;
+ if(infoRec->PushPixelsSolid)
+ infoRec->PushPixelsSolid = XAAOverPushPixelsSolid;
+ if(infoRec->PolyFillRectSolid)
+ infoRec->PolyFillRectSolid = XAAOverPolyFillRectSolid;
+ if(infoRec->PolyFillRectStippled)
+ infoRec->PolyFillRectStippled = XAAOverPolyFillRectStippled;
+ if(infoRec->PolyFillRectOpaqueStippled)
+ infoRec->PolyFillRectOpaqueStippled = XAAOverPolyFillRectOpaqueStippled;
+ if(infoRec->PolyFillRectTiled)
+ infoRec->PolyFillRectTiled = XAAOverPolyFillRectTiled;
+ if(infoRec->FillSpansSolid)
+ infoRec->FillSpansSolid = XAAOverFillSpansSolid;
+ if(infoRec->FillSpansStippled)
+ infoRec->FillSpansStippled = XAAOverFillSpansStippled;
+ if(infoRec->FillSpansOpaqueStippled)
+ infoRec->FillSpansOpaqueStippled = XAAOverFillSpansOpaqueStippled;
+ if(infoRec->FillSpansTiled)
+ infoRec->FillSpansTiled = XAAOverFillSpansTiled;
+ if(infoRec->PolyText8TE)
+ infoRec->PolyText8TE = XAAOverPolyText8TE;
+ if(infoRec->PolyText16TE)
+ infoRec->PolyText16TE = XAAOverPolyText16TE;
+ if(infoRec->ImageText8TE)
+ infoRec->ImageText8TE = XAAOverImageText8TE;
+ if(infoRec->ImageText16TE)
+ infoRec->ImageText16TE = XAAOverImageText16TE;
+ if(infoRec->ImageGlyphBltTE)
+ infoRec->ImageGlyphBltTE = XAAOverImageGlyphBltTE;
+ if(infoRec->PolyGlyphBltTE)
+ infoRec->PolyGlyphBltTE = XAAOverPolyGlyphBltTE;
+ if(infoRec->PolyText8NonTE)
+ infoRec->PolyText8NonTE = XAAOverPolyText8NonTE;
+ if(infoRec->PolyText16NonTE)
+ infoRec->PolyText16NonTE = XAAOverPolyText16NonTE;
+ if(infoRec->ImageText8NonTE)
+ infoRec->ImageText8NonTE = XAAOverImageText8NonTE;
+ if(infoRec->ImageText16NonTE)
+ infoRec->ImageText16NonTE = XAAOverImageText16NonTE;
+ if(infoRec->ImageGlyphBltNonTE)
+ infoRec->ImageGlyphBltNonTE = XAAOverImageGlyphBltNonTE;
+ if(infoRec->PolyGlyphBltNonTE)
+ infoRec->PolyGlyphBltNonTE = XAAOverPolyGlyphBltNonTE;
+ if(infoRec->PolyRectangleThinSolid)
+ infoRec->PolyRectangleThinSolid = XAAOverPolyRectangleThinSolid;
+ if(infoRec->PolylinesWideSolid)
+ infoRec->PolylinesWideSolid = XAAOverPolylinesWideSolid;
+ if(infoRec->PolylinesThinSolid)
+ infoRec->PolylinesThinSolid = XAAOverPolylinesThinSolid;
+ if(infoRec->PolySegmentThinSolid)
+ infoRec->PolySegmentThinSolid = XAAOverPolySegmentThinSolid;
+ if(infoRec->PolylinesThinDashed)
+ infoRec->PolylinesThinDashed = XAAOverPolylinesThinDashed;
+ if(infoRec->PolySegmentThinDashed)
+ infoRec->PolySegmentThinDashed = XAAOverPolySegmentThinDashed;
+ if(infoRec->FillPolygonSolid)
+ infoRec->FillPolygonSolid = XAAOverFillPolygonSolid;
+ if(infoRec->FillPolygonStippled)
+ infoRec->FillPolygonStippled = XAAOverFillPolygonStippled;
+ if(infoRec->FillPolygonOpaqueStippled)
+ infoRec->FillPolygonOpaqueStippled = XAAOverFillPolygonOpaqueStippled;
+ if(infoRec->FillPolygonTiled)
+ infoRec->FillPolygonTiled = XAAOverFillPolygonTiled;
+ if(infoRec->PolyFillArcSolid)
+ infoRec->PolyFillArcSolid = XAAOverPolyFillArcSolid;
+ if(infoRec->PutImage)
+ infoRec->PutImage = XAAOverPutImage;
+
+ return TRUE;
+}
+
+/*********************** Screen functions ************************/
+
+void
+XAAOverCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+ DDXPointPtr ppt, pptSrc;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+
+ if (!pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAAOverCopyWindow);
+ return;
+ }
+
+ infoRec->ScratchGC.alu = GXcopy;
+ infoRec->ScratchGC.planemask = ~0;
+
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))) {
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ SWITCH_DEPTH(8);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ if(pWin->drawable.bitsPerPixel != 8) {
+ SWITCH_DEPTH(pScrn->depth);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+ }
+
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+
+ REGION_UNINIT(pScreen, &rgnDst);
+
+ if(pWin->drawable.depth == 8) {
+ REGION_INIT(pScreen, &rgnDst, NullBox, 0);
+ miSegregateChildren(pWin, &rgnDst, pScrn->depth);
+ if(REGION_NOTEMPTY(pScreen, &rgnDst)) {
+ REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrc);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )ALLOCATE_LOCAL(nbox * sizeof(DDXPointRec)))){
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ SWITCH_DEPTH(pScrn->depth);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+ DEALLOCATE_LOCAL(pptSrc);
+ }
+ }
+ REGION_UNINIT(pScreen, &rgnDst);
+ }
+}
+
+
+static void
+XAAOverPaintWindow(
+ WindowPtr pWin,
+ RegionPtr pRegion,
+ int what
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+
+ if(pScrn->vtSema) {
+ if(what == PW_BACKGROUND) {
+ SWITCH_DEPTH(pWin->drawable.depth);
+ (*infoRec->PaintWindowBackground)(pWin, pRegion, what);
+ return;
+ } else {
+ if(pWin->drawable.bitsPerPixel == 8) {
+ SWITCH_DEPTH(8);
+ (*infoRec->PaintWindowBorder)(pWin, pRegion, what);
+ return;
+ } else if (infoRec->FillSolidRects) {
+ SWITCH_DEPTH(8);
+ (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey, GXcopy,
+ ~0, REGION_NUM_RECTS(pRegion), REGION_RECTS(pRegion));
+
+ SWITCH_DEPTH(pWin->drawable.depth);
+ (*infoRec->PaintWindowBorder)(pWin, pRegion, what);
+ return;
+ }
+ }
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ if(what == PW_BACKGROUND) {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, pRegion, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAOverPaintWindow);
+ } else {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, pRegion, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAOverPaintWindow);
+ }
+}
+
+
+void
+XAAOverWindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if((pWin->drawable.bitsPerPixel != 8) && infoRec->pScrn->vtSema) {
+ if(REGION_NUM_RECTS(pReg) && infoRec->FillSolidRects) {
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+
+ SWITCH_DEPTH(8);
+ (*infoRec->FillSolidRects)(infoRec->pScrn,
+ infoRec->pScrn->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(pReg), REGION_RECTS(pReg));
+ miWindowExposures(pWin, pReg, pOtherReg);
+ return;
+ } else if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, WindowExposures);
+ (*pScreen->WindowExposures) (pWin, pReg, pOtherReg);
+ XAA_SCREEN_EPILOGUE(pScreen, WindowExposures, XAAOverWindowExposures);
+}
+
+
+static void
+XAAOverSaveAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnSave,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pWin->drawable.pScreen);
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((DrawablePtr)pWin);
+
+ if(pOverPriv->pScrn->vtSema) {
+ SWITCH_DEPTH(pWin->drawable.depth);
+ }
+
+ (*infoRec->SaveAreas)(pPixmap, prgnSave, xorg, yorg, pWin);
+}
+
+
+static void
+XAAOverRestoreAreas (
+ PixmapPtr pPixmap,
+ RegionPtr prgnRestore,
+ int xorg,
+ int yorg,
+ WindowPtr pWin
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pWin->drawable.pScreen);
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((DrawablePtr)pWin);
+
+ if(pOverPriv->pScrn->vtSema) {
+ SWITCH_DEPTH(pWin->drawable.depth);
+ }
+
+ (*infoRec->RestoreAreas)(pPixmap, prgnRestore, xorg, yorg, pWin);
+}
+
+/********************* Choosers *************************/
+
+static int
+XAAOverStippledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->StippledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+XAAOverOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->OpaqueStippledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+XAAOverTiledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->TiledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+/**************************** GC Functions **************************/
+
+static RegionPtr
+XAAOverCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+}
+
+static RegionPtr
+XAAOverCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+
+}
+
+static void
+XAAOverPushPixelsSolid(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy,
+ int xOrg, int yOrg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PushPixelsSolid)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+}
+
+
+
+static void
+XAAOverPolyFillRectSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectSolid)(pDraw, pGC, nrectFill, prectInit);
+}
+
+static void
+XAAOverPolyFillRectStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectStippled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+
+static void
+XAAOverPolyFillRectOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectOpaqueStippled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+static void
+XAAOverPolyFillRectTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectTiled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+
+static void
+XAAOverFillSpansSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansSolid)(
+ pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+
+static void
+XAAOverFillSpansStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansStippled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+static void
+XAAOverFillSpansOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansOpaqueStippled)(
+ pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+
+static void
+XAAOverFillSpansTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansTiled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+static int
+XAAOverPolyText8TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText8TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static int
+XAAOverPolyText16TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText16TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageText8TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText8TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageText16TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText16TE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageGlyphBltTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageGlyphBltTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyGlyphBltTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyGlyphBltTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static int
+XAAOverPolyText8NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText8NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static int
+XAAOverPolyText16NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText16NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageText8NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText8NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageText16NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText16NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageGlyphBltNonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageGlyphBltNonTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyGlyphBltNonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyGlyphBltNonTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyRectangleThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyRectangleThinSolid)(pDraw, pGC, nRectsInit, pRectsInit);
+}
+
+
+
+static void
+XAAOverPolylinesWideSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesWideSolid)(pDraw, pGC, mode, npt, pPts);
+}
+
+
+static void
+XAAOverPolylinesThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesThinSolid)(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+XAAOverPolySegmentThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolySegmentThinSolid)(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+XAAOverPolylinesThinDashed(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesThinDashed)(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+XAAOverPolySegmentThinDashed(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolySegmentThinDashed)(pDraw, pGC, nseg, pSeg);
+}
+
+
+static void
+XAAOverFillPolygonSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonSolid)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+static void
+XAAOverFillPolygonStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonStippled)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+
+static void
+XAAOverFillPolygonOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonOpaqueStippled)(
+ pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+static void
+XAAOverFillPolygonTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonTiled)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+
+static void
+XAAOverPolyFillArcSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillArcSolid)(pDraw, pGC, narcs, parcs);
+}
+
+
+static void
+XAAOverPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+}
+
diff --git a/hw/xfree86/xaa/xaaPCache.c b/hw/xfree86/xaa/xaaPCache.c
new file mode 100644
index 000000000..e6163b33a
--- /dev/null
+++ b/hw/xfree86/xaa/xaaPCache.c
@@ -0,0 +1,2366 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPCache.c,v 1.30 2000/09/25 23:56:14 mvojkovi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "gc.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "servermd.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaacexp.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+#define MAX_COLOR 32
+#define MAX_MONO 32
+#define MAX_8 32
+#define MAX_128 32
+#define MAX_256 32
+#define MAX_512 16
+
+static int CacheInitIndex = -1;
+#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
+
+
+typedef struct _CacheLink {
+ int x;
+ int y;
+ int w;
+ int h;
+ struct _CacheLink *next;
+} CacheLink, *CacheLinkPtr;
+
+
+static void
+TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
+{
+ while(num--) {
+ array->x = list->x;
+ array->y = list->y;
+ array->w = list->w;
+ array->h = list->h;
+ array->serialNumber = 0;
+ array->fg = array->bg = -1;
+ list = list->next;
+ array++;
+ }
+}
+
+
+
+static CacheLinkPtr
+Enlist(CacheLinkPtr link, int x, int y, int w, int h)
+{
+ CacheLinkPtr newLink;
+
+ newLink = xalloc(sizeof(CacheLink));
+ newLink->next = link;
+ newLink->x = x; newLink->y = y;
+ newLink->w = w; newLink->h = h;
+ return newLink;
+}
+
+
+
+static CacheLinkPtr
+Delist(CacheLinkPtr link) {
+ CacheLinkPtr ret = NULL;
+
+ if(link) {
+ ret = link->next;
+ xfree(link);
+ }
+ return ret;
+}
+
+
+
+static void
+FreeList(CacheLinkPtr link) {
+ CacheLinkPtr tmp;
+
+ while(link) {
+ tmp = link;
+ link = link->next;
+ xfree(tmp);
+ }
+}
+
+
+
+static CacheLinkPtr
+QuadLinks(CacheLinkPtr big, CacheLinkPtr little)
+{
+ /* CAUTION: This doesn't free big */
+ int w1, w2, h1, h2;
+
+ while(big) {
+ w1 = big->w >> 1;
+ w2 = big->w - w1;
+ h1 = big->h >> 1;
+ h2 = big->h - h1;
+
+ little = Enlist(little, big->x, big->y, w1, h1);
+ little = Enlist(little, big->x + w1, big->y, w2, h1);
+ little = Enlist(little, big->x, big->y + h1, w1, h2);
+ little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
+
+ big = big->next;
+ }
+ return little;
+}
+
+
+static void
+SubdivideList(CacheLinkPtr *large, CacheLinkPtr *small)
+{
+ CacheLinkPtr big = *large;
+ CacheLinkPtr little = *small;
+ int size = big->w >> 1;
+
+ little = Enlist(little, big->x, big->y, size, size);
+ little = Enlist(little, big->x + size, big->y, size, size);
+ little = Enlist(little, big->x, big->y + size, size, size);
+ little = Enlist(little, big->x + size, big->y + size, size, size);
+ *small = little;
+ big = Delist(big);
+ *large = big;
+}
+
+static void
+FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
+{
+ if(!pPriv) return;
+
+ if(pPriv->Info512)
+ xfree(pPriv->Info512);
+ if(pPriv->Info256)
+ xfree(pPriv->Info256);
+ if(pPriv->Info128)
+ xfree(pPriv->Info128);
+ if(pPriv->InfoColor)
+ xfree(pPriv->InfoColor);
+ if(pPriv->InfoMono)
+ xfree(pPriv->InfoMono);
+ if(pPriv->InfoPartial)
+ xfree(pPriv->InfoPartial);
+
+ xfree(pPriv);
+}
+
+void
+XAAClosePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(infoRec->PixmapCachePrivate)
+ FreePixmapCachePrivate(
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
+
+ infoRec->PixmapCachePrivate = NULL;
+}
+
+
+
+static CacheLinkPtr
+ThinOutPartials(
+ CacheLinkPtr ListPartial,
+ int *num, int *maxw, int *maxh
+) {
+/* This guy's job is to get at least 4 big slots out of a list of fragments */
+
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h;
+
+ List64 = List32 = List16 = List8 = ListKeepers = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ w = h = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
+ we free it. */
+
+ pCur = ListPartial;
+ while(pCur) {
+ next = pCur->next;
+ if((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64; List64 = pCur;
+ Num64++;
+ } else
+ if((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32; List32 = pCur;
+ Num32++;
+ } else
+ if((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16; List16 = pCur;
+ Num16++;
+ } else
+ if((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8; List8 = pCur;
+ Num8++;
+ } else {
+ xfree(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if(Num64 >= 4) {
+ ListKeepers = List64; List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ } else if(Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if(Num32 >= 4) {
+ ListKeepers = List32; List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ } else if(Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if(Num16 >= 4) {
+ ListKeepers = List16; List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ } else if(Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if(Num8 >= 4) {
+ ListKeepers = List8; List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if(List64) FreeList(List64);
+ if(List32) FreeList(List32);
+ if(List16) FreeList(List16);
+ if(List8) FreeList(List8);
+
+
+ /* Enlarge the slots if we can */
+
+ if(ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+ w = h = 128;
+
+ while(pLink) {
+ if(pLink->w < w) w = pLink->w;
+ if(pLink->h < h) h = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *maxw = w;
+ *maxh = h;
+ *num = NumKeepers;
+ return ListKeepers;
+}
+
+static void
+ConvertColorToMono(
+ CacheLinkPtr *ColorList,
+ int ColorW, int ColorH,
+ CacheLinkPtr *MonoList,
+ int MonoW, int MonoH
+){
+ int x, y, w;
+
+ x = (*ColorList)->x; y = (*ColorList)->y;
+ *ColorList = Delist(*ColorList);
+
+ while(ColorH) {
+ ColorH -= MonoH;
+ for(w = 0; w <= (ColorW - MonoW); w += MonoW)
+ *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
+ }
+}
+
+static void
+ConvertAllPartialsTo8x8(
+ int *NumMono, int *NumColor,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr *ListMono,
+ CacheLinkPtr *ListColor,
+ XAAInfoRecPtr infoRec
+){
+/* This guy extracts as many 8x8 slots as it can out of fragments */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ int x, y, w, Height, Width;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr pLink = ListPartial;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+ int MonosPerColor = 1;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ /* Break up the area into as many Color and Mono slots as we can */
+
+ while(pLink) {
+ Height = pLink->h;
+ Width = pLink->w;
+ x = pLink->x;
+ y = pLink->y;
+
+ if(DoColor) {
+ while(Height >= ColorH) {
+ Height -= ColorH;
+ for(w = 0; w <= (Width - ColorW); w += ColorW) {
+ ColorList = Enlist(
+ ColorList, x + w, y + Height, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+
+ if(DoMono && (Height >= MonoH)) {
+ while(Height >= MonoH) {
+ Height -= MonoH;
+ for(w = 0; w <= (Width - MonoW); w += MonoW) {
+ MonoList = Enlist(
+ MonoList, x + w, y + Height, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+
+ pLink = pLink->next;
+ }
+
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ FreeList(ListPartial);
+}
+
+
+static CacheLinkPtr
+ExtractOneThatFits(CacheLinkPtr *initList, int w, int h)
+{
+ CacheLinkPtr list = *initList;
+ CacheLinkPtr prev = NULL;
+
+ while(list) {
+ if((list->w >= w) && (list->h >= h))
+ break;
+ prev = list;
+ list = list->next;
+ }
+
+ if(list) {
+ if(prev)
+ prev->next = list->next;
+ else
+ *initList = list->next;
+
+ list->next = NULL;
+ }
+
+ return list;
+}
+
+
+static CacheLinkPtr
+ConvertSomePartialsTo8x8(
+ int *NumMono, int *NumColor, int *NumPartial,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr *ListMono,
+ CacheLinkPtr *ListColor,
+ int *maxw, int *maxh,
+ XAAInfoRecPtr infoRec
+){
+/* This guy tries to get 4 of each type of 8x8 slot requested out of
+ a list of fragments all while trying to retain some big fragments
+ for the cache blits */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h, Width, Height;
+ int MonosPerColor = 1;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ Width = Height = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ We make 8x8 patterns from the leftovers if we can. */
+
+ pCur = ListPartial;
+ while(pCur) {
+ next = pCur->next;
+ if((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64; List64 = pCur;
+ Num64++;
+ } else
+ if((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32; List32 = pCur;
+ Num32++;
+ } else
+ if((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16; List16 = pCur;
+ Num16++;
+ } else
+ if((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8; List8 = pCur;
+ Num8++;
+ } else {
+ h = pCur->h;
+ if(DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
+ while(h >= ColorH) {
+ h -= ColorH;
+ for(w = 0; w <= (pCur->w - ColorW); w += ColorW) {
+ ColorList = Enlist( ColorList,
+ pCur->x + w, pCur->y + h, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+ if(DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
+ while(h >= MonoH) {
+ h -= MonoH;
+ for(w = 0; w <= (pCur->w - MonoW); w += MonoW) {
+ MonoList = Enlist( MonoList,
+ pCur->x + w, pCur->y + h, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+ xfree(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* Try to extract at least 4 of each type of 8x8 slot that we need */
+
+ if(DoColor) {
+ CacheLinkPtr theOne;
+ while(*NumColor < 4) {
+ theOne = NULL;
+ if(Num8) {
+ if((theOne = ExtractOneThatFits(&List8, ColorW, ColorH)))
+ Num8--;
+ }
+ if(Num16 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List16, ColorW, ColorH)))
+ Num16--;
+ }
+ if(Num32 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
+ Num32--;
+ }
+ if(Num64 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
+ Num64--;
+ }
+
+ if(!theOne) break;
+
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+
+ if(DoMono) {
+ while(*NumColor && (*NumMono < 4)) {
+ ConvertColorToMono(&ColorList, ColorW, ColorH,
+ &MonoList, MonoW, MonoH);
+ (*NumColor)--; *NumMono += MonosPerColor;
+ }
+ }
+ }
+ }
+
+ if(DoMono) {
+ CacheLinkPtr theOne;
+ while(*NumMono < 4) {
+ theOne = NULL;
+ if(Num8) {
+ if((theOne = ExtractOneThatFits(&List8, MonoW, MonoH)))
+ Num8--;
+ }
+ if(Num16 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List16, MonoW, MonoH)))
+ Num16--;
+ }
+ if(Num32 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
+ Num32--;
+ }
+ if(Num64 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
+ Num64--;
+ }
+
+ if(!theOne) break;
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+ }
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if(Num64 >= 4) {
+ ListKeepers = List64; List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ } else if(Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if(Num32 >= 4) {
+ ListKeepers = List32; List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ } else if(Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if(Num16 >= 4) {
+ ListKeepers = List16; List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ } else if(Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if(Num8 >= 4) {
+ ListKeepers = List8; List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if(List64)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List64,
+ &MonoList, &ColorList, infoRec);
+ if(List32)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List32,
+ &MonoList, &ColorList, infoRec);
+ if(List16)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List16,
+ &MonoList, &ColorList, infoRec);
+ if(List8)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List8,
+ &MonoList, &ColorList, infoRec);
+
+
+ /* Enlarge the slots if we can */
+
+ if(ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+ Width = Height = 128;
+
+ while(pLink) {
+ if(pLink->w < Width) Width = pLink->w;
+ if(pLink->h < Height) Height = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ *maxw = Width;
+ *maxh = Height;
+ *NumPartial = NumKeepers;
+ return ListKeepers;
+}
+
+
+void
+XAAInitPixmapCache(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = (XAAInfoRecPtr)data;
+ XAAPixmapCachePrivatePtr pCachePriv;
+ BoxPtr pBox = REGION_RECTS(areas);
+ int nBox = REGION_NUM_RECTS(areas);
+ int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
+ int Target512, Target256;
+ CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
+ int x, y, w, h, ntotal, granularity, width, height, i;
+ int MaxPartialWidth, MaxPartialHeight;
+
+ infoRec->MaxCacheableTileWidth = 0;
+ infoRec->MaxCacheableTileHeight = 0;
+ infoRec->MaxCacheableStippleHeight = 0;
+ infoRec->MaxCacheableStippleWidth = 0;
+ infoRec->UsingPixmapCache = FALSE;
+
+
+ if(!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
+ return;
+
+ /* Allocate a persistent per-screen init flag to control messages */
+ if (CacheInitIndex < 0)
+ CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ /* free the old private data if it exists */
+ if(infoRec->PixmapCachePrivate) {
+ FreePixmapCachePrivate(
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
+ infoRec->PixmapCachePrivate = NULL;
+ }
+
+ Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
+ List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
+ granularity = infoRec->CachePixelGranularity;
+ if(granularity <= 1) granularity = 0;
+
+ /* go through the boxes and break it into as many pieces as we can fit */
+
+ while(nBox--) {
+ x = pBox->x1;
+ if(granularity) {
+ int tmp = x % granularity;
+ if(tmp) x += (granularity - tmp);
+ }
+ width = pBox->x2 - x;
+ if(width <= 0) {pBox++; continue;}
+
+ y = pBox->y1;
+ height = pBox->y2 - y;
+
+ for(h = 0; h <= (height - 512); h += 512) {
+ for(w = 0; w <= (width - 512); w += 512) {
+ List512 = Enlist(List512, x + w, y + h, 512, 512);
+ Num512++;
+ }
+ for(; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
+ Num256 += 2;
+ }
+ for(; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
+ Num128 += 4;
+ }
+ if(w < width) {
+ int d = width - w;
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
+ NumPartial += 4;
+ }
+ }
+ for(; h <= (height - 256); h += 256) {
+ for(w = 0; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ Num256++;
+ }
+ for(; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ Num128 += 2;
+ }
+ if(w < width) {
+ int d = width - w;
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ NumPartial += 2;
+ }
+ }
+ for(; h <= (height - 128); h += 128) {
+ for(w = 0; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ Num128++;
+ }
+ if(w < width) {
+ ListPartial = Enlist(
+ ListPartial, x + w, y + h, width - w, 128);
+ NumPartial++;
+ }
+ }
+ if(h < height) {
+ int d = height - h;
+ for(w = 0; w <= (width - 128); w += 128) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
+ NumPartial++;
+ }
+ if(w < width) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
+ NumPartial++;
+ }
+ }
+ pBox++;
+ }
+
+
+/*
+ by this point we've carved the space into as many 512x512, 256x256
+ and 128x128 blocks as we could fit. We will then break larger
+ blocks into smaller ones if we need to. The rules are as follows:
+
+ 512x512 -
+ 1) Don't take up more than half the memory.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_512.
+
+ 256x256 -
+ 1) Don't take up more than a quarter of the memory enless there
+ aren't any 512x512s. Then we can take up to half.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_256.
+
+ 128x128 -
+ 1) Don't make more than MAX_128.
+
+ We don't bother with the partial blocks unless we can use them
+ for 8x8 pattern fills or we are short on larger blocks.
+
+*/
+
+ ntotal = Num128 + (Num256<<2) + (Num512<<4);
+
+ Target512 = ntotal >> 5;
+ if(Target512 < 4) Target512 = 0;
+ if(!Target512) Target256 = ntotal >> 3;
+ else Target256 = ntotal >> 4;
+ if(Target256 < 4) Target256 = 0;
+
+ if(!Num512) { /* no room */
+ } else if((Num512 < 4) || (!Target512)) {
+ while(Num512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ } else if((Num512 > MAX_512) || (Num512 > Target512)){
+ while(Num512 > MAX_512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ while(Num512 > Target512) {
+ if(Num256 < MAX_256) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ } else break;
+ }
+ }
+
+ if(!Num256) { /* no room */
+ } else if((Num256 < 4) || (!Target256)) {
+ while(Num256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ }
+ } else if((Num256 > MAX_256) || (Num256 > Target256)) {
+ while(Num256 > MAX_256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ }
+ while(Num256 > Target256) {
+ if(Num128 < MAX_128) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ } else break;
+ }
+ }
+
+ if(Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
+ CacheLinkPtr next;
+ int max = (Num128 > MAX_128) ? MAX_128 : 0;
+
+ /*
+ * Note: next is set in this way to work around a code generation
+ * bug in gcc 2.7.2.3.
+ */
+ next = List128->next;
+ while(Num128 > max) {
+ List128->next = ListPartial;
+ ListPartial = List128;
+ if((List128 = next))
+ next = List128->next;
+ NumPartial++; Num128--;
+ }
+ }
+
+ MaxPartialHeight = MaxPartialWidth = 0;
+
+ /* at this point we have as many 512x512 and 256x256 slots as we
+ want but may have an excess of 128x128 slots. We still need
+ to find out if we need 8x8 slots. We take these from the
+ partials if we have them. Otherwise, we break some 128x128's */
+
+ if(!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
+ if(NumPartial) {
+ if(Num128) { /* don't bother with partials */
+ FreeList(ListPartial);
+ NumPartial = 0; ListPartial = NULL;
+ } else {
+ /* We have no big slots. Weed out the unusable partials */
+ ListPartial = ThinOutPartials(ListPartial, &NumPartial,
+ &MaxPartialWidth, &MaxPartialHeight);
+ }
+ }
+ } else {
+ int MonosPerColor = 1;
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+
+ if(DoColor) infoRec->CanDoColor8x8 = FALSE;
+ if(DoMono) infoRec->CanDoMono8x8 = FALSE;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ if(Num128) {
+ if(NumPartial) { /* use all for 8x8 slots */
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ ListPartial, &ListMono, &ListColor, infoRec);
+ NumPartial = 0; ListPartial = NULL;
+ }
+
+ /* Get some 8x8 slots from the 128 slots */
+ while((Num128 > 4) &&
+ ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
+ CacheLinkPtr tmp = NULL;
+
+ tmp = Enlist(tmp, List128->x, List128->y,
+ List128->w, List128->h);
+ List128 = Delist(List128);
+ Num128--;
+
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ tmp, &ListMono, &ListColor, infoRec);
+ }
+ } else if(NumPartial) {
+ /* We have share partials between 8x8 slots and tiles. */
+ ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,
+ &NumPartial, ListPartial, &ListMono, &ListColor,
+ &MaxPartialWidth, &MaxPartialHeight, infoRec);
+ }
+
+
+ if(DoMono && DoColor) {
+ if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while(NumColor > max) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--; NumMono += MonosPerColor;
+ }
+ }
+
+ /* favor Mono slots over Color ones */
+ while((NumColor > 4) && (NumMono < MAX_MONO)) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--; NumMono += MonosPerColor;
+ }
+ }
+
+ if(NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
+ int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
+
+ while(NumMono > max) {
+ ListMono = Delist(ListMono);
+ NumMono--;
+ }
+ }
+ if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while(NumColor > max) {
+ ListColor = Delist(ListColor);
+ NumColor--;
+ }
+ }
+ }
+
+
+ pCachePriv = xcalloc(1,sizeof(XAAPixmapCachePrivate));
+ if(!pCachePriv) {
+ if(Num512) FreeList(List512);
+ if(Num256) FreeList(List256);
+ if(Num128) FreeList(List128);
+ if(NumPartial) FreeList(ListPartial);
+ if(NumColor) FreeList(ListColor);
+ if(NumMono) FreeList(ListMono);
+ return;
+ }
+
+ infoRec->PixmapCachePrivate = (char*)pCachePriv;
+
+ if(Num512) {
+ pCachePriv->Info512 = xcalloc(Num512,sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info512) Num512 = 0;
+ if(Num512) TransferList(List512, pCachePriv->Info512, Num512);
+ FreeList(List512);
+ pCachePriv->Num512x512 = Num512;
+ }
+ if(Num256) {
+ pCachePriv->Info256 = xcalloc(Num256, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info256) Num256 = 0;
+ if(Num256) TransferList(List256, pCachePriv->Info256, Num256);
+ FreeList(List256);
+ pCachePriv->Num256x256 = Num256;
+ }
+ if(Num128) {
+ pCachePriv->Info128 = xcalloc(Num128, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info128) Num128 = 0;
+ if(Num128) TransferList(List128, pCachePriv->Info128, Num128);
+ FreeList(List128);
+ pCachePriv->Num128x128 = Num128;
+ }
+
+ if(NumPartial) {
+ pCachePriv->InfoPartial = xcalloc(NumPartial, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoPartial) NumPartial = 0;
+ if(NumPartial)
+ TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
+ FreeList(ListPartial);
+ pCachePriv->NumPartial = NumPartial;
+ }
+
+ if(NumColor) {
+ pCachePriv->InfoColor = xcalloc(NumColor, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoColor) NumColor = 0;
+ if(NumColor) TransferList(ListColor, pCachePriv->InfoColor, NumColor);
+ FreeList(ListColor);
+ pCachePriv->NumColor = NumColor;
+ }
+
+ if(NumMono) {
+ pCachePriv->InfoMono = xcalloc(NumMono, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoMono) NumMono = 0;
+ if(NumMono) TransferList(ListMono, pCachePriv->InfoMono, NumMono);
+ FreeList(ListMono);
+ pCachePriv->NumMono = NumMono;
+ }
+
+
+ if(NumPartial) {
+ infoRec->MaxCacheableTileWidth = MaxPartialWidth;
+ infoRec->MaxCacheableTileHeight = MaxPartialHeight;
+ }
+ if(Num128)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
+ if(Num256)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
+ if(Num512)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
+
+
+ infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
+ infoRec->MaxCacheableStippleWidth =
+ infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
+ if(infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP)
+ infoRec->MaxCacheableStippleWidth /= 3;
+
+ if(NumMono) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ (HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS))) {
+ int numPerLine =
+ infoRec->CacheWidthMono8x8Pattern/infoRec->MonoPatternPitch;
+
+ for(i = 0; i < 64; i++) {
+ pCachePriv->MonoOffsets[i].y = i/numPerLine;
+ pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
+ infoRec->MonoPatternPitch;
+ }
+ }
+ infoRec->CanDoMono8x8 = TRUE;
+ }
+ if(NumColor) {
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+
+ for(i = 0; i < 64; i++) {
+ pCachePriv->ColorOffsets[i].y = i & 0x07;
+ pCachePriv->ColorOffsets[i].x = i & ~0x07;
+ }
+ }
+ infoRec->CanDoColor8x8 = TRUE;
+ }
+
+ if(!CACHEINIT(pScrn)) {
+ xf86ErrorF("\tSetting up tile and stipple cache:\n");
+ if(NumPartial)
+ xf86ErrorF("\t\t%i %ix%i slots\n",
+ NumPartial, MaxPartialWidth, MaxPartialHeight);
+ if(Num128) xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
+ if(Num256) xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
+ if(Num512) xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
+ if(NumColor) xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
+ if(NumMono) xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
+ }
+
+ if(!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
+ if(!CACHEINIT(pScrn))
+ xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
+ } else infoRec->UsingPixmapCache = TRUE;
+
+ CACHEINIT(pScrn) = 1;
+}
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+static CARD32 StippleMasks[4] = {
+ 0x80808080,
+ 0xC0C0C0C0,
+ 0x00000000,
+ 0xF0F0F0F0
+};
+#else
+static CARD32 StippleMasks[4] = {
+ 0x01010101,
+ 0x03030303,
+ 0x00000000,
+ 0x0F0F0F0F
+};
+#endif
+
+Bool
+XAACheckStippleReducibility(PixmapPtr pPixmap)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ CARD32 *IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int i;
+ CARD32 bits[8];
+ CARD32 mask = SHIFT_R(0xFFFFFFFF,24);
+
+ pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
+ pPriv->flags &= ~REDUCIBLE_TO_8x8;
+
+ if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ i = (h > 8) ? 8 : h;
+
+ switch(w) {
+ case 32:
+ while(i--) {
+ bits[i] = IntPtr[i] & mask;
+ if( (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 8)), 8)) ||
+ (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,16)),16)) ||
+ (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,24)),24)))
+ return FALSE;
+ }
+ break;
+ case 16:
+ while(i--) {
+ bits[i] = IntPtr[i] & mask;
+ if(bits[i] != ((IntPtr[i] & SHIFT_R(SHIFT_L(mask,8),8))))
+ return FALSE;
+ }
+ break;
+ default:
+ while(i--)
+ bits[i] = IntPtr[i] & mask;
+ break;
+ }
+
+ switch(h) {
+ case 32:
+ if( (IntPtr[8] != IntPtr[16]) || (IntPtr[9] != IntPtr[17]) ||
+ (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
+ (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
+ (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
+ (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
+ (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
+ (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
+ (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
+ return FALSE;
+ /* fall through */
+ case 16:
+ if( (IntPtr[0] != IntPtr[8]) || (IntPtr[1] != IntPtr[9]) ||
+ (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
+ (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
+ (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
+ return FALSE;
+ case 8: break;
+ case 1: bits[1] = bits[0];
+ case 2: bits[2] = bits[0]; bits[3] = bits[1];
+ case 4: bits[4] = bits[0]; bits[5] = bits[1];
+ bits[6] = bits[2]; bits[7] = bits[3];
+ break;
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ pPriv->pattern0 = bits[0] | SHIFT_L(bits[1],8) | SHIFT_L(bits[2],16) | SHIFT_L(bits[3],24);
+ pPriv->pattern1 = bits[4] | SHIFT_L(bits[5],8) | SHIFT_L(bits[6],16) | SHIFT_L(bits[7],24);
+
+ if(w < 8) {
+ pPriv->pattern0 &= StippleMasks[w - 1];
+ pPriv->pattern1 &= StippleMasks[w - 1];
+
+ switch(w) {
+ case 1: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,1);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,1);
+ case 2: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,2);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,2);
+ case 4: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,4);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,4);
+ }
+ }
+
+ if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
+ pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
+ }
+
+
+ return TRUE;
+}
+
+
+Bool
+XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ CARD32 *IntPtr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int pitch = pPixmap->devKind >> 2;
+ int dwords, i, j;
+
+ pPriv->flags |= REDUCIBILITY_CHECKED;
+ pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
+
+ if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
+ i = (h > 8) ? 8 : h;
+
+
+ if(w > 8) {
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ switch(pPixmap->drawable.bitsPerPixel) {
+ case 8:
+ while(i--) {
+ for(j = 2; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x01])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 16:
+ while(i--) {
+ for(j = 4; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x03])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 24:
+ while(i--) {
+ for(j = 6; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j % 6])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 32:
+ while(i--) {
+ for(j = 8; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x07])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ default: return FALSE;
+ }
+
+ }
+
+
+ if(h == 32) {
+ CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
+ i = 8;
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ IntPtr3 = IntPtr2 + (pitch << 3);
+ IntPtr4 = IntPtr3 + (pitch << 3);
+ while(i--) {
+ for(j = 0; j < dwords; j++)
+ if((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
+ (IntPtr[j] != IntPtr4[j]))
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ IntPtr3 += pitch;
+ IntPtr4 += pitch;
+ }
+ } else if (h == 16) {
+ CARD32 *IntPtr2;
+ i = 8;
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ while(i--) {
+ for(j = 0; j < dwords; j++)
+ if(IntPtr[j] != IntPtr2[j])
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ }
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ if(checkMono) {
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ unsigned char bits[8];
+ int fg, bg = -1, x, y;
+
+ i = (h > 8) ? 8 : h;
+ j = (w > 8) ? 8 : w;
+
+ if(pPixmap->drawable.bitsPerPixel == 8) {
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+ fg = srcp[0];
+ pitch = pPixmap->devKind;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(srcp[x] != fg) {
+ if(bg == -1) bg = srcp[x];
+ else if(bg != srcp[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 16) {
+ unsigned short *srcp = (unsigned short*)pPixmap->devPrivate.ptr;
+ fg = srcp[0];
+ pitch = pPixmap->devKind >> 1;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(srcp[x] != fg) {
+ if(bg == -1) bg = srcp[x];
+ else if(bg != srcp[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 24) {
+ CARD32 val;
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+ fg = *((CARD32*)srcp) & 0x00FFFFFF;
+ pitch = pPixmap->devKind;
+ j *= 3;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x+=3) {
+ val = *((CARD32*)(srcp+x)) & 0x00FFFFFF;
+ if(val != fg) {
+ if(bg == -1) bg = val;
+ else if(bg != val)
+ return TRUE;
+ } else bits[y] |= 1 << (x/3);
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 32) {
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ fg = IntPtr[0];
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(IntPtr[x] != fg) {
+ if(bg == -1) bg = IntPtr[x];
+ else if(bg != IntPtr[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ IntPtr += pitch;
+ }
+ } else return TRUE;
+
+ pPriv->fg = fg;
+ if(bg == -1) pPriv->bg = fg;
+ else pPriv->bg = bg;
+
+ if(h < 8) {
+ switch(h) {
+ case 1: bits[1] = bits[0];
+ case 2: bits[2] = bits[0]; bits[3] = bits[1];
+ case 4: bits[4] = bits[0]; bits[5] = bits[1];
+ bits[6] = bits[2]; bits[7] = bits[3];
+ break;
+ }
+ }
+
+ pPriv->pattern0 =
+ bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
+ pPriv->pattern1 =
+ bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
+
+ if(w < 8) {
+ switch(w) {
+ case 1: pPriv->pattern0 |= (pPriv->pattern0 << 1);
+ pPriv->pattern1 |= (pPriv->pattern1 << 1);
+ case 2: pPriv->pattern0 |= (pPriv->pattern0 << 2);
+ pPriv->pattern1 |= (pPriv->pattern1 << 2);
+ case 4: pPriv->pattern0 |= (pPriv->pattern0 << 4);
+ pPriv->pattern1 |= (pPriv->pattern1 << 4);
+ }
+ }
+ pPriv->flags |= REDUCIBLE_TO_2_COLOR;
+
+ if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
+ pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
+ }
+
+ }
+
+ return TRUE;
+}
+
+
+void XAATileCache(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache,
+ int w, int h
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
+
+ while((w << 1) <= pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, w, h);
+ w <<= 1;
+ }
+ if(w != pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, pCache->w - w, h);
+ w = pCache->w;
+ }
+
+ while((h << 1) <= pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w, h);
+ h <<= 1;
+ }
+ if(h != pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w, pCache->h - h);
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if(size <= 128) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if(size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if(size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheTile()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if(pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, w, h, pPix->devPrivate.ptr,
+ pPix->devKind, pPix->drawable.bitsPerPixel, pPix->drawable.depth);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
+ int *current;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ if((h <= 128) && (w <= 128 * bpp)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256 * bpp)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 526 * bpp)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ if(w <= 32) {
+ if(w & (w - 1)) funcNo = 1;
+ else funcNo = 0;
+ } else funcNo = 2;
+
+ pad = BitmapBytePad(pCache->w * bpp);
+ dwords = pad >> 2;
+ dstPtr = data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ srcPtr = (unsigned char*)pPix->devPrivate.ptr;
+
+ if(infoRec->ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
+ else
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
+
+ /* don't bother generating more than we'll ever use */
+ max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
+ if(dwords > max)
+ dwords = max;
+
+ for(i = 0; i < h; i++) {
+ (*StippleFunc)((CARD32*)dstPtr, (CARD32*)srcPtr, 0, w, dwords);
+ srcPtr += pPix->devKind;
+ dstPtr += pad;
+ }
+
+ while((h<<1) <= pCache->h) {
+ memcpy(data + (pad * h), data, pad * h);
+ h <<= 1;
+ }
+
+ if(h < pCache->h)
+ memcpy(data + (pad * h), data, pad * (pCache->h - h));
+
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
+ pad, bpp, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if((h <= 128) && (w <= 128)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 526)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
+ pPix->devKind, 1, 2);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if(size <= 128) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if(size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if(size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+ /* lets look for it */
+ if(bg == -1)
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ else
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (bg == pCache->bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->fg = fg;
+ if(bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+ pCache->bg = bg;
+
+ pCache->orig_w = w; pCache->orig_h = h;
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
+ pPix->devKind, fg, bg);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoMono;
+ int i;
+
+ for(i = 0; i < pCachePriv->NumMono; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
+ return pCache;
+ }
+
+ /* OK, let's cache it */
+ pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++];
+ if(pCachePriv->CurrentMono >= pCachePriv->NumMono)
+ pCachePriv->CurrentMono = 0;
+
+ pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
+ pCache->pat0 = pat0;
+ pCache->pat1 = pat1;
+
+ (*infoRec->WriteMono8x8PatternToCache)(pScrn, pCache);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoColor;
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int i;
+
+ if(!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->fg = pCache->bg = -1;
+ } else {
+ int pat0 = pixPriv->pattern0;
+ int pat1 = pixPriv->pattern1;
+
+ if(fg == -1) { /* it's a tile */
+ fg = pixPriv->fg; bg = pixPriv->bg;
+ }
+
+ if(bg == -1) { /* stipple */
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg != fg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ } else { /* opaque stipple */
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg == bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ if(bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+
+ pCache->pat0 = pat0; pCache->pat1 = pat1;
+ pCache->fg = fg; pCache->bg = bg;
+ pCache->serialNumber = 1;
+ }
+
+ (*infoRec->WriteColor8x8PatternToCache)(pScrn, pPix, pCache);
+
+ return pCache;
+}
+
+
+void
+XAAWriteBitmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WriteBitmap)(pScrn, x, y, w, h, src, srcwidth,
+ 0, fg, bg, GXcopy, ~0);
+}
+
+void
+XAAWriteBitmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+){
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ XID gcvals[2];
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
+ y + h, pScreenPix->drawable.depth,
+ pScreenPix->drawable.bitsPerPixel,
+ pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
+ gcvals[0] = fg;
+ gcvals[1] = bg;
+ DoChangeGC(pGC, GCForeground | GCBackground, gcvals, 0);
+ ValidateGC((DrawablePtr)pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, 1, x, y, w, h, 0,
+ XYBitmap, (pointer)src);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+
+void
+XAAWritePixmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WritePixmap)(pScrn, x, y, w, h, src, srcwidth,
+ GXcopy, ~0, -1, bpp, depth);
+}
+
+
+
+void
+XAAWritePixmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+){
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, x + w, y + h,
+ depth, bpp, pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(depth, pScreen);
+ ValidateGC((DrawablePtr)pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ if(bpp == BitsPerPixel(depth))
+ (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, depth, x, y, w,
+ h, 0, ZPixmap, (pointer)src);
+ else {
+ PixmapPtr pSrcPix;
+
+ pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
+ srcwidth, (pointer)src);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pSrcPix, (DrawablePtr)pDstPix,
+ pGC, 0, 0, w, h, x, y);
+
+ FreeScratchPixmapHeader(pSrcPix);
+ }
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+
+void
+XAAWriteMono8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ unsigned char *data;
+ int pad, Bpp = (pScrn->bitsPerPixel >> 3);
+
+ pCache->offsets = pCachePriv->MonoOffsets;
+
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ if(!data) return;
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ CARD32* ptr = (CARD32*)data;
+ ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
+ } else {
+ CARD32 *ptr;
+ DDXPointPtr pPoint = pCache->offsets;
+ int patx, paty, i;
+
+ for(i = 0; i < 64; i++, pPoint++) {
+ patx = pCache->pat0; paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32*)(data + (pad * pPoint->y) + (Bpp * pPoint->x));
+ ptr[0] = patx; ptr[1] = paty;
+ }
+ }
+
+ (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+}
+
+void
+XAAWriteColor8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ int pad, i, w, h, nw, nh, Bpp;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ pCache->offsets = pCachePriv->ColorOffsets;
+
+ if(pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
+ CARD32* ptr;
+ pad = BitmapBytePad(pCache->w);
+ data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ if(!data) return;
+
+ if(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ ptr = (CARD32*)data;
+ ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
+ } else {
+ int patx, paty;
+
+ ptr = (CARD32*)data;
+ ptr[0] = ptr[2] = pCache->pat0; ptr[1] = ptr[3] = pCache->pat1;
+ for(i = 1; i < 8; i++) {
+ patx = pCache->pat0; paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i, 0,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32*)(data + (pad * i));
+ ptr[0] = ptr[2] = patx; ptr[1] = ptr[3] = paty;
+ }
+ }
+
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pCache->fg, pCache->bg);
+
+ DEALLOCATE_LOCAL(data);
+ return;
+ }
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ h = min(8,pPix->drawable.height);
+ w = min(8,pPix->drawable.width);
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char*)ALLOCATE_LOCAL(pad * pCache->h);
+ if(!data) return;
+
+ /* Write and expand horizontally. */
+ for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--;
+ srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
+ nw = w;
+ memcpy(dstPtr, srcPtr, w * Bpp);
+ while (nw != 8) {
+ memcpy(dstPtr + (nw * Bpp), srcPtr, nw * Bpp);
+ nw <<= 1;
+ }
+ }
+ nh = h;
+ /* Expand vertically. */
+ while (nh != 8) {
+ memcpy(data + (nh*pScrn->bitsPerPixel), data, nh*pScrn->bitsPerPixel);
+ nh <<= 1;
+ }
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int j;
+ unsigned char *ptr = data + (128 * Bpp);
+
+ memcpy(data + (64 * Bpp), data, 64 * Bpp);
+ for(i = 1; i < 8; i++, ptr += (128 * Bpp)) {
+ for(j = 0; j < 8; j++) {
+ memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
+ (8 - i) * Bpp);
+ memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp, i*Bpp);
+ }
+ memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
+ }
+ }
+
+ (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
+
+ DEALLOCATE_LOCAL(data);
+}
+
+
+
+int
+XAAStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if(infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+
+ if(infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+
+int
+XAAOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(XAA_DEPTH_BUG(pGC))
+ return 0;
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if(infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+ if(infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+
+
+int
+XAATiledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->tile.pixmap;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_PIXMAP_COPY;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPixmap,infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ CHECK_NO_GXCOPY(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROP(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillImageWriteRectsFlags)) {
+
+ return DO_IMAGE_WRITE;
+ }
+
+ return 0;
+}
+
+
+static int RotateMasksX[8] = {
+ 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
+ 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
+};
+
+static int RotateMasksY[4] = {
+ 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
+};
+
+void
+XAARotateMonoPattern(
+ int *pat0, int *pat1,
+ int xorg, int yorg,
+ Bool msbfirst
+){
+ int tmp, mask;
+
+ if(xorg) {
+ if(msbfirst) xorg = 8 - xorg;
+ mask = RotateMasksX[xorg];
+ *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
+ *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
+ }
+ if(yorg >= 4) {
+ tmp = *pat0; *pat0 = *pat1; *pat1 = tmp;
+ yorg -= 4;
+ }
+ if(yorg) {
+ mask = RotateMasksY[yorg];
+ yorg <<= 3;
+ tmp = *pat0;
+ *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);
+ *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
+ }
+}
+
+
+
+void
+XAAInvalidatePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ int i;
+
+ if(!pCachePriv) return;
+
+ for(i = 0; i < pCachePriv->Num512x512; i++)
+ (pCachePriv->Info512)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->Num256x256; i++)
+ (pCachePriv->Info256)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->Num128x128; i++)
+ (pCachePriv->Info128)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumPartial; i++)
+ (pCachePriv->InfoPartial)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumMono; i++)
+ (pCachePriv->InfoMono)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumColor; i++)
+ (pCachePriv->InfoColor)[i].serialNumber = 0;
+}
diff --git a/hw/xfree86/xaa/xaaPaintWin.c b/hw/xfree86/xaa/xaaPaintWin.c
new file mode 100644
index 000000000..2adf42466
--- /dev/null
+++ b/hw/xfree86/xaa/xaaPaintWin.c
@@ -0,0 +1,198 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPaintWin.c,v 1.11 2003/02/17 16:08:29 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+void
+XAAPaintWindow(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+ int nBox = REGION_NUM_RECTS(prgn);
+ BoxPtr pBox = REGION_RECTS(prgn);
+ int fg = -1;
+ PixmapPtr pPix = NULL;
+
+ if(!infoRec->pScrn->vtSema) goto BAILOUT;
+
+ switch (what) {
+ case PW_BACKGROUND:
+ switch(pWin->backgroundState) {
+ case None: return;
+ case ParentRelative:
+ do { pWin = pWin->parent; }
+ while(pWin->backgroundState == ParentRelative);
+ (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, prgn, what);
+ return;
+ case BackgroundPixel:
+ fg = pWin->background.pixel;
+ break;
+ case BackgroundPixmap:
+ pPix = pWin->background.pixmap;
+ break;
+ }
+ break;
+ case PW_BORDER:
+ if (pWin->borderIsPixel)
+ fg = pWin->border.pixel;
+ else /* pixmap */
+ pPix = pWin->border.pixmap;
+ break;
+ default: return;
+ }
+
+
+ if(!pPix) {
+ if(infoRec->FillSolidRects &&
+ (!(infoRec->FillSolidRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(fg))) ) {
+ (*infoRec->FillSolidRects)(infoRec->pScrn, fg, GXcopy, ~0,
+ nBox, pBox);
+ return;
+ }
+ } else { /* pixmap */
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ WindowPtr pBgWin = pWin;
+ Bool NoCache = FALSE;
+ int xorg, yorg;
+
+ /* Hack so we can use this with the dual framebuffer layers
+ which only support the pixmap cache in the primary bpp */
+ if(pPix->drawable.bitsPerPixel != infoRec->pScrn->bitsPerPixel)
+ NoCache = TRUE;
+
+ if (what == PW_BORDER) {
+ for (pBgWin = pWin;
+ pBgWin->backgroundState == ParentRelative;
+ pBgWin = pBgWin->parent);
+ }
+
+ xorg = pBgWin->drawable.x;
+ yorg = pBgWin->drawable.y;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ int index = pScreen->myNum;
+ if(WindowTable[index] == pBgWin) {
+ xorg -= panoramiXdataPtr[index].x;
+ yorg -= panoramiXdataPtr[index].y;
+ }
+ }
+#endif
+
+ if(IS_OFFSCREEN_PIXMAP(pPix) && infoRec->FillCacheBltRects) {
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+ pCache->trans_color = -1;
+
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, ~0,
+ nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+
+ if(pPriv->flags & DIRTY) {
+ pPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPix, infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) &&
+ infoRec->CanDoMono8x8 && infoRec->FillMono8x8PatternRects &&
+ !(infoRec->FillMono8x8PatternRectsFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->FillMono8x8PatternRectsFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg)))) {
+
+ (*infoRec->FillMono8x8PatternRects)(infoRec->pScrn,
+ pPriv->fg, pPriv->bg, GXcopy, ~0, nBox, pBox,
+ pPriv->pattern0, pPriv->pattern1, xorg, yorg);
+ return;
+ }
+ if(infoRec->CanDoColor8x8 && !NoCache &&
+ infoRec->FillColor8x8PatternRects) {
+ XAACacheInfoPtr pCache = (*infoRec->CacheColor8x8Pattern)(
+ infoRec->pScrn, pPix, -1, -1);
+
+ (*infoRec->FillColor8x8PatternRects) ( infoRec->pScrn,
+ GXcopy, ~0, nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+ }
+
+ /* The window size check is to reduce pixmap cache thrashing
+ when there are lots of little windows with pixmap backgrounds
+ like are sometimes used for buttons, etc... */
+
+ if(infoRec->UsingPixmapCache &&
+ infoRec->FillCacheBltRects && !NoCache &&
+ ((what == PW_BORDER) ||
+ (pPix->drawable.height != pWin->drawable.height) ||
+ (pPix->drawable.width != pWin->drawable.width)) &&
+ (pPix->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPix->drawable.width <= infoRec->MaxCacheableTileWidth)) {
+
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheTile)(infoRec->pScrn, pPix);
+ (*infoRec->FillCacheBltRects)(infoRec->pScrn, GXcopy, ~0,
+ nBox, pBox, xorg, yorg, pCache);
+ return;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ !(infoRec->FillImageWriteRectsFlags & NO_GXCOPY)) {
+ (*infoRec->FillImageWriteRects) (infoRec->pScrn, GXcopy,
+ ~0, nBox, pBox, xorg, yorg, pPix);
+ return;
+ }
+ }
+
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+BAILOUT:
+
+ if(what == PW_BACKGROUND) {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBackground);
+ (*pScreen->PaintWindowBackground) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBackground, XAAPaintWindow);
+ } else {
+ XAA_SCREEN_PROLOGUE (pScreen, PaintWindowBorder);
+ (*pScreen->PaintWindowBorder) (pWin, prgn, what);
+ XAA_SCREEN_EPILOGUE(pScreen, PaintWindowBorder, XAAPaintWindow);
+ }
+
+}
diff --git a/hw/xfree86/xaa/xaaPict.c b/hw/xfree86/xaa/xaaPict.c
new file mode 100644
index 000000000..4b7e3d0f0
--- /dev/null
+++ b/hw/xfree86/xaa/xaaPict.c
@@ -0,0 +1,683 @@
+/*
+ * $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaPict.c,v 1.17 2002/12/10 04:17:21 dawes Exp $
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+#include "picture.h"
+#include "mipict.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xaacexp.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+Bool
+XAAGetPixelFromRGBA (
+ CARD32 *pixel,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ CARD32 format
+){
+ int rbits, bbits, gbits, abits;
+ int rshift, bshift, gshift, ashift;
+
+ *pixel = 0;
+
+ if(!PICT_FORMAT_COLOR(format))
+ return FALSE;
+
+ rbits = PICT_FORMAT_R(format);
+ gbits = PICT_FORMAT_G(format);
+ bbits = PICT_FORMAT_B(format);
+ abits = PICT_FORMAT_A(format);
+
+ if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ } else { /* PICT_TYPE_ABGR */
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
+ }
+
+ *pixel |= ( blue >> (16 - bbits)) << bshift;
+ *pixel |= ( red >> (16 - rbits)) << rshift;
+ *pixel |= (green >> (16 - gbits)) << gshift;
+ *pixel |= (alpha >> (16 - abits)) << ashift;
+
+ return TRUE;
+}
+
+
+Bool
+XAAGetRGBAFromPixel(
+ CARD32 pixel,
+ CARD16 *red,
+ CARD16 *green,
+ CARD16 *blue,
+ CARD16 *alpha,
+ CARD32 format
+){
+ int rbits, bbits, gbits, abits;
+ int rshift, bshift, gshift, ashift;
+
+ if(!PICT_FORMAT_COLOR(format))
+ return FALSE;
+
+ rbits = PICT_FORMAT_R(format);
+ gbits = PICT_FORMAT_G(format);
+ bbits = PICT_FORMAT_B(format);
+ abits = PICT_FORMAT_A(format);
+
+ if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ } else { /* PICT_TYPE_ABGR */
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
+ }
+
+ *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
+ while(rbits < 16) {
+ *red |= *red >> rbits;
+ rbits <<= 1;
+ }
+
+ *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
+ while(gbits < 16) {
+ *green |= *green >> gbits;
+ gbits <<= 1;
+ }
+
+ *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
+ while(bbits < 16) {
+ *blue |= *blue >> bbits;
+ bbits <<= 1;
+ }
+
+ if(abits) {
+ *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
+ while(abits < 16) {
+ *alpha |= *alpha >> abits;
+ abits <<= 1;
+ }
+ } else *alpha = 0xffff;
+
+ return TRUE;
+}
+
+/* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */
+
+void
+XAA_888_plus_PICT_a8_to_8888 (
+ CARD32 color,
+ CARD8 *alphaPtr, /* in bytes */
+ int alphaPitch,
+ CARD32 *dstPtr,
+ int dstPitch, /* in dwords */
+ int width,
+ int height
+){
+ int x;
+
+ color &= 0x00ffffff;
+
+ while(height--) {
+ for(x = 0; x < width; x++)
+ dstPtr[x] = color | (alphaPtr[x] << 24);
+ dstPtr += dstPitch;
+ alphaPtr += alphaPitch;
+ }
+}
+
+Bool
+XAADoComposite (
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height
+){
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ RegionRec region;
+ CARD32 *formats;
+ int flags = 0;
+ BoxPtr pbox;
+ int nbox, w, h;
+
+ if(!REGION_NUM_RECTS(pDst->pCompositeClip))
+ return TRUE;
+
+ if(!infoRec->pScrn->vtSema ||
+ ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
+ !IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
+ return FALSE;
+
+ if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
+ IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
+ return FALSE;
+
+ if (pSrc->transform || (pMask && pMask->transform))
+ return FALSE;
+
+ if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
+ return FALSE;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if(pMask) {
+ /* for now we only do it if there is a 1x1 (solid) source */
+
+ if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) {
+ CARD16 red, green, blue, alpha;
+ CARD32 pixel =
+ *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
+
+ if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
+ return FALSE;
+
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+
+ /* pull out color expandable operations here */
+ if((pMask->format == PICT_a1) && (alpha == 0xffff) &&
+ (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) &&
+ (!(infoRec->WriteBitmapFlags & RGB_EQUAL) ||
+ ((red == green) && (green == blue))))
+ {
+ PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable);
+ int skipleft;
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return TRUE;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox)
+ return TRUE;
+
+ XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
+
+ xMask -= xDst;
+ yMask -= yDst;
+
+ while(nbox--) {
+ skipleft = pbox->x1 + xMask;
+
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)(pPix->devPrivate.ptr) +
+ (pPix->devKind * (pbox->y1 + yMask)) +
+ ((skipleft >> 3) & ~3), pPix->devKind,
+ skipleft & 31, pixel, -1, GXcopy, ~0);
+ pbox++;
+ }
+
+ /* WriteBitmap sets the Sync flag */
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+ if(!(formats = infoRec->CPUToScreenAlphaTextureFormats))
+ return FALSE;
+
+ w = pMask->pDrawable->width;
+ h = pMask->pDrawable->height;
+
+ if(pMask->repeat) {
+ if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) ||
+ ((infoRec->CPUToScreenAlphaTextureFlags &
+ XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
+ ((h & (h - 1)) || (w & (w - 1)))))
+ {
+ return FALSE;
+ }
+ flags |= XAA_RENDER_REPEAT;
+ }
+
+ if((alpha != 0xffff) &&
+ (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA))
+ return FALSE;
+
+ while(*formats != pMask->format) {
+ if(!(*formats)) return FALSE;
+ formats++;
+ }
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return TRUE;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox) {
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+ if(!(infoRec->SetupForCPUToScreenAlphaTexture)(infoRec->pScrn,
+ op, red, green, blue, alpha, pMask->format,
+ ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr,
+ ((PixmapPtr)(pMask->pDrawable))->devKind,
+ w, h, flags))
+ {
+ REGION_UNINIT(pScreen, &region);
+ return FALSE;
+ }
+
+ xMask -= xDst;
+ yMask -= yDst;
+
+ while(nbox--) {
+ (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn,
+ pbox->x1, pbox->y1,
+ pbox->x1 + xMask, pbox->y1 + yMask,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+ } else {
+ if(!(formats = infoRec->CPUToScreenTextureFormats))
+ return FALSE;
+
+ w = pSrc->pDrawable->width;
+ h = pSrc->pDrawable->height;
+
+ if(pSrc->repeat) {
+ if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) ||
+ ((infoRec->CPUToScreenTextureFlags &
+ XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
+ ((h & (h - 1)) || (w & (w - 1)))))
+ {
+ return FALSE;
+ }
+ flags |= XAA_RENDER_REPEAT;
+ }
+
+
+ while(*formats != pSrc->format) {
+ if(!(*formats)) return FALSE;
+ formats++;
+ }
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return TRUE;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox) {
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+ if(!(infoRec->SetupForCPUToScreenTexture)(infoRec->pScrn,
+ op, pSrc->format,
+ ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr,
+ ((PixmapPtr)(pSrc->pDrawable))->devKind,
+ w, h, flags))
+ {
+ REGION_UNINIT(pScreen, &region);
+ return FALSE;
+ }
+
+
+ xSrc -= xDst;
+ ySrc -= yDst;
+
+ while(nbox--) {
+ (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn,
+ pbox->x1, pbox->y1,
+ pbox->x1 + xSrc, pbox->y1 + ySrc,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+
+ return FALSE;
+}
+
+
+void
+XAAComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAA_RENDER_PROLOGUE(pScreen, Composite);
+
+ if(!infoRec->Composite ||
+ !(*infoRec->Composite)(op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ {
+ if(pSrc->pDrawable->type == DRAWABLE_WINDOW ||
+ pDst->pDrawable->type == DRAWABLE_WINDOW ||
+ IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) ||
+ IS_OFFSCREEN_PIXMAP(pDst->pDrawable)) {
+ SYNC_CHECK(pDst->pDrawable);
+ }
+ (*GetPictureScreen(pScreen)->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ }
+
+ if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
+
+ XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite);
+}
+
+Bool
+XAADoGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(!REGION_NUM_RECTS(pDst->pCompositeClip))
+ return TRUE;
+
+ if(!infoRec->pScrn->vtSema ||
+ ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
+ !IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
+ return FALSE;
+
+ if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
+ IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
+ return FALSE;
+
+ if(maskFormat && (maskFormat->depth == 1) &&
+ (pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1) &&
+ (op == PictOpOver) && infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY))
+ {
+ CARD16 red, green, blue, alpha;
+ CARD32 pixel =
+ *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
+ CARD32 *bits, *pntr, *pnt;
+ int x, y, i, n, left, top, right, bottom, width, height, pitch;
+ int L, T, R, B, X, Y, h, w, dwords, row, column, nbox;
+ int leftEdge, rightEdge, topLine, botLine;
+ BoxPtr pbox;
+ GlyphPtr glyph;
+
+ if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
+ return FALSE;
+
+ if(alpha != 0xffff) return FALSE;
+
+ XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
+
+ if((infoRec->WriteBitmapFlags & RGB_EQUAL) && !((red == green) && (green == blue)))
+ return FALSE;
+
+ x = pDst->pDrawable->x;
+ y = pDst->pDrawable->y;
+
+ while(nlist--) {
+ x += list->xOff;
+ y += list->yOff;
+ left = right = X = x;
+ top = bottom = Y = y;
+ for(i = 0; i < list->len; i++) {
+ glyph = glyphs[i];
+
+ L = X - glyph->info.x;
+ if(L < left) left = L;
+ R = L + glyph->info.width;
+ if(R > right) right = R;
+
+ T = Y - glyph->info.y;
+ if(T < top) top = T;
+ B = T + glyph->info.height;
+ if(B > bottom) bottom = B;
+
+ X += glyph->info.xOff;
+ Y += glyph->info.yOff;
+ }
+
+ width = right - left;
+ height = bottom - top;
+
+ if(width && height) {
+ pitch = (((width + 31) & ~31) >> 5) + 1;
+ pntr = (CARD32*)xalloc(sizeof(CARD32) * pitch * height);
+ if(!pntr)
+ return TRUE;
+ bzero(pntr, sizeof(CARD32) * pitch * height);
+ n = list->len;
+
+ X = x; Y = y;
+ while(n--) {
+ glyph = *glyphs++;
+ h = glyph->info.height;
+ w = glyph->info.width;
+ if(h && w) {
+ row = y - top - glyph->info.y;
+ column = x - left - glyph->info.x;
+ pnt = pntr + (row * pitch) + (column >> 5);
+ column &= 31;
+ dwords = ((w + 31) >> 5) - 1;
+ bits = (CARD32*)(glyph + 1);
+ if(dwords) {
+ while(h--) {
+ for(i = 0; i <= dwords; i++) {
+ if(column) {
+ pnt[i] |= SHIFT_L(*bits, column);
+ pnt[i + 1] |= SHIFT_R(*bits, 32 - column);
+ } else
+ pnt[i] |= *bits;
+
+ if(i != dwords) bits++;
+ }
+ bits++;
+ pnt += pitch;
+ }
+ } else {
+ if(column) {
+ while(h--) {
+ pnt[0] |= SHIFT_L(*bits, column);
+ pnt[0 + 1] |= SHIFT_R(*bits, 32 - column);
+ bits++;
+ pnt += pitch;
+ }
+ } else {
+ while(h--) {
+ *pnt |= *bits++;
+ pnt += pitch;
+ }
+ }
+ }
+ }
+ x += glyph->info.xOff;
+ y += glyph->info.yOff;
+ }
+
+ nbox = REGION_NUM_RECTS(pDst->pCompositeClip);
+ pbox = REGION_RECTS(pDst->pCompositeClip);
+
+ while(nbox && (top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (bottom > pbox->y1)) {
+ leftEdge = max(left, pbox->x1);
+ rightEdge = min(right, pbox->x2);
+
+ if(rightEdge > leftEdge) {
+ column = leftEdge - left;
+ topLine = max(top, pbox->y1);
+ botLine = min(bottom, pbox->y2);
+ h = botLine - topLine;
+
+ if(h > 0) {
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ leftEdge, topLine, rightEdge - leftEdge, h,
+ (unsigned char*)(pntr +
+ ((topLine - top) * pitch) + (column >> 5)),
+ pitch << 2, column & 31, pixel, -1, GXcopy, ~0);
+ }
+ }
+ nbox--; pbox++;
+ }
+ xfree(pntr);
+ } else {
+ x = X; y = Y;
+ }
+ list++;
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * If it looks like we have a chance of being able to draw these
+ * glyphs with an accelerated Composite, do that now to avoid
+ * unneeded and costly syncs.
+ */
+ if(maskFormat) {
+ if(!infoRec->CPUToScreenAlphaTextureFormats)
+ return FALSE;
+ } else {
+ if(!infoRec->CPUToScreenTextureFormats)
+ return FALSE;
+ }
+
+ miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+
+ return TRUE;
+}
+
+
+void
+XAAGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAA_RENDER_PROLOGUE(pScreen, Glyphs);
+
+ if(!infoRec->Glyphs ||
+ !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
+ xSrc, ySrc, nlist, list, glyphs))
+ {
+ if((pSrc->pDrawable->type == DRAWABLE_WINDOW) ||
+ (pDst->pDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrc->pDrawable) ||
+ IS_OFFSCREEN_PIXMAP(pDst->pDrawable)) {
+ SYNC_CHECK(pDst->pDrawable);
+ }
+ (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
+ xSrc, ySrc, nlist, list, glyphs);
+ }
+
+ if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
+
+ XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs);
+}
diff --git a/hw/xfree86/xaa/xaaROP.c b/hw/xfree86/xaa/xaaROP.c
new file mode 100644
index 000000000..4075bab6a
--- /dev/null
+++ b/hw/xfree86/xaa/xaaROP.c
@@ -0,0 +1,164 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaROP.c,v 1.2 2000/09/28 20:48:01 mvojkovi Exp $ */
+
+#include "X.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaarop.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+int XAACopyROP[16] =
+{
+ ROP_0, /* GXclear */
+ ROP_DSa, /* GXand */
+ ROP_SDna, /* GXandReverse */
+ ROP_S, /* GXcopy */
+ ROP_DSna, /* GXandInverted */
+ ROP_D, /* GXnoop */
+ ROP_DSx, /* GXxor */
+ ROP_DSo, /* GXor */
+ ROP_DSon, /* GXnor */
+ ROP_DSxn, /* GXequiv */
+ ROP_Dn, /* GXinvert*/
+ ROP_SDno, /* GXorReverse */
+ ROP_Sn, /* GXcopyInverted */
+ ROP_DSno, /* GXorInverted */
+ ROP_DSan, /* GXnand */
+ ROP_1 /* GXset */
+};
+
+int XAACopyROP_PM[16] =
+{
+ ROP_0, /* not used */
+ ROP_DSPnoa,
+ ROP_DPSnaon,
+ ROP_DPSDxax,
+ ROP_DPSana,
+ ROP_D, /* not used */
+ ROP_DPSax,
+ ROP_DPSao,
+ ROP_DPSaon,
+ ROP_DPSaxn,
+ ROP_Dn, /* not used */
+ ROP_DPSanan,
+ ROP_PSDPxox, /* is that correct ? */
+ ROP_DPSnao,
+ ROP_DSPnoan,
+ ROP_1 /* not used */
+};
+
+
+int XAAPatternROP[16]=
+{
+ ROP_0,
+ ROP_DPa,
+ ROP_PDna,
+ ROP_P,
+ ROP_DPna,
+ ROP_D,
+ ROP_DPx,
+ ROP_DPo,
+ ROP_DPon,
+ ROP_PDxn,
+ ROP_Dn,
+ ROP_PDno,
+ ROP_Pn,
+ ROP_DPno,
+ ROP_DPan,
+ ROP_1
+};
+
+int XAAPatternROP_PM[16] =
+{
+ ROP_DPna,
+ ROP_DPSnoa,
+ ROP_DSPnaon,
+ ROP_DSPDxax,
+ ROP_DPSana,
+ ROP_D,
+ ROP_DPSax,
+ ROP_DPSao,
+ ROP_DPSaon,
+ ROP_DPSaxn,
+ ROP_DPx,
+ ROP_DPSanan,
+ ROP_SPDSxox, /* is that correct ? */
+ ROP_DSPnao,
+ ROP_DPSnoan,
+ ROP_DPo
+};
+
+
+int
+XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int ret = 0;
+
+ pm &= infoRec->FullPlanemasks[pScrn->depth - 1];
+
+ if(pm == infoRec->FullPlanemasks[pScrn->depth - 1]) {
+ if(!NO_SRC_ROP(*rop))
+ ret |= ROP_PAT;
+ *rop = XAAPatternROP[*rop];
+ } else {
+ switch(*rop) {
+ case GXnoop:
+ break;
+ case GXset:
+ case GXclear:
+ case GXinvert:
+ ret |= ROP_PAT;
+ *fg = pm;
+ if(*bg != -1)
+ *bg = pm;
+ break;
+ default:
+ ret |= ROP_PAT | ROP_SRC;
+ break;
+ }
+ *rop = XAAPatternROP_PM[*rop];
+ }
+
+ return ret;
+}
+
+
+int
+XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int ret = 0;
+
+ pm &= infoRec->FullPlanemasks[pScrn->depth - 1];
+
+ if(pm == infoRec->FullPlanemasks[pScrn->depth - 1]) {
+ if(!NO_SRC_ROP(*rop))
+ ret |= ROP_PAT;
+ *rop = XAAPatternROP[*rop];
+ } else {
+ switch(*rop) {
+ case GXnoop:
+ break;
+ case GXset:
+ case GXclear:
+ case GXinvert:
+ ret |= ROP_PAT;
+ *fg = pm;
+ break;
+ default:
+ ret |= ROP_PAT | ROP_SRC;
+ break;
+ }
+ *rop = XAAPatternROP_PM[*rop];
+ }
+
+ return ret;
+}
+
diff --git a/hw/xfree86/xaa/xaaRect.c b/hw/xfree86/xaa/xaaRect.c
new file mode 100644
index 000000000..fe8d70de2
--- /dev/null
+++ b/hw/xfree86/xaa/xaaRect.c
@@ -0,0 +1,134 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaRect.c,v 1.3 1999/05/30 03:03:33 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+/*
+ Much of this file based on code by
+ Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+*/
+
+
+void
+XAAPolyRectangleThinSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int nClipRects; /* number of clip rectangles */
+ BoxPtr pClipRects; /* points to the list of clip rects */
+ int xOrigin; /* Drawables x origin */
+ int yOrigin; /* Drawables x origin */
+ xRectangle *pRect; /* list of rects */
+ int nRects; /* running count of number of rects */
+ int origX1, origY1; /* original rectangle's U/L corner */
+ int origX2, origY2; /* original rectangle's L/R corner */
+ int clippedX1; /* clipped rectangle's left x */
+ int clippedY1; /* clipped rectangle's top y */
+ int clippedX2; /* clipped rectangle's right x */
+ int clippedY2; /* clipped rectangle's bottom y */
+ int clipXMin; /* upper left corner of clip rect */
+ int clipYMin; /* upper left corner of clip rect */
+ int clipXMax; /* lower right corner of clip rect */
+ int clipYMax; /* lower right corner of clip rect */
+ int width, height; /* width and height of rect */
+
+ nClipRects = REGION_NUM_RECTS(pGC->pCompositeClip);
+ pClipRects = REGION_RECTS(pGC->pCompositeClip);
+
+ if(!nClipRects) return;
+
+ xOrigin = pDrawable->x;
+ yOrigin = pDrawable->y;
+
+
+ (*infoRec->SetupForSolidLine)(infoRec->pScrn,
+ pGC->fgPixel, pGC->alu, pGC->planemask);
+
+
+ for ( ; nClipRects > 0;
+ nClipRects--, pClipRects++ )
+ {
+ clipYMin = pClipRects->y1;
+ clipYMax = pClipRects->y2 - 1;
+ clipXMin = pClipRects->x1;
+ clipXMax = pClipRects->x2 - 1;
+
+ for (pRect = pRectsInit, nRects = nRectsInit;
+ nRects > 0;
+ nRects--, pRect++ )
+ {
+ /* translate rectangle data over to the drawable */
+ origX1 = pRect->x + xOrigin;
+ origY1 = pRect->y + yOrigin;
+ origX2 = origX1 + pRect->width;
+ origY2 = origY1 + pRect->height;
+
+ /* reject entire rectangle if completely outside clip rect */
+ if ((origX1 > clipXMax) || (origX2 < clipXMin) ||
+ (origY1 > clipYMax) || (origY2 < clipYMin))
+ continue;
+
+ /* clip the rectangle */
+ clippedX1 = max (origX1, clipXMin);
+ clippedX2 = min (origX2, clipXMax);
+ clippedY1 = max (origY1, clipYMin);
+ clippedY2 = min (origY2, clipYMax);
+
+ width = clippedX2 - clippedX1 + 1;
+
+ if (origY1 >= clipYMin) {
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX1, clippedY1, width, DEGREES_0);
+
+ /* don't overwrite corner */
+ clippedY1++;
+ }
+
+ if ((origY2 <= clipYMax) && (origY1 != origY2)) {
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX1, clippedY2, width, DEGREES_0);
+
+ /* don't overwrite corner */
+ clippedY2--;
+ }
+
+ if (clippedY2 < clippedY1) continue;
+
+ height = clippedY2 - clippedY1 + 1;
+
+ /* draw vertical edges using lines if not clipped out */
+ if (origX1 >= clipXMin)
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX1, clippedY1, height, DEGREES_270);
+
+ if ((origX2 <= clipXMax) && (origX2 != origX1))
+ (*infoRec->SubsequentSolidHorVertLine)(infoRec->pScrn,
+ clippedX2, clippedY1, height, DEGREES_270);
+ }
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hw/xfree86/xaa/xaaSpans.c b/hw/xfree86/xaa/xaaSpans.c
new file mode 100644
index 000000000..522225665
--- /dev/null
+++ b/hw/xfree86/xaa/xaaSpans.c
@@ -0,0 +1,880 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaSpans.c,v 1.15 2001/10/28 03:34:04 tsi Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "mispans.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+static void XAARenderSolidSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderColor8x8Spans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderMono8x8Spans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderCacheBltSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderColorExpandSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderCacheExpandSpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+static void XAARenderPixmapCopySpans(
+ GCPtr, int, DDXPointPtr, int*, int, int, int);
+
+void
+XAAFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit, /* number of spans to fill */
+ DDXPointPtr pptInit, /* pointer to list of start points */
+ int *pwidthInit, /* pointer to list of n widths */
+ int fSorted
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int type = 0;
+ ClipAndRenderSpansFunc function;
+ Bool fastClip = FALSE;
+
+ if((nInit <= 0) || !pGC->planemask)
+ return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ switch(pGC->fillStyle) {
+ case FillSolid:
+ type = DO_SOLID;
+ break;
+ case FillStippled:
+ type = (*infoRec->StippledFillChooser)(pGC);
+ break;
+ case FillOpaqueStippled:
+ if((pGC->fgPixel == pGC->bgPixel) && infoRec->FillSpansSolid &&
+ CHECK_PLANEMASK(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROP(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillSpansSolidFlags) &&
+ CHECK_FG(pGC,infoRec->FillSpansSolidFlags))
+ type = DO_SOLID;
+ else
+ type = (*infoRec->OpaqueStippledFillChooser)(pGC);
+ break;
+ case FillTiled:
+ type = (*infoRec->TiledFillChooser)(pGC);
+ break;
+ }
+
+ switch(type) {
+ case DO_SOLID:
+ function = XAARenderSolidSpans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL)
+ fastClip = TRUE;
+ break;
+ case DO_COLOR_8x8:
+ function = XAARenderColor8x8Spans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_COLOR_8x8_FILL)
+ fastClip = TRUE;
+ break;
+ case DO_MONO_8x8:
+ function = XAARenderMono8x8Spans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_MONO_8x8_FILL)
+ fastClip = TRUE;
+ break;
+ case DO_CACHE_BLT:
+ function = XAARenderCacheBltSpans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
+ fastClip = TRUE;
+ break;
+ case DO_COLOR_EXPAND:
+ function = XAARenderColorExpandSpans;
+ break;
+ case DO_CACHE_EXPAND:
+ function = XAARenderCacheExpandSpans;
+ if(infoRec->ClippingFlags &
+ HARDWARE_CLIP_SCREEN_TO_SCREEN_COLOR_EXPAND)
+ fastClip = TRUE;
+ break;
+ case DO_PIXMAP_COPY:
+ function = XAARenderPixmapCopySpans;
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SCREEN_TO_SCREEN_COPY)
+ fastClip = TRUE;
+ break;
+ case DO_IMAGE_WRITE:
+ default:
+ (*XAAFallbackOps.FillSpans)(pDraw, pGC, nInit, pptInit,
+ pwidthInit, fSorted);
+ return;
+ }
+
+
+ if((nInit < 10) || (REGION_NUM_RECTS(pGC->pCompositeClip) != 1))
+ fastClip = FALSE;
+
+ if(fastClip) {
+ infoRec->ClipBox = &pGC->pCompositeClip->extents;
+ (*function)(pGC, nInit, pptInit, pwidthInit, fSorted,
+ pDraw->x, pDraw->y);
+ infoRec->ClipBox = NULL;
+ } else
+ XAAClipAndRenderSpans(pGC, pptInit, pwidthInit, nInit, fSorted,
+ function, pDraw->x, pDraw->y);
+}
+
+
+ /*********************\
+ | Solid Spans |
+ \*********************/
+
+
+static void
+XAARenderSolidSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ (*infoRec->FillSolidSpans) (infoRec->pScrn, pGC->fgPixel,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted);
+}
+
+
+ /************************\
+ | Mono 8x8 Spans |
+ \************************/
+
+
+static void
+XAARenderMono8x8Spans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAPixmapPtr pPriv;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ fg = pPriv->fg; bg = pPriv->bg;
+ break;
+ default: /* Muffle compiler */
+ pPriv = NULL; /* Kaboom */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillMono8x8PatternSpans) (infoRec->pScrn,
+ fg, bg, pGC->alu, pGC->planemask,
+ n, ppt, pwidth, fSorted, pPriv->pattern0, pPriv->pattern1,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+
+ /*************************\
+ | Color 8x8 Spans |
+ \*************************/
+
+
+static void
+XAARenderColor8x8Spans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+ PixmapPtr pPix;
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pPix = pGC->stipple;
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ pPix = pGC->stipple;
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ case FillTiled:
+ pPix = pGC->tile.pixmap;
+ fg = -1; bg = -1;
+ break;
+ default: /* Muffle compiler */
+ pPix = NULL;
+ fg = -1; bg = -1;
+ break;
+ }
+
+ pCache = (*infoRec->CacheColor8x8Pattern)(infoRec->pScrn, pPix, fg, bg);
+
+ (*infoRec->FillColor8x8PatternSpans) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
+ (yorg + pGC->patOrg.x), (xorg + pGC->patOrg.y));
+}
+
+
+ /****************************\
+ | Color Expand Spans |
+ \****************************/
+
+
+static void
+XAARenderColorExpandSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ default: /* Muffle compiler */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillColorExpandSpans) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+
+}
+
+
+ /*************************\
+ | Cache Blt Spans |
+ \*************************/
+
+
+static void
+XAARenderCacheBltSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, -1);
+ break;
+ case FillOpaqueStippled:
+ pCache = (*infoRec->CacheStipple)(infoRec->pScrn, pGC->stipple,
+ pGC->fgPixel, pGC->bgPixel);
+ break;
+ case FillTiled:
+ pCache = (*infoRec->CacheTile)(infoRec->pScrn, pGC->tile.pixmap);
+ break;
+ default: /* Muffle compiler */
+ pCache = NULL;
+ break;
+ }
+
+ (*infoRec->FillCacheBltSpans) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+
+}
+
+
+ /****************************\
+ | Cache Expand Spans |
+ \****************************/
+
+
+static void
+XAARenderCacheExpandSpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int fg, bg;
+
+ switch(pGC->fillStyle) {
+ case FillStippled:
+ fg = pGC->fgPixel; bg = -1;
+ break;
+ case FillOpaqueStippled:
+ fg = pGC->fgPixel; bg = pGC->bgPixel;
+ break;
+ default: /* Muffle compiler */
+ fg = -1; bg = -1;
+ break;
+ }
+
+ (*infoRec->FillCacheExpandSpans) (infoRec->pScrn, fg, bg,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y),
+ pGC->stipple);
+}
+
+
+ /***************************\
+ | Pixmap Copy Spans |
+ \***************************/
+
+
+static void
+XAARenderPixmapCopySpans(
+ GCPtr pGC,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAACacheInfoPtr pCache = &(infoRec->ScratchCacheInfoRec);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ pCache->x = pPriv->offscreenArea->box.x1;
+ pCache->y = pPriv->offscreenArea->box.y1;
+ pCache->w = pCache->orig_w =
+ pPriv->offscreenArea->box.x2 - pCache->x;
+ pCache->h = pCache->orig_h =
+ pPriv->offscreenArea->box.y2 - pCache->y;
+ pCache->trans_color = -1;
+
+ (*infoRec->FillCacheBltSpans) (infoRec->pScrn,
+ pGC->alu, pGC->planemask, n, ppt, pwidth, fSorted, pCache,
+ (xorg + pGC->patOrg.x), (yorg + pGC->patOrg.y));
+}
+
+
+
+
+
+ /****************\
+ | Solid |
+ \****************/
+
+
+void
+XAAFillSolidSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForSolidFill)(pScrn, fg, rop, planemask);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ if (*pwidth > 0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, ppt->x, ppt->y,
+ *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+ /***************\
+ | Mono 8x8 |
+ \***************/
+
+
+void
+XAAFillMono8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ }
+ } else {
+ XAACacheInfoPtr pCache =
+ (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ patx += pCache->offsets[slot].x;
+ paty += pCache->offsets[slot].y;
+ xorg = patx; yorg = paty;
+ }
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAFillMono8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int pattern0, int pattern1,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pattern0, paty = pattern1;
+ int xorg, yorg, slot;
+ XAACacheInfoPtr pCache = NULL;
+
+
+ if(!(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_BITS)){
+ pCache = (*infoRec->CacheMono8x8Pattern)(pScrn, pattern0, pattern1);
+ patx = pCache->x; paty = pCache->y;
+ }
+
+ (*infoRec->SetupForMono8x8PatternFill)(pScrn, patx, paty,
+ fg, bg, rop, planemask);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ xorg = (ppt->x - xorigin) & 0x07;
+ yorg = (ppt->y - yorigin) & 0x07;
+
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ patx = pattern0; paty = pattern1;
+ XAARotateMonoPattern(&patx, &paty, xorg, yorg,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ xorg = patx; yorg = paty;
+ } else {
+ slot = (yorg << 3) + xorg;
+ xorg = patx + pCache->offsets[slot].x;
+ yorg = paty + pCache->offsets[slot].y;
+ }
+ }
+
+ (*infoRec->SubsequentMono8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+ /****************\
+ | Color 8x8 |
+ \****************/
+
+
+void
+XAAFillColor8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int patx = pCache->x, paty = pCache->y;
+ int xorg = (-xorigin) & 0x07;
+ int yorg = (-yorigin) & 0x07;
+
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int slot = (yorg << 3) + xorg;
+ paty += pCache->offsets[slot].y;
+ patx += pCache->offsets[slot].x;
+ xorg = patx; yorg = paty;
+ }
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, patx, paty,
+ rop, planemask, pCache->trans_color);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAFillColor8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorigin, int yorigin
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int xorg, yorg, slot;
+
+ (*infoRec->SetupForColor8x8PatternFill)(pScrn, pCache->x, pCache->y,
+ rop, planemask, pCache->trans_color);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ xorg = (ppt->x - xorigin) & 0x07;
+ yorg = (ppt->y - yorigin) & 0x07;
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ slot = (yorg << 3) + xorg;
+ yorg = pCache->y + pCache->offsets[slot].y;
+ xorg = pCache->x + pCache->offsets[slot].x;
+ }
+
+ (*infoRec->SubsequentColor8x8PatternFillRect)(pScrn,
+ xorg, yorg, ppt->x, ppt->y, *pwidth, 1);
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+ /*****************\
+ | Cache Blit |
+ \*****************/
+
+
+void
+XAAFillCacheBltSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, w, phaseX, phaseY, blit_w;
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, rop, planemask,
+ pCache->trans_color);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ x = ppt->x;
+ w = *pwidth;
+ phaseX = (x - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ phaseY = (ppt->y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+
+ while(1) {
+ blit_w = pCache->w - phaseX;
+ if(blit_w > w) blit_w = w;
+
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pCache->x + phaseX, pCache->y + phaseY,
+ x, ppt->y, blit_w, 1);
+
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pCache->orig_w;
+ }
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+ /****************\
+ | Cache Expand |
+ \****************/
+
+
+void
+XAAFillCacheExpandSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x, w, phaseX, phaseY, blit_w, cacheWidth;
+ XAACacheInfoPtr pCache;
+
+ pCache = (*infoRec->CacheMonoStipple)(pScrn, pPix);
+
+ cacheWidth = (pCache->w * pScrn->bitsPerPixel) /
+ infoRec->CacheColorExpandDensity;
+
+ (*infoRec->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+
+ if(infoRec->ClipBox)
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+
+ while(n--) {
+ x = ppt->x;
+ w = *pwidth;
+ phaseX = (x - xorg) % pCache->orig_w;
+ if(phaseX < 0) phaseX += pCache->orig_w;
+ phaseY = (ppt->y - yorg) % pCache->orig_h;
+ if(phaseY < 0) phaseY += pCache->orig_h;
+
+ while(1) {
+ blit_w = cacheWidth - phaseX;
+ if(blit_w > w) blit_w = w;
+
+ (*infoRec->SubsequentScreenToScreenColorExpandFill)(
+ pScrn, x, ppt->y, blit_w, 1,
+ pCache->x, pCache->y + phaseY, phaseX);
+
+ w -= blit_w;
+ if(!w) break;
+ x += blit_w;
+ phaseX = (phaseX + blit_w) % pCache->orig_w;
+ }
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->ClipBox)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+
+void
+XAAClipAndRenderSpans(
+ GCPtr pGC,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted,
+ ClipAndRenderSpansFunc func,
+ int xorg,
+ int yorg
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ DDXPointPtr pptNew, pptBase;
+ int *pwidthBase, *pwidthNew;
+ int Right, numRects, MaxBoxes;
+
+ MaxBoxes = infoRec->PreAllocSize/(sizeof(DDXPointRec) + sizeof(int));
+ pptBase = (DDXPointRec*)infoRec->PreAllocMem;
+ pwidthBase = (int*)(&pptBase[MaxBoxes]);
+
+ pptNew = pptBase;
+ pwidthNew = pwidthBase;
+
+ numRects = REGION_NUM_RECTS(pGC->pCompositeClip);
+
+ if(numRects == 1) {
+ BoxPtr pextent = REGION_RECTS(pGC->pCompositeClip);
+
+ while(nspans--) {
+ if ((pextent->y1 <= ppt->y) && (ppt->y < pextent->y2)) {
+ pptNew->x = max(pextent->x1, ppt->x);
+ Right = ppt->x + *pwidth;
+ *pwidthNew = min(pextent->x2, Right) - pptNew->x;
+
+ if (*pwidthNew > 0) {
+ pptNew->y = ppt->y;
+ pptNew++;
+ pwidthNew++;
+
+ if(pptNew >= (pptBase + MaxBoxes)) {
+ (*func)(pGC, MaxBoxes, pptBase, pwidthBase, fSorted,
+ xorg, yorg);
+ pptNew = pptBase;
+ pwidthNew = pwidthBase;
+ }
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ } else if (numRects) {
+ BoxPtr pbox;
+ int nbox;
+
+ while(nspans--) {
+ nbox = numRects;
+ pbox = REGION_RECTS(pGC->pCompositeClip);
+
+ /* find the first band */
+ while(nbox && (pbox->y2 <= ppt->y)) {
+ pbox++;
+ nbox--;
+ }
+
+ if(nbox && (pbox->y1 <= ppt->y)) {
+ int orig_y = pbox->y1;
+ Right = ppt->x + *pwidth;
+ while(nbox && (orig_y == pbox->y1)) {
+ if(pbox->x2 <= ppt->x) {
+ nbox--;
+ pbox++;
+ continue;
+ }
+
+ if(pbox->x1 >= Right) {
+ nbox = 0;
+ break;
+ }
+
+ pptNew->x = max(pbox->x1, ppt->x);
+ *pwidthNew = min(pbox->x2, Right) - pptNew->x;
+ if(*pwidthNew > 0) {
+ pptNew->y = ppt->y;
+ pptNew++;
+ pwidthNew++;
+
+ if(pptNew >= (pptBase + MaxBoxes)) {
+ (*func)(pGC, MaxBoxes, pptBase, pwidthBase,
+ fSorted, xorg, yorg);
+ pptNew = pptBase;
+ pwidthNew = pwidthBase;
+ }
+ }
+ pbox++;
+ nbox--;
+ }
+ }
+ ppt++;
+ pwidth++;
+ }
+ }
+
+ if(pptNew != pptBase)
+ (*func)(pGC, pptNew - pptBase, pptBase, pwidthBase, fSorted,
+ xorg, yorg);
+}
diff --git a/hw/xfree86/xaa/xaaStateChange.c b/hw/xfree86/xaa/xaaStateChange.c
new file mode 100644
index 000000000..512c6a260
--- /dev/null
+++ b/hw/xfree86/xaa/xaaStateChange.c
@@ -0,0 +1,1677 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStateChange.c,v 3.2 2003/02/04 01:44:07 dawes Exp $ */
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "servermd.h"
+
+#define XAA_STATE_WRAP(func) do {\
+if(infoRec->func) { \
+ pStatePriv->func = infoRec->func;\
+ infoRec->func = XAAStateWrap##func;\
+}} while(0)
+
+/* Wrap all XAA functions and allocate our private structure.
+ */
+
+typedef struct _XAAStateWrapRec {
+ ScrnInfoPtr pScrn;
+ void (*RestoreAccelState)(ScrnInfoPtr pScrn);
+ void (*Sync)(ScrnInfoPtr pScrn);
+ void (*SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int trans_color);
+ void (*SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+ void (*SetupForSolidLine)(ScrnInfoPtr pScrn,int color,int rop,
+ unsigned int planemask);
+ void (*SetupForDashedLine)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern);
+ void (*SetClippingRectangle) (ScrnInfoPtr pScrn, int left, int top,
+ int right, int bottom);
+ void (*DisableClipping)(ScrnInfoPtr pScrn);
+ void (*SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask,
+ int transparency_color);
+ void (*SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForScanlineCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForScreenToScreenColorExpandFill) (ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+ void (*SetupForScanlineImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth);
+ void (*SetupForImageRead) (ScrnInfoPtr pScrn, int bpp, int depth);
+ void (*ScreenToScreenBitBlt)(ScrnInfoPtr pScrn, int nbox,
+ DDXPointPtr pptSrc, BoxPtr pbox, int xdir,
+ int ydir, int alu, unsigned int planmask);
+ void (*WriteBitmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int skipleft,
+ int fg, int bg, int rop, unsigned int planemask);
+ void (*FillSolidRects)(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox);
+ void (*FillMono8x8PatternRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int pat0, int pat1,
+ int xorg, int yorg);
+ void (*FillColor8x8PatternRects)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ XAACacheInfoPtr pCache);
+ void (*FillCacheBltRects)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, XAACacheInfoPtr pCache);
+ void (*FillColorExpandRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ PixmapPtr pPix);
+ void (*FillCacheExpandRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix);
+ void (*FillImageWriteRects)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix);
+ void (*FillSolidSpans)(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int n, DDXPointPtr points,
+ int *widths, int fSorted);
+ void (*FillMono8x8PatternSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, int pat0, int pat1,
+ int xorg, int yorg);
+ void (*FillColor8x8PatternSpans)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg);
+ void (*FillCacheBltSpans)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n, DDXPointPtr points,
+ int *widths, int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg);
+ void (*FillColorExpandSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths, int fSorted,
+ int xorg, int yorg, PixmapPtr pPix);
+ void (*FillCacheExpandSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n, DDXPointPtr ppt,
+ int *pwidth, int fSorted, int xorg, int yorg,
+ PixmapPtr pPix);
+ void (*TEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft, int startline, unsigned int **glyphs,
+ int glyphWidth, int fg, int bg, int rop,
+ unsigned planemask);
+ void (*NonTEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox,
+ int fg, int rop, unsigned int planemask);
+ void (*WritePixmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+ void (*ReadPixmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth);
+ RegionPtr (*CopyArea)(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GC *pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty);
+ RegionPtr (*CopyPlane)(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx,
+ int dsty, unsigned long bitPlane);
+ void (*PushPixelsSolid) (GCPtr pGC, PixmapPtr pBitMap,
+ DrawablePtr pDrawable, int dx, int dy, int xOrg,
+ int yOrg);
+ void (*PolyFillRectSolid)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit);
+ void (*PolyFillRectStippled)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit);
+ void (*PolyFillRectOpaqueStippled)(DrawablePtr pDraw, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+ void (*PolyFillRectTiled)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit);
+ void (*FillSpansSolid)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ void (*FillSpansStippled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ void (*FillSpansOpaqueStippled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ void (*FillSpansTiled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ int (*PolyText8TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ char *chars);
+ int (*PolyText16TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars);
+ void (*ImageText8TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ char *chars);
+ void (*ImageText16TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+ void (*ImageGlyphBltTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+ void (*PolyGlyphBltTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+ int (*PolyText8NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars);
+ int (*PolyText16NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+ void (*ImageText8NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars);
+ void (*ImageText16NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+ void (*ImageGlyphBltNonTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+ void (*PolyGlyphBltNonTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+ void (*PolyRectangleThinSolid)(DrawablePtr pDrawable,GCPtr pGC,
+ int nRectsInit, xRectangle *pRectsInit);
+ void (*PolylinesWideSolid)(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts);
+ void (*PolylinesThinSolid)(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts);
+ void (*PolySegmentThinSolid)(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+ void (*PolylinesThinDashed)(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts);
+ void (*PolySegmentThinDashed)(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+ void (*FillPolygonSolid)(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+ void (*FillPolygonStippled)(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+ void (*FillPolygonOpaqueStippled)(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr ptsIn);
+ void (*FillPolygonTiled)(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+ void (*PolyFillArcSolid)(DrawablePtr pDraw, GCPtr pGC, int narcs,
+ xArc *parcs);
+ void (*PutImage)(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage);
+ ValidateGCProcPtr ValidateFillSpans;
+ ValidateGCProcPtr ValidateSetSpans;
+ ValidateGCProcPtr ValidatePutImage;
+ ValidateGCProcPtr ValidateCopyArea;
+ ValidateGCProcPtr ValidateCopyPlane;
+ ValidateGCProcPtr ValidatePolyPoint;
+ ValidateGCProcPtr ValidatePolylines;
+ ValidateGCProcPtr ValidatePolySegment;
+ ValidateGCProcPtr ValidatePolyRectangle;
+ ValidateGCProcPtr ValidatePolyArc;
+ ValidateGCProcPtr ValidateFillPolygon;
+ ValidateGCProcPtr ValidatePolyFillRect;
+ ValidateGCProcPtr ValidatePolyFillArc;
+ ValidateGCProcPtr ValidatePolyText8;
+ ValidateGCProcPtr ValidatePolyText16;
+ ValidateGCProcPtr ValidateImageText8;
+ ValidateGCProcPtr ValidateImageText16;
+ ValidateGCProcPtr ValidatePolyGlyphBlt;
+ ValidateGCProcPtr ValidateImageGlyphBlt;
+ ValidateGCProcPtr ValidatePushPixels;
+ void (*ComputeDash)(GCPtr pGC);
+ void (*InitPixmapCache)(ScreenPtr pScreen, RegionPtr areas, pointer data);
+ void (*ClosePixmapCache)(ScreenPtr pScreen);
+ int (*StippledFillChooser)(GCPtr pGC);
+ int (*OpaqueStippledFillChooser)(GCPtr pGC);
+ int (*TiledFillChooser)(GCPtr pGC);
+ XAACacheInfoPtr (*CacheTile)(ScrnInfoPtr Scrn, PixmapPtr pPix);
+ XAACacheInfoPtr (*CacheStipple)(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg,
+ int bg);
+ XAACacheInfoPtr (*CacheMonoStipple)(ScrnInfoPtr Scrn, PixmapPtr pPix);
+ XAACacheInfoPtr (*CacheMono8x8Pattern)(ScrnInfoPtr Scrn, int pat0,
+ int pat1);
+ XAACacheInfoPtr (*CacheColor8x8Pattern)(ScrnInfoPtr Scrn, PixmapPtr pPix,
+ int fg, int bg);
+ void (*WriteBitmapToCache) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int fg,
+ int bg);
+ void (*WritePixmapToCache) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int bpp,
+ int depth);
+ void (*WriteMono8x8PatternToCache)(ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache);
+ void (*WriteColor8x8PatternToCache)(ScrnInfoPtr pScrn, PixmapPtr pPix,
+ XAACacheInfoPtr pCache);
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ BackingStoreSaveAreasProcPtr SaveAreas;
+ BackingStoreRestoreAreasProcPtr RestoreAreas;
+#ifdef RENDER
+ Bool (*SetupForCPUToScreenAlphaTexture)(ScrnInfoPtr pScrn, int op,
+ CARD16 red, CARD16 green,
+ CARD16 blue, CARD16 alpha,
+ int alphaType, CARD8 *alphaPtr,
+ int alphaPitch, int width,
+ int height, int flags);
+ Bool (*SetupForCPUToScreenTexture)(ScrnInfoPtr pScrn, int op, int texType,
+ CARD8 *texPtr, int texPitch,
+ int width, int height, int flags);
+#endif
+} XAAStateWrapRec, *XAAStateWrapPtr;
+
+static int XAAStateIndex = -1;
+static unsigned long XAAStateGeneration = 0;
+
+/* Wrap functions start here */
+#define GET_STATEPRIV_GC(pGC) XAAStateWrapPtr pStatePriv =\
+(XAAStateWrapPtr)(pGC->pScreen->devPrivates[XAAStateIndex].ptr)
+
+#define GET_STATEPRIV_SCREEN(pScreen) XAAStateWrapPtr pStatePriv =\
+(XAAStateWrapPtr)(pScreen->devPrivates[XAAStateIndex].ptr)
+
+#define GET_STATEPRIV_PSCRN(pScrn) XAAStateWrapPtr pStatePriv =\
+(XAAStateWrapPtr)(pScrn->pScreen->devPrivates[XAAStateIndex].ptr)
+
+#define STATE_CHECK_SP(pStatePriv) {\
+ ScrnInfoPtr pScrn = pStatePriv->pScrn;\
+ int i = 0;\
+ int need_change = 0;\
+ while(i < pScrn->numEntities) {\
+ if(xf86IsEntityShared(pScrn->entityList[i]) &&\
+ xf86GetLastScrnFlag(pScrn->entityList[i]) != pScrn->scrnIndex) {\
+ need_change = 1;\
+ xf86SetLastScrnFlag(pScrn->entityList[i],\
+ pScrn->scrnIndex);\
+ }\
+ i++;\
+ }\
+ if(need_change == 1) (*pStatePriv->RestoreAccelState)(pScrn);\
+}
+
+#define STATE_CHECK_PSCRN(pScrn) {\
+ int i = 0;\
+ int need_change = 0;\
+ while(i < pScrn->numEntities) {\
+ if(xf86IsEntityShared(pScrn->entityList[i]) &&\
+ xf86GetLastScrnFlag(pScrn->entityList[i]) != pScrn->scrnIndex) {\
+ need_change = 1;\
+ xf86SetLastScrnFlag(pScrn->entityList[i],\
+ pScrn->scrnIndex);\
+ }\
+ i++;\
+ }\
+ if(need_change == 1) (*pStatePriv->RestoreAccelState)(pScrn);\
+}
+
+static void XAAStateWrapSync(ScrnInfoPtr pScrn)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->Sync)(pScrn);
+}
+
+static void XAAStateWrapSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int trans_color)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, rop, planemask,
+ trans_color);
+}
+
+static void XAAStateWrapSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForSolidFill)(pScrn, color, rop, planemask);
+}
+
+static void XAAStateWrapSetupForSolidLine(ScrnInfoPtr pScrn,int color,int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForSolidLine)(pScrn, color, rop, planemask);
+}
+
+static void XAAStateWrapSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForDashedLine)(pScrn, fg, bg, rop, planemask, length, pattern);
+}
+
+static void XAAStateWrapSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top,
+ int right, int bottom)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetClippingRectangle)(pScrn, left, top, right, bottom);
+}
+
+static void XAAStateWrapDisableClipping(ScrnInfoPtr pScrn)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->DisableClipping)(pScrn);
+}
+
+static void XAAStateWrapSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForMono8x8PatternFill)(pScrn, patx, paty, fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask,
+ int transparency_color)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForColor8x8PatternFill)(pScrn, patx, paty, rop, planemask,
+ transparency_color);
+}
+
+static void XAAStateWrapSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+}
+
+static void XAAStateWrapSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapSetupForImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForImageWrite)(pScrn, rop, planemask, transparency_color, bpp,
+ depth);
+}
+
+static void XAAStateWrapSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScanlineImageWrite)(pScrn, rop, planemask, transparency_color,
+ bpp, depth);
+}
+
+static void XAAStateWrapSetupForImageRead(ScrnInfoPtr pScrn, int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForImageRead)(pScrn, bpp, depth);
+}
+
+static void XAAStateWrapScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox,
+ DDXPointPtr pptSrc, BoxPtr pbox, int xdir,
+ int ydir, int alu, unsigned int planmask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->ScreenToScreenBitBlt)(pScrn, nbox,
+ pptSrc, pbox, xdir,
+ ydir, alu, planmask);
+}
+
+static void XAAStateWrapWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int skipleft,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteBitmap)(pScrn, x, y, w, h,
+ src, srcwidth, skipleft,
+ fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapFillSolidRects(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillSolidRects)(pScrn, fg, rop,
+ planemask, nBox, pBox);
+}
+
+static void XAAStateWrapFillMono8x8PatternRects(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int nBox,
+ BoxPtr pBox, int pat0, int pat1,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillMono8x8PatternRects)(pScrn, fg, bg,
+ rop, planemask, nBox,
+ pBox, pat0, pat1,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillColor8x8PatternRects(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColor8x8PatternRects)(pScrn, rop,
+ planemask, nBox,
+ pBox, xorg, yorg,
+ pCache);
+}
+
+static void XAAStateWrapFillCacheBltRects(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheBltRects)(pScrn, rop,
+ planemask, nBox, pBox,
+ xorg, yorg, pCache);
+}
+
+static void XAAStateWrapFillColorExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColorExpandRects)(pScrn, fg, bg, rop,
+ planemask, nBox,
+ pBox, xorg, yorg,
+ pPix);
+}
+
+static void XAAStateWrapFillCacheExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheExpandRects)(pScrn, fg, bg, rop,
+ planemask, nBox,
+ pBox, xorg, yorg,
+ pPix);
+}
+
+static void XAAStateWrapFillImageWriteRects(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillImageWriteRects)(pScrn, rop,
+ planemask, nBox, pBox,
+ xorg, yorg, pPix);
+}
+
+static void XAAStateWrapFillSolidSpans(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int n, DDXPointPtr points,
+ int *widths, int fSorted)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillSolidSpans)(pScrn, fg, rop,
+ planemask, n, points,
+ widths, fSorted);
+}
+
+static void XAAStateWrapFillMono8x8PatternSpans(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, int pat0, int pat1,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillMono8x8PatternSpans)(pScrn, fg, bg,
+ rop, planemask, n,
+ points, widths,
+ fSorted, pat0, pat1,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillColor8x8PatternSpans(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColor8x8PatternSpans)(pScrn, rop,
+ planemask, n,
+ points, widths,
+ fSorted, pCache,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillCacheBltSpans(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheBltSpans)(pScrn, rop,
+ planemask, n,
+ points, widths,
+ fSorted, pCache,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillColorExpandSpans(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths, int fSorted,
+ int xorg, int yorg, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColorExpandSpans)(pScrn, fg, bg, rop,
+ planemask, n,
+ points, widths, fSorted,
+ xorg, yorg, pPix);
+}
+
+static void XAAStateWrapFillCacheExpandSpans(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted,
+ int xorg, int yorg, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheExpandSpans)(pScrn, fg, bg, rop,
+ planemask, n,
+ ppt, pwidth, fSorted,
+ xorg, yorg, pPix);
+}
+
+static void XAAStateWrapTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft, int startline,
+ unsigned int **glyphs,
+ int glyphWidth, int fg, int bg, int rop,
+ unsigned planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->TEGlyphRenderer)(pScrn, x, y, w, h,
+ skipleft, startline,
+ glyphs,
+ glyphWidth, fg, bg, rop,
+ planemask);
+}
+
+static void XAAStateWrapNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox,
+ int fg, int rop, unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->NonTEGlyphRenderer)(pScrn, x, y, n,
+ glyphs, pbox,
+ fg, rop, planemask);
+}
+
+static void XAAStateWrapWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WritePixmap)(pScrn, x, y, w, h,
+ src, srcwidth, rop,
+ planemask, transparency_color,
+ bpp, depth);
+}
+
+static void XAAStateWrapReadPixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->ReadPixmap)(pScrn, x, y, w, h,
+ dst, dstwidth, bpp, depth);
+}
+
+static RegionPtr XAAStateWrapCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GC *pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->CopyArea)(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height,
+ dstx, dsty);
+}
+
+static RegionPtr XAAStateWrapCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+}
+
+static void XAAStateWrapPushPixelsSolid(GCPtr pGC, PixmapPtr pBitMap,
+ DrawablePtr pDrawable, int dx, int dy, int xOrg,
+ int yOrg)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PushPixelsSolid)(pGC, pBitMap,
+ pDrawable, dx, dy, xOrg,
+ yOrg);
+}
+
+static void XAAStateWrapPolyFillRectSolid(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectSolid)(pDraw, pGC, nrectFill,
+ prectInit);
+}
+
+static void XAAStateWrapPolyFillRectStippled(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectStippled)(pDraw, pGC, nrectFill,
+ prectInit);
+}
+
+static void XAAStateWrapPolyFillRectOpaqueStippled(DrawablePtr pDraw, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectOpaqueStippled)(pDraw, pGC,
+ nrectFill, prectInit);
+}
+
+static void XAAStateWrapPolyFillRectTiled(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectTiled)(pDraw, pGC, nrectFill,
+ prectInit);
+}
+
+static void XAAStateWrapFillSpansSolid(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansSolid)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static void XAAStateWrapFillSpansStippled(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansStippled)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static void XAAStateWrapFillSpansOpaqueStippled(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansOpaqueStippled)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static void XAAStateWrapFillSpansTiled(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansTiled)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static int XAAStateWrapPolyText8TE(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText8TE)(pDraw, pGC, x, y, count,
+ chars);
+}
+
+static int XAAStateWrapPolyText16TE(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText16TE)(pDraw, pGC, x, y, count,
+ chars);
+}
+
+static void XAAStateWrapImageText8TE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText8TE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageText16TE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText16TE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageGlyphBltTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageGlyphBltTE)(pDrawable, pGC, xInit,
+ yInit, nglyph, ppci,
+ pglyphBase);
+}
+
+static void XAAStateWrapPolyGlyphBltTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyGlyphBltTE)(pDrawable, pGC, xInit,
+ yInit, nglyph, ppci,
+ pglyphBase);
+}
+
+static int XAAStateWrapPolyText8NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText8NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static int XAAStateWrapPolyText16NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText16NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageText8NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText8NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageText16NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText16NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageGlyphBltNonTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageGlyphBltNonTE)(pDrawable, pGC, xInit,
+ yInit, nglyph,
+ ppci, pglyphBase);
+}
+
+static void XAAStateWrapPolyGlyphBltNonTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyGlyphBltNonTE)(pDrawable, pGC, xInit,
+ yInit, nglyph,
+ ppci, pglyphBase);
+}
+
+static void XAAStateWrapPolyRectangleThinSolid(DrawablePtr pDrawable,GCPtr pGC,
+ int nRectsInit, xRectangle *pRectsInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyRectangleThinSolid)(pDrawable, pGC,
+ nRectsInit, pRectsInit);
+}
+
+static void XAAStateWrapPolylinesWideSolid(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolylinesWideSolid)(pDrawable, pGC, mode,
+ npt, pPts);
+}
+
+static void XAAStateWrapPolylinesThinSolid(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolylinesThinSolid)(pDrawable, pGC, mode,
+ npt, pPts);
+}
+
+static void XAAStateWrapPolySegmentThinSolid(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolySegmentThinSolid)(pDrawable, pGC, nseg,
+ pSeg);
+}
+
+static void XAAStateWrapPolylinesThinDashed(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolylinesThinDashed)(pDrawable, pGC, mode,
+ npt, pPts);
+}
+
+static void XAAStateWrapPolySegmentThinDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolySegmentThinDashed)(pDrawable, pGC, nseg,
+ pSeg);
+}
+
+static void XAAStateWrapFillPolygonSolid(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonSolid)(pDrawable, pGC, shape,
+ mode, count, ptsIn);
+}
+
+static void XAAStateWrapFillPolygonStippled(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonStippled)(pDrawable, pGC, shape,
+ mode, count, ptsIn);
+}
+
+static void XAAStateWrapFillPolygonOpaqueStippled(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonOpaqueStippled)(pDrawable, pGC,
+ shape, mode, count,
+ ptsIn);
+}
+
+static void XAAStateWrapFillPolygonTiled(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonTiled)(pDrawable, pGC, shape,
+ mode, count, ptsIn);
+}
+
+static void XAAStateWrapPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs,
+ xArc *parcs)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillArcSolid)(pDraw, pGC, narcs,
+ parcs);
+}
+
+static void XAAStateWrapPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PutImage)(pDraw, pGC, depth, x, y,
+ w, h, leftPad, format, pImage);
+}
+
+static void XAAStateWrapValidateFillSpans(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateFillSpans)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateSetSpans(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateSetSpans)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePutImage(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePutImage)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateCopyArea(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateCopyArea)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateCopyPlane(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateCopyPlane)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyPoint(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyPoint)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolylines(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolylines)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolySegment(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolySegment)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyRectangle(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyRectangle)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyArc(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyArc)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateFillPolygon(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateFillPolygon)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyFillRect(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyFillRect)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyFillArc(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyFillArc)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyText8(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyText8)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyText16(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyText16)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateImageText8(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateImageText8)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateImageText16(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateImageText16)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyGlyphBlt(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyGlyphBlt)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateImageGlyphBlt(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+ (*pStatePriv->ValidateImageGlyphBlt)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePushPixels(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePushPixels)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapComputeDash(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ComputeDash)(pGC);
+}
+
+static void XAAStateWrapInitPixmapCache(ScreenPtr pScreen, RegionPtr areas,
+ pointer data)
+{
+ GET_STATEPRIV_SCREEN(pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->InitPixmapCache)(pScreen, areas,
+ data);
+}
+
+static void XAAStateWrapClosePixmapCache(ScreenPtr pScreen)
+{
+ GET_STATEPRIV_SCREEN(pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ClosePixmapCache)(pScreen);
+}
+
+static int XAAStateWrapStippledFillChooser(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->StippledFillChooser)(pGC);
+}
+
+static int XAAStateWrapOpaqueStippledFillChooser(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->OpaqueStippledFillChooser)(pGC);
+}
+
+static int XAAStateWrapTiledFillChooser(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->TiledFillChooser)(pGC);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheTile)(pScrn, pPix);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg,
+ int bg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheStipple)(pScrn, pPix, fg,
+ bg);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheMonoStipple)(pScrn, pPix);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0,
+ int pat1)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheMono8x8Pattern)(pScrn, pat0,
+ pat1);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix,
+ int fg, int bg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheColor8x8Pattern)(pScrn, pPix,
+ fg, bg);
+}
+
+static void XAAStateWrapWriteBitmapToCache(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int fg,
+ int bg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteBitmapToCache)(pScrn, x, y, w, h,
+ src, srcwidth, fg,
+ bg);
+}
+
+static void XAAStateWrapWritePixmapToCache(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int bpp,
+ int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WritePixmapToCache)(pScrn, x, y, w, h,
+ src, srcwidth, bpp,
+ depth);
+}
+
+static void XAAStateWrapWriteMono8x8PatternToCache(ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteMono8x8PatternToCache)(pScrn,
+ pCache);
+}
+
+static void XAAStateWrapWriteColor8x8PatternToCache(ScrnInfoPtr pScrn, PixmapPtr pPix,
+ XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteColor8x8PatternToCache)(pScrn, pPix,
+ pCache);
+}
+
+static void XAAStateWrapGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format,unsigned long planeMask,
+ char *pdstLine)
+{
+ GET_STATEPRIV_SCREEN(pDrawable->pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->GetImage)(pDrawable, sx, sy, w, h,
+ format, planeMask,
+ pdstLine);
+}
+
+static void XAAStateWrapGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart)
+{
+ GET_STATEPRIV_SCREEN(pDrawable->pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->GetSpans)(pDrawable, wMax, ppt,
+ pwidth, nspans, pdstStart);
+}
+
+static void XAAStateWrapPaintWindowBackground(WindowPtr pWindow, RegionPtr pRegion,
+ int what)
+{
+ GET_STATEPRIV_SCREEN(pWindow->drawable.pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PaintWindowBackground)(pWindow, pRegion,
+ what);
+}
+
+static void XAAStateWrapPaintWindowBorder(WindowPtr pWindow, RegionPtr pRegion,
+ int what)
+{
+ GET_STATEPRIV_SCREEN(pWindow->drawable.pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PaintWindowBorder)(pWindow, pRegion,
+ what);
+}
+
+static void XAAStateWrapCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ GET_STATEPRIV_SCREEN(pWindow->drawable.pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->CopyWindow)(pWindow, ptOldOrg,
+ prgnSrc);
+}
+
+static void XAAStateWrapSaveAreas(PixmapPtr pBackingPixmap, RegionPtr pObscured, int x,
+ int y, WindowPtr pWin)
+{
+ GET_STATEPRIV_SCREEN(pBackingPixmap->drawable.pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->SaveAreas)(pBackingPixmap, pObscured, x,
+ y, pWin);
+}
+
+static void XAAStateWrapRestoreAreas(PixmapPtr pBackingPixmap, RegionPtr pExposed,
+ int x, int y, WindowPtr pWin)
+{
+ GET_STATEPRIV_SCREEN(pBackingPixmap->drawable.pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->RestoreAreas)(pBackingPixmap, pExposed,
+ x, y, pWin);
+}
+
+#ifdef RENDER
+static Bool XAAStateWrapSetupForCPUToScreenAlphaTexture(ScrnInfoPtr pScrn,
+ int op, CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ int alphaType,
+ CARD8 *alphaPtr,
+ int alphaPitch,
+ int width, int height,
+ int flags)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->SetupForCPUToScreenAlphaTexture)(pScrn, op, red, green,
+ blue, alpha, alphaType,
+ alphaPtr, alphaPitch,
+ width, height, flags);
+}
+
+static Bool XAAStateWrapSetupForCPUToScreenTexture(ScrnInfoPtr pScrn, int op,
+ int texType, CARD8 *texPtr,
+ int texPitch,
+ int width, int height,
+ int flags)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->SetupForCPUToScreenTexture)(pScrn, op, texType, texPtr,
+ texPitch, width, height,
+ flags);
+}
+#endif
+
+/* Setup Function */
+Bool
+XAAInitStateWrap(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAStateWrapPtr pStatePriv;
+ int i = 0;
+
+ if (XAAStateGeneration != serverGeneration) {
+ if((XAAStateIndex = AllocateScreenPrivateIndex()) < 0) return FALSE;
+ XAAStateGeneration = serverGeneration;
+ }
+ if(!(pStatePriv = xalloc(sizeof(XAAStateWrapRec)))) return FALSE;
+ pScreen->devPrivates[XAAStateIndex].ptr = (pointer)pStatePriv;
+ pStatePriv->RestoreAccelState = infoRec->RestoreAccelState;
+ pStatePriv->pScrn = pScrn;
+
+ /* Initialize the last screen to -1 so whenever an accel function
+ * is called the proper state is setup
+ */
+ while(i < pScrn->numEntities) {
+ xf86SetLastScrnFlag(pScrn->entityList[i], -1);
+ i++;
+ }
+/* Do the wrapping */
+ XAA_STATE_WRAP(Sync);
+ XAA_STATE_WRAP(SetupForScreenToScreenCopy);
+ XAA_STATE_WRAP(SetupForSolidFill);
+ XAA_STATE_WRAP(SetupForSolidLine);
+ XAA_STATE_WRAP(SetupForDashedLine);
+ XAA_STATE_WRAP(SetClippingRectangle);
+ XAA_STATE_WRAP(DisableClipping);
+ XAA_STATE_WRAP(SetupForMono8x8PatternFill);
+ XAA_STATE_WRAP(SetupForColor8x8PatternFill);
+ XAA_STATE_WRAP(SetupForCPUToScreenColorExpandFill);
+ XAA_STATE_WRAP(SetupForScanlineCPUToScreenColorExpandFill);
+ XAA_STATE_WRAP(SetupForScreenToScreenColorExpandFill);
+ XAA_STATE_WRAP(SetupForImageWrite);
+ XAA_STATE_WRAP(SetupForScanlineImageWrite);
+ XAA_STATE_WRAP(SetupForImageRead);
+ XAA_STATE_WRAP(ScreenToScreenBitBlt);
+ XAA_STATE_WRAP(WriteBitmap);
+ XAA_STATE_WRAP(FillSolidRects);
+ XAA_STATE_WRAP(FillMono8x8PatternRects);
+ XAA_STATE_WRAP(FillColor8x8PatternRects);
+ XAA_STATE_WRAP(FillCacheBltRects);
+ XAA_STATE_WRAP(FillColorExpandRects);
+ XAA_STATE_WRAP(FillCacheExpandRects);
+ XAA_STATE_WRAP(FillImageWriteRects);
+ XAA_STATE_WRAP(FillSolidSpans);
+ XAA_STATE_WRAP(FillMono8x8PatternSpans);
+ XAA_STATE_WRAP(FillColor8x8PatternSpans);
+ XAA_STATE_WRAP(FillCacheBltSpans);
+ XAA_STATE_WRAP(FillColorExpandSpans);
+ XAA_STATE_WRAP(FillCacheExpandSpans);
+ XAA_STATE_WRAP(TEGlyphRenderer);
+ XAA_STATE_WRAP(NonTEGlyphRenderer);
+ XAA_STATE_WRAP(WritePixmap);
+ XAA_STATE_WRAP(ReadPixmap);
+ XAA_STATE_WRAP(CopyArea);
+ XAA_STATE_WRAP(CopyPlane);
+ XAA_STATE_WRAP(PushPixelsSolid);
+ XAA_STATE_WRAP(PolyFillRectSolid);
+ XAA_STATE_WRAP(PolyFillRectStippled);
+ XAA_STATE_WRAP(PolyFillRectOpaqueStippled);
+ XAA_STATE_WRAP(PolyFillRectTiled);
+ XAA_STATE_WRAP(FillSpansSolid);
+ XAA_STATE_WRAP(FillSpansStippled);
+ XAA_STATE_WRAP(FillSpansOpaqueStippled);
+ XAA_STATE_WRAP(FillSpansTiled);
+ XAA_STATE_WRAP(PolyText8TE);
+ XAA_STATE_WRAP(PolyText16TE);
+ XAA_STATE_WRAP(ImageText8TE);
+ XAA_STATE_WRAP(ImageText16TE);
+ XAA_STATE_WRAP(ImageGlyphBltTE);
+ XAA_STATE_WRAP(PolyGlyphBltTE);
+ XAA_STATE_WRAP(PolyText8NonTE);
+ XAA_STATE_WRAP(PolyText16NonTE);
+ XAA_STATE_WRAP(ImageText8NonTE);
+ XAA_STATE_WRAP(ImageText16NonTE);
+ XAA_STATE_WRAP(ImageGlyphBltNonTE);
+ XAA_STATE_WRAP(PolyGlyphBltNonTE);
+ XAA_STATE_WRAP(PolyRectangleThinSolid);
+ XAA_STATE_WRAP(PolylinesWideSolid);
+ XAA_STATE_WRAP(PolylinesThinSolid);
+ XAA_STATE_WRAP(PolySegmentThinSolid);
+ XAA_STATE_WRAP(PolylinesThinDashed);
+ XAA_STATE_WRAP(PolySegmentThinDashed);
+ XAA_STATE_WRAP(FillPolygonSolid);
+ XAA_STATE_WRAP(FillPolygonStippled);
+ XAA_STATE_WRAP(FillPolygonOpaqueStippled);
+ XAA_STATE_WRAP(FillPolygonTiled);
+ XAA_STATE_WRAP(PolyFillArcSolid);
+ XAA_STATE_WRAP(PutImage);
+ XAA_STATE_WRAP(ValidateFillSpans);
+ XAA_STATE_WRAP(ValidateSetSpans);
+ XAA_STATE_WRAP(ValidatePutImage);
+ XAA_STATE_WRAP(ValidateCopyArea);
+ XAA_STATE_WRAP(ValidateCopyPlane);
+ XAA_STATE_WRAP(ValidatePolyPoint);
+ XAA_STATE_WRAP(ValidatePolylines);
+ XAA_STATE_WRAP(ValidatePolySegment);
+ XAA_STATE_WRAP(ValidatePolyRectangle);
+ XAA_STATE_WRAP(ValidatePolyArc);
+ XAA_STATE_WRAP(ValidateFillPolygon);
+ XAA_STATE_WRAP(ValidatePolyFillRect);
+ XAA_STATE_WRAP(ValidatePolyFillArc);
+ XAA_STATE_WRAP(ValidatePolyText8);
+ XAA_STATE_WRAP(ValidatePolyText16);
+ XAA_STATE_WRAP(ValidateImageText8);
+ XAA_STATE_WRAP(ValidateImageText16);
+ XAA_STATE_WRAP(ValidatePolyGlyphBlt);
+ XAA_STATE_WRAP(ValidateImageGlyphBlt);
+ XAA_STATE_WRAP(ValidatePushPixels);
+ XAA_STATE_WRAP(ComputeDash);
+ XAA_STATE_WRAP(InitPixmapCache);
+ XAA_STATE_WRAP(ClosePixmapCache);
+ XAA_STATE_WRAP(StippledFillChooser);
+ XAA_STATE_WRAP(OpaqueStippledFillChooser);
+ XAA_STATE_WRAP(TiledFillChooser);
+ XAA_STATE_WRAP(CacheTile);
+ XAA_STATE_WRAP(CacheStipple);
+ XAA_STATE_WRAP(CacheMonoStipple);
+ XAA_STATE_WRAP(CacheMono8x8Pattern);
+ XAA_STATE_WRAP(CacheColor8x8Pattern);
+ XAA_STATE_WRAP(WriteBitmapToCache);
+ XAA_STATE_WRAP(WritePixmapToCache);
+ XAA_STATE_WRAP(WriteMono8x8PatternToCache);
+ XAA_STATE_WRAP(WriteColor8x8PatternToCache);
+ XAA_STATE_WRAP(GetImage);
+ XAA_STATE_WRAP(GetSpans);
+ XAA_STATE_WRAP(PaintWindowBackground);
+ XAA_STATE_WRAP(PaintWindowBorder);
+ XAA_STATE_WRAP(CopyWindow);
+ XAA_STATE_WRAP(SaveAreas);
+ XAA_STATE_WRAP(RestoreAreas);
+ XAA_STATE_WRAP(SetupForCPUToScreenAlphaTexture);
+ XAA_STATE_WRAP(SetupForCPUToScreenTexture);
+
+ return TRUE;
+}
diff --git a/hw/xfree86/xaa/xaaStipple.c b/hw/xfree86/xaa/xaaStipple.c
new file mode 100644
index 000000000..8037a3eaf
--- /dev/null
+++ b/hw/xfree86/xaa/xaaStipple.c
@@ -0,0 +1,843 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaStipple.c,v 1.11 2001/10/28 03:34:04 tsi Exp $ */
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+static CARD32* StipplePowerOfTwo(CARD32*, CARD32*, int, int, int);
+static CARD32* StipplePowerOfTwo_Inverted(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleUpTo32(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleUpTo32_Inverted(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleOver32(CARD32*, CARD32*, int, int, int);
+static CARD32* StippleOver32_Inverted(CARD32*, CARD32*, int, int, int);
+
+#ifdef TRIPLE_BITS
+#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc3)
+#else
+#define stipple_scanline_func EXPNAME(XAAStippleScanlineFunc)
+#endif
+
+StippleScanlineProcPtr stipple_scanline_func[6] = {
+ StipplePowerOfTwo,
+ StippleUpTo32,
+ StippleOver32,
+ StipplePowerOfTwo_Inverted,
+ StippleUpTo32_Inverted,
+ StippleOver32_Inverted
+};
+
+
+#ifdef FIXEDBASE
+# define DEST(i) *dest
+# define RETURN(i) return(dest)
+#else
+# define DEST(i) dest[i]
+# define RETURN(i) return(dest + i)
+#endif
+
+
+/* TRIPLE_BITS pattern expansion */
+#ifdef TRIPLE_BITS
+#define EXPAND_PAT \
+ CARD32 pat1 = byte_expand3[pat & 0xFF], \
+ pat2 = byte_expand3[(pat & 0xFF00) >> 8], \
+ pat3 = byte_expand3[(pat & 0xFF0000) >> 16], \
+ pat4 = byte_expand3[(pat & 0xFF000000) >> 24], \
+ patA = pat1 | (pat2 << 24), \
+ patB = (pat2 >> 8) | (pat3 << 16), \
+ patC = (pat3 >> 16) | (pat4 << 8)
+#ifdef FIXED_BASE
+#define WRITE_PAT1 { \
+ *dest = patA; }
+#define WRITE_PAT2 { \
+ *dest = patA; \
+ *dest = patB; }
+#define WRITE_PAT3 { \
+ *dest = patA; \
+ *dest = patB; \
+ *dest = patC; }
+#else
+#define WRITE_PAT1 { \
+ *(dest++) = patA; }
+#define WRITE_PAT2 { \
+ *(dest) = patA; \
+ *(dest + 1) = patB; \
+ dest += 2; }
+#define WRITE_PAT3 { \
+ *(dest) = patA; \
+ *(dest + 1) = patB; \
+ *(dest + 2) = patC; \
+ dest += 3; }
+#endif
+#endif
+
+
+#if !defined(FIXEDBASE) && !defined(MSBFIRST) && !defined(TRIPLE_BITS)
+
+unsigned int XAAShiftMasks[32] = {
+ /* gcc is rather pedantic about SHIFT_R(0xFFFFFFFF,32) */
+ 0x00000000 , SHIFT_R(0xFFFFFFFF,31),
+ SHIFT_R(0xFFFFFFFF,30), SHIFT_R(0xFFFFFFFF,29),
+ SHIFT_R(0xFFFFFFFF,28), SHIFT_R(0xFFFFFFFF,27),
+ SHIFT_R(0xFFFFFFFF,26), SHIFT_R(0xFFFFFFFF,25),
+ SHIFT_R(0xFFFFFFFF,24), SHIFT_R(0xFFFFFFFF,23),
+ SHIFT_R(0xFFFFFFFF,22), SHIFT_R(0xFFFFFFFF,21),
+ SHIFT_R(0xFFFFFFFF,20), SHIFT_R(0xFFFFFFFF,19),
+ SHIFT_R(0xFFFFFFFF,18), SHIFT_R(0xFFFFFFFF,17),
+ SHIFT_R(0xFFFFFFFF,16), SHIFT_R(0xFFFFFFFF,15),
+ SHIFT_R(0xFFFFFFFF,14), SHIFT_R(0xFFFFFFFF,13),
+ SHIFT_R(0xFFFFFFFF,12), SHIFT_R(0xFFFFFFFF,11),
+ SHIFT_R(0xFFFFFFFF,10), SHIFT_R(0xFFFFFFFF,9),
+ SHIFT_R(0xFFFFFFFF,8), SHIFT_R(0xFFFFFFFF,7),
+ SHIFT_R(0xFFFFFFFF,6), SHIFT_R(0xFFFFFFFF,5),
+ SHIFT_R(0xFFFFFFFF,4), SHIFT_R(0xFFFFFFFF,3),
+ SHIFT_R(0xFFFFFFFF,2), SHIFT_R(0xFFFFFFFF,1)
+};
+
+#endif
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillColorExpandRects3)(
+#else
+EXPNAME(XAAFillColorExpandRects)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, srcy, srcx, funcNo = 2, h;
+ unsigned char *src = (unsigned char*)pPix->devPrivate.ptr;
+ unsigned char *srcp;
+ int flag;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidRects) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
+#else
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+#endif
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ h = pBox->y2 - pBox->y1;
+ flag = (infoRec->CPUToScreenColorExpandFillFlags
+ & CPU_TRANSFER_PAD_QWORD) && ((dwords * h) & 0x01);
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+#ifndef FIXEDBASE
+ if((dwords * h) <= infoRec->ColorExpandRange) {
+ while(h--) {
+ base = (*StippleFunc)(
+ base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+ } else
+#endif
+ while(h--) {
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ if (flag) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ pBox++;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillColorExpandSpans3)(
+#else
+EXPNAME(XAAFillColorExpandSpans)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int dwords, srcy, srcx, funcNo = 2;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->CPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->CPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidSpans)(
+ pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(n--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * *pwidth + 31) >> 5;
+#else
+ dwords = (*pwidth + 31) >> 5;
+#endif
+
+ srcy = (ppt->y - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (ppt->x - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, ppt->x, ppt->y,
+ *pwidth, 1, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+
+ if((infoRec->CPUToScreenColorExpandFillFlags & CPU_TRANSFER_PAD_QWORD)
+ && (dwords & 0x01)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ ppt++; pwidth++;
+ }
+
+ if(infoRec->CPUToScreenColorExpandFillFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+#ifndef FIXEDBASE
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillScanlineColorExpandRects3)(
+#else
+EXPNAME(XAAFillScanlineColorExpandRects)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int srcwidth = pPix->devKind;
+ int dwords, srcy, srcx, funcNo = 2, bufferNo, h;
+ unsigned char *src = pPix->devPrivate.ptr;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidRects) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidRects)(pScrn, bg, rop, planemask, nBox, pBox);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ while(nBox--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * (pBox->x2 - pBox->x1) + 31) >> 5;
+#else
+ dwords = (pBox->x2 - pBox->x1 + 31) >> 5;
+#endif
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ h = pBox->y2 - pBox->y1;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, pBox->x1, pBox->y1, pBox->x2 - pBox->x1, h, 0);
+
+ bufferNo = 0;
+
+ srcy = (pBox->y1 - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (pBox->x1 - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (srcwidth * srcy) + src;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ srcy++;
+ srcp += srcwidth;
+ if (srcy >= stippleheight) {
+ srcy = 0;
+ srcp = src;
+ }
+ }
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ pBox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+#ifdef TRIPLE_BITS
+EXPNAME(XAAFillScanlineColorExpandSpans3)(
+#else
+EXPNAME(XAAFillScanlineColorExpandSpans)(
+#endif
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base;
+ Bool TwoPass = FALSE, FirstPass = TRUE;
+ StippleScanlineProcPtr StippleFunc, FirstFunc, SecondFunc;
+ int stipplewidth = pPix->drawable.width;
+ int stippleheight = pPix->drawable.height;
+ int dwords, srcy, srcx, funcNo = 2;
+ unsigned char *srcp;
+
+ if(stipplewidth <= 32) {
+ if(stipplewidth & (stipplewidth - 1))
+ funcNo = 1;
+ else
+ funcNo = 0;
+ }
+ StippleFunc = stipple_scanline_func[funcNo];
+ SecondFunc = stipple_scanline_func[funcNo];
+ FirstFunc = stipple_scanline_func[funcNo + 3];
+
+#ifdef TRIPLE_BITS
+ if((bg == -1) ||
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY) &&
+ (!(infoRec->ScanlineCPUToScreenColorExpandFillFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(bg))))) {
+#else
+ if((bg == -1) ||
+ !(infoRec->ScanlineCPUToScreenColorExpandFillFlags & TRANSPARENCY_ONLY)) {
+#endif
+ /* one pass */
+ } else if((rop == GXcopy) && infoRec->FillSolidSpans) {
+ /* one pass but we fill background rects first */
+ (*infoRec->FillSolidSpans)(
+ pScrn, bg, rop, planemask, n, ppt, pwidth, fSorted);
+ bg = -1;
+ } else {
+ /* gotta do two passes */
+ TwoPass = TRUE;
+ }
+
+ if(!TwoPass)
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+
+ while(n--) {
+#ifdef TRIPLE_BITS
+ dwords = (3 * *pwidth + 31) >> 5;
+#else
+ dwords = (*pwidth + 31) >> 5;
+#endif
+
+ srcy = (ppt->y - yorg) % stippleheight;
+ if(srcy < 0) srcy += stippleheight;
+ srcx = (ppt->x - xorg) % stipplewidth;
+ if(srcx < 0) srcx += stipplewidth;
+
+ srcp = (pPix->devKind * srcy) + (unsigned char*)pPix->devPrivate.ptr;
+
+SECOND_PASS:
+ if(TwoPass) {
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(pScrn,
+ (FirstPass) ? bg : fg, -1, rop, planemask);
+ StippleFunc = (FirstPass) ? FirstFunc : SecondFunc;
+ }
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, ppt->x, ppt->y, *pwidth, 1, 0);
+
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[0];
+
+ (*StippleFunc)(base, (CARD32*)srcp, srcx, stipplewidth, dwords);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, 0);
+
+ if(TwoPass) {
+ if(FirstPass) {
+ FirstPass = FALSE;
+ goto SECOND_PASS;
+ } else FirstPass = TRUE;
+ }
+
+ ppt++; pwidth++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+static CARD32 *
+StipplePowerOfTwo(
+ CARD32* dest, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src;
+ if(width < 32) {
+ pat &= XAAShiftMasks[width];
+ while(width < 32) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ }
+
+ if(shift)
+ pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
+
+#ifdef MSBFIRST
+ pat = SWAP_BITS_IN_BYTES(pat);
+#endif
+
+#ifdef TRIPLE_BITS
+ {
+ EXPAND_PAT;
+
+ while(dwords >= 3) {
+ WRITE_PAT3;
+ dwords -= 3;
+ }
+ if (dwords == 2) {
+ WRITE_PAT2;
+ } else if (dwords == 1) {
+ WRITE_PAT1;
+ }
+
+ return dest;
+ }
+#else /* TRIPLE_BITS */
+ while(dwords >= 4) {
+ DEST(0) = pat;
+ DEST(1) = pat;
+ DEST(2) = pat;
+ DEST(3) = pat;
+ dwords -= 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!dwords) return dest;
+ DEST(0) = pat;
+ if(dwords == 1) RETURN(1);
+ DEST(1) = pat;
+ if(dwords == 2) RETURN(2);
+ DEST(2) = pat;
+ RETURN(3);
+#endif /* TRIPLE_BITS */
+}
+
+static CARD32 *
+StipplePowerOfTwo_Inverted(
+ CARD32* dest, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src;
+ if(width < 32) {
+ pat &= XAAShiftMasks[width];
+ while(width < 32) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ }
+
+ if(shift)
+ pat = SHIFT_R(pat,shift) | SHIFT_L(pat,32 - shift);
+
+#ifdef MSBFIRST
+ pat = SWAP_BITS_IN_BYTES(pat);
+#endif
+
+ pat = ~pat;
+
+#ifdef TRIPLE_BITS
+ {
+ EXPAND_PAT;
+
+ while(dwords >= 3) {
+ WRITE_PAT3;
+ dwords -= 3;
+ }
+ if (dwords == 2) {
+ WRITE_PAT2;
+ } else if (dwords == 1) {
+ WRITE_PAT1;
+ }
+
+ return dest;
+ }
+#else /* TRIPLE_BITS */
+ while(dwords >= 4) {
+ DEST(0) = pat;
+ DEST(1) = pat;
+ DEST(2) = pat;
+ DEST(3) = pat;
+ dwords -= 4;
+#ifndef FIXEDBASE
+ dest += 4;
+#endif
+ }
+
+ if(!dwords) return dest;
+ DEST(0) = pat;
+ if(dwords == 1) RETURN(1);
+ DEST(1) = pat;
+ if(dwords == 2) RETURN(2);
+ DEST(2) = pat;
+ RETURN(3);
+#endif /* TRIPLE_BITS */
+}
+
+
+static CARD32 *
+StippleUpTo32(
+ CARD32* base, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src & XAAShiftMasks[width];
+
+ while(width <= 15) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ pat |= SHIFT_L(pat,width);
+
+ while(dwords--) {
+ CARD32 bits = SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift);
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ shift += 32;
+ shift %= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleUpTo32_Inverted(
+ CARD32* base, CARD32* src,
+ int shift, int width, int dwords
+){
+ CARD32 pat = *src & XAAShiftMasks[width];
+
+ while(width <= 15) {
+ pat |= SHIFT_L(pat,width);
+ width <<= 1;
+ }
+ pat |= SHIFT_L(pat,width);
+
+ while(dwords--) {
+ CARD32 bits = ~(SHIFT_R(pat,shift) | SHIFT_L(pat,width-shift));
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ shift += 32;
+ shift %= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleOver32(
+ CARD32* base, CARD32* src,
+ int offset, int width, int dwords
+){
+ CARD32* srcp;
+ CARD32 bits;
+ int bitsleft, shift;
+
+ while(dwords--) {
+ bitsleft = width - offset;
+ srcp = src + (offset >> 5);
+ shift = offset & 31;
+
+ if(bitsleft < 32)
+ bits = SHIFT_L(*src,bitsleft) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
+ else if(shift)
+ bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],32-shift);
+ else
+ bits = *srcp;
+
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ offset += 32;
+ offset %= width;
+ }
+ return base;
+}
+
+
+static CARD32 *
+StippleOver32_Inverted(
+ CARD32* base, CARD32* src,
+ int offset, int width, int dwords
+){
+ CARD32* srcp;
+ CARD32 bits;
+ int bitsleft, shift;
+
+ while(dwords--) {
+ bitsleft = width - offset;
+ srcp = src + (offset >> 5);
+ shift = offset & 31;
+
+ if(bitsleft < 32)
+ bits = SHIFT_L(*src,bitsleft) |
+ (SHIFT_R(*srcp,shift) & XAAShiftMasks[bitsleft]);
+ else if(shift)
+ bits = SHIFT_R(*srcp,shift) | SHIFT_L(srcp[1],32-shift);
+ else
+ bits = *srcp;
+
+ bits = ~bits;
+
+#ifdef TRIPLE_BITS
+ if(dwords >= 2) {
+ WRITE_BITS3(bits);
+ dwords -= 2;
+ } else if(dwords > 0) {
+ WRITE_BITS2(bits);
+ dwords--;
+ } else {
+ WRITE_BITS1(bits);
+ }
+#else
+ WRITE_BITS(bits);
+#endif
+
+ offset += 32;
+ offset %= width;
+ }
+ return base;
+}
diff --git a/hw/xfree86/xaa/xaaTEGlyph.c b/hw/xfree86/xaa/xaaTEGlyph.c
new file mode 100644
index 000000000..845dccd4e
--- /dev/null
+++ b/hw/xfree86/xaa/xaaTEGlyph.c
@@ -0,0 +1,1072 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyph.c,v 1.9 2000/09/01 05:49:45 mvojkovi Exp $ */
+
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+
+
+/* scanline function for TRIPLE_BITS_24BPP */
+static CARD32 *DrawTextScanline3(CARD32 *base, CARD32 *mem, int width);
+
+/* Loop unrolled functions for common font widths */
+static CARD32 *DrawTETextScanlineGeneric(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth7(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth10(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth12(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth14(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth16(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth18(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth24(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+
+
+#ifdef USEASSEMBLER
+# ifdef FIXEDBASE
+# ifdef MSBFIRST
+CARD32 *DrawTETextScanlineWidth6PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+# else
+CARD32 *DrawTETextScanlineWidth6PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+# endif
+# else
+# ifdef MSBFIRST
+CARD32 *DrawTETextScanlineWidth6PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+# else
+CARD32 *DrawTETextScanlineWidth6PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+# endif
+# endif
+#else
+static CARD32 *DrawTETextScanlineWidth6(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth8(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth9(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+#endif
+
+#define glyph_scanline_func EXPNAME(XAAGlyphScanlineFunc)
+
+
+
+GlyphScanlineFuncPtr glyph_scanline_func[32] = {
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric,
+#ifdef USEASSEMBLER
+# ifdef FIXEDBASE
+# ifdef MSBFIRST
+ DrawTETextScanlineWidth6PMSBFirstFixedBase,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PMSBFirstFixedBase,
+ DrawTETextScanlineWidth9PMSBFirstFixedBase,
+# else
+ DrawTETextScanlineWidth6PLSBFirstFixedBase,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PLSBFirstFixedBase,
+ DrawTETextScanlineWidth9PLSBFirstFixedBase,
+# endif
+# else
+# ifdef MSBFIRST
+ DrawTETextScanlineWidth6PMSBFirst,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PMSBFirst,
+ DrawTETextScanlineWidth9PMSBFirst,
+# else
+ DrawTETextScanlineWidth6PLSBFirst,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PLSBFirst,
+ DrawTETextScanlineWidth9PLSBFirst,
+# endif
+# endif
+#else
+ DrawTETextScanlineWidth6, DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8, DrawTETextScanlineWidth9,
+#endif
+ DrawTETextScanlineWidth10,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth12,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth14,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth16,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth18,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth24,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric
+};
+
+
+/********************************************************************
+
+ Here we have TEGlyphRenders for a bunch of different color
+ expansion types. The driver may provide its own renderer, but
+ this is the default one which renders using lower-level primitives
+ exported by the chipset driver.
+
+********************************************************************/
+
+/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not.
+ A total of 4 versions */
+
+void
+EXPNAME(XAATEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
+ int dwords = 0;
+
+ if((bg != -1) && (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft &&
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ while(count--) {
+ register CARD32 tmp = SHIFT_R(glyphs[0][line++],skipleft);
+ WRITE_BITS(tmp);
+ }
+
+ w -= width;
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((((width + 31) >> 5) * h) & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = ((w + 31) >> 5) * h;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+#ifndef FIXEDBASE
+ if((((w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ base = (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+ else
+#endif
+ while(h--) {
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+THE_END:
+
+ if(infoRec->TEGlyphRendererFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+/********************************************************************
+
+ This is the GlyphRenderer for TRIPLE_BITS_24BPP. It renders to a buffer
+ with the non FIXEDBASE LSB_FIRST code before tripling, and possibly
+ reversing the bits and sending them to the screen
+
+********************************************************************/
+
+void
+EXPNAME(XAATEGlyphRenderer3)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base, *mem;
+ GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+ int dwords = 0;
+
+ if((bg != -1) &&
+ ((infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->TEGlyphRendererFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+ CARD32 bits;
+
+ if(width > w) width = w;
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ while(count--) {
+ bits = SHIFT_R(glyphs[0][line++],skipleft);
+ if (width >= 22) {
+ WRITE_BITS3(bits);
+ } else if (width >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+ }
+
+ w -= width;
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((((3 * width + 31) >> 5) * h) & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ dwords = ((3 * w + 31) >> 5) * h;
+ mem = (CARD32*)ALLOCATE_LOCAL(((w + 31) >> 3) * sizeof(char));
+ if (!mem) return;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, x, y, w, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+# ifndef FIXEDBASE
+ if((((3 * w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ base = DrawTextScanline3(base, mem, w);
+ }
+ else
+# endif
+ while(h--) {
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ DrawTextScanline3(base, mem, w);
+ }
+
+ DEALLOCATE_LOCAL(mem);
+
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+THE_END:
+
+ if(infoRec->TEGlyphRendererFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+#ifndef FIXEDBASE
+/* Scanline version of above gets built for LSBFIRST and MSBFIRST */
+
+void
+EXPNAME(XAATEGlyphRendererScanline)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo;
+ CARD32* base;
+ GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
+
+ if((bg != -1) && (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft &&
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ bufferNo = 0;
+
+ while(count--) {
+ register CARD32 tmp = SHIFT_R(glyphs[0][line++],skipleft);
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ WRITE_BITS(tmp);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ w -= width;
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+THE_END:
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+EXPNAME(XAATEGlyphRendererScanline3)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo;
+ CARD32 *base, *mem;
+ GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+
+ if((bg != -1) &&
+ ((infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->TEGlyphRendererFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+ CARD32 bits;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ bufferNo = 0;
+
+ while(count--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ bits = SHIFT_R(glyphs[0][line++],skipleft);
+ if (width >= 22) {
+ WRITE_BITS3(bits);
+ } else if (width >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ w -= width;
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+ mem = (CARD32*)ALLOCATE_LOCAL(((w + 31) >> 3) * sizeof(char));
+ if (!mem) return;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ DrawTextScanline3(base, mem, w);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ DEALLOCATE_LOCAL(mem);
+
+THE_END:
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+
+
+/********************************************************************
+
+ TRIPLE_BITS_24BPP scanline rendering code.
+
+********************************************************************/
+
+
+
+static CARD32*
+DrawTextScanline3(
+ CARD32 *base,
+ CARD32 *mem,
+ int width )
+{
+
+ while(width > 32) {
+ WRITE_BITS3(*mem);
+ mem++;
+ width -= 32;
+ }
+ if(width) {
+ if (width >= 22) {
+ WRITE_BITS3(*mem);
+ } else if (width >= 11) {
+ WRITE_BITS2(*mem);
+ } else {
+ WRITE_BITS1(*mem);
+ }
+ }
+
+ return base;
+}
+
+
+/********************************************************************
+
+ Generic TE scanline rendering code.
+
+********************************************************************/
+
+
+
+static CARD32*
+DrawTETextScanlineGeneric(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ CARD32 bits = (*glyphp)[line];
+ int shift = glyphwidth;
+
+ while(width > 32) {
+ while(shift < 32) {
+ glyphp++;
+ bits |= SHIFT_L((*glyphp)[line], shift);
+ shift += glyphwidth;
+ }
+ WRITE_BITS(bits);
+ shift &= 31;
+ if(shift)
+ bits = SHIFT_R((*glyphp)[line],(glyphwidth - shift));
+ else bits = 0;
+ width -= 32;
+ }
+
+ if(width) {
+ width -= shift;
+ while(width > 0) {
+ glyphp++;
+ bits |= SHIFT_L((*glyphp)[line],shift);
+ shift += glyphwidth;
+ width -= glyphwidth;
+ }
+ WRITE_BITS(bits);
+ }
+
+ return base;
+}
+
+
+/********************************************************************
+
+ Loop unrolled TE font scanline rendering code
+
+********************************************************************/
+
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth6(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],6);
+ bits |= SHIFT_L(glyphp[2][line],12);
+ bits |= SHIFT_L(glyphp[3][line],18);
+ bits |= SHIFT_L(glyphp[4][line],24);
+ bits |= SHIFT_L(glyphp[5][line],30);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[5][line],2);
+ bits |= SHIFT_L(glyphp[6][line],4);
+ bits |= SHIFT_L(glyphp[7][line],10);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],22);
+ bits |= SHIFT_L(glyphp[10][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[10][line],4);
+ bits |= SHIFT_L(glyphp[11][line],2);
+ bits |= SHIFT_L(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],14);
+ bits |= SHIFT_L(glyphp[14][line],20);
+ bits |= SHIFT_L(glyphp[15][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 16;
+ }
+ return base;
+}
+#endif
+
+static CARD32*
+DrawTETextScanlineWidth7(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],7);
+ bits |= SHIFT_L(glyphp[2][line],14);
+ bits |= SHIFT_L(glyphp[3][line],21);
+ bits |= SHIFT_L(glyphp[4][line],28);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[4][line],4);
+ bits |= SHIFT_L(glyphp[5][line],3);
+ bits |= SHIFT_L(glyphp[6][line],10);
+ bits |= SHIFT_L(glyphp[7][line],17);
+ bits |= SHIFT_L(glyphp[8][line],24);
+ bits |= SHIFT_L(glyphp[9][line],31);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[9][line],1);
+ bits |= SHIFT_L(glyphp[10][line],6);
+ bits |= SHIFT_L(glyphp[11][line],13);
+ bits |= SHIFT_L(glyphp[12][line],20);
+ bits |= SHIFT_L(glyphp[13][line],27);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[13][line],5);
+ bits |= SHIFT_L(glyphp[14][line],2);
+ bits |= SHIFT_L(glyphp[15][line],9);
+ bits |= SHIFT_L(glyphp[16][line],16);
+ bits |= SHIFT_L(glyphp[17][line],23);
+ bits |= SHIFT_L(glyphp[18][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[18][line],2);
+ bits |= SHIFT_L(glyphp[19][line],5);
+ bits |= SHIFT_L(glyphp[20][line],12);
+ bits |= SHIFT_L(glyphp[21][line],19);
+ bits |= SHIFT_L(glyphp[22][line],26);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[22][line],6);
+ bits |= SHIFT_L(glyphp[23][line],1);
+ bits |= SHIFT_L(glyphp[24][line],8);
+ bits |= SHIFT_L(glyphp[25][line],15);
+ bits |= SHIFT_L(glyphp[26][line],22);
+ bits |= SHIFT_L(glyphp[27][line],29);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[27][line],3);
+ bits |= SHIFT_L(glyphp[28][line],4);
+ bits |= SHIFT_L(glyphp[29][line],11);
+ bits |= SHIFT_L(glyphp[30][line],18);
+ bits |= SHIFT_L(glyphp[31][line],25);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+#ifndef FIXEDBASE
+ base += 7;
+#endif
+ width -= 224;
+ glyphp += 32;
+ }
+ return base;
+}
+
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth8(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],8);
+ bits |= SHIFT_L(glyphp[2][line],16);
+ bits |= SHIFT_L(glyphp[3][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = glyphp[4][line];
+ bits |= SHIFT_L(glyphp[5][line],8);
+ bits |= SHIFT_L(glyphp[6][line],16);
+ bits |= SHIFT_L(glyphp[7][line],24);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+#ifndef FIXEDBASE
+ base += 2;
+#endif
+ width -= 64;
+ glyphp += 8;
+ }
+ return base;
+}
+#endif
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth9(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],9);
+ bits |= SHIFT_L(glyphp[2][line],18);
+ bits |= SHIFT_L(glyphp[3][line],27);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[3][line],5);
+ bits |= SHIFT_L(glyphp[4][line],4);
+ bits |= SHIFT_L(glyphp[5][line],13);
+ bits |= SHIFT_L(glyphp[6][line],22);
+ bits |= SHIFT_L(glyphp[7][line],31);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[7][line],1);
+ bits |= SHIFT_L(glyphp[8][line],8);
+ bits |= SHIFT_L(glyphp[9][line],17);
+ bits |= SHIFT_L(glyphp[10][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[10][line],6);
+ bits |= SHIFT_L(glyphp[11][line],3);
+ bits |= SHIFT_L(glyphp[12][line],12);
+ bits |= SHIFT_L(glyphp[13][line],21);
+ bits |= SHIFT_L(glyphp[14][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[14][line],2);
+ bits |= SHIFT_L(glyphp[15][line],7);
+ bits |= SHIFT_L(glyphp[16][line],16);
+ bits |= SHIFT_L(glyphp[17][line],25);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[17][line],7);
+ bits |= SHIFT_L(glyphp[18][line],2);
+ bits |= SHIFT_L(glyphp[19][line],11);
+ bits |= SHIFT_L(glyphp[20][line],20);
+ bits |= SHIFT_L(glyphp[21][line],29);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[21][line],3);
+ bits |= SHIFT_L(glyphp[22][line],6);
+ bits |= SHIFT_L(glyphp[23][line],15);
+ bits |= SHIFT_L(glyphp[24][line],24);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+ bits = SHIFT_R(glyphp[24][line],8);
+ bits |= SHIFT_L(glyphp[25][line],1);
+ bits |= SHIFT_L(glyphp[26][line],10);
+ bits |= SHIFT_L(glyphp[27][line],19);
+ bits |= SHIFT_L(glyphp[28][line],28);
+ WRITE_IN_BITORDER(base, 7, bits);
+ CHECKRETURN(8);
+ bits = SHIFT_R(glyphp[28][line],4);
+ bits |= SHIFT_L(glyphp[29][line],5);
+ bits |= SHIFT_L(glyphp[30][line],14);
+ bits |= SHIFT_L(glyphp[31][line],23);
+ WRITE_IN_BITORDER(base, 8, bits);
+ CHECKRETURN(9);
+#ifndef FIXEDBASE
+ base += 9;
+#endif
+ width -= 288;
+ glyphp += 32;
+ }
+ return base;
+}
+#endif
+
+static CARD32*
+DrawTETextScanlineWidth10(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],10);
+ bits |= SHIFT_L(glyphp[2][line],20);
+ bits |= SHIFT_L(glyphp[3][line],30);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[3][line],2);
+ bits |= SHIFT_L(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],18);
+ bits |= SHIFT_L(glyphp[6][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[6][line],4);
+ bits |= SHIFT_L(glyphp[7][line],6);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[9][line],6);
+ bits |= SHIFT_L(glyphp[10][line],4);
+ bits |= SHIFT_L(glyphp[11][line],14);
+ bits |= SHIFT_L(glyphp[12][line],24);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],2);
+ bits |= SHIFT_L(glyphp[14][line],12);
+ bits |= SHIFT_L(glyphp[15][line],22);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+#ifndef FIXEDBASE
+ base += 5;
+#endif
+ width -= 160;
+ glyphp += 16;
+ }
+ return base;
+}
+
+static CARD32*
+DrawTETextScanlineWidth12(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],12);
+ bits |= SHIFT_L(glyphp[2][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[2][line],8);
+ bits |= SHIFT_L(glyphp[3][line],4);
+ bits |= SHIFT_L(glyphp[4][line],16);
+ bits |= SHIFT_L(glyphp[5][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[5][line],4);
+ bits |= SHIFT_L(glyphp[6][line],8);
+ bits |= SHIFT_L(glyphp[7][line],20);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 8;
+ }
+ return base;
+}
+
+
+
+static CARD32*
+DrawTETextScanlineWidth14(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],14);
+ bits |= SHIFT_L(glyphp[2][line],28);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[2][line],4);
+ bits |= SHIFT_L(glyphp[3][line],10);
+ bits |= SHIFT_L(glyphp[4][line],24);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],6);
+ bits |= SHIFT_L(glyphp[6][line],20);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[6][line],12);
+ bits |= SHIFT_L(glyphp[7][line],2);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[9][line],2);
+ bits |= SHIFT_L(glyphp[10][line],12);
+ bits |= SHIFT_L(glyphp[11][line],26);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[11][line],6);
+ bits |= SHIFT_L(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],22);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[13][line],10);
+ bits |= SHIFT_L(glyphp[14][line],4);
+ bits |= SHIFT_L(glyphp[15][line],18);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+#ifndef FIXEDBASE
+ base += 7;
+#endif
+ width -= 224;
+ glyphp += 16;
+ }
+ return base;
+}
+
+
+static CARD32*
+DrawTETextScanlineWidth16(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],16);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = glyphp[2][line];
+ bits |= SHIFT_L(glyphp[3][line],16);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = glyphp[4][line];
+ bits |= SHIFT_L(glyphp[5][line],16);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = glyphp[6][line];
+ bits |= SHIFT_L(glyphp[7][line],16);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+#ifndef FIXEDBASE
+ base += 4;
+#endif
+ width -= 128;
+ glyphp += 8;
+ }
+ return base;
+}
+
+
+
+static CARD32*
+DrawTETextScanlineWidth18(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],18);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[1][line],14);
+ bits |= SHIFT_L(glyphp[2][line],4);
+ bits |= SHIFT_L(glyphp[3][line],22);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[3][line],10);
+ bits |= SHIFT_L(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[5][line],6);
+ bits |= SHIFT_L(glyphp[6][line],12);
+ bits |= SHIFT_L(glyphp[7][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[7][line],2);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],2);
+ bits |= SHIFT_L(glyphp[10][line],20);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[10][line],12);
+ bits |= SHIFT_L(glyphp[11][line],6);
+ bits |= SHIFT_L(glyphp[12][line],24);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+ bits = SHIFT_R(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],10);
+ bits |= SHIFT_L(glyphp[14][line],28);
+ WRITE_IN_BITORDER(base, 7, bits);
+ CHECKRETURN(8);
+ bits = SHIFT_R(glyphp[14][line],4);
+ bits |= SHIFT_L(glyphp[15][line],14);
+ WRITE_IN_BITORDER(base, 8, bits);
+ CHECKRETURN(9);
+#ifndef FIXEDBASE
+ base += 9;
+#endif
+ width -= 288;
+ glyphp += 16;
+ }
+ return base;
+}
+
+
+static CARD32*
+DrawTETextScanlineWidth24(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[1][line],8);
+ bits |= SHIFT_L(glyphp[2][line],16);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[2][line],16);
+ bits |= SHIFT_L(glyphp[3][line],8);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 4;
+ }
+ return base;
+}
+
+
diff --git a/hw/xfree86/xaa/xaaTEGlyphBlt.S b/hw/xfree86/xaa/xaaTEGlyphBlt.S
new file mode 100644
index 000000000..f5c580760
--- /dev/null
+++ b/hw/xfree86/xaa/xaaTEGlyphBlt.S
@@ -0,0 +1,964 @@
+/*
+ * Copyright 1996 The XFree86 Project
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * HARM HANEMAAYER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEGlyphBlt.S,v 1.2 1999/12/27 00:39:52 robin Exp $ */
+
+
+/*
+ * Intel Pentium-optimized versions of "terminal emulator font" text
+ * bitmap transfer routines.
+ *
+ * SCANLINE_PAD_DWORD.
+ *
+ * Only for glyphs with a fixed width of 6 pixels or 8 pixels.
+ */
+
+#include "assyntax.h"
+
+#ifndef QNX4
+ FILE("xaaTEGlyphBlt.s")
+#else
+ FILE( __FILE__ )
+#endif
+
+ AS_BEGIN
+
+/*
+ * Definition of stack frame function arguments.
+ * All functions have the same arguments (some don't have glyphwidth,
+ * but that's OK, since it comes last and doesn't affect the offset
+ * of the other arguments).
+ */
+
+#define base_arg REGOFF(20,ESP)
+#define glyphp_arg REGOFF(24,ESP)
+#define line_arg REGOFF(28,ESP)
+#define width_arg REGOFF(32,ESP)
+#define glyphwidth_arg REGOFF(36,ESP)
+
+#define BYTE_REVERSED GLNAME(byte_reversed)
+
+/* I assume %eax and %edx can be trashed. */
+
+ SEG_TEXT
+
+ ALIGNTEXT4
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth6PMSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth6PMSBFirstFixedBase):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth6PLSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth6PLSBFirstFixedBase):
+# endif
+#else
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth6PMSBFirst)
+GLNAME(DrawTETextScanlineWidth6PMSBFirst):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth6PLSBFirst)
+GLNAME(DrawTETextScanlineWidth6PLSBFirst):
+# endif
+#endif
+
+/* Definition of stack frame function arguments. */
+
+#define base_arg REGOFF(20,ESP)
+#define glyphp_arg REGOFF(24,ESP)
+#define line_arg REGOFF(28,ESP)
+#define width_arg REGOFF(32,ESP)
+
+ SUB_L (CONST(16),ESP)
+ MOV_L (EBP,REGOFF(12,ESP)) /* PUSH EBP */
+ MOV_L (EBX,REGOFF(8,ESP)) /* PUSH EBX */
+ MOV_L (ESI,REGOFF(4,ESP)) /* PUSH ESI */
+ MOV_L (EDI,REGOFF(0,ESP)) /* PUSH EDI */
+
+ MOV_L (line_arg,EBP)
+ MOV_L (base_arg,EDI)
+ MOV_L (glyphp_arg,ESI)
+
+ ALIGNTEXT4
+
+.L6_1:
+ /* Pentium-optimized instruction pairing. */
+ /* EBX = bits = glyph[0][line] */
+ MOV_L (REGOFF(4,ESI),EDX) /* glyphp[1] */
+ MOV_L (REGIND(ESI),EBX) /* glyphp[0] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[1][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[0][line] */
+ SAL_L (CONST(6),EDX) /* glyphp[1][line] << 6 */
+ MOV_L (REGOFF(8,ESI),ECX) /* glyphp[2] */
+ MOV_L (REGOFF(12,ESI),EAX) /* glyphp[3] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[2][line] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[3][line] */
+ SAL_L (CONST(12),ECX) /* glyphp[2][line] << 12 */
+ OR_L (EDX,EBX) /* bits |= ..[1].. << 6 */
+ SAL_L (CONST(18),EAX) /* glyphp[3][line] << 18 */
+ OR_L (ECX,EBX) /* bits |= ..[2].. << 12 */
+
+ MOV_L (REGOFF(16,ESI),EDX) /* glyphp[4] */
+ MOV_L (REGOFF(20,ESI),ECX) /* glyphp[5] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[4][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[5][line] */
+ SAL_L (CONST(24),EDX) /* glyphp[4][line] << 24 */
+ OR_L (EAX,EBX) /* bits |= ..[3].. << 18 */
+ SAL_L (CONST(30),ECX) /* glyphp[5][line] << 30 */
+ OR_L (EDX,EBX) /* bits |= ..[4].. << 24 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(20,ESI),EAX) /* glyphp[5] */
+ OR_L (ECX,EBX) /* bits |= ..[5].. << 30 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[5][line] */
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (CONST(0),EAX)
+ OR_L (ECX,EBX) /* bits |= ..[5].. << 30 */
+ MOV_L (CONST(0),EDX)
+ MOV_B (BL,AL)
+ MOV_B (BH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+ ROL_L (CONST(16),EBX)
+ MOV_B (BL,AL)
+ MOV_B (BH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+ ROL_L (CONST(16),EBX)
+ MOV_L (REGOFF(20,ESI),EAX) /* glyphp[5] */
+ MOV_L (EBX,REGIND(EDI))
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[5][line] */
+#endif
+
+ CMP_L (CONST(32),width_arg)
+ JG (.L6_2)
+#ifndef FIXEDBASE
+ ADD_L (CONST(4),EDI) /* base++ */
+#endif
+ JMP (.L6_4)
+.L6_2:
+ /* Note that glyphp[5][line] is already read again. */
+ /* EAX = bits = glyphp[5][line] >> 2 */
+ MOV_L (REGOFF(24,ESI),EDX) /* glyphp[6] */
+ MOV_L (REGOFF(28,ESI),EBX) /* glyphp[7] */
+ SHR_L (CONST(2),EAX) /* glyphp[5][line] >> 2 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[6][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[7][line] */
+ MOV_L (REGOFF(32,ESI),ECX) /* glyphp[8] */
+ SAL_L (CONST(4),EDX) /* glyphp[6][line] << 4 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[8][line] */
+ SAL_L (CONST(10),EBX) /* glyphp[7][line] << 10 */
+ OR_L (EDX,EAX) /* bits |= ..[6].. << 4 */
+ SAL_L (CONST(16),ECX) /* glyphp[8][line] << 16 */
+ MOV_L (REGOFF(36,ESI),EDX) /* glyphp[9] */
+ OR_L (EBX,EAX) /* bits |= ..[7].. << 10 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[9][line] */
+ OR_L (ECX,EAX) /* bits |= ..[8].. << 16 */
+ MOV_L (REGOFF(40,ESI),EBX) /* glyphp[10] */
+ SAL_L (CONST(22),EDX) /* glyphp[9][line] << 22 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[10][line] */
+ OR_L (EDX,EAX) /* bits |= ..[9].. << 22 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(40,ESI),ECX) /* glyphp[10] */
+ SAL_L (CONST(28),EBX) /* glyphp[10][line] << 28 */
+ MOV_L (REGOFF(44,ESI),EDX) /* glyphp[11] */
+ OR_L (EBX,EAX) /* bits |= ..[10].. << 28 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[10][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[11][line] */
+#else
+ MOV_L (CONST(0),ECX)
+ SAL_L (CONST(28),EBX) /* glyphp[10][line] << 28 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,EAX) /* bits |= ..[10].. << 28 */
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ MOV_L (REGOFF(40,ESI),ECX) /* glyphp[10] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGOFF(44,ESI),EDX) /* glyphp[11] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[10][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[11][line] */
+#endif
+
+ CMP_L (CONST(64),width_arg)
+ JG (.L6_3)
+#ifndef FIXEDBASE
+ ADD_L (CONST(8),EDI) /* base+=2 */
+#endif
+ JMP (.L6_4)
+.L6_3:
+ /* Note that glyphp[10][line] is read again. */
+ /* EAX = bits = glyphp[10][line] >> 4 */
+ SHR_L (CONST(4),ECX) /* glyphp[10][line] >> 4 */
+ MOV_L (REGOFF(48,ESI),EBX) /* glyphp[12] */
+ SAL_L (CONST(2),EDX) /* glyphp[11][line] << 2 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[12][line] */
+ OR_L (EDX,ECX) /* bits |= ..[11].. << 2 */
+ MOV_L (REGOFF(52,ESI),EAX) /* glyphp[13] */
+ SAL_L (CONST(8),EBX) /* glyphp[12][line] << 8 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[13][line] */
+ OR_L (EBX,ECX) /* bits |= ..[12].. << 8 */
+ MOV_L (REGOFF(56,ESI),EDX) /* glyphp[14] */
+ SAL_L (CONST(14),EAX) /* glyphp[13][line] << 14 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[14][line] */
+ OR_L (EAX,ECX) /* bits |= ..[13].. << 14 */
+ MOV_L (REGOFF(60,ESI),EBX) /* glyphp[15] */
+ SAL_L (CONST(20),EDX) /* glyphp[14][line] << 20 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[15][line] */
+ OR_L (EDX,ECX) /* bits |= ..[14].. << 20 */
+
+#ifndef MSBFIRST
+ SAL_L (CONST(26),EBX) /* glyphp[15][line] << 26 */
+ OR_L (EBX,ECX) /* bits |= ..[15].. << 26 */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EAX)
+ SAL_L (CONST(26),EBX) /* glyphp[15][line] << 26 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,ECX) /* bits |= ..[15].. << 26 */
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ ROL_L (CONST(16),ECX)
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ ROL_L (CONST(16),ECX)
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+#ifndef FIXEDBASE
+ ADD_L (CONST(12),EDI) /* base += 3*/
+#endif
+ CMP_L (CONST(96),width_arg)
+ JLE (.L6_4)
+ ADD_L (CONST(64),ESI) /* glyphp += 16 */
+ SUB_L (CONST(96),width_arg)
+ JMP (.L6_1)
+
+.L6_4:
+
+#ifndef FIXEDBASE
+ MOV_L (EDI,EAX) /* return base */
+#else
+ MOV_L (base_arg,EAX) /* return base */
+#endif
+ MOV_L (REGOFF(0,ESP),EDI) /* POPL EDI */
+ MOV_L (REGOFF(4,ESP),ESI) /* POPL ESI */
+ MOV_L (REGOFF(8,ESP),EBX) /* POPL EBX */
+ MOV_L (REGOFF(12,ESP),EBP) /* POPL EBP */
+ ADD_L (CONST(16),ESP)
+ RET
+
+
+ ALIGNTEXT4
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth8PMSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth8PMSBFirstFixedBase):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth8PLSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth8PLSBFirstFixedBase):
+# endif
+#else
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth8PMSBFirst)
+GLNAME(DrawTETextScanlineWidth8PMSBFirst):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth8PLSBFirst)
+GLNAME(DrawTETextScanlineWidth8PLSBFirst):
+# endif
+#endif
+
+ SUB_L (CONST(16),ESP)
+ MOV_L (EBP,REGOFF(12,ESP)) /* PUSH EBP */
+ MOV_L (EBX,REGOFF(8,ESP)) /* PUSH EBX */
+ MOV_L (ESI,REGOFF(4,ESP)) /* PUSH ESI */
+ MOV_L (EDI,REGOFF(0,ESP)) /* PUSH EDI */
+
+ MOV_L (line_arg,EBP)
+ MOV_L (base_arg,EDI)
+ MOV_L (glyphp_arg,ESI)
+
+ ALIGNTEXT4
+
+.L8_1:
+ /* Pentium-optimized instruction pairing. */
+ /* EBX = bits */
+ MOV_L (REGIND(ESI),EAX) /* glyphp[0] */
+ MOV_L (REGOFF(4,ESI),EDX) /* glyphp[1] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[0][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[1][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+#else
+ MOV_L (EAX,EBX) /* bits = glyph[0][line] */
+ MOV_B (DL,BH) /* bits |= ..[1].. << 8 */
+#endif
+
+ ROL_L (CONST(16),EBX)
+ MOV_L (REGOFF(8,ESI),EAX) /* glyphp[2] */
+ MOV_L (REGOFF(12,ESI),ECX) /* glyphp[3] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[2][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[3][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BH)
+#else
+ MOV_B (AL,BL) /* bits |= ..[2].. << 16 */
+ MOV_B (CL,BH) /* bits |= ..[3].. << 24 */
+#endif
+ ROL_L (CONST(16),EBX)
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+ CMP_L (CONST(32),width_arg)
+#ifndef FIXEDBASE
+ JLE (.L8_2)
+#else
+ JLE (.L8_3)
+#endif
+
+ MOV_L (REGOFF(16,ESI),EAX) /* glyphp[4] */
+ MOV_L (REGOFF(20,ESI),EDX) /* glyphp[5] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[4][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[5][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),BH)
+#else
+ MOV_L (EAX,EBX) /* bits = glyph[4][line] */
+ MOV_B (DL,BH) /* nits |= ..[5].. << 8 */
+#endif
+
+ ROL_L (CONST(16),EBX)
+ MOV_L (REGOFF(24,ESI),EAX) /* glyphp[6] */
+ MOV_L (REGOFF(28,ESI),ECX) /* glyphp[7] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[6][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[7][line] */
+#ifdef MSBFIRST
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BH)
+#else
+ MOV_B (AL,BL) /* bits |= ..[6].. << 16 */
+ MOV_B (CL,BH) /* bits |= ..[7].. << 24 */
+#endif
+ ROL_L (CONST(16),EBX)
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base+1, bits) */
+ ADD_L (CONST(8),EDI) /* base += 2 */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ CMP_L (CONST(64),width_arg)
+ JLE (.L8_3)
+ ADD_L (CONST(32),ESI) /* glyphp += 8 */
+ SUB_L (CONST(64),width_arg)
+ JMP (.L8_1)
+
+#ifndef FIXEDBASE
+.L8_2:
+ ADD_L (CONST(4),EDI) /* base++ */
+.L8_3:
+ MOV_L (EDI,EAX) /* return base */
+#else
+.L8_3:
+ MOV_L (base_arg,EAX) /* return base */
+#endif
+ MOV_L (REGOFF(0,ESP),EDI) /* POPL EDI */
+ MOV_L (REGOFF(4,ESP),ESI) /* POPL ESI */
+ MOV_L (REGOFF(8,ESP),EBX) /* POPL EBX */
+ MOV_L (REGOFF(12,ESP),EBP) /* POPL EBP */
+ ADD_L (CONST(16),ESP)
+ RET
+
+ ALIGNTEXT4
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth9PMSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth9PMSBFirstFixedBase):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth9PLSBFirstFixedBase)
+GLNAME(DrawTETextScanlineWidth9PLSBFirstFixedBase):
+# endif
+#else
+# ifdef MSBFIRST
+ GLOBL GLNAME(DrawTETextScanlineWidth9PMSBFirst)
+GLNAME(DrawTETextScanlineWidth9PMSBFirst):
+# else
+ GLOBL GLNAME(DrawTETextScanlineWidth9PLSBFirst)
+GLNAME(DrawTETextScanlineWidth9PLSBFirst):
+# endif
+#endif
+
+ SUB_L (CONST(16),ESP)
+ MOV_L (EBP,REGOFF(12,ESP)) /* PUSH EBP */
+ MOV_L (EBX,REGOFF(8,ESP)) /* PUSH EBX */
+ MOV_L (ESI,REGOFF(4,ESP)) /* PUSH ESI */
+ MOV_L (EDI,REGOFF(0,ESP)) /* PUSH EDI */
+
+ MOV_L (line_arg,EBP)
+ MOV_L (base_arg,EDI)
+ MOV_L (glyphp_arg,ESI)
+
+ ALIGNTEXT4
+
+.L9_1:
+ /* Pentium-optimized instruction pairing. */
+ /* EAX = bits */
+ MOV_L (REGOFF(4,ESI),EBX) /* glyphp[1] */
+ MOV_L (REGIND(ESI),EAX) /* glyphp[0] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[1][line] */
+ MOV_L (REGOFF(8,ESI),ECX) /* glyphp[2] */
+ SAL_L (CONST(9),EBX) /* glyphp[1][line] << 9 */
+ MOV_L (REGOFF(12,ESI),EDX) /* glyphp[3] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[0][line] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[3][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[2][line] */
+ OR_L (EBX,EAX) /* bits |= ..[1].. << 9 */
+ SAL_L (CONST(18),ECX) /* glyphp[2][line] << 18 */
+ OR_L (ECX,EAX) /* bits |= ..[2].. << 18 */
+ SAL_L (CONST(27),EDX) /* glyphp[3][line << 27 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(12,ESI),EBX) /* glyphp[3] */
+ OR_L (EDX,EAX) /* bits |= ..[3].. << 27 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[3][line] */
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (CONST(0),EBX)
+ OR_L (EDX,EAX) /* bits |= ..[3].. << 27 */
+ MOV_L (CONST(0),ECX)
+ MOV_B (AL,BL)
+ MOV_B (AH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,BL)
+ MOV_B (AH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AH)
+ MOV_L (REGOFF(12,ESI),EBX) /* glyphp[3] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[3][line] */
+ MOV_L (EAX,REGIND(EDI))
+#endif
+
+ CMP_L (CONST(32),width_arg)
+ JG (.L9_2)
+#ifndef FIXEDBASE
+ ADD_L (CONST(4),EDI) /* base++ */
+#endif
+ JMP (.L9_11)
+.L9_2:
+ /* Note that glyphp[3][line] is read again. */
+ /* EAX = bits, EBX = glyphp[3][line] >> 5 */
+ SHR_L (CONST(5),EBX) /* glyphp[3][line] >> 5 */
+ MOV_L (REGOFF(16,ESI),EAX) /* glyphp[4] */
+ MOV_L (REGOFF(20,ESI),ECX) /* glyphp[5] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[4][line] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[5][line] */
+ MOV_L (REGOFF(24,ESI),EDX) /* glyphp[6] */
+ SAL_L (CONST(4),EAX) /* glyphp[4][line] << 4 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[6][line] */
+ SAL_L (CONST(13),ECX) /* glyphp[5][line] << 13 */
+ OR_L (EBX,EAX) /* bits |= ..[4].. << 4 */
+ SAL_L (CONST(22),EDX) /* glyphp[6][line] << 22 */
+ MOV_L (REGOFF(28,ESI),EBX) /* glyphp[7] */
+ OR_L (ECX,EAX) /* bits |= ..[5].. << 13 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[7][line] */
+ OR_L (EDX,EAX) /* bits |= ..[6].. << 22 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(28,ESI),ECX) /* glyphp[7] */
+ SAL_L (CONST(31),EBX) /* glyphp[7][line] << 31 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[7][line] */
+ OR_L (EBX,EAX) /* bits |= ..[7].. << 31 */
+ MOV_L (REGOFF(32,ESI),EDX) /* glyphp[8] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),ECX)
+ SAL_L (CONST(31),EBX) /* glyphp[7][line] << 31 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,EAX) /* bits |= ..[7].. << 31 */
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,CL)
+ MOV_B (AH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AH)
+ MOV_L (REGOFF(28,ESI),ECX) /* glyphp[7] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[7][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(4,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGOFF(32,ESI),EDX) /* glyphp[8] */
+#endif
+
+ CMP_L (CONST(64),width_arg)
+ JG (.L9_3)
+#ifndef FIXEDBASE
+ ADD_L (CONST(8),EDI) /* base+=2 */
+#endif
+ JMP (.L9_11)
+.L9_3:
+
+ /* Note that glyphp[7][line] is read again. */
+ /* ECX = bits = glyphp[7][line] >> 1 */
+ SHR_L (CONST(1),ECX) /* glyphp[7][line] >> 1 */
+ MOV_L (REGOFF(36,ESI),EBX) /* glyphp[9] */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[8][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[9][line] */
+ SAL_L (CONST(8),EDX) /* glyphp[8][line] << 8 */
+ MOV_L (REGOFF(40,ESI),EAX) /* glyphp[10] */
+ SAL_L (CONST(17),EBX) /* glyphp[9][line] << 17 */
+ OR_L (EDX,ECX) /* bits |= ..[8].. << 8 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[10][line] */
+ OR_L (EBX,ECX) /* bits |= ..[9].. << 17 */
+ SAL_L (CONST(26),EAX) /* glyphp[10][line] << 26 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(40,ESI),EDX) /* glyphp[10] */
+ OR_L (EAX,ECX) /* bits |= ..[10].. << 26 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[10][line] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EDX)
+ OR_L (EAX,ECX) /* bits |= ..[10].. << 26 */
+ MOV_L (CONST(0),EBX)
+ MOV_B (CL,DL)
+ MOV_B (CH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),CH)
+ ROL_L (CONST(16),ECX)
+ MOV_B (CL,DL)
+ MOV_B (CH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),CH)
+ MOV_L (REGOFF(40,ESI),EDX) /* glyphp[10] */
+ ROL_L (CONST(16),ECX)
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[10][line] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(8,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(96),width_arg)
+ JG (.L9_4)
+#ifndef FIXEDBASE
+ ADD_L (CONST(12),EDI) /* base+=3 */
+#endif
+ JMP (.L9_11)
+.L9_4:
+ /* Note that glyphp[10][line] is read again. */
+ /* EDX = bits = glyphp[10][line] >> 6 */
+ SHR_L (CONST(6),EDX) /* glyphp[10][line] >> 6 */
+ MOV_L (REGOFF(44,ESI),EBX) /* glyphp[11] */
+ MOV_L (REGOFF(48,ESI),EAX) /* glyphp[12] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[11][line] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[12][line] */
+ MOV_L (REGOFF(52,ESI),ECX) /* glyphp[13] */
+ SAL_L (CONST(3),EBX) /* glyphp[11][line] << 3 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[13][line] */
+ SAL_L (CONST(12),EAX) /* glyphp[12][line] << 12 */
+ OR_L (EBX,EDX) /* bits |= ..[11].. << 3 */
+ SAL_L (CONST(21),ECX) /* glyphp[13][line] << 21 */
+ MOV_L (REGOFF(56,ESI),EBX) /* glyphp[14] */
+ OR_L (EAX,EDX) /* bits |= ..[12].. << 17 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[14][line] */
+ SAL_L (CONST(30),EBX) /* glyphp[14][line] << 30 */
+ OR_L (ECX,EDX) /* bits |= ..[13].. << 21 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(56,ESI),EAX) /* glyphp[14] */
+ OR_L (EBX,EDX) /* bits |= ..[14].. << 30 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[14][line] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(12,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EAX)
+ OR_L (EBX,EDX) /* bits |= ..[14].. << 30 */
+ MOV_L (CONST(0),ECX)
+ MOV_B (DL,AL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ ROL_L (CONST(16),EDX)
+ MOV_B (DL,AL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ MOV_L (REGOFF(56,ESI),EAX) /* glyphp[14] */
+ ROL_L (CONST(16),EDX)
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[14][line] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(12,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(128),width_arg)
+ JG (.L9_5)
+#ifndef FIXEDBASE
+ ADD_L (CONST(16),EDI) /* base+=4 */
+#endif
+ JMP (.L9_11)
+.L9_5:
+ /* Note that glyphp[14][line] is read again. */
+ /* EAX = bits = glyphp[14][line] >> 2 */
+ SHR_L (CONST(2),EAX) /* glyphp[14][line] >> 2 */
+ MOV_L (REGOFF(60,ESI),ECX) /* glyphp[15] */
+ MOV_L (REGOFF(64,ESI),EBX) /* glyphp[16] */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[15][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[16][line] */
+ MOV_L (REGOFF(68,ESI),EDX) /* glyphp[17] */
+ SAL_L (CONST(7),ECX) /* glyphp[15][line] << 7 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[17][line] */
+ SAL_L (CONST(16),EBX) /* glyphp[16][line] << 16 */
+ OR_L (ECX,EAX) /* bits |= ..[15].. << 7 */
+ SAL_L (CONST(25),EDX) /* glyphp[17][line] << 25 */
+ OR_L (EBX,EAX) /* bits |= ..[16].. << 16 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(68,ESI),ECX) /* glyphp[17] */
+ OR_L (EDX,EAX) /* bits |= ..[17].. << 25 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[17][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(16,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),ECX)
+ OR_L (EDX,EAX) /* bits |= ..[17].. << 25 */
+ MOV_L (CONST(0),EBX)
+ MOV_B (AL,CL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,CL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ MOV_L (REGOFF(68,ESI),ECX) /* glyphp[17] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[17][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(16,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(160),width_arg)
+ JG (.L9_6)
+#ifndef FIXEDBASE
+ ADD_L (CONST(20),EDI) /* base+=5 */
+#endif
+ JMP (.L9_11)
+.L9_6:
+ /* Note that glyphp[17][line] is read again. */
+ /* ECX = bits = glyphp[17][line] >> 7 */
+ SHR_L (CONST(7),ECX) /* glyphp[17][line] >> 7 */
+ MOV_L (REGOFF(72,ESI),EBX) /* glyphp[18] */
+ MOV_L (REGOFF(76,ESI),EAX) /* glyphp[19] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[18][line] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[19][line] */
+ MOV_L (REGOFF(80,ESI),EDX) /* glyphp[20] */
+ SAL_L (CONST(2),EBX) /* glyphp[18][line] << 2 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[20][line] */
+ SAL_L (CONST(11),EAX) /* glyphp[19][line] << 11 */
+ OR_L (EBX,ECX) /* bits |= ..[18].. << 2 */
+ SAL_L (CONST(20),EDX) /* glyphp[20][line] << 20 */
+ MOV_L (REGOFF(84,ESI),EBX) /* glyphp[21] */
+ OR_L (EAX,ECX) /* bits |= ..[19].. << 11 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[21][line] */
+ OR_L (EDX,ECX) /* bits |= ..[20].. << 20 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(84,ESI),EAX) /* glyphp[21] */
+ SAL_L (CONST(29),EBX) /* glyphp[21][line] << 29 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[21][line] */
+ OR_L (EBX,ECX) /* bits |= ..[14].. << 30 */
+ MOV_L (REGOFF(88,ESI),EDX) /* glyphp[22] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(20,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EAX)
+ SAL_L (CONST(29),EBX) /* glyphp[21][line] << 29 */
+ MOV_L (CONST(0),EDX)
+ OR_L (EBX,ECX) /* bits |= ..[14].. << 30 */
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ ROL_L (CONST(16),ECX)
+ MOV_B (CL,AL)
+ MOV_B (CH,DL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),CH)
+ MOV_L (REGOFF(84,ESI),EAX) /* glyphp[21] */
+ ROL_L (CONST(16),ECX)
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[21][line] */
+#ifndef FIXEDBASE
+ MOV_L (ECX,REGOFF(20,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (ECX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGOFF(88,ESI),EDX) /* glyphp[22] */
+#endif
+
+ CMP_L (CONST(192),width_arg)
+ JG (.L9_7)
+#ifndef FIXEDBASE
+ ADD_L (CONST(24),EDI) /* base+=6 */
+#endif
+ JMP (.L9_11)
+.L9_7:
+ /* Note that glyphp[21][line] is read again. */
+ /* EAX = bits = glyphp[21][line] >> 3 */
+ SHR_L (CONST(3),EAX) /* glyphp[21][line] >> 3 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[22][line] */
+ MOV_L (REGOFF(92,ESI),EBX) /* glyphp[23] */
+ MOV_L (REGOFF(96,ESI),ECX) /* glyphp[24] */
+ SAL_L (CONST(6),EDX) /* glyphp[22][line] << 6 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[23][line] */
+ OR_L (EDX,EAX) /* bits |= ..[22].. << 6 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[24][line] */
+ SAL_L (CONST(15),EBX) /* glyphp[23][line] << 15 */
+ OR_L (EBX,EAX) /* bits |= ..[23].. << 15 */
+ SAL_L (CONST(24),ECX) /* glyphp[24][line] << 24 */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(96,ESI),EDX) /* glyphp[24] */
+ OR_L (ECX,EAX) /* bits |= ..[24].. << 24 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[24][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(24,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EDX)
+ OR_L (ECX,EAX) /* bits |= ..[24].. << 24 */
+ MOV_L (CONST(0),EBX)
+ MOV_B (AL,DL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ ROL_L (CONST(16),EAX)
+ MOV_B (AL,DL)
+ MOV_B (AH,BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EDX),AL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),AH)
+ MOV_L (REGOFF(96,ESI),EDX) /* glyphp[24] */
+ ROL_L (CONST(16),EAX)
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[24][line] */
+#ifndef FIXEDBASE
+ MOV_L (EAX,REGOFF(24,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EAX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ CMP_L (CONST(224),width_arg)
+ JG (.L9_8)
+#ifndef FIXEDBASE
+ ADD_L (CONST(28),EDI) /* base+=7 */
+#endif
+ JMP (.L9_11)
+.L9_8:
+ /* Note that glyphp[24][line] is read again. */
+ /* EDX = bits = glyphp[24][line] >> 8 */
+
+ SHR_L (CONST(8),EDX) /* glyphp[24][line] >> 8 */
+ MOV_L (REGOFF(100,ESI),EAX) /* glyphp[25] */
+ MOV_L (REGOFF(104,ESI),EBX) /* glyphp[26] */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[25][line] */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[26][line] */
+ MOV_L (REGOFF(108,ESI),ECX) /* glyphp[27] */
+ SAL_L (CONST(1),EAX) /* glyphp[25][line] << 1 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[27][line] */
+ SAL_L (CONST(10),EBX) /* glyphp[26][line] << 10 */
+ OR_L (EAX,EDX) /* bits |= ..[25].. << 1 */
+ SAL_L (CONST(19),ECX) /* glyphp[27][line] << 19 */
+ OR_L (EBX,EDX) /* bits |= ..[26].. << 10 */
+ MOV_L (REGOFF(112,ESI),EAX) /* glyphp[28] */
+ OR_L (ECX,EDX) /* bits |= ..[27].. << 19 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[28][line] */
+
+#ifndef MSBFIRST
+ MOV_L (REGOFF(112,ESI),EBX) /* glyphp[28] */
+ SAL_L (CONST(28),EAX) /* glyphp[28][line] << 28 */
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[28][line] */
+ OR_L (EAX,EDX) /* bits |= ..[28].. << 28 */
+ MOV_L (REGOFF(116,ESI),ECX) /* glyphp[29] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(28,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),EBX)
+ SAL_L (CONST(28),EAX) /* glyphp[28][line] << 28 */
+ MOV_L (CONST(0),ECX)
+ OR_L (EAX,EDX) /* bits |= ..[28].. << 28 */
+ MOV_B (DL,BL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ ROL_L (CONST(16),EDX)
+ MOV_B (DL,BL)
+ MOV_B (DH,CL)
+ MOV_B (REGOFF(BYTE_REVERSED,EBX),DL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),DH)
+ MOV_L (REGOFF(112,ESI),EBX) /* glyphp[28] */
+ ROL_L (CONST(16),EDX)
+ MOV_L (REGOFF(116,ESI),ECX) /* glyphp[29] */
+#ifndef FIXEDBASE
+ MOV_L (EDX,REGOFF(28,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EDX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+ MOV_L (REGBISD(EBX,EBP,4,0),EBX) /* glyphp[28][line] */
+#endif
+
+ CMP_L (CONST(256),width_arg)
+ JG (.L9_9)
+#ifndef FIXEDBASE
+ ADD_L (CONST(32),EDI) /* base+=8 */
+#endif
+ JMP (.L9_11)
+.L9_9:
+ /* Note that glyphp[28][line] is read again. */
+ /* EBX = bits = glyphp[28][line] >> 4 */
+ SHR_L (CONST(4),EBX) /* glyphp[28][line] >> 4 */
+ MOV_L (REGBISD(ECX,EBP,4,0),ECX) /* glyphp[29][line] */
+ MOV_L (REGOFF(120,ESI),EAX) /* glyphp[30] */
+ MOV_L (REGOFF(124,ESI),EDX) /* glyphp[31] */
+ SAL_L (CONST(5),ECX) /* glyphp[29][line] << 5 */
+ MOV_L (REGBISD(EAX,EBP,4,0),EAX) /* glyphp[30][line] */
+ OR_L (ECX,EBX) /* bits |= ..[29].. << 5 */
+ MOV_L (REGBISD(EDX,EBP,4,0),EDX) /* glyphp[31][line] */
+ SAL_L (CONST(14),EAX) /* glyphp[30][line] << 14 */
+ ADD_L (CONST(128),ESI) /* glyphp+=32 */
+ SAL_L (CONST(23),EDX) /* glyphp[31][line] << 23 */
+ OR_L (EAX,EBX) /* bits |= ..[30].. << 14 */
+ SUB_L (CONST(288),width_arg) /* width-=288 */
+ OR_L (EDX,EBX) /* bits |= ..[31].. << 23 */
+
+#ifndef MSBFIRST
+#ifndef FIXEDBASE
+ MOV_L (EBX,REGOFF(32,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#else
+ MOV_L (CONST(0),ECX)
+ MOV_L (CONST(0),EAX)
+ MOV_B (BL,CL)
+ MOV_B (BH,AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BH)
+ ROL_L (CONST(16),EBX)
+ MOV_B (BL,CL)
+ MOV_B (BH,AL)
+ MOV_B (REGOFF(BYTE_REVERSED,ECX),BL)
+ MOV_B (REGOFF(BYTE_REVERSED,EAX),BH)
+ ROL_L (CONST(16),EBX)
+#ifndef FIXEDBASE
+ MOV_L (EBX,REGOFF(32,EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#else
+ MOV_L (EBX,REGIND(EDI)) /* WRITE_IN_BIT_ORDER(base, bits) */
+#endif
+#endif
+
+ ADD_L (CONST(36),EDI) /* base+=9 */
+ CMP_L (CONST(0),width_arg)
+ JG (.L9_1)
+
+.L9_11:
+#ifndef FIXEDBASE
+ MOV_L (EDI,EAX) /* return base */
+#else
+ MOV_L (base_arg,EAX) /* return base */
+#endif
+ MOV_L (REGOFF(0,ESP),EDI) /* POPL EDI */
+ MOV_L (REGOFF(4,ESP),ESI) /* POPL ESI */
+ MOV_L (REGOFF(8,ESP),EBX) /* POPL EBX */
+ MOV_L (REGOFF(12,ESP),EBP) /* POPL EBP */
+ ADD_L (CONST(16),ESP)
+ RET
diff --git a/hw/xfree86/xaa/xaaTEText.c b/hw/xfree86/xaa/xaaTEText.c
new file mode 100644
index 000000000..82fa28674
--- /dev/null
+++ b/hw/xfree86/xaa/xaaTEText.c
@@ -0,0 +1,293 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTEText.c,v 1.7 1999/05/30 03:03:33 dawes Exp $ */
+
+/********************************************************************
+
+ In this file we have GC level replacements for PolyText8/16,
+ ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
+ The idea is that everything in this file is device independent.
+ The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
+ which calculates the boxes containing arbitrarily clipped text
+ and passes them to the TEGlyphRenderer which will usually be a lower
+ level XAA function which renders these clipped glyphs using
+ the basic color expansion functions exported by the chipset driver.
+ The TEGlyphRenderer itself may optionally be driver supplied to
+ facilitate work-arounds/optimizations at a higher level than usual.
+
+ v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
+
+
+********************************************************************/
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "font.h"
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+
+static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
+ int yInit, FontPtr font, int fg, int bg, int rop,
+ unsigned int planemask, RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+
+
+/********************************************************************
+
+ GC level replacements for PolyText8/16 and ImageText8/16
+ for TE fonts when using color expansion.
+
+********************************************************************/
+
+
+int
+XAAPolyText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+
+ return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
+}
+
+
+int
+XAAPolyText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+
+ return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
+}
+
+
+void
+XAAImageText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+void
+XAAImageText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+
+/********************************************************************
+
+ GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
+ TE fonts when using color expansion.
+
+********************************************************************/
+
+
+void
+XAAImageGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+void
+XAAPolyGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+
+
+
+/********************************************************************
+
+ XAAGlyphBltTEColorExpansion -
+
+ This guy computes the clipped pieces of text and sends it to
+ the lower-level function which will handle acceleration of
+ arbitrarily clipped text.
+
+********************************************************************/
+
+
+static void
+XAAGlyphBltTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyphs;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge, ytop, ybot;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+ unsigned int **glyphs = NULL;
+ int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
+
+ /* find the size of the box */
+ Left = xInit;
+ Right = Left + (glyphWidth * nglyph);
+ Top = yInit - FONTASCENT(font);
+ Bottom = yInit + FONTDESCENT(font);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom > pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we have something to draw */
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+
+ if((skippix = LeftEdge - Left)) {
+ skipglyphs = skippix/glyphWidth;
+ skippix %= glyphWidth;
+ } else skipglyphs = 0;
+
+ if(!glyphs) {
+ int count;
+ glyphs = (unsigned int**)(infoRec->PreAllocMem);
+
+ for(count = 0; count < nglyph; count++)
+ glyphs[count] = (unsigned int*)
+ FONTGLYPHBITS(gBase,*ppci++);
+
+ /* our new unrolled TE code only writes DWORDS at a time
+ so it can read up to 6 characters past the last one
+ we're displaying */
+ glyphs[count + 0] = glyphs[0];
+ glyphs[count + 1] = glyphs[0];
+ glyphs[count + 2] = glyphs[0];
+ glyphs[count + 3] = glyphs[0];
+ glyphs[count + 4] = glyphs[0];
+ glyphs[count + 5] = glyphs[0];
+ }
+
+ /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
+
+ (*infoRec->TEGlyphRenderer)( pScrn,
+ LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop,
+ skippix, ytop - Top, glyphs + skipglyphs, glyphWidth,
+ fg, bg, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+}
+
+
+
+
diff --git a/hw/xfree86/xaa/xaaTables.c b/hw/xfree86/xaa/xaaTables.c
new file mode 100644
index 000000000..0d2ce760a
--- /dev/null
+++ b/hw/xfree86/xaa/xaaTables.c
@@ -0,0 +1,88 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaTables.c,v 1.2 1998/07/25 16:58:53 dawes Exp $ */
+
+/*
+ * This is a table of 24-bit values, indexed with an 8-bit byte value, then
+ * expands each bit to three consecutive bits. This is required for color
+ * expansion in 24bpp mode with the coprocessor in 8bpp mode, with LSB-first
+ * bit order within a byte.
+ */
+
+unsigned int byte_expand3[256] =
+{
+ 0x000000, 0x000007, 0x000038, 0x00003F, 0x0001C0, 0x0001C7, 0x0001F8, 0x0001FF,
+ 0x000E00, 0x000E07, 0x000E38, 0x000E3F, 0x000FC0, 0x000FC7, 0x000FF8, 0x000FFF,
+ 0x007000, 0x007007, 0x007038, 0x00703F, 0x0071C0, 0x0071C7, 0x0071F8, 0x0071FF,
+ 0x007E00, 0x007E07, 0x007E38, 0x007E3F, 0x007FC0, 0x007FC7, 0x007FF8, 0x007FFF,
+ 0x038000, 0x038007, 0x038038, 0x03803F, 0x0381C0, 0x0381C7, 0x0381F8, 0x0381FF,
+ 0x038E00, 0x038E07, 0x038E38, 0x038E3F, 0x038FC0, 0x038FC7, 0x038FF8, 0x038FFF,
+ 0x03F000, 0x03F007, 0x03F038, 0x03F03F, 0x03F1C0, 0x03F1C7, 0x03F1F8, 0x03F1FF,
+ 0x03FE00, 0x03FE07, 0x03FE38, 0x03FE3F, 0x03FFC0, 0x03FFC7, 0x03FFF8, 0x03FFFF,
+ 0x1C0000, 0x1C0007, 0x1C0038, 0x1C003F, 0x1C01C0, 0x1C01C7, 0x1C01F8, 0x1C01FF,
+ 0x1C0E00, 0x1C0E07, 0x1C0E38, 0x1C0E3F, 0x1C0FC0, 0x1C0FC7, 0x1C0FF8, 0x1C0FFF,
+ 0x1C7000, 0x1C7007, 0x1C7038, 0x1C703F, 0x1C71C0, 0x1C71C7, 0x1C71F8, 0x1C71FF,
+ 0x1C7E00, 0x1C7E07, 0x1C7E38, 0x1C7E3F, 0x1C7FC0, 0x1C7FC7, 0x1C7FF8, 0x1C7FFF,
+ 0x1F8000, 0x1F8007, 0x1F8038, 0x1F803F, 0x1F81C0, 0x1F81C7, 0x1F81F8, 0x1F81FF,
+ 0x1F8E00, 0x1F8E07, 0x1F8E38, 0x1F8E3F, 0x1F8FC0, 0x1F8FC7, 0x1F8FF8, 0x1F8FFF,
+ 0x1FF000, 0x1FF007, 0x1FF038, 0x1FF03F, 0x1FF1C0, 0x1FF1C7, 0x1FF1F8, 0x1FF1FF,
+ 0x1FFE00, 0x1FFE07, 0x1FFE38, 0x1FFE3F, 0x1FFFC0, 0x1FFFC7, 0x1FFFF8, 0x1FFFFF,
+ 0xE00000, 0xE00007, 0xE00038, 0xE0003F, 0xE001C0, 0xE001C7, 0xE001F8, 0xE001FF,
+ 0xE00E00, 0xE00E07, 0xE00E38, 0xE00E3F, 0xE00FC0, 0xE00FC7, 0xE00FF8, 0xE00FFF,
+ 0xE07000, 0xE07007, 0xE07038, 0xE0703F, 0xE071C0, 0xE071C7, 0xE071F8, 0xE071FF,
+ 0xE07E00, 0xE07E07, 0xE07E38, 0xE07E3F, 0xE07FC0, 0xE07FC7, 0xE07FF8, 0xE07FFF,
+ 0xE38000, 0xE38007, 0xE38038, 0xE3803F, 0xE381C0, 0xE381C7, 0xE381F8, 0xE381FF,
+ 0xE38E00, 0xE38E07, 0xE38E38, 0xE38E3F, 0xE38FC0, 0xE38FC7, 0xE38FF8, 0xE38FFF,
+ 0xE3F000, 0xE3F007, 0xE3F038, 0xE3F03F, 0xE3F1C0, 0xE3F1C7, 0xE3F1F8, 0xE3F1FF,
+ 0xE3FE00, 0xE3FE07, 0xE3FE38, 0xE3FE3F, 0xE3FFC0, 0xE3FFC7, 0xE3FFF8, 0xE3FFFF,
+ 0xFC0000, 0xFC0007, 0xFC0038, 0xFC003F, 0xFC01C0, 0xFC01C7, 0xFC01F8, 0xFC01FF,
+ 0xFC0E00, 0xFC0E07, 0xFC0E38, 0xFC0E3F, 0xFC0FC0, 0xFC0FC7, 0xFC0FF8, 0xFC0FFF,
+ 0xFC7000, 0xFC7007, 0xFC7038, 0xFC703F, 0xFC71C0, 0xFC71C7, 0xFC71F8, 0xFC71FF,
+ 0xFC7E00, 0xFC7E07, 0xFC7E38, 0xFC7E3F, 0xFC7FC0, 0xFC7FC7, 0xFC7FF8, 0xFC7FFF,
+ 0xFF8000, 0xFF8007, 0xFF8038, 0xFF803F, 0xFF81C0, 0xFF81C7, 0xFF81F8, 0xFF81FF,
+ 0xFF8E00, 0xFF8E07, 0xFF8E38, 0xFF8E3F, 0xFF8FC0, 0xFF8FC7, 0xFF8FF8, 0xFF8FFF,
+ 0xFFF000, 0xFFF007, 0xFFF038, 0xFFF03F, 0xFFF1C0, 0xFFF1C7, 0xFFF1F8, 0xFFF1FF,
+ 0xFFFE00, 0xFFFE07, 0xFFFE38, 0xFFFE3F, 0xFFFFC0, 0xFFFFC7, 0xFFFFF8, 0xFFFFFF
+};
+
+/*
+ * This is a table of 24-bit values, indexed with an 8-bit byte value,
+ * that reverses the bit order of a byte and then expands each bit to three
+ * consecutive bits. This is required for color expansion in 24bpp mode
+ * with the coprocessor in 8bpp mode, with MSB-first bit order within a
+ * byte.
+ */
+
+unsigned int byte_reversed_expand3[256] =
+{
+ 0x000000, 0x0000E0, 0x00001C, 0x0000FC, 0x008003, 0x0080E3, 0x00801F, 0x0080FF,
+ 0x007000, 0x0070E0, 0x00701C, 0x0070FC, 0x00F003, 0x00F0E3, 0x00F01F, 0x00F0FF,
+ 0x000E00, 0x000EE0, 0x000E1C, 0x000EFC, 0x008E03, 0x008EE3, 0x008E1F, 0x008EFF,
+ 0x007E00, 0x007EE0, 0x007E1C, 0x007EFC, 0x00FE03, 0x00FEE3, 0x00FE1F, 0x00FEFF,
+ 0xC00100, 0xC001E0, 0xC0011C, 0xC001FC, 0xC08103, 0xC081E3, 0xC0811F, 0xC081FF,
+ 0xC07100, 0xC071E0, 0xC0711C, 0xC071FC, 0xC0F103, 0xC0F1E3, 0xC0F11F, 0xC0F1FF,
+ 0xC00F00, 0xC00FE0, 0xC00F1C, 0xC00FFC, 0xC08F03, 0xC08FE3, 0xC08F1F, 0xC08FFF,
+ 0xC07F00, 0xC07FE0, 0xC07F1C, 0xC07FFC, 0xC0FF03, 0xC0FFE3, 0xC0FF1F, 0xC0FFFF,
+ 0x380000, 0x3800E0, 0x38001C, 0x3800FC, 0x388003, 0x3880E3, 0x38801F, 0x3880FF,
+ 0x387000, 0x3870E0, 0x38701C, 0x3870FC, 0x38F003, 0x38F0E3, 0x38F01F, 0x38F0FF,
+ 0x380E00, 0x380EE0, 0x380E1C, 0x380EFC, 0x388E03, 0x388EE3, 0x388E1F, 0x388EFF,
+ 0x387E00, 0x387EE0, 0x387E1C, 0x387EFC, 0x38FE03, 0x38FEE3, 0x38FE1F, 0x38FEFF,
+ 0xF80100, 0xF801E0, 0xF8011C, 0xF801FC, 0xF88103, 0xF881E3, 0xF8811F, 0xF881FF,
+ 0xF87100, 0xF871E0, 0xF8711C, 0xF871FC, 0xF8F103, 0xF8F1E3, 0xF8F11F, 0xF8F1FF,
+ 0xF80F00, 0xF80FE0, 0xF80F1C, 0xF80FFC, 0xF88F03, 0xF88FE3, 0xF88F1F, 0xF88FFF,
+ 0xF87F00, 0xF87FE0, 0xF87F1C, 0xF87FFC, 0xF8FF03, 0xF8FFE3, 0xF8FF1F, 0xF8FFFF,
+ 0x070000, 0x0700E0, 0x07001C, 0x0700FC, 0x078003, 0x0780E3, 0x07801F, 0x0780FF,
+ 0x077000, 0x0770E0, 0x07701C, 0x0770FC, 0x07F003, 0x07F0E3, 0x07F01F, 0x07F0FF,
+ 0x070E00, 0x070EE0, 0x070E1C, 0x070EFC, 0x078E03, 0x078EE3, 0x078E1F, 0x078EFF,
+ 0x077E00, 0x077EE0, 0x077E1C, 0x077EFC, 0x07FE03, 0x07FEE3, 0x07FE1F, 0x07FEFF,
+ 0xC70100, 0xC701E0, 0xC7011C, 0xC701FC, 0xC78103, 0xC781E3, 0xC7811F, 0xC781FF,
+ 0xC77100, 0xC771E0, 0xC7711C, 0xC771FC, 0xC7F103, 0xC7F1E3, 0xC7F11F, 0xC7F1FF,
+ 0xC70F00, 0xC70FE0, 0xC70F1C, 0xC70FFC, 0xC78F03, 0xC78FE3, 0xC78F1F, 0xC78FFF,
+ 0xC77F00, 0xC77FE0, 0xC77F1C, 0xC77FFC, 0xC7FF03, 0xC7FFE3, 0xC7FF1F, 0xC7FFFF,
+ 0x3F0000, 0x3F00E0, 0x3F001C, 0x3F00FC, 0x3F8003, 0x3F80E3, 0x3F801F, 0x3F80FF,
+ 0x3F7000, 0x3F70E0, 0x3F701C, 0x3F70FC, 0x3FF003, 0x3FF0E3, 0x3FF01F, 0x3FF0FF,
+ 0x3F0E00, 0x3F0EE0, 0x3F0E1C, 0x3F0EFC, 0x3F8E03, 0x3F8EE3, 0x3F8E1F, 0x3F8EFF,
+ 0x3F7E00, 0x3F7EE0, 0x3F7E1C, 0x3F7EFC, 0x3FFE03, 0x3FFEE3, 0x3FFE1F, 0x3FFEFF,
+ 0xFF0100, 0xFF01E0, 0xFF011C, 0xFF01FC, 0xFF8103, 0xFF81E3, 0xFF811F, 0xFF81FF,
+ 0xFF7100, 0xFF71E0, 0xFF711C, 0xFF71FC, 0xFFF103, 0xFFF1E3, 0xFFF11F, 0xFFF1FF,
+ 0xFF0F00, 0xFF0FE0, 0xFF0F1C, 0xFF0FFC, 0xFF8F03, 0xFF8FE3, 0xFF8F1F, 0xFF8FFF,
+ 0xFF7F00, 0xFF7FE0, 0xFF7F1C, 0xFF7FFC, 0xFFFF03, 0xFFFFE3, 0xFFFF1F, 0xFFFFFF,
+};
diff --git a/hw/xfree86/xaa/xaaWideLine.c b/hw/xfree86/xaa/xaaWideLine.c
new file mode 100644
index 000000000..7425f9d20
--- /dev/null
+++ b/hw/xfree86/xaa/xaaWideLine.c
@@ -0,0 +1,941 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaaWideLine.c,v 1.10 2001/11/16 16:47:56 dawes Exp $ */
+
+/*
+
+XAAPolylinesWideSolid does not maintain a span list and subsequently does
+not follow the "touch-each-pixel-once" rules for wide lines and arcs.
+This means it can only be used in the case where we have
+miSpansEasyRop(pGC->alu). Since we clip spans on the fly, we
+limited usage of this function to one rect situations. This
+function is used only for solid lines.
+
+ Adapted from miWideLine by Mark Vojkovich (mvojkovi@ucsd.edu)
+Original mi code written by Keith Packard.
+
+*/
+
+#ifndef XFree86LOADER
+#if defined(_XOPEN_SOURCE) || defined(__QNXNTO__)
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for hypot on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+
+#include "X.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "miscstruct.h"
+#include "miwideline.h"
+#include "mi.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+#ifdef ICEILTEMPDECL
+ICEILTEMPDECL
+#endif
+
+#define DRAW_POINT(pScrn, x, y) \
+ if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1); \
+ else XAAPointHelper(pScrn, x, y)
+
+#define FILL_RECT(pScrn, x, y, w, h) \
+ if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h); \
+ else XAAFillRectHelper(pScrn, x, y, w, h)
+
+#define FILL_SPAN(pScrn, x, y, w) \
+ if(hardClip) (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, 1); \
+ else XAASpanHelper(pScrn, x, y, w)
+
+
+#define CLIPSTEPEDGE(edgey,edge,edgeleft) \
+ if (ybase == edgey) { \
+ if (edgeleft) { \
+ if (edge->x > xcl) \
+ xcl = edge->x; \
+ } else { \
+ if (edge->x < xcr) \
+ xcr = edge->x; \
+ } \
+ edgey++; \
+ edge->x += edge->stepx; \
+ edge->e += edge->dx; \
+ if (edge->e > 0) { \
+ edge->x += edge->signdx; \
+ edge->e -= edge->dy; \
+ } \
+ }
+
+static void
+XAAPointHelper(ScrnInfoPtr pScrn, int x, int y)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ BoxPtr extents = infoRec->ClipBox;
+
+ if((x >= extents->x1) && (x < extents->x2) &&
+ (y >= extents->y1) && (y < extents->y2))
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, 1);
+}
+
+static void
+XAAFillRectHelper(ScrnInfoPtr pScrn, int x1, int y1, int dx, int dy)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ BoxPtr extents = infoRec->ClipBox;
+ int x2 = x1 + dx;
+ int y2 = y1 + dy;
+
+ if(x1 < extents->x1) x1 = extents->x1;
+ if(x2 >= extents->x2) x2 = extents->x2;
+ if((dx = x2 - x1)<1) return;
+ if(y1 < extents->y1) y1 = extents->y1;
+ if(y2 >= extents->y2) y2 = extents->y2;
+ if((dy = y2 - y1)<1) return;
+
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x1, y1, dx, dy);
+}
+
+
+static void
+XAASpanHelper(ScrnInfoPtr pScrn, int x1, int y, int width)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ BoxPtr extents = infoRec->ClipBox;
+ int x2;
+
+ if((y < extents->y1) || (y >= extents->y2)) return;
+
+ x2 = x1 + width;
+ if(x1 < extents->x1) x1 = extents->x1;
+ if(x2 > extents->x2) x2 = extents->x2;
+ width = x2 - x1;
+
+ if(width > 0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x1, y, width, 1);
+
+}
+
+#define FixError(x, dx, dy, e, sign, step, h) { \
+ e += (h) * dx; \
+ x += (h) * step; \
+ if(e > 0) { \
+ x += e * sign/dy; \
+ e %= dy; \
+ if(e) { \
+ x += sign; \
+ e -= dy; \
+ } \
+ } \
+}
+
+
+static void
+XAAFillPolyHelper (
+ GCPtr pGC,
+ int y, /* start y coordinate */
+ int overall_height, /* height of entire segment */
+ PolyEdgePtr left, PolyEdgePtr right,
+ int left_count, int right_count )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr extents = infoRec->ClipBox;
+ int left_x, left_e, left_stepx, left_signdx, left_dy, left_dx;
+ int right_x, right_e, right_stepx, right_signdx, right_dy, right_dx;
+ int height, left_height, right_height;
+ int xorg;
+ Bool hardClip;
+
+ if((y >= extents->y2) || ((y + overall_height) <= extents->y1))
+ return;
+
+ /* Muffle compiler */
+ left_x = left_e = left_stepx = left_signdx = left_dy = left_dx = 0;
+ right_x = right_e = right_stepx = right_signdx = right_dy = right_dx = 0;
+
+ left_height = right_height = 0;
+ xorg = 0;
+
+ hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+ while ((left_count || left_height) && (right_count || right_height)) {
+ if (!left_height && left_count) {
+ left_height = left->height;
+ left_x = left->x + xorg;
+ left_stepx = left->stepx;
+ left_signdx = left->signdx;
+ left_e = left->e;
+ left_dy = left->dy;
+ left_dx = left->dx;
+ left_count--;
+ left++;
+ }
+ if (!right_height && right_count) {
+ right_height = right->height;
+ right_x = right->x + xorg + 1;
+ right_stepx = right->stepx;
+ right_signdx = right->signdx;
+ right_e = right->e;
+ right_dy = right->dy;
+ right_dx = right->dx;
+ right_count--;
+ right++;
+ }
+
+ height = (left_height > right_height) ? right_height : left_height;
+
+ left_height -= height;
+ right_height -= height;
+
+ if(hardClip && infoRec->SubsequentSolidFillTrap && (height > 6)) {
+ int right_DX, left_DX;
+
+ right_DX = (right_dx * right_signdx) + (right_stepx * right_dy);
+ left_DX = (left_dx * left_signdx) + (left_stepx * left_dy);
+
+ (*infoRec->SubsequentSolidFillTrap)(infoRec->pScrn, y, height,
+ left_x, left_DX, left_dy, left_e,
+ right_x - 1, right_DX, right_dy, right_e);
+
+ FixError(left_x, left_dx, left_dy, left_e, left_signdx,
+ left_stepx, height);
+ FixError(right_x, right_dx, right_dy, right_e, right_signdx,
+ right_stepx, height);
+ y += height;
+ continue;
+ }
+
+ while (height--) {
+ if(right_x > left_x) {
+ FILL_SPAN(infoRec->pScrn, left_x, y, right_x - left_x);
+ }
+ y++;
+
+ left_x += left_stepx;
+ left_e += left_dx;
+ if (left_e > 0) {
+ left_x += left_signdx;
+ left_e -= left_dy;
+ }
+ right_x += right_stepx;
+ right_e += right_dx;
+ if (right_e > 0) {
+ right_x += right_signdx;
+ right_e -= right_dy;
+ }
+
+ }
+ }
+}
+
+
+
+static void
+XAAWideSegment (
+ GCPtr pGC,
+ int x1, int y1, int x2, int y2,
+ Bool projectLeft, Bool projectRight,
+ LineFacePtr leftFace, LineFacePtr rightFace )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ double l, L, r;
+ double xa, ya;
+ double projectXoff, projectYoff;
+ double k;
+ double maxy;
+ int x, y;
+ int dx, dy;
+ int finaly;
+ PolyEdgePtr left, right;
+ PolyEdgePtr top, bottom;
+ int lefty, righty, topy, bottomy;
+ int signdx;
+ PolyEdgeRec lefts[2], rights[2];
+ LineFacePtr tface;
+ int lw = pGC->lineWidth;
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+ /* draw top-to-bottom always */
+ if ((y2 < y1) || ((y2 == y1) && (x2 < x1))) {
+ x = x1;
+ x1 = x2;
+ x2 = x;
+
+ y = y1;
+ y1 = y2;
+ y2 = y;
+
+ x = projectLeft;
+ projectLeft = projectRight;
+ projectRight = x;
+
+ tface = leftFace;
+ leftFace = rightFace;
+ rightFace = tface;
+ }
+
+ dy = y2 - y1;
+ signdx = 1;
+ dx = x2 - x1;
+ if (dx < 0)
+ signdx = -1;
+
+ leftFace->x = x1;
+ leftFace->y = y1;
+ leftFace->dx = dx;
+ leftFace->dy = dy;
+
+ rightFace->x = x2;
+ rightFace->y = y2;
+ rightFace->dx = -dx;
+ rightFace->dy = -dy;
+
+ if (!dy) {
+ rightFace->xa = 0;
+ rightFace->ya = (double) lw / 2.0;
+ rightFace->k = -(double) (lw * dx) / 2.0;
+ leftFace->xa = 0;
+ leftFace->ya = -rightFace->ya;
+ leftFace->k = rightFace->k;
+ x = x1;
+ if (projectLeft)
+ x -= (lw >> 1);
+ y = y1 - (lw >> 1);
+ dx = x2 - x;
+ if (projectRight)
+ dx += ((lw + 1) >> 1);
+ dy = lw;
+ FILL_RECT(infoRec->pScrn, x, y, dx, dy);
+ } else if (!dx) {
+ leftFace->xa = (double) lw / 2.0;
+ leftFace->ya = 0;
+ leftFace->k = (double) (lw * dy) / 2.0;
+ rightFace->xa = -leftFace->xa;
+ rightFace->ya = 0;
+ rightFace->k = leftFace->k;
+ y = y1;
+ if (projectLeft)
+ y -= lw >> 1;
+ x = x1 - (lw >> 1);
+ dy = y2 - y;
+ if (projectRight)
+ dy += ((lw + 1) >> 1);
+ dx = lw;
+ FILL_RECT(infoRec->pScrn, x, y, dx, dy);
+ } else {
+ l = ((double) lw) / 2.0;
+ L = sqrt((double)(dx*dx + dy*dy));
+
+ if (dx < 0) {
+ right = &rights[1];
+ left = &lefts[0];
+ top = &rights[0];
+ bottom = &lefts[1];
+ } else {
+ right = &rights[0];
+ left = &lefts[1];
+ top = &lefts[0];
+ bottom = &rights[1];
+ }
+ r = l / L;
+
+ /* coord of upper bound at integral y */
+ ya = -r * dx;
+ xa = r * dy;
+
+ projectXoff = -ya;
+ projectYoff = xa;
+
+ /* xa * dy - ya * dx */
+ k = l * L;
+
+ leftFace->xa = xa;
+ leftFace->ya = ya;
+ leftFace->k = k;
+ rightFace->xa = -xa;
+ rightFace->ya = -ya;
+ rightFace->k = k;
+
+ if (projectLeft)
+ righty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 0, right);
+ else
+ righty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 0, right);
+
+ /* coord of lower bound at integral y */
+ ya = -ya;
+ xa = -xa;
+
+ /* xa * dy - ya * dx */
+ k = - k;
+
+ if (projectLeft)
+ lefty = miPolyBuildEdge (xa - projectXoff, ya - projectYoff,
+ k, dx, dy, x1, y1, 1, left);
+ else
+ lefty = miPolyBuildEdge (xa, ya,
+ k, dx, dy, x1, y1, 1, left);
+
+ /* coord of top face at integral y */
+
+ if (signdx > 0) {
+ ya = -ya;
+ xa = -xa;
+ }
+
+ if (projectLeft) {
+ double xap = xa - projectXoff;
+ double yap = ya - projectYoff;
+ topy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x1, y1, dx > 0, top);
+ }
+ else
+ topy = miPolyBuildEdge(xa, ya, 0.0,
+ -dy, dx, x1, y1, dx > 0, top);
+
+ /* coord of bottom face at integral y */
+
+ if (projectRight) {
+ double xap = xa + projectXoff;
+ double yap = ya + projectYoff;
+ bottomy = miPolyBuildEdge (xap, yap, xap * dx + yap * dy,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya + projectYoff;
+ } else {
+ bottomy = miPolyBuildEdge (xa, ya, 0.0,
+ -dy, dx, x2, y2, dx < 0, bottom);
+ maxy = -ya;
+ }
+
+ finaly = ICEIL (maxy) + y2;
+
+ if (dx < 0) {
+ left->height = bottomy - lefty;
+ right->height = finaly - righty;
+ top->height = righty - topy;
+ } else {
+ right->height = bottomy - righty;
+ left->height = finaly - lefty;
+ top->height = lefty - topy;
+ }
+ bottom->height = finaly - bottomy;
+ XAAFillPolyHelper (pGC, topy,
+ bottom->height + bottomy - topy, lefts, rights, 2, 2);
+ }
+}
+
+
+static void
+XAALineArcI (GCPtr pGC, int xorg, int yorg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int x, y, e, ex;
+ int slw = pGC->lineWidth;
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+ y = (slw >> 1) + 1;
+ if (slw & 1)
+ e = - ((y << 2) + 3);
+ else
+ e = - (y << 3);
+ ex = -4;
+ x = 0;
+ while (y) {
+ e += (y << 3) - 4;
+ while (e >= 0) {
+ x++;
+ e += (ex = -((x << 3) + 4));
+ }
+ y--;
+ slw = (x << 1) + 1;
+ if ((e == ex) && (slw > 1))
+ slw--;
+
+ FILL_SPAN(infoRec->pScrn, xorg - x, yorg - y, slw);
+
+ if ((y != 0) && ((slw > 1) || (e != ex))) {
+ FILL_SPAN(infoRec->pScrn, xorg - x, yorg + y, slw);
+ }
+ }
+}
+
+
+static void
+XAALineArcD (
+ GCPtr pGC,
+ double xorg,
+ double yorg,
+ PolyEdgePtr edge1,
+ int edgey1,
+ Bool edgeleft1,
+ PolyEdgePtr edge2,
+ int edgey2,
+ Bool edgeleft2 )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ double radius, x0, y0, el, er, yk, xlk, xrk, k;
+ int xbase, ybase, y, boty, xl, xr, xcl, xcr;
+ int ymin, ymax;
+ Bool edge1IsMin, edge2IsMin;
+ int ymin1, ymin2;
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+
+
+ xbase = floor(xorg);
+ x0 = xorg - xbase;
+ ybase = ICEIL (yorg);
+ y0 = yorg - ybase;
+
+ xlk = x0 + x0 + 1.0;
+ xrk = x0 + x0 - 1.0;
+ yk = y0 + y0 - 1.0;
+ radius = ((double)pGC->lineWidth) / 2.0;
+ y = floor(radius - y0 + 1.0);
+ ybase -= y;
+ ymin = ybase;
+ ymax = 65536;
+ edge1IsMin = FALSE;
+ ymin1 = edgey1;
+ if (edge1->dy >= 0) {
+ if (!edge1->dy) {
+ if (edgeleft1)
+ edge1IsMin = TRUE;
+ else
+ ymax = edgey1;
+ edgey1 = 65536;
+ } else if ((edge1->signdx < 0) == edgeleft1)
+ edge1IsMin = TRUE;
+ }
+ edge2IsMin = FALSE;
+ ymin2 = edgey2;
+ if (edge2->dy >= 0) {
+ if (!edge2->dy) {
+ if (edgeleft2)
+ edge2IsMin = TRUE;
+ else
+ ymax = edgey2;
+ edgey2 = 65536;
+ } else if ((edge2->signdx < 0) == edgeleft2)
+ edge2IsMin = TRUE;
+ }
+ if (edge1IsMin) {
+ ymin = ymin1;
+ if (edge2IsMin && (ymin1 > ymin2))
+ ymin = ymin2;
+ } else if (edge2IsMin)
+ ymin = ymin2;
+ el = radius * radius - ((y + y0) * (y + y0)) - (x0 * x0);
+ er = el + xrk;
+ xl = 1;
+ xr = 0;
+ if (x0 < 0.5) {
+ xl = 0;
+ el -= xlk;
+ }
+ boty = (y0 < -0.5) ? 1 : 0;
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty) {
+ k = (y << 1) + yk;
+ er += k;
+ while (er > 0.0) {
+ xr++;
+ er += xrk - (xr << 1);
+ }
+ el += k;
+ while (el >= 0.0) {
+ xl--;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if(xcr >= xcl) {
+ FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
+ }
+ }
+ er = xrk - (xr << 1) - er;
+ el = (xl << 1) - xlk - el;
+ boty = floor(-y0 - radius + 1.0);
+ if (ybase + y - boty > ymax)
+ boty = ymax - ybase - y;
+ while (y > boty) {
+ k = (y << 1) + yk;
+ er -= k;
+ while ((er >= 0.0) && (xr >= 0)) {
+ xr--;
+ er += xrk - (xr << 1);
+ }
+ el -= k;
+ while ((el > 0.0) && (xl <= 0)) {
+ xl++;
+ el += (xl << 1) - xlk;
+ }
+ y--;
+ ybase++;
+ if (ybase < ymin)
+ continue;
+ xcl = xl + xbase;
+ xcr = xr + xbase;
+ CLIPSTEPEDGE(edgey1, edge1, edgeleft1);
+ CLIPSTEPEDGE(edgey2, edge2, edgeleft2);
+ if(xcr >= xcl) {
+ FILL_SPAN(infoRec->pScrn, xcl, ybase, xcr - xcl + 1);
+ }
+ }
+}
+
+
+static void
+XAALineArc (
+ GCPtr pGC,
+ LineFacePtr leftFace,
+ LineFacePtr rightFace,
+ double xorg,
+ double yorg,
+ Bool isInt )
+{
+ int xorgi, yorgi;
+ PolyEdgeRec edge1, edge2;
+ int edgey1, edgey2;
+ Bool edgeleft1, edgeleft2;
+
+ if (isInt) {
+ xorgi = leftFace ? leftFace->x : rightFace->x;
+ yorgi = leftFace ? leftFace->y : rightFace->y;
+ } else { /* Muffle compiler */
+ xorgi = yorgi = 0;
+ }
+ edgey1 = 65536;
+ edgey2 = 65536;
+ edge1.x = 0; /* not used, keep memory checkers happy */
+ edge1.dy = -1;
+ edge2.x = 0; /* not used, keep memory checkers happy */
+ edge2.dy = -1;
+ edgeleft1 = FALSE;
+ edgeleft2 = FALSE;
+
+ if ((pGC->lineWidth > 2) &&
+ ((pGC->capStyle == CapRound && pGC->joinStyle != JoinRound) ||
+ (pGC->joinStyle == JoinRound && pGC->capStyle == CapButt))) {
+ if (isInt) {
+ xorg = (double) xorgi;
+ yorg = (double) yorgi;
+ }
+
+ if (leftFace && rightFace)
+ miRoundJoinClip (leftFace, rightFace, &edge1, &edge2,
+ &edgey1, &edgey2, &edgeleft1, &edgeleft2);
+ else if (leftFace)
+ edgey1 = miRoundCapClip (leftFace, isInt, &edge1, &edgeleft1);
+ else if (rightFace)
+ edgey2 = miRoundCapClip (rightFace, isInt, &edge2, &edgeleft2);
+
+ isInt = FALSE;
+ }
+
+ if (isInt) {
+ if(pGC->lineWidth == 1) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+ DRAW_POINT(infoRec->pScrn, xorgi, yorgi);
+ } else
+ XAALineArcI(pGC, xorgi, yorgi);
+ } else
+ XAALineArcD(pGC, xorg, yorg, &edge1, edgey1, edgeleft1,
+ &edge2, edgey2, edgeleft2);
+
+}
+
+
+static void
+XAALineJoin (
+ GCPtr pGC,
+ LineFacePtr pLeft,
+ LineFacePtr pRight )
+{
+ double mx = 0, my = 0;
+ double denom = 0;
+ PolyVertexRec vertices[4];
+ PolySlopeRec slopes[4];
+ int edgecount;
+ PolyEdgeRec left[4], right[4];
+ int nleft, nright;
+ int y, height;
+ int swapslopes;
+ int joinStyle = pGC->joinStyle;
+ int lw = pGC->lineWidth;
+
+ if (lw == 1) {
+ /* Lines going in the same direction have no join */
+ if ((pLeft->dx >= 0) == (pRight->dx <= 0))
+ return;
+ if (joinStyle != JoinRound) {
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
+ (double)pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+ if (joinStyle != JoinMiter) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ Bool hardClip = (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL);
+ DRAW_POINT(infoRec->pScrn, pLeft->x, pLeft->y);
+ return;
+ }
+ } else {
+ if (joinStyle == JoinRound) {
+ XAALineArc(pGC, pLeft, pRight,(double)0.0, (double)0.0, TRUE);
+ return;
+ }
+ denom = - pLeft->dx * (double)pRight->dy + pRight->dx *
+ (double)pLeft->dy;
+ if (denom == 0.0)
+ return; /* no join to draw */
+ }
+
+ swapslopes = 0;
+ if (denom > 0) {
+ pLeft->xa = -pLeft->xa;
+ pLeft->ya = -pLeft->ya;
+ pLeft->dx = -pLeft->dx;
+ pLeft->dy = -pLeft->dy;
+ } else {
+ swapslopes = 1;
+ pRight->xa = -pRight->xa;
+ pRight->ya = -pRight->ya;
+ pRight->dx = -pRight->dx;
+ pRight->dy = -pRight->dy;
+ }
+
+ vertices[0].x = pRight->xa;
+ vertices[0].y = pRight->ya;
+ slopes[0].dx = -pRight->dy;
+ slopes[0].dy = pRight->dx;
+ slopes[0].k = 0;
+
+ vertices[1].x = 0;
+ vertices[1].y = 0;
+ slopes[1].dx = pLeft->dy;
+ slopes[1].dy = -pLeft->dx;
+ slopes[1].k = 0;
+
+ vertices[2].x = pLeft->xa;
+ vertices[2].y = pLeft->ya;
+
+ if (joinStyle == JoinMiter) {
+ my = (pLeft->dy * (pRight->xa * pRight->dy - pRight->ya * pRight->dx) -
+ pRight->dy * (pLeft->xa * pLeft->dy - pLeft->ya * pLeft->dx ))/
+ denom;
+ if (pLeft->dy != 0)
+ mx = pLeft->xa + (my - pLeft->ya) *
+ (double) pLeft->dx / (double) pLeft->dy;
+ else
+ mx = pRight->xa + (my - pRight->ya) *
+ (double) pRight->dx / (double) pRight->dy;
+
+ /* check miter limit */
+ if ((mx * mx + my * my) * 4 > SQSECANT * lw * lw)
+ joinStyle = JoinBevel;
+ }
+
+ if (joinStyle == JoinMiter) {
+ slopes[2].dx = pLeft->dx;
+ slopes[2].dy = pLeft->dy;
+ slopes[2].k = pLeft->k;
+ if (swapslopes) {
+ slopes[2].dx = -slopes[2].dx;
+ slopes[2].dy = -slopes[2].dy;
+ slopes[2].k = -slopes[2].k;
+ }
+ vertices[3].x = mx;
+ vertices[3].y = my;
+ slopes[3].dx = pRight->dx;
+ slopes[3].dy = pRight->dy;
+ slopes[3].k = pRight->k;
+ if (swapslopes) {
+ slopes[3].dx = -slopes[3].dx;
+ slopes[3].dy = -slopes[3].dy;
+ slopes[3].k = -slopes[3].k;
+ }
+ edgecount = 4;
+ } else {
+ double scale, dx, dy, adx, ady;
+
+ adx = dx = pRight->xa - pLeft->xa;
+ ady = dy = pRight->ya - pLeft->ya;
+ if (adx < 0)
+ adx = -adx;
+ if (ady < 0)
+ ady = -ady;
+ scale = ady;
+ if (adx > ady)
+ scale = adx;
+ slopes[2].dx = (dx * 65536) / scale;
+ slopes[2].dy = (dy * 65536) / scale;
+ slopes[2].k = ((pLeft->xa + pRight->xa) * slopes[2].dy -
+ (pLeft->ya + pRight->ya) * slopes[2].dx) / 2.0;
+ edgecount = 3;
+ }
+
+ y = miPolyBuildPoly (vertices, slopes, edgecount, pLeft->x, pLeft->y,
+ left, right, &nleft, &nright, &height);
+ XAAFillPolyHelper(pGC, y, height, left, right, nleft, nright);
+}
+
+
+void
+XAAPolylinesWideSolid (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int x1, y1, x2, y2;
+ Bool projectLeft, projectRight;
+ LineFaceRec leftFace, rightFace, prevRightFace, firstFace;
+ int first = TRUE;
+ Bool somethingDrawn = FALSE;
+ Bool selfJoin = FALSE;
+ int xorg = pDrawable->x;
+ int yorg = pDrawable->y;
+ Bool hardClip = FALSE;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ if(REGION_NUM_RECTS(pGC->pCompositeClip) != 1) {
+ miWideLine(pDrawable, pGC, mode, npt, pPts);
+ return;
+ }
+
+ if (mode == CoordModePrevious) {
+ pPts->x += xorg;
+ pPts->y += yorg;
+ } else if(xorg | yorg) {
+ register int n = npt;
+ register DDXPointPtr pts = pPts;
+
+ while(n--) {
+ pts->x += xorg;
+ pts->y += yorg;
+ pts++;
+ }
+ }
+
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (npt > 1) {
+ if (mode == CoordModePrevious) {
+ int nptTmp;
+ register DDXPointPtr pPtsTmp;
+
+ x1 = x2;
+ y1 = y2;
+ nptTmp = npt;
+ pPtsTmp = pPts + 1;
+ while (--nptTmp) {
+ x1 += pPtsTmp->x;
+ y1 += pPtsTmp->y;
+ ++pPtsTmp;
+ }
+ if ((x2 == x1) && (y2 == y1))
+ selfJoin = TRUE;
+ } else if ((x2 == pPts[npt-1].x) && (y2 == pPts[npt-1].y))
+ selfJoin = TRUE;
+ }
+
+ projectLeft = ((pGC->capStyle == CapProjecting) && !selfJoin);
+ projectRight = FALSE;
+
+ (*infoRec->SetupForSolidFill)(infoRec->pScrn, pGC->fgPixel, pGC->alu,
+ pGC->planemask);
+
+ infoRec->ClipBox = &pGC->pCompositeClip->extents;
+
+ if(infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_FILL) {
+ hardClip = TRUE;
+ (*infoRec->SetClippingRectangle)(infoRec->pScrn,
+ infoRec->ClipBox->x1, infoRec->ClipBox->y1,
+ infoRec->ClipBox->x2 - 1, infoRec->ClipBox->y2 - 1);
+ }
+
+ while (--npt) {
+ x1 = x2;
+ y1 = y2;
+ ++pPts;
+ x2 = pPts->x;
+ y2 = pPts->y;
+ if (mode == CoordModePrevious) {
+ x2 += x1;
+ y2 += y1;
+ }
+ if ((x1 != x2) || (y1 != y2)) {
+ somethingDrawn = TRUE;
+ if ((npt == 1) && (pGC->capStyle == CapProjecting) && !selfJoin)
+ projectRight = TRUE;
+ XAAWideSegment(pGC, x1, y1, x2, y2,
+ projectLeft, projectRight, &leftFace, &rightFace);
+ if (first) {
+ if (selfJoin)
+ firstFace = leftFace;
+ else if (pGC->capStyle == CapRound) {
+ if (pGC->lineWidth == 1) {
+ DRAW_POINT(infoRec->pScrn, x1, y1);
+ } else
+ XAALineArc(pGC,&leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0,TRUE);
+ }
+ } else
+ XAALineJoin (pGC, &leftFace, &prevRightFace);
+
+ prevRightFace = rightFace;
+ first = FALSE;
+ projectLeft = FALSE;
+ }
+ if (npt == 1 && somethingDrawn) {
+ if (selfJoin)
+ XAALineJoin (pGC, &firstFace, &rightFace);
+ else if (pGC->capStyle == CapRound) {
+ if (pGC->lineWidth == 1) {
+ DRAW_POINT(infoRec->pScrn, x2, y2);
+ } else
+ XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0,TRUE);
+ }
+ }
+ }
+ /* handle crock where all points are coincedent */
+ if (!somethingDrawn) {
+ projectLeft = (pGC->capStyle == CapProjecting);
+ XAAWideSegment (pGC, x2, y2, x2, y2, projectLeft, projectLeft,
+ &leftFace, &rightFace);
+ if (pGC->capStyle == CapRound) {
+ XAALineArc (pGC, &leftFace, (LineFacePtr) NULL,
+ (double)0.0, (double)0.0, TRUE);
+ rightFace.dx = -1; /* sleezy hack to make it work */
+ XAALineArc (pGC, (LineFacePtr) NULL, &rightFace,
+ (double)0.0, (double)0.0, TRUE);
+ }
+ }
+
+ infoRec->ClipBox = NULL;
+ if(hardClip)
+ (*infoRec->DisableClipping)(infoRec->pScrn);
+
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/hw/xfree86/xaa/xaacexp.h b/hw/xfree86/xaa/xaacexp.h
new file mode 100644
index 000000000..276f01672
--- /dev/null
+++ b/hw/xfree86/xaa/xaacexp.h
@@ -0,0 +1,124 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaacexp.h,v 1.5 2000/06/13 02:51:25 mvojkovi Exp $ */
+
+
+#include "Xarch.h"
+
+#ifndef FIXEDBASE
+#define CHECKRETURN(b) if(width <= ((b) * 32)) return(base + (b))
+#else
+#define CHECKRETURN(b) if(width <= ((b) * 32)) return(base)
+#endif
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+# define SHIFT_L(value, shift) ((value) >> (shift))
+# define SHIFT_R(value, shift) ((value) << (shift))
+#else
+# define SHIFT_L(value, shift) ((value) << (shift))
+# define SHIFT_R(value, shift) ((value) >> (shift))
+#endif
+
+#ifndef MSBFIRST
+# ifdef FIXEDBASE
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest) = data;
+# else
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest + offset) = data;
+# endif
+#else
+# ifdef FIXEDBASE
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest) = SWAP_BITS_IN_BYTES(data);
+# else
+# define WRITE_IN_BITORDER(dest, offset, data) *(dest + offset) = SWAP_BITS_IN_BYTES(data)
+# endif
+#endif
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+# define WRITE_BITS(b) *base = SWAP_BITS_IN_BYTES(b)
+# define WRITE_BITS1(b) { \
+ *base = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *base = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; }
+# define WRITE_BITS3(b) { \
+ *base = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *base = byte_reversed_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_reversed_expand3[((b) & 0xFF000000) >> 24] << 8; }
+# else
+# define WRITE_BITS(b) *base = (b)
+# define WRITE_BITS1(b) { \
+ *base = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *base = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; }
+# define WRITE_BITS3(b) { \
+ *base = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *base = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *base = byte_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_expand3[((b) & 0xFF000000) >> 24] << 8; }
+# endif
+#else
+# ifdef MSBFIRST
+# define WRITE_BITS(b) *(base++) = SWAP_BITS_IN_BYTES(b)
+# define WRITE_BITS1(b) { \
+ *(base++) = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *(base) = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ base += 2; }
+# define WRITE_BITS3(b) { \
+ *(base) = byte_reversed_expand3[(b) & 0xFF] | \
+ byte_reversed_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_reversed_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_reversed_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *(base + 2) = byte_reversed_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_reversed_expand3[((b) & 0xFF000000) >> 24] << 8; \
+ base += 3; }
+# else
+# define WRITE_BITS(b) *(base++) = (b)
+# define WRITE_BITS1(b) { \
+ *(base++) = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; }
+# define WRITE_BITS2(b) { \
+ *(base) = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ base += 2; }
+# define WRITE_BITS3(b) { \
+ *(base) = byte_expand3[(b) & 0xFF] | \
+ byte_expand3[((b) & 0xFF00) >> 8] << 24; \
+ *(base + 1) = byte_expand3[((b) & 0xFF00) >> 8] >> 8 | \
+ byte_expand3[((b) & 0xFF0000) >> 16] << 16; \
+ *(base + 2) = byte_expand3[((b) & 0xFF0000) >> 16] >> 16 | \
+ byte_expand3[((b) & 0xFF000000) >> 24] << 8; \
+ base += 3; }
+# endif
+#endif
+
+#ifdef FIXEDBASE
+# ifdef MSBFIRST
+# define EXPNAME(x) x##MSBFirstFixedBase
+# else
+# define EXPNAME(x) x##LSBFirstFixedBase
+# endif
+#else
+# ifdef MSBFIRST
+# define EXPNAME(x) x##MSBFirst
+# else
+# define EXPNAME(x) x##LSBFirst
+# endif
+#endif
diff --git a/hw/xfree86/xaa/xaalocal.h b/hw/xfree86/xaa/xaalocal.h
new file mode 100644
index 000000000..0c239c234
--- /dev/null
+++ b/hw/xfree86/xaa/xaalocal.h
@@ -0,0 +1,1756 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaalocal.h,v 1.36 2003/02/17 16:08:29 dawes Exp $ */
+
+#ifndef _XAALOCAL_H
+#define _XAALOCAL_H
+
+/* This file is very unorganized ! */
+
+
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+#include "xaa.h"
+#include "mi.h"
+#ifdef RENDER
+#include "picturestr.h"
+#endif
+
+#define GCWhenForced (GCArcMode << 1)
+
+#define DO_COLOR_8x8 0x00000001
+#define DO_MONO_8x8 0x00000002
+#define DO_CACHE_BLT 0x00000003
+#define DO_COLOR_EXPAND 0x00000004
+#define DO_CACHE_EXPAND 0x00000005
+#define DO_IMAGE_WRITE 0x00000006
+#define DO_PIXMAP_COPY 0x00000007
+#define DO_SOLID 0x00000008
+
+
+typedef CARD32 * (*GlyphScanlineFuncPtr)(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+typedef CARD32 *(*StippleScanlineProcPtr)(CARD32*, CARD32*, int, int, int);
+
+typedef void (*RectFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
+ XAACacheInfoPtr);
+typedef void (*TrapFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
+ int, int, int, int, int, int,
+ XAACacheInfoPtr);
+
+
+
+typedef struct _XAAScreen {
+ CreateGCProcPtr CreateGC;
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ PaintWindowBackgroundProcPtr PaintWindowBackground;
+ PaintWindowBorderProcPtr PaintWindowBorder;
+ CopyWindowProcPtr CopyWindow;
+ WindowExposuresProcPtr WindowExposures;
+ BSFuncRec BackingStoreFuncs;
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ XAAInfoRecPtr AccelInfoRec;
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ int (*SetDGAMode)(int, int, DGADevicePtr);
+ void (*EnableDisableFBAccess)(int, Bool);
+#ifdef RENDER
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+#endif
+} XAAScreenRec, *XAAScreenPtr;
+
+#define OPS_ARE_PIXMAP 0x00000001
+#define OPS_ARE_ACCEL 0x00000002
+
+typedef struct _XAAGC {
+ GCOps *wrapOps;
+ GCFuncs *wrapFuncs;
+ GCOps *XAAOps;
+ int DashLength;
+ unsigned char* DashPattern;
+ unsigned long changes;
+ unsigned long flags;
+} XAAGCRec, *XAAGCPtr;
+
+#define REDUCIBILITY_CHECKED 0x00000001
+#define REDUCIBLE_TO_8x8 0x00000002
+#define REDUCIBLE_TO_2_COLOR 0x00000004
+#define DIRTY 0x00010000
+#define OFFSCREEN 0x00020000
+#define DGA_PIXMAP 0x00040000
+#define SHARED_PIXMAP 0x00080000
+#define LOCKED_PIXMAP 0x00100000
+
+#define REDUCIBILITY_MASK \
+ (REDUCIBILITY_CHECKED | REDUCIBLE_TO_8x8 | REDUCIBLE_TO_2_COLOR)
+
+typedef struct _XAAPixmap {
+ unsigned long flags;
+ CARD32 pattern0;
+ CARD32 pattern1;
+ int fg;
+ int bg;
+ FBAreaPtr offscreenArea;
+ Bool freeData;
+} XAAPixmapRec, *XAAPixmapPtr;
+
+
+Bool
+XAACreateGC(
+ GCPtr pGC
+);
+
+Bool
+XAAInitAccel(
+ ScreenPtr pScreen,
+ XAAInfoRecPtr infoRec
+);
+
+RegionPtr
+XAABitBlt(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
+ unsigned long bitPlane
+);
+
+void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir,
+ int ydir,
+ int alu,
+ unsigned int planemask
+);
+
+void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+void
+XAADoImageRead(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+void
+XAACopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+
+RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty
+);
+
+void
+XAAValidateCopyArea(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePutImage(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidateCopyPlane(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePushPixels(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidateFillSpans(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePolyGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidateImageGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+void
+XAAValidatePolylines(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+
+RegionPtr
+XAACopyPlaneColorExpansion(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane
+);
+
+
+void
+XAAPushPixelsSolidColorExpansion(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg
+);
+
+void
+XAAWriteBitmapColorExpandMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpandMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpandLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpandLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapColorExpand3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+
+void
+XAAWriteBitmapScanlineColorExpandMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpandMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpandLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpandLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWriteBitmapScanlineColorExpand3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+void
+XAAWritePixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+
+void
+XAAWritePixmapScanline (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+
+typedef void (*ClipAndRenderRectsFunc)(GCPtr, int, BoxPtr, int, int);
+
+
+void
+XAAClipAndRenderRects(
+ GCPtr pGC,
+ ClipAndRenderRectsFunc func,
+ int nrectFill,
+ xRectangle *prectInit,
+ int xorg, int yorg
+);
+
+
+typedef void (*ClipAndRenderSpansFunc)(GCPtr, int, DDXPointPtr, int*,
+ int, int, int);
+
+void
+XAAClipAndRenderSpans(
+ GCPtr pGC,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted,
+ ClipAndRenderSpansFunc func,
+ int xorg,
+ int yorg
+);
+
+
+void
+XAAFillSolidRects(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox
+);
+
+void
+XAAFillMono8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+);
+
+void
+XAAFillMono8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+);
+
+
+void
+XAAFillColor8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAFillColor8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAFillCacheExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillImageWriteRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+);
+
+
+void
+XAATEGlyphRendererMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRenderer3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRenderer3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+void
+XAATEGlyphRenderer3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRenderer3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+void
+XAATEGlyphRendererScanlineMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererScanline3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererScanlineLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+void
+XAATEGlyphRendererScanline3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+extern CARD32 *(*XAAGlyphScanlineFuncMSBFirstFixedBase[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern CARD32 *(*XAAGlyphScanlineFuncMSBFirst[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern CARD32 *(*XAAGlyphScanlineFuncLSBFirstFixedBase[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern CARD32 *(*XAAGlyphScanlineFuncLSBFirst[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+void
+XAAFillColorExpandRectsLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRects3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRectsLSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRects3LSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRectsMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRects3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRectsMSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandRects3MSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandRectsLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandRects3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandRectsMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandRects3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpansLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpans3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpansLSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpans3LSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpansMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpans3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpansMSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillColorExpandSpans3MSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandSpansLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandSpans3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+void
+XAAFillScanlineColorExpandSpansMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillScanlineColorExpandSpans3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+extern CARD32 *(*XAAStippleScanlineFuncMSBFirstFixedBase[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern CARD32 *(*XAAStippleScanlineFuncMSBFirst[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern CARD32 *(*XAAStippleScanlineFuncLSBFirstFixedBase[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern CARD32 *(*XAAStippleScanlineFuncLSBFirst[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+int
+XAAPolyText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+int
+XAAPolyText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+void
+XAAImageText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+XAAPolyGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+
+int
+XAAPolyText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+int
+XAAPolyText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+void
+XAAImageText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+void
+XAAImageGlyphBltNonTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+void
+XAAPolyGlyphBltNonTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+
+void XAANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+);
+
+void
+XAAFillSolidSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted
+);
+
+void
+XAAFillMono8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int patx, int paty,
+ int xorg, int yorg
+);
+
+void
+XAAFillMono8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int patx, int paty,
+ int xorg, int yorg
+);
+
+void
+XAAFillColor8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr,
+ int xorigin, int yorigin
+);
+
+void
+XAAFillColor8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr,
+ int xorigin, int yorigin
+);
+
+void
+XAAFillCacheBltSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+);
+
+void
+XAAFillCacheExpandSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+void
+XAAFillSpans(
+ DrawablePtr pDrawable,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidth,
+ int fSorted
+);
+
+
+void
+XAAInitPixmapCache(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+);
+
+void
+XAAWriteBitmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+);
+
+void
+XAAWriteBitmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+);
+
+void
+XAAWritePixmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+);
+
+void
+XAAWritePixmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+);
+
+
+void
+XAAPaintWindow(
+ WindowPtr pWin,
+ RegionPtr prgn,
+ int what
+);
+
+void
+XAASolidHorVertLineAsRects(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+void
+XAASolidHorVertLineAsTwoPoint(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+void
+XAASolidHorVertLineAsBresenham(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+
+void
+XAAPolyRectangleThinSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+);
+
+
+void
+XAAPolylinesWideSolid (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+);
+
+void
+XAAFillPolygonSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+void
+XAAFillPolygonStippled(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+
+void
+XAAFillPolygonTiled(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+
+int
+XAAIsEasyPolygon(
+ DDXPointPtr ptsIn,
+ int count,
+ BoxPtr extents,
+ int origin,
+ DDXPointPtr *topPoint,
+ int *topY, int *bottomY,
+ int shape
+);
+
+void
+XAAFillPolygonHelper(
+ ScrnInfoPtr pScrn,
+ DDXPointPtr ptsIn,
+ int count,
+ DDXPointPtr topPoint,
+ int y,
+ int maxy,
+ int origin,
+ RectFuncPtr RectFunc,
+ TrapFuncPtr TrapFunc,
+ int xorg,
+ int yorg,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAAPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+void
+XAAPolyLines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+void
+XAAPolySegmentDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+void
+XAAPolyLinesDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+
+void
+XAAWriteMono8x8PatternToCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache);
+
+void
+XAAWriteColor8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+);
+
+void
+XAARotateMonoPattern(
+ int *pat0, int *pat1,
+ int xoffset, int yoffset,
+ Bool msbfirst
+);
+
+void XAAComputeDash(GCPtr pGC);
+
+void XAAMoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+void XAAMoveDWORDS_FixedSrc(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+void XAAMoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+int
+XAAGetRectClipBoxes(
+ RegionPtr prgnClip,
+ BoxPtr pboxClippedBase,
+ int nrectFill,
+ xRectangle *prectInit
+);
+
+void
+XAASetupOverlay8_32Planar(ScreenPtr);
+
+void
+XAAPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs);
+
+XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
+
+XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr Scrn, int pat0, int pat1);
+
+XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
+
+void
+XAATileCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache, int w, int h);
+
+void XAAClosePixmapCache(ScreenPtr pScreen);
+void XAAInvalidatePixmapCache(ScreenPtr pScreen);
+
+Bool XAACheckStippleReducibility(PixmapPtr pPixmap);
+Bool XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono);
+
+int XAAStippledFillChooser(GCPtr pGC);
+int XAAOpaqueStippledFillChooser(GCPtr pGC);
+int XAATiledFillChooser(GCPtr pGC);
+
+void XAAMoveInOffscreenPixmaps(ScreenPtr pScreen);
+void XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen);
+void XAARemoveAreaCallback(FBAreaPtr area);
+void XAAMoveOutOffscreenPixmap(PixmapPtr pPix);
+Bool XAAInitStateWrap(ScreenPtr pScreen, XAAInfoRecPtr infoRec);
+
+#ifdef RENDER
+void
+XAAComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+
+Bool
+XAADoComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+
+void
+XAAGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+Bool
+XAADoGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+
+
+/* helpers */
+void
+XAA_888_plus_PICT_a8_to_8888 (
+ CARD32 color,
+ CARD8 *alphaPtr, /* in bytes */
+ int alphaPitch,
+ CARD32 *dstPtr,
+ int dstPitch, /* in dwords */
+ int width,
+ int height
+);
+
+Bool
+XAAGetRGBAFromPixel(
+ CARD32 pixel,
+ CARD16 *red,
+ CARD16 *green,
+ CARD16 *blue,
+ CARD16 *alpha,
+ CARD32 format
+);
+
+
+Bool
+XAAGetPixelFromRGBA (
+ CARD32 *pixel,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ CARD32 format
+);
+
+#endif
+
+
+extern GCOps XAAFallbackOps;
+extern GCFuncs XAAGCFuncs;
+extern int XAAScreenIndex;
+extern int XAAGCIndex;
+extern int XAAPixmapIndex;
+
+extern unsigned int XAAShiftMasks[32];
+
+extern unsigned int byte_expand3[256], byte_reversed_expand3[256];
+
+CARD32 XAAReverseBitOrder(CARD32 data);
+
+#define GET_XAASCREENPTR_FROM_SCREEN(pScreen)\
+ (pScreen)->devPrivates[XAAScreenIndex].ptr
+
+#define GET_XAASCREENPTR_FROM_GC(pGC)\
+ (pGC)->pScreen->devPrivates[XAAScreenIndex].ptr
+
+#define GET_XAASCREENPTR_FROM_DRAWABLE(pDraw)\
+ (pDraw)->pScreen->devPrivates[XAAScreenIndex].ptr
+
+#define GET_XAAINFORECPTR_FROM_SCREEN(pScreen)\
+ ((XAAScreenPtr)((pScreen)->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_GC(pGC)\
+((XAAScreenPtr)((pGC)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_DRAWABLE(pDraw)\
+((XAAScreenPtr)((pDraw)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn)\
+((XAAScreenPtr)((pScrn)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec
+
+#define XAA_GET_PIXMAP_PRIVATE(pix)\
+ (XAAPixmapPtr)((pix)->devPrivates[XAAPixmapIndex].ptr)
+
+#define CHECK_RGB_EQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
+
+#define CHECK_FG(pGC, flags) \
+ (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->fgPixel))
+
+#define CHECK_BG(pGC, flags) \
+ (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->bgPixel))
+
+#define CHECK_ROP(pGC, flags) \
+ (!(flags & GXCOPY_ONLY) || (pGC->alu == GXcopy))
+
+#define CHECK_ROPSRC(pGC, flags) \
+ (!(flags & ROP_NEEDS_SOURCE) || ((pGC->alu != GXclear) && \
+ (pGC->alu != GXnoop) && (pGC->alu != GXinvert) && \
+ (pGC->alu != GXset)))
+
+#define CHECK_PLANEMASK(pGC, flags) \
+ (!(flags & NO_PLANEMASK) || \
+ ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) == \
+ infoRec->FullPlanemasks[pGC->depth - 1]))
+
+#define CHECK_COLORS(pGC, flags) \
+ (!(flags & RGB_EQUAL) || \
+ (CHECK_RGB_EQUAL(pGC->fgPixel) && CHECK_RGB_EQUAL(pGC->bgPixel)))
+
+#define CHECK_NO_GXCOPY(pGC, flags) \
+ ((pGC->alu != GXcopy) || !(flags & NO_GXCOPY) || \
+ ((pGC->planemask & infoRec->FullPlanemask) != infoRec->FullPlanemask))
+
+#define IS_OFFSCREEN_PIXMAP(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->offscreenArea)
+
+#define PIXMAP_IS_SHARED(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & SHARED_PIXMAP)
+
+#define OFFSCREEN_PIXMAP_LOCKED(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & LOCKED_PIXMAP)
+
+#define XAA_DEPTH_BUG(pGC) \
+ ((pGC->depth == 32) && (pGC->bgPixel == 0xffffffff))
+
+#define DELIST_OFFSCREEN_PIXMAP(pPix) { \
+ PixmapLinkPtr _pLink, _prev; \
+ _pLink = infoRec->OffscreenPixmaps; \
+ _prev = NULL; \
+ while(_pLink) { \
+ if(_pLink->pPix == pPix) { \
+ if(_prev) _prev->next = _pLink->next; \
+ else infoRec->OffscreenPixmaps = _pLink->next; \
+ xfree(_pLink); \
+ break; \
+ } \
+ _prev = _pLink; \
+ _pLink = _pLink->next; \
+ }}
+
+
+#define SWAP_BITS_IN_BYTES(v) \
+ (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \
+ ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \
+ ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \
+ ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7))
+
+/*
+ * Moved XAAPixmapCachePrivate here from xaaPCache.c, since driver
+ * replacements for CacheMonoStipple need access to it
+ */
+
+typedef struct {
+ int Num512x512;
+ int Current512;
+ XAACacheInfoPtr Info512;
+ int Num256x256;
+ int Current256;
+ XAACacheInfoPtr Info256;
+ int Num128x128;
+ int Current128;
+ XAACacheInfoPtr Info128;
+ int NumMono;
+ int CurrentMono;
+ XAACacheInfoPtr InfoMono;
+ int NumColor;
+ int CurrentColor;
+ XAACacheInfoPtr InfoColor;
+ int NumPartial;
+ int CurrentPartial;
+ XAACacheInfoPtr InfoPartial;
+ DDXPointRec MonoOffsets[64];
+ DDXPointRec ColorOffsets[64];
+} XAAPixmapCachePrivate, *XAAPixmapCachePrivatePtr;
+
+
+#endif /* _XAALOCAL_H */
diff --git a/hw/xfree86/xaa/xaarop.h b/hw/xfree86/xaa/xaarop.h
new file mode 100644
index 000000000..8fee07533
--- /dev/null
+++ b/hw/xfree86/xaa/xaarop.h
@@ -0,0 +1,307 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaarop.h,v 1.1 1999/03/21 07:35:31 dawes Exp $ */
+
+/*
+
+ int XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop)
+
+ For use with solid fills emulated by solid 8x8 patterns. You
+ give it the foreground, planemask and X rop and it will replace
+ the foreground with a new one and the rop with the appropriate
+ MS triadic raster op. The function will return which components
+ (S-P) need to be enabled.
+
+
+ int XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop)
+
+ For use with 8x8 opaque pattern fills. You give it the foreground,
+ and background, planemask and X rop and it will replace the
+ foreground and background with new ones and the rop with the
+ appropriate MS triadic raster op. The function will return which
+ components (S-P) need to be enabled.
+
+
+ ROP_PAT - Means to enable 8x8 mono patterns (all bits
+ set for solid patterns). Set the foreground and
+ background as returned by the function.
+
+ ROP_SRC - Means a source of color == planemask should be used.
+
+
+*/
+
+#ifndef _XAAROP_H
+#define _XAAROP_H
+
+#define ROP_DST 0x00000001
+#define ROP_SRC 0x00000002
+#define ROP_PAT 0x00000004
+
+#define ROP_0 0x00
+#define ROP_DPSoon 0x01
+#define ROP_DPSona 0x02
+#define ROP_PSon 0x03
+#define ROP_SDPona 0x04
+#define ROP_DPon 0x05
+#define ROP_PDSxnon 0x06
+#define ROP_PDSaon 0x07
+#define ROP_SDPnaa 0x08
+#define ROP_PDSxon 0x09
+#define ROP_DPna 0x0A
+#define ROP_PSDnaon 0x0B
+#define ROP_SPna 0x0C
+#define ROP_PDSnaon 0x0D
+#define ROP_PDSonon 0x0E
+#define ROP_Pn 0x0F
+#define ROP_PDSona 0x10
+#define ROP_DSon 0x11
+#define ROP_SDPxnon 0x12
+#define ROP_SDPaon 0x13
+#define ROP_DPSxnon 0x14
+#define ROP_DPSaon 0x15
+#define ROP_PSDPSanaxx 0x16
+#define ROP_SSPxDSxaxn 0x17
+#define ROP_SPxPDxa 0x18
+#define ROP_SDPSanaxn 0x19
+#define ROP_PDSPaox 0x1A
+#define ROP_SDPSxaxn 0x1B
+#define ROP_PSDPaox 0x1C
+#define ROP_DSPDxaxn 0x1D
+#define ROP_PDSox 0x1E
+#define ROP_PDSoan 0x1F
+#define ROP_DPSnaa 0x20
+#define ROP_SDPxon 0x21
+#define ROP_DSna 0x22
+#define ROP_SPDnaon 0x23
+#define ROP_SPxDSxa 0x24
+#define ROP_PDSPanaxn 0x25
+#define ROP_SDPSaox 0x26
+#define ROP_SDPSxnox 0x27
+#define ROP_DPSxa 0x28
+#define ROP_PSDPSaoxxn 0x29
+#define ROP_DPSana 0x2A
+#define ROP_SSPxPDxaxn 0x2B
+#define ROP_SPDSoax 0x2C
+#define ROP_PSDnox 0x2D
+#define ROP_PSDPxox 0x2E
+#define ROP_PSDnoan 0x2F
+#define ROP_PSna 0x30
+#define ROP_SDPnaon 0x31
+#define ROP_SDPSoox 0x32
+#define ROP_Sn 0x33
+#define ROP_SPDSaox 0x34
+#define ROP_SPDSxnox 0x35
+#define ROP_SDPox 0x36
+#define ROP_SDPoan 0x37
+#define ROP_PSDPoax 0x38
+#define ROP_SPDnox 0x39
+#define ROP_SPDSxox 0x3A
+#define ROP_SPDnoan 0x3B
+#define ROP_PSx 0x3C
+#define ROP_SPDSonox 0x3D
+#define ROP_SPDSnaox 0x3E
+#define ROP_PSan 0x3F
+#define ROP_PSDnaa 0x40
+#define ROP_DPSxon 0x41
+#define ROP_SDxPDxa 0x42
+#define ROP_SPDSanaxn 0x43
+#define ROP_SDna 0x44
+#define ROP_DPSnaon 0x45
+#define ROP_DSPDaox 0x46
+#define ROP_PSDPxaxn 0x47
+#define ROP_SDPxa 0x48
+#define ROP_PDSPDaoxxn 0x49
+#define ROP_DPSDoax 0x4A
+#define ROP_PDSnox 0x4B
+#define ROP_SDPana 0x4C
+#define ROP_SSPxDSxoxn 0x4D
+#define ROP_PDSPxox 0x4E
+#define ROP_PDSnoan 0x4F
+#define ROP_PDna 0x50
+#define ROP_DSPnaon 0x51
+#define ROP_DPSDaox 0x52
+#define ROP_SPDSxaxn 0x53
+#define ROP_DPSonon 0x54
+#define ROP_Dn 0x55
+#define ROP_DPSox 0x56
+#define ROP_DPSoan 0x57
+#define ROP_PDSPoax 0x58
+#define ROP_DPSnox 0x59
+#define ROP_DPx 0x5A
+#define ROP_DPSDonox 0x5B
+#define ROP_DPSDxox 0x5C
+#define ROP_DPSnoan 0x5D
+#define ROP_DPSDnaox 0x5E
+#define ROP_DPan 0x5F
+#define ROP_PDSxa 0x60
+#define ROP_DSPDSaoxxn 0x61
+#define ROP_DSPDoax 0x62
+#define ROP_SDPnox 0x63
+#define ROP_SDPSoax 0x64
+#define ROP_DSPnox 0x65
+#define ROP_DSx 0x66
+#define ROP_SDPSonox 0x67
+#define ROP_DSPDSonoxxn 0x68
+#define ROP_PDSxxn 0x69
+#define ROP_DPSax 0x6A
+#define ROP_PSDPSoaxxn 0x6B
+#define ROP_SDPax 0x6C
+#define ROP_PDSPDoaxxn 0x6D
+#define ROP_SDPSnoax 0x6E
+#define ROP_PDSxnan 0x6F
+#define ROP_PDSana 0x70
+#define ROP_SSDxPDxaxn 0x71
+#define ROP_SDPSxox 0x72
+#define ROP_SDPnoan 0x73
+#define ROP_DSPDxox 0x74
+#define ROP_DSPnoan 0x75
+#define ROP_SDPSnaox 0x76
+#define ROP_DSan 0x77
+#define ROP_PDSax 0x78
+#define ROP_DSPDSoaxxn 0x79
+#define ROP_DPSDnoax 0x7A
+#define ROP_SDPxnan 0x7B
+#define ROP_SPDSnoax 0x7C
+#define ROP_DPSxnan 0x7D
+#define ROP_SPxDSxo 0x7E
+#define ROP_DPSaan 0x7F
+#define ROP_DPSaa 0x80
+#define ROP_SPxDSxon 0x81
+#define ROP_DPSxna 0x82
+#define ROP_SPDSnoaxn 0x83
+#define ROP_SDPxna 0x84
+#define ROP_PDSPnoaxn 0x85
+#define ROP_DSPDSoaxx 0x86
+#define ROP_PDSaxn 0x87
+#define ROP_DSa 0x88
+#define ROP_SDPSnaoxn 0x89
+#define ROP_DSPnoa 0x8A
+#define ROP_DSPDxoxn 0x8B
+#define ROP_SDPnoa 0x8C
+#define ROP_SDPSxoxn 0x8D
+#define ROP_SSDxPDxax 0x8E
+#define ROP_PDSanan 0x8F
+#define ROP_PDSxna 0x90
+#define ROP_SDPSnoaxn 0x91
+#define ROP_DPSDPoaxx 0x92
+#define ROP_SPDaxn 0x93
+#define ROP_PSDPSoaxx 0x94
+#define ROP_DPSaxn 0x95
+#define ROP_DPSxx 0x96
+#define ROP_PSDPSonoxx 0x97
+#define ROP_SDPSonoxn 0x98
+#define ROP_DSxn 0x99
+#define ROP_DPSnax 0x9A
+#define ROP_SDPSoaxn 0x9B
+#define ROP_SPDnax 0x9C
+#define ROP_DSPDoaxn 0x9D
+#define ROP_DSPDSaoxx 0x9E
+#define ROP_PDSxan 0x9F
+#define ROP_DPa 0xA0
+#define ROP_PDSPnaoxn 0xA1
+#define ROP_DPSnoa 0xA2
+#define ROP_DPSDxoxn 0xA3
+#define ROP_PDSPonoxn 0xA4
+#define ROP_PDxn 0xA5
+#define ROP_DSPnax 0xA6
+#define ROP_PDSPoaxn 0xA7
+#define ROP_DPSoa 0xA8
+#define ROP_DPSoxn 0xA9
+#define ROP_D 0xAA
+#define ROP_DPSono 0xAB
+#define ROP_SPDSxax 0xAC
+#define ROP_DPSDaoxn 0xAD
+#define ROP_DSPnao 0xAE
+#define ROP_DPno 0xAF
+#define ROP_PDSnoa 0xB0
+#define ROP_PDSPxoxn 0xB1
+#define ROP_SSPxDSxox 0xB2
+#define ROP_SDPanan 0xB3
+#define ROP_PSDnax 0xB4
+#define ROP_DPSDoaxn 0xB5
+#define ROP_DPSDPaoxx 0xB6
+#define ROP_SDPxan 0xB7
+#define ROP_PSDPxax 0xB8
+#define ROP_DSPDaoxn 0xB9
+#define ROP_DPSnao 0xBA
+#define ROP_DSno 0xBB
+#define ROP_SPDSanax 0xBC
+#define ROP_SDxPDxan 0xBD
+#define ROP_DPSxo 0xBE
+#define ROP_DPSano 0xBF
+#define ROP_Psa 0xC0
+#define ROP_SPDSnaoxn 0xC1
+#define ROP_SPDSonoxn 0xC2
+#define ROP_PSxn 0xC3
+#define ROP_SPDnoa 0xC4
+#define ROP_SPDSxoxn 0xC5
+#define ROP_SDPnax 0xC6
+#define ROP_PSDPoaxn 0xC7
+#define ROP_SDPoa 0xC8
+#define ROP_SPDoxn 0xC9
+#define ROP_DPSDxax 0xCA
+#define ROP_SPDSaoxn 0xCB
+#define ROP_S 0xCC
+#define ROP_SDPono 0xCD
+#define ROP_SDPnao 0xCE
+#define ROP_SPno 0xCF
+#define ROP_PSDnoa 0xD0
+#define ROP_PSDPxoxn 0xD1
+#define ROP_PDSnax 0xD2
+#define ROP_SPDSoaxn 0xD3
+#define ROP_SSPxPDxax 0xD4
+#define ROP_DPSanan 0xD5
+#define ROP_PSDPSaoxx 0xD6
+#define ROP_DPSxan 0xD7
+#define ROP_PDSPxax 0xD8
+#define ROP_SDPSaoxn 0xD9
+#define ROP_DPSDanax 0xDA
+#define ROP_SPxDSxan 0xDB
+#define ROP_SPDnao 0xDC
+#define ROP_SDno 0xDD
+#define ROP_SDPxo 0xDE
+#define ROP_SDPano 0xDF
+#define ROP_PDSoa 0xE0
+#define ROP_PDSoxn 0xE1
+#define ROP_DSPDxax 0xE2
+#define ROP_PSDPaoxn 0xE3
+#define ROP_SDPSxax 0xE4
+#define ROP_PDSPaoxn 0xE5
+#define ROP_SDPSanax 0xE6
+#define ROP_SPxPDxan 0xE7
+#define ROP_SSPxDSxax 0xE8
+#define ROP_DSPDSanaxxn 0xE9
+#define ROP_DPSao 0xEA
+#define ROP_DPSxno 0xEB
+#define ROP_SDPao 0xEC
+#define ROP_SDPxno 0xED
+#define ROP_DSo 0xEE
+#define ROP_SDPnoo 0xEF
+#define ROP_P 0xF0
+#define ROP_PDSono 0xF1
+#define ROP_PDSnao 0xF2
+#define ROP_PSno 0xF3
+#define ROP_PSDnao 0xF4
+#define ROP_PDno 0xF5
+#define ROP_PDSxo 0xF6
+#define ROP_PDSano 0xF7
+#define ROP_PDSao 0xF8
+#define ROP_PDSxno 0xF9
+#define ROP_DPo 0xFA
+#define ROP_DPSnoo 0xFB
+#define ROP_PSo 0xFC
+#define ROP_PSDnoo 0xFD
+#define ROP_DPSoo 0xFE
+#define ROP_1 0xFF
+
+#define NO_SRC_ROP(rop) \
+ ((rop == GXnoop) || (rop == GXset) || (rop == GXclear) || (rop == GXinvert))
+
+int XAAHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);
+int XAAHelpPatternROP(ScrnInfoPtr pScrn, int *fg, int *bg, int pm, int *rop);
+
+extern int XAACopyROP[16];
+extern int XAACopyROP_PM[16];
+extern int XAAPatternROP[16];
+extern int XAAPatternROP_PM[16];
+
+#endif /* _XAAROP_H */
diff --git a/hw/xfree86/xaa/xaawrap.h b/hw/xfree86/xaa/xaawrap.h
new file mode 100644
index 000000000..e6963c325
--- /dev/null
+++ b/hw/xfree86/xaa/xaawrap.h
@@ -0,0 +1,78 @@
+/* $XFree86: xc/programs/Xserver/hw/xfree86/xaa/xaawrap.h,v 1.5 2000/09/20 02:05:42 keithp Exp $ */
+
+#define XAA_SCREEN_PROLOGUE(pScreen, field)\
+ ((pScreen)->field = \
+ ((XAAScreenPtr) (pScreen)->devPrivates[XAAScreenIndex].ptr)->field)
+
+#define XAA_SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+
+#define XAA_GC_FUNC_PROLOGUE(pGC)\
+ XAAGCPtr pGCPriv = (XAAGCPtr) (pGC)->devPrivates[XAAGCIndex].ptr;\
+ (pGC)->funcs = pGCPriv->wrapFuncs;\
+ if(pGCPriv->flags)\
+ (pGC)->ops = pGCPriv->wrapOps
+
+#define XAA_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->wrapFuncs = (pGC)->funcs;\
+ (pGC)->funcs = &XAAGCFuncs;\
+ if(pGCPriv->flags) {\
+ pGCPriv->wrapOps = (pGC)->ops;\
+ (pGC)->ops = (pGCPriv->flags & OPS_ARE_ACCEL) ? pGCPriv->XAAOps :\
+ &XAAPixmapOps;\
+ }
+
+
+#define XAA_GC_OP_PROLOGUE(pGC)\
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+#define XAA_GC_OP_PROLOGUE_WITH_RETURN(pGC)\
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip)) return; \
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+
+#define XAA_GC_OP_EPILOGUE(pGC)\
+ pGCPriv->wrapOps = pGC->ops;\
+ pGC->funcs = oldFuncs;\
+ pGC->ops = pGCPriv->XAAOps
+
+
+#define XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw)\
+ XAAGCPtr pGCPriv = (XAAGCPtr)(pGC->devPrivates[XAAGCIndex].ptr);\
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDraw));\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->wrapFuncs;\
+ pGC->ops = pGCPriv->wrapOps
+
+
+#define XAA_PIXMAP_OP_EPILOGUE(pGC)\
+ pGCPriv->wrapOps = pGC->ops;\
+ pGC->funcs = oldFuncs;\
+ pGC->ops = &XAAPixmapOps;\
+ pixPriv->flags |= DIRTY
+
+#ifdef RENDER
+#define XAA_RENDER_PROLOGUE(pScreen,field)\
+ (GetPictureScreen(pScreen)->field = \
+ ((XAAScreenPtr) (pScreen)->devPrivates[XAAScreenIndex].ptr)->field)
+
+#define XAA_RENDER_EPILOGUE(pScreen, field, wrapper)\
+ (GetPictureScreen(pScreen)->field = wrapper)
+#endif
+
+/* This also works fine for drawables */
+
+#define SYNC_CHECK(pGC) {\
+ XAAInfoRecPtr infoRec =\
+((XAAScreenPtr)((pGC)->pScreen->devPrivates[XAAScreenIndex].ptr))->AccelInfoRec;\
+ if(infoRec->NeedToSync) {\
+ (*infoRec->Sync)(infoRec->pScrn);\
+ infoRec->NeedToSync = FALSE;\
+ }}