dix: Call SourceValidate before GetImage

This ensures that any prep work for the drawable we're about to read
from is already done before we call down to GetImage. This should be no
functional change as most of the callers with a non-trivial
SourceValidate are already wrapping GetImage and doing the equivalent
thing, but we'll be simplifying that shortly.

More importantly this ensures that if any of that prep work would
generate events - like automatic compositing flushing rendering to a
parent pixmap which then triggers damage - then it happens entirely
before we start writing the GetImage reply header.

Note that we do not do the same for GetSpans, but that's okay. The only
way to get to GetSpans is through miCopyArea or miCopyPlane - where the
callers must already call SourceValidate - or miGetImage - which this
commit now protects with SourceValidate.

Fixes: xorg/xserver#902
Reviewed-by: Michel Dänzer <mdaenzer@redhat.com>
This commit is contained in:
Adam Jackson 2019-10-09 11:57:18 -04:00 committed by Adam Jackson
parent ff310903f3
commit 516e75dbb6
5 changed files with 29 additions and 1 deletions

View File

@ -1105,6 +1105,10 @@ PanoramiXCopyArea(ClientPtr client)
DixGetAttrAccess);
if (rc != Success)
return rc;
drawables[j]->pScreen->SourceValidate(drawables[j], 0, 0,
drawables[j]->width,
drawables[j]->height,
IncludeInferiors);
}
pitch = PixmapBytePad(width, drawables[0]->depth);
@ -2007,6 +2011,12 @@ PanoramiXGetImage(ClientPtr client)
if (rc != Success)
return rc;
}
FOR_NSCREENS_FORWARD(i) {
drawables[i]->pScreen->SourceValidate(drawables[i], 0, 0,
drawables[i]->width,
drawables[i]->height,
IncludeInferiors);
}
xgi = (xGetImageReply) {
.type = X_Reply,

View File

@ -655,6 +655,9 @@ ProcShmGetImage(ClientPtr client)
visual = wVisual(((WindowPtr) pDraw));
if (pDraw->type == DRAWABLE_WINDOW)
pVisibleRegion = &((WindowPtr) pDraw)->borderClip;
pDraw->pScreen->SourceValidate(pDraw, stuff->x, stuff->y,
stuff->width, stuff->height,
IncludeInferiors);
}
else {
if (stuff->x < 0 ||
@ -863,6 +866,12 @@ ProcPanoramiXShmGetImage(ClientPtr client)
return rc;
}
}
FOR_NSCREENS_FORWARD(i) {
drawables[i]->pScreen->SourceValidate(drawables[i], 0, 0,
drawables[i]->width,
drawables[i]->height,
IncludeInferiors);
}
xgi = (xShmGetImageReply) {
.type = X_Reply,

View File

@ -2210,8 +2210,11 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
return BadAlloc;
WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
if (pDraw->type == DRAWABLE_WINDOW)
if (pDraw->type == DRAWABLE_WINDOW) {
pVisibleRegion = &((WindowPtr) pDraw)->borderClip;
pDraw->pScreen->SourceValidate(pDraw, x, y, width, height,
IncludeInferiors);
}
if (linesPerBuf == 0) {
/* nothing to do */

View File

@ -324,6 +324,7 @@ swrastGetImage(__DRIdrawable * draw,
ScreenPtr pScreen = pDraw->pScreen;
__GLXcontext *cx = lastGLContext;
pScreen->SourceValidate(pDraw, x, y, w, h, IncludeInferiors);
pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
if (cx != lastGLContext) {
lastGLContext = cx;

View File

@ -1492,6 +1492,11 @@ ProcRenderCreateCursor(ClientPtr client)
return BadAlloc;
}
/* what kind of maniac creates a cursor from a window picture though */
if (pSrc->pDrawable->type == DRAWABLE_WINDOW)
pScreen->SourceValidate(pSrc->pDrawable, 0, 0, width, height,
IncludeInferiors);
if (pSrc->format == PICT_a8r8g8b8) {
(*pScreen->GetImage) (pSrc->pDrawable,
0, 0, width, height, ZPixmap,