composite: Add exception mechanism for implicit redirection policy

Normally composite will decide to add implicit redirection when a
window with an alternate visual is a parent of a window with a regular
visual or vice versa.  This uses extra pixmap memory and incurs an extra
copy.  This exception mechanism provides a way for a DDX to override this
if the DDX knows that its acceleration architecture will render correctly.

The relevant case is that of an RGB window reparented into a ARGB parent
frame window.  If the DDX knows that the acceleration architecture in use
will pad the alpha channel to opaque when rendering to the RGB window,
the implicit redirection can be avoided.

This patch adds a new composite function:

  CompositeRegisterImplicitRedirectionException()

which lets a DDX register a pair of parent and child window visuals, that
will not be implicitly redirected even if the normal policy would have
made that choice.

Signed-off-by: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by: Keith Packard <keithp@keithp.com>
This commit is contained in:
Kristian Høgsberg 2014-03-27 22:15:28 -07:00
parent 73698d41e4
commit 4ba7b59446
4 changed files with 53 additions and 0 deletions

View File

@ -229,6 +229,28 @@ CompositeRegisterAlternateVisuals(ScreenPtr pScreen, VisualID * vids,
return compRegisterAlternateVisuals(cs, vids, nVisuals);
}
Bool
CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
VisualID parentVisual,
VisualID winVisual)
{
CompScreenPtr cs = GetCompScreen(pScreen);
CompImplicitRedirectException *p;
p = realloc(cs->implicitRedirectExceptions,
sizeof(p[0]) * (cs->numImplicitRedirectExceptions + 1));
if (p == NULL)
return FALSE;
p[cs->numImplicitRedirectExceptions].parentVisual = parentVisual;
p[cs->numImplicitRedirectExceptions].winVisual = winVisual;
cs->implicitRedirectExceptions = p;
cs->numImplicitRedirectExceptions++;
return TRUE;
}
typedef struct _alternateVisual {
int depth;
CARD32 format;
@ -349,6 +371,8 @@ compScreenInit(ScreenPtr pScreen)
cs->numAlternateVisuals = 0;
cs->alternateVisuals = NULL;
cs->numImplicitRedirectExceptions = 0;
cs->implicitRedirectExceptions = NULL;
if (!compAddAlternateVisuals(pScreen, cs)) {
free(cs);

View File

@ -119,6 +119,11 @@ typedef struct _CompOverlayClientRec {
XID resource;
} CompOverlayClientRec;
typedef struct _CompImplicitRedirectException {
XID parentVisual;
XID winVisual;
} CompImplicitRedirectException;
typedef struct _CompScreen {
PositionWindowProcPtr PositionWindow;
CopyWindowProcPtr CopyWindow;
@ -155,6 +160,8 @@ typedef struct _CompScreen {
CloseScreenProcPtr CloseScreen;
int numAlternateVisuals;
VisualID *alternateVisuals;
int numImplicitRedirectExceptions;
CompImplicitRedirectException *implicitRedirectExceptions;
WindowPtr pOverlayWin;
Window overlayWid;

View File

@ -35,6 +35,10 @@ extern _X_EXPORT Bool CompositeRegisterAlternateVisuals(ScreenPtr pScreen,
VisualID * vids,
int nVisuals);
extern _X_EXPORT Bool CompositeRegisterImplicitRedirectionException(ScreenPtr pScreen,
VisualID parentVisual,
VisualID winVisual);
extern _X_EXPORT RESTYPE CompositeClientWindowType;
#endif /* _COMPOSITEEXT_H_ */

View File

@ -335,6 +335,21 @@ compIsAlternateVisual(ScreenPtr pScreen, XID visual)
return FALSE;
}
static Bool
compIsImplicitRedirectException(ScreenPtr pScreen,
XID parentVisual, XID winVisual)
{
CompScreenPtr cs = GetCompScreen(pScreen);
int i;
for (i = 0; i < cs->numImplicitRedirectExceptions; i++)
if (cs->implicitRedirectExceptions[i].parentVisual == parentVisual &&
cs->implicitRedirectExceptions[i].winVisual == winVisual)
return TRUE;
return FALSE;
}
static Bool
compImplicitRedirect(WindowPtr pWin, WindowPtr pParent)
{
@ -343,6 +358,9 @@ compImplicitRedirect(WindowPtr pWin, WindowPtr pParent)
XID winVisual = wVisual(pWin);
XID parentVisual = wVisual(pParent);
if (compIsImplicitRedirectException(pScreen, parentVisual, winVisual))
return FALSE;
if (winVisual != parentVisual &&
(compIsAlternateVisual(pScreen, winVisual) ||
compIsAlternateVisual(pScreen, parentVisual)))