On Tue, Sep 21, 2010 at 07:51:21AM +0200, ext Feng, Haitao wrote: > Hi, > > This patch will enable off-screen rendering feature for Xephyr. > > Basically on Xephyr host side, I use XCompositeRedirect to do the off-screen > rendering after creating a host peer window. And when glSwapBuffer happens in > Xephyr clients, I will copy the host peer window contents into Xephyr and > register a damage to let the Xephyr clients redraw the content. > > This feature could be disabled by -noosr. > > Thanks > -Haitao > > Signed-off-by: Haitao Feng <[email protected]> > --- > configure.ac | 3 ++ > hw/kdrive/ephyr/dri2.h | 10 +------ > hw/kdrive/ephyr/dri2buffer.h | 45 ++++++++++++++++++++++++++++++ > hw/kdrive/ephyr/ephyr.c | 45 ++++++++++++++++++++++++++++++ > hw/kdrive/ephyr/ephyrdri2.c | 1 + > hw/kdrive/ephyr/ephyrdri2.h | 3 +- > hw/kdrive/ephyr/ephyrdri2ext.c | 38 +++++++++++++++++++++++-- > hw/kdrive/ephyr/ephyrdri2ext.h | 10 ++++++ > hw/kdrive/ephyr/ephyrinit.c | 8 +++++ > hw/kdrive/ephyr/hostx.c | 60 > +++++++++++++++++++++++++++++++++++++++- > hw/kdrive/ephyr/hostx.h | 7 ++++ > 11 files changed, 216 insertions(+), 14 deletions(-) > create mode 100644 hw/kdrive/ephyr/dri2buffer.h > > diff --git a/configure.ac b/configure.ac > index 95f7a76..daea4e0 100644 > --- a/configure.ac > +++ b/configure.ac > @@ -2069,6 +2069,9 @@ if test "$KDRIVE" = yes; then > if test "x$DRI" = xyes && test "x$GLX" = xyes; then > XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL libdrm" > fi > + if test "x$DRI2" = xyes && test "x$GLX" = xyes; then > + XEPHYR_REQUIRED_LIBS="$XEPHYR_REQUIRED_LIBS $LIBGL xcomposite" > + fi > > PKG_CHECK_MODULES(XEPHYR, $XEPHYR_REQUIRED_LIBS, [xephyr="yes"], > [xephyr="no"]) > if test "x$XEPHYR" = xauto; then > diff --git a/hw/kdrive/ephyr/dri2.h b/hw/kdrive/ephyr/dri2.h > index 9db77f4..1d32cad 100644 > --- a/hw/kdrive/ephyr/dri2.h > +++ b/hw/kdrive/ephyr/dri2.h > @@ -36,15 +36,7 @@ > #include <X11/extensions/Xfixes.h> > #include <X11/extensions/dri2tokens.h> > #include <xf86drm.h> > - > -typedef struct > -{ > - unsigned int attachment; > - unsigned int name; > - unsigned int pitch; > - unsigned int cpp; > - unsigned int flags; > -} DRI2Buffer; > +#include "dri2buffer.h" > > extern Bool > DRI2QueryExtension(Display * display, int *eventBase, int *errorBase); > diff --git a/hw/kdrive/ephyr/dri2buffer.h b/hw/kdrive/ephyr/dri2buffer.h > new file mode 100644 > index 0000000..ab219c2 > --- /dev/null > +++ b/hw/kdrive/ephyr/dri2buffer.h > @@ -0,0 +1,45 @@ > +/* > + * Copyright © 2007,2008 Red Hat, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Soft- > + * ware"), to deal in the Software without restriction, including without > + * limitation the rights to use, copy, modify, merge, publish, distribute, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, provided that the above copyright > + * notice(s) and this permission notice appear in all copies of the Soft- > + * ware and that both the above copyright notice(s) and this permission > + * notice appear in supporting documentation. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS > + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL- > + * ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY > + * RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN > + * THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSE- > + * QUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, > + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER > + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFOR- > + * MANCE OF THIS SOFTWARE. > + * > + * Except as contained in this notice, the name of a copyright holder shall > + * not be used in advertising or otherwise to promote the sale, use or > + * other dealings in this Software without prior written authorization of > + * the copyright holder. > + * > + * Authors: > + * Kristian Høgsberg ([email protected]) > + */ > + > +#ifndef _DRI2BUFFER_H_ > +#define _DRI2BUFFER_H_ > + > +typedef struct > +{ > + unsigned int attachment; > + unsigned int name; > + unsigned int pitch; > + unsigned int cpp; > + unsigned int flags; > +} DRI2Buffer; > + > +#endif > diff --git a/hw/kdrive/ephyr/ephyr.c b/hw/kdrive/ephyr/ephyr.c > index e4252ee..47bd82d 100644 > --- a/hw/kdrive/ephyr/ephyr.c > +++ b/hw/kdrive/ephyr/ephyr.c > @@ -55,6 +55,7 @@ KdPointerInfo *ephyrMouse; > EphyrKeySyms ephyrKeySyms; > Bool ephyrNoDRI=FALSE ; > Bool ephyrNoDRI2=FALSE ; > +Bool ephyrNoOSR=FALSE ; > Bool ephyrNoXV=FALSE ; > > static int mouseState = 0; > @@ -663,6 +664,7 @@ ephyrInitScreen (ScreenPtr pScreen) > if (!ephyrNoDRI) { > ephyrDRIExtensionInit (pScreen) ; > ephyrHijackGLXExtension () ; > + ephyrNoOSR = TRUE ; > } > #endif > > @@ -675,6 +677,9 @@ ephyrInitScreen (ScreenPtr pScreen) > if (ephyrNoDRI && !ephyrNoDRI2) { > ephyrDRI2ExtensionInit (pScreen) ; > ephyrHijackGLXExtension () ; > + if (!ephyrNoOSR && !hostx_has_composite ()) { > + ephyrNoOSR = TRUE ; > + } > } > #endif > > @@ -900,6 +905,46 @@ ephyrExposePairedWindow (int a_remote) > } > #endif /* XF86DRI */ > > +#ifdef OFFSCREEN_RENDERING > +void > +ephyrPaintPairedLocalWindow (int a_remote, int depth, char *data, int sx, > int sy, int width, int height) > +{ > + EphyrDRI2WindowPair *pair = NULL; > + RegionRec reg; > + ScreenPtr screen; > + GCPtr pGC; > + XID gcval = FALSE; > + int status; > + > + if (!findDRI2WindowPairFromRemote (a_remote, &pair)) { > + EPHYR_LOG ("did not find a pair for this window\n"); > + return; > + } > + > + screen = pair->local->drawable.pScreen; > + > + pGC = pair->gc; > + if (!pGC) { > + pGC = CreateGC((DrawablePtr)pair->local, > + GCGraphicsExposures, &gcval, > + &status, (XID)0, serverClient); > + pair->gc = pGC; > + } > + if (pGC) { > + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); > + pPriv->pm = FB_ALLONES; > + > + REGION_NULL (screen, ®); > + REGION_COPY (screen, ®, &pair->local->clipList); > + pGC->pCompositeClip = ® > + pGC->ops->PutImage((DrawablePtr)pair->local, pGC, depth, 0, 0, > width, height, 0, ZPixmap, data); > + DamageRegionAppend((DrawablePtr)pair->local, ®); > + DamageRegionProcessPending((DrawablePtr)pair->local); > + REGION_UNINIT (screen, ®); > + } > +} > +#endif > + > void > ephyrPoll(void) > { > diff --git a/hw/kdrive/ephyr/ephyrdri2.c b/hw/kdrive/ephyr/ephyrdri2.c > index c8508b9..ec0ec75 100644 > --- a/hw/kdrive/ephyr/ephyrdri2.c > +++ b/hw/kdrive/ephyr/ephyrdri2.c > @@ -39,6 +39,7 @@ > #include "ephyrlog.h" > #include "dixstruct.h" > #include "pixmapstr.h" > +#include "dri2.h" > #include "ephyrdri2.h" > > #ifndef TRUE > diff --git a/hw/kdrive/ephyr/ephyrdri2.h b/hw/kdrive/ephyr/ephyrdri2.h > index 7132261..50419cc 100644 > --- a/hw/kdrive/ephyr/ephyrdri2.h > +++ b/hw/kdrive/ephyr/ephyrdri2.h > @@ -30,7 +30,8 @@ > #define __EPHYRDRI2_H__ > > #include <X11/extensions/dri2tokens.h> > -#include "dri2.h" > +#include <xf86drm.h> > +#include "dri2buffer.h" > #include "ephyrdri2ext.h" > > void ephyrDRI2CloseScreen(ScreenPtr pScreen); > diff --git a/hw/kdrive/ephyr/ephyrdri2ext.c b/hw/kdrive/ephyr/ephyrdri2ext.c > index cb1ae16..2d61808 100644 > --- a/hw/kdrive/ephyr/ephyrdri2ext.c > +++ b/hw/kdrive/ephyr/ephyrdri2ext.c > @@ -55,14 +55,15 @@ > #include "ephyrlog.h" > > #include "ephyrdri2ext.h" > +#include "gcstruct.h" > > #include <X11/extensions/dri2proto.h> > #include "ephyrdri2.h" > -#include <X11/extensions/xfixeswire.h> > -#include <X11/Xlib.h> > > +extern Bool ephyrNoOSR; > extern RESTYPE RegionResType; > extern int XFixesErrorBase; > + > #define VERIFY_REGION(pRegion, rid, client, mode) \ > do { \ > int err; \ > @@ -271,6 +272,7 @@ ephyrDRI2DestroyWindow (WindowPtr a_win) > Bool is_ok=FALSE ; > ScreenPtr screen=NULL ; > EphyrDRI2ScreenPrivPtr screen_priv =NULL; > + EphyrDRI2WindowPrivPtr win_priv; > > EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ; > screen = a_win->drawable.pScreen ; > @@ -280,6 +282,22 @@ ephyrDRI2DestroyWindow (WindowPtr a_win) > && screen_priv->DestroyWindow, > FALSE) ; > > +#ifdef OFFSCREEN_RENDERING > + if (!ephyrNoOSR) { > + win_priv=GET_EPHYR_DRI2_WINDOW_PRIV (a_win) ; > + if (win_priv) { > + EphyrDRI2WindowPair *pair=NULL ; > + findWindowPairFromLocal (a_win, &pair); > + if (pair) { > + GCPtr pGC = pair->gc; > + if (pGC){ > + (*pGC->funcs->DestroyGC)(pGC); > + } > + } > + } > + } > +#endif > + > screen->DestroyWindow = screen_priv->DestroyWindow ; > if (screen->DestroyWindow) { > is_ok = (*screen->DestroyWindow) (a_win) ; > @@ -287,7 +305,7 @@ ephyrDRI2DestroyWindow (WindowPtr a_win) > screen->DestroyWindow = ephyrDRI2DestroyWindow ; > > if (is_ok) { > - EphyrDRI2WindowPrivPtr win_priv=GET_EPHYR_DRI2_WINDOW_PRIV (a_win) ; > + win_priv=GET_EPHYR_DRI2_WINDOW_PRIV (a_win) ; > if (win_priv) { > destroyHostPeerWindow (a_win) ; > free (win_priv) ; > @@ -682,6 +700,9 @@ appendWindowPairToList (WindowPtr a_local, > if (window_pairs[i].local == NULL) { > window_pairs[i].local = a_local ; > window_pairs[i].remote = a_remote ; > +#ifdef OFFSCREEN_RENDERING > + window_pairs[i].gc = 0; > +#endif > return TRUE ; > } > } > @@ -792,6 +813,9 @@ destroyHostPeerWindow (const WindowPtr a_win) > hostx_destroy_window (pair->remote) ; > pair->local = NULL; > pair->remote = 0; > +#ifdef OFFSCREEN_RENDERING > + pair->gc = 0; > +#endif > is_ok = TRUE ; > > out: > @@ -1117,6 +1141,14 @@ ProcDRI2CopyRegion(ClientPtr client) > if (status != Success) > return status; > > +#ifdef OFFSCREEN_RENDERING > + if (!ephyrNoOSR) { > + int width = pRegion->extents.x2 - pRegion->extents.x1; > + int height = pRegion->extents.y2 - pRegion->extents.y1; > + hostx_copy_region(stuff->drawable, pair->remote, width, height, > pDrawable->x, pDrawable->y); > + } > +#endif > + > /* CopyRegion needs to be a round trip to make sure the X server > * queues the swap buffer rendering commands before the DRI client > * continues rendering. The reply has a bitmask to signal the > diff --git a/hw/kdrive/ephyr/ephyrdri2ext.h b/hw/kdrive/ephyr/ephyrdri2ext.h > index b0b5ea9..154e3c8 100644 > --- a/hw/kdrive/ephyr/ephyrdri2ext.h > +++ b/hw/kdrive/ephyr/ephyrdri2ext.h > @@ -29,15 +29,25 @@ > #ifndef __EPHYRDRI2EXT_H__ > #define __EPHYRDRI2EXT_H__ > > +#define OFFSCREEN_RENDERING 1
I think you can remove all references to this macro in the patch. Also, the same argument that I gave for the patch #3 maybe is valid in this patch: is there a real reason to not fallback silently to software when off-screen rendering is not possible? Who would want to not execute with off-screen just for fun? :) Tiago _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
