Merge branch 'master' of git+ssh://brianp@git.freedesktop.org/git/xorg/xserver

This commit is contained in:
Brian 2007-04-30 10:26:19 -06:00
commit 6b33459bf5
41 changed files with 2311 additions and 1059 deletions

View File

@ -258,12 +258,14 @@ __glXMesaScreenDestroy(__GLXscreen *screen)
__GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen; __GLXMESAscreen *mesaScreen = (__GLXMESAscreen *) screen;
int i; int i;
if (mesaScreen->xm_vis) {
for (i = 0; i < mesaScreen->num_vis; i++) { for (i = 0; i < mesaScreen->num_vis; i++) {
if (mesaScreen->xm_vis[i]) if (mesaScreen->xm_vis[i])
XMesaDestroyVisual(mesaScreen->xm_vis[i]); XMesaDestroyVisual(mesaScreen->xm_vis[i]);
} }
xfree(mesaScreen->xm_vis); xfree(mesaScreen->xm_vis);
}
__glXScreenDestroy(screen); __glXScreenDestroy(screen);

View File

@ -628,7 +628,7 @@ XEXT_LIB='$(top_builddir)/Xext/libXext.la'
XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la' XEXTXORG_LIB='$(top_builddir)/Xext/libXextbuiltin.la'
dnl Core modules for most extensions, et al. 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" REQUIRED_LIBS="xfont xau fontenc"
if test "x$DBUS" = xauto; then if test "x$DBUS" = xauto; then

View File

@ -75,6 +75,7 @@ SOFTWARE.
#include "swaprep.h" #include "swaprep.h"
#include "dixevents.h" #include "dixevents.h"
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h> #include <X11/extensions/XIproto.h>
#include "exglobals.h" #include "exglobals.h"
#include "exevents.h" #include "exevents.h"
@ -157,6 +158,8 @@ EnableDevice(DeviceIntPtr dev)
{ {
DeviceIntPtr *prev; DeviceIntPtr *prev;
int ret; int ret;
DeviceIntRec dummyDev;
devicePresenceNotify ev;
for (prev = &inputInfo.off_devices; for (prev = &inputInfo.off_devices;
*prev && (*prev != dev); *prev && (*prev != dev);
@ -175,6 +178,14 @@ EnableDevice(DeviceIntPtr dev)
*prev = dev; *prev = dev;
dev->next = NULL; 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; return TRUE;
} }
@ -182,6 +193,8 @@ Bool
DisableDevice(DeviceIntPtr dev) DisableDevice(DeviceIntPtr dev)
{ {
DeviceIntPtr *prev; DeviceIntPtr *prev;
DeviceIntRec dummyDev;
devicePresenceNotify ev;
for (prev = &inputInfo.devices; for (prev = &inputInfo.devices;
*prev && (*prev != dev); *prev && (*prev != dev);
@ -194,6 +207,15 @@ DisableDevice(DeviceIntPtr dev)
*prev = dev->next; *prev = dev->next;
dev->next = inputInfo.off_devices; dev->next = inputInfo.off_devices;
inputInfo.off_devices = dev; 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; return TRUE;
} }
@ -212,8 +234,8 @@ ActivateDevice(DeviceIntPtr dev)
ev.type = DevicePresenceNotify; ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds; ev.time = currentTime.milliseconds;
ev.devchange = 0; ev.devchange = DeviceAdded;
ev.deviceid = 0; ev.deviceid = dev->id;
dummyDev.id = 0; dummyDev.id = 0;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1); (xEvent *) &ev, 1);
@ -547,12 +569,16 @@ RemoveDevice(DeviceIntPtr dev)
int ret = BadMatch; int ret = BadMatch;
devicePresenceNotify ev; devicePresenceNotify ev;
DeviceIntRec dummyDev; DeviceIntRec dummyDev;
int deviceid;
DebugF("(dix) removing device %d\n", dev->id); DebugF("(dix) removing device %d\n", dev->id);
if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer) if (!dev || dev == inputInfo.keyboard || dev == inputInfo.pointer)
return BadImplementation; return BadImplementation;
deviceid = dev->id;
DisableDevice(dev);
prev = NULL; prev = NULL;
for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) { for (tmp = inputInfo.devices; tmp; (prev = tmp), (tmp = next)) {
next = tmp->next; next = tmp->next;
@ -587,8 +613,8 @@ RemoveDevice(DeviceIntPtr dev)
inputInfo.numDevices--; inputInfo.numDevices--;
ev.type = DevicePresenceNotify; ev.type = DevicePresenceNotify;
ev.time = currentTime.milliseconds; ev.time = currentTime.milliseconds;
ev.devchange = 0; ev.devchange = DeviceRemoved;
ev.deviceid = 0; ev.deviceid = deviceid;
dummyDev.id = 0; dummyDev.id = 0;
SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask, SendEventToAllWindows(&dummyDev, DevicePresenceNotifyMask,
(xEvent *) &ev, 1); (xEvent *) &ev, 1);

View File

@ -126,7 +126,7 @@ exaGetDrawablePixmap(DrawablePtr pDrawable)
* the backing drawable. These coordinates are nonzero only for redirected * the backing drawable. These coordinates are nonzero only for redirected
* windows. * windows.
*/ */
static void void
exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap, exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
int *xp, int *yp) int *xp, int *yp)
{ {
@ -172,29 +172,6 @@ exaPixmapDirty (PixmapPtr pPix, int x1, int y1, int x2, int y2)
REGION_UNINIT(pScreen, &region); REGION_UNINIT(pScreen, &region);
} }
/**
* exaDrawableDirty() marks a pixmap backing a drawable as dirty, allowing for
* optimizations in pixmap migration when no changes have occurred.
*/
void
exaDrawableDirty (DrawablePtr pDrawable, int x1, int y1, int x2, int y2)
{
PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);
int xoff, yoff;
x1 = max(x1, pDrawable->x);
y1 = max(y1, pDrawable->y);
x2 = min(x2, pDrawable->x + pDrawable->width);
y2 = min(y2, pDrawable->y + pDrawable->height);
if (x1 >= x2 || y1 >= y2)
return;
exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
}
static Bool static Bool
exaDestroyPixmap (PixmapPtr pPixmap) exaDestroyPixmap (PixmapPtr pPixmap)
{ {

View File

@ -74,6 +74,7 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
pGC->planemask, pGC->planemask,
pGC->fgPixel)) pGC->fgPixel))
{ {
exaDoMigration (pixmaps, 1, FALSE);
ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
return; return;
} }
@ -109,8 +110,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
(*pExaScr->info->Solid) (pPixmap, (*pExaScr->info->Solid) (pPixmap,
fullX1 + off_x, fullY1 + off_y, fullX1 + off_x, fullY1 + off_y,
fullX2 + off_x, fullY1 + 1 + off_y); fullX2 + off_x, fullY1 + 1 + off_y);
exaPixmapDirty (pPixmap, fullX1 + off_x, fullY1 + off_y,
fullX2 + off_x, fullY1 + 1 + off_y);
} }
else else
{ {
@ -129,8 +128,6 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
(*pExaScr->info->Solid) (pPixmap, (*pExaScr->info->Solid) (pPixmap,
partX1 + off_x, fullY1 + off_y, partX1 + off_x, fullY1 + off_y,
partX2 + off_x, fullY1 + 1 + off_y); partX2 + off_x, fullY1 + 1 + off_y);
exaPixmapDirty (pPixmap, partX1 + off_x, fullY1 + off_y,
partX2 + off_x, fullY1 + 1 + off_y);
} }
} }
pbox++; pbox++;
@ -154,8 +151,9 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
int xoff, yoff; int xoff, yoff;
int src_stride, bpp = pDrawable->bitsPerPixel; int src_stride, bpp = pDrawable->bitsPerPixel;
if (pExaScr->swappedOut || pExaScr->info->UploadToScreen == NULL) pixmaps[0].as_dst = TRUE;
goto migrate_and_fallback; pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
/* Don't bother with under 8bpp, XYPixmaps. */ /* Don't bother with under 8bpp, XYPixmaps. */
if (format != ZPixmap || bpp < 8) if (format != ZPixmap || bpp < 8)
@ -165,10 +163,14 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy) if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
goto migrate_and_fallback; goto migrate_and_fallback;
pixmaps[0].as_dst = TRUE; if (pExaScr->swappedOut)
pixmaps[0].as_src = FALSE; goto fallback;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, TRUE); exaDoMigration (pixmaps, 1, TRUE);
if (pExaScr->info->UploadToScreen == NULL)
goto fallback;
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL) if (pPix == NULL)
@ -221,25 +223,23 @@ exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)), fbBltStip((FbStip *)bits + (y1 - y) * (src_stride / sizeof(FbStip)),
src_stride / sizeof(FbStip), src_stride / sizeof(FbStip),
(x1 - x) * bpp, (x1 - x) * dstBpp,
dst + (y1 + yoff) * dst_stride, dst + (y1 + dstYoff) * dst_stride,
dst_stride, dst_stride,
(x1 + xoff) * bpp, (x1 + dstXoff) * dstBpp,
(x2 - x1) * bpp, (x2 - x1) * dstBpp,
y2 - y1, y2 - y1,
GXcopy, FB_ALLONES, bpp); GXcopy, FB_ALLONES, dstBpp);
exaFinishAccess(pDrawable, EXA_PREPARE_DEST); exaFinishAccess(pDrawable, EXA_PREPARE_DEST);
} }
exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff); exaPixmapDirty(pPix, x1 + xoff, y1 + yoff, x2 + xoff, y2 + yoff);
} }
return; return;
migrate_and_fallback: migrate_and_fallback:
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, FALSE); exaDoMigration (pixmaps, 1, FALSE);
fallback: fallback:
@ -387,6 +387,7 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
int src_off_x, src_off_y; int src_off_x, src_off_y;
int dst_off_x, dst_off_y; int dst_off_x, dst_off_y;
ExaMigrationRec pixmaps[2]; ExaMigrationRec pixmaps[2];
Bool fallback = FALSE;
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE; pixmaps[0].as_src = FALSE;
@ -404,50 +405,37 @@ exaCopyNtoN (DrawablePtr pSrcDrawable,
pDstPixmap->drawable.width > pExaScr->info->maxX || pDstPixmap->drawable.width > pExaScr->info->maxX ||
pDstPixmap->drawable.height > pExaScr->info->maxY) pDstPixmap->drawable.height > pExaScr->info->maxY)
{ {
exaDoMigration (pixmaps, 2, FALSE); fallback = TRUE;
goto fallback;
} else { } else {
exaDoMigration (pixmaps, 2, TRUE); exaDoMigration (pixmaps, 2, TRUE);
} }
/* Mixed directions must be handled specially if the card is lame */ /* Mixed directions must be handled specially if the card is lame */
if (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS && if (!fallback && (pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
reverse != upsidedown) { reverse != upsidedown) {
if (!exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
dx, dy)) dx, dy))
goto fallback;
return; return;
fallback = TRUE;
} }
if ((pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y)) && pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
(pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y)) && pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap,
reverse ? -1 : 1, upsidedown ? -1 : 1, exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
if (fallback || !exaPixmapIsOffscreen(pSrcPixmap) ||
!exaPixmapIsOffscreen(pDstPixmap) ||
!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
upsidedown ? -1 : 1,
pGC ? pGC->alu : GXcopy, pGC ? pGC->alu : GXcopy,
pGC ? pGC->planemask : FB_ALLONES)) pGC ? pGC->planemask : FB_ALLONES)) {
{ fallback = TRUE;
while (nbox--)
{
(*pExaScr->info->Copy) (pDstPixmap,
pbox->x1 + dx + src_off_x,
pbox->y1 + dy + src_off_y,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1);
exaPixmapDirty (pDstPixmap,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++;
}
(*pExaScr->info->DoneCopy) (pDstPixmap);
exaMarkSync(pDstDrawable->pScreen);
return;
}
fallback:
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable, EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrcDrawable, pDstDrawable,
exaDrawableLocation(pSrcDrawable), exaDrawableLocation(pSrcDrawable),
exaDrawableLocation(pDstDrawable))); exaDrawableLocation(pDstDrawable)));
exaDoMigration (pixmaps, 2, FALSE);
exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDstDrawable, EXA_PREPARE_DEST);
exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC); exaPrepareAccess (pSrcDrawable, EXA_PREPARE_SRC);
fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC, fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
@ -455,11 +443,26 @@ fallback:
bitplane, closure); bitplane, closure);
exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC); exaFinishAccess (pSrcDrawable, EXA_PREPARE_SRC);
exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDstDrawable, EXA_PREPARE_DEST);
}
while (nbox--) while (nbox--)
{ {
exaDrawableDirty (pDstDrawable, pbox->x1, pbox->y1, pbox->x2, pbox->y2); if (!fallback)
(*pExaScr->info->Copy) (pDstPixmap,
pbox->x1 + dx + src_off_x,
pbox->y1 + dy + src_off_y,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
exaPixmapDirty (pDstPixmap, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++; pbox++;
} }
if (fallback)
return;
(*pExaScr->info->DoneCopy) (pDstPixmap);
exaMarkSync (pDstDrawable->pScreen);
} }
RegionPtr RegionPtr
@ -618,6 +621,9 @@ exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
DEALLOCATE_LOCAL(prect); DEALLOCATE_LOCAL(prect);
} }
static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
Pixel pixel, CARD32 planemask, CARD32 alu);
static void static void
exaPolyFillRect(DrawablePtr pDrawable, exaPolyFillRect(DrawablePtr pDrawable,
GCPtr pGC, GCPtr pGC,
@ -626,7 +632,7 @@ exaPolyFillRect(DrawablePtr pDrawable,
{ {
ExaScreenPriv (pDrawable->pScreen); ExaScreenPriv (pDrawable->pScreen);
RegionPtr pClip = fbGetCompositeClip(pGC); RegionPtr pClip = fbGetCompositeClip(pGC);
PixmapPtr pPixmap; PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
register BoxPtr pbox; register BoxPtr pbox;
BoxPtr pextent; BoxPtr pextent;
int extentX1, extentX2, extentY1, extentY2; int extentX1, extentX2, extentY1, extentY2;
@ -635,39 +641,80 @@ exaPolyFillRect(DrawablePtr pDrawable,
int xoff, yoff; int xoff, yoff;
int xorg, yorg; int xorg, yorg;
int n; int n;
ExaMigrationRec pixmaps[1]; ExaMigrationRec pixmaps[2];
RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
RegionPtr pDamageReg = DamageRegion(ExaGetPixmapPriv(pPixmap)->pDamage);
/* Compute intersection of rects and clip region */
REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
REGION_INTERSECT(pScreen, pReg, pClip, pReg);
if (!REGION_NUM_RECTS(pReg)) {
REGION_DESTROY(pScreen, pReg);
return;
}
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE; pixmaps[0].as_src = FALSE;
pixmaps[0].pPix = pPixmap = exaGetDrawablePixmap (pDrawable); pixmaps[0].pPix = pPixmap;
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
if (pExaScr->swappedOut || if (pExaScr->swappedOut ||
pGC->fillStyle != FillSolid ||
pPixmap->drawable.width > pExaScr->info->maxX || pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY) pPixmap->drawable.height > pExaScr->info->maxY)
{ {
exaDoMigration (pixmaps, 1, FALSE); goto fallback;
ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
while (nrect-- >= 0) {
exaDrawableDirty(pDrawable,
pDrawable->x + prect->x,
pDrawable->y + prect->y,
pDrawable->x + prect->x + prect->width,
pDrawable->y + prect->y + prect->height);
prect++;
}
return;
} else {
exaDoMigration (pixmaps, 1, TRUE);
} }
if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) || /* For ROPs where overlaps don't matter, convert rectangles to region and
* call exaFillRegion{Solid,Tiled}.
*/
if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
(pGC->alu == GXcopy || pGC->alu == GXclear || pGC->alu == GXnoop ||
pGC->alu == GXcopyInverted || pGC->alu == GXset)) {
if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
pGC->alu)) ||
(pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
pGC->planemask, pGC->alu))) {
goto damage;
}
}
if (pGC->fillStyle != FillSolid &&
!(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
{
goto fallback;
}
exaDoMigration (pixmaps, 1, TRUE);
if (!exaPixmapIsOffscreen (pPixmap) ||
!(*pExaScr->info->PrepareSolid) (pPixmap, !(*pExaScr->info->PrepareSolid) (pPixmap,
pGC->alu, pGC->alu,
pGC->planemask, pGC->planemask,
pGC->fgPixel)) pGC->fgPixel))
{ {
fallback:
if (pGC->fillStyle == FillTiled && !pGC->tileIsPixel) {
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = pGC->tile.pixmap;
exaDoMigration (pixmaps, 2, FALSE);
} else {
exaDoMigration (pixmaps, 1, FALSE);
}
ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect); ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
damage:
REGION_TRANSLATE(pScreen, pReg, xoff, yoff);
REGION_UNION(pScreen, pDamageReg, pReg, pDamageReg);
REGION_DESTROY(pScreen, pReg);
return; return;
} }
@ -715,7 +762,8 @@ exaPolyFillRect(DrawablePtr pDrawable,
pbox = REGION_RECTS(pClip); pbox = REGION_RECTS(pClip);
/* /*
* clip the rectangle to each box in the clip region * clip the rectangle to each box in the clip region
* this is logically equivalent to calling Intersect() * this is logically equivalent to calling Intersect(),
* but rectangles may overlap each other here.
*/ */
while(n--) while(n--)
{ {
@ -775,20 +823,19 @@ exaSolidBoxClipped (DrawablePtr pDrawable,
pPixmap->drawable.width > pExaScr->info->maxX || pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY) pPixmap->drawable.height > pExaScr->info->maxY)
{ {
exaDoMigration (pixmaps, 1, FALSE); fallback = TRUE;
goto fallback;
} else { } else {
exaDoMigration (pixmaps, 1, TRUE); exaDoMigration (pixmaps, 1, TRUE);
} }
pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); exaGetDrawableDeltas (pDrawable, pPixmap, &xoff, &yoff);
if (!pPixmap || if (fallback || !exaPixmapIsOffscreen(pPixmap) ||
!(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg)) !(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
{ {
fallback:
EXA_FALLBACK(("to %p (%c)\n", pDrawable, EXA_FALLBACK(("to %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable))); exaDrawableLocation(pDrawable)));
exaDoMigration (pixmaps, 1, FALSE);
fallback = TRUE; fallback = TRUE;
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel); fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
@ -827,10 +874,10 @@ fallback:
(*pExaScr->info->Solid) (pPixmap, (*pExaScr->info->Solid) (pPixmap,
partX1 + xoff, partY1 + yoff, partX1 + xoff, partY1 + yoff,
partX2 + xoff, partY2 + yoff); partX2 + xoff, partY2 + yoff);
exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, }
partX2 + xoff, partY2 + yoff);
} else exaPixmapDirty (pPixmap, partX1 + xoff, partY1 + yoff, partX2 + xoff,
exaDrawableDirty (pDrawable, partX1, partY1, partX2, partY2); partY2 + yoff);
} }
if (fallback) if (fallback)
@ -870,12 +917,36 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
int dstBpp; int dstBpp;
int dstXoff, dstYoff; int dstXoff, dstYoff;
FbBits depthMask; FbBits depthMask;
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
ExaMigrationRec pixmaps[1];
int xBack, widthBack, yBack, heightBack;
for (ppci = ppciInit, n = nglyph, widthBack = 0; n; n--)
widthBack += (*ppci++)->metrics.characterWidth;
xBack = x;
if (widthBack < 0)
{
xBack += widthBack;
widthBack = -widthBack;
}
yBack = y - FONTASCENT(pGC->font);
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
if (xBack >= pDrawable->width || yBack >= pDrawable->height ||
(xBack + widthBack) <= 0 || (yBack + heightBack) <= 0)
return;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap;
depthMask = FbFullMask(pDrawable->depth); depthMask = FbFullMask(pDrawable->depth);
if ((pGC->planemask & depthMask) != depthMask) if ((pGC->planemask & depthMask) != depthMask)
{ {
exaDoMigration(pixmaps, 1, FALSE);
ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase); ExaCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
return; goto damage;
} }
glyph = NULL; glyph = NULL;
switch (pDrawable->bitsPerPixel) { switch (pDrawable->bitsPerPixel) {
@ -887,6 +958,8 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
x += pDrawable->x; x += pDrawable->x;
y += pDrawable->y; y += pDrawable->y;
xBack += pDrawable->x;
yBack += pDrawable->y;
if (TERMINALFONT (pGC->font) && !glyph) if (TERMINALFONT (pGC->font) && !glyph)
{ {
@ -894,23 +967,6 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
} }
else else
{ {
int xBack, widthBack;
int yBack, heightBack;
ppci = ppciInit;
n = nglyph;
widthBack = 0;
while (n--)
widthBack += (*ppci++)->metrics.characterWidth;
xBack = x;
if (widthBack < 0)
{
xBack += widthBack;
widthBack = -widthBack;
}
yBack = y - FONTASCENT(pGC->font);
heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
exaSolidBoxClipped (pDrawable, exaSolidBoxClipped (pDrawable,
fbGetCompositeClip(pGC), fbGetCompositeClip(pGC),
pGC->planemask, pGC->planemask,
@ -923,74 +979,50 @@ exaImageGlyphBlt (DrawablePtr pDrawable,
} }
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
exaDoMigration(pixmaps, 1, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
exaPrepareAccessGC (pGC); exaPrepareAccessGC (pGC);
fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
ppci = ppciInit; for (ppci = ppciInit; nglyph; nglyph--, x += pci->metrics.characterWidth)
while (nglyph--)
{ {
pci = *ppci++; pci = *ppci++;
pglyph = FONTGLYPHBITS(pglyphBase, pci);
gWidth = GLYPHWIDTHPIXELS(pci); gWidth = GLYPHWIDTHPIXELS(pci);
gHeight = GLYPHHEIGHTPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci);
if (gWidth && gHeight)
{
gx = x + pci->metrics.leftSideBearing; gx = x + pci->metrics.leftSideBearing;
gy = y - pci->metrics.ascent; gy = y - pci->metrics.ascent;
if (!gWidth || !gHeight || (gx + gWidth) <= xBack ||
(gy + gHeight) <= yBack || gx >= (xBack + widthBack) ||
gy >= (yBack + heightBack))
continue;
pglyph = FONTGLYPHBITS(pglyphBase, pci);
if (glyph && gWidth <= sizeof (FbStip) * 8 && if (glyph && gWidth <= sizeof (FbStip) * 8 &&
fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
{ {
(*glyph) (dst + (gy + dstYoff) * dstStride, (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
dstStride, (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight);
dstBpp,
(FbStip *) pglyph,
pPriv->fg,
gx + dstXoff,
gHeight);
exaDrawableDirty (pDrawable, gx, gy, gx + gWidth, gy + gHeight);
} }
else else
{ {
RegionPtr pClip = fbGetCompositeClip(pGC); RegionPtr pClip = fbGetCompositeClip(pGC);
int nbox;
BoxPtr pbox;
gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
fbPutXYImage (pDrawable, fbPutXYImage (pDrawable, pClip, pPriv->fg, pPriv->bg, pPriv->pm,
pClip, GXcopy, opaque, gx, gy, gWidth, gHeight,
pPriv->fg, (FbStip *) pglyph, gStride, 0);
pPriv->bg,
pPriv->pm,
GXcopy,
opaque,
gx,
gy,
gWidth, gHeight,
(FbStip *) pglyph,
gStride,
0);
for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
nbox--; pbox++) {
int x1 = max(gx, pbox->x1), x2 = min(gx + gWidth, pbox->x2);
int y1 = max(gy, pbox->y1), y2 = min(gy + gHeight, pbox->y2);
if (x1 >= x2 || y1 >= y2)
continue;
exaDrawableDirty (pDrawable, gx, gy, gx + gWidth,
gy + gHeight);
} }
} }
}
x += pci->metrics.characterWidth;
}
exaFinishAccessGC (pGC); exaFinishAccessGC (pGC);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
damage:
exaGetDrawableDeltas(pDrawable, pPixmap, &dstXoff, &dstYoff);
exaPixmapDirty(pPixmap, xBack + dstXoff, yBack + dstYoff,
xBack + dstXoff + widthBack, yBack + dstYoff + heightBack);
} }
const GCOps exaOps = { const GCOps exaOps = {
@ -1043,10 +1075,12 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
} }
static void static Bool
exaFillRegionSolid (DrawablePtr pDrawable, exaFillRegionSolid (DrawablePtr pDrawable,
RegionPtr pRegion, RegionPtr pRegion,
Pixel pixel) Pixel pixel,
CARD32 planemask,
CARD32 alu)
{ {
ExaScreenPriv(pDrawable->pScreen); ExaScreenPriv(pDrawable->pScreen);
PixmapPtr pPixmap; PixmapPtr pPixmap;
@ -1062,22 +1096,19 @@ exaFillRegionSolid (DrawablePtr pDrawable,
if (pPixmap->drawable.width > pExaScr->info->maxX || if (pPixmap->drawable.width > pExaScr->info->maxX ||
pPixmap->drawable.height > pExaScr->info->maxY) pPixmap->drawable.height > pExaScr->info->maxY)
{ {
exaDoMigration (pixmaps, 1, FALSE);
goto fallback; goto fallback;
} else { } else {
exaDoMigration (pixmaps, 1, TRUE); exaDoMigration (pixmaps, 1, TRUE);
} }
if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) && if ((pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
(*pExaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel)) (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
{ {
while (nbox--) while (nbox--)
{ {
(*pExaScr->info->Solid) (pPixmap, (*pExaScr->info->Solid) (pPixmap,
pBox->x1 + xoff, pBox->y1 + yoff, pBox->x1 + xoff, pBox->y1 + yoff,
pBox->x2 + xoff, pBox->y2 + yoff); pBox->x2 + xoff, pBox->y2 + yoff);
exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
pBox->x2 + xoff, pBox->y2 + yoff);
pBox++; pBox++;
} }
(*pExaScr->info->DoneSolid) (pPixmap); (*pExaScr->info->DoneSolid) (pPixmap);
@ -1086,27 +1117,30 @@ exaFillRegionSolid (DrawablePtr pDrawable,
else else
{ {
fallback: fallback:
if (alu != GXcopy || planemask != FB_ALLONES)
return FALSE;
EXA_FALLBACK(("to %p (%c)\n", pDrawable, EXA_FALLBACK(("to %p (%c)\n", pDrawable,
exaDrawableLocation(pDrawable))); exaDrawableLocation(pDrawable)));
exaDoMigration (pixmaps, 1, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbFillRegionSolid (pDrawable, pRegion, 0, fbFillRegionSolid (pDrawable, pRegion, 0,
fbReplicatePixel (pixel, pDrawable->bitsPerPixel)); fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
exaFinishAccess (pDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
while (nbox--)
{
exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
pBox++;
}
} }
return TRUE;
} }
/* Try to do an accelerated tile of the pTile into pRegion of pDrawable. /* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
* Based on fbFillRegionTiled(), fbTile(). * Based on fbFillRegionTiled(), fbTile().
*/ */
static void Bool
exaFillRegionTiled (DrawablePtr pDrawable, exaFillRegionTiled (DrawablePtr pDrawable,
RegionPtr pRegion, RegionPtr pRegion,
PixmapPtr pTile) PixmapPtr pTile,
DDXPointPtr pPatOrg,
CARD32 planemask,
CARD32 alu)
{ {
ExaScreenPriv(pDrawable->pScreen); ExaScreenPriv(pDrawable->pScreen);
PixmapPtr pPixmap; PixmapPtr pPixmap;
@ -1122,10 +1156,10 @@ exaFillRegionTiled (DrawablePtr pDrawable,
/* If we're filling with a solid color, grab it out and go to /* If we're filling with a solid color, grab it out and go to
* FillRegionSolid, saving numerous copies. * FillRegionSolid, saving numerous copies.
*/ */
if (tileWidth == 1 && tileHeight == 1) { if (tileWidth == 1 && tileHeight == 1)
exaFillRegionSolid(pDrawable, pRegion, exaGetPixmapFirstPixel (pTile)); return exaFillRegionSolid(pDrawable, pRegion,
return; exaGetPixmapFirstPixel (pTile), planemask,
} alu);
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = FALSE; pixmaps[0].as_src = FALSE;
@ -1139,7 +1173,6 @@ exaFillRegionTiled (DrawablePtr pDrawable,
tileWidth > pExaScr->info->maxX || tileWidth > pExaScr->info->maxX ||
tileHeight > pExaScr->info->maxY) tileHeight > pExaScr->info->maxY)
{ {
exaDoMigration (pixmaps, 2, FALSE);
goto fallback; goto fallback;
} else { } else {
exaDoMigration (pixmaps, 2, TRUE); exaDoMigration (pixmaps, 2, TRUE);
@ -1153,8 +1186,9 @@ exaFillRegionTiled (DrawablePtr pDrawable,
if (!exaPixmapIsOffscreen(pTile)) if (!exaPixmapIsOffscreen(pTile))
goto fallback; goto fallback;
if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile, &tileXoff, &tileYoff), pPixmap, 0, 0, GXcopy, if ((*pExaScr->info->PrepareCopy) (exaGetOffscreenPixmap((DrawablePtr)pTile,
FB_ALLONES)) &tileXoff, &tileYoff),
pPixmap, 0, 0, alu, planemask))
{ {
while (nbox--) while (nbox--)
{ {
@ -1162,7 +1196,7 @@ exaFillRegionTiled (DrawablePtr pDrawable,
int dstY = pBox->y1; int dstY = pBox->y1;
int tileY; int tileY;
tileY = (dstY - pDrawable->y) % tileHeight; tileY = (dstY - pDrawable->y - pPatOrg->y) % tileHeight;
while (height > 0) { while (height > 0) {
int width = pBox->x2 - pBox->x1; int width = pBox->x2 - pBox->x1;
int dstX = pBox->x1; int dstX = pBox->x1;
@ -1173,7 +1207,7 @@ exaFillRegionTiled (DrawablePtr pDrawable,
h = height; h = height;
height -= h; height -= h;
tileX = (dstX - pDrawable->x) % tileWidth; tileX = (dstX - pDrawable->x - pPatOrg->x) % tileWidth;
while (width > 0) { while (width > 0) {
int w = tileWidth - tileX; int w = tileWidth - tileX;
if (w > width) if (w > width)
@ -1190,38 +1224,44 @@ exaFillRegionTiled (DrawablePtr pDrawable,
dstY += h; dstY += h;
tileY = 0; tileY = 0;
} }
exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
pBox->x2 + xoff, pBox->y2 + yoff);
pBox++; pBox++;
} }
(*pExaScr->info->DoneCopy) (pPixmap); (*pExaScr->info->DoneCopy) (pPixmap);
exaMarkSync(pDrawable->pScreen); exaMarkSync(pDrawable->pScreen);
return; return TRUE;
} }
fallback: fallback:
if (alu != GXcopy || planemask != FB_ALLONES)
return FALSE;
EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable, EXA_FALLBACK(("from %p to %p (%c,%c)\n", pTile, pDrawable,
exaDrawableLocation(&pTile->drawable), exaDrawableLocation(&pTile->drawable),
exaDrawableLocation(pDrawable))); exaDrawableLocation(pDrawable)));
exaDoMigration (pixmaps, 2, FALSE);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC); exaPrepareAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
fbFillRegionTiled (pDrawable, pRegion, pTile); fbFillRegionTiled (pDrawable, pRegion, pTile);
exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC); exaFinishAccess ((DrawablePtr)pTile, EXA_PREPARE_SRC);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
while (nbox--)
{ return TRUE;
exaDrawableDirty (pDrawable, pBox->x1, pBox->y1, pBox->x2, pBox->y2);
pBox++;
}
} }
void void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what) exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{ {
ExaScreenPriv (pWin->drawable.pScreen); ExaScreenPriv (pWin->drawable.pScreen);
if (!REGION_NUM_RECTS(pRegion)) PixmapPtr pPixmap = exaGetDrawablePixmap((DrawablePtr)pWin);
int xoff, yoff;
BoxPtr pBox;
int nbox = REGION_NUM_RECTS(pRegion);
if (!nbox)
return; return;
if (!pExaScr->swappedOut) { if (!pExaScr->swappedOut) {
DDXPointRec zeros = { 0, 0 };
switch (what) { switch (what) {
case PW_BACKGROUND: case PW_BACKGROUND:
switch (pWin->backgroundState) { switch (pWin->backgroundState) {
@ -1235,25 +1275,41 @@ exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
what); what);
return; return;
case BackgroundPixel: case BackgroundPixel:
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel); exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->background.pixel,
return; FB_ALLONES, GXcopy);
goto damage;
case BackgroundPixmap: case BackgroundPixmap:
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap); exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->background.pixmap,
return; &zeros, FB_ALLONES, GXcopy);
goto damage;
} }
break; break;
case PW_BORDER: case PW_BORDER:
if (pWin->borderIsPixel) { if (pWin->borderIsPixel) {
exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel); exaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel,
return; FB_ALLONES, GXcopy);
goto damage;
} else { } else {
exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap); exaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap,
return; &zeros, FB_ALLONES, GXcopy);
goto damage;
} }
break; break;
} }
} }
ExaCheckPaintWindow (pWin, pRegion, what); ExaCheckPaintWindow (pWin, pRegion, what);
damage:
exaGetDrawableDeltas((DrawablePtr)pWin, pPixmap, &xoff, &yoff);
pBox = REGION_RECTS(pRegion);
while (nbox--)
{
exaPixmapDirty (pPixmap, pBox->x1 + xoff, pBox->y1 + yoff,
pBox->x2 + xoff, pBox->y2 + yoff);
pBox++;
}
} }
/** /**
@ -1273,27 +1329,22 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
int xoff, yoff; int xoff, yoff;
Bool ok; Bool ok;
if (pExaScr->swappedOut || pExaScr->info->DownloadFromScreen == NULL) if (pExaScr->info->DownloadFromScreen == NULL)
goto fallback; goto migrate_and_fallback;
/* Only cover the ZPixmap, solid copy case. */ /* Only cover the ZPixmap, solid copy case. */
if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
goto fallback; goto migrate_and_fallback;
/* Only try to handle the 8bpp and up cases, since we don't want to think /* Only try to handle the 8bpp and up cases, since we don't want to think
* about <8bpp. * about <8bpp.
*/ */
if (pDrawable->bitsPerPixel < 8) if (pDrawable->bitsPerPixel < 8)
goto migrate_and_fallback;
if (pExaScr->swappedOut)
goto fallback; goto fallback;
/* Migrate, but assume that we could accelerate the download. It is up to
* the migration scheme to ensure that this case doesn't result in bad
* moving of pixmaps.
*/
pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, TRUE);
pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
if (pPix == NULL) if (pPix == NULL)
goto fallback; goto fallback;
@ -1308,12 +1359,12 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
return; return;
} }
fallback: migrate_and_fallback:
pixmaps[0].as_dst = FALSE; pixmaps[0].as_dst = FALSE;
pixmaps[0].as_src = TRUE; pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable); pixmaps[0].pPix = exaGetDrawablePixmap (pDrawable);
exaDoMigration (pixmaps, 1, FALSE); exaDoMigration (pixmaps, 1, FALSE);
fallback:
ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d); ExaCheckGetImage (pDrawable, x, y, w, h, format, planeMask, d);
} }

View File

@ -464,12 +464,10 @@ exaAssertNotDirty (PixmapPtr pPixmap)
BoxPtr pBox = REGION_RECTS(pValidReg); BoxPtr pBox = REGION_RECTS(pValidReg);
Bool ret = TRUE; Bool ret = TRUE;
if (pExaPixmap == NULL || pExaPixmap->fb_ptr == NULL) if (!nbox || exaPixmapIsPinned(pPixmap) || pExaPixmap->fb_ptr == NULL)
return ret; return ret;
dst = pExaPixmap->sys_ptr;
dst_pitch = pExaPixmap->sys_pitch; dst_pitch = pExaPixmap->sys_pitch;
src = pExaPixmap->fb_ptr;
src_pitch = pExaPixmap->fb_pitch; src_pitch = pExaPixmap->fb_pitch;
cpp = pPixmap->drawable.bitsPerPixel / 8; cpp = pPixmap->drawable.bitsPerPixel / 8;
@ -486,21 +484,18 @@ exaAssertNotDirty (PixmapPtr pPixmap)
continue; continue;
rowbytes = (pBox->x2 - pBox->x1) * cpp; rowbytes = (pBox->x2 - pBox->x1) * cpp;
src += pBox->y1 * src_pitch + pBox->x1 * cpp; src = pExaPixmap->fb_ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
dst += pBox->y1 * dst_pitch + pBox->x1 * cpp; dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
for (y = pBox->y2 - pBox->y1; y; y--) { for (y = pBox->y1; y < pBox->y2;
if (memcmp(dst + pBox->y1 * dst_pitch + pBox->x1 * cpp, y++, src += src_pitch, dst += dst_pitch) {
src + pBox->y1 * src_pitch + pBox->x1 * cpp, if (memcmp(dst, src, rowbytes) != 0) {
(pBox->x2 - pBox->x1) * cpp) != 0) {
ret = FALSE; ret = FALSE;
exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
pBox->y2);
break; break;
} }
src += src_pitch;
dst += dst_pitch;
} }
src -= pBox->y1 * src_pitch + pBox->x1 * cpp;
dst -= pBox->y1 * dst_pitch + pBox->x1 * cpp;
} }
exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);

View File

@ -54,7 +54,7 @@ ExaOffscreenValidate (ScreenPtr pScreen)
assert (area->offset >= area->base_offset && assert (area->offset >= area->base_offset &&
area->offset < (area->base_offset + area->size)); area->offset < (area->base_offset + area->size));
if (prev) if (prev)
assert (prev->base_offset + prev->area.size == area->base_offset); assert (prev->base_offset + prev->size == area->base_offset);
prev = area; prev = area;
} }
assert (prev->base_offset + prev->size == pExaScr->info->memorySize); assert (prev->base_offset + prev->size == pExaScr->info->memorySize);
@ -341,13 +341,15 @@ exaEnableDisableFBAccess (int index, Bool enable)
ScreenPtr pScreen = screenInfo.screens[index]; ScreenPtr pScreen = screenInfo.screens[index];
ExaScreenPriv (pScreen); ExaScreenPriv (pScreen);
if (!enable) { if (!enable && pExaScr->disableFbCount++ == 0) {
if (pExaScr->info->exa_minor < 1) if (pExaScr->info->exa_minor < 1)
ExaOffscreenSwapOut (pScreen); ExaOffscreenSwapOut (pScreen);
else else
ExaOffscreenEjectPixmaps (pScreen); ExaOffscreenEjectPixmaps (pScreen);
pExaScr->swappedOut = TRUE; pExaScr->swappedOut = TRUE;
} else { }
if (enable && --pExaScr->disableFbCount == 0) {
if (pExaScr->info->exa_minor < 1) if (pExaScr->info->exa_minor < 1)
ExaOffscreenSwapIn (pScreen); ExaOffscreenSwapIn (pScreen);
pExaScr->swappedOut = FALSE; pExaScr->swappedOut = FALSE;

View File

@ -113,6 +113,7 @@ typedef struct {
enum ExaMigrationHeuristic migration; enum ExaMigrationHeuristic migration;
Bool hideOffscreenPixmapData; Bool hideOffscreenPixmapData;
Bool checkDirtyCorrectness; Bool checkDirtyCorrectness;
unsigned disableFbCount;
} ExaScreenPrivRec, *ExaScreenPrivPtr; } ExaScreenPrivRec, *ExaScreenPrivPtr;
/* /*
@ -287,6 +288,10 @@ exaGetPixmapFirstPixel (PixmapPtr pPixmap);
void void
exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
Bool
exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu);
void void
exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what); exaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what);
@ -343,7 +348,8 @@ void
exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2); exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2);
void void
exaDrawableDirty(DrawablePtr pDrawable, int x1, int y1, int x2, int y2); exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap,
int *xp, int *yp);
Bool Bool
exaDrawableIsOffscreen (DrawablePtr pDrawable); exaDrawableIsOffscreen (DrawablePtr pDrawable);

View File

@ -297,15 +297,15 @@ exaTryDriverSolidFill(PicturePtr pSrc,
nbox = REGION_NUM_RECTS(&region); nbox = REGION_NUM_RECTS(&region);
pbox = REGION_RECTS(&region); pbox = REGION_RECTS(&region);
while (nbox--) while (nbox--)
{ {
(*pExaScr->info->Solid) (pDstPix, (*pExaScr->info->Solid) (pDstPix,
pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y); pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++; pbox++;
} }
(*pExaScr->info->DoneSolid) (pDstPix); (*pExaScr->info->DoneSolid) (pDstPix);
exaMarkSync(pDst->pDrawable->pScreen); exaMarkSync(pDst->pDrawable->pScreen);
@ -446,8 +446,6 @@ exaTryDriverComposite(CARD8 op,
pbox->y1 + dst_off_y, pbox->y1 + dst_off_y,
pbox->x2 - pbox->x1, pbox->x2 - pbox->x1,
pbox->y2 - pbox->y1); pbox->y2 - pbox->y1);
exaPixmapDirty (pDstPix, pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
pbox->x2 + dst_off_x, pbox->y2 + dst_off_y);
pbox++; pbox++;
} }
(*pExaScr->info->DoneComposite) (pDstPix); (*pExaScr->info->DoneComposite) (pDstPix);
@ -521,6 +519,9 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op,
CARD16 height) CARD16 height)
{ {
ExaScreenPriv (pDst->pDrawable->pScreen); ExaScreenPriv (pDst->pDrawable->pScreen);
DrawablePtr pDstDraw = pDst->pDrawable;
PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDstDraw);
int xoff, yoff;
assert(op == PictOpOver); assert(op == PictOpOver);
@ -539,6 +540,12 @@ exaTryMagicTwoPassCompositeHelper(CARD8 op,
exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, exaComposite(PictOpOutReverse, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
xDst, yDst, width, height); xDst, yDst, width, height);
exaGetDrawableDeltas(pDstDraw, pDstPixmap, &xoff, &yoff);
xoff += pDstDraw->x;
yoff += pDstDraw->y;
exaPixmapDirty(pDstPixmap, xDst + xoff, yDst + yoff, xDst + xoff + width,
yDst + yoff + height);
/* Then, add in the source value times the destination alpha factors (1.0). /* Then, add in the source value times the destination alpha factors (1.0).
*/ */
exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, exaComposite(PictOpAdd, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
@ -565,6 +572,28 @@ exaComposite(CARD8 op,
int ret = -1; int ret = -1;
Bool saveSrcRepeat = pSrc->repeat; Bool saveSrcRepeat = pSrc->repeat;
Bool saveMaskRepeat = pMask ? pMask->repeat : 0; Bool saveMaskRepeat = pMask ? pMask->repeat : 0;
ExaMigrationRec pixmaps[3];
int npixmaps = 1;
PixmapPtr pSrcPixmap = NULL;
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op);
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
if (pSrc->pDrawable) {
pSrcPixmap = exaGetDrawablePixmap (pSrc->pDrawable);
pixmaps[npixmaps].as_dst = FALSE;
pixmaps[npixmaps].as_src = TRUE;
pixmaps[npixmaps].pPix = pSrcPixmap;
npixmaps++;
}
if (pMask && pMask->pDrawable) {
pixmaps[npixmaps].as_dst = FALSE;
pixmaps[npixmaps].as_src = TRUE;
pixmaps[npixmaps].pPix = exaGetDrawablePixmap (pMask->pDrawable);
npixmaps++;
}
/* We currently don't support acceleration of gradients, or other pictures /* We currently don't support acceleration of gradients, or other pictures
* with a NULL pDrawable. * with a NULL pDrawable.
@ -583,19 +612,24 @@ exaComposite(CARD8 op,
if (!pMask) if (!pMask)
{ {
if (op == PictOpSrc) if ((op == PictOpSrc &&
((pSrc->format == pDst->format) ||
(pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
(pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
(op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
pSrc->format == pDst->format &&
(pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8)))
{ {
if (pSrc->pDrawable->width == 1 && if (pSrc->pDrawable->width == 1 &&
pSrc->pDrawable->height == 1 && pSrc->repeat && pSrc->pDrawable->height == 1 &&
pSrc->repeatType == RepeatNormal) pSrc->repeat)
{ {
ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst, ret = exaTryDriverSolidFill(pSrc, pDst, xSrc, ySrc, xDst, yDst,
width, height); width, height);
if (ret == 1) if (ret == 1)
goto done; goto done;
} }
else if (!pSrc->repeat && !pSrc->transform && else if (pSrcPixmap && !pSrc->repeat && !pSrc->transform)
pSrc->format == pDst->format)
{ {
RegionRec region; RegionRec region;
@ -617,6 +651,45 @@ exaComposite(CARD8 op,
REGION_UNINIT(pDst->pDrawable->pScreen, &region); REGION_UNINIT(pDst->pDrawable->pScreen, &region);
goto done; goto done;
} }
else if (pSrcPixmap && !pSrc->transform &&
pSrc->repeatType == RepeatNormal)
{
RegionRec region;
DDXPointRec srcOrg;
/* Let's see if the driver can do the repeat in one go */
if (pExaScr->info->PrepareComposite && !pSrc->alphaMap &&
!pDst->alphaMap)
{
ret = exaTryDriverComposite(op, pSrc, pMask, pDst, xSrc,
ySrc, xMask, yMask, xDst, yDst,
width, height);
if (ret == 1)
goto done;
}
/* Now see if we can use exaFillRegionTiled() */
xDst += pDst->pDrawable->x;
yDst += pDst->pDrawable->y;
xSrc += pSrc->pDrawable->x;
ySrc += pSrc->pDrawable->y;
if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst, xSrc,
ySrc, xMask, yMask, xDst, yDst,
width, height))
goto done;
srcOrg.x = (xSrc - xDst) % pSrcPixmap->drawable.width;
srcOrg.y = (ySrc - yDst) % pSrcPixmap->drawable.height;
ret = exaFillRegionTiled(pDst->pDrawable, &region, pSrcPixmap,
&srcOrg, FB_ALLONES, GXcopy);
REGION_UNINIT(pDst->pDrawable->pScreen, &region);
if (ret)
goto done;
}
} }
} }
@ -627,8 +700,8 @@ exaComposite(CARD8 op,
pMask->repeat = 0; pMask->repeat = 0;
if (pExaScr->info->PrepareComposite && if (pExaScr->info->PrepareComposite &&
(!pSrc->repeat || pSrc->repeat == RepeatNormal) && (!pSrc->repeat || pSrc->repeatType == RepeatNormal) &&
(!pMask || !pMask->repeat || pMask->repeat == RepeatNormal) && (!pMask || !pMask->repeat || pMask->repeatType == RepeatNormal) &&
!pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap) !pSrc->alphaMap && (!pMask || !pMask->alphaMap) && !pDst->alphaMap)
{ {
Bool isSrcSolid; Bool isSrcSolid;
@ -660,39 +733,14 @@ exaComposite(CARD8 op,
} }
} }
if (ret != 0) {
ExaMigrationRec pixmaps[3];
/* failure to accelerate was not due to pixmaps being in the wrong
* locations.
*/
pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = exaOpReadsDestination(op);
pixmaps[0].pPix = exaGetDrawablePixmap (pDst->pDrawable);
pixmaps[1].as_dst = FALSE;
pixmaps[1].as_src = TRUE;
pixmaps[1].pPix = exaGetDrawablePixmap (pSrc->pDrawable);
if (pMask) {
pixmaps[2].as_dst = FALSE;
pixmaps[2].as_src = TRUE;
pixmaps[2].pPix = exaGetDrawablePixmap (pMask->pDrawable);
exaDoMigration(pixmaps, 3, FALSE);
} else {
exaDoMigration(pixmaps, 2, FALSE);
}
}
fallback: fallback:
#if DEBUG_TRACE_FALL #if DEBUG_TRACE_FALL
exaPrintCompositeFallback (op, pSrc, pMask, pDst); exaPrintCompositeFallback (op, pSrc, pMask, pDst);
#endif #endif
exaDoMigration(pixmaps, npixmaps, FALSE);
ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc, ExaCheckComposite (op, pSrc, pMask, pDst, xSrc, ySrc,
xMask, yMask, xDst, yDst, width, height); xMask, yMask, xDst, yDst, width, height);
exaDrawableDirty(pDst->pDrawable,
pDst->pDrawable->x + xDst,
pDst->pDrawable->y + yDst,
pDst->pDrawable->x + xDst + width,
pDst->pDrawable->y + yDst + height);
done: done:
pSrc->repeat = saveSrcRepeat; pSrc->repeat = saveSrcRepeat;
@ -716,6 +764,7 @@ exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
{ {
DrawablePtr pDraw = pPicture->pDrawable; DrawablePtr pDraw = pPicture->pDrawable;
ExaMigrationRec pixmaps[1]; ExaMigrationRec pixmaps[1];
int xoff, yoff;
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE; pixmaps[0].as_src = TRUE;
@ -724,8 +773,10 @@ exaRasterizeTrapezoid (PicturePtr pPicture, xTrapezoid *trap,
exaPrepareAccess(pDraw, EXA_PREPARE_DEST); exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbRasterizeTrapezoid(pPicture, trap, x_off, y_off); fbRasterizeTrapezoid(pPicture, trap, x_off, y_off);
exaDrawableDirty(pDraw, pDraw->x, pDraw->y, exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
pDraw->x + pDraw->width, pDraw->y + pDraw->height); exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
pDraw->x + xoff + pDraw->width,
pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST); exaFinishAccess(pDraw, EXA_PREPARE_DEST);
} }
@ -739,6 +790,7 @@ exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
{ {
DrawablePtr pDraw = pPicture->pDrawable; DrawablePtr pDraw = pPicture->pDrawable;
ExaMigrationRec pixmaps[1]; ExaMigrationRec pixmaps[1];
int xoff, yoff;
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE; pixmaps[0].as_src = TRUE;
@ -747,8 +799,10 @@ exaAddTriangles (PicturePtr pPicture, INT16 x_off, INT16 y_off, int ntri,
exaPrepareAccess(pDraw, EXA_PREPARE_DEST); exaPrepareAccess(pDraw, EXA_PREPARE_DEST);
fbAddTriangles(pPicture, x_off, y_off, ntri, tris); fbAddTriangles(pPicture, x_off, y_off, ntri, tris);
exaDrawableDirty(pDraw, pDraw->x, pDraw->y, exaGetDrawableDeltas(pDraw, pixmaps[0].pPix, &xoff, &yoff);
pDraw->x + pDraw->width, pDraw->y + pDraw->height); exaPixmapDirty(pixmaps[0].pPix, pDraw->x + xoff, pDraw->y + yoff,
pDraw->x + xoff + pDraw->width,
pDraw->y + yoff + pDraw->height);
exaFinishAccess(pDraw, EXA_PREPARE_DEST); exaFinishAccess(pDraw, EXA_PREPARE_DEST);
} }
@ -845,10 +899,11 @@ exaGlyphs (CARD8 op,
PixmapPtr pPixmap = NULL; PixmapPtr pPixmap = NULL;
PicturePtr pPicture; PicturePtr pPicture;
PixmapPtr pMaskPixmap = NULL; PixmapPtr pMaskPixmap = NULL;
PixmapPtr pDstPixmap = exaGetDrawablePixmap(pDst->pDrawable);
PicturePtr pMask; PicturePtr pMask;
ScreenPtr pScreen = pDst->pDrawable->pScreen; ScreenPtr pScreen = pDst->pDrawable->pScreen;
int width = 0, height = 0; int width = 0, height = 0;
int x, y; int x, y, x1, y1, xoff, yoff;
int xDst = list->xOff, yDst = list->yOff; int xDst = list->xOff, yDst = list->yOff;
int n; int n;
int error; int error;
@ -893,6 +948,11 @@ exaGlyphs (CARD8 op,
miGlyphExtents (nlist, list, glyphs, &extents); miGlyphExtents (nlist, list, glyphs, &extents);
extents.x1 = max(extents.x1, 0);
extents.y1 = max(extents.y1, 0);
extents.x2 = min(extents.x2, pDst->pDrawable->width);
extents.y2 = min(extents.y2, pDst->pDrawable->height);
if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1) if (extents.x2 <= extents.x1 || extents.y2 <= extents.y1)
return; return;
width = extents.x2 - extents.x1; width = extents.x2 - extents.x1;
@ -918,6 +978,7 @@ exaGlyphs (CARD8 op,
rect.width = width; rect.width = width;
rect.height = height; rect.height = height;
(*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect); (*pGC->ops->PolyFillRect) (&pMaskPixmap->drawable, pGC, 1, &rect);
exaPixmapDirty(pMaskPixmap, 0, 0, width, height);
FreeScratchGC (pGC); FreeScratchGC (pGC);
x = -extents.x1; x = -extents.x1;
y = -extents.y1; y = -extents.y1;
@ -929,6 +990,8 @@ exaGlyphs (CARD8 op,
y = 0; y = 0;
} }
exaGetDrawableDeltas(pDst->pDrawable, pDstPixmap, &xoff, &yoff);
while (nlist--) while (nlist--)
{ {
GCPtr pGC = NULL; GCPtr pGC = NULL;
@ -983,12 +1046,20 @@ exaGlyphs (CARD8 op,
pixmaps[0].as_dst = TRUE; pixmaps[0].as_dst = TRUE;
pixmaps[0].as_src = TRUE; pixmaps[0].as_src = TRUE;
pixmaps[0].pPix = pPixmap; pixmaps[0].pPix = pPixmap;
exaDoMigration (pixmaps, 1, TRUE); exaDoMigration (pixmaps, 1, pExaScr->info->PrepareComposite != NULL);
while (n--) while (n--)
{ {
GlyphPtr glyph = *glyphs++; GlyphPtr glyph = *glyphs++;
pointer glyphdata = (pointer) (glyph + 1); pointer glyphdata = (pointer) (glyph + 1);
DrawablePtr pCmpDrw = (maskFormat ? pMask : pDst)->pDrawable;
x1 = x - glyph->info.x;
y1 = y - glyph->info.y;
if (x1 >= pCmpDrw->width || y1 >= pCmpDrw->height ||
(x1 + glyph->info.width) <= 0 || (y1 + glyph->info.height) <= 0)
goto nextglyph;
(*pScreen->ModifyPixmapHeader) (pScratchPixmap, (*pScreen->ModifyPixmapHeader) (pScratchPixmap,
glyph->info.width, glyph->info.width,
@ -1048,17 +1119,22 @@ exaGlyphs (CARD8 op,
if (maskFormat) if (maskFormat)
{ {
exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0, exaComposite (PictOpAdd, pPicture, NULL, pMask, 0, 0, 0, 0,
x - glyph->info.x, y - glyph->info.y, x1, y1, glyph->info.width, glyph->info.height);
glyph->info.width, glyph->info.height); exaPixmapDirty(pMaskPixmap, x1, y1, x1 + glyph->info.width,
y1 + glyph->info.height);
} }
else else
{ {
exaComposite (op, pSrc, pPicture, pDst, exaComposite (op, pSrc, pPicture, pDst,
xSrc + (x - glyph->info.x) - xDst, xSrc + x1 - xDst, ySrc + y1 - yDst,
ySrc + (y - glyph->info.y) - yDst, 0, 0, x1, y1, glyph->info.width,
0, 0, x - glyph->info.x, y - glyph->info.y, glyph->info.height);
glyph->info.width, glyph->info.height); x1 += pDst->pDrawable->x + xoff;
y1 += pDst->pDrawable->y + yoff;
exaPixmapDirty(pDstPixmap, x1, y1, x1 + glyph->info.width,
y1 + glyph->info.height);
} }
nextglyph:
x += glyph->info.xOff; x += glyph->info.xOff;
y += glyph->info.yOff; y += glyph->info.yOff;
} }

View File

@ -88,10 +88,15 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
int x, int y, int w, int h, int leftPad, int format, int x, int y, int w, int h, int leftPad, int format,
char *bits) char *bits)
{ {
PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
int xoff, yoff;
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); fbPutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
exaPixmapDirty(pPixmap, x + xoff, y + yoff, x + xoff + w, y + yoff + h);
} }
RegionPtr RegionPtr
@ -201,32 +206,11 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
{ {
EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
if (nrect) {
int x1 = max(prect->x, 0), y1 = max(prect->y, 0);
int x2 = min(prect->x + prect->width, pDrawable->width);
int y2 = min(prect->y + prect->height, pDrawable->height);
exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
exaPrepareAccessGC (pGC); exaPrepareAccessGC (pGC);
fbPolyFillRect (pDrawable, pGC, nrect, prect); fbPolyFillRect (pDrawable, pGC, nrect, prect);
exaFinishAccessGC (pGC); exaFinishAccessGC (pGC);
exaFinishAccess (pDrawable, EXA_PREPARE_DEST); exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
/* Only track bounding box of damage, as this path can degenerate to
* zillions of damage boxes
*/
while (--nrect)
{
prect++;
x1 = min(x1, prect->x);
x2 = max(x2, prect->x + prect->width);
y1 = min(y1, prect->y);
y2 = max(y2, prect->y + prect->height);
}
exaDrawableDirty (pDrawable, pDrawable->x + x1, pDrawable->y + y1,
pDrawable->x + x2, pDrawable->y + y2);
}
} }
void void

File diff suppressed because it is too large Load Diff

View File

@ -82,6 +82,32 @@ void fbCompositeSrc_8888x8888mmx (CARD8 op,
INT16 yDst, INT16 yDst,
CARD16 width, CARD16 width,
CARD16 height); 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, void fbCompositeSolidMask_nx8888x8888Cmmx (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
PicturePtr pMask, PicturePtr pMask,
@ -106,6 +132,42 @@ void fbCompositeSolidMask_nx8x8888mmx (CARD8 op,
INT16 yDst, INT16 yDst,
CARD16 width, CARD16 width,
CARD16 height); 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, void fbCompositeSrcAdd_8000x8000mmx (CARD8 op,
PicturePtr pSrc, PicturePtr pSrc,
PicturePtr pMask, PicturePtr pMask,

File diff suppressed because it is too large Load Diff

View File

@ -121,7 +121,15 @@ fbCanGetSolid(PicturePtr pict)
break; \ break; \
case 16: \ case 16: \
(bits) = READ((CARD16 *) __bits__); \ (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; \ break; \
default: \ default: \
return; \ return; \
@ -153,7 +161,7 @@ fbCanGetSolid(PicturePtr pict)
#define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \ #define cvt8888to0565(s) ((((s) >> 3) & 0x001f) | \
(((s) >> 5) & 0x07e0) | \ (((s) >> 5) & 0x07e0) | \
(((s) >> 8) & 0xf800)) (((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) << 5) & 0xfc00) | (((s) >> 1) & 0x300)) | \
((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000))) ((((s) << 8) & 0xf80000) | (((s) << 3) & 0x70000)))

View File

@ -23,14 +23,20 @@ if KDRIVELINUX
LINUX_SUBDIRS = linux LINUX_SUBDIRS = linux
endif endif
SUBDIRS = \ SERVER_SUBDIRS = \
src \
$(LINUX_SUBDIRS) \
$(XSDL_SUBDIRS) \ $(XSDL_SUBDIRS) \
$(FBDEV_SUBDIRS) \ $(FBDEV_SUBDIRS) \
$(VESA_SUBDIRS) \ $(VESA_SUBDIRS) \
$(XEPHYR_SUBDIRS) \ $(XEPHYR_SUBDIRS) \
$(XFAKE_SUBDIRS) $(XFAKE_SUBDIRS)
SUBDIRS = \
src \
$(LINUX_SUBDIRS) \
$(SERVER_SUBDIRS)
DIST_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \ DIST_SUBDIRS = vesa ati chips epson i810 mach64 mga neomagic nvidia pm2 r128 \
smi via fbdev sdl ephyr src linux fake sis300 smi via fbdev sdl ephyr src linux fake sis300
relink:
@for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done

View File

@ -62,3 +62,6 @@ Xati_LDADD = \
$(ATI_LIBS) \ $(ATI_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -24,3 +24,6 @@ Xchips_LDADD = \
$(CHIPS_LIBS) \ $(CHIPS_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -29,3 +29,6 @@ Xephyr_LDADD = \
../../../exa/libexa.la \ ../../../exa/libexa.la \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XEPHYR_LIBS@ @XEPHYR_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -24,3 +24,6 @@ Xepson_LDADD = \
$(EPSON_LIBS) \ $(EPSON_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -20,3 +20,6 @@ Xfake_LDADD = \
libfake.a \ libfake.a \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -18,4 +18,7 @@ Xfbdev_LDADD = \
libfbdev.a \ libfbdev.a \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
endif endif

View File

@ -27,3 +27,6 @@ Xi810_LDADD = \
$(I810_LIBS) \ $(I810_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -31,3 +31,6 @@ Xmach64_LDADD = \
$(MACH64_LIBS) \ $(MACH64_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -26,3 +26,6 @@ Xmga_LDADD = \
$(MGA_LIBS) \ $(MGA_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -38,3 +38,6 @@ Xneomagic_LDADD = \
$(NEOMAGIC_LIBS) \ $(NEOMAGIC_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -27,3 +27,6 @@ Xnvidia_LDADD = \
$(NVIDIA_LIBS) \ $(NVIDIA_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -25,3 +25,6 @@ Xpm2_LDADD = \
$(PM2_LIBS) \ $(PM2_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -24,3 +24,6 @@ Xr128_LDADD = \
$(R128_LIBS) \ $(R128_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -11,3 +11,6 @@ Xsdl_LDADD = @KDRIVE_PURE_LIBS@ \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ \ @XSERVER_LIBS@ \
@XSDL_LIBS@ @XSDL_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -38,3 +38,6 @@ Xsis_LDADD = \
$(SIS_LIBS) \ $(SIS_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
$(TSLIB_FLAG) $(TSLIB_FLAG)
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -29,3 +29,6 @@ Xsmi_LDADD = \
$(SMI_LIBS) \ $(SMI_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -23,3 +23,6 @@ Xvesa_LDADD = \
libvesa.a \ libvesa.a \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -25,3 +25,6 @@ Xvia_LDADD = \
$(VIA_LIBS) \ $(VIA_LIBS) \
@KDRIVE_LIBS@ \ @KDRIVE_LIBS@ \
@XSERVER_LIBS@ @XSERVER_LIBS@
relink:
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)

View File

@ -764,4 +764,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 */ /* end of xf86Xinput.c */

View File

@ -187,6 +187,8 @@ void xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval,
void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum); void xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum);
void xf86AddEnabledDevice(InputInfoPtr pInfo); void xf86AddEnabledDevice(InputInfoPtr pInfo);
void xf86RemoveEnabledDevice(InputInfoPtr pInfo); void xf86RemoveEnabledDevice(InputInfoPtr pInfo);
void xf86DisableDevice(DeviceIntPtr dev, Bool panic);
void xf86EnableDevice(DeviceIntPtr dev);
/* xf86Helper.c */ /* xf86Helper.c */
void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags); void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags);
@ -204,6 +206,7 @@ int xf86GetMotionEvents(DeviceIntPtr dev, xTimecoord *buff,
void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts, void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
pointer extraOpts); pointer extraOpts);
/* Legacy hatred */ /* Legacy hatred */
#define SendCoreEvents 59 #define SendCoreEvents 59
#define DontSendCoreEvents 60 #define DontSendCoreEvents 60

View File

@ -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;
}
}
}

View File

@ -24,6 +24,9 @@
#define _XF86_RANDR_H_ #define _XF86_RANDR_H_
#include <randrstr.h> #include <randrstr.h>
#include <X11/extensions/render.h> #include <X11/extensions/render.h>
#if XF86_MODES_RENAME
#include "xf86Rename.h"
#endif
Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen); Bool xf86RandR12CreateScreenResources (ScreenPtr pScreen);
Bool xf86RandR12Init(ScreenPtr pScreen); Bool xf86RandR12Init(ScreenPtr pScreen);

View File

@ -232,14 +232,14 @@ _X_EXPORT int pciNumBuses = 0; /* Actual number of PCI buses */
int pciMaxBusNum = MAX_PCI_BUSES; int pciMaxBusNum = MAX_PCI_BUSES;
static Bool inProbe = FALSE; 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, static int readPciBios( PCITAG Tag, CARD8* tmp, ADDRESS hostbase,
unsigned char * buf, int len, PciBiosType BiosType ); unsigned char * buf, int len, PciBiosType BiosType );
static int (*pciOSHandleBIOS)(PCITAG Tag, int basereg, unsigned char *buf, int len); 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. * Platform specific PCI function pointers.
@ -272,6 +272,14 @@ pciInit()
if (pciNumBuses <= 0) if (pciNumBuses <= 0)
ARCH_PCI_OS_INIT(); ARCH_PCI_OS_INIT();
#endif #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)) 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 * result in an endless recursion if platform/OS specific PCI
* bus probing code calls this function from with in it. * bus probing code calls this function from with in it.
*/ */
if (done || pci_devp[0]) if (done || pci_devp)
return pci_devp; return pci_devp;
done = TRUE; done = TRUE;

View File

@ -177,7 +177,7 @@ xglCompositeGeneral (CARD8 op,
{ {
if (!pSrc->transform && pSrc->filter != PictFilterConvolution) if (!pSrc->transform && pSrc->filter != PictFilterConvolution)
{ {
if (pSrc->pDrawable && pSrc->repeat == RepeatNormal) if (pSrc->pDrawable && pSrc->repeatType == RepeatNormal)
{ {
XGL_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable); XGL_PIXMAP_PRIV ((PixmapPtr) pSrc->pDrawable);

View File

@ -30,6 +30,7 @@
#include "gcstruct.h" #include "gcstruct.h"
#include "pixmapstr.h" #include "pixmapstr.h"
#include "cw.h" #include "cw.h"
#include "mi.h"
#define SETUP_BACKING_DST(_pDst, _pGC) \ #define SETUP_BACKING_DST(_pDst, _pGC) \
cwGCPtr pGCPrivate = getCwGC (_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 w, int h, int dstx, int dsty)
{ {
int odstx, odsty; int odstx, odsty;
RegionPtr exposed = NULL; int osrcx, osrcy;
SETUP_BACKING_DST(pDst, pGC); SETUP_BACKING_DST(pDst, pGC);
SETUP_BACKING_SRC(pSrc, pGC); SETUP_BACKING_SRC(pSrc, pGC);
@ -193,19 +194,20 @@ cwCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
odstx = dstx; odstx = dstx;
odsty = dsty; odsty = dsty;
osrcx = srcx;
osrcy = srcy;
CW_OFFSET_XY_DST(dstx, dsty); CW_OFFSET_XY_DST(dstx, dsty);
CW_OFFSET_XY_SRC(srcx, srcy); CW_OFFSET_XY_SRC(srcx, srcy);
exposed = (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst, (*pBackingGC->ops->CopyArea)(pBackingSrc, pBackingDst,
pBackingGC, srcx, srcy, w, h, pBackingGC, srcx, srcy, w, h,
dstx, dsty); dstx, dsty);
if (exposed != NULL)
REGION_TRANSLATE(pDst->pScreen, exposed, odstx - dstx, odsty - dsty);
EPILOGUE(pGC); EPILOGUE(pGC);
return exposed; return miHandleExposures(pSrc, pDst, pGC,
osrcx, osrcy, w, h,
odstx, odsty, 0);
} }
static RegionPtr 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 w, int h, int dstx, int dsty, unsigned long plane)
{ {
int odstx, odsty; int odstx, odsty;
RegionPtr exposed = NULL; int osrcx, osrcy;
SETUP_BACKING_DST(pDst, pGC); SETUP_BACKING_DST(pDst, pGC);
SETUP_BACKING_SRC(pSrc, pGC); SETUP_BACKING_SRC(pSrc, pGC);
@ -221,19 +223,20 @@ cwCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy,
odstx = dstx; odstx = dstx;
odsty = dsty; odsty = dsty;
osrcx = srcx;
osrcy = srcy;
CW_OFFSET_XY_DST(dstx, dsty); CW_OFFSET_XY_DST(dstx, dsty);
CW_OFFSET_XY_SRC(srcx, srcy); CW_OFFSET_XY_SRC(srcx, srcy);
exposed = (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst, (*pBackingGC->ops->CopyPlane)(pBackingSrc, pBackingDst,
pBackingGC, srcx, srcy, w, h, pBackingGC, srcx, srcy, w, h,
dstx, dsty, plane); dstx, dsty, plane);
if (exposed != NULL)
REGION_TRANSLATE(pDst->pScreen, exposed, odstx - dstx, odsty - dsty);
EPILOGUE(pGC); EPILOGUE(pGC);
return exposed; return miHandleExposures(pSrc, pDst, pGC,
osrcx, osrcy, w, h,
odstx, odsty, plane);
} }
static void static void

View File

@ -428,6 +428,14 @@ RRXineramaExtensionInit(void)
return; return;
#endif #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, (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0,
ProcRRXineramaDispatch, ProcRRXineramaDispatch,
SProcRRXineramaDispatch, SProcRRXineramaDispatch,