[PATCH 2/3] Enable off-screen rendering feature for Xephyr
Tiago Vignatti
tiago.vignatti at nokia.com
Fri Sep 24 08:05:03 PDT 2010
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 <haitao.feng at intel.com>
> ---
> 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 (krh at redhat.com)
> + */
> +
> +#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
More information about the xorg-devel
mailing list