summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2004-08-15 03:34:18 +0000
committerKeith Packard <keithp@keithp.com>2004-08-15 03:34:18 +0000
commit1e728c3e88f6a74b93dc11827c9fcfe7b39ca5a5 (patch)
tree3a63ec7b7c0493ac63cd2b3cd4f13d3071f9f304
parent943308517905d16bda1bb27cd745bd291a84dbf6 (diff)
Copy bits from parent window when allocating pixmaps so that Background ==
None works. Copy filter to backing picture during validation. Mark picture serialNumber when setting Filter or Transform so Validate occurs. Initialize xf86Screens[i]->pScreen to NULL so that RADEON driver doesn't crash during server reset using old pScreen.
-rw-r--r--composite/compalloc.c84
-rw-r--r--hw/xfree86/common/xf86Init.c1
-rw-r--r--miext/cw/cw_render.c16
-rw-r--r--render/filter.c1
-rw-r--r--render/picture.c3
5 files changed, 69 insertions, 36 deletions
diff --git a/composite/compalloc.c b/composite/compalloc.c
index 8e2881e85..2e4eeb0c7 100644
--- a/composite/compalloc.c
+++ b/composite/compalloc.c
@@ -418,24 +418,58 @@ compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
return Success;
}
-Bool
-compAllocPixmap (WindowPtr pWin)
+static PixmapPtr
+compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
PixmapPtr pPixmap;
- int bw = (int) pWin->borderWidth;
- int x, y, w, h;
- CompWindowPtr cw = GetCompWindow (pWin);
+ GCPtr pGC;
- x = pWin->drawable.x - bw;
- y = pWin->drawable.y - bw;
- w = pWin->drawable.width + (bw << 1);
- h = pWin->drawable.height + (bw << 1);
pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth);
+
if (!pPixmap)
- return FALSE;
+ return 0;
+
pPixmap->screen_x = x;
pPixmap->screen_y = y;
+
+ pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ /*
+ * Copy bits from the parent into the new pixmap so that it will
+ * have "reasonable" contents in case for background None areas.
+ */
+ if (pGC)
+ {
+ XID val = IncludeInferiors;
+
+ ValidateGC(&pPixmap->drawable, pGC);
+ dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL);
+ (*pGC->ops->CopyArea) (&pParent->drawable,
+ &pPixmap->drawable,
+ pGC,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ w, h, 0, 0);
+ FreeScratchGC (pGC);
+ }
+ return pPixmap;
+}
+
+Bool
+compAllocPixmap (WindowPtr pWin)
+{
+ int bw = (int) pWin->borderWidth;
+ int x = pWin->drawable.x - bw;
+ int y = pWin->drawable.y - bw;
+ int w = pWin->drawable.width + (bw << 1);
+ int h = pWin->drawable.height + (bw << 1);
+ PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (!pPixmap)
+ return FALSE;
pWin->redirectDraw = TRUE;
compSetPixmap (pWin, pPixmap);
cw->oldx = COMP_ORIGIN_INVALID;
@@ -490,42 +524,22 @@ compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
PixmapPtr pNew;
CompWindowPtr cw = GetCompWindow (pWin);
int pix_x, pix_y;
- unsigned int pix_w, pix_h;
+ int pix_w, pix_h;
assert (cw && pWin->redirectDraw);
+ cw->oldx = pOld->screen_x;
+ cw->oldy = pOld->screen_y;
pix_x = draw_x - bw;
pix_y = draw_y - bw;
pix_w = w + (bw << 1);
pix_h = h + (bw << 1);
- cw->oldx = pOld->screen_x;
- cw->oldy = pOld->screen_y;
- if (pix_w != pOld->drawable.width ||
- pix_h != pOld->drawable.height)
+ if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
{
- GCPtr pGC;
-
- pNew = (*pScreen->CreatePixmap) (pScreen, pix_w, pix_h, pWin->drawable.depth);
+ pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
if (!pNew)
return FALSE;
cw->pOldPixmap = pOld;
compSetPixmap (pWin, pNew);
- /*
- * Copy new bits to align at same place on the screen. CopyWindow
- * calls will patch up any differences
- */
- pGC = GetScratchGC (pNew->drawable.depth, pScreen);
- if (pGC)
- {
- ValidateGC(&pNew->drawable, pGC);
- (*pGC->ops->CopyArea) (&pOld->drawable,
- &pNew->drawable,
- pGC,
- pWin->drawable.x - draw_x,
- pWin->drawable.y - draw_y,
- pix_w, pix_h,
- 0, 0);
- FreeScratchGC (pGC);
- }
}
else
{
diff --git a/hw/xfree86/common/xf86Init.c b/hw/xfree86/common/xf86Init.c
index dcb132dbd..9f90c08d8 100644
--- a/hw/xfree86/common/xf86Init.c
+++ b/hw/xfree86/common/xf86Init.c
@@ -905,6 +905,7 @@ InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
xf86Screens[i]->LoadPalette = NULL;
xf86Screens[i]->SetOverscan = NULL;
xf86Screens[i]->RRFunc = NULL;
+ xf86Screens[i]->pScreen = NULL;
scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
if (scr_index == i) {
/*
diff --git a/miext/cw/cw_render.c b/miext/cw/cw_render.c
index 01e2bc468..f7e361496 100644
--- a/miext/cw/cw_render.c
+++ b/miext/cw/cw_render.c
@@ -207,8 +207,22 @@ cwValidatePicture (PicturePtr pPicture,
pBackingPicture = pPicturePrivate->pBackingPicture;
+ /*
+ * Always copy transform and filters because there's no
+ * indication of when they've changed
+ */
SetPictureTransform(pBackingPicture, pPicture->transform);
- /* XXX Set filters */
+
+ if (pBackingPicture->filter != pPicture->filter ||
+ pPicture->filter_nparams > 0)
+ {
+ char *filter = PictureGetFilterName (pPicture->filter);
+
+ SetPictureFilter(pBackingPicture,
+ filter, strlen (filter),
+ pPicture->filter_params,
+ pPicture->filter_nparams);
+ }
pPicturePrivate->stateChanges |= mask;
diff --git a/render/filter.c b/render/filter.c
index 16d01e45d..cb9297e9c 100644
--- a/render/filter.c
+++ b/render/filter.c
@@ -272,5 +272,6 @@ SetPictureFilter (PicturePtr pPicture, char *name, int len, xFixed *params, int
for (i = 0; i < nparams; i++)
pPicture->filter_params[i] = params[i];
pPicture->filter = pFilter->id;
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
return Success;
}
diff --git a/render/picture.c b/render/picture.c
index e6c1a89a4..b0c44e694 100644
--- a/render/picture.c
+++ b/render/picture.c
@@ -1177,6 +1177,8 @@ SetPictureTransform (PicturePtr pPicture,
pPicture->transform = 0;
}
}
+ pPicture->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
return Success;
}
@@ -1188,6 +1190,7 @@ CopyPicture (PicturePtr pSrc,
PictureScreenPtr ps = GetPictureScreen(pSrc->pDrawable->pScreen);
Mask origMask = mask;
+ pDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
pDst->stateChanges |= mask;
while (mask) {