summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-04-27 16:34:36 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-04-27 16:34:36 +0930
commitf28eea0647f007c2e2415ecc6fceef46201faad4 (patch)
tree5b0bb409d87faa22b091e0190f32a48fd3cda342
parent339b73e710a0920608a3fbcb20b406f0f6c4e0f6 (diff)
parentae04f2cb0a068cdc1e519627bf745de0c9e4a85a (diff)
Merge branch 'master' into mpx
Conflicts: dix/devices.c dix/events.c
-rw-r--r--GL/glx/Makefile.am3
-rw-r--r--GL/glx/glxcontext.h3
-rw-r--r--GL/glx/glxglcore.c (renamed from GL/mesa/X/xf86glx.c)13
-rw-r--r--GL/glx/glxscreens.h3
-rw-r--r--GL/glx/indirect_size_get.c2
-rw-r--r--GL/mesa/X/Makefile.am2
-rw-r--r--GL/mesa/main/Makefile.am2
-rw-r--r--GL/mesa/shader/slang/Makefile.am1
-rw-r--r--GL/mesa/tnl/Makefile.am2
-rw-r--r--configure.ac9
-rw-r--r--dix/devices.c35
-rw-r--r--dix/events.c441
-rw-r--r--fb/fbcompose.c2095
-rw-r--r--fb/fbmmx.c880
-rw-r--r--fb/fbmmx.h62
-rw-r--r--fb/fbpict.c1048
-rw-r--r--fb/fbpict.h12
-rw-r--r--hw/kdrive/Makefile.am12
-rw-r--r--hw/kdrive/ati/Makefile.am3
-rw-r--r--hw/kdrive/chips/Makefile.am3
-rw-r--r--hw/kdrive/ephyr/Makefile.am3
-rw-r--r--hw/kdrive/epson/Makefile.am3
-rw-r--r--hw/kdrive/fake/Makefile.am3
-rw-r--r--hw/kdrive/fbdev/Makefile.am3
-rw-r--r--hw/kdrive/i810/Makefile.am3
-rw-r--r--hw/kdrive/mach64/Makefile.am3
-rw-r--r--hw/kdrive/mga/Makefile.am3
-rw-r--r--hw/kdrive/neomagic/Makefile.am3
-rw-r--r--hw/kdrive/nvidia/Makefile.am3
-rw-r--r--hw/kdrive/pm2/Makefile.am3
-rw-r--r--hw/kdrive/r128/Makefile.am3
-rw-r--r--hw/kdrive/sdl/Makefile.am3
-rw-r--r--hw/kdrive/sis300/Makefile.am3
-rw-r--r--hw/kdrive/smi/Makefile.am3
-rw-r--r--hw/kdrive/vesa/Makefile.am3
-rw-r--r--hw/kdrive/via/Makefile.am3
-rw-r--r--hw/xfree86/common/xf86Xinput.c44
-rw-r--r--hw/xfree86/common/xf86Xinput.h3
-rw-r--r--hw/xfree86/ddc/edid_modes.c361
-rw-r--r--hw/xfree86/dri/dri.c511
-rw-r--r--hw/xfree86/dri/dri.h18
-rw-r--r--hw/xfree86/dri/dristruct.h24
-rw-r--r--hw/xfree86/dri/sarea.h5
-rw-r--r--hw/xfree86/loader/loadmod.c2
-rw-r--r--hw/xfree86/modes/xf86Crtc.c78
-rw-r--r--hw/xfree86/modes/xf86Crtc.h12
-rw-r--r--hw/xfree86/modes/xf86EdidModes.c10
-rw-r--r--hw/xfree86/modes/xf86RandR12.c5
-rw-r--r--hw/xfree86/modes/xf86RandR12.h3
-rw-r--r--hw/xfree86/modes/xf86Rename.h9
-rw-r--r--hw/xfree86/modes/xf86Rotate.c20
-rw-r--r--hw/xfree86/os-support/bus/Pci.c14
-rw-r--r--mi/Makefile.am7
-rw-r--r--miext/cw/cw_ops.c37
-rw-r--r--randr/rrcrtc.c6
-rw-r--r--randr/rrxinerama.c8
-rw-r--r--render/picture.c135
-rw-r--r--render/picturestr.h49
58 files changed, 4304 insertions, 1736 deletions
diff --git a/GL/glx/Makefile.am b/GL/glx/Makefile.am
index cd1130d61..c4141bceb 100644
--- a/GL/glx/Makefile.am
+++ b/GL/glx/Makefile.am
@@ -46,12 +46,13 @@ libglx_la_SOURCES = \
glxdrawable.h \
glxext.c \
glxext.h \
- glxvisuals.c \
+ glxglcore.c \
glxscreens.c \
glxscreens.h \
glxserver.h \
glxutil.c \
glxutil.h \
+ glxvisuals.c \
indirect_dispatch.c \
indirect_dispatch.h \
indirect_dispatch_swap.c \
diff --git a/GL/glx/glxcontext.h b/GL/glx/glxcontext.h
index a54e323cc..eb10ee2a8 100644
--- a/GL/glx/glxcontext.h
+++ b/GL/glx/glxcontext.h
@@ -40,9 +40,6 @@
**
*/
-/* XXX: should be defined somewhere globally */
-#define CAPI
-
#include "GL/internal/glcore.h"
typedef struct __GLXtextureFromPixmap __GLXtextureFromPixmap;
diff --git a/GL/mesa/X/xf86glx.c b/GL/glx/glxglcore.c
index 6fffdeb1f..b50740c3c 100644
--- a/GL/mesa/X/xf86glx.c
+++ b/GL/glx/glxglcore.c
@@ -45,7 +45,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <glxdrawable.h>
#include <glxcontext.h>
#include <glxutil.h>
-#include "xmesaP.h"
#include "glcontextmodes.h"
#include "os.h"
@@ -259,12 +258,14 @@ __glXMesaScreenDestroy(__GLXscreen *screen)
__GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
int i;
- for (i = 0; i < mesaScreen->num_vis; i++) {
- if (mesaScreen->xm_vis[i])
- XMesaDestroyVisual(mesaScreen->xm_vis[i]);
- }
+ if (mesaScreen->xm_vis) {
+ for (i = 0; i < mesaScreen->num_vis; i++) {
+ if (mesaScreen->xm_vis[i])
+ XMesaDestroyVisual(mesaScreen->xm_vis[i]);
+ }
- xfree(mesaScreen->xm_vis);
+ xfree(mesaScreen->xm_vis);
+ }
__glXScreenDestroy(screen);
diff --git a/GL/glx/glxscreens.h b/GL/glx/glxscreens.h
index a7700f649..bba45572f 100644
--- a/GL/glx/glxscreens.h
+++ b/GL/glx/glxscreens.h
@@ -40,9 +40,6 @@
**
*/
-/* XXX: should be defined somewhere globally */
-#define CAPI
-
#include "GL/internal/glcore.h"
/*
diff --git a/GL/glx/indirect_size_get.c b/GL/glx/indirect_size_get.c
index ccb25f80e..f29ae474e 100644
--- a/GL/glx/indirect_size_get.c
+++ b/GL/glx/indirect_size_get.c
@@ -370,6 +370,7 @@ __glGetBooleanv_size(GLenum e)
case GL_PROJECTION_STACK_DEPTH:
case GL_TEXTURE_STACK_DEPTH:
case GL_ATTRIB_STACK_DEPTH:
+ case GL_CLIENT_ATTRIB_STACK_DEPTH:
case GL_ALPHA_TEST:
case GL_ALPHA_TEST_FUNC:
case GL_ALPHA_TEST_REF:
@@ -448,6 +449,7 @@ __glGetBooleanv_size(GLenum e)
case GL_MAX_NAME_STACK_DEPTH:
case GL_MAX_PROJECTION_STACK_DEPTH:
case GL_MAX_TEXTURE_STACK_DEPTH:
+ case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
case GL_SUBPIXEL_BITS:
case GL_INDEX_BITS:
case GL_RED_BITS:
diff --git a/GL/mesa/X/Makefile.am b/GL/mesa/X/Makefile.am
index f8f16c39e..ace118170 100644
--- a/GL/mesa/X/Makefile.am
+++ b/GL/mesa/X/Makefile.am
@@ -22,8 +22,6 @@ AM_CFLAGS = \
-DXFree86Server \
@GLX_DEFINES@
-libX_la_SOURCES = xf86glx.c
-
nodist_libX_la_SOURCES = \
xm_api.c \
xm_buffer.c \
diff --git a/GL/mesa/main/Makefile.am b/GL/mesa/main/Makefile.am
index 2b838e903..f8ce13775 100644
--- a/GL/mesa/main/Makefile.am
+++ b/GL/mesa/main/Makefile.am
@@ -61,10 +61,10 @@ nodist_libmain_la_SOURCES = accum.c \
matrix.c \
mipmap.c \
mm.c \
- occlude.c \
pixel.c \
points.c \
polygon.c \
+ queryobj.c \
rastpos.c \
rbadaptors.c \
renderbuffer.c \
diff --git a/GL/mesa/shader/slang/Makefile.am b/GL/mesa/shader/slang/Makefile.am
index 7f0cd649e..71498eeac 100644
--- a/GL/mesa/shader/slang/Makefile.am
+++ b/GL/mesa/shader/slang/Makefile.am
@@ -31,6 +31,7 @@ nodist_libslang_la_SOURCES = slang_builtin.c \
slang_library_noise.c \
slang_link.c \
slang_log.c \
+ slang_mem.c \
slang_preprocess.c \
slang_print.c \
slang_simplify.c \
diff --git a/GL/mesa/tnl/Makefile.am b/GL/mesa/tnl/Makefile.am
index 84301d3d8..b3c82066f 100644
--- a/GL/mesa/tnl/Makefile.am
+++ b/GL/mesa/tnl/Makefile.am
@@ -21,8 +21,6 @@ INCLUDES = -I@MESA_SOURCE@/include \
nodist_libtnl_la_SOURCES = t_context.c \
t_draw.c \
t_pipeline.c \
- t_vb_arbprogram.c \
- t_vb_arbprogram_sse.c \
t_vb_cull.c \
t_vb_fog.c \
t_vb_light.c \
diff --git a/configure.ac b/configure.ac
index cb8b4351b..9d4a50a01 100644
--- a/configure.ac
+++ b/configure.ac
@@ -382,9 +382,9 @@ AC_DEFINE_UNQUOTED(OSNAME, "$OSNAME",
DEFAULT_VENDOR_NAME="The X.Org Foundation"
DEFAULT_VENDOR_NAME_SHORT="X.Org"
DEFAULT_VERSION_MAJOR=7
-DEFAULT_VERSION_MINOR=1
-DEFAULT_VERSION_PATCH=99
-DEFAULT_VERSION_SNAP=2
+DEFAULT_VERSION_MINOR=2
+DEFAULT_VERSION_PATCH=0
+DEFAULT_VERSION_SNAP=0
DEFAULT_RELEASE_DATE="21 December 2005"
DEFAULT_VENDOR_WEB="http://wiki.x.org"
@@ -628,7 +628,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
dnl Core modules for most extensions, et al.
-REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto xproto xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4] [kbproto >= 1.0.3]"
+REQUIRED_MODULES="[randrproto >= 1.2] renderproto [fixesproto >= 4.0] [damageproto >= 1.1] xcmiscproto xextproto xproto xtrans [scrnsaverproto >= 1.1] bigreqsproto resourceproto fontsproto [inputproto >= 1.4.2] [kbproto >= 1.0.3]"
REQUIRED_LIBS="xfont xau fontenc"
if test "x$DBUS" = xauto; then
@@ -986,7 +986,6 @@ else
fi
CWRAP_LIB='$(top_builddir)/os/libcwrapper.la'
MI_LIB='$(top_builddir)/mi/libmi.la'
-MINIMI_LIB='$(top_builddir)/mi/libminimi.la'
MI_EXT_LIB='$(top_builddir)/mi/libmiext.la'
MI_INC='-I$(top_srcdir)/mi'
FB_LIB='$(top_builddir)/fb/libfb.la'
diff --git a/dix/devices.c b/dix/devices.c
index cf6090d80..a6e141559 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -75,6 +75,7 @@ SOFTWARE.
#include "swaprep.h"
#include "dixevents.h"
+#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
#include "exglobals.h"
#include "exevents.h"
@@ -189,6 +190,8 @@ EnableDevice(DeviceIntPtr dev)
{
DeviceIntPtr *prev;
int ret;
+ DeviceIntRec dummyDev;
+ devicePresenceNotify ev;
for (prev = &inputInfo.off_devices;
*prev && (*prev != dev);
@@ -215,6 +218,14 @@ EnableDevice(DeviceIntPtr dev)
*prev = dev;
dev->next = NULL;
+ ev.type = DevicePresenceNotify;
+ ev.time = currentTime.milliseconds;
+ ev.devchange = DeviceEnabled;
+ ev.deviceid = dev->id;
+ dummyDev.id = 0;
+ SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+ (xEvent *) &ev, 1);
+
return TRUE;
}
@@ -225,6 +236,8 @@ Bool
DisableDevice(DeviceIntPtr dev)
{
DeviceIntPtr *prev;
+ DeviceIntRec dummyDev;
+ devicePresenceNotify ev;
for (prev = &inputInfo.devices;
*prev && (*prev != dev);
@@ -237,6 +250,15 @@ DisableDevice(DeviceIntPtr dev)
*prev = dev->next;
dev->next = inputInfo.off_devices;
inputInfo.off_devices = dev;
+
+ ev.type = DevicePresenceNotify;
+ ev.time = currentTime.milliseconds;
+ ev.devchange = DeviceDisabled;
+ ev.deviceid = dev->id;
+ dummyDev.id = 0;
+ SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+ (xEvent *) &ev, 1);
+
return TRUE;
}
@@ -266,8 +288,8 @@ ActivateDevice(DeviceIntPtr dev)
ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds;
- ev.devchange = 0;
- ev.deviceid = 0;
+ ev.devchange = DeviceAdded;
+ ev.deviceid = dev->id;
dummyDev.id = 0;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1);
@@ -694,6 +716,7 @@ RemoveDevice(DeviceIntPtr dev)
devicePresenceNotify ev;
DeviceIntRec dummyDev;
ScreenPtr screen = screenInfo.screens[0];
+ int deviceid;
DebugF("(dix) removing device %d\n", dev->id);
@@ -702,6 +725,9 @@ RemoveDevice(DeviceIntPtr dev)
screen->UndisplayCursor(dev, screen);
+ deviceid = dev->id;
+ DisableDevice(dev);
+
prev = NULL;
for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
next = tmp->next;
@@ -736,8 +762,8 @@ RemoveDevice(DeviceIntPtr dev)
inputInfo.numDevices--;
ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds;
- ev.devchange = 0;
- ev.deviceid = 0;
+ ev.devchange = DeviceRemoved;
+ ev.deviceid = deviceid;
dummyDev.id = 0;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1);
@@ -1391,6 +1417,7 @@ DoSetModifierMapping(ClientPtr client, KeyCode *inputMap,
}
else {
pDev->key->modifierKeyMap = NULL;
+ pDev->key->maxKeysPerModifier = 0;
}
}
}
diff --git a/dix/events.c b/dix/events.c
index da3f6aa7e..deb2da104 100644
--- a/dix/events.c
+++ b/dix/events.c
@@ -113,6 +113,10 @@ of the copyright holder.
* Author: Peter Hutterer <peter@cs.unisa.edu.au>
*/
+/** @file
+ * This file handles event delivery and a big part of the server-side protocol
+ * handling (the parts for input devices).
+ */
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
@@ -174,7 +178,9 @@ static xEvent *xeviexE;
#include "dixevents.h"
#include "dixgrabs.h"
#include "dispatch.h"
-
+/**
+ * Extension events type numbering starts at EXTENSION_EVENT_BASE.
+ */
#define EXTENSION_EVENT_BASE 64
#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
@@ -220,6 +226,28 @@ _X_EXPORT CallbackListPtr DeviceEventCallback;
Mask DontPropagateMasks[DNPMCOUNT];
static int DontPropagateRefCnts[DNPMCOUNT];
+/**
+ * Main input device struct.
+ * inputInfo.pointer
+ * is the core pointer. Referred to as "virtual core pointer", "VCP",
+ * "core pointer" or inputInfo.pointer. There is exactly one core pointer,
+ * but multiple devices may send core events. If a device generates core
+ * events, those events will appear to originate from the core pointer.
+ *
+ * inputInfo.keyboard
+ * is the core keyboard ("virtual core keyboard", "VCK", "core keyboard").
+ * See inputInfo.pointer.
+ *
+ * inputInfo.devices
+ * linked list containing all devices including VCK and VCP. The VCK will
+ * always be the first entry, the VCP the second entry in the device list.
+ *
+ * inputInfo.off_devices
+ * Devices that have not been initialized and are thus turned off.
+ *
+ * inputInfo.numDevices
+ * Total number of devices.
+ */
_X_EXPORT InputInfo inputInfo;
static struct {
@@ -262,7 +290,6 @@ IsKeyboardDevice(DeviceIntPtr dev)
return ((dev->key && dev->kbdfeed) || dev == inputInfo.keyboard);
}
-
#ifdef XEVIE
_X_EXPORT WindowPtr xeviewin;
_X_EXPORT HotSpot xeviehot;
@@ -281,6 +308,9 @@ static WindowPtr XYToWindow(
int y
);
+/**
+ * Max event opcode.
+ */
extern int lastEvent;
static Mask lastEventMask;
@@ -890,6 +920,13 @@ PointerConfinedToScreen(DeviceIntPtr pDev)
return pDev->spriteInfo->sprite->confined;
}
+/**
+ * Update the sprite cursor to the given cursor.
+ *
+ * ChangeToCursor() will display the new cursor and free the old cursor (if
+ * applicable). If the provided cursor is already the updated cursor, nothing
+ * happens.
+ */
static void
ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
{
@@ -917,7 +954,9 @@ ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
}
}
-/* returns true if b is a descendent of a */
+/**
+ * @returns true if b is a descendent of a
+ */
Bool
IsParent(WindowPtr a, WindowPtr b)
{
@@ -926,6 +965,11 @@ IsParent(WindowPtr a, WindowPtr b)
return FALSE;
}
+/**
+ * Update the cursor displayed on the screen.
+ *
+ * Called whenever a cursor may have changed shape or position.
+ */
static void
PostNewCursor(DeviceIntPtr pDev)
{
@@ -977,18 +1021,27 @@ GetCurrentRootWindow(DeviceIntPtr dev)
return RootWindow(dev);
}
+/**
+ * @return window underneath the cursor sprite.
+ */
_X_EXPORT WindowPtr
GetSpriteWindow(DeviceIntPtr pDev)
{
return pDev->spriteInfo->sprite->win;
}
+/**
+ * @return current sprite cursor.
+ */
_X_EXPORT CursorPtr
GetSpriteCursor(DeviceIntPtr pDev)
{
return pDev->spriteInfo->sprite->current;
}
+/**
+ * Set x/y current sprite position in screen coordinates.
+ */
_X_EXPORT void
GetSpritePosition(DeviceIntPtr pDev, int *px, int *py)
{
@@ -1315,6 +1368,19 @@ CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
ComputeFreezes();
}
+/**
+ * Activate a pointer grab on the given device. A pointer grab will cause all
+ * core pointer events to be delivered to the grabbing client only. Can cause
+ * the cursor to change if a grab cursor is set.
+ *
+ * As a pointer grab can only be issued on the core devices, mouse is always
+ * inputInfo.pointer. Extension devices are set up for ActivateKeyboardGrab().
+ *
+ * @param mouse The device to grab.
+ * @param grab The grab structure, needs to be setup.
+ * @param autoGrab True if the grab was caused by a button down event and not
+ * explicitely by a client.
+ */
void
ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
TimeStamp time, Bool autoGrab)
@@ -1346,6 +1412,12 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
}
+/**
+ * Delete grab on given device, update the sprite.
+ *
+ * As a pointer grab can only be issued on the core devices, mouse is always
+ * inputInfo.pointer. Extension devices are set up for ActivateKeyboardGrab().
+ */
void
DeactivatePointerGrab(DeviceIntPtr mouse)
{
@@ -1371,6 +1443,11 @@ DeactivatePointerGrab(DeviceIntPtr mouse)
ComputeFreezes();
}
+/**
+ * Activate a keyboard grab on the given device.
+ *
+ * Extension devices have ActivateKeyboardGrab() set as their grabbing proc.
+ */
void
ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
{
@@ -1397,6 +1474,9 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
}
+/**
+ * Delete keyboard grab for the given device.
+ */
void
DeactivateKeyboardGrab(DeviceIntPtr keybd)
{
@@ -1550,6 +1630,11 @@ AllowSome(ClientPtr client,
}
}
+/**
+ * Server-side protocol handling for AllowEvents request.
+ *
+ * Release some events from a frozen device. Only applicable for core devices.
+ */
int
ProcAllowEvents(ClientPtr client)
{
@@ -1593,6 +1678,9 @@ ProcAllowEvents(ClientPtr client)
return Success;
}
+/**
+ * Deactivate grabs from any device that has been grabbed by the client.
+ */
void
ReleaseActiveGrabs(ClientPtr client)
{
@@ -1625,6 +1713,30 @@ ReleaseActiveGrabs(ClientPtr client)
* The following procedures deal with delivering events *
**************************************************************************/
+/**
+ * Deliver the given events to the given client.
+ *
+ * More than one event may be delivered at a time. This is the case with
+ * DeviceMotionNotifies which may be followed by DeviceValuator events.
+ *
+ * TryClientEvents() is the last station before actually writing the events to
+ * the socket. Anything that is not filtered here, will get delivered to the
+ * client.
+ * An event is only delivered if
+ * - mask and filter match up.
+ * - no other client has a grab on the device that caused the event.
+ *
+ *
+ * @param client The target client to deliver to.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param mask Event mask as set by the window.
+ * @param filter Mask based on event type.
+ * @param grab Possible grab on the device that caused the event.
+ *
+ * @return 1 if event was delivered, 0 if not or -1 if grab was not set by the
+ * client.
+ */
_X_EXPORT int
TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
Mask filter, GrabPtr grab)
@@ -1703,6 +1815,23 @@ TryClientEvents (ClientPtr client, xEvent *pEvents, int count, Mask mask,
}
}
+/**
+ * Deliver events to a window. At this point, we do not yet know if the event
+ * actually needs to be delivered. May activate a grab if the event is a
+ * button press.
+ *
+ * More than one event may be delivered at a time. This is the case with
+ * DeviceMotionNotifies which may be followed by DeviceValuator events.
+ *
+ * @param pWin The window that would get the event.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param filter Mask based on event type.
+ * @param grab Possible grab on the device that caused the event.
+ * @param mskidx Mask index, depending on device that caused event.
+ *
+ * @return Number of events delivered to various clients.
+ */
int
DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
*pEvents, int count, Mask filter, GrabPtr grab, int mskidx)
@@ -1838,6 +1967,15 @@ XineramaTryClientEventsResult(
}
#endif
+/**
+ * Try to deliver events to the interested parties.
+ *
+ * @param pWin The window that would get the event.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param filter Mask based on event type.
+ * @param dontClient Don't deliver to the dontClient.
+ */
int
MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
int count, Mask filter, ClientPtr dontClient)
@@ -1875,6 +2013,14 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
return 2;
}
+/**
+ * Adjust event fields to comply with the window properties.
+ *
+ * @param xE Event to be modified in place
+ * @param pWin The window to get the information from.
+ * @param child Child window setting for event (if applicable)
+ * @param calcChild If True, calculate the child window.
+ */
static void
FixUpEventFromWindow(
DeviceIntPtr pDev,
@@ -1932,6 +2078,22 @@ FixUpEventFromWindow(
}
}
+/**
+ * Deliver events caused by input devices. Called for all core input events
+ * and XI events. No filtering of events happens before DeliverDeviceEvents(),
+ * it will be called for any event that comes out of the event queue.
+ *
+ * For all core events, dev is either inputInfo.pointer or inputInfo.keyboard.
+ * For all extension events, dev is the device that caused the event.
+ *
+ * @param pWin Window to deliver event to.
+ * @param xE Events to deliver.
+ * @param grab Possible grab on a device.
+ * @param stopAt Don't recurse up to the root window.
+ * @param dev The device that is responsible for the event.
+ * @param count number of events in xE.
+ *
+ */
int
DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
WindowPtr stopAt, DeviceIntPtr dev, int count)
@@ -1995,7 +2157,19 @@ DeliverDeviceEvents(WindowPtr pWin, xEvent *xE, GrabPtr grab,
return 0;
}
-/* not useful for events that propagate up the tree or extension events */
+/**
+ * Deliver event to a window and it's immediate parent. Used for most window
+ * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that
+ * propagate up the tree or extension events
+ *
+ * In case of a ReparentNotify event, the event will be delivered to the
+ * otherParent as well.
+ *
+ * @param pWin Window to deliver events to.
+ * @param xE Events to deliver.
+ * @param count number of events in xE.
+ * @param otherParent Used for ReparentNotify events.
+ */
_X_EXPORT int
DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
WindowPtr otherParent)
@@ -2062,6 +2236,17 @@ PointInBorderSize(WindowPtr pWin, int x, int y)
return FALSE;
}
+/**
+ * Traversed from the root window to the window at the position x/y. While
+ * traversing, it sets up the traversal history in the spriteTrace array.
+ * After completing, the spriteTrace history is set in the following way:
+ * spriteTrace[0] ... root window
+ * spriteTrace[1] ... top level window that encloses x/y
+ * ...
+ * spriteTrace[spriteTraceGood - 1] ... window at x/y
+ *
+ * @returns the window at the given coordinates.
+ */
static WindowPtr
XYToWindow(DeviceIntPtr pDev, int x, int y)
{
@@ -2113,6 +2298,12 @@ XYToWindow(DeviceIntPtr pDev, int x, int y)
return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
}
+/**
+ * Update the sprite coordinates based on the event. Update the cursor
+ * position, then update the event with the new coordinates that may have been
+ * changed. If the window underneath the sprite has changed, change to new
+ * cursor and send enter/leave events.
+ */
Bool
CheckMotion(xEvent *xE, DeviceIntPtr pDev)
{
@@ -2191,6 +2382,10 @@ CheckMotion(xEvent *xE, DeviceIntPtr pDev)
return TRUE;
}
+/**
+ * Windows have restructured, we need to update the sprite position and the
+ * sprite's cursor.
+ */
_X_EXPORT void
WindowsRestructured(void)
{
@@ -2257,6 +2452,10 @@ void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
}
#endif
+/**
+ * Set the given window to sane values, display the cursor in the center of
+ * the screen. Called from main() with the root window on the first screen.
+ */
void
DefineInitialRootWindow(WindowPtr win)
{
@@ -2537,6 +2736,10 @@ XineramaWarpPointer(ClientPtr client)
#endif
+/**
+ * Server-side protocol handling for WarpPointer request.
+ * Warps the cursor position to the coordinates given in the request.
+ */
int
ProcWarpPointer(ClientPtr client)
{
@@ -2648,8 +2851,15 @@ BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
return FALSE;
}
-/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
- passive grab set on the window to be activated. */
+/**
+ * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ * passive grab set on the window to be activated.
+ *
+ * @param pWin The window that may be subject to a passive grab.
+ * @param device Device that caused the event.
+ * @param xE List of events (multiple ones for DeviceMotionNotify)
+ * @count number of elements in xE.
+ */
static Bool
CheckPassiveGrabsOnWindow(
@@ -2803,6 +3013,16 @@ CheckDeviceGrabs(DeviceIntPtr device, xEvent *xE,
return FALSE;
}
+/**
+ * Called for keyboard events to deliver event to whatever client owns the
+ * focus. Event is delivered to the keyboard's focus window, the root window
+ * or to the window owning the input focus.
+ *
+ * @param keybd The keyboard originating the event.
+ * @param xE The event list.
+ * @param window Window underneath the sprite.
+ * @param count number of events in xE.
+ */
void
DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
{
@@ -2834,6 +3054,13 @@ DeliverFocusedEvent(DeviceIntPtr keybd, xEvent *xE, WindowPtr window, int count)
NullGrab, mskidx);
}
+/**
+ * Deliver an event from a device that is currently grabbed. Uses
+ * DeliverDeviceEvents() for further delivery if a ownerEvents is set on the
+ * grab. If not, TryClientEvents() is used.
+ *
+ * @param deactivateGrab True if the device's grab should be deactivated.
+ */
void
DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
Bool deactivateGrab, int count)
@@ -2930,6 +3157,17 @@ DeliverGrabbedEvent(xEvent *xE, DeviceIntPtr thisDev,
}
}
+/**
+ * Main keyboard event processing function for core keyboard events.
+ * Updates the events fields from the current pointer state and delivers the
+ * event.
+ *
+ * For key events, xE will always be a single event.
+ *
+ * @param xE Event list
+ * @param keybd The device that caused an event.
+ * @param count Number of elements in xE.
+ */
void
#ifdef XKB
CoreProcessKeyboardEvent (xEvent *xE, DeviceIntPtr keybd, int count)
@@ -3133,6 +3371,18 @@ FixKeyState (xEvent *xE, DeviceIntPtr keybd)
}
#endif
+/**
+ * Main pointer event processing function for core pointer events.
+ * For motion events: update the sprite.
+ * For all other events: Update the event fields based on the current sprite
+ * state.
+ *
+ * For core pointer events, xE will always be a single event.
+ *
+ * @param xE Event list
+ * @param mouse The device that caused an event.
+ * @param count Number of elements in xE.
+ */
void
#ifdef XKB
CoreProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
@@ -3248,6 +3498,18 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
#define AtMostOneClient \
(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+/**
+ * Recalculate which events may be deliverable for the given window.
+ * Recalculated mask is used for quicker determination which events may be
+ * delivered to a window.
+ *
+ * The otherEventMasks on a WindowOptional is the combination of all event
+ * masks set by all clients on the window.
+ * deliverableEventMask is the combination of the eventMask and the
+ * otherEventMask.
+ *
+ * Traverses to siblings and parents of the window.
+ */
void
RecalculateDeliverableEvents(pWin)
WindowPtr pWin;
@@ -3446,6 +3708,9 @@ EventSuppressForWindow(WindowPtr pWin, ClientPtr client,
return Success;
}
+/**
+ * @return The window that is the first ancestor of both a and b.
+ */
static WindowPtr
CommonAncestor(
WindowPtr a,
@@ -3456,6 +3721,10 @@ CommonAncestor(
return NullWindow;
}
+/**
+ * Assembles an EnterNotify or LeaveNotify and sends it event to the client.
+ * The core devices are used to fill in the event fields.
+ */
static void
EnterLeaveEvent(
DeviceIntPtr mouse,
@@ -3610,6 +3879,10 @@ EnterLeaveEvent(
}
}
+/**
+ * Send enter notifies to all parent windows up to ancestor.
+ * This function recurses.
+ */
static void
EnterNotifies(DeviceIntPtr pDev,
WindowPtr ancestor,
@@ -3625,6 +3898,11 @@ EnterNotifies(DeviceIntPtr pDev,
EnterLeaveEvent(pDev, EnterNotify, mode, detail, parent,
child->drawable.id); }
+
+/**
+ * Send leave notifies to all parent windows up to ancestor.
+ * This function recurses.
+ */
static void
LeaveNotifies(DeviceIntPtr pDev,
WindowPtr child,
@@ -3644,6 +3922,13 @@ LeaveNotifies(DeviceIntPtr pDev,
}
}
+/**
+ * Figure out if enter/leave events are necessary and send them to the
+ * appropriate windows.
+ *
+ * @param fromWin Window the sprite moved out of.
+ * @param toWin Window the sprite moved into.
+ */
static void
DoEnterLeaveEvents(DeviceIntPtr pDev,
WindowPtr fromWin,
@@ -3933,6 +4218,23 @@ DoFocusEvents(DeviceIntPtr dev, WindowPtr fromWin, WindowPtr toWin, int mode)
}
}
+/**
+ * Set the input focus to the given window. Subsequent keyboard events will be
+ * delivered to the given window.
+ *
+ * Usually called from ProcSetInputFocus as result of a client request. If so,
+ * the device is the inputInfo.keyboard.
+ * If called from ProcXSetInputFocus as result of a client xinput request, the
+ * device is set to the device specified by the client.
+ *
+ * @param client Client that requested input focus change.
+ * @param dev Focus device.
+ * @param focusID The window to obtain the focus. Can be PointerRoot or None.
+ * @param revertTo Specifies where the focus reverts to when window becomes
+ * unviewable.
+ * @param ctime Specifies the time.
+ * @param followOK True if pointer is allowed to follow the keyboard.
+ */
int
SetInputFocus(
ClientPtr client,
@@ -4023,6 +4325,11 @@ SetInputFocus(
return Success;
}
+/**
+ * Server-side protocol handling for SetInputFocus request.
+ *
+ * Sets the input focus for the virtual core keyboard.
+ */
int
ProcSetInputFocus(client)
ClientPtr client;
@@ -4039,6 +4346,12 @@ ProcSetInputFocus(client)
stuff->revertTo, stuff->time, FALSE);
}
+/**
+ * Server-side protocol handling for GetInputFocus request.
+ *
+ * Sends the current input focus for the virtual core keyboard back to the
+ * client.
+ */
int
ProcGetInputFocus(ClientPtr client)
{
@@ -4061,6 +4374,12 @@ ProcGetInputFocus(ClientPtr client)
return Success;
}
+/**
+ * Server-side protocol handling for Grabpointer request.
+ *
+ * Sets an active grab on the inputInfo.pointer and returns success status to
+ * client.
+ */
int
ProcGrabPointer(ClientPtr client)
{
@@ -4171,6 +4490,14 @@ ProcGrabPointer(ClientPtr client)
return Success;
}
+/**
+ * Server-side protocol handling for ChangeActivePointerGrab request.
+ *
+ * Changes properties of the grab hold by the client. If the client does not
+ * hold an active grab on the device, nothing happens.
+ *
+ * Works on the core pointer only.
+ */
int
ProcChangeActivePointerGrab(ClientPtr client)
{
@@ -4217,6 +4544,11 @@ ProcChangeActivePointerGrab(ClientPtr client)
return Success;
}
+/**
+ * Server-side protocol handling for UngrabPointer request.
+ *
+ * Deletes the pointer grab on the core pointer device.
+ */
int
ProcUngrabPointer(ClientPtr client)
{
@@ -4236,6 +4568,24 @@ ProcUngrabPointer(ClientPtr client)
return Success;
}
+/**
+ * Sets a grab on the given device.
+ *
+ * Called from ProcGrabKeyboard to work on the inputInfo.keyboard.
+ * Called from ProcXGrabDevice to work on the device specified by the client.
+ *
+ * The parameters this_mode and other_mode represent the keyboard_mode and
+ * pointer_mode parameters of XGrabKeyboard().
+ * See man page for details on all the parameters
+ *
+ * @param client Client that owns the grab.
+ * @param dev The device to grab.
+ * @param this_mode GrabModeSync or GrabModeAsync
+ * @param other_mode GrabModeSync or GrabModeAsync
+ * @param status Return code to be returned to the caller.
+ *
+ * @returns Success or BadValue.
+ */
int
GrabDevice(ClientPtr client, DeviceIntPtr dev,
unsigned this_mode, unsigned other_mode, Window grabWindow,
@@ -4301,6 +4651,11 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
return Success;
}
+/**
+ * Server-side protocol handling for GrabKeyboard request.
+ *
+ * Grabs the inputInfo.keyboad and returns success status to client.
+ */
int
ProcGrabKeyboard(ClientPtr client)
{
@@ -4330,6 +4685,11 @@ ProcGrabKeyboard(ClientPtr client)
return Success;
}
+/**
+ * Server-side protocol handling for UngrabKeyboard request.
+ *
+ * Deletes a possible grab on the inputInfo.keyboard.
+ */
int
ProcUngrabKeyboard(ClientPtr client)
{
@@ -4349,6 +4709,11 @@ ProcUngrabKeyboard(ClientPtr client)
return Success;
}
+/**
+ * Server-side protocol handling for QueryPointer request.
+ *
+ * Returns the current state and position of the core pointer to the client.
+ */
int
ProcQueryPointer(ClientPtr client)
{
@@ -4409,6 +4774,10 @@ ProcQueryPointer(ClientPtr client)
return(Success);
}
+/**
+ * Initializes the device list and the DIX sprite to sane values. Allocates
+ * trace memory used for quick window traversal.
+ */
void
InitEvents(void)
{
@@ -4457,6 +4826,11 @@ CloseDownEvents(void)
}
+/**
+ * Server-side protocol handling for SendEvent request.
+ *
+ * Locates the window to send the event to and forwards the event.
+ */
int
ProcSendEvent(ClientPtr client)
{
@@ -4545,6 +4919,12 @@ ProcSendEvent(ClientPtr client)
return Success;
}
+/**
+ * Server-side protocol handling for UngrabKey request.
+ *
+ * Deletes a passive grab for the given key. Only works on the
+ * inputInfo.keyboard.
+ */
int
ProcUngrabKey(ClientPtr client)
{
@@ -4587,6 +4967,12 @@ ProcUngrabKey(ClientPtr client)
return(Success);
}
+/**
+ * Server-side protocol handling for GrabKey request.
+ *
+ * Creates a grab for the inputInfo.keyboard and adds it to the list of
+ * passive grabs.
+ */
int
ProcGrabKey(ClientPtr client)
{
@@ -4642,6 +5028,12 @@ ProcGrabKey(ClientPtr client)
}
+/**
+ * Server-side protocol handling for GrabButton request.
+ *
+ * Creates a grab for the inputInfo.pointer and adds it as a passive grab to
+ * the list.
+ */
int
ProcGrabButton(ClientPtr client)
{
@@ -4715,6 +5107,11 @@ ProcGrabButton(ClientPtr client)
return AddPassiveGrabToList(grab);
}
+/**
+ * Server-side protocol handling for UngrabButton request.
+ *
+ * Deletes a passive grab on the inputInfo.pointer from the list.
+ */
int
ProcUngrabButton(ClientPtr client)
{
@@ -4748,6 +5145,17 @@ ProcUngrabButton(ClientPtr client)
return(Success);
}
+/**
+ * Deactivate any grab that may be on the window, remove the focus.
+ * Delete any XInput extension events from the window too. Does not change the
+ * window mask. Use just before the window is deleted.
+ *
+ * If freeResources is set, passive grabs on the window are deleted.
+ *
+ * @param pWin The window to delete events from.
+ * @param freeResources True if resources associated with the window should be
+ * deleted.
+ */
void
DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
{
@@ -4859,7 +5267,9 @@ DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
}
/**
- * Call this whenever some window at or below pWin has changed geometry
+ * Call this whenever some window at or below pWin has changed geometry. If
+ * there is a grab on the window, the cursor will be re-confined into the
+ * window.
*/
_X_EXPORT void
CheckCursorConfinement(WindowPtr pWin)
@@ -4903,6 +5313,9 @@ EventMaskForClient(WindowPtr pWin, ClientPtr client)
return 0;
}
+/**
+ * Server-side protocol handling for RecolorCursor request.
+ */
int
ProcRecolorCursor(ClientPtr client)
{
@@ -4945,6 +5358,20 @@ ProcRecolorCursor(ClientPtr client)
return (Success);
}
+/**
+ * Write the given events to a client, swapping the byte order if necessary.
+ * To swap the byte ordering, a callback is called that has to be set up for
+ * the given event type.
+ *
+ * In the case of DeviceMotionNotify trailed by DeviceValuators, the events
+ * can be more than one. Usually it's just one event.
+ *
+ * Do not modify the event structure passed in. See comment below.
+ *
+ * @param pClient Client to send events to.
+ * @param count Number of events.
+ * @param events The event list.
+ */
_X_EXPORT void
WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
{
diff --git a/fb/fbcompose.c b/fb/fbcompose.c
index 6ea948307..24b552e0b 100644
--- a/fb/fbcompose.c
+++ b/fb/fbcompose.c
@@ -40,6 +40,65 @@
#include "mipict.h"
#include "fbpict.h"
+static unsigned int
+SourcePictureClassify (PicturePtr pict,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ if (pict->pSourcePict->type == SourcePictTypeSolidFill)
+ {
+ pict->pSourcePict->solidFill.class = SourcePictClassHorizontal;
+ }
+ else if (pict->pSourcePict->type == SourcePictTypeLinear)
+ {
+ PictVector v;
+ xFixed_32_32 l;
+ xFixed_48_16 dx, dy, a, b, off;
+ xFixed_48_16 factors[4];
+ int i;
+
+ dx = pict->pSourcePict->linear.p2.x - pict->pSourcePict->linear.p1.x;
+ dy = pict->pSourcePict->linear.p2.y - pict->pSourcePict->linear.p1.y;
+ l = dx * dx + dy * dy;
+ if (l)
+ {
+ a = (dx << 32) / l;
+ b = (dy << 32) / l;
+ }
+ else
+ {
+ a = b = 0;
+ }
+
+ off = (-a * pict->pSourcePict->linear.p1.x
+ -b * pict->pSourcePict->linear.p1.y) >> 16;
+
+ for (i = 0; i < 3; i++)
+ {
+ v.vector[0] = IntToxFixed ((i % 2) * (width - 1) + x);
+ v.vector[1] = IntToxFixed ((i / 2) * (height - 1) + y);
+ v.vector[2] = xFixed1;
+
+ if (pict->transform)
+ {
+ if (!PictureTransformPoint3d (pict->transform, &v))
+ return SourcePictClassUnknown;
+ }
+
+ factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
+ }
+
+ if (factors[2] == factors[0])
+ pict->pSourcePict->linear.class = SourcePictClassHorizontal;
+ else if (factors[1] == factors[0])
+ pict->pSourcePict->linear.class = SourcePictClassVertical;
+ }
+
+ return pict->pSourcePict->solidFill.class;
+}
+
#define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
#define SCANLINE_BUFFER_LENGTH 2048
@@ -86,9 +145,9 @@ fbFetch_x8b8g8r8 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexe
const CARD32 *end = pixel + width;
while (pixel < end) {
WRITE(buffer++, 0xff000000 |
- ((READ(pixel) & 0x0000ff00) |
- ((READ(pixel) >> 16) & 0xff) |
- ((READ(pixel) & 0xff) << 16)));
+ ((READ(pixel) & 0x0000ff00) |
+ ((READ(pixel) >> 16) & 0xff) |
+ ((READ(pixel) & 0xff) << 16)));
++pixel;
}
}
@@ -132,8 +191,8 @@ fbFetch_r5g6b5 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedP
while (pixel < end) {
CARD32 p = READ(pixel++);
CARD32 r = (((p) << 3) & 0xf8) |
- (((p) << 5) & 0xfc00) |
- (((p) << 8) & 0xf80000);
+ (((p) << 5) & 0xfc00) |
+ (((p) << 8) & 0xf80000);
r |= (r >> 5) & 0x70007;
r |= (r >> 6) & 0x300;
WRITE(buffer++, 0xff000000 | r);
@@ -335,7 +394,7 @@ fbFetch_b2g3r3 (const FbBits *bits, int x, int width, CARD32 *buffer, miIndexedP
((p & 0x07) << 3) |
((p & 0x06) << 6)) << 16;
WRITE(buffer++, (0xff000000 | r | g | b));
- }
+ }
}
static FASTCALL void
@@ -558,7 +617,7 @@ static fetchProc fetchProcForPicture (PicturePtr pict)
case PICT_c8: return fbFetch_c8;
case PICT_g8: return fbFetch_c8;
case PICT_x4a4: return fbFetch_x4a4;
-
+
/* 4bpp formats */
case PICT_a4: return fbFetch_a4;
case PICT_r1g2b1: return fbFetch_r1g2b1;
@@ -1095,8 +1154,8 @@ fbStore_r5g6b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP
for (i = 0; i < width; ++i) {
CARD32 s = READ(values + i);
WRITE(pixel++, ((s >> 3) & 0x001f) |
- ((s >> 5) & 0x07e0) |
- ((s >> 8) & 0xf800));
+ ((s >> 5) & 0x07e0) |
+ ((s >> 8) & 0xf800));
}
}
@@ -1108,8 +1167,8 @@ fbStore_b5g6r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((b << 8) & 0xf800) |
- ((g << 3) & 0x07e0) |
- ((r >> 3) ));
+ ((g << 3) & 0x07e0) |
+ ((r >> 3) ));
}
}
@@ -1121,9 +1180,9 @@ fbStore_a1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
WRITE(pixel++, ((a << 8) & 0x8000) |
- ((r << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((b >> 3) ));
+ ((r << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((b >> 3) ));
}
}
@@ -1135,8 +1194,8 @@ fbStore_x1r5g5b5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((r << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((b >> 3) ));
+ ((g << 2) & 0x03e0) |
+ ((b >> 3) ));
}
}
@@ -1148,10 +1207,10 @@ fbStore_a1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
WRITE(pixel++, ((a << 8) & 0x8000) |
- ((b << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((r >> 3) ));
- }
+ ((b << 7) & 0x7c00) |
+ ((g << 2) & 0x03e0) |
+ ((r >> 3) ));
+ }
}
static FASTCALL void
@@ -1162,8 +1221,8 @@ fbStore_x1b5g5r5 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((b << 7) & 0x7c00) |
- ((g << 2) & 0x03e0) |
- ((r >> 3) ));
+ ((g << 2) & 0x03e0) |
+ ((r >> 3) ));
}
}
@@ -1175,9 +1234,9 @@ fbStore_a4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
WRITE(pixel++, ((a << 8) & 0xf000) |
- ((r << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((b >> 4) ));
+ ((r << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((b >> 4) ));
}
}
@@ -1189,8 +1248,8 @@ fbStore_x4r4g4b4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((r << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((b >> 4) ));
+ ((g ) & 0x00f0) |
+ ((b >> 4) ));
}
}
@@ -1202,9 +1261,9 @@ fbStore_a4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
WRITE(pixel++, ((a << 8) & 0xf000) |
- ((b << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((r >> 4) ));
+ ((b << 4) & 0x0f00) |
+ ((g ) & 0x00f0) |
+ ((r >> 4) ));
}
}
@@ -1216,8 +1275,8 @@ fbStore_x4b4g4r4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((b << 4) & 0x0f00) |
- ((g ) & 0x00f0) |
- ((r >> 4) ));
+ ((g ) & 0x00f0) |
+ ((r >> 4) ));
}
}
@@ -1239,8 +1298,8 @@ fbStore_r3g3b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((r ) & 0xe0) |
- ((g >> 3) & 0x1c) |
- ((b >> 6) ));
+ ((g >> 3) & 0x1c) |
+ ((b >> 6) ));
}
}
@@ -1252,8 +1311,8 @@ fbStore_b2g3r3 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedP
for (i = 0; i < width; ++i) {
Split(READ(values + i));
WRITE(pixel++, ((b ) & 0xe0) |
- ((g >> 3) & 0x1c) |
- ((r >> 6) ));
+ ((g >> 3) & 0x1c) |
+ ((r >> 6) ));
}
}
@@ -1265,9 +1324,9 @@ fbStore_a2r2g2b2 (FbBits *bits, const CARD32 *values, int x, int width, miIndexe
for (i = 0; i < width; ++i) {
Splita(READ(values + i));
WRITE(pixel++, ((a ) & 0xc0) |
- ((r >> 2) & 0x30) |
- ((g >> 4) & 0x0c) |
- ((b >> 6) ));
+ ((r >> 2) & 0x30) |
+ ((g >> 4) & 0x0c) |
+ ((b >> 6) ));
}
}
@@ -1293,11 +1352,11 @@ fbStore_x4a4 (FbBits *bits, const CARD32 *values, int x, int width, miIndexedPtr
#define Store8(l,o,v) (((CARD8 *) l)[(o) >> 3] = (v))
#if IMAGE_BYTE_ORDER == MSBFirst
-#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
- (Fetch8(l,o) & 0xf0) | (v) : \
+#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
+ (Fetch8(l,o) & 0xf0) | (v) : \
(Fetch8(l,o) & 0x0f) | ((v) << 4)))
#else
-#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
+#define Store4(l,o,v) Store8(l,o,((o) & 4 ? \
(Fetch8(l,o) & 0x0f) | ((v) << 4) : \
(Fetch8(l,o) & 0xf0) | (v)))
#endif
@@ -1655,22 +1714,22 @@ fbCombineSaturateU (CARD32 *dest, const CARD32 *src, int width)
A nor B, areas covered only by A, areas covered only by B and finally
areas covered by both A and B.
- Disjoint Conjoint
- Fa Fb Fa Fb
-(0,0,0,0) 0 0 0 0
-(0,A,0,A) 1 0 1 0
-(0,0,B,B) 0 1 0 1
-(0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
-(0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
-(0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
-(0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
-(0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
-(0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
-(0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
-(0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
-(0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
-
- */
+ Disjoint Conjoint
+ Fa Fb Fa Fb
+ (0,0,0,0) 0 0 0 0
+ (0,A,0,A) 1 0 1 0
+ (0,0,B,B) 0 1 0 1
+ (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0)
+ (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1
+ (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0
+ (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1)
+ (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0
+ (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0)
+ (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0)
+ (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b)
+ (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0)
+
+*/
#define CombineAOut 1
#define CombineAIn 2
@@ -2005,114 +2064,116 @@ static CombineFuncU fbCombineFuncU[] = {
fbCombineConjointXorU,
};
-static FASTCALL void
-fbCombineMaskC (CARD32 *src, CARD32 *mask, int width)
+static INLINE void
+fbCombineMaskC (CARD32 *src, CARD32 *mask)
{
- int i;
- for (i = 0; i < width; ++i) {
- CARD32 a = READ(mask + i);
+ CARD32 a = *mask;
- CARD32 x;
- CARD16 xa;
+ CARD32 x;
+ CARD16 xa;
- if (!a)
- {
- WRITE(src + i, 0);
- continue;
- }
-
- x = READ(src + i);
- if (a == 0xffffffff)
- {
- x = x >> 24;
- x |= x << 8;
- x |= x << 16;
- WRITE(mask + i, x);
- continue;
- }
+ if (!a)
+ {
+ WRITE(src, 0);
+ return;
+ }
- xa = x >> 24;
- FbByteMulC(x, a);
- WRITE(src + i, x);
- FbByteMul(a, xa);
- WRITE(mask + i, a);
+ x = READ(src);
+ if (a == 0xffffffff)
+ {
+ x = x >> 24;
+ x |= x << 8;
+ x |= x << 16;
+ WRITE(mask, x);
+ return;
}
+
+ xa = x >> 24;
+ FbByteMulC(x, a);
+ WRITE(src, x);
+ FbByteMul(a, xa);
+ WRITE(mask, a);
}
-static FASTCALL void
-fbCombineMaskValueC (CARD32 *src, const CARD32 *mask, int width)
+static INLINE void
+fbCombineMaskValueC (CARD32 *src, const CARD32 *mask)
{
- int i;
- for (i = 0; i < width; ++i) {
- CARD32 a = READ(mask + i);
- CARD32 x;
+ CARD32 a = READ(mask);
+ CARD32 x;
- if (!a)
- {
- WRITE(src + i, 0);
- continue;
- }
+ if (!a)
+ {
+ WRITE(src, 0);
+ return;
+ }
- if (a == 0xffffffff)
- continue;
+ if (a == 0xffffffff)
+ return;
- x = READ(src + i);
- FbByteMulC(x, a);
- WRITE(src + i, x);
- }
+ x = READ(src);
+ FbByteMulC(x, a);
+ WRITE(src,x);
}
-
-static FASTCALL void
-fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask, int width)
+static INLINE void
+fbCombineMaskAlphaC (const CARD32 *src, CARD32 *mask)
{
- int i;
- for (i = 0; i < width; ++i) {
- CARD32 a = READ(mask + i);
- CARD32 x;
+ CARD32 a = READ(mask);
+ CARD32 x;
- if (!a)
- continue;
-
- x = READ(src + i) >> 24;
- if (x == 0xff)
- continue;
- if (a == 0xffffffff)
- {
- x = x >> 24;
- x |= x << 8;
- x |= x << 16;
- WRITE(mask + i, x);
- continue;
- }
+ if (!a)
+ return;
- FbByteMul(a, x);
- WRITE(mask + i, a);
+ x = READ(src) >> 24;
+ if (x == 0xff)
+ return;
+ if (a == 0xffffffff)
+ {
+ x = x >> 24;
+ x |= x << 8;
+ x |= x << 16;
+ WRITE(mask, x);
+ return;
}
+
+ FbByteMul(a, x);
+ WRITE(mask, a);
}
static FASTCALL void
fbCombineClearC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
- memset(dest, 0, width*sizeof(CARD32));
+ MEMSET_WRAPPED(dest, 0, width*sizeof(CARD32));
}
static FASTCALL void
fbCombineSrcC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
- fbCombineMaskValueC(src, mask, width);
- MEMCPY_WRAPPED(dest, src, width*sizeof(CARD32));
+ int i;
+
+ for (i = 0; i < width; ++i) {
+ CARD32 s = READ(src + i);
+ CARD32 m = READ(mask + i);
+
+ fbCombineMaskValueC (&s, &m);
+
+ WRITE(dest, s);
+ }
}
static FASTCALL void
fbCombineOverC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
- CARD32 s = READ(src + i);
- CARD32 a = ~READ(mask + i);
+ CARD32 s = READ(src + i);
+ CARD32 m = READ(mask + i);
+ CARD32 a;
+
+ fbCombineMaskC (&s, &m);
+ a = ~m;
if (a != 0xffffffff)
{
if (a)
@@ -2130,7 +2191,7 @@ static FASTCALL void
fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskValueC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 d = READ(dest + i);
CARD32 a = ~d >> 24;
@@ -2138,6 +2199,10 @@ fbCombineOverReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
if (a)
{
CARD32 s = READ(src + i);
+ CARD32 m = READ(mask + i);
+
+ fbCombineMaskValueC (&s, &m);
+
if (a != 0xff)
{
FbByteMulAdd(s, a, d);
@@ -2151,14 +2216,17 @@ static FASTCALL void
fbCombineInC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskValueC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 d = READ(dest + i);
CARD16 a = d >> 24;
CARD32 s = 0;
if (a)
{
- s = READ(src + i);
+ CARD32 m = READ(mask + i);
+
+ s = READ(src + i);
+ fbCombineMaskValueC (&s, &m);
if (a != 0xff)
{
FbByteMul(s, a);
@@ -2172,10 +2240,15 @@ static FASTCALL void
fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskAlphaC(src, mask, width);
+
for (i = 0; i < width; ++i) {
- CARD32 a = READ(mask + i);
+ CARD32 s = READ(src + i);
+ CARD32 m = READ(mask + i);
+ CARD32 a;
+
+ fbCombineMaskAlphaC (&s, &m);
+ a = m;
if (a != 0xffffffff)
{
CARD32 d = 0;
@@ -2184,7 +2257,7 @@ fbCombineInReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
d = READ(dest + i);
FbByteMulC(d, a);
}
- WRITE(dest + i, d);
+ WRITE(dest + i, d);
}
}
}
@@ -2193,14 +2266,18 @@ static FASTCALL void
fbCombineOutC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskValueC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 d = READ(dest + i);
CARD16 a = ~d >> 24;
CARD32 s = 0;
if (a)
{
- s = READ(src + i);
+ CARD32 m = READ(mask + i);
+
+ s = READ(src + i);
+ fbCombineMaskValueC (&s, &m);
+
if (a != 0xff)
{
FbByteMul(s, a);
@@ -2214,10 +2291,15 @@ static FASTCALL void
fbCombineOutReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskAlphaC(src, mask, width);
+
for (i = 0; i < width; ++i) {
- CARD32 a = ~READ(mask + i);
+ CARD32 s = READ(src + i);
+ CARD32 m = READ(mask + i);
+ CARD32 a;
+ fbCombineMaskAlphaC (&s, &m);
+
+ a = ~m;
if (a != 0xffffffff)
{
CARD32 d = 0;
@@ -2235,12 +2317,18 @@ static FASTCALL void
fbCombineAtopC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 d = READ(dest + i);
CARD32 s = READ(src + i);
- CARD32 ad = ~READ(mask + i);
+ CARD32 m = READ(mask + i);
+ CARD32 ad;
CARD16 as = d >> 24;
+
+ fbCombineMaskC (&s, &m);
+
+ ad = ~m;
+
FbByteAddMulC(d, ad, s, as);
WRITE(dest + i, d);
}
@@ -2250,13 +2338,19 @@ static FASTCALL void
fbCombineAtopReverseC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 d = READ(dest + i);
CARD32 s = READ(src + i);
- CARD32 ad = READ(mask + i);
+ CARD32 m = READ(mask + i);
+ CARD32 ad;
CARD16 as = ~d >> 24;
+
+ fbCombineMaskC (&s, &m);
+
+ ad = m;
+
FbByteAddMulC(d, ad, s, as);
WRITE(dest + i, d);
}
@@ -2266,12 +2360,18 @@ static FASTCALL void
fbCombineXorC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 d = READ(dest + i);
CARD32 s = READ(src + i);
- CARD32 ad = ~READ(mask + i);
+ CARD32 m = READ(mask + i);
+ CARD32 ad;
CARD16 as = ~d >> 24;
+
+ fbCombineMaskC (&s, &m);
+
+ ad = ~m;
+
FbByteAddMulC(d, ad, s, as);
WRITE(dest + i, d);
}
@@ -2281,10 +2381,14 @@ static FASTCALL void
fbCombineAddC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskValueC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 s = READ(src + i);
+ CARD32 m = READ(mask + i);
CARD32 d = READ(dest + i);
+
+ fbCombineMaskValueC (&s, &m);
+
FbByteAdd(d, s);
WRITE(dest + i, d);
}
@@ -2294,7 +2398,7 @@ static FASTCALL void
fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 s, d;
CARD16 sa, sr, sg, sb, da;
@@ -2303,10 +2407,14 @@ fbCombineSaturateC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width)
d = READ(dest + i);
s = READ(src + i);
- sa = (READ(mask + i) >> 24);
- sr = (READ(mask + i) >> 16) & 0xff;
- sg = (READ(mask + i) >> 8) & 0xff;
- sb = (READ(mask + i) ) & 0xff;
+ m = READ(mask + i);
+
+ fbCombineMaskC (&s, &m);
+
+ sa = (m >> 24);
+ sr = (m >> 16) & 0xff;
+ sg = (m >> 8) & 0xff;
+ sb = (m ) & 0xff;
da = ~d >> 24;
if (sb <= da)
@@ -2337,7 +2445,7 @@ static FASTCALL void
fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 s, d;
CARD32 m,n,o,p;
@@ -2347,10 +2455,14 @@ fbCombineDisjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, C
CARD8 da;
s = READ(src + i);
- sa = READ(mask + i);
+ m = READ(mask + i);
d = READ(dest + i);
da = d >> 24;
+ fbCombineMaskC (&s, &m);
+
+ sa = m;
+
switch (combine & CombineA) {
default:
Fa = 0;
@@ -2457,7 +2569,7 @@ static FASTCALL void
fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, CARD8 combine)
{
int i;
- fbCombineMaskC(src, mask, width);
+
for (i = 0; i < width; ++i) {
CARD32 s, d;
CARD32 m,n,o,p;
@@ -2467,10 +2579,14 @@ fbCombineConjointGeneralC (CARD32 *dest, CARD32 *src, CARD32 *mask, int width, C
CARD8 da;
s = READ(src + i);
- sa = READ(mask + i);
+ m = READ(mask + i);
d = READ(dest + i);
da = d >> 24;
+ fbCombineMaskC (&s, &m);
+
+ sa = m;
+
switch (combine & CombineA) {
default:
Fa = 0;
@@ -2634,7 +2750,7 @@ FbComposeFunctions composeFunctions = {
};
-static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
FbBits *bits;
FbStride stride;
@@ -2656,7 +2772,7 @@ static void fbFetchSolid(PicturePtr pict, int x, int y, int width, CARD32 *buffe
fbFinishAccess (pict->pDrawable);
}
-static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
FbBits *bits;
FbStride stride;
@@ -2676,47 +2792,239 @@ static void fbFetch(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
}
#define MOD(a,b) ((a) < 0 ? ((b) - ((-(a) - 1) % (b))) - 1 : (a) % (b))
-#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) :\
- ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
+#define DIV(a,b) ((((a) < 0) == ((b) < 0)) ? (a) / (b) : \
+ ((a) - (b) + 1 - (((b) < 0) << 1)) / (b))
+
+typedef struct
+{
+ CARD32 left_ag;
+ CARD32 left_rb;
+ CARD32 right_ag;
+ CARD32 right_rb;
+ int32_t left_x;
+ int32_t right_x;
+ int32_t stepper;
+
+ PictGradientStopPtr stops;
+ int num_stops;
+ unsigned int spread;
+ int need_reset;
+} GradientWalker;
-static CARD32 gradientPixel(const SourcePictPtr pGradient, xFixed_48_16 pos, unsigned int spread)
+static void
+_gradient_walker_init (GradientWalker *walker,
+ SourcePictPtr pGradient,
+ unsigned int spread)
{
- int ipos = (pos * PICT_GRADIENT_STOPTABLE_SIZE - 1) >> 16;
-
- /* calculate the actual offset. */
- if (ipos < 0 || ipos >= PICT_GRADIENT_STOPTABLE_SIZE) {
- if (pGradient->type == SourcePictTypeConical || spread == RepeatNormal) {
- ipos = ipos % PICT_GRADIENT_STOPTABLE_SIZE;
- ipos = ipos < 0 ? PICT_GRADIENT_STOPTABLE_SIZE + ipos : ipos;
+ walker->num_stops = pGradient->gradient.nstops;
+ walker->stops = pGradient->gradient.stops;
+ walker->left_x = 0;
+ walker->right_x = 0x10000;
+ walker->stepper = 0;
+ walker->left_ag = 0;
+ walker->left_rb = 0;
+ walker->right_ag = 0;
+ walker->right_rb = 0;
+ walker->spread = spread;
- } else if (spread == RepeatReflect) {
- const int limit = PICT_GRADIENT_STOPTABLE_SIZE * 2 - 1;
- ipos = ipos % limit;
- ipos = ipos < 0 ? limit + ipos : ipos;
- ipos = ipos >= PICT_GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos;
+ walker->need_reset = TRUE;
+}
- } else if (spread == RepeatPad) {
- if (ipos < 0)
- ipos = 0;
- else if (ipos >= PICT_GRADIENT_STOPTABLE_SIZE)
- ipos = PICT_GRADIENT_STOPTABLE_SIZE-1;
- } else { /* RepeatNone */
- return 0;
- }
+static void
+_gradient_walker_reset (GradientWalker *walker,
+ xFixed_32_32 pos)
+{
+ int32_t x, left_x, right_x;
+ xRenderColor *left_c, *right_c;
+ int n, count = walker->num_stops;
+ PictGradientStopPtr stops = walker->stops;
+
+ static const xRenderColor transparent_black = { 0, 0, 0, 0 };
+
+ switch (walker->spread)
+ {
+ case RepeatNormal:
+ x = (int32_t)pos & 0xFFFF;
+ for (n = 0; n < count; n++)
+ if (x < stops[n].x)
+ break;
+ if (n == 0) {
+ left_x = stops[count-1].x - 0x10000;
+ left_c = &stops[count-1].color;
+ } else {
+ left_x = stops[n-1].x;
+ left_c = &stops[n-1].color;
+ }
+
+ if (n == count) {
+ right_x = stops[0].x + 0x10000;
+ right_c = &stops[0].color;
+ } else {
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
+ }
+ left_x += (pos - x);
+ right_x += (pos - x);
+ break;
+
+ case RepeatPad:
+ for (n = 0; n < count; n++)
+ if (pos < stops[n].x)
+ break;
+
+ if (n == 0) {
+ left_x = INT_MIN;
+ left_c = &stops[0].color;
+ } else {
+ left_x = stops[n-1].x;
+ left_c = &stops[n-1].color;
+ }
+
+ if (n == count) {
+ right_x = INT_MAX;
+ right_c = &stops[n-1].color;
+ } else {
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
+ }
+ break;
+
+ case RepeatReflect:
+ x = (int32_t)pos & 0xFFFF;
+ if ((int32_t)pos & 0x10000)
+ x = 0x10000 - x;
+ for (n = 0; n < count; n++)
+ if (x < stops[n].x)
+ break;
+
+ if (n == 0) {
+ left_x = -stops[0].x;
+ left_c = &stops[0].color;
+ } else {
+ left_x = stops[n-1].x;
+ left_c = &stops[n-1].color;
+ }
+
+ if (n == count) {
+ right_x = 0x20000 - stops[n-1].x;
+ right_c = &stops[n-1].color;
+ } else {
+ right_x = stops[n].x;
+ right_c = &stops[n].color;
+ }
+
+ if ((int32_t)pos & 0x10000) {
+ xRenderColor *tmp_c;
+ int32_t tmp_x;
+
+ tmp_x = 0x10000 - right_x;
+ right_x = 0x10000 - left_x;
+ left_x = tmp_x;
+
+ tmp_c = right_c;
+ right_c = left_c;
+ left_c = tmp_c;
+
+ x = 0x10000 - x;
+ }
+ left_x += (pos - x);
+ right_x += (pos - x);
+ break;
+
+ default: /* RepeatNone */
+ for (n = 0; n < count; n++)
+ if (pos < stops[n].x)
+ break;
+
+ if (n == 0)
+ {
+ left_x = INT_MIN;
+ right_x = stops[0].x;
+ left_c = right_c = (xRenderColor*) &transparent_black;
+ }
+ else if (n == count)
+ {
+ left_x = stops[n-1].x;
+ right_x = INT_MAX;
+ left_c = right_c = (xRenderColor*) &transparent_black;
+ }
+ else
+ {
+ left_x = stops[n-1].x;
+ right_x = stops[n].x;
+ left_c = &stops[n-1].color;
+ right_c = &stops[n].color;
+ }
+ }
+
+ walker->left_x = left_x;
+ walker->right_x = right_x;
+ walker->left_ag = ((left_c->alpha >> 8) << 16) | (left_c->green >> 8);
+ walker->left_rb = ((left_c->red & 0xff00) << 8) | (left_c->blue >> 8);
+ walker->right_ag = ((right_c->alpha >> 8) << 16) | (right_c->green >> 8);
+ walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
+
+ if ( walker->left_x == walker->right_x ||
+ ( walker->left_ag == walker->right_ag &&
+ walker->left_rb == walker->right_rb ) )
+ {
+ walker->stepper = 0;
+ }
+ else
+ {
+ int32_t width = right_x - left_x;
+ walker->stepper = ((1 << 24) + width/2)/width;
}
- assert(ipos >= 0);
- assert(ipos < PICT_GRADIENT_STOPTABLE_SIZE);
-
- return pGradient->linear.colorTable[ipos];
+ walker->need_reset = FALSE;
}
-static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+#define GRADIENT_WALKER_NEED_RESET(w,x) \
+ ( (w)->need_reset || (x) < (w)->left_x || (x) >= (w)->right_x)
+
+
+/* the following assumes that GRADIENT_WALKER_NEED_RESET(w,x) is FALSE */
+static CARD32
+_gradient_walker_pixel (GradientWalker *walker,
+ xFixed_32_32 x)
{
- SourcePictPtr pGradient = pict->pSourcePict;
- CARD32 *end = buffer + width;
+ int dist, idist;
+ CARD32 t1, t2, a, color;
+
+ if (GRADIENT_WALKER_NEED_RESET (walker, x))
+ _gradient_walker_reset (walker, x);
+
+ dist = ((int)(x - walker->left_x)*walker->stepper) >> 16;
+ idist = 256 - dist;
+
+ /* combined INTERPOLATE and premultiply */
+ t1 = walker->left_rb*idist + walker->right_rb*dist;
+ t1 = (t1 >> 8) & 0xff00ff;
+
+ t2 = walker->left_ag*idist + walker->right_ag*dist;
+ t2 &= 0xff00ff00;
+
+ color = t2 & 0xff000000;
+ a = t2 >> 24;
+
+ t1 = t1*a + 0x800080;
+ t1 = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
+
+ t2 = (t2 >> 8)*a + 0x800080;
+ t2 = (t2 + ((t2 >> 8) & 0xff00ff));
+
+ return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
+}
+static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
+{
+ SourcePictPtr pGradient = pict->pSourcePict;
+ GradientWalker walker;
+ CARD32 *end = buffer + width;
+
+ _gradient_walker_init (&walker, pGradient, pict->repeat);
+
if (pGradient->type == SourcePictTypeSolidFill) {
register CARD32 color = pGradient->solidFill.color;
while (buffer < end) {
@@ -2726,7 +3034,7 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
PictVector v, unit;
xFixed_32_32 l;
xFixed_48_16 dx, dy, a, b, off;
-
+
/* reference point is the center of the pixel */
v.vector[0] = IntToxFixed(x) + xFixed1/2;
v.vector[1] = IntToxFixed(y) + xFixed1/2;
@@ -2761,36 +3069,207 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
t = ((a*v.vector[0] + b*v.vector[1]) >> 16) + off;
inc = (a * unit.vector[0] + b * unit.vector[1]) >> 16;
}
- while (buffer < end) {
- WRITE(buffer++, gradientPixel(pGradient, t, pict->repeatType));
- t += inc;
- }
- } else {
- /* projective transformation */
- while (buffer < end) {
- xFixed_48_16 t;
- if (v.vector[2] == 0) {
- t = 0;
+
+ if (pGradient->linear.class == SourcePictClassVertical)
+ {
+ register CARD32 color;
+
+ color = _gradient_walker_pixel( &walker, t );
+ while (buffer < end)
+ WRITE(buffer++, color);
+ }
+ else
+ {
+ if (!mask) {
+ while (buffer < end)
+ {
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ buffer += 1;
+ t += inc;
+ }
} else {
- xFixed_48_16 x, y;
- x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
- y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
- t = ((a*x + b*y) >> 16) + off;
+ while (buffer < end) {
+ if (*mask++ & maskBits)
+ {
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ }
+ buffer += 1;
+ t += inc;
+ }
}
- WRITE(buffer++, gradientPixel(pGradient, t, pict->repeatType));
- v.vector[0] += unit.vector[0];
- v.vector[1] += unit.vector[1];
- v.vector[2] += unit.vector[2];
+ }
+ }
+ else /* projective transformation */
+ {
+ xFixed_48_16 t;
+
+ if (pGradient->linear.class == SourcePictClassVertical)
+ {
+ register CARD32 color;
+
+ if (v.vector[2] == 0)
+ {
+ t = 0;
+ }
+ else
+ {
+ xFixed_48_16 x, y;
+
+ x = ((xFixed_48_16) v.vector[0] << 16) / v.vector[2];
+ y = ((xFixed_48_16) v.vector[1] << 16) / v.vector[2];
+ t = ((a * x + b * y) >> 16) + off;
+ }
+
+ color = _gradient_walker_pixel( &walker, t );
+ while (buffer < end)
+ WRITE(buffer++, color);
+ }
+ else
+ {
+ while (buffer < end)
+ {
+ if (!mask || *mask++ & maskBits)
+ {
+ if (v.vector[2] == 0) {
+ t = 0;
+ } else {
+ xFixed_48_16 x, y;
+ x = ((xFixed_48_16)v.vector[0] << 16) / v.vector[2];
+ y = ((xFixed_48_16)v.vector[1] << 16) / v.vector[2];
+ t = ((a*x + b*y) >> 16) + off;
+ }
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ }
+ ++buffer;
+ v.vector[0] += unit.vector[0];
+ v.vector[1] += unit.vector[1];
+ v.vector[2] += unit.vector[2];
+ }
}
}
} else {
+
+/*
+ * In the radial gradient problem we are given two circles (c₁,r₁) and
+ * (c₂,r₂) that define the gradient itself. Then, for any point p, we
+ * must compute the value(s) of t within [0.0, 1.0] representing the
+ * circle(s) that would color the point.
+ *
+ * There are potentially two values of t since the point p can be
+ * colored by both sides of the circle, (which happens whenever one
+ * circle is not entirely contained within the other).
+ *
+ * If we solve for a value of t that is outside of [0.0, 1.0] then we
+ * use the extend mode (NONE, REPEAT, REFLECT, or PAD) to map to a
+ * value within [0.0, 1.0].
+ *
+ * Here is an illustration of the problem:
+ *
+ * p₂
+ * p •
+ * • ╲
+ * · ╲r₂
+ * p₁ · ╲
+ * • θ╲
+ * ╲ ╌╌•
+ * ╲r₁ · c₂
+ * θ╲ ·
+ * ╌╌•
+ * c₁
+ *
+ * Given (c₁,r₁), (c₂,r₂) and p, we must find an angle θ such that two
+ * points p₁ and p₂ on the two circles are collinear with p. Then, the
+ * desired value of t is the ratio of the length of p₁p to the length
+ * of p₁p₂.
+ *
+ * So, we have six unknown values: (p₁x, p₁y), (p₂x, p₂y), θ and t.
+ * We can also write six equations that constrain the problem:
+ *
+ * Point p₁ is a distance r₁ from c₁ at an angle of θ:
+ *
+ * 1. p₁x = c₁x + r₁·cos θ
+ * 2. p₁y = c₁y + r₁·sin θ
+ *
+ * Point p₂ is a distance r₂ from c₂ at an angle of θ:
+ *
+ * 3. p₂x = c₂x + r2·cos θ
+ * 4. p₂y = c₂y + r2·sin θ
+ *
+ * Point p lies at a fraction t along the line segment p₁p₂:
+ *
+ * 5. px = t·p₂x + (1-t)·p₁x
+ * 6. py = t·p₂y + (1-t)·p₁y
+ *
+ * To solve, first subtitute 1-4 into 5 and 6:
+ *
+ * px = t·(c₂x + r₂·cos θ) + (1-t)·(c₁x + r₁·cos θ)
+ * py = t·(c₂y + r₂·sin θ) + (1-t)·(c₁y + r₁·sin θ)
+ *
+ * Then solve each for cos θ and sin θ expressed as a function of t:
+ *
+ * cos θ = (-(c₂x - c₁x)·t + (px - c₁x)) / ((r₂-r₁)·t + r₁)
+ * sin θ = (-(c₂y - c₁y)·t + (py - c₁y)) / ((r₂-r₁)·t + r₁)
+ *
+ * To simplify this a bit, we define new variables for several of the
+ * common terms as shown below:
+ *
+ * p₂
+ * p •
+ * • ╲
+ * · ┆ ╲r₂
+ * p₁ · ┆ ╲
+ * • pdy┆ ╲
+ * ╲ ┆ •c₂
+ * ╲r₁ ┆ · ┆
+ * ╲ ·┆ ┆cdy
+ * •╌╌╌╌┴╌╌╌╌╌╌╌┘
+ * c₁ pdx cdx
+ *
+ * cdx = (c₂x - c₁x)
+ * cdy = (c₂y - c₁y)
+ * dr = r₂-r₁
+ * pdx = px - c₁x
+ * pdy = py - c₁y
+ *
+ * Note that cdx, cdy, and dr do not depend on point p at all, so can
+ * be pre-computed for the entire gradient. The simplifed equations
+ * are now:
+ *
+ * cos θ = (-cdx·t + pdx) / (dr·t + r₁)
+ * sin θ = (-cdy·t + pdy) / (dr·t + r₁)
+ *
+ * Finally, to get a single function of t and eliminate the last
+ * unknown θ, we use the identity sin²θ + cos²θ = 1. First, square
+ * each equation, (we knew a quadratic was coming since it must be
+ * possible to obtain two solutions in some cases):
+ *
+ * cos²θ = (cdx²t² - 2·cdx·pdx·t + pdx²) / (dr²·t² + 2·r₁·dr·t + r₁²)
+ * sin²θ = (cdy²t² - 2·cdy·pdy·t + pdy²) / (dr²·t² + 2·r₁·dr·t + r₁²)
+ *
+ * Then add both together, set the result equal to 1, and express as a
+ * standard quadratic equation in t of the form At² + Bt + C = 0
+ *
+ * (cdx² + cdy² - dr²)·t² - 2·(cdx·pdx + cdy·pdy + r₁·dr)·t + (pdx² + pdy² - r₁²) = 0
+ *
+ * In other words:
+ *
+ * A = cdx² + cdy² - dr²
+ * B = -2·(pdx·cdx + pdy·cdy + r₁·dr)
+ * C = pdx² + pdy² - r₁²
+ *
+ * And again, notice that A does not depend on p, so can be
+ * precomputed. From here we just use the quadratic formula to solve
+ * for t:
+ *
+ * t = (-2·B ± ⎷(B² - 4·A·C)) / 2·A
+ */
/* radial or conical */
Bool affine = TRUE;
double cx = 1.;
double cy = 0.;
double cz = 0.;
- double rx = x;
- double ry = y;
+ double rx = x + 0.5;
+ double ry = y + 0.5;
double rz = 1.;
if (pict->transform) {
@@ -2812,45 +3291,89 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
}
if (pGradient->type == SourcePictTypeRadial) {
+ PictRadialGradient *radial;
+ radial = &pGradient->radial;
if (affine) {
- rx -= pGradient->radial.fx;
- ry -= pGradient->radial.fy;
-
while (buffer < end) {
- double b = 2*(rx*pGradient->radial.dx + ry*pGradient->radial.dy);
- double c = -(rx*rx + ry*ry);
- double det = (b * b) - (4 * pGradient->radial.a * c);
- double s = (-b + sqrt(det))/(2. * pGradient->radial.a);
- WRITE(buffer, gradientPixel(pGradient,
- (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
- pict->repeatType));
- ++buffer;
+ if (!mask || *mask++ & maskBits)
+ {
+ double pdx, pdy;
+ double B, C;
+ double det;
+ double c1x = radial->c1.x / 65536.0;
+ double c1y = radial->c1.y / 65536.0;
+ double r1 = radial->c1.radius / 65536.0;
+ xFixed_48_16 t;
+
+ pdx = rx - c1x;
+ pdy = ry - c1y;
+
+ B = -2 * ( pdx * radial->cdx
+ + pdy * radial->cdy
+ + r1 * radial->dr);
+ C = (pdx * pdx + pdy * pdy - r1 * r1);
+
+ det = (B * B) - (4 * radial->A * C);
+ if (det < 0.0)
+ det = 0.0;
+
+ if (radial->A < 0)
+ t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
+ else
+ t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
+
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ }
+ ++buffer;
+
rx += cx;
ry += cy;
}
} else {
+ /* projective */
while (buffer < end) {
- double x, y;
- double b, c, det, s;
- if (rz != 0) {
- x = rx/rz;
- y = ry/rz;
- } else {
- x = y = 0.;
- }
- x -= pGradient->radial.fx;
- y -= pGradient->radial.fy;
- b = 2*(x*pGradient->radial.dx + y*pGradient->radial.dy);
- c = -(x*x + y*y);
- det = (b * b) - (4 * pGradient->radial.a * c);
- s = (-b + sqrt(det))/(2. * pGradient->radial.a);
- WRITE(buffer, gradientPixel(pGradient,
- (xFixed_48_16)((s*pGradient->radial.m + pGradient->radial.b)*65536),
- pict->repeatType));
- ++buffer;
+ if (!mask || *mask++ & maskBits)
+ {
+ double pdx, pdy;
+ double B, C;
+ double det;
+ double c1x = radial->c1.x / 65536.0;
+ double c1y = radial->c1.y / 65536.0;
+ double r1 = radial->c1.radius / 65536.0;
+ xFixed_48_16 t;
+ double x, y;
+
+ if (rz != 0) {
+ x = rx/rz;
+ y = ry/rz;
+ } else {
+ x = y = 0.;
+ }
+
+ pdx = x - c1x;
+ pdy = y - c1y;
+
+ B = -2 * ( pdx * radial->cdx
+ + pdy * radial->cdy
+ + r1 * radial->dr);
+ C = (pdx * pdx + pdy * pdy - r1 * r1);
+
+ det = (B * B) - (4 * radial->A * C);
+ if (det < 0.0)
+ det = 0.0;
+
+ if (radial->A < 0)
+ t = (xFixed_48_16) ((- B - sqrt(det)) / (2.0 * radial->A) * 65536);
+ else
+ t = (xFixed_48_16) ((- B + sqrt(det)) / (2.0 * radial->A) * 65536);
+
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ }
+ ++buffer;
+
rx += cx;
ry += cy;
- rz += cz;
+ rz += cz;
}
}
} else /* SourcePictTypeConical */ {
@@ -2860,28 +3383,45 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
ry -= pGradient->conical.center.y/65536.;
while (buffer < end) {
- double angle = atan2(ry, rx) + a;
- WRITE(buffer, gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
- pict->repeatType));
+ double angle;
+
+ if (!mask || *mask++ & maskBits)
+ {
+ xFixed_48_16 t;
+
+ angle = atan2(ry, rx) + a;
+ t = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
+
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ }
+
++buffer;
rx += cx;
ry += cy;
}
} else {
-
while (buffer < end) {
- double x, y, angle;
- if (rz != 0) {
- x = rx/rz;
- y = ry/rz;
- } else {
- x = y = 0.;
- }
- x -= pGradient->conical.center.x/65536.;
- y -= pGradient->conical.center.y/65536.;
- angle = atan2(y, x) + a;
- WRITE(buffer, gradientPixel(pGradient, (xFixed_48_16) (angle * (65536. / (2*M_PI))),
- pict->repeatType));
+ double x, y;
+ double angle;
+
+ if (!mask || *mask++ & maskBits)
+ {
+ xFixed_48_16 t;
+
+ if (rz != 0) {
+ x = rx/rz;
+ y = ry/rz;
+ } else {
+ x = y = 0.;
+ }
+ x -= pGradient->conical.center.x/65536.;
+ y -= pGradient->conical.center.y/65536.;
+ angle = atan2(y, x) + a;
+ t = (xFixed_48_16) (angle * (65536. / (2*M_PI)));
+
+ WRITE(buffer, _gradient_walker_pixel (&walker, t));
+ }
+
++buffer;
rx += cx;
ry += cy;
@@ -2892,9 +3432,7 @@ static void fbFetchSourcePict(PicturePtr pict, int x, int y, int width, CARD32 *
}
}
-
-
-static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
FbBits *bits;
FbStride stride;
@@ -2943,39 +3481,47 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (pict->repeatType == RepeatNormal) {
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- if (!affine) {
- y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
- x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
- } else {
- y = MOD(v.vector[1]>>16, pict->pDrawable->height);
- x = MOD(v.vector[0]>>16, pict->pDrawable->width);
- }
- WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ if (!affine) {
+ y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+ x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+ } else {
+ y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+ x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+ }
+ WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
+ }
+ }
+
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- if (!affine) {
- y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
- x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
- } else {
- y = MOD(v.vector[1]>>16, pict->pDrawable->height);
- x = MOD(v.vector[0]>>16, pict->pDrawable->width);
- }
- if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
- WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
- else
- WRITE(buffer + i, 0);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ if (!affine) {
+ y = MOD(DIV(v.vector[1],v.vector[2]), pict->pDrawable->height);
+ x = MOD(DIV(v.vector[0],v.vector[2]), pict->pDrawable->width);
+ } else {
+ y = MOD(v.vector[1]>>16, pict->pDrawable->height);
+ x = MOD(v.vector[0]>>16, pict->pDrawable->width);
+ }
+ if (POINT_IN_REGION (0, pict->pCompositeClip, x, y, &box))
+ WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
+ else
+ WRITE(buffer + i, 0);
+ }
+ }
+
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -2985,40 +3531,46 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- if (!affine) {
- y = DIV(v.vector[1],v.vector[2]);
- x = DIV(v.vector[0],v.vector[2]);
- } else {
- y = v.vector[1]>>16;
- x = v.vector[0]>>16;
- }
- WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
- 0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ if (!affine) {
+ y = DIV(v.vector[1],v.vector[2]);
+ x = DIV(v.vector[0],v.vector[2]);
+ } else {
+ y = v.vector[1]>>16;
+ x = v.vector[0]>>16;
+ }
+ WRITE(buffer + i, ((x < box.x1-dx) | (x >= box.x2-dx) | (y < box.y1-dy) | (y >= box.y2-dy)) ?
+ 0 : fetch(bits + (y + dy)*stride, x + dx, indexed));
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- if (!affine) {
- y = DIV(v.vector[1],v.vector[2]);
- x = DIV(v.vector[0],v.vector[2]);
- } else {
- y = v.vector[1]>>16;
- x = v.vector[0]>>16;
- }
- if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
- WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
- else
- WRITE(buffer + i, 0);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ if (!affine) {
+ y = DIV(v.vector[1],v.vector[2]);
+ x = DIV(v.vector[0],v.vector[2]);
+ } else {
+ y = v.vector[1]>>16;
+ x = v.vector[0]>>16;
+ }
+ if (POINT_IN_REGION (0, pict->pCompositeClip, x + dx, y + dy, &box))
+ WRITE(buffer + i, fetch(bits + (y + dy)*stride, x + dx, indexed));
+ else
+ WRITE(buffer + i, 0);
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3035,126 +3587,133 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (pict->repeatType == RepeatNormal) {
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- CARD32 ft, fb;
-
- if (!affine) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- x1 = MOD (x1, pict->pDrawable->width);
- x2 = MOD (x2, pict->pDrawable->width);
- y1 = MOD (y1, pict->pDrawable->height);
- y2 = MOD (y2, pict->pDrawable->height);
-
- b = bits + (y1 + dy)*stride;
-
- tl = fetch(b, x1 + dx, indexed);
- tr = fetch(b, x2 + dx, indexed);
- b = bits + (y2 + dy)*stride;
- bl = fetch(b, x1 + dx, indexed);
- br = fetch(b, x2 + dx, indexed);
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- WRITE(buffer + i, r);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ x1 = MOD (x1, pict->pDrawable->width);
+ x2 = MOD (x2, pict->pDrawable->width);
+ y1 = MOD (y1, pict->pDrawable->height);
+ y2 = MOD (y2, pict->pDrawable->height);
+
+ b = bits + (y1 + dy)*stride;
+
+ tl = fetch(b, x1 + dx, indexed);
+ tr = fetch(b, x2 + dx, indexed);
+ b = bits + (y2 + dy)*stride;
+ bl = fetch(b, x1 + dx, indexed);
+ br = fetch(b, x2 + dx, indexed);
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ WRITE(buffer + i, r);
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- CARD32 ft, fb;
-
- if (!affine) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- x1 = MOD (x1, pict->pDrawable->width);
- x2 = MOD (x2, pict->pDrawable->width);
- y1 = MOD (y1, pict->pDrawable->height);
- y2 = MOD (y2, pict->pDrawable->height);
-
- b = bits + (y1 + dy)*stride;
-
- tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
- ? fetch(b, x1 + dx, indexed) : 0;
- tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
- ? fetch(b, x2 + dx, indexed) : 0;
- b = bits + (y2 + dy)*stride;
- bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
- ? fetch(b, x1 + dx, indexed) : 0;
- br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
- ? fetch(b, x2 + dx, indexed) : 0;
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- WRITE(buffer + i, r);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ x1 = MOD (x1, pict->pDrawable->width);
+ x2 = MOD (x2, pict->pDrawable->width);
+ y1 = MOD (y1, pict->pDrawable->height);
+ y2 = MOD (y2, pict->pDrawable->height);
+
+ b = bits + (y1 + dy)*stride;
+
+ tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
+ ? fetch(b, x1 + dx, indexed) : 0;
+ tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
+ ? fetch(b, x2 + dx, indexed) : 0;
+ b = bits + (y2 + dy)*stride;
+ bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
+ ? fetch(b, x1 + dx, indexed) : 0;
+ br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
+ ? fetch(b, x2 + dx, indexed) : 0;
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ WRITE(buffer + i, r);
+ }
+ }
+
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3164,124 +3723,132 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
if (REGION_NUM_RECTS(pict->pCompositeClip) == 1) {
box = pict->pCompositeClip->extents;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- Bool x1_out, x2_out, y1_out, y2_out;
- CARD32 ft, fb;
-
- if (!affine) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- b = bits + (y1 + dy)*stride;
- x_off = x1 + dx;
-
- x1_out = (x1 < box.x1-dx) | (x1 >= box.x2-dx);
- x2_out = (x2 < box.x1-dx) | (x2 >= box.x2-dx);
- y1_out = (y1 < box.y1-dy) | (y1 >= box.y2-dy);
- y2_out = (y2 < box.y1-dy) | (y2 >= box.y2-dy);
-
- tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
- tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
- b += stride;
- bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
- br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- WRITE(buffer + i, r);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ Bool x1_out, x2_out, y1_out, y2_out;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ b = bits + (y1 + dy)*stride;
+ x_off = x1 + dx;
+
+ x1_out = (x1 < box.x1-dx) | (x1 >= box.x2-dx);
+ x2_out = (x2 < box.x1-dx) | (x2 >= box.x2-dx);
+ y1_out = (y1 < box.y1-dy) | (y1 >= box.y2-dy);
+ y2_out = (y2 < box.y1-dy) | (y2 >= box.y2-dy);
+
+ tl = x1_out|y1_out ? 0 : fetch(b, x_off, indexed);
+ tr = x2_out|y1_out ? 0 : fetch(b, x_off + 1, indexed);
+ b += stride;
+ bl = x1_out|y2_out ? 0 : fetch(b, x_off, indexed);
+ br = x2_out|y2_out ? 0 : fetch(b, x_off + 1, indexed);
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ WRITE(buffer + i, r);
+ }
+ }
+
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
}
} else {
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
- FbBits *b;
- CARD32 tl, tr, bl, br, r;
- CARD32 ft, fb;
-
- if (!affine) {
- xFixed_48_16 div;
- div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
- x1 = div >> 16;
- distx = ((xFixed)div >> 8) & 0xff;
- div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
- y1 = div >> 16;
- disty = ((xFixed)div >> 8) & 0xff;
- } else {
- x1 = v.vector[0] >> 16;
- distx = (v.vector[0] >> 8) & 0xff;
- y1 = v.vector[1] >> 16;
- disty = (v.vector[1] >> 8) & 0xff;
- }
- x2 = x1 + 1;
- y2 = y1 + 1;
-
- idistx = 256 - distx;
- idisty = 256 - disty;
-
- b = bits + (y1 + dy)*stride;
- x_off = x1 + dx;
-
- tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
- ? fetch(b, x_off, indexed) : 0;
- tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
- ? fetch(b, x_off + 1, indexed) : 0;
- b += stride;
- bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
- ? fetch(b, x_off, indexed) : 0;
- br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
- ? fetch(b, x_off + 1, indexed) : 0;
-
- ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
- fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
- r = (((ft * idisty + fb * disty) >> 16) & 0xff);
- ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
- fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
- r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
- ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
- fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
- r |= (((ft * idisty + fb * disty)) & 0xff0000);
- ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
- fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
- r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
- WRITE(buffer + i, r);
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ int x1, x2, y1, y2, distx, idistx, disty, idisty, x_off;
+ FbBits *b;
+ CARD32 tl, tr, bl, br, r;
+ CARD32 ft, fb;
+
+ if (!affine) {
+ xFixed_48_16 div;
+ div = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2];
+ x1 = div >> 16;
+ distx = ((xFixed)div >> 8) & 0xff;
+ div = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2];
+ y1 = div >> 16;
+ disty = ((xFixed)div >> 8) & 0xff;
+ } else {
+ x1 = v.vector[0] >> 16;
+ distx = (v.vector[0] >> 8) & 0xff;
+ y1 = v.vector[1] >> 16;
+ disty = (v.vector[1] >> 8) & 0xff;
+ }
+ x2 = x1 + 1;
+ y2 = y1 + 1;
+
+ idistx = 256 - distx;
+ idisty = 256 - disty;
+
+ b = bits + (y1 + dy)*stride;
+ x_off = x1 + dx;
+
+ tl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y1 + dy, &box)
+ ? fetch(b, x_off, indexed) : 0;
+ tr = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y1 + dy, &box)
+ ? fetch(b, x_off + 1, indexed) : 0;
+ b += stride;
+ bl = POINT_IN_REGION(0, pict->pCompositeClip, x1 + dx, y2 + dy, &box)
+ ? fetch(b, x_off, indexed) : 0;
+ br = POINT_IN_REGION(0, pict->pCompositeClip, x2 + dx, y2 + dy, &box)
+ ? fetch(b, x_off + 1, indexed) : 0;
+
+ ft = FbGet8(tl,0) * idistx + FbGet8(tr,0) * distx;
+ fb = FbGet8(bl,0) * idistx + FbGet8(br,0) * distx;
+ r = (((ft * idisty + fb * disty) >> 16) & 0xff);
+ ft = FbGet8(tl,8) * idistx + FbGet8(tr,8) * distx;
+ fb = FbGet8(bl,8) * idistx + FbGet8(br,8) * distx;
+ r |= (((ft * idisty + fb * disty) >> 8) & 0xff00);
+ ft = FbGet8(tl,16) * idistx + FbGet8(tr,16) * distx;
+ fb = FbGet8(bl,16) * idistx + FbGet8(br,16) * distx;
+ r |= (((ft * idisty + fb * disty)) & 0xff0000);
+ ft = FbGet8(tl,24) * idistx + FbGet8(tr,24) * distx;
+ fb = FbGet8(bl,24) * idistx + FbGet8(br,24) * distx;
+ r |= (((ft * idisty + fb * disty) << 8) & 0xff000000);
+ WRITE(buffer + i, r);
+ }
+ }
+
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3296,62 +3863,65 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
int yoff = (params[1] - xFixed1) >> 1;
params += 2;
for (i = 0; i < width; ++i) {
- if (!v.vector[2]) {
- WRITE(buffer + i, 0);
- } else {
- int x1, x2, y1, y2, x, y;
- INT32 srtot, sgtot, sbtot, satot;
- xFixed *p = params;
-
- if (!affine) {
- xFixed_48_16 tmp;
- tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
- x1 = xFixedToInt(tmp);
- tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
- y1 = xFixedToInt(tmp);
- } else {
- x1 = xFixedToInt(v.vector[0] - xoff);
- y1 = xFixedToInt(v.vector[1] - yoff);
- }
- x2 = x1 + cwidth;
- y2 = y1 + cheight;
-
- srtot = sgtot = sbtot = satot = 0;
-
- for (y = y1; y < y2; y++) {
- int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
- for (x = x1; x < x2; x++) {
- if (*p) {
- int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
- if (POINT_IN_REGION (0, pict->pCompositeClip, tx + dx, ty + dy, &box)) {
- FbBits *b = bits + (ty + dy)*stride;
- CARD32 c = fetch(b, tx + dx, indexed);
-
- srtot += Red(c) * *p;
- sgtot += Green(c) * *p;
- sbtot += Blue(c) * *p;
- satot += Alpha(c) * *p;
- }
- }
- p++;
- }
- }
-
- satot >>= 16;
- srtot >>= 16;
- sgtot >>= 16;
- sbtot >>= 16;
-
- if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
- if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
- if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
- if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
-
- WRITE(buffer + i, ((satot << 24) |
- (srtot << 16) |
- (sgtot << 8) |
- (sbtot )));
- }
+ if (!mask || mask[i] & maskBits)
+ {
+ if (!v.vector[2]) {
+ WRITE(buffer + i, 0);
+ } else {
+ int x1, x2, y1, y2, x, y;
+ INT32 srtot, sgtot, sbtot, satot;
+ xFixed *p = params;
+
+ if (!affine) {
+ xFixed_48_16 tmp;
+ tmp = ((xFixed_48_16)v.vector[0] << 16)/v.vector[2] - xoff;
+ x1 = xFixedToInt(tmp);
+ tmp = ((xFixed_48_16)v.vector[1] << 16)/v.vector[2] - yoff;
+ y1 = xFixedToInt(tmp);
+ } else {
+ x1 = xFixedToInt(v.vector[0] - xoff);
+ y1 = xFixedToInt(v.vector[1] - yoff);
+ }
+ x2 = x1 + cwidth;
+ y2 = y1 + cheight;
+
+ srtot = sgtot = sbtot = satot = 0;
+
+ for (y = y1; y < y2; y++) {
+ int ty = (pict->repeatType == RepeatNormal) ? MOD (y, pict->pDrawable->height) : y;
+ for (x = x1; x < x2; x++) {
+ if (*p) {
+ int tx = (pict->repeatType == RepeatNormal) ? MOD (x, pict->pDrawable->width) : x;
+ if (POINT_IN_REGION (0, pict->pCompositeClip, tx + dx, ty + dy, &box)) {
+ FbBits *b = bits + (ty + dy)*stride;
+ CARD32 c = fetch(b, tx + dx, indexed);
+
+ srtot += Red(c) * *p;
+ sgtot += Green(c) * *p;
+ sbtot += Blue(c) * *p;
+ satot += Alpha(c) * *p;
+ }
+ }
+ p++;
+ }
+ }
+
+ satot >>= 16;
+ srtot >>= 16;
+ sgtot >>= 16;
+ sbtot >>= 16;
+
+ if (satot < 0) satot = 0; else if (satot > 0xff) satot = 0xff;
+ if (srtot < 0) srtot = 0; else if (srtot > 0xff) srtot = 0xff;
+ if (sgtot < 0) sgtot = 0; else if (sgtot > 0xff) sgtot = 0xff;
+ if (sbtot < 0) sbtot = 0; else if (sbtot > 0xff) sbtot = 0xff;
+
+ WRITE(buffer + i, ((satot << 24) |
+ (srtot << 16) |
+ (sgtot << 8) |
+ (sbtot )));
+ }
+ }
v.vector[0] += unit.vector[0];
v.vector[1] += unit.vector[1];
v.vector[2] += unit.vector[2];
@@ -3362,27 +3932,32 @@ static void fbFetchTransformed(PicturePtr pict, int x, int y, int width, CARD32
}
-static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer)
+static void fbFetchExternalAlpha(PicturePtr pict, int x, int y, int width, CARD32 *buffer, CARD32 *mask, CARD32 maskBits)
{
int i;
CARD32 _alpha_buffer[SCANLINE_BUFFER_LENGTH];
CARD32 *alpha_buffer = _alpha_buffer;
if (!pict->alphaMap) {
- fbFetchTransformed(pict, x, y, width, buffer);
+ fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
return;
}
if (width > SCANLINE_BUFFER_LENGTH)
alpha_buffer = (CARD32 *) malloc(width*sizeof(CARD32));
- fbFetchTransformed(pict, x, y, width, buffer);
- fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x, y - pict->alphaOrigin.y, width, alpha_buffer);
+ fbFetchTransformed(pict, x, y, width, buffer, mask, maskBits);
+ fbFetchTransformed(pict->alphaMap, x - pict->alphaOrigin.x,
+ y - pict->alphaOrigin.y, width, alpha_buffer,
+ mask, maskBits);
for (i = 0; i < width; ++i) {
- int a = alpha_buffer[i]>>24;
- WRITE(buffer + i, (a << 24)
- | (div_255(Red(READ(buffer + i)) * a) << 16)
- | (div_255(Green(READ(buffer + i)) * a) << 8)
- | (div_255(Blue(READ(buffer + i)) * a)));
+ if (!mask || mask[i] & maskBits)
+ {
+ int a = alpha_buffer[i]>>24;
+ WRITE(buffer + i, (a << 24)
+ | (div_255(Red(READ(buffer + i)) * a) << 16)
+ | (div_255(Green(READ(buffer + i)) * a) << 8)
+ | (div_255(Blue(READ(buffer + i)) * a)));
+ }
}
if (alpha_buffer != _alpha_buffer)
@@ -3450,7 +4025,7 @@ static void fbStoreExternalAlpha(PicturePtr pict, int x, int y, int width, CARD3
}
typedef void (*scanStoreProc)(PicturePtr , int , int , int , CARD32 *);
-typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 *);
+typedef void (*scanFetchProc)(PicturePtr , int , int , int , CARD32 * , CARD32 *, CARD32);
static void
fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
@@ -3460,31 +4035,52 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
int i;
scanStoreProc store;
scanFetchProc fetchSrc = NULL, fetchMask = NULL, fetchDest = NULL;
-
+ unsigned int srcClass = SourcePictClassUnknown;
+ unsigned int maskClass = SourcePictClassUnknown;
+ FbBits *bits;
+ FbStride stride;
+ int xoff, yoff;
+
if (data->op == PictOpClear)
fetchSrc = NULL;
else if (!data->src->pDrawable) {
if (data->src->pSourcePict)
+ {
fetchSrc = fbFetchSourcePict;
+ srcClass = SourcePictureClassify (data->src,
+ data->xSrc, data->ySrc,
+ data->width, data->height);
+ }
} else if (data->src->alphaMap)
fetchSrc = fbFetchExternalAlpha;
else if (data->src->repeatType == RepeatNormal &&
data->src->pDrawable->width == 1 && data->src->pDrawable->height == 1)
+ {
fetchSrc = fbFetchSolid;
+ srcClass = SourcePictClassHorizontal;
+ }
else if (!data->src->transform && data->src->filter != PictFilterConvolution)
fetchSrc = fbFetch;
else
fetchSrc = fbFetchTransformed;
-
+
if (data->mask && data->op != PictOpClear) {
if (!data->mask->pDrawable) {
if (data->mask->pSourcePict)
fetchMask = fbFetchSourcePict;
} else if (data->mask->alphaMap)
+ {
fetchMask = fbFetchExternalAlpha;
+ maskClass = SourcePictureClassify (data->mask,
+ data->xMask, data->yMask,
+ data->width, data->height);
+ }
else if (data->mask->repeatType == RepeatNormal
&& data->mask->pDrawable->width == 1 && data->mask->pDrawable->height == 1)
- fetchMask = fbFetchSolid;
+ {
+ fetchMask = fbFetchSolid;
+ maskClass = SourcePictClassHorizontal;
+ }
else if (!data->mask->transform && data->mask->filter != PictFilterConvolution)
fetchMask = fbFetch;
else
@@ -3492,79 +4088,210 @@ fbCompositeRect (const FbComposeData *data, CARD32 *scanline_buffer)
} else {
fetchMask = NULL;
}
-
- if (data->dest->alphaMap) {
- fetchDest = fbFetchExternalAlpha;
- store = fbStoreExternalAlpha;
- } else {
- fetchDest = fbFetch;
- store = fbStore;
+
+ if (data->dest->alphaMap)
+ {
+ fetchDest = fbFetchExternalAlpha;
+ store = fbStoreExternalAlpha;
+
+ if (data->op == PictOpClear || data->op == PictOpSrc)
+ fetchDest = NULL;
}
- if (data->op == PictOpClear || data->op == PictOpSrc)
- fetchDest = NULL;
-
- if (fetchSrc && fetchMask && data->mask && data->mask->componentAlpha && PICT_FORMAT_RGB(data->mask->format)) {
- CARD32 *mask_buffer = dest_buffer + data->width;
- CombineFuncC compose = composeFunctions.combineC[data->op];
- if (!compose)
- return;
-
- for (i = 0; i < data->height; ++i)
- {
- /* fill first half of scanline with source */
- fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
- fetchMask(data->mask, data->xMask, data->yMask + i, data->width, mask_buffer);
-
- /* fill dest into second half of scanline */
- if (fetchDest)
- fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
-
- /* blend */
- compose(dest_buffer, src_buffer, mask_buffer, data->width);
-
- /* write back */
- store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
- }
- } else {
-
- CombineFuncU compose = composeFunctions.combineU[data->op];
- if (!compose)
- return;
-
- if (fetchSrc == fbFetchSolid && (!fetchMask || fetchMask == fbFetchSolid)) {
- fetchSrc(data->src, data->xSrc, data->ySrc, data->width, src_buffer);
- if (fetchMask) {
- fetchMask(data->mask, data->xMask, data->yMask, data->width, dest_buffer);
- composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
- }
- fetchSrc = NULL;
- fetchMask = NULL;
- }
-
- for (i = 0; i < data->height; ++i)
- {
- /* fill first half of scanline with source */
- if (fetchSrc) {
- fetchSrc(data->src, data->xSrc, data->ySrc + i, data->width, src_buffer);
-
- /* add in mask */
- if (fetchMask) {
- fetchMask(data->mask, data->xMask, data->yMask + i, data->width, dest_buffer);
- composeFunctions.combineMaskU(src_buffer, dest_buffer, data->width);
- }
- }
-
- /* fill dest into second half of scanline */
- if (fetchDest)
- fetchDest(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
-
- /* blend */
- compose(dest_buffer, src_buffer, data->width);
-
- /* write back */
- store(data->dest, data->xDest, data->yDest + i, data->width, dest_buffer);
- }
+ else
+ {
+ fetchDest = fbFetch;
+ store = fbStore;
+
+ switch (data->op) {
+ case PictOpClear:
+ case PictOpSrc:
+ fetchDest = NULL;
+ /* fall-through */
+ case PictOpAdd:
+ case PictOpOver:
+ switch (data->dest->format) {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ store = NULL;
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ }
+
+ if (!store)
+ {
+ int bpp;
+
+ fbGetDrawable (data->dest->pDrawable, bits, stride, bpp, xoff, yoff);
+ }
+ else
+ {
+ bits = NULL;
+ stride = 0;
+ xoff = yoff = 0;
}
+
+ if (fetchSrc &&
+ fetchMask &&
+ data->mask &&
+ data->mask->componentAlpha &&
+ PICT_FORMAT_RGB (data->mask->format))
+ {
+ CARD32 *mask_buffer = dest_buffer + data->width;
+ CombineFuncC compose = composeFunctions.combineC[data->op];
+ if (!compose)
+ return;
+
+ for (i = 0; i < data->height; ++i) {
+ /* fill first half of scanline with source */
+ if (fetchSrc)
+ {
+ if (fetchMask)
+ {
+ /* fetch mask before source so that fetching of
+ source can be optimized */
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
+
+ if (maskClass == SourcePictClassHorizontal)
+ fetchMask = NULL;
+ }
+
+ if (srcClass == SourcePictClassHorizontal)
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, 0, 0);
+ fetchSrc = NULL;
+ }
+ else
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, mask_buffer,
+ 0xffffffff);
+ }
+ }
+ else if (fetchMask)
+ {
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
+ }
+
+ if (store)
+ {
+ /* fill dest into second half of scanline */
+ if (fetchDest)
+ fetchDest (data->dest, data->xDest, data->yDest + i,
+ data->width, dest_buffer, 0, 0);
+
+ /* blend */
+ compose (dest_buffer, src_buffer, mask_buffer, data->width);
+
+ /* write back */
+ store (data->dest, data->xDest, data->yDest + i, data->width,
+ dest_buffer);
+ }
+ else
+ {
+ /* blend */
+ compose (bits + (data->yDest + i+ yoff) * stride +
+ data->xDest + xoff,
+ src_buffer, mask_buffer, data->width);
+ }
+ }
+ }
+ else
+ {
+ CARD32 *src_mask_buffer = 0, *mask_buffer = 0;
+ CombineFuncU compose = composeFunctions.combineU[data->op];
+ if (!compose)
+ return;
+
+ if (fetchMask)
+ mask_buffer = dest_buffer + data->width;
+
+ for (i = 0; i < data->height; ++i) {
+ /* fill first half of scanline with source */
+ if (fetchSrc)
+ {
+ if (fetchMask)
+ {
+ /* fetch mask before source so that fetching of
+ source can be optimized */
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
+
+ if (maskClass == SourcePictClassHorizontal)
+ fetchMask = NULL;
+ }
+
+ if (srcClass == SourcePictClassHorizontal)
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, 0, 0);
+
+ if (mask_buffer)
+ {
+ fbCombineInU (mask_buffer, src_buffer, data->width);
+ src_mask_buffer = mask_buffer;
+ }
+ else
+ src_mask_buffer = src_buffer;
+
+ fetchSrc = NULL;
+ }
+ else
+ {
+ fetchSrc (data->src, data->xSrc, data->ySrc + i,
+ data->width, src_buffer, mask_buffer,
+ 0xff000000);
+
+ if (mask_buffer)
+ composeFunctions.combineMaskU (src_buffer,
+ mask_buffer,
+ data->width);
+
+ src_mask_buffer = src_buffer;
+ }
+ }
+ else if (fetchMask)
+ {
+ fetchMask (data->mask, data->xMask, data->yMask + i,
+ data->width, mask_buffer, 0, 0);
+
+ fbCombineInU (mask_buffer, src_buffer, data->width);
+
+ src_mask_buffer = mask_buffer;
+ }
+
+ if (store)
+ {
+ /* fill dest into second half of scanline */
+ if (fetchDest)
+ fetchDest (data->dest, data->xDest, data->yDest + i,
+ data->width, dest_buffer, 0, 0);
+
+ /* blend */
+ compose (dest_buffer, src_mask_buffer, data->width);
+
+ /* write back */
+ store (data->dest, data->xDest, data->yDest + i, data->width,
+ dest_buffer);
+ }
+ else
+ {
+ /* blend */
+ compose (bits + (data->yDest + i+ yoff) * stride +
+ data->xDest + xoff,
+ src_mask_buffer, data->width);
+ }
+ }
+ }
+
+ if (!store)
+ fbFinishAccess (data->dest->pDrawable);
}
void
@@ -3593,11 +4320,11 @@ fbCompositeGeneral (CARD8 op,
if (pSrc->pDrawable)
srcRepeat = pSrc->repeatType == RepeatNormal && !pSrc->transform
- && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
+ && (pSrc->pDrawable->width != 1 || pSrc->pDrawable->height != 1);
if (pMask && pMask->pDrawable)
maskRepeat = pMask->repeatType == RepeatNormal && !pMask->transform
- && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
+ && (pMask->pDrawable->width != 1 || pMask->pDrawable->height != 1);
if (op == PictOpOver && !pMask && !pSrc->transform && !PICT_FORMAT_A(pSrc->format) && !pSrc->alphaMap)
op = PictOpSrc;
@@ -3614,7 +4341,7 @@ fbCompositeGeneral (CARD8 op,
yDst,
width,
height))
- return;
+ return;
compose_data.op = op;
compose_data.src = pSrc;
@@ -3675,7 +4402,7 @@ fbCompositeGeneral (CARD8 op,
compose_data.ySrc += compose_data.height;
compose_data.yMask += compose_data.height;
compose_data.yDest += compose_data.height;
- }
+ }
pbox++;
}
REGION_UNINIT (pDst->pDrawable->pScreen, &region);
diff --git a/fb/fbmmx.c b/fb/fbmmx.c
index 5bbede10b..0e9074648 100644
--- a/fb/fbmmx.c
+++ b/fb/fbmmx.c
@@ -85,30 +85,40 @@
typedef unsigned long long ullong;
+#ifdef __GNUC__
+typedef ullong mmxdatafield;
+#endif
+#ifdef _MSC_VER
+typedef unsigned __int64 ullong;
+typedef __m64 mmxdatafield;
+#endif
+
typedef struct
{
- ullong mmx_4x00ff;
- ullong mmx_4x0080;
- ullong mmx_565_rgb;
- ullong mmx_565_unpack_multiplier;
- ullong mmx_565_r;
- ullong mmx_565_g;
- ullong mmx_565_b;
- ullong mmx_mask_0;
- ullong mmx_mask_1;
- ullong mmx_mask_2;
- ullong mmx_mask_3;
- ullong mmx_full_alpha;
- ullong mmx_ffff0000ffff0000;
- ullong mmx_0000ffff00000000;
- ullong mmx_000000000000ffff;
+ mmxdatafield mmx_4x00ff;
+ mmxdatafield mmx_4x0080;
+ mmxdatafield mmx_565_rgb;
+ mmxdatafield mmx_565_unpack_multiplier;
+ mmxdatafield mmx_565_r;
+ mmxdatafield mmx_565_g;
+ mmxdatafield mmx_565_b;
+ mmxdatafield mmx_mask_0;
+ mmxdatafield mmx_mask_1;
+ mmxdatafield mmx_mask_2;
+ mmxdatafield mmx_mask_3;
+ mmxdatafield mmx_full_alpha;
+ mmxdatafield mmx_ffff0000ffff0000;
+ mmxdatafield mmx_0000ffff00000000;
+ mmxdatafield mmx_000000000000ffff;
} MMXData;
static const MMXData c =
{
+#ifdef __GNUC__
.mmx_4x00ff = 0x00ff00ff00ff00ffULL,
.mmx_4x0080 = 0x0080008000800080ULL,
.mmx_565_rgb = 0x000001f0003f001fULL,
+ .mmx_565_unpack_multiplier = 0x0000008404100840ULL,
.mmx_565_r = 0x000000f800000000ULL,
.mmx_565_g = 0x0000000000fc0000ULL,
.mmx_565_b = 0x00000000000000f8ULL,
@@ -117,15 +127,42 @@ static const MMXData c =
.mmx_mask_2 = 0xffff0000ffffffffULL,
.mmx_mask_3 = 0x0000ffffffffffffULL,
.mmx_full_alpha = 0x00ff000000000000ULL,
- .mmx_565_unpack_multiplier = 0x0000008404100840ULL,
.mmx_ffff0000ffff0000 = 0xffff0000ffff0000ULL,
.mmx_0000ffff00000000 = 0x0000ffff00000000ULL,
.mmx_000000000000ffff = 0x000000000000ffffULL,
+#endif
+#ifdef _MSC_VER
+ { 0x00ff00ff00ff00ffUI64 },
+ { 0x0080008000800080UI64 },
+ { 0x000001f0003f001fUI64 },
+ { 0x0000008404100840UI64 },
+ { 0x000000f800000000UI64 },
+ { 0x0000000000fc0000UI64 },
+ { 0x00000000000000f8UI64 },
+ { 0xffffffffffff0000UI64 },
+ { 0xffffffff0000ffffUI64 },
+ { 0xffff0000ffffffffUI64 },
+ { 0x0000ffffffffffffUI64 },
+ { 0x00ff000000000000UI64 },
+ { 0xffff0000ffff0000UI64 },
+ { 0x0000ffff00000000UI64 },
+ { 0x000000000000ffffUI64 },
+#endif
};
+#ifdef _MSC_VER
+#undef inline
+#define inline __forceinline
+#endif
+
+#ifdef __GNUC__
#define MC(x) ((__m64) c.mmx_##x)
+#endif
+#ifdef _MSC_VER
+#define MC(x) c.mmx_##x
+#endif
-static __inline__ __m64
+static inline __m64
shift (__m64 v, int s)
{
if (s > 0)
@@ -136,13 +173,13 @@ shift (__m64 v, int s)
return v;
}
-static __inline__ __m64
+static inline __m64
negate (__m64 mask)
{
return _mm_xor_si64 (mask, MC(4x00ff));
}
-static __inline__ __m64
+static inline __m64
pix_multiply (__m64 a, __m64 b)
{
__m64 res;
@@ -155,7 +192,7 @@ pix_multiply (__m64 a, __m64 b)
return res;
}
-static __inline__ __m64
+static inline __m64
pix_add (__m64 a, __m64 b)
{
return _mm_adds_pu8 (a, b);
@@ -163,19 +200,19 @@ pix_add (__m64 a, __m64 b)
#ifdef USE_SSE
-static __inline__ __m64
+static inline __m64
expand_alpha (__m64 pixel)
{
return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 3, 3, 3));
}
-static __inline__ __m64
+static inline __m64
expand_alpha_rev (__m64 pixel)
{
return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(0, 0, 0, 0));
}
-static __inline__ __m64
+static inline __m64
invert_colors (__m64 pixel)
{
return _mm_shuffle_pi16 (pixel, _MM_SHUFFLE(3, 0, 1, 2));
@@ -183,7 +220,7 @@ invert_colors (__m64 pixel)
#else
-static __inline__ __m64
+static inline __m64
expand_alpha (__m64 pixel)
{
__m64 t1, t2;
@@ -197,7 +234,7 @@ expand_alpha (__m64 pixel)
return t1;
}
-static __inline__ __m64
+static inline __m64
expand_alpha_rev (__m64 pixel)
{
__m64 t1, t2;
@@ -214,7 +251,7 @@ expand_alpha_rev (__m64 pixel)
return t1;
}
-static __inline__ __m64
+static inline __m64
invert_colors (__m64 pixel)
{
__m64 x, y, z;
@@ -236,13 +273,13 @@ invert_colors (__m64 pixel)
#endif
-static __inline__ __m64
+static inline __m64
over (__m64 src, __m64 srca, __m64 dest)
{
return _mm_adds_pu8 (src, pix_multiply(dest, negate(srca)));
}
-static __inline__ __m64
+static inline __m64
over_rev_non_pre (__m64 src, __m64 dest)
{
__m64 srca = expand_alpha (src);
@@ -251,14 +288,15 @@ over_rev_non_pre (__m64 src, __m64 dest)
return over(pix_multiply(invert_colors(src), srcfaaa), srca, dest);
}
-static __inline__ __m64
+static inline __m64
in (__m64 src,
__m64 mask)
{
return pix_multiply (src, mask);
}
-static __inline__ __m64
+#ifndef _MSC_VER
+static inline __m64
in_over (__m64 src,
__m64 srca,
__m64 mask,
@@ -266,20 +304,23 @@ in_over (__m64 src,
{
return over(in(src, mask), pix_multiply(srca, mask), dest);
}
+#else
+#define in_over(src, srca, mask, dest) over(in(src, mask), pix_multiply(srca, mask), dest)
+#endif
-static __inline__ __m64
+static inline __m64
load8888 (CARD32 v)
{
return _mm_unpacklo_pi8 (_mm_cvtsi32_si64 (v), _mm_setzero_si64());
}
-static __inline__ __m64
+static inline __m64
pack8888 (__m64 lo, __m64 hi)
{
return _mm_packs_pu16 (lo, hi);
}
-static __inline__ CARD32
+static inline CARD32
store8888 (__m64 v)
{
return _mm_cvtsi64_si32(pack8888(v, _mm_setzero_si64()));
@@ -299,7 +340,7 @@ store8888 (__m64 v)
* Note the trick here - the top word is shifted by another nibble to
* avoid it bumping into the middle word
*/
-static __inline__ __m64
+static inline __m64
expand565 (__m64 pixel, int pos)
{
__m64 p = pixel;
@@ -319,7 +360,7 @@ expand565 (__m64 pixel, int pos)
return _mm_srli_pi16 (pixel, 8);
}
-static __inline__ __m64
+static inline __m64
expand8888 (__m64 in, int pos)
{
if (pos == 0)
@@ -328,7 +369,7 @@ expand8888 (__m64 in, int pos)
return _mm_unpackhi_pi8 (in, _mm_setzero_si64());
}
-static __inline__ __m64
+static inline __m64
pack565 (__m64 pixel, __m64 target, int pos)
{
__m64 p = pixel;
@@ -358,20 +399,28 @@ pack565 (__m64 pixel, __m64 target, int pos)
return _mm_or_si64 (b, p);
}
-static __inline__ __m64
+#ifndef _MSC_VER
+static inline __m64
pix_add_mul (__m64 x, __m64 a, __m64 y, __m64 b)
{
- x = _mm_mullo_pi16 (x, a);
- y = _mm_mullo_pi16 (y, b);
- x = _mm_srli_pi16(x, 1);
- y = _mm_srli_pi16(y, 1);
- x = _mm_adds_pu16 (x, y);
- x = _mm_adds_pu16 (x, _mm_srli_pi16 (x, 8));
+ x = _mm_mullo_pi16 (x, a);
+ y = _mm_mullo_pi16 (y, b);
x = _mm_adds_pu16 (x, MC(4x0080));
- x = _mm_srli_pi16 (x, 7);
+ x = _mm_adds_pu16 (x, y);
+ x = _mm_adds_pu16 (x, _mm_srli_pi16 (x, 8));
+ x = _mm_srli_pi16 (x, 8);
return x;
}
+#else
+#define pix_add_mul(x, a, y, b) \
+( x = _mm_mullo_pi16 (x, a), \
+ y = _mm_mullo_pi16 (y, b), \
+ x = _mm_adds_pu16 (x, MC(4x0080)), \
+ x = _mm_adds_pu16 (x, y), \
+ x = _mm_adds_pu16 (x, _mm_srli_pi16 (x, 8)), \
+ _mm_srli_pi16 (x, 8) )
+#endif
/* --------------- MMX code patch for fbcompose.c --------------------- */
@@ -590,8 +639,8 @@ mmxCombineSaturateU (CARD32 *dest, const CARD32 *src, int width)
CARD32 da = ~d >> 24;
if (sa > da) {
- __m64 msa = load8888(FbIntDiv(da, sa));
- msa = expand_alpha_rev(msa);
+ __m64 msa = load8888(FbIntDiv(da, sa) << 24);
+ msa = expand_alpha(msa);
ms = pix_multiply(ms, msa);
}
md = pix_add(md, ms);
@@ -1140,23 +1189,22 @@ fbCompositeSrc_8888x8x8888mmx (CARD8 op,
{
CARD32 *dstLine, *dst;
CARD32 *srcLine, *src;
- CARD8 *maskLine;
CARD32 mask;
__m64 vmask;
- FbStride dstStride, srcStride, maskStride;
+ FbStride dstStride, srcStride;
CARD16 w;
__m64 srca;
-
+
CHECKPOINT();
-
+
fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
- fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
- mask = *maskLine << 24 | *maskLine << 16 | *maskLine << 8 | *maskLine;
+ fbComposeGetSolid (pMask, mask, pDst->format);
+ mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
vmask = load8888 (mask);
srca = MC(4x00ff);
-
+
while (height--)
{
dst = dstLine;
@@ -1169,9 +1217,93 @@ fbCompositeSrc_8888x8x8888mmx (CARD8 op,
{
__m64 s = load8888 (*src);
__m64 d = load8888 (*dst);
-
+
+ *dst = store8888 (in_over (s, expand_alpha (s), vmask, d));
+
+ w--;
+ dst++;
+ src++;
+ }
+
+ while (w >= 2)
+ {
+ __m64 vs = *(__m64 *)src;
+ __m64 vd = *(__m64 *)dst;
+ __m64 vsrc0 = expand8888 (vs, 0);
+ __m64 vsrc1 = expand8888 (vs, 1);
+
+ *(__m64 *)dst = pack8888 (
+ in_over (vsrc0, expand_alpha (vsrc0), vmask, expand8888 (vd, 0)),
+ in_over (vsrc1, expand_alpha (vsrc1), vmask, expand8888 (vd, 1)));
+
+ w -= 2;
+ dst += 2;
+ src += 2;
+ }
+
+ while (w)
+ {
+ __m64 s = load8888 (*src);
+ __m64 d = load8888 (*dst);
+
+ *dst = store8888 (in_over (s, expand_alpha (s), vmask, d));
+
+ w--;
+ dst++;
+ src++;
+ }
+ }
+
+ _mm_empty();
+}
+
+void
+fbCompositeSrc_x888x8x8888mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 *dstLine, *dst;
+ CARD32 *srcLine, *src;
+ CARD32 mask;
+ __m64 vmask;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ __m64 srca;
+
+ CHECKPOINT();
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD32, srcStride, srcLine, 1);
+ fbComposeGetSolid (pMask, mask, pDst->format);
+
+ mask = mask | mask >> 8 | mask >> 16 | mask >> 24;
+ vmask = load8888 (mask);
+ srca = MC(4x00ff);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ while (w && (unsigned long)dst & 7)
+ {
+ __m64 s = load8888 (*src);
+ __m64 d = load8888 (*dst);
+
*dst = store8888 (in_over (s, srca, vmask, d));
-
+
w--;
dst++;
src++;
@@ -1197,39 +1329,39 @@ fbCompositeSrc_8888x8x8888mmx (CARD8 op,
__m64 vs6 = *(__m64 *)(src + 12);
__m64 vs7 = *(__m64 *)(src + 14);
- vd0 = (__m64)pack8888 (
+ vd0 = pack8888 (
in_over (expand8888 (vs0, 0), srca, vmask, expand8888 (vd0, 0)),
in_over (expand8888 (vs0, 1), srca, vmask, expand8888 (vd0, 1)));
-
- vd1 = (__m64)pack8888 (
+
+ vd1 = pack8888 (
in_over (expand8888 (vs1, 0), srca, vmask, expand8888 (vd1, 0)),
in_over (expand8888 (vs1, 1), srca, vmask, expand8888 (vd1, 1)));
-
- vd2 = (__m64)pack8888 (
+
+ vd2 = pack8888 (
in_over (expand8888 (vs2, 0), srca, vmask, expand8888 (vd2, 0)),
in_over (expand8888 (vs2, 1), srca, vmask, expand8888 (vd2, 1)));
-
- vd3 = (__m64)pack8888 (
+
+ vd3 = pack8888 (
in_over (expand8888 (vs3, 0), srca, vmask, expand8888 (vd3, 0)),
in_over (expand8888 (vs3, 1), srca, vmask, expand8888 (vd3, 1)));
-
- vd4 = (__m64)pack8888 (
+
+ vd4 = pack8888 (
in_over (expand8888 (vs4, 0), srca, vmask, expand8888 (vd4, 0)),
in_over (expand8888 (vs4, 1), srca, vmask, expand8888 (vd4, 1)));
-
- vd5 = (__m64)pack8888 (
+
+ vd5 = pack8888 (
in_over (expand8888 (vs5, 0), srca, vmask, expand8888 (vd5, 0)),
in_over (expand8888 (vs5, 1), srca, vmask, expand8888 (vd5, 1)));
-
- vd6 = (__m64)pack8888 (
+
+ vd6 = pack8888 (
in_over (expand8888 (vs6, 0), srca, vmask, expand8888 (vd6, 0)),
in_over (expand8888 (vs6, 1), srca, vmask, expand8888 (vd6, 1)));
-
- vd7 = (__m64)pack8888 (
+
+ vd7 = pack8888 (
in_over (expand8888 (vs7, 0), srca, vmask, expand8888 (vd7, 0)),
in_over (expand8888 (vs7, 1), srca, vmask, expand8888 (vd7, 1)));
- *(__m64 *)(dst + 0) = vd0;
+ *(__m64 *)(dst + 0) = vd0;
*(__m64 *)(dst + 2) = vd1;
*(__m64 *)(dst + 4) = vd2;
*(__m64 *)(dst + 6) = vd3;
@@ -1237,26 +1369,26 @@ fbCompositeSrc_8888x8x8888mmx (CARD8 op,
*(__m64 *)(dst + 10) = vd5;
*(__m64 *)(dst + 12) = vd6;
*(__m64 *)(dst + 14) = vd7;
-
+
w -= 16;
dst += 16;
src += 16;
}
-
+
while (w)
{
__m64 s = load8888 (*src);
__m64 d = load8888 (*dst);
-
+
*dst = store8888 (in_over (s, srca, vmask, d));
-
+
w--;
dst++;
src++;
}
}
- _mm_empty();
+ _mm_empty();
}
void
@@ -1552,6 +1684,256 @@ fbCompositeSolidMask_nx8x8888mmx (CARD8 op,
}
+Bool
+fbSolidFillmmx (DrawablePtr pDraw,
+ int x,
+ int y,
+ int width,
+ int height,
+ FbBits xor)
+{
+ FbStride stride;
+ int bpp;
+ ullong fill;
+ __m64 vfill;
+ CARD32 byte_width;
+ CARD8 *byte_line;
+ FbBits *bits;
+ int xoff, yoff;
+ __m64 v1, v2, v3, v4, v5, v6, v7;
+
+ CHECKPOINT();
+
+ fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff);
+
+ if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
+ return FALSE;
+
+ if (bpp != 16 && bpp != 32)
+ return FALSE;
+
+ if (bpp == 16)
+ {
+ stride = stride * sizeof (FbBits) / 2;
+ byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff));
+ byte_width = 2 * width;
+ stride *= 2;
+ }
+ else
+ {
+ stride = stride * sizeof (FbBits) / 4;
+ byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff));
+ byte_width = 4 * width;
+ stride *= 4;
+ }
+
+ fill = ((ullong)xor << 32) | xor;
+ vfill = (__m64)fill;
+
+ __asm__ (
+ "movq %7, %0\n"
+ "movq %7, %1\n"
+ "movq %7, %2\n"
+ "movq %7, %3\n"
+ "movq %7, %4\n"
+ "movq %7, %5\n"
+ "movq %7, %6\n"
+ : "=y" (v1), "=y" (v2), "=y" (v3),
+ "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
+ : "y" (vfill));
+
+ while (height--)
+ {
+ int w;
+ CARD8 *d = byte_line;
+ byte_line += stride;
+ w = byte_width;
+
+ while (w >= 2 && ((unsigned long)d & 3))
+ {
+ *(CARD16 *)d = xor;
+ w -= 2;
+ d += 2;
+ }
+
+ while (w >= 4 && ((unsigned long)d & 7))
+ {
+ *(CARD32 *)d = xor;
+
+ w -= 4;
+ d += 4;
+ }
+
+ while (w >= 64)
+ {
+ __asm__ (
+ "movq %1, (%0)\n"
+ "movq %2, 8(%0)\n"
+ "movq %3, 16(%0)\n"
+ "movq %4, 24(%0)\n"
+ "movq %5, 32(%0)\n"
+ "movq %6, 40(%0)\n"
+ "movq %7, 48(%0)\n"
+ "movq %8, 56(%0)\n"
+ :
+ : "r" (d),
+ "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
+ "y" (v4), "y" (v5), "y" (v6), "y" (v7)
+ : "memory");
+
+ w -= 64;
+ d += 64;
+ }
+
+ while (w >= 4)
+ {
+ *(CARD32 *)d = xor;
+
+ w -= 4;
+ d += 4;
+ }
+ if (w >= 2)
+ {
+ *(CARD16 *)d = xor;
+ w -= 2;
+ d += 2;
+ }
+ }
+
+ _mm_empty();
+ return TRUE;
+}
+
+void
+fbCompositeSolidMaskSrc_nx8x8888mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca;
+ CARD32 *dstLine, *dst;
+ CARD8 *maskLine, *mask;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ __m64 vsrc, vsrca;
+ ullong srcsrc;
+
+ CHECKPOINT();
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ srca = src >> 24;
+ if (srca == 0)
+ {
+ fbSolidFillmmx (pDst->pDrawable, xDst, yDst, width, height, 0);
+ return;
+ }
+
+ srcsrc = (ullong)src << 32 | src;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ vsrc = load8888 (src);
+ vsrca = expand_alpha (vsrc);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ CHECKPOINT();
+
+ while (w && (unsigned long)dst & 7)
+ {
+ ullong m = *mask;
+
+ if (m)
+ {
+ __m64 vdest = in(vsrc, expand_alpha_rev ((__m64)m));
+ *dst = store8888(vdest);
+ }
+ else
+ {
+ *dst = 0;
+ }
+
+ w--;
+ mask++;
+ dst++;
+ }
+
+ CHECKPOINT();
+
+ while (w >= 2)
+ {
+ ullong m0, m1;
+ m0 = *mask;
+ m1 = *(mask + 1);
+
+ if (srca == 0xff && (m0 & m1) == 0xff)
+ {
+ *(ullong *)dst = srcsrc;
+ }
+ else if (m0 | m1)
+ {
+ __m64 vdest;
+ __m64 dest0, dest1;
+
+ vdest = *(__m64 *)dst;
+
+ dest0 = in(vsrc, expand_alpha_rev ((__m64)m0));
+ dest1 = in(vsrc, expand_alpha_rev ((__m64)m1));
+
+ *(__m64 *)dst = pack8888(dest0, dest1);
+ }
+ else
+ {
+ *dst = 0;
+ }
+
+ mask += 2;
+ dst += 2;
+ w -= 2;
+ }
+
+ CHECKPOINT();
+
+ while (w)
+ {
+ ullong m = *mask;
+
+ if (m)
+ {
+ __m64 vdest = load8888(*dst);
+ vdest = in(vsrc, expand_alpha_rev ((__m64)m));
+ *dst = store8888(vdest);
+ }
+ else
+ {
+ *dst = 0;
+ }
+
+ w--;
+ mask++;
+ dst++;
+ }
+ }
+
+ _mm_empty();
+}
+
void
fbCompositeSolidMask_nx8x0565mmx (CARD8 op,
PicturePtr pSrc,
@@ -2003,6 +2385,232 @@ fbCompositeSolidMask_nx8888x0565Cmmx (CARD8 op,
}
void
+fbCompositeIn_nx8x8mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD8 *maskLine, *mask;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 src;
+ CARD8 sa;
+ __m64 vsrc, vsrca;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ sa = src >> 24;
+ if (sa == 0)
+ return;
+
+ vsrc = load8888(src);
+ vsrca = expand_alpha(vsrc);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ if ((((unsigned long)pDst & 3) == 0) &&
+ (((unsigned long)pSrc & 3) == 0))
+ {
+ while (w >= 4)
+ {
+ CARD32 m;
+ __m64 vmask;
+ __m64 vdest;
+
+ m = 0;
+
+ vmask = load8888 (*(CARD32 *)mask);
+ vdest = load8888 (*(CARD32 *)dst);
+
+ *(CARD32 *)dst = store8888 (in (in (vsrca, vmask), vdest));
+
+ dst += 4;
+ mask += 4;
+ w -= 4;
+ }
+ }
+
+ while (w--)
+ {
+ CARD16 tmp;
+ CARD8 a;
+ CARD32 m, d;
+ CARD32 r;
+
+ a = *mask++;
+ d = *dst;
+
+ m = FbInU (sa, 0, a, tmp);
+ r = FbInU (m, 0, d, tmp);
+
+ *dst++ = r;
+ }
+ }
+
+ _mm_empty();
+}
+
+void
+fbCompositeIn_8x8mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD8 *srcLine, *src;
+ FbStride srcStride, dstStride;
+ CARD16 w;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ if ((((unsigned long)pDst & 3) == 0) &&
+ (((unsigned long)pSrc & 3) == 0))
+ {
+ while (w >= 4)
+ {
+ CARD32 *s = (CARD32 *)src;
+ CARD32 *d = (CARD32 *)dst;
+
+ *d = store8888 (in (load8888 (*s), load8888 (*d)));
+
+ w -= 4;
+ dst += 4;
+ src += 4;
+ }
+ }
+
+ while (w--)
+ {
+ CARD8 s, d;
+ CARD16 tmp;
+
+ s = *src;
+ d = *dst;
+
+ *dst = FbInU (s, 0, d, tmp);
+
+ src++;
+ dst++;
+ }
+ }
+
+ _mm_empty ();
+}
+
+void
+fbCompositeSrcAdd_8888x8x8mmx (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD8 *maskLine, *mask;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 src;
+ CARD8 sa;
+ __m64 vsrc, vsrca;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ sa = src >> 24;
+ if (sa == 0)
+ return;
+
+ vsrc = load8888(src);
+ vsrca = expand_alpha(vsrc);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ if ((((unsigned long)pMask & 3) == 0) &&
+ (((unsigned long)pDst & 3) == 0))
+ {
+ while (w >= 4)
+ {
+ __m64 vmask = load8888 (*(CARD32 *)mask);
+ __m64 vdest = load8888 (*(CARD32 *)dst);
+
+ *(CARD32 *)dst = store8888 (_mm_adds_pu8 (in (vsrca, vmask), vdest));
+
+ w -= 4;
+ dst += 4;
+ mask += 4;
+ }
+ }
+
+ while (w--)
+ {
+ CARD16 tmp;
+ CARD16 a;
+ CARD32 m, d;
+ CARD32 r;
+
+ a = *mask++;
+ d = *dst;
+
+ m = FbInU (sa, 0, a, tmp);
+ r = FbAdd (m, d, 0, tmp);
+
+ *dst++ = r;
+ }
+ }
+
+ _mm_empty();
+}
+
+void
fbCompositeSrcAdd_8000x8000mmx (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
@@ -2135,126 +2743,6 @@ fbCompositeSrcAdd_8888x8888mmx (CARD8 op,
}
Bool
-fbSolidFillmmx (DrawablePtr pDraw,
- int x,
- int y,
- int width,
- int height,
- FbBits xor)
-{
- FbStride stride;
- int bpp;
- ullong fill;
- __m64 vfill;
- CARD32 byte_width;
- CARD8 *byte_line;
- FbBits *bits;
- int xoff, yoff;
- __m64 v1, v2, v3, v4, v5, v6, v7;
-
- CHECKPOINT();
-
- fbGetDrawable(pDraw, bits, stride, bpp, xoff, yoff);
-
- if (bpp == 16 && (xor >> 16 != (xor & 0xffff)))
- return FALSE;
-
- if (bpp != 16 && bpp != 32)
- return FALSE;
-
- if (bpp == 16)
- {
- stride = stride * sizeof (FbBits) / 2;
- byte_line = (CARD8 *)(((CARD16 *)bits) + stride * (y + yoff) + (x + xoff));
- byte_width = 2 * width;
- stride *= 2;
- }
- else
- {
- stride = stride * sizeof (FbBits) / 4;
- byte_line = (CARD8 *)(((CARD32 *)bits) + stride * (y + yoff) + (x + xoff));
- byte_width = 4 * width;
- stride *= 4;
- }
-
- fill = ((ullong)xor << 32) | xor;
- vfill = (__m64)fill;
-
- __asm__ (
- "movq %7, %0\n"
- "movq %7, %1\n"
- "movq %7, %2\n"
- "movq %7, %3\n"
- "movq %7, %4\n"
- "movq %7, %5\n"
- "movq %7, %6\n"
- : "=y" (v1), "=y" (v2), "=y" (v3),
- "=y" (v4), "=y" (v5), "=y" (v6), "=y" (v7)
- : "y" (vfill));
-
- while (height--)
- {
- int w;
- CARD8 *d = byte_line;
- byte_line += stride;
- w = byte_width;
-
- while (w >= 2 && ((unsigned long)d & 3))
- {
- *(CARD16 *)d = xor;
- w -= 2;
- d += 2;
- }
-
- while (w >= 4 && ((unsigned long)d & 7))
- {
- *(CARD32 *)d = xor;
-
- w -= 4;
- d += 4;
- }
-
- while (w >= 64)
- {
- __asm__ (
- "movq %1, (%0)\n"
- "movq %2, 8(%0)\n"
- "movq %3, 16(%0)\n"
- "movq %4, 24(%0)\n"
- "movq %5, 32(%0)\n"
- "movq %6, 40(%0)\n"
- "movq %7, 48(%0)\n"
- "movq %8, 56(%0)\n"
- :
- : "r" (d),
- "y" (vfill), "y" (v1), "y" (v2), "y" (v3),
- "y" (v4), "y" (v5), "y" (v6), "y" (v7)
- : "memory");
-
- w -= 64;
- d += 64;
- }
-
- while (w >= 4)
- {
- *(CARD32 *)d = xor;
-
- w -= 4;
- d += 4;
- }
- if (w >= 2)
- {
- *(CARD16 *)d = xor;
- w -= 2;
- d += 2;
- }
- }
-
- _mm_empty();
- return TRUE;
-}
-
-Bool
fbCopyAreammx (DrawablePtr pSrc,
DrawablePtr pDst,
int src_x,
diff --git a/fb/fbmmx.h b/fb/fbmmx.h
index b3e4d71ef..ca9c7e796 100644
--- a/fb/fbmmx.h
+++ b/fb/fbmmx.h
@@ -82,6 +82,32 @@ void fbCompositeSrc_8888x8888mmx (CARD8 op,
INT16 yDst,
CARD16 width,
CARD16 height);
+void
+fbCompositeSolidMaskSrc_nx8x8888mmx (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
+fbCompositeSrc_x888x8x8888mmx (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 fbCompositeSolidMask_nx8888x8888Cmmx (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
@@ -106,6 +132,42 @@ void fbCompositeSolidMask_nx8x8888mmx (CARD8 op,
INT16 yDst,
CARD16 width,
CARD16 height);
+void fbCompositeIn_nx8x8mmx (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 fbCompositeIn_8x8mmx (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 fbCompositeSrcAdd_8888x8x8mmx (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 fbCompositeSrcAdd_8000x8000mmx (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
diff --git a/fb/fbpict.c b/fb/fbpict.c
index cd6cac277..0a08affd7 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -91,6 +91,64 @@ fbIn (CARD32 x, CARD8 y)
return m|n|o|p;
}
+#define genericCombine24(a,b,c,d) (((a)*(c)+(b)*(d)))
+
+/*
+ * This macro does src IN mask OVER dst when src and dst are 0888.
+ * If src has alpha, this will not work
+ */
+#define inOver0888(alpha, source, destval, dest) { \
+ CARD32 dstrb=destval&0xFF00FF; CARD32 dstag=(destval>>8)&0xFF00FF; \
+ CARD32 drb=((source&0xFF00FF)-dstrb)*alpha; CARD32 dag=(((source>>8)&0xFF00FF)-dstag)*alpha; \
+ WRITE(dest, ((((drb>>8) + dstrb) & 0x00FF00FF) | ((((dag>>8) + dstag) << 8) & 0xFF00FF00))); \
+ }
+
+/*
+ * This macro does src IN mask OVER dst when src and dst are 0565 and
+ * mask is a 5-bit alpha value. Again, if src has alpha, this will not
+ * work.
+ */
+#define inOver0565(alpha, source, destval, dest) { \
+ CARD16 dstrb = destval & 0xf81f; CARD16 dstg = destval & 0x7e0; \
+ CARD32 drb = ((source&0xf81f)-dstrb)*alpha; CARD32 dg=((source & 0x7e0)-dstg)*alpha; \
+ WRITE(dest, ((((drb>>5) + dstrb)&0xf81f) | (((dg>>5) + dstg) & 0x7e0))); \
+ }
+
+
+#define inOver2x0565(alpha, source, destval, dest) { \
+ CARD32 dstrb = destval & 0x07e0f81f; CARD32 dstg = (destval & 0xf81f07e0)>>5; \
+ CARD32 drb = ((source&0x07e0f81f)-dstrb)*alpha; CARD32 dg=(((source & 0xf81f07e0)>>5)-dstg)*alpha; \
+ WRITE(dest, ((((drb>>5) + dstrb)&0x07e0f81f) | ((((dg>>5) + dstg)<<5) & 0xf81f07e0))); \
+ }
+
+
+#if IMAGE_BYTE_ORDER == LSBFirst
+#define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \
+ temp=count&3; \
+ where-=temp; \
+ workingWhere=(CARD32 *)where; \
+ workingVal=READ(workingWhere++); \
+ count=4-temp; \
+ workingVal>>=(8*temp)
+ #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)&0xff; (y)>>=8; (x)--;}
+ #define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
+ #define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
+ #define writePacked(what) workingoDest>>=8; workingoDest|=(what<<24); ww--; if(!ww) { ww=4; WRITE (wodst++, workingoDest); }
+#else
+ #warning "I havn't tested fbCompositeTrans_0888xnx0888() on big endian yet!"
+ #define setupPackedReader(count,temp,where,workingWhere,workingVal) count=(long)where; \
+ temp=count&3; \
+ where-=temp; \
+ workingWhere=(CARD32 *)where; \
+ workingVal=READ(workingWhere)++; \
+ count=4-temp; \
+ workingVal<<=(8*temp)
+ #define readPacked(where,x,y,z) {if(!(x)) { (x)=4; y = READ(z++); } where=(y)>>24; (y)<<=8; (x)--;}
+ #define readPackedSource(where) readPacked(where,ws,workingSource,wsrc)
+ #define readPackedDest(where) readPacked(where,wd,workingiDest,widst)
+ #define writePacked(what) workingoDest<<=8; workingoDest|=what; ww--; if(!ww) { ww=4; WRITE(wodst++, workingoDest); }
+#endif
+
/*
* Naming convention:
*
@@ -234,6 +292,7 @@ fbCompositeSolidMask_nx8888x8888C (CARD8 op,
fbFinishAccess (pDst->pDrawable);
}
+#define srcAlphaCombine24(a,b) genericCombine24(a,b,srca,srcia)
void
fbCompositeSolidMask_nx8x0888 (CARD8 op,
PicturePtr pSrc,
@@ -248,53 +307,86 @@ fbCompositeSolidMask_nx8x0888 (CARD8 op,
CARD16 width,
CARD16 height)
{
- CARD32 src, srca;
- CARD8 *dstLine, *dst;
- CARD32 d;
+ CARD32 src, srca, srcia;
+ CARD8 *dstLine, *dst, *edst;
CARD8 *maskLine, *mask, m;
FbStride dstStride, maskStride;
CARD16 w;
+ CARD32 rs,gs,bs,rd,gd,bd;
fbComposeGetSolid(pSrc, src, pDst->format);
srca = src >> 24;
+ srcia = 255-srca;
if (src == 0)
return;
+ rs=src&0xff;
+ gs=(src>>8)&0xff;
+ bs=(src>>16)&0xff;
+
fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
while (height--)
{
- dst = dstLine;
+ /* fixme: cleanup unused */
+ unsigned long wt, wd;
+ CARD32 workingiDest;
+ CARD32 *widst;
+
+ edst = dst = dstLine;
dstLine += dstStride;
mask = maskLine;
maskLine += maskStride;
w = width;
-
+
+#ifndef NO_MASKED_PACKED_READ
+ setupPackedReader(wd,wt,edst,widst,workingiDest);
+#endif
+
while (w--)
{
+#ifndef NO_MASKED_PACKED_READ
+ readPackedDest(rd);
+ readPackedDest(gd);
+ readPackedDest(bd);
+#else
+ rd = READ(edst++);
+ gd = READ(edst++);
+ bd = READ(edst++);
+#endif
m = READ(mask++);
if (m == 0xff)
{
if (srca == 0xff)
- d = src;
+ {
+ WRITE(dst++, rs);
+ WRITE(dst++, gs);
+ WRITE(dst++, bs);
+ }
else
{
- d = Fetch24(dst);
- d = fbOver24 (src, d);
+ WRITE(dst++, (srcAlphaCombine24(rs, rd)>>8));
+ WRITE(dst++, (srcAlphaCombine24(gs, gd)>>8));
+ WRITE(dst++, (srcAlphaCombine24(bs, bd)>>8));
}
- Store24(dst,d);
}
else if (m)
{
- d = fbOver24 (fbIn(src,m), Fetch24(dst));
- Store24(dst,d);
+ int na=(srca*(int)m)>>8;
+ int nia=255-na;
+ WRITE(dst++, (genericCombine24(rs, rd, na, nia)>>8));
+ WRITE(dst++, (genericCombine24(gs, gd, na, nia)>>8));
+ WRITE(dst++, (genericCombine24(bs, bd, na, nia)>>8));
+ }
+ else
+ {
+ dst+=3;
}
- dst += 3;
}
}
-
+
fbFinishAccess (pMask->pDrawable);
fbFinishAccess (pDst->pDrawable);
}
@@ -313,21 +405,105 @@ fbCompositeSolidMask_nx8x0565 (CARD8 op,
CARD16 width,
CARD16 height)
{
- CARD32 src, srca;
+ CARD32 src, srca8, srca5;
CARD16 *dstLine, *dst;
- CARD32 d;
+ CARD16 d;
+ CARD32 t;
CARD8 *maskLine, *mask, m;
FbStride dstStride, maskStride;
- CARD16 w;
+ CARD16 w,src16;
+
+ fbComposeGetSolid(pSrc, src, pDst->format);
+
+ if (src == 0)
+ return;
+
+ srca8 = (src >> 24);
+ srca5 = (srca8 >> 3);
+ src16 = cvt8888to0565(src);
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ m = READ(mask++);
+ if (m == 0)
+ dst++;
+ else if (srca5 == (0xff >> 3))
+ {
+ if (m == 0xff)
+ WRITE(dst++, src16);
+ else
+ {
+ d = READ(dst);
+ m >>= 3;
+ inOver0565 (m, src16, d, dst++);
+ }
+ }
+ else
+ {
+ d = READ(dst);
+ if (m == 0xff)
+ {
+ t = fbOver24 (src, cvt0565to0888 (d));
+ }
+ else
+ {
+ t = fbIn (src, m);
+ t = fbOver (t, cvt0565to0888 (d));
+ }
+ WRITE(dst++, cvt8888to0565 (t));
+ }
+ }
+ }
+
+ fbFinishAccess (pMask->pDrawable);
+ fbFinishAccess (pDst->pDrawable);
+}
+
+static void
+fbCompositeSolidMask_nx8888x0565 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD32 src, srca8, srca5;
+ CARD16 *dstLine, *dst;
+ CARD16 d;
+ CARD32 *maskLine, *mask;
+ CARD32 t;
+ CARD8 m;
+ FbStride dstStride, maskStride;
+ CARD16 w, src16;
fbComposeGetSolid(pSrc, src, pDst->format);
- srca = src >> 24;
if (src == 0)
return;
+ srca8 = src >> 24;
+ srca5 = srca8 >> 3;
+ src16 = cvt8888to0565(src);
+
fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
- fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD32, maskStride, maskLine, 1);
while (height--)
{
@@ -339,30 +515,38 @@ fbCompositeSolidMask_nx8x0565 (CARD8 op,
while (w--)
{
- m = READ(mask++);
- if (m == 0xff)
+ m = READ(mask++) >> 24;
+ if (m == 0)
+ dst++;
+ else if (srca5 == (0xff >> 3))
{
- if (srca == 0xff)
- d = src;
+ if (m == 0xff)
+ WRITE(dst++, src16);
else
{
d = READ(dst);
- d = fbOver24 (src, cvt0565to8888(d));
+ m >>= 3;
+ inOver0565 (m, src16, d, dst++);
}
- WRITE(dst, cvt8888to0565(d));
}
- else if (m)
+ else
{
- d = READ(dst);
- d = fbOver24 (fbIn(src,m), cvt0565to8888(d));
- WRITE(dst, cvt8888to0565(d));
+ if (m == 0xff)
+ {
+ d = READ(dst);
+ t = fbOver24 (src, cvt0565to0888 (d));
+ WRITE(dst++, cvt8888to0565 (t));
+ }
+ else
+ {
+ d = READ(dst);
+ t = fbIn (src, m);
+ t = fbOver (t, cvt0565to0888 (d));
+ WRITE(dst++, cvt8888to0565 (t));
+ }
}
- dst++;
}
}
-
- fbFinishAccess (pMask->pDrawable);
- fbFinishAccess (pDst->pDrawable);
}
void
@@ -419,14 +603,14 @@ fbCompositeSolidMask_nx8888x0565C (CARD8 op,
else
{
d = READ(dst);
- d = fbOver24 (src, cvt0565to8888(d));
+ d = fbOver24 (src, cvt0565to0888(d));
WRITE(dst, cvt8888to0565(d));
}
}
else if (ma)
{
d = READ(dst);
- d = cvt0565to8888(d);
+ d = cvt0565to0888(d);
FbInOverC (src, srca, ma, d, 0, m);
FbInOverC (src, srca, ma, d, 8, n);
FbInOverC (src, srca, ma, d, 16, o);
@@ -585,7 +769,7 @@ fbCompositeSrc_8888x0565 (CARD8 op,
else
{
d = READ(dst);
- d = fbOver24 (s, cvt0565to8888(d));
+ d = fbOver24 (s, cvt0565to0888(d));
}
WRITE(dst, cvt8888to0565(d));
}
@@ -598,45 +782,6 @@ fbCompositeSrc_8888x0565 (CARD8 op,
}
void
-fbCompositeSrc_0565x0565 (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- CARD16 *dstLine, *dst;
- CARD16 *srcLine, *src;
- FbStride dstStride, srcStride;
- CARD16 w;
-
- fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
-
- fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
-
- while (height--)
- {
- dst = dstLine;
- dstLine += dstStride;
- src = srcLine;
- srcLine += srcStride;
- w = width;
-
- while (w--)
- WRITE(dst, READ(src++));
- }
-
- fbFinishAccess (pDst->pDrawable);
- fbFinishAccess (pSrc->pDrawable);
-}
-
-void
fbCompositeSrcAdd_8000x8000 (CARD8 op,
PicturePtr pSrc,
PicturePtr pMask,
@@ -749,6 +894,61 @@ fbCompositeSrcAdd_8888x8888 (CARD8 op,
fbFinishAccess (pSrc->pDrawable);
}
+static void
+fbCompositeSrcAdd_8888x8x8 (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst;
+ CARD8 *maskLine, *mask;
+ FbStride dstStride, maskStride;
+ CARD16 w;
+ CARD32 src;
+ CARD8 sa;
+
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 1);
+ fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);
+ fbComposeGetSolid (pSrc, src, pDst->format);
+ sa = (src >> 24);
+
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ mask = maskLine;
+ maskLine += maskStride;
+ w = width;
+
+ while (w--)
+ {
+ CARD16 tmp;
+ CARD16 a;
+ CARD32 m, d;
+ CARD32 r;
+
+ a = READ(mask++);
+ d = READ(dst);
+
+ m = FbInU (sa, 0, a, tmp);
+ r = FbAdd (m, d, 0, tmp);
+
+ WRITE(dst++, r);
+ }
+ }
+
+ fbFinishAccess(pDst->pDrawable);
+ fbFinishAccess(pMask->pDrawable);
+}
+
void
fbCompositeSrcAdd_1000x1000 (CARD8 op,
PicturePtr pSrc,
@@ -864,6 +1064,385 @@ fbCompositeSolidMask_nx1xn (CARD8 op,
# define mod(a,b) ((b) == 1 ? 0 : (a) >= 0 ? (a) % (b) : (b) - (-a) % (b))
+/*
+ * Apply a constant alpha value in an over computation
+ */
+static void
+fbCompositeSrcSrc_nxn (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+static void
+fbCompositeTrans_0565xnx0565(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD16 *dstLine, *dst;
+ CARD16 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ FbBits mask;
+ CARD8 maskAlpha;
+ CARD16 s_16, d_16;
+ CARD32 s_32, d_32;
+
+ fbComposeGetSolid (pMask, mask, pDst->format);
+ maskAlpha = mask >> 27;
+
+ if (!maskAlpha)
+ return;
+ if (maskAlpha == 0xff)
+ {
+ fbCompositeSrcSrc_nxn (PictOpSrc, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height);
+ return;
+ }
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD16, srcStride, srcLine, 1);
+ fbComposeGetStart (pDst, xDst, yDst, CARD16, dstStride, dstLine, 1);
+
+ while (height--)
+ {
+ CARD32 *isrc, *idst;
+ dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width;
+
+ if(((long)src&1)==1)
+ {
+ s_16 = READ(src++);
+ d_16 = READ(dst);
+ inOver0565(maskAlpha, s_16, d_16, dst++);
+ w--;
+ }
+ isrc=(CARD32 *)src;
+ if(((long)dst&1)==0)
+ {
+ idst=(CARD32 *)dst;
+ while (w>1)
+ {
+ s_32 = READ(isrc++);
+ d_32 = READ(idst);
+ inOver2x0565(maskAlpha, s_32, d_32, idst++);
+ w-=2;
+ }
+ dst=(CARD16 *)idst;
+ }
+ else
+ {
+ while (w > 1)
+ {
+ s_32 = READ(isrc++);
+#if IMAGE_BYTE_ORDER == LSBFirst
+ s_16=s_32&0xffff;
+#else
+ s_16=s_32>>16;
+#endif
+ d_16 = READ(dst);
+ inOver0565 (maskAlpha, s_16, d_16, dst++);
+#if IMAGE_BYTE_ORDER == LSBFirst
+ s_16=s_32>>16;
+#else
+ s_16=s_32&0xffff;
+#endif
+ d_16 = READ(dst);
+ inOver0565(maskAlpha, s_16, d_16, dst++);
+ w-=2;
+ }
+ }
+ src=(CARD16 *)isrc;
+ if(w!=0)
+ {
+ s_16 = READ(src);
+ d_16 = READ(dst);
+ inOver0565(maskAlpha, s_16, d_16, dst);
+ }
+ }
+
+ fbFinishAccess (pSrc->pDrawable);
+ fbFinishAccess (pDst->pDrawable);
+}
+
+/* macros for "i can't believe it's not fast" packed pixel handling */
+#define alphamaskCombine24(a,b) genericCombine24(a,b,maskAlpha,maskiAlpha)
+
+static void
+fbCompositeTrans_0888xnx0888(CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ CARD8 *dstLine, *dst,*idst;
+ CARD8 *srcLine, *src;
+ FbStride dstStride, srcStride;
+ CARD16 w;
+ FbBits mask;
+ CARD16 maskAlpha,maskiAlpha;
+
+ fbComposeGetSolid (pMask, mask, pDst->format);
+ maskAlpha = mask >> 24;
+ maskiAlpha= 255-maskAlpha;
+
+ if (!maskAlpha)
+ return;
+ /*
+ if (maskAlpha == 0xff)
+ {
+ fbCompositeSrc_0888x0888 (op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height);
+ return;
+ }
+ */
+
+ fbComposeGetStart (pSrc, xSrc, ySrc, CARD8, srcStride, srcLine, 3);
+ fbComposeGetStart (pDst, xDst, yDst, CARD8, dstStride, dstLine, 3);
+
+ {
+ unsigned long ws,wt;
+ CARD32 workingSource;
+ CARD32 *wsrc, *wdst, *widst;
+ CARD32 rs, rd, nd;
+ CARD8 *isrc;
+
+
+ /* are xSrc and xDst at the same alignment? if not, we need to be complicated :) */
+ /* if(0==0) */
+ if ((((xSrc * 3) & 3) != ((xDst * 3) & 3)) ||
+ ((srcStride & 3) != (dstStride & 3)))
+ {
+ while (height--)
+ {
+ dst = dstLine;
+ dstLine += dstStride;
+ isrc = src = srcLine;
+ srcLine += srcStride;
+ w = width*3;
+
+ setupPackedReader(ws,wt,isrc,wsrc,workingSource);
+
+ /* get to word aligned */
+ switch(~(long)dst&3)
+ {
+ case 1:
+ readPackedSource(rs);
+ /* *dst++=alphamaskCombine24(rs, *dst)>>8; */
+ rd = READ(dst); /* make gcc happy. hope it doens't cost us too much performance*/
+ WRITE(dst++, alphamaskCombine24(rs, rd) >> 8);
+ w--; if(w==0) break;
+ case 2:
+ readPackedSource(rs);
+ rd = READ(dst);
+ WRITE(dst++, alphamaskCombine24(rs, rd) >> 8);
+ w--; if(w==0) break;
+ case 3:
+ readPackedSource(rs);
+ rd = READ(dst);
+ WRITE(dst++,alphamaskCombine24(rs, rd) >> 8);
+ w--; if(w==0) break;
+ }
+ wdst=(CARD32 *)dst;
+ while (w>3)
+ {
+ rs=READ(wsrc++);
+ /* FIXME: write a special readPackedWord macro, which knows how to
+ * halfword combine
+ */
+#if IMAGE_BYTE_ORDER == LSBFirst
+ rd=READ(wdst);
+ readPackedSource(nd);
+ readPackedSource(rs);
+ nd|=rs<<8;
+ readPackedSource(rs);
+ nd|=rs<<16;
+ readPackedSource(rs);
+ nd|=rs<<24;
+#else
+ readPackedSource(nd);
+ nd<<=24;
+ readPackedSource(rs);
+ nd|=rs<<16;
+ readPackedSource(rs);
+ nd|=rs<<8;
+ readPackedSource(rs);
+ nd|=rs;
+#endif
+ inOver0888(maskAlpha, nd, rd, wdst++);
+ w-=4;
+ }
+ src=(CARD8 *)wdst;
+ switch(w)
+ {
+ case 3:
+ readPackedSource(rs);
+ rd=READ(dst);
+ WRITE(dst++,alphamaskCombine24(rs, rd)>>8);
+ case 2:
+ readPackedSource(rs);
+ rd = READ(dst);
+ WRITE(dst++, alphamaskCombine24(rs, rd)>>8);
+ case 1:
+ readPackedSource(rs);
+ rd = READ(dst);
+ WRITE(dst++, alphamaskCombine24(rs, rd)>>8);
+ }
+ }
+ }
+ else
+ {
+ while (height--)
+ {
+ idst=dst = dstLine;
+ dstLine += dstStride;
+ src = srcLine;
+ srcLine += srcStride;
+ w = width*3;
+ /* get to word aligned */
+ switch(~(long)src&3)
+ {
+ case 1:
+ rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+ WRITE(dst++, rd);
+ w--; if(w==0) break;
+ case 2:
+ rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+ WRITE(dst++, rd);
+ w--; if(w==0) break;
+ case 3:
+ rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+ WRITE(dst++, rd);
+ w--; if(w==0) break;
+ }
+ wsrc=(CARD32 *)src;
+ widst=(CARD32 *)dst;
+ while(w>3)
+ {
+ rs = READ(wsrc++);
+ rd = READ(widst);
+ inOver0888 (maskAlpha, rs, rd, widst++);
+ w-=4;
+ }
+ src=(CARD8 *)wsrc;
+ dst=(CARD8 *)widst;
+ switch(w)
+ {
+ case 3:
+ rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+ WRITE(dst++, rd);
+ case 2:
+ rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+ WRITE(dst++, rd);
+ case 1:
+ rd=alphamaskCombine24(READ(src++), READ(dst))>>8;
+ WRITE(dst++, rd);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Simple bitblt
+ */
+
+static void
+fbCompositeSrcSrc_nxn (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ FbBits *dst;
+ FbBits *src;
+ FbStride dstStride, srcStride;
+ int srcXoff, srcYoff;
+ int dstXoff, dstYoff;
+ int srcBpp;
+ int dstBpp;
+ Bool reverse = FALSE;
+ Bool upsidedown = FALSE;
+
+ fbGetDrawable(pSrc->pDrawable,src,srcStride,srcBpp,srcXoff,srcYoff);
+ fbGetDrawable(pDst->pDrawable,dst,dstStride,dstBpp,dstXoff,dstYoff);
+
+ fbBlt (src + (ySrc + srcYoff) * srcStride,
+ srcStride,
+ (xSrc + srcXoff) * srcBpp,
+
+ dst + (yDst + dstYoff) * dstStride,
+ dstStride,
+ (xDst + dstXoff) * dstBpp,
+
+ (width) * dstBpp,
+ (height),
+
+ GXcopy,
+ FB_ALLONES,
+ dstBpp,
+
+ reverse,
+ upsidedown);
+
+ fbFinishAccess(pSrc->pDrawable);
+ fbFinishAccess(pDst->pDrawable);
+}
+
+/*
+ * Solid fill
+void
+fbCompositeSolidSrc_nxn (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
fbComposite (CARD8 op,
PicturePtr pSrc,
@@ -882,8 +1461,10 @@ fbComposite (CARD8 op,
int n;
BoxPtr pbox;
CompositeFunc func = NULL;
- Bool srcRepeat = pSrc->pDrawable && pSrc->repeat;
+ Bool srcRepeat = pSrc->pDrawable && pSrc->repeatType == RepeatNormal;
Bool maskRepeat = FALSE;
+ Bool srcTransform = pSrc->transform != 0;
+ Bool maskTransform = FALSE;
Bool srcAlphaMap = pSrc->alphaMap != 0;
Bool maskAlphaMap = FALSE;
Bool dstAlphaMap = pDst->alphaMap != 0;
@@ -897,43 +1478,48 @@ fbComposite (CARD8 op,
mmx_setup = TRUE;
}
#endif
-
+
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
if (pSrc->pDrawable) {
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
}
+
+ if (srcRepeat && srcTransform &&
+ pSrc->pDrawable->width == 1 &&
+ pSrc->pDrawable->height == 1)
+ srcTransform = FALSE;
+
if (pMask && pMask->pDrawable)
{
xMask += pMask->pDrawable->x;
yMask += pMask->pDrawable->y;
maskRepeat = pMask->repeat == RepeatNormal;
+
+ if (pMask->filter == PictFilterConvolution)
+ maskTransform = TRUE;
+
maskAlphaMap = pMask->alphaMap != 0;
+
+ if (maskRepeat && maskTransform &&
+ pMask->pDrawable->width == 1 &&
+ pMask->pDrawable->height == 1)
+ maskTransform = FALSE;
}
if (pSrc->pDrawable && (!pMask || pMask->pDrawable)
- && !pSrc->transform && !(pMask && pMask->transform)
+ && !srcTransform && !maskTransform
&& !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
&& (pSrc->filter != PictFilterConvolution)
&& (!pMask || pMask->filter != PictFilterConvolution))
switch (op) {
- case PictOpSrc:
-#ifdef USE_MMX
- if (!pMask && pSrc->format == pDst->format &&
- pSrc->format != PICT_a8 && pSrc->pDrawable != pDst->pDrawable)
- {
- func = fbCompositeCopyAreammx;
- }
-#endif
- break;
case PictOpOver:
if (pMask)
{
if (fbCanGetSolid(pSrc) &&
!maskRepeat)
{
- srcRepeat = FALSE;
if (PICT_FORMAT_COLOR(pSrc->format)) {
switch (pMask->format) {
case PICT_a8:
@@ -990,6 +1576,16 @@ fbComposite (CARD8 op,
break;
}
}
+ else
+ {
+ switch (pDst->format) {
+ case PICT_r5g6b5:
+ func = fbCompositeSolidMask_nx8888x0565;
+ break;
+ default:
+ break;
+ }
+ }
break;
case PICT_a8b8g8r8:
if (pMask->componentAlpha) {
@@ -1015,6 +1611,16 @@ fbComposite (CARD8 op,
break;
}
}
+ else
+ {
+ switch (pDst->format) {
+ case PICT_b5g6r5:
+ func = fbCompositeSolidMask_nx8888x0565;
+ break;
+ default:
+ break;
+ }
+ }
break;
case PICT_a1:
switch (pDst->format) {
@@ -1035,11 +1641,11 @@ fbComposite (CARD8 op,
default:
break;
}
- default:
- break;
}
+ if (func != fbCompositeGeneral)
+ srcRepeat = FALSE;
}
- else if (! srcRepeat) /* has mask and non-repeating source */
+ else if (!srcRepeat) /* has mask and non-repeating source */
{
if (pSrc->pDrawable == pMask->pDrawable &&
xSrc == xMask && ySrc == yMask &&
@@ -1104,21 +1710,53 @@ fbComposite (CARD8 op,
}
break;
}
- else
+ else if (maskRepeat &&
+ pMask->pDrawable->width == 1 &&
+ pMask->pDrawable->height == 1)
{
- /* non-repeating source, repeating mask => translucent window */
- if (fbCanGetSolid(pMask))
- {
- if (pSrc->format == PICT_x8r8g8b8 &&
- pDst->format == PICT_x8r8g8b8 &&
- pMask->format == PICT_a8)
- {
+ switch (pSrc->format) {
+ case PICT_r5g6b5:
+ case PICT_b5g6r5:
+ if (pDst->format == pSrc->format)
+ func = fbCompositeTrans_0565xnx0565;
+ break;
+ case PICT_r8g8b8:
+ case PICT_b8g8r8:
+ if (pDst->format == pSrc->format)
+ func = fbCompositeTrans_0888xnx0888;
+ break;
#ifdef USE_MMX
- if (fbHaveMMX())
- func = fbCompositeSrc_8888x8x8888mmx;
+ case PICT_x8r8g8b8:
+ if ((pDst->format == PICT_a8r8g8b8 ||
+ pDst->format == PICT_x8r8g8b8) &&
+ pMask->format == PICT_a8 && fbHaveMMX())
+ func = fbCompositeSrc_x888x8x8888mmx;
+ break;
+ case PICT_x8b8g8r8:
+ if ((pDst->format == PICT_a8b8g8r8 ||
+ pDst->format == PICT_x8b8g8r8) &&
+ pMask->format == PICT_a8 && fbHaveMMX())
+ func = fbCompositeSrc_x888x8x8888mmx;
+ break;
+ case PICT_a8r8g8b8:
+ if ((pDst->format == PICT_a8r8g8b8 ||
+ pDst->format == PICT_x8r8g8b8) &&
+ pMask->format == PICT_a8 && fbHaveMMX())
+ func = fbCompositeSrc_8888x8x8888mmx;
+ break;
+ case PICT_a8b8g8r8:
+ if ((pDst->format == PICT_a8b8g8r8 ||
+ pDst->format == PICT_x8b8g8r8) &&
+ pMask->format == PICT_a8 && fbHaveMMX())
+ func = fbCompositeSrc_8888x8x8888mmx;
+ break;
#endif
- }
+ default:
+ break;
}
+
+ if (func != fbCompositeGeneral)
+ maskRepeat = FALSE;
}
}
}
@@ -1159,7 +1797,20 @@ fbComposite (CARD8 op,
}
else if (! srcRepeat)
{
- switch (pSrc->format) {
+ /*
+ * Formats without alpha bits are just Copy with Over
+ */
+ if (pSrc->format == pDst->format && !PICT_FORMAT_A(pSrc->format))
+ {
+#ifdef USE_MMX
+ if (fbHaveMMX() &&
+ (pSrc->format == PICT_x8r8g8b8 || pSrc->format == PICT_x8b8g8r8))
+ func = fbCompositeCopyAreammx;
+ else
+#endif
+ func = fbCompositeSrcSrc_nxn;
+ }
+ else switch (pSrc->format) {
case PICT_a8r8g8b8:
switch (pDst->format) {
case PICT_a8r8g8b8:
@@ -1237,24 +1888,6 @@ fbComposite (CARD8 op,
break;
}
break;
- case PICT_r5g6b5:
- switch (pDst->format) {
- case PICT_r5g6b5:
- func = fbCompositeSrc_0565x0565;
- break;
- default:
- break;
- }
- break;
- case PICT_b5g6r5:
- switch (pDst->format) {
- case PICT_b5g6r5:
- func = fbCompositeSrc_0565x0565;
- break;
- default:
- break;
- }
- break;
default:
break;
}
@@ -1320,6 +1953,92 @@ fbComposite (CARD8 op,
break;
}
}
+ else
+ {
+ if ((pSrc->format == PICT_a8r8g8b8 ||
+ pSrc->format == PICT_a8b8g8r8) &&
+ fbCanGetSolid (pSrc) &&
+ pMask->format == PICT_a8 &&
+ pDst->format == PICT_a8)
+ {
+ srcRepeat = FALSE;
+#ifdef USE_MMX
+ if (fbHaveMMX())
+ func = fbCompositeSrcAdd_8888x8x8mmx;
+ else
+#endif
+ func = fbCompositeSrcAdd_8888x8x8;
+ }
+ }
+ break;
+ case PictOpSrc:
+ if (pMask)
+ {
+#ifdef USE_MMX
+ if (fbCanGetSolid (pSrc))
+ {
+ if (pMask->format == PICT_a8)
+ {
+ switch (pDst->format)
+ {
+ case PICT_a8r8g8b8:
+ case PICT_x8r8g8b8:
+ case PICT_a8b8g8r8:
+ case PICT_x8b8g8r8:
+ if (fbHaveMMX())
+ {
+ srcRepeat = FALSE;
+ func = fbCompositeSolidMaskSrc_nx8x8888mmx;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ }
+#endif
+ }
+ else
+ {
+ if (pSrc->format == pDst->format)
+ {
+#ifdef USE_MMX
+ if (pSrc->pDrawable != pDst->pDrawable && fbHaveMMX() &&
+ (PICT_FORMAT_BPP (pSrc->format) == 16 ||
+ PICT_FORMAT_BPP (pSrc->format) == 32))
+ func = fbCompositeCopyAreammx;
+ else
+#endif
+ func = fbCompositeSrcSrc_nxn;
+ }
+ }
+ break;
+ case PictOpIn:
+#ifdef USE_MMX
+ if (pSrc->format == PICT_a8 &&
+ pDst->format == PICT_a8 &&
+ !pMask)
+ {
+ if (fbHaveMMX())
+ func = fbCompositeIn_8x8mmx;
+ }
+ else if (srcRepeat && pMask && !pMask->componentAlpha &&
+ (pSrc->format == PICT_a8r8g8b8 ||
+ pSrc->format == PICT_a8b8g8r8) &&
+ (pMask->format == PICT_a8) &&
+ pDst->format == PICT_a8)
+ {
+ if (fbHaveMMX())
+ {
+ srcRepeat = FALSE;
+ func = fbCompositeIn_nx8x8mmx;
+ }
+ }
+#else
+ func = NULL;
+#endif
+ break;
+ default:
break;
}
@@ -1329,18 +2048,14 @@ fbComposite (CARD8 op,
return;
}
- if (!miComputeCompositeRegion (&region,
- pSrc,
- pMask,
- pDst,
- xSrc,
- ySrc,
- xMask,
- yMask,
- xDst,
- yDst,
- width,
- height))
+ /* if we are transforming, we handle repeats in fbFetchTransformed */
+ if (srcTransform)
+ srcRepeat = FALSE;
+ if (maskTransform)
+ maskRepeat = FALSE;
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height))
return;
n = REGION_NUM_RECTS (&region);
@@ -1455,7 +2170,7 @@ enum CPUFeatures {
static unsigned int detectCPUFeatures(void) {
unsigned int features = 0;
- unsigned int result;
+ unsigned int result = 0;
#ifdef HAVE_GETISAX
if (getisax(&result, 1)) {
@@ -1472,8 +2187,13 @@ static unsigned int detectCPUFeatures(void) {
}
#else
char vendor[13];
+#ifdef _MSC_VER
+ int vendor0 = 0, vendor1, vendor2;
+#endif
vendor[0] = 0;
vendor[12] = 0;
+
+#ifdef __GNUC__
/* see p. 118 of amd64 instruction set manual Vol3 */
/* We need to be careful about the handling of %ebx and
* %esp here. We can't declare either one as clobbered
@@ -1492,7 +2212,7 @@ static unsigned int detectCPUFeatures(void) {
"pop %%eax\n"
"mov $0x0, %%edx\n"
"xor %%ecx, %%eax\n"
- "jz 1\n"
+ "jz 1f\n"
"mov $0x00000000, %%eax\n"
"push %%ebx\n"
@@ -1516,6 +2236,45 @@ static unsigned int detectCPUFeatures(void) {
: "%eax", "%ecx", "%edx"
);
+#elif defined (_MSC_VER)
+
+ _asm {
+ pushfd
+ pop eax
+ mov ecx, eax
+ xor eax, 00200000h
+ push eax
+ popfd
+ pushfd
+ pop eax
+ mov edx, 0
+ xor eax, ecx
+ jz nocpuid
+
+ mov eax, 0
+ push ebx
+ cpuid
+ mov eax, ebx
+ pop ebx
+ mov vendor0, eax
+ mov vendor1, edx
+ mov vendor2, ecx
+ mov eax, 1
+ push ebx
+ cpuid
+ pop ebx
+ nocpuid:
+ mov result, edx
+ }
+ memmove (vendor+0, &vendor0, 4);
+ memmove (vendor+4, &vendor1, 4);
+ memmove (vendor+8, &vendor2, 4);
+
+#else
+# error unsupported compiler
+#endif
+
+ features = 0;
if (result) {
/* result now contains the standard feature bits */
if (result & (1 << 15))
@@ -1530,14 +2289,13 @@ static unsigned int detectCPUFeatures(void) {
(strcmp(vendor, "AuthenticAMD") == 0 ||
strcmp(vendor, "Geode by NSC") == 0)) {
/* check for AMD MMX extensions */
-
- unsigned int result;
+#ifdef __GNUC__
__asm__("push %%ebx\n"
"mov $0x80000000, %%eax\n"
"cpuid\n"
"xor %%edx, %%edx\n"
"cmp $0x1, %%eax\n"
- "jge 2\n"
+ "jge 2f\n"
"mov $0x80000001, %%eax\n"
"cpuid\n"
"2:\n"
@@ -1547,11 +2305,27 @@ static unsigned int detectCPUFeatures(void) {
:
: "%eax", "%ecx", "%edx"
);
+#elif defined _MSC_VER
+ _asm {
+ push ebx
+ mov eax, 80000000h
+ cpuid
+ xor edx, edx
+ cmp eax, 1
+ jge notamd
+ mov eax, 80000001h
+ cpuid
+ notamd:
+ pop ebx
+ mov result, edx
+ }
+#endif
if (result & (1<<22))
features |= MMX_Extensions;
}
}
#endif /* HAVE_GETISAX */
+
return features;
}
diff --git a/fb/fbpict.h b/fb/fbpict.h
index 434526e32..5246cd5ac 100644
--- a/fb/fbpict.h
+++ b/fb/fbpict.h
@@ -121,7 +121,15 @@ fbCanGetSolid(PicturePtr pict)
break; \
case 16: \
(bits) = READ((CARD16 *) __bits__); \
- (bits) = cvt0565to8888(bits); \
+ (bits) = cvt0565to0888(bits); \
+ break; \
+ case 8: \
+ (bits) = READ((CARD8 *) __bits__); \
+ (bits) = (bits) << 24; \
+ break; \
+ case 1: \
+ (bits) = READ((CARD32 *) __bits__); \
+ (bits) = FbLeftStipBits((bits),1) ? 0xff000000 : 0x00000000;\
break; \
default: \
return; \
@@ -153,7 +161,7 @@ fbCanGetSolid(PicturePtr pict)
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
(((s) >> 5) & 0x07e0) | \
(((s) >> 8) & 0xf800))
-#define cvt0565to8888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
+#define cvt0565to0888(s) (((((s) << 3) & 0xf8) | (((s) >> 2) & 0x7)) | \
((((s) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))
diff --git a/hw/kdrive/Makefile.am b/hw/kdrive/Makefile.am
index e07804948..267d772e2 100644
--- a/hw/kdrive/Makefile.am
+++ b/hw/kdrive/Makefile.am
@@ -23,14 +23,20 @@ if KDRIVELINUX
LINUX_SUBDIRS = linux
endif
-SUBDIRS = \
- src \
- $(LINUX_SUBDIRS) \
+SERVER_SUBDIRS = \
$(XSDL_SUBDIRS) \
$(FBDEV_SUBDIRS) \
$(VESA_SUBDIRS) \
$(XEPHYR_SUBDIRS) \
$(XFAKE_SUBDIRS)
+SUBDIRS = \
+ src \
+ $(LINUX_SUBDIRS) \
+ $(SERVER_SUBDIRS)
+
DIST_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \
smi via fbdev sdl ephyr src linux fake sis300
+
+relink:
+ @for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done
diff --git a/hw/kdrive/ati/Makefile.am b/hw/kdrive/ati/Makefile.am
index 76635fb52..61c1c844b 100644
--- a/hw/kdrive/ati/Makefile.am
+++ b/hw/kdrive/ati/Makefile.am
@@ -62,3 +62,6 @@ Xati_LDADD = \
$(ATI_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/chips/Makefile.am b/hw/kdrive/chips/Makefile.am
index 2f8a88da0..a0a10d715 100644
--- a/hw/kdrive/chips/Makefile.am
+++ b/hw/kdrive/chips/Makefile.am
@@ -24,3 +24,6 @@ Xchips_LDADD = \
$(CHIPS_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/ephyr/Makefile.am b/hw/kdrive/ephyr/Makefile.am
index c201fe9d6..1e820c097 100644
--- a/hw/kdrive/ephyr/Makefile.am
+++ b/hw/kdrive/ephyr/Makefile.am
@@ -29,3 +29,6 @@ Xephyr_LDADD = \
../../../exa/libexa.la \
@KDRIVE_LIBS@ \
@XEPHYR_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/epson/Makefile.am b/hw/kdrive/epson/Makefile.am
index a5bc70b02..d36230abe 100644
--- a/hw/kdrive/epson/Makefile.am
+++ b/hw/kdrive/epson/Makefile.am
@@ -24,3 +24,6 @@ Xepson_LDADD = \
$(EPSON_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/fake/Makefile.am b/hw/kdrive/fake/Makefile.am
index d7ebfc243..69fdf59d5 100644
--- a/hw/kdrive/fake/Makefile.am
+++ b/hw/kdrive/fake/Makefile.am
@@ -20,3 +20,6 @@ Xfake_LDADD = \
libfake.a \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/fbdev/Makefile.am b/hw/kdrive/fbdev/Makefile.am
index cb7180184..b7a863bf6 100644
--- a/hw/kdrive/fbdev/Makefile.am
+++ b/hw/kdrive/fbdev/Makefile.am
@@ -18,4 +18,7 @@ Xfbdev_LDADD = \
libfbdev.a \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
endif
diff --git a/hw/kdrive/i810/Makefile.am b/hw/kdrive/i810/Makefile.am
index 503958571..79093da60 100644
--- a/hw/kdrive/i810/Makefile.am
+++ b/hw/kdrive/i810/Makefile.am
@@ -27,3 +27,6 @@ Xi810_LDADD = \
$(I810_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/mach64/Makefile.am b/hw/kdrive/mach64/Makefile.am
index 67712e262..b4d9a4eef 100644
--- a/hw/kdrive/mach64/Makefile.am
+++ b/hw/kdrive/mach64/Makefile.am
@@ -31,3 +31,6 @@ Xmach64_LDADD = \
$(MACH64_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/mga/Makefile.am b/hw/kdrive/mga/Makefile.am
index ee0798915..db1a9563d 100644
--- a/hw/kdrive/mga/Makefile.am
+++ b/hw/kdrive/mga/Makefile.am
@@ -26,3 +26,6 @@ Xmga_LDADD = \
$(MGA_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/neomagic/Makefile.am b/hw/kdrive/neomagic/Makefile.am
index 9a1af990c..33bc3a911 100644
--- a/hw/kdrive/neomagic/Makefile.am
+++ b/hw/kdrive/neomagic/Makefile.am
@@ -38,3 +38,6 @@ Xneomagic_LDADD = \
$(NEOMAGIC_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/nvidia/Makefile.am b/hw/kdrive/nvidia/Makefile.am
index 67eff6961..79d2738a0 100644
--- a/hw/kdrive/nvidia/Makefile.am
+++ b/hw/kdrive/nvidia/Makefile.am
@@ -27,3 +27,6 @@ Xnvidia_LDADD = \
$(NVIDIA_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/pm2/Makefile.am b/hw/kdrive/pm2/Makefile.am
index a7b0f0088..ec70276c5 100644
--- a/hw/kdrive/pm2/Makefile.am
+++ b/hw/kdrive/pm2/Makefile.am
@@ -25,3 +25,6 @@ Xpm2_LDADD = \
$(PM2_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/r128/Makefile.am b/hw/kdrive/r128/Makefile.am
index eab80cce0..1ca1a605b 100644
--- a/hw/kdrive/r128/Makefile.am
+++ b/hw/kdrive/r128/Makefile.am
@@ -24,3 +24,6 @@ Xr128_LDADD = \
$(R128_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/sdl/Makefile.am b/hw/kdrive/sdl/Makefile.am
index f5abb86e8..fa09640d2 100644
--- a/hw/kdrive/sdl/Makefile.am
+++ b/hw/kdrive/sdl/Makefile.am
@@ -11,3 +11,6 @@ Xsdl_LDADD = @KDRIVE_PURE_LIBS@ \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@ \
@XSDL_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/sis300/Makefile.am b/hw/kdrive/sis300/Makefile.am
index 98020745c..62f3266e1 100644
--- a/hw/kdrive/sis300/Makefile.am
+++ b/hw/kdrive/sis300/Makefile.am
@@ -38,3 +38,6 @@ Xsis_LDADD = \
$(SIS_LIBS) \
@KDRIVE_LIBS@ \
$(TSLIB_FLAG)
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/smi/Makefile.am b/hw/kdrive/smi/Makefile.am
index 0fd9729fc..a6ac474b0 100644
--- a/hw/kdrive/smi/Makefile.am
+++ b/hw/kdrive/smi/Makefile.am
@@ -29,3 +29,6 @@ Xsmi_LDADD = \
$(SMI_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/vesa/Makefile.am b/hw/kdrive/vesa/Makefile.am
index 54a6f47ee..e062fe777 100644
--- a/hw/kdrive/vesa/Makefile.am
+++ b/hw/kdrive/vesa/Makefile.am
@@ -23,3 +23,6 @@ Xvesa_LDADD = \
libvesa.a \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/via/Makefile.am b/hw/kdrive/via/Makefile.am
index 0ea88816a..1c5796963 100644
--- a/hw/kdrive/via/Makefile.am
+++ b/hw/kdrive/via/Makefile.am
@@ -25,3 +25,6 @@ Xvia_LDADD = \
$(VIA_LIBS) \
@KDRIVE_LIBS@ \
@XSERVER_LIBS@
+
+relink:
+ rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c
index 6a5d4ee9d..6bf18f148 100644
--- a/hw/xfree86/common/xf86Xinput.c
+++ b/hw/xfree86/common/xf86Xinput.c
@@ -807,4 +807,48 @@ xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
}
}
+
+/**
+ * Deactivate a device. Call this function from the driver if you receive a
+ * read error or something else that spoils your day.
+ * Device will be moved to the off_devices list, but it will still be there
+ * until you really clean up after it.
+ * Notifies the client about an inactive device.
+ *
+ * @param panic True if device is unrecoverable and needs to be removed.
+ */
+_X_EXPORT void
+xf86DisableDevice(DeviceIntPtr dev, Bool panic)
+{
+ devicePresenceNotify ev;
+ DeviceIntRec dummyDev;
+
+ if(!panic)
+ {
+ DisableDevice(dev);
+ } else
+ {
+ ev.type = DevicePresenceNotify;
+ ev.time = currentTime.milliseconds;
+ ev.devchange = DeviceUnrecoverable;
+ ev.deviceid = dev->id;
+ dummyDev.id = 0;
+ SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
+ (xEvent *) &ev, 1);
+
+ DeleteInputDeviceRequest(dev);
+ }
+}
+
+/**
+ * Reactivate a device. Call this function from the driver if you just found
+ * out that the read error wasn't quite that bad after all.
+ * Device will be re-activated, and an event sent to the client.
+ */
+_X_EXPORT void
+xf86EnableDevice(DeviceIntPtr dev)
+{
+ EnableDevice(dev);
+}
+
/* end of xf86Xinput.c */
diff --git a/hw/xfree86/common/xf86Xinput.h b/hw/xfree86/common/xf86Xinput.h
index 60f9ec337..37786f615 100644
--- a/hw/xfree86/common/xf86Xinput.h
+++ b/hw/xfree86/common/xf86Xinput.h
@@ -188,6 +188,8 @@ void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval,
void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
void xf86AddEnabledDevice(InputInfoPtr pInfo);
void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
+void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
+void xf86EnableDevice(DeviceIntPtr dev);
/* xf86Helper.c */
void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
@@ -205,6 +207,7 @@ int xf86GetMotionEvents(DeviceIntPtr dev, xTimecoord *buff,
void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
pointer extraOpts);
+
/* Legacy hatred */
#define SendCoreEvents 59
#define DontSendCoreEvents 60
diff --git a/hw/xfree86/ddc/edid_modes.c b/hw/xfree86/ddc/edid_modes.c
deleted file mode 100644
index 926bc8921..000000000
--- a/hw/xfree86/ddc/edid_modes.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- *
- * 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, sub license,
- * 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS 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.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86DDC.h"
-
-/*
- * TODO:
- * - for those with access to the VESA DMT standard; review please.
- */
-#define MODEPREFIX(name) NULL, NULL, name, 0,M_T_DRIVER
-#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-DisplayModeRec DDCEstablishedModes[17] = {
- { MODEPREFIX("800x600"), 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
- { MODEPREFIX("800x600"), 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
- { MODEPREFIX("640x480"), 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
- { MODEPREFIX("640x480"), 31500, 640, 664, 704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
- { MODEPREFIX("640x480"), 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */
- { MODEPREFIX("640x480"), 25200, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
- { MODEPREFIX("720x400"), 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */
- { MODEPREFIX("720x400"), 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */
- { MODEPREFIX("1280x1024"), 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
- { MODEPREFIX("1024x768"), 78800, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
- { MODEPREFIX("1024x768"), 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
- { MODEPREFIX("1024x768"), 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
- { MODEPREFIX("1024x768"), 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 776, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */
- { MODEPREFIX("832x624"), 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */
- { MODEPREFIX("800x600"), 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
- { MODEPREFIX("800x600"), 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
- { MODEPREFIX("1152x864"), 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
-};
-
-static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing)
-{
- DisplayModePtr Modes = NULL, Mode = NULL;
- CARD32 bits = (timing->t1) | (timing->t2 << 8) |
- ((timing->t_manu & 0x80) << 9);
- int i;
-
- for (i = 0; i < 17; i++) {
- if (bits & (0x01 << i)) {
- Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
- Modes = xf86ModesAdd(Modes, Mode);
- }
- }
-
- return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModesFromStandardTiming(int scrnIndex, struct std_timings *timing)
-{
- DisplayModePtr Modes = NULL, Mode = NULL;
- int i;
-
- for (i = 0; i < STD_TIMINGS; i++) {
- if (timing[i].hsize && timing[i].vsize && timing[i].refresh) {
- Mode = xf86CVTMode(timing[i].hsize, timing[i].vsize,
- timing[i].refresh, FALSE, FALSE);
- Mode->type = M_T_DRIVER;
- Modes = xf86ModesAdd(Modes, Mode);
- }
- }
-
- return Modes;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
- int preferred)
-{
- DisplayModePtr Mode;
-
- /*
- * Refuse to create modes that are insufficiently large. 64 is a random
- * number, maybe the spec says something about what the minimum is. In
- * particular I see this frequently with _old_ EDID, 1.0 or so, so maybe
- * our parser is just being too aggresive there.
- */
- if (timing->h_active < 64 || timing->v_active < 64) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: Ignoring tiny %dx%d mode\n", __func__,
- timing->h_active, timing->v_active);
- return NULL;
- }
-
- /* We don't do stereo */
- if (timing->stereo) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: Ignoring: We don't handle stereo.\n", __func__);
- return NULL;
- }
-
- /* We only do seperate sync currently */
- if (timing->sync != 0x03) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: %dx%d Warning: We only handle seperate"
- " sync.\n", __func__, timing->h_active, timing->v_active);
- }
-
- Mode = xnfalloc(sizeof(DisplayModeRec));
- memset(Mode, 0, sizeof(DisplayModeRec));
-
- Mode->type = M_T_DRIVER;
- if (preferred)
- Mode->type |= M_T_PREFERRED;
-
- Mode->Clock = timing->clock / 1000.0;
-
- Mode->HDisplay = timing->h_active;
- Mode->HSyncStart = timing->h_active + timing->h_sync_off;
- Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
- Mode->HTotal = timing->h_active + timing->h_blanking;
-
- Mode->VDisplay = timing->v_active;
- Mode->VSyncStart = timing->v_active + timing->v_sync_off;
- Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
- Mode->VTotal = timing->v_active + timing->v_blanking;
-
- xf86SetModeDefaultName(Mode);
-
- /* We ignore h/v_size and h/v_border for now. */
-
- if (timing->interlaced)
- Mode->Flags |= V_INTERLACE;
-
- if (timing->misc & 0x02)
- Mode->Flags |= V_PHSYNC;
- else
- Mode->Flags |= V_NHSYNC;
-
- if (timing->misc & 0x01)
- Mode->Flags |= V_PVSYNC;
- else
- Mode->Flags |= V_NVSYNC;
-
- return Mode;
-}
-
-/*
- *
- */
-static void
-DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
-{
- DisplayModePtr Mode = Modes;
-
- if (!Monitor || !Modes)
- return;
-
- /* set up the ranges for scanning through the modes */
- Monitor->nHsync = 1;
- Monitor->hsync[0].lo = 1024.0;
- Monitor->hsync[0].hi = 0.0;
-
- Monitor->nVrefresh = 1;
- Monitor->vrefresh[0].lo = 1024.0;
- Monitor->vrefresh[0].hi = 0.0;
-
- while (Mode) {
- if (!Mode->HSync)
- Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
-
- if (!Mode->VRefresh)
- Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
- ((float) (Mode->HTotal * Mode->VTotal));
-
- if (Mode->HSync < Monitor->hsync[0].lo)
- Monitor->hsync[0].lo = Mode->HSync;
-
- if (Mode->HSync > Monitor->hsync[0].hi)
- Monitor->hsync[0].hi = Mode->HSync;
-
- if (Mode->VRefresh < Monitor->vrefresh[0].lo)
- Monitor->vrefresh[0].lo = Mode->VRefresh;
-
- if (Mode->VRefresh > Monitor->vrefresh[0].hi)
- Monitor->vrefresh[0].hi = Mode->VRefresh;
-
- Mode = Mode->next;
- }
-}
-
-DisplayModePtr
-xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
-{
- int preferred, i;
- DisplayModePtr Modes = NULL, Mode;
-
- preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
-
- /* Add established timings */
- Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1);
- Modes = xf86ModesAdd(Modes, Mode);
-
- /* Add standard timings */
- Mode = DDCModesFromStandardTiming(scrnIndex, DDC->timings2);
- Modes = xf86ModesAdd(Modes, Mode);
-
- for (i = 0; i < DET_TIMINGS; i++) {
- struct detailed_monitor_section *det_mon = &DDC->det_mon[i];
-
- switch (det_mon->type) {
- case DT:
- Mode = DDCModeFromDetailedTiming(scrnIndex,
- &det_mon->section.d_timings,
- preferred);
- preferred = 0;
- Modes = xf86ModesAdd(Modes, Mode);
- break;
- case DS_STD_TIMINGS:
- Mode = DDCModesFromStandardTiming(scrnIndex,
- det_mon->section.std_t);
- Modes = xf86ModesAdd(Modes, Mode);
- break;
- default:
- break;
- }
- }
-
- return Modes;
-}
-
-/*
- * Fill out MonPtr with xf86MonPtr information.
- */
-void
-xf86DDCMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
-{
- DisplayModePtr Modes = NULL, Mode;
- int i, clock;
- Bool have_hsync = FALSE, have_vrefresh = FALSE;
-
- if (!Monitor || !DDC)
- return;
-
- Monitor->DDC = DDC;
-
- Monitor->widthmm = 10 * DDC->features.hsize;
- Monitor->heightmm = 10 * DDC->features.vsize;
-
- /* If this is a digital display, then we can use reduced blanking */
- if (DDC->features.input_type)
- Monitor->reducedblanking = TRUE;
- /* Allow the user to also enable this through config */
-
- Modes = xf86DDCGetModes(scrnIndex, DDC);
-
- /* Skip EDID ranges if they were specified in the config file */
- have_hsync = (Monitor->nHsync != 0);
- have_vrefresh = (Monitor->nVrefresh != 0);
-
- /* Go through the detailed monitor sections */
- for (i = 0; i < DET_TIMINGS; i++) {
- switch (DDC->det_mon[i].type) {
- case DS_RANGES:
- if (!have_hsync) {
- if (!Monitor->nHsync)
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using EDID range info for horizontal sync\n");
- Monitor->hsync[Monitor->nHsync].lo =
- DDC->det_mon[i].section.ranges.min_h;
- Monitor->hsync[Monitor->nHsync].hi =
- DDC->det_mon[i].section.ranges.max_h;
- Monitor->nHsync++;
- } else {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using hsync ranges from config file\n");
- }
-
- if (!have_vrefresh) {
- if (!Monitor->nVrefresh)
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using EDID range info for vertical refresh\n");
- Monitor->vrefresh[Monitor->nVrefresh].lo =
- DDC->det_mon[i].section.ranges.min_v;
- Monitor->vrefresh[Monitor->nVrefresh].hi =
- DDC->det_mon[i].section.ranges.max_v;
- Monitor->nVrefresh++;
- } else {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using vrefresh ranges from config file\n");
- }
-
- clock = DDC->det_mon[i].section.ranges.max_clock * 1000;
- if (clock > Monitor->maxPixClock)
- Monitor->maxPixClock = clock;
-
- break;
- default:
- break;
- }
- }
-
- if (Modes) {
- /* Print Modes */
- xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n");
-
- Mode = Modes;
- while (Mode) {
- xf86PrintModeline(scrnIndex, Mode);
- Mode = Mode->next;
- }
-
- /* Do we still need ranges to be filled in? */
- if (!Monitor->nHsync || !Monitor->nVrefresh)
- DDCGuessRangesFromModes(scrnIndex, Monitor, Modes);
-
- /* look for last Mode */
- Mode = Modes;
-
- while (Mode->next)
- Mode = Mode->next;
-
- /* add to MonPtr */
- if (Monitor->Modes) {
- Monitor->Last->next = Modes;
- Modes->prev = Monitor->Last;
- Monitor->Last = Mode;
- } else {
- Monitor->Modes = Modes;
- Monitor->Last = Mode;
- }
- }
-}
diff --git a/hw/xfree86/dri/dri.c b/hw/xfree86/dri/dri.c
index 05df54aec..023c81ebb 100644
--- a/hw/xfree86/dri/dri.c
+++ b/hw/xfree86/dri/dri.c
@@ -43,6 +43,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
+#include <errno.h>
#define NEED_REPLIES
#define NEED_EVENTS
@@ -78,6 +79,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern Bool noPanoramiXExtension;
#endif
+static int DRIEntPrivIndex = -1;
static int DRIScreenPrivIndex = -1;
static int DRIWindowPrivIndex = -1;
static unsigned long DRIGeneration = 0;
@@ -113,18 +115,203 @@ DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
}
+static void
+DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
+{
+ if (pDRIEntPriv->pLSAREA != NULL) {
+ drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
+ pDRIEntPriv->pLSAREA = NULL;
+ }
+ if (pDRIEntPriv->hLSAREA != 0) {
+ drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
+ }
+ if (pDRIEntPriv->drmFD >= 0) {
+ drmClose(pDRIEntPriv->drmFD);
+ pDRIEntPriv->drmFD = 0;
+ }
+}
+
+int
+DRIMasterFD(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->drmFD;
+}
+
+void *
+DRIMasterSareaPointer(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->pLSAREA;
+}
+
+drm_handle_t
+DRIMasterSareaHandle(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->hLSAREA;
+}
+
+
+Bool
+DRIOpenDRMMaster(ScrnInfoPtr pScrn,
+ unsigned long sAreaSize,
+ const char *busID,
+ const char *drmDriverName)
+{
+ drmSetVersion saveSv, sv;
+ Bool drmWasAvailable;
+ DRIEntPrivPtr pDRIEntPriv;
+ DRIEntPrivRec tmp;
+ drmVersionPtr drmlibv;
+ int drmlibmajor, drmlibminor;
+ const char *openBusID;
+ int count;
+ int err;
+
+ if (DRIEntPrivIndex == -1)
+ DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
+
+ pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+
+ if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
+ return TRUE;
+
+ drmWasAvailable = drmAvailable();
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ /* Check the DRM lib version.
+ * drmGetLibVersion was not supported in version 1.0, so check for
+ * symbol first to avoid possible crash or hang.
+ */
+
+ drmlibmajor = 1;
+ drmlibminor = 0;
+ if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
+ drmlibv = drmGetLibVersion(-1);
+ if (drmlibv != NULL) {
+ drmlibmajor = drmlibv->version_major;
+ drmlibminor = drmlibv->version_minor;
+ drmFreeVersion(drmlibv);
+ }
+ }
+
+ /* Check if the libdrm can handle falling back to loading based on name
+ * if a busid string is passed.
+ */
+ openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
+
+ tmp.drmFD = -1;
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 1;
+ sv.drm_dd_major = -1;
+
+ saveSv = sv;
+ count = 10;
+ while (count--) {
+ tmp.drmFD = drmOpen(drmDriverName, openBusID);
+
+ if (tmp.drmFD < 0) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
+ goto out_err;
+ }
+
+ err = drmSetInterfaceVersion(tmp.drmFD, &sv);
+
+ if (err != -EPERM)
+ break;
+
+ sv = saveSv;
+ drmClose(tmp.drmFD);
+ tmp.drmFD = -1;
+ usleep(100000);
+ }
+
+ if (tmp.drmFD <= 0) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
+ goto out_err;
+ }
+
+ if (!drmWasAvailable) {
+ DRIDrvMsg(-1, X_INFO,
+ "[drm] loaded kernel module for \"%s\" driver.\n",
+ drmDriverName);
+ }
+
+ if (err != 0) {
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 0;
+ }
+
+ DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
+ sv.drm_di_major, sv.drm_di_minor);
+
+ if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
+ err = 0;
+ else
+ err = drmSetBusid(tmp.drmFD, busID);
+
+ if (err) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
+ goto out_err;
+ }
+
+ /*
+ * Create a lock-containing sarea.
+ */
+
+ if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
+ DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
+ tmp.hLSAREA = 0;
+ goto out_err;
+ }
+
+ if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
+ (drmAddressPtr)(&tmp.pLSAREA)) < 0) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
+ tmp.pLSAREA = NULL;
+ goto out_err;
+ }
+
+ memset(tmp.pLSAREA, 0, sAreaSize);
+
+ /*
+ * Reserved contexts are handled by the first opened screen.
+ */
+
+ tmp.resOwner = NULL;
+
+ if (!pDRIEntPriv)
+ pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
+
+ if (!pDRIEntPriv) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
+ "DRM device.\n");
+ goto out_err;
+ }
+ *pDRIEntPriv = tmp;
+ xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
+ pDRIEntPriv;
+
+ DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
+ return TRUE;
+
+ out_err:
+
+ DRIOpenDRMCleanup(&tmp);
+ return FALSE;
+}
+
+
Bool
DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
{
DRIScreenPrivPtr pDRIPriv;
drm_context_t * reserved;
int reserved_count;
- int i, fd, drmWasAvailable;
+ int i;
Bool xineramaInCore = FALSE;
- int err = 0;
- char *openbusid;
- drmVersionPtr drmlibv;
- int drmlibmajor, drmlibminor, drmdimajor, drmdiminor;
+ DRIEntPrivPtr pDRIEntPriv;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
if (DRIGeneration != serverGeneration) {
if ((DRIScreenPrivIndex = AllocateScreenPrivateIndex()) < 0)
@@ -154,47 +341,12 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
}
}
- drmWasAvailable = drmAvailable();
-
- /* Check the DRM lib version.
- * drmGetLibVersion was not supported in version 1.0, so check for
- * symbol first to avoid possible crash or hang.
- */
- drmlibmajor = 1;
- drmlibminor = 0;
- if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
- drmlibv = drmGetLibVersion(-1);
- if (drmlibv != NULL) {
- drmlibmajor = drmlibv->version_major;
- drmlibminor = drmlibv->version_minor;
- drmFreeVersion(drmlibv);
- }
- }
-
- /* Check if the libdrm can handle falling back to loading based on name
- * if a busid string is passed.
- */
- if (drmlibmajor == 1 && drmlibminor >= 2)
- openbusid = pDRIInfo->busIdString;
- else
- openbusid = NULL;
+ if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
+ pDRIInfo->busIdString,
+ pDRIInfo->drmDriverName))
+ return FALSE;
- /* Note that drmOpen will try to load the kernel module, if needed. */
- fd = drmOpen(pDRIInfo->drmDriverName, openbusid);
- if (fd < 0) {
- /* failed to open DRM */
- pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmOpen failed\n");
- return FALSE;
- }
-
- if (!drmWasAvailable) {
- /* drmOpen loaded the kernel module, print a message to say so */
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] loaded kernel module for \"%s\" driver\n",
- pDRIInfo->drmDriverName);
- }
+ pDRIEntPriv = DRI_ENT_PRIV(pScrn);
pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
if (!pDRIPriv) {
@@ -203,7 +355,7 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
}
pScreen->devPrivates[DRIScreenPrivIndex].ptr = (pointer) pDRIPriv;
- pDRIPriv->drmFD = fd;
+ pDRIPriv->drmFD = pDRIEntPriv->drmFD;
pDRIPriv->directRenderingSupport = TRUE;
pDRIPriv->pDriverInfo = pDRIInfo;
pDRIPriv->nrWindows = 0;
@@ -215,89 +367,54 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
pDRIPriv->grabbedDRILock = FALSE;
pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
-
- if (drmlibmajor == 1 && drmlibminor >= 2) {
- drmSetVersion sv;
-
- /* Get the interface version, asking for 1.1. */
- sv.drm_di_major = 1;
- sv.drm_di_minor = 1;
- sv.drm_dd_major = -1;
- err = drmSetInterfaceVersion(pDRIPriv->drmFD, &sv);
- if (err == 0) {
- drmdimajor = sv.drm_di_major;
- drmdiminor = sv.drm_di_minor;
- } else {
- /* failure, so set it to 1.0.0. */
- drmdimajor = 1;
- drmdiminor = 0;
- }
- }
- else {
- /* We can't check the DI DRM interface version, so set it to 1.0.0. */
- drmdimajor = 1;
- drmdiminor = 0;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] DRM interface version %d.%d\n", drmdimajor, drmdiminor);
-
- /* If the interface minor number is 1.1, then we've opened a DRM device
- * that already had the busid set through drmOpen.
- */
- if (drmdimajor == 1 && drmdiminor >= 1)
- err = 0;
- else
- err = drmSetBusid(pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString);
-
- if (err < 0) {
- pDRIPriv->directRenderingSupport = FALSE;
- pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmSetBusid failed (%d, %s), %s\n",
- pDRIPriv->drmFD, pDRIPriv->pDriverInfo->busIdString, strerror(-err));
- return FALSE;
- }
-
*pDRMFD = pDRIPriv->drmFD;
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] created \"%s\" driver at busid \"%s\"\n",
- pDRIPriv->pDriverInfo->drmDriverName,
- pDRIPriv->pDriverInfo->busIdString);
- if (drmAddMap( pDRIPriv->drmFD,
- 0,
- pDRIPriv->pDriverInfo->SAREASize,
- DRM_SHM,
- DRM_CONTAINS_LOCK,
- &pDRIPriv->hSAREA) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmAddMap failed\n");
- return FALSE;
+ if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
+
+ if (drmAddMap( pDRIPriv->drmFD,
+ 0,
+ pDRIPriv->pDriverInfo->SAREASize,
+ DRM_SHM,
+ 0,
+ &pDRIPriv->hSAREA) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmAddMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] added %d byte SAREA at %p\n",
+ pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
+
+ /* Backwards compat. */
+ if (drmMap( pDRIPriv->drmFD,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pDriverInfo->SAREASize,
+ (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
+ pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+ memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
+ "SAREA also for drawables.\n");
+ pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
+ pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
+ pDRIEntPriv->sAreaGrabbed = TRUE;
}
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] added %d byte SAREA at %p\n",
- pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
- if (drmMap( pDRIPriv->drmFD,
- pDRIPriv->hSAREA,
- pDRIPriv->pDriverInfo->SAREASize,
- (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmMap failed\n");
- return FALSE;
- }
- memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
- pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+ pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
+ pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
if (drmAddMap( pDRIPriv->drmFD,
(drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
@@ -317,22 +434,26 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
pDRIPriv->hFrameBuffer);
- /* Add tags for reserved contexts */
- if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
- &reserved_count))) {
- int i;
- void *tag;
-
- for (i = 0; i < reserved_count; i++) {
- tag = DRICreateContextPrivFromHandle(pScreen,
- reserved[i],
- DRI_CONTEXT_RESERVED);
- drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+ if (pDRIEntPriv->resOwner == NULL) {
+ pDRIEntPriv->resOwner = pScreen;
+
+ /* Add tags for reserved contexts */
+ if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+ &reserved_count))) {
+ int i;
+ void *tag;
+
+ for (i = 0; i < reserved_count; i++) {
+ tag = DRICreateContextPrivFromHandle(pScreen,
+ reserved[i],
+ DRI_CONTEXT_RESERVED);
+ drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+ }
+ drmFreeReservedContextList(reserved);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] added %d reserved context%s for kernel\n",
+ reserved_count, reserved_count > 1 ? "s" : "");
}
- drmFreeReservedContextList(reserved);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] added %d reserved context%s for kernel\n",
- reserved_count, reserved_count > 1 ? "s" : "");
}
/* validate max drawable table entry set by driver */
@@ -350,6 +471,14 @@ DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
pDRIPriv->pSAREA->drawableTable[i].flags = 0;
}
+ pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
+ pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
+
+ if (!pDRIEntPriv->keepFDOpen)
+ pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
+
+ pDRIEntPriv->refCount++;
+
return TRUE;
}
@@ -491,6 +620,9 @@ DRICloseScreen(ScreenPtr pScreen)
DRIInfoPtr pDRIInfo;
drm_context_t * reserved;
int reserved_count;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+ Bool closeMaster;
if (pDRIPriv && pDRIPriv->directRenderingSupport) {
@@ -543,38 +675,55 @@ DRICloseScreen(ScreenPtr pScreen)
}
/* Remove tags for reserved contexts */
- if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+ if (pDRIEntPriv->resOwner == pScreen) {
+ pDRIEntPriv->resOwner = NULL;
+
+ if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
&reserved_count))) {
- int i;
+ int i;
- for (i = 0; i < reserved_count; i++) {
- DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
- reserved[i]));
+ for (i = 0; i < reserved_count; i++) {
+ DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
+ reserved[i]));
+ }
+ drmFreeReservedContextList(reserved);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] removed %d reserved context%s for kernel\n",
+ reserved_count, reserved_count > 1 ? "s" : "");
}
- drmFreeReservedContextList(reserved);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] removed %d reserved context%s for kernel\n",
- reserved_count, reserved_count > 1 ? "s" : "");
}
/* Make sure signals get unblocked etc. */
drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
- pDRIPriv->lockRefCount = 0;
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] unmapping %d bytes of SAREA %p at %p\n",
- pDRIInfo->SAREASize,
- pDRIPriv->hSAREA,
- pDRIPriv->pSAREA);
- if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] unable to unmap %d bytes"
- " of SAREA %p at %p\n",
+ pDRIPriv->pLockRefCount = NULL;
+ closeMaster = (--pDRIEntPriv->refCount == 0) &&
+ !pDRIEntPriv->keepFDOpen;
+ if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] unmapping %d bytes of SAREA %p at %p\n",
pDRIInfo->SAREASize,
pDRIPriv->hSAREA,
pDRIPriv->pSAREA);
+ if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] unable to unmap %d bytes"
+ " of SAREA %p at %p\n",
+ pDRIInfo->SAREASize,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pSAREA);
+ }
+ } else {
+ pDRIEntPriv->sAreaGrabbed = FALSE;
}
- drmClose(pDRIPriv->drmFD);
+ if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
+ drmClose(pDRIPriv->drmFD);
+ if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Closed DRM master.\n");
+ pDRIEntPriv->drmFD = -1;
+ }
+ }
xfree(pDRIPriv);
pScreen->devPrivates[DRIScreenPrivIndex].ptr = NULL;
@@ -2002,28 +2151,46 @@ void
DRILock(ScreenPtr pScreen, int flags)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- if(!pDRIPriv) return;
- if (!pDRIPriv->lockRefCount)
- DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext, flags);
- pDRIPriv->lockRefCount++;
+ if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+ if (!*pDRIPriv->pLockRefCount) {
+ DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
+ *pDRIPriv->pLockingContext = pDRIPriv->myContext;
+ } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Locking deadlock.\n"
+ "\tAlready locked with context %d,\n"
+ "\ttrying to lock with context %d.\n",
+ pDRIPriv->pLockingContext,
+ pDRIPriv->myContext);
+ }
+ (*pDRIPriv->pLockRefCount)++;
}
void
DRIUnlock(ScreenPtr pScreen)
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- if(!pDRIPriv) return;
- if (pDRIPriv->lockRefCount > 0) {
- pDRIPriv->lockRefCount--;
- }
- else {
- ErrorF("DRIUnlock called when not locked\n");
+ if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+ if (*pDRIPriv->pLockRefCount > 0) {
+ if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Unlocking inconsistency:\n"
+ "\tContext %d trying to unlock lock held by context %d\n",
+ pDRIPriv->pLockingContext,
+ pDRIPriv->myContext);
+ }
+ (*pDRIPriv->pLockRefCount)--;
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "DRIUnlock called when not locked.\n");
return;
}
- if (!pDRIPriv->lockRefCount)
- DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pSAREA, pDRIPriv->myContext);
+ if (! *pDRIPriv->pLockRefCount)
+ DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
}
void *
diff --git a/hw/xfree86/dri/dri.h b/hw/xfree86/dri/dri.h
index f65c57160..a21338a90 100644
--- a/hw/xfree86/dri/dri.h
+++ b/hw/xfree86/dri/dri.h
@@ -107,7 +107,7 @@ typedef struct {
*/
#define DRIINFO_MAJOR_VERSION 5
-#define DRIINFO_MINOR_VERSION 1
+#define DRIINFO_MINOR_VERSION 2
#define DRIINFO_PATCH_VERSION 0
typedef struct {
@@ -176,9 +176,17 @@ typedef struct {
/* New with DRI version 5.1.0 */
void (*ClipNotify)(ScreenPtr pScreen, WindowPtr *ppWin, int num);
+
+ /* New with DRI version 5.2.0 */
+ Bool allocSarea;
+ Bool keepFDOpen;
} DRIInfoRec, *DRIInfoPtr;
+extern Bool DRIOpenDRMMaster(ScrnInfoPtr pScrn, unsigned long sAreaSize,
+ const char *busID,
+ const char *drmDriverName);
+
extern Bool DRIScreenInit(ScreenPtr pScreen,
DRIInfoPtr pDRIInfo,
int *pDRMFD);
@@ -344,6 +352,14 @@ extern char *DRICreatePCIBusID(pciVideoPtr PciInfo);
extern int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *));
extern int drmRemoveSIGIOHandler(int fd);
+extern int DRIMasterFD(ScrnInfoPtr pScrn);
+
+extern void *DRIMasterSareaPointer(ScrnInfoPtr pScrn);
+
+extern drm_handle_t DRIMasterSareaHandle(ScrnInfoPtr pScrn);
+
+
+
#define _DRI_H_
#endif
diff --git a/hw/xfree86/dri/dristruct.h b/hw/xfree86/dri/dristruct.h
index 9c42ff9cc..a3bac8556 100644
--- a/hw/xfree86/dri/dristruct.h
+++ b/hw/xfree86/dri/dristruct.h
@@ -73,6 +73,11 @@ struct _DRIContextPrivRec
#define DRI_SCREEN_PRIV_FROM_INDEX(screenIndex) ((DRIScreenPrivPtr) \
(screenInfo.screens[screenIndex]->devPrivates[DRIScreenPrivIndex].ptr))
+#define DRI_ENT_PRIV(pScrn) \
+ ((DRIEntPrivIndex < 0) ? \
+ NULL: \
+ ((DRIEntPrivPtr)(xf86GetEntityPrivate((pScrn)->entityList[0], \
+ DRIEntPrivIndex)->ptr)))
typedef struct _DRIScreenPrivRec
{
@@ -103,6 +108,25 @@ typedef struct _DRIScreenPrivRec
Bool wrapped;
Bool windowsTouched;
int lockRefCount;
+ drm_handle_t hLSAREA; /* Handle to SAREA containing lock, for mapping */
+ XF86DRILSAREAPtr pLSAREA; /* Mapped pointer to SAREA containing lock */
+ int* pLockRefCount;
+ int* pLockingContext;
} DRIScreenPrivRec, *DRIScreenPrivPtr;
+
+typedef struct _DRIEntPrivRec {
+ int drmFD;
+ Bool drmOpened;
+ Bool sAreaGrabbed;
+ drm_handle_t hLSAREA;
+ XF86DRILSAREAPtr pLSAREA;
+ unsigned long sAreaSize;
+ int lockRefCount;
+ int lockingContext;
+ ScreenPtr resOwner;
+ Bool keepFDOpen;
+ int refCount;
+} DRIEntPrivRec, *DRIEntPrivPtr;
+
#endif /* DRI_STRUCT_H */
diff --git a/hw/xfree86/dri/sarea.h b/hw/xfree86/dri/sarea.h
index a0d6084f3..1528cc191 100644
--- a/hw/xfree86/dri/sarea.h
+++ b/hw/xfree86/dri/sarea.h
@@ -89,4 +89,9 @@ typedef struct _XF86DRISAREA {
drm_context_t dummy_context;
} XF86DRISAREARec, *XF86DRISAREAPtr;
+typedef struct _XF86DRILSAREA {
+ drmLock lock;
+ drmLock otherLocks[31];
+} XF86DRILSAREARec, *XF86DRILSAREAPtr;
+
#endif
diff --git a/hw/xfree86/loader/loadmod.c b/hw/xfree86/loader/loadmod.c
index db12da466..6a1c65e4a 100644
--- a/hw/xfree86/loader/loadmod.c
+++ b/hw/xfree86/loader/loadmod.c
@@ -869,7 +869,7 @@ doLoadModule(const char *module, const char *path, const char **subdirlist,
for (cim = compiled_in_modules; *cim; cim++)
if (!strcmp (module, *cim))
{
- xf86MsgVerb(X_INFO, 3, "Module already built-in\n");
+ xf86MsgVerb(X_INFO, 0, "Module already built-in\n");
return (ModuleDescPtr) 1;
}
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 7e7c7e7ec..00ec56c00 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -414,22 +414,51 @@ xf86OutputSetMonitor (xf86OutputPtr output)
xfree (option_name);
output->conf_monitor = xf86findMonitor (monitor,
xf86configptr->conf_monitor_lst);
+ /*
+ * Find the monitor section of the screen and use that
+ */
+ if (!output->conf_monitor && output->use_screen_monitor)
+ output->conf_monitor = xf86findMonitor (output->scrn->monitor->id,
+ xf86configptr->conf_monitor_lst);
if (output->conf_monitor)
+ {
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s using monitor section %s\n",
+ output->name, output->conf_monitor->mon_identifier);
xf86ProcessOptions (output->scrn->scrnIndex,
output->conf_monitor->mon_option_lst,
output->options);
+ }
+ else
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s has no monitor section\n",
+ output->name);
}
static Bool
-xf86OutputEnabled (xf86OutputPtr output)
+xf86OutputEnabled (xf86OutputPtr output)
{
- /* Check to see if this output was disabled in the config file */
- if (xf86ReturnOptValBool (output->options, OPTION_ENABLE, TRUE) == FALSE ||
- xf86ReturnOptValBool (output->options, OPTION_DISABLE, FALSE) == TRUE)
+ Bool enable, disable;
+
+ /* check to see if this output was enabled in the config file */
+ if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable)
{
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s enabled by config file\n", output->name);
+ return TRUE;
+ }
+ /* or if this output was disabled in the config file */
+ if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable)
+ {
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s disabled by config file\n", output->name);
return FALSE;
}
- return TRUE;
+ /* otherwise, enable if it is not disconnected */
+ enable = output->status != XF86OutputStatusDisconnected;
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s %sconnected\n", output->name, enable ? "" : "dis");
+ return enable;
}
static Bool
@@ -463,7 +492,7 @@ xf86OutputInitialRotation (xf86OutputPtr output)
xf86OutputPtr
xf86OutputCreate (ScrnInfoPtr scrn,
- const xf86OutputFuncsRec *funcs,
+ const xf86OutputFuncsRec *funcs,
const char *name)
{
xf86OutputPtr output, *outputs;
@@ -486,6 +515,10 @@ xf86OutputCreate (ScrnInfoPtr scrn,
strcpy (output->name, name);
}
output->subpixel_order = SubPixelUnknown;
+ /*
+ * Use the old per-screen monitor section for the first output
+ */
+ output->use_screen_monitor = (xf86_config->num_output == 0);
#ifdef RANDR_12_INTERFACE
output->randr_output = NULL;
#endif
@@ -537,6 +570,16 @@ xf86OutputRename (xf86OutputPtr output, const char *name)
}
void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor)
+{
+ if (use_screen_monitor != output->use_screen_monitor)
+ {
+ output->use_screen_monitor = use_screen_monitor;
+ xf86OutputSetMonitor (output);
+ }
+}
+
+void
xf86OutputDestroy (xf86OutputPtr output)
{
ScrnInfoPtr scrn = output->scrn;
@@ -1203,7 +1246,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
*/
output->status = (*output->funcs->detect)(output);
- if (output->status == XF86OutputStatusDisconnected)
+ if (!xf86OutputEnabled (output))
{
xf86OutputSetEDID (output, NULL);
continue;
@@ -1514,8 +1557,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
xf86OutputPtr output = config->output[o];
modes[o] = NULL;
- enabled[o] = (xf86OutputEnabled (output) &&
- output->status != XF86OutputStatusDisconnected);
+ enabled[o] = xf86OutputEnabled (output);
}
/*
@@ -1560,8 +1602,20 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
{
xf86OutputPtr output = config->output[o];
- if (enabled[o] && !modes[o])
- modes[o] = xf86ClosestMode (output, target_mode, target_rotation, width, height);
+ if (enabled[o])
+ {
+ if (!modes[o])
+ modes[o] = xf86ClosestMode (output, target_mode,
+ target_rotation, width, height);
+ if (!modes[o])
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Output %s enabled but has no modes\n",
+ output->name);
+ else
+ xf86DrvMsg (scrn->scrnIndex, X_INFO,
+ "Output %s using initial mode %s\n",
+ output->name, modes[o]->name);
+ }
}
/*
@@ -1849,7 +1903,9 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
}
}
xf86DisableUnusedFunctions(pScrn);
+#if RANDR_12_INTERFACE
xf86RandR12TellChanged (pScrn->pScreen);
+#endif
return ok;
}
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 030f6bf3a..0c019e0e6 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -479,6 +479,9 @@ struct _xf86Output {
/** driver private information */
void *driver_private;
+ /** Whether to use the old per-screen Monitor config section */
+ Bool use_screen_monitor;
+
#ifdef RANDR_12_INTERFACE
/**
* RandR 1.2 output structure.
@@ -618,9 +621,12 @@ xf86CrtcInUse (xf86CrtcPtr crtc);
* Output functions
*/
xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr scrn,
- const xf86OutputFuncsRec *funcs,
- const char *name);
+xf86OutputCreate (ScrnInfoPtr scrn,
+ const xf86OutputFuncsRec *funcs,
+ const char *name);
+
+void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor);
Bool
xf86OutputRename (xf86OutputPtr output, const char *name);
diff --git a/hw/xfree86/modes/xf86EdidModes.c b/hw/xfree86/modes/xf86EdidModes.c
index 7a8ec1935..46cb6c41e 100644
--- a/hw/xfree86/modes/xf86EdidModes.c
+++ b/hw/xfree86/modes/xf86EdidModes.c
@@ -82,6 +82,16 @@ static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
DDC->vendor.prod_id == 1516)
return TRUE;
+ /* Acer AL1706 */
+ if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
+ DDC->vendor.prod_id == 44358)
+ return TRUE;
+
+ /* Samsung SyncMaster 226BW */
+ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+ DDC->vendor.prod_id == 638)
+ return TRUE;
+
return FALSE;
}
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index d0e1dfd24..e1593d9c0 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -338,6 +338,7 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
WindowPtr pRoot = WindowTable[pScreen->myNum];
+ PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
Bool ret = FALSE;
if (randrp->virtualX == -1 || randrp->virtualY == -1)
@@ -354,8 +355,8 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
ret = TRUE;
- pScreen->width = width;
- pScreen->height = height;
+ pScreen->width = pScrnPix->drawable.width = width;
+ pScreen->height = pScrnPix->drawable.height = height;
pScreen->mmWidth = mmWidth;
pScreen->mmHeight = mmHeight;
diff --git a/hw/xfree86/modes/xf86RandR12.h b/hw/xfree86/modes/xf86RandR12.h
index 0d3346a77..4fd855cf5 100644
--- a/hw/xfree86/modes/xf86RandR12.h
+++ b/hw/xfree86/modes/xf86RandR12.h
@@ -24,6 +24,9 @@
#define _XF86_RANDR_H_
#include <randrstr.h>
#include <X11/extensions/render.h>
+#if XF86_MODES_RENAME
+#include "xf86Rename.h"
+#endif
Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
Bool xf86RandR12Init(ScreenPtr pScreen);
diff --git a/hw/xfree86/modes/xf86Rename.h b/hw/xfree86/modes/xf86Rename.h
index 9dcfef5da..b8c1d70ef 100644
--- a/hw/xfree86/modes/xf86Rename.h
+++ b/hw/xfree86/modes/xf86Rename.h
@@ -25,6 +25,12 @@
#include "local_xf86Rename.h"
+#define xf86_cursors_fini XF86NAME(xf86_cursors_fini)
+#define xf86_cursors_init XF86NAME(xf86_cursors_init)
+#define xf86_hide_cursors XF86NAME(xf86_hide_cursors)
+#define xf86_reload_cursors XF86NAME(xf86_reload_cursors)
+#define xf86_show_cursors XF86NAME(xf86_show_cursors)
+#define xf86ConnectorGetName XF86NAME(xf86ConnectorGetName)
#define xf86CrtcConfigInit XF86NAME(xf86CrtcConfigInit)
#define xf86CrtcConfigPrivateIndex XF86NAME(xf86CrtcConfigPrivateIndex)
#define xf86CrtcCreate XF86NAME(xf86CrtcCreate)
@@ -35,6 +41,7 @@
#define xf86CrtcSetMode XF86NAME(xf86CrtcSetMode)
#define xf86CrtcSetSizeRange XF86NAME(xf86CrtcSetSizeRange)
#define xf86CVTMode XF86NAME(xf86CVTMode)
+#define xf86DDCMonitorSet XF86NAME(xf86DDCMonitorSet)
#define xf86DisableUnusedFunctions XF86NAME(xf86DisableUnusedFunctions)
#define xf86DPMSSet XF86NAME(xf86DPMSSet)
#define xf86DuplicateMode XF86NAME(xf86DuplicateMode)
@@ -52,9 +59,11 @@
#define xf86OutputGetEDIDModes XF86NAME(xf86OutputGetEDIDModes)
#define xf86OutputRename XF86NAME(xf86OutputRename)
#define xf86OutputSetEDID XF86NAME(xf86OutputSetEDID)
+#define xf86OutputUseScreenMonitor XF86NAME(xf86OutputUseScreenMonitor)
#define xf86PrintModeline XF86NAME(xf86PrintModeline)
#define xf86ProbeOutputModes XF86NAME(xf86ProbeOutputModes)
#define xf86PruneInvalidModes XF86NAME(xf86PruneInvalidModes)
+#define xf86RotateCloseScreen XF86NAME(xf86RotateCloseScreen)
#define xf86SetModeCrtc XF86NAME(xf86SetModeCrtc)
#define xf86SetModeDefaultName XF86NAME(xf86SetModeDefaultName)
#define xf86SetScrnInfoModes XF86NAME(xf86SetScrnInfoModes)
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index e8fafd073..359501e38 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -278,13 +278,23 @@ xf86RotateRedisplay(ScreenPtr pScreen)
region = DamageRegion(damage);
if (REGION_NOTEMPTY(pScreen, region))
{
- int c;
-
+ int c;
+ SourceValidateProcPtr SourceValidate;
+
+ /*
+ * SourceValidate is used by the software cursor code
+ * to pull the cursor off of the screen when reading
+ * bits from the frame buffer. Bypassing this function
+ * leaves the software cursor in place
+ */
+ SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = NULL;
+
for (c = 0; c < xf86_config->num_crtc; c++)
{
xf86CrtcPtr crtc = xf86_config->crtc[c];
- if (crtc->rotation != RR_Rotate_0)
+ if (crtc->rotation != RR_Rotate_0 && crtc->enabled)
{
BoxRec box;
RegionRec crtc_damage;
@@ -304,6 +314,7 @@ xf86RotateRedisplay(ScreenPtr pScreen)
REGION_UNINIT (pScreen, &crtc_damage);
}
}
+ pScreen->SourceValidate = SourceValidate;
DamageEmpty(damage);
}
}
@@ -338,7 +349,8 @@ xf86RotateDestroy (xf86CrtcPtr crtc)
}
for (c = 0; c < xf86_config->num_crtc; c++)
- if (crtc->rotatedPixmap || crtc->rotatedData)
+ if (xf86_config->crtc[c]->rotatedPixmap ||
+ xf86_config->crtc[c]->rotatedData)
return;
/*
diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c
index b80371d83..bc5e11fb8 100644
--- a/hw/xfree86/os-support/bus/Pci.c
+++ b/hw/xfree86/os-support/bus/Pci.c
@@ -232,14 +232,14 @@ _X_EXPORT int pciNumBuses = 0; /* Actual number of PCI buses */
int pciMaxBusNum = MAX_PCI_BUSES;
static Bool inProbe = FALSE;
-static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, };
+static pciConfigPtr *pci_devp = NULL;
static int readPciBios( PCITAG Tag, CARD8* tmp, ADDRESS hostbase,
unsigned char * buf, int len, PciBiosType BiosType );
static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len);
-int xf86MaxPciDevs = MAX_PCI_DEVICES;
+int xf86MaxPciDevs = 0;
/*
* Platform specific PCI function pointers.
@@ -272,6 +272,14 @@ pciInit()
if (pciNumBuses <= 0)
ARCH_PCI_OS_INIT();
#endif
+ if (xf86MaxPciDevs == 0) {
+ xf86Msg(X_WARNING,
+ "OS did not count PCI devices, guessing wildly\n");
+ xf86MaxPciDevs = MAX_PCI_DEVICES;
+ }
+ if (pci_devp)
+ xfree(pci_devp);
+ pci_devp = xnfcalloc(xf86MaxPciDevs + 1, sizeof(pciConfigPtr));
}
void pciSetOSBIOSPtr(int (*bios_fn)(PCITAG Tag, int basereg, unsigned char * buf, int len))
@@ -920,7 +928,7 @@ xf86scanpci(int flags)
* result in an endless recursion if platform/OS specific PCI
* bus probing code calls this function from with in it.
*/
- if (done || pci_devp[0])
+ if (done || pci_devp)
return pci_devp;
done = TRUE;
diff --git a/mi/Makefile.am b/mi/Makefile.am
index 42f75ae73..f262f4bff 100644
--- a/mi/Makefile.am
+++ b/mi/Makefile.am
@@ -1,4 +1,4 @@
-noinst_LTLIBRARIES = libminimi.la libmi.la
+noinst_LTLIBRARIES = libmi.la
if XORG
sdk_HEADERS = mibank.h micmap.h miline.h mipointer.h mi.h mibstore.h \
@@ -8,8 +8,7 @@ endif
AM_CFLAGS = $(DIX_CFLAGS)
-# libminimi is for dmx - it has different defines for miinitext.c
-libminimi_la_SOURCES = \
+libmi_la_SOURCES = \
cbrt.c \
mi.h \
miarc.c \
@@ -70,6 +69,4 @@ libminimi_la_SOURCES = \
mizerclip.c \
mizerline.c
-libmi_la_SOURCES = $(libminimi_la_SOURCES)
-
INCLUDES = -I$(top_srcdir)/mfb
diff --git a/miext/cw/cw_ops.c b/miext/cw/cw_ops.c
index 80b72806c..82ec99999 100644
--- a/miext/cw/cw_ops.c
+++ b/miext/cw/cw_ops.c
@@ -30,6 +30,7 @@
#include "gcstruct.h"
#include "pixmapstr.h"
#include "cw.h"
+#include "mi.h"
#define SETUP_BACKING_DST(_pDst, _pGC) \
cwGCPtr pGCPrivate = getCwGC (_pGC); \
@@ -185,7 +186,7 @@ cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
int w, int h, int dstx, int dsty)
{
int odstx, odsty;
- RegionPtr exposed = NULL;
+ int osrcx, osrcy;
SETUP_BACKING_DST(pDst, pGC);
SETUP_BACKING_SRC(pSrc, pGC);
@@ -193,19 +194,20 @@ cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
odstx = dstx;
odsty = dsty;
+ osrcx = srcx;
+ osrcy = srcy;
CW_OFFSET_XY_DST(dstx, dsty);
CW_OFFSET_XY_SRC(srcx, srcy);
- exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
- pBackingGC, srcx, srcy, w, h,
- dstx, dsty);
-
- if (exposed != NULL)
- REGION_TRANSLATE(pDst->pScreen, exposed, odstx - dstx, odsty - dsty);
-
+ (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
+ pBackingGC, srcx, srcy, w, h,
+ dstx, dsty);
+
EPILOGUE(pGC);
- return exposed;
+ return miHandleExposures(pSrc, pDst, pGC,
+ osrcx, osrcy, w, h,
+ odstx, odsty, 0);
}
static RegionPtr
@@ -213,7 +215,7 @@ cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
int w, int h, int dstx, int dsty, unsigned long plane)
{
int odstx, odsty;
- RegionPtr exposed = NULL;
+ int osrcx, osrcy;
SETUP_BACKING_DST(pDst, pGC);
SETUP_BACKING_SRC(pSrc, pGC);
@@ -221,19 +223,20 @@ cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
odstx = dstx;
odsty = dsty;
+ osrcx = srcx;
+ osrcy = srcy;
CW_OFFSET_XY_DST(dstx, dsty);
CW_OFFSET_XY_SRC(srcx, srcy);
- exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
- pBackingGC, srcx, srcy, w, h,
- dstx, dsty, plane);
-
- if (exposed != NULL)
- REGION_TRANSLATE(pDst->pScreen, exposed, odstx - dstx, odsty - dsty);
+ (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
+ pBackingGC, srcx, srcy, w, h,
+ dstx, dsty, plane);
EPILOGUE(pGC);
- return exposed;
+ return miHandleExposures(pSrc, pDst, pGC,
+ osrcx, osrcy, w, h,
+ odstx, odsty, plane);
}
static void
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 1dfc3bbb0..c8c2be264 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -518,6 +518,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
RROutput *outputs;
RROutput *possible;
int i, j, k, n;
+ int width, height;
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
crtc = LookupCrtc(client, stuff->crtc, DixReadAccess);
@@ -540,8 +541,9 @@ ProcRRGetCrtcInfo (ClientPtr client)
rep.timestamp = pScrPriv->lastSetTime.milliseconds;
rep.x = crtc->x;
rep.y = crtc->y;
- rep.width = mode ? mode->mode.width : 0;
- rep.height = mode ? mode->mode.height : 0;
+ RRCrtcGetScanoutSize (crtc, &width, &height);
+ rep.width = width;
+ rep.height = height;
rep.mode = mode ? mode->mode.id : 0;
rep.rotation = crtc->rotation;
rep.rotations = crtc->rotations;
diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
index 1db27f14c..2a57e4e32 100644
--- a/randr/rrxinerama.c
+++ b/randr/rrxinerama.c
@@ -428,6 +428,14 @@ RRXineramaExtensionInit(void)
return;
#endif
+ /*
+ * Xinerama isn't capable enough to have multiple protocol screens each
+ * with their own output geometry. So if there's more than one protocol
+ * screen, just don't even try.
+ */
+ if (screenInfo.numScreens > 1)
+ return;
+
(void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
ProcRRXineramaDispatch,
SProcRRXineramaDispatch,
diff --git a/render/picture.c b/render/picture.c
index c30649c6b..2022175b6 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -890,54 +890,22 @@ static unsigned int INTERPOLATE_PIXEL_256(unsigned int x, unsigned int a,
return x;
}
-static void initGradientColorTable(SourcePictPtr pGradient, int *error)
+CARD32
+PictureGradientColor (PictGradientStopPtr stop1,
+ PictGradientStopPtr stop2,
+ CARD32 x)
{
- int begin_pos, end_pos;
- xFixed incr, dpos;
- int pos, current_stop;
- PictGradientStopPtr stops = pGradient->linear.stops;
- int nstops = pGradient->linear.nstops;
-
- /* The position where the gradient begins and ends */
- begin_pos = (stops[0].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
- end_pos = (stops[nstops - 1].x * PICT_GRADIENT_STOPTABLE_SIZE) >> 16;
-
- pos = 0; /* The position in the color table. */
-
- /* Up to first point */
- while (pos <= begin_pos) {
- pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[0].color);
- ++pos;
- }
-
- incr = (1<<16)/ PICT_GRADIENT_STOPTABLE_SIZE; /* the double increment. */
- dpos = incr * pos; /* The position in terms of 0-1. */
-
- current_stop = 0; /* We always interpolate between current and current + 1. */
-
- /* Gradient area */
- while (pos < end_pos) {
- unsigned int current_color = xRenderColorToCard32(stops[current_stop].color);
- unsigned int next_color = xRenderColorToCard32(stops[current_stop + 1].color);
+ CARD32 current_color, next_color;
+ int dist, idist;
- int dist = (int)(256*(dpos - stops[current_stop].x)
- / (stops[current_stop+1].x - stops[current_stop].x));
- int idist = 256 - dist;
+ current_color = xRenderColorToCard32 (stop1->color);
+ next_color = xRenderColorToCard32 (stop2->color);
- pGradient->linear.colorTable[pos] = premultiply(INTERPOLATE_PIXEL_256(current_color, idist, next_color, dist));
+ dist = (int) (256 * (x - stop1->x) / (stop2->x - stop1->x));
+ idist = 256 - dist;
- ++pos;
- dpos += incr;
-
- if (dpos > stops[current_stop + 1].x)
- ++current_stop;
- }
-
- /* After last point */
- while (pos < PICT_GRADIENT_STOPTABLE_SIZE) {
- pGradient->linear.colorTable[pos] = xRenderColorToCard32(stops[nstops - 1].color);
- ++pos;
- }
+ return premultiply (INTERPOLATE_PIXEL_256 (current_color, idist,
+ next_color, dist));
}
static void initGradient(SourcePictPtr pGradient, int stopCount,
@@ -953,26 +921,30 @@ static void initGradient(SourcePictPtr pGradient, int stopCount,
dpos = -1;
for (i = 0; i < stopCount; ++i) {
- if (stopPoints[i] <= dpos || stopPoints[i] > (1<<16)) {
+ if (stopPoints[i] < dpos || stopPoints[i] > (1<<16)) {
*error = BadValue;
return;
}
dpos = stopPoints[i];
}
- pGradient->linear.stops = xalloc(stopCount*sizeof(PictGradientStop));
- if (!pGradient->linear.stops) {
+ pGradient->gradient.stops = xalloc(stopCount*sizeof(PictGradientStop));
+ if (!pGradient->gradient.stops) {
*error = BadAlloc;
return;
}
- pGradient->linear.nstops = stopCount;
+ pGradient->gradient.nstops = stopCount;
for (i = 0; i < stopCount; ++i) {
- pGradient->linear.stops[i].x = stopPoints[i];
- pGradient->linear.stops[i].color = stopColors[i];
+ pGradient->gradient.stops[i].x = stopPoints[i];
+ pGradient->gradient.stops[i].color = stopColors[i];
}
- initGradientColorTable(pGradient, error);
+
+ pGradient->gradient.class = SourcePictClassUnknown;
+ pGradient->gradient.stopRange = 0xffff;
+ pGradient->gradient.colorTable = NULL;
+ pGradient->gradient.colorTableSize = 0;
}
static PicturePtr createSourcePicture(void)
@@ -980,9 +952,9 @@ static PicturePtr createSourcePicture(void)
PicturePtr pPicture;
pPicture = (PicturePtr) xalloc(sizeof(PictureRec));
pPicture->pDrawable = 0;
- pPicture->format = PICT_a8r8g8b8;
pPicture->pFormat = 0;
pPicture->pNext = 0;
+ pPicture->format = PICT_a8r8g8b8;
pPicture->devPrivates = 0;
SetPictureToDefaults(pPicture);
@@ -1027,10 +999,6 @@ CreateLinearGradientPicture (Picture pid, xPointFixed *p1, xPointFixed *p2,
*error = BadAlloc;
return 0;
}
- if (p1->x == p2->x && p1->y == p2->y) {
- *error = BadValue;
- return 0;
- }
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictLinearGradient));
@@ -1072,14 +1040,6 @@ CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer
*error = BadAlloc;
return 0;
}
- {
- double dx = (double)(inner->x - outer->x);
- double dy = (double)(inner->y - outer->y);
- if (sqrt(dx*dx + dy*dy) + (double)(innerRadius) > (double)(outerRadius)) {
- *error = BadValue;
- return 0;
- }
- }
pPicture->id = pid;
pPicture->pSourcePict = (SourcePictPtr) xalloc(sizeof(PictRadialGradient));
@@ -1091,22 +1051,19 @@ CreateRadialGradientPicture (Picture pid, xPointFixed *inner, xPointFixed *outer
radial = &pPicture->pSourcePict->radial;
radial->type = SourcePictTypeRadial;
- {
- double x = (double)innerRadius / (double)outerRadius;
- radial->dx = (outer->x - inner->x);
- radial->dy = (outer->y - inner->y);
- radial->fx = (inner->x) - x*radial->dx;
- radial->fy = (inner->y) - x*radial->dy;
- radial->m = 1./(1+x);
- radial->b = -x*radial->m;
- radial->dx /= 65536.;
- radial->dy /= 65536.;
- radial->fx /= 65536.;
- radial->fy /= 65536.;
- x = outerRadius/65536.;
- radial->a = x*x - radial->dx*radial->dx - radial->dy*radial->dy;
- }
-
+ radial->c1.x = inner->x;
+ radial->c1.y = inner->y;
+ radial->c1.radius = innerRadius;
+ radial->c2.x = outer->x;
+ radial->c2.y = outer->y;
+ radial->c2.radius = outerRadius;
+ radial->cdx = (radial->c2.x - radial->c1.x) / 65536.;
+ radial->cdy = (radial->c2.y - radial->c1.y) / 65536.;
+ radial->dr = (radial->c2.radius - radial->c1.radius) / 65536.;
+ radial->A = ( radial->cdx * radial->cdx
+ + radial->cdy * radial->cdy
+ - radial->dr * radial->dr);
+
initGradient(pPicture->pSourcePict, nStops, stops, colors, error);
if (*error) {
xfree(pPicture);
@@ -1627,13 +1584,17 @@ FreePicture (pointer value,
{
if (pPicture->transform)
xfree (pPicture->transform);
- if (!pPicture->pDrawable) {
- if (pPicture->pSourcePict) {
- if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
- xfree(pPicture->pSourcePict->linear.stops);
- xfree(pPicture->pSourcePict);
- }
- } else {
+
+ if (pPicture->pSourcePict)
+ {
+ if (pPicture->pSourcePict->type != SourcePictTypeSolidFill)
+ xfree(pPicture->pSourcePict->linear.stops);
+
+ xfree(pPicture->pSourcePict);
+ }
+
+ if (pPicture->pDrawable)
+ {
ScreenPtr pScreen = pPicture->pDrawable->pScreen;
PictureScreenPtr ps = GetPictureScreen(pScreen);
diff --git a/render/picturestr.h b/render/picturestr.h
index f1617f627..62687681d 100644
--- a/render/picturestr.h
+++ b/render/picturestr.h
@@ -68,8 +68,13 @@ typedef struct _PictTransform {
#define SourcePictTypeRadial 2
#define SourcePictTypeConical 3
+#define SourcePictClassUnknown 0
+#define SourcePictClassHorizontal 1
+#define SourcePictClassVertical 2
+
typedef struct _PictSolidFill {
unsigned int type;
+ unsigned int class;
CARD32 color;
} PictSolidFill, *PictSolidFillPtr;
@@ -80,39 +85,56 @@ typedef struct _PictGradientStop {
typedef struct _PictGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
} PictGradient, *PictGradientPtr;
typedef struct _PictLinearGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
xPointFixed p1;
xPointFixed p2;
} PictLinearGradient, *PictLinearGradientPtr;
+typedef struct _PictCircle {
+ xFixed x;
+ xFixed y;
+ xFixed radius;
+} PictCircle, *PictCirclePtr;
+
typedef struct _PictRadialGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
- double fx;
- double fy;
- double dx;
- double dy;
- double a;
- double m;
- double b;
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
+ PictCircle c1;
+ PictCircle c2;
+ double cdx;
+ double cdy;
+ double dr;
+ double A;
} PictRadialGradient, *PictRadialGradientPtr;
typedef struct _PictConicalGradient {
unsigned int type;
+ unsigned int class;
int nstops;
PictGradientStopPtr stops;
- CARD32 colorTable[PICT_GRADIENT_STOPTABLE_SIZE];
+ int stopRange;
+ CARD32 *colorTable;
+ int colorTableSize;
xPointFixed center;
xFixed angle;
} PictConicalGradient, *PictConicalGradientPtr;
@@ -624,6 +646,11 @@ Bool
PictureTransformPoint3d (PictTransformPtr transform,
PictVectorPtr vector);
+CARD32
+PictureGradientColor (PictGradientStopPtr stop1,
+ PictGradientStopPtr stop2,
+ CARD32 x);
+
void RenderExtensionInit (void);
Bool