From 704bf42673200da900f0069d6bb136c5cc15fe67 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Jan 07 2010 02:14:19 +0000 Subject: Update to 1.7.3. Copied F-12 spec file to here, so the F-12 patch history is maintained. --- diff --git a/.cvsignore b/.cvsignore index 572311c..433f6b4 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -xorg-server-1.6.99.903.tar.bz2 +xorg-server-1.7.3.tar.bz2 diff --git a/sources b/sources index efc397f..566b478 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -3a2f20ebbeeae5c13f7a78df314b1164 xorg-server-1.6.99.903.tar.bz2 +4c63b22cad9ed8ae8b86561f0f92c327 xorg-server-1.7.3.tar.bz2 diff --git a/xorg-x11-server.spec b/xorg-x11-server.spec index 5fd67e0..fa2d869 100644 --- a/xorg-x11-server.spec +++ b/xorg-x11-server.spec @@ -18,8 +18,8 @@ Summary: X.Org X11 X server Name: xorg-x11-server -Version: 1.6.99.903 -Release: 2%{dist} +Version: 1.7.3 +Release: 7%{dist} URL: http://www.x.org License: MIT Group: User Interface/X @@ -72,6 +72,17 @@ Patch6028: xserver-1.6.99-randr-error-debugging.patch Patch6030: xserver-1.6.99-right-of.patch Patch6033: xserver-1.6.99-default-modes.patch Patch6044: xserver-1.6.99-hush-prerelease-warning.patch +Patch6045: xserver-1.7.0-randr-gamma-restore.patch + +Patch6047: xserver-1.7.0-glx-versioning.patch +#Patch6048: xserver-1.7.0-exa-fix-mixed.patch +Patch6049: xserver-1.7.1-multilib.patch +Patch6051: xserver-1.7.1-gamma-kdm-fix.patch +Patch6052: xserver-1.7.1-libcrypto.patch +Patch6066: xserver-1.7.1-glx14-swrast.patch + +Patch6067: xserver-1.7.3-exa-master.patch +Patch6068: xserver-1.7.3-fb-backport.patch %define moduledir %{_libdir}/xorg/modules %define drimoduledir %{_libdir}/dri @@ -111,7 +122,6 @@ BuildRequires: libXi-devel libXpm-devel libXaw-devel libXfixes-devel # Broken, this is global, should be Xephyr-only BuildRequires: libXv-devel -# openssl? really? BuildRequires: pixman-devel >= 0.15.14 BuildRequires: libpciaccess-devel >= 0.10.6-1 openssl-devel byacc flex BuildRequires: mesa-libGL-devel >= 7.6-0.6 @@ -315,7 +325,7 @@ git am -p1 %{lua: for i, p in ipairs(patches) do print(p.." ") end} %endif %if 0%{?fedora} -%define bodhi_flags --with-vendor-web="http://bodhi.fedoraproject.org/" +%define bodhi_flags --with-vendor-web="http://bodhi.fedoraproject.org/" --with-vendor-name="Fedora Project" %endif # --with-pie ? @@ -335,7 +345,7 @@ export CFLAGS="${RPM_OPT_FLAGS} -Wstrict-overflow -rdynamic $CFLAGS" %{dri_flags} %{?bodhi_flags} \ ${CONFIGURE} -make %{?_smp_mflags} +make V=1 %{?_smp_mflags} %install rm -rf $RPM_BUILD_ROOT @@ -358,6 +368,7 @@ install -m 644 %{SOURCE10} $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/xserver %define inst_srcdir %{buildroot}/%{xserver_source_dir} mkdir -p %{inst_srcdir}/{Xext,xkb,GL,hw/{xquartz/bundle,xfree86/common}} cp cpprules.in %{inst_srcdir} +cp shave*in %{inst_srcdir} cp {,%{inst_srcdir}/}hw/xquartz/bundle/cpprules.in cp xkb/README.compiled %{inst_srcdir}/xkb cp hw/xfree86/xorgconf.cpp %{inst_srcdir}/hw/xfree86 @@ -500,8 +511,96 @@ rm -rf $RPM_BUILD_ROOT %{xserver_source_dir} %changelog -* Wed Jan 06 2010 Peter Hutterer 1.6.99.903-2 -- Require xkeyboard-config, not the obsolete xkbdata. +* Tue Jan 05 2010 Peter Hutterer 1.7.3-7 +- Require xkeyboard-config, not xkbdata. xkbdata has been replaced by + xkeyboard-config. + +* Mon Jan 04 2010 Adam Jackson 1.7.3-6 +- Build with V=1 for debugging. + +* Mon Dec 21 2009 Adam Tkac 1.7.3-5 +- ship shave.in and shave-libtool.in in the -source subpackage + +* Mon Dec 21 2009 Dave Airlie 1.7.3-4 +- Backport FB changes from master. + +* Wed Dec 17 2009 Dave Airlie 1.7.3-3 +- backport EXA fixes from master, should fix xfig crashes X server + +* Mon Dec 14 2009 Adam Jackson 1.7.3-2 +- xserver-1.7.1-sigaction.patch: Drop, exacerbates a race that leads to weird + behaviour like spontaneously repeating keys. + +* Tue Dec 08 2009 Peter Hutterer 1.7.3-1 +- xserver 1.7.3 +- xserver-1.7.1-stat-sanity.patch: Drop, merged upstream. +- xserver-1.7.1-window-pictures.patch: Drop, code it bases on reverted + upstream +- xserver-1.7.1-window-picture-performance-regression.patch: Drop, code it + bases on reverted upstream. + +* Tue Nov 24 2009 Adam Jackson 1.7.1-12 +- xserver-1.7.1-glx14-swrast.patch: Enable GLX 1.4 for software GLX. + +* Tue Nov 24 2009 Adam Jackson 1.7.1-11 +- xserver-1.7.1-window-picture-performance-regression.patch: Paper over a + performance regression caused by the window picture fixes. + +* Mon Nov 23 2009 Adam Jackson 1.7.1-10 +- Fix crash message output. (#539401) + +* Fri Nov 20 2009 Peter Hutterer 1.7.1-9 +- xserver-1.7.1-stat-sanity.patch: stat directories that actually exist + (possibly #537737). + +* Mon Nov 16 2009 Adam Jackson 1.7.1-8 +- xserver-1.7.1-libcrypto.patch: Avoid linking against libssl, which is huge + and drags in dependent libs we don't care about. +- xserver-1.7.1-sigaction.patch: Microoptimization to SIGIO handling. + +* Fri Nov 06 2009 Adam Jackson +- Fix the previous changelog entry to name the right patch + +* Fri Nov 06 2009 Dave Airlie 1.7.1-7 +- xserver-1.7.1-window-pictures.patch: remove the miClearDrawable (fingers crossed) (#533236) +- xserver-1.7.1-gamma-kdm-fix.patch: fix KDM vt gamma (#533217) + +* Wed Nov 04 2009 Adam Jackson 1.7.1-6 +- xserver-1.7.1-multilib.patch: Keep defining _XSERVER64, it's needed in + some of the shared client/server headers. + +* Wed Nov 4 2009 Soren Sandmann 1.7.1-5 +- Update xserver-1.7.1-window-pictures.patch. Instead of calling + GetImage(), simply call fb* functions rather than the screen + hooks. (#524244) + +* Tue Nov 3 2009 Adam Jackson 1.7.1-3 +- xserver-1.7.1-window-pictures.patch: Fix Render from Pictures backed by + Windows to not crash in the presence of KMS. (#524244) + +* Thu Oct 29 2009 Adam Jackson 1.7.1-2 +- xserver-1.7.1-multilib.patch: Fix silly multilib issue. (#470885) + +* Mon Oct 26 2009 Adam Jackson 1.7.1-1 +- xserver 1.7.1 + +* Sat Oct 24 2009 Ben Skeggs 1.7.0-5 +- Fix unbalancing of Prepare/FinishAccess in EXA mixed pixmaps (rh#528005) + +* Fri Oct 16 2009 Dave Airlie 1.7.0-4 +- update GLX for 1.4 version reporting + +* Fri Oct 09 2009 Ben Skeggs 1.7.0-3 +- xserver-1.7.0-exa-looping-forever-is-evil.patch: Fix rendercheck hang + +* Thu Oct 08 2009 Adam Jackson 1.7.0-2 +- xserver-1.7.0-randr-gamma-restore.patch: Restore CRTC gamma on EnterVT. + +* Mon Oct 05 2009 Dave Airlie 1.7.0-1 +- rebase to 1.7.0 upstream release - were 99% this already + +* Thu Oct 01 2009 Dave Airlie 1.6.99.903-2 +- backport EXA and rotate crash fixes * Mon Sep 28 2009 Peter Hutterer 1.6.99.903-1 - xserver 1.6.99.903 diff --git a/xserver-1.7.0-glx-versioning.patch b/xserver-1.7.0-glx-versioning.patch new file mode 100644 index 0000000..c8a1c30 --- /dev/null +++ b/xserver-1.7.0-glx-versioning.patch @@ -0,0 +1,233 @@ +From 3ef4be8129f78afd5566a9e5d0fb901449dcb771 Mon Sep 17 00:00:00 2001 +From: Ian Romanick +Date: Tue, 29 Sep 2009 16:43:43 -0700 +Subject: [PATCH] GLX: Enable GLX 1.4 on DRI2 + +this squashes 4 commits +(cherry picked from commit ad5c0d9efa47476ed5cf75c82265c73919e468b4) +(cherry picked from commit cb54cf1b3e8c4109541cfb698542c00f2473e731) +(cherry picked from commit 4c6bfa2c09ae2b0cffdf9211a6dfbcaefe0366b5) +(cherry picked from commit 9bf2ff4faf730913de3073f346646a8727be41d4) +--- + glx/glxcmds.c | 12 ++++++++---- + glx/glxdri2.c | 12 ++++++++++++ + glx/glxext.c | 8 +++++++- + glx/glxscreens.c | 15 ++++++++++++--- + glx/glxscreens.h | 11 +++++++++++ + glx/glxserver.h | 3 +++ + glx/indirect_texture_compression.c | 4 ++-- + include/protocol-versions.h | 2 +- + 8 files changed, 56 insertions(+), 11 deletions(-) + +diff --git a/glx/glxcmds.c b/glx/glxcmds.c +index b1061a8..ba4c123 100644 +--- a/glx/glxcmds.c ++++ b/glx/glxcmds.c +@@ -50,7 +50,6 @@ + #include "indirect_dispatch.h" + #include "indirect_table.h" + #include "indirect_util.h" +-#include "protocol-versions.h" + + static int + validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) +@@ -739,8 +738,8 @@ int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc) + ** client if it wants to work with older clients; however, in this + ** implementation the server just returns its version number. + */ +- reply.majorVersion = SERVER_GLX_MAJOR_VERSION; +- reply.minorVersion = SERVER_GLX_MINOR_VERSION; ++ reply.majorVersion = glxMajorVersion; ++ reply.minorVersion = glxMinorVersion; + reply.length = 0; + reply.type = X_Reply; + reply.sequenceNumber = client->sequence; +@@ -2360,6 +2359,7 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) + char *buf; + __GLXscreen *pGlxScreen; + int err; ++ char ver_str[16]; + + if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) + return err; +@@ -2369,7 +2369,11 @@ int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) + ptr = pGlxScreen->GLXvendor; + break; + case GLX_VERSION: +- ptr = pGlxScreen->GLXversion; ++ /* Return to the server version rather than the screen version ++ * to prevent confusion when they do not match. ++ */ ++ snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion); ++ ptr = ver_str; + break; + case GLX_EXTENSIONS: + ptr = pGlxScreen->GLXextensions; +diff --git a/glx/glxdri2.c b/glx/glxdri2.c +index ed7fb4c..ed7dc80 100644 +--- a/glx/glxdri2.c ++++ b/glx/glxdri2.c +@@ -685,6 +685,18 @@ __glXDRIscreenProbe(ScreenPtr pScreen) + screen->base.GLXextensions); + } + ++ /* We're going to assume (perhaps incorrectly?) that all DRI2-enabled ++ * drivers support the required extensions for GLX 1.4. The extensions ++ * we're assuming are: ++ * ++ * - GLX_SGI_make_current_read (1.3) ++ * - GLX_SGIX_fbconfig (1.3) ++ * - GLX_SGIX_pbuffer (1.3) ++ * - GLX_ARB_multisample (1.4) ++ */ ++ screen->base.GLXmajor = 1; ++ screen->base.GLXminor = 4; ++ + screen->enterVT = pScrn->EnterVT; + pScrn->EnterVT = glxDRIEnterVT; + screen->leaveVT = pScrn->LeaveVT; +diff --git a/glx/glxext.c b/glx/glxext.c +index 19d70d4..9f9c0ed 100644 +--- a/glx/glxext.c ++++ b/glx/glxext.c +@@ -360,12 +360,18 @@ void GlxExtensionInit(void) + pScreen = screenInfo.screens[i]; + + for (p = __glXProviderStack; p != NULL; p = p->next) { +- if (p->screenProbe(pScreen) != NULL) { ++ __GLXscreen *glxScreen; ++ ++ glxScreen = p->screenProbe(pScreen); ++ if (glxScreen != NULL) { ++ if (glxScreen->GLXminor < glxMinorVersion) ++ glxMinorVersion = glxScreen->GLXminor; + LogMessage(X_INFO, + "GLX: Initialized %s GL provider for screen %d\n", + p->name, i); + break; + } ++ + } + + if (!p) +diff --git a/glx/glxscreens.c b/glx/glxscreens.c +index 7d29d31..674e2c6 100644 +--- a/glx/glxscreens.c ++++ b/glx/glxscreens.c +@@ -42,6 +42,7 @@ + #include "glxserver.h" + #include "glxutil.h" + #include "glxext.h" ++#include "protocol-versions.h" + + static int glxScreenPrivateKeyIndex; + static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKeyIndex; +@@ -162,7 +163,8 @@ static const char GLServerExtensions[] = + ** supported across all screens in a multi-screen system. + */ + static char GLXServerVendorName[] = "SGI"; +-static char GLXServerVersion[] = "1.2"; ++unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION; ++unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION; + static char GLXServerExtensions[] = + "GLX_ARB_multisample " + "GLX_EXT_visual_info " +@@ -378,9 +380,17 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) + pGlxScreen->pScreen = pScreen; + pGlxScreen->GLextensions = xstrdup(GLServerExtensions); + pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); +- pGlxScreen->GLXversion = xstrdup(GLXServerVersion); + pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); + ++ /* All GLX providers must support all of the functionality required for at ++ * least GLX 1.2. If the provider supports a higher version, the GLXminor ++ * version can be changed in the provider's screen-probe routine. For ++ * most providers, the screen-probe routine is the caller of this ++ * function. ++ */ ++ pGlxScreen->GLXmajor = 1; ++ pGlxScreen->GLXminor = 2; ++ + pGlxScreen->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = glxCloseScreen; + pGlxScreen->DestroyWindow = pScreen->DestroyWindow; +@@ -454,7 +464,6 @@ void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) + void __glXScreenDestroy(__GLXscreen *screen) + { + xfree(screen->GLXvendor); +- xfree(screen->GLXversion); + xfree(screen->GLXextensions); + xfree(screen->GLextensions); + } +diff --git a/glx/glxscreens.h b/glx/glxscreens.h +index 3c1bdd4..bff4363 100644 +--- a/glx/glxscreens.h ++++ b/glx/glxscreens.h +@@ -161,6 +161,17 @@ struct __GLXscreen { + char *GLXversion; + char *GLXextensions; + ++ /** ++ * \name GLX version supported by this screen. ++ * ++ * Since the GLX version advertised by the server is for the whole server, ++ * the GLX protocol code uses the minimum version supported on all screens. ++ */ ++ /*@{*/ ++ unsigned GLXmajor; ++ unsigned GLXminor; ++ /*@}*/ ++ + Bool (*CloseScreen)(int index, ScreenPtr pScreen); + Bool (*DestroyWindow)(WindowPtr pWindow); + }; +diff --git a/glx/glxserver.h b/glx/glxserver.h +index 4aa8c2e..80f1b28 100644 +--- a/glx/glxserver.h ++++ b/glx/glxserver.h +@@ -248,4 +248,7 @@ extern int __glXImageSize(GLenum format, GLenum type, + GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows, + GLint alignment); + ++extern unsigned glxMajorVersion; ++extern unsigned glxMinorVersion; ++ + #endif /* !__GLX_server_h__ */ +diff --git a/glx/indirect_texture_compression.c b/glx/indirect_texture_compression.c +index 25c6eb3..5f44d7b 100644 +--- a/glx/indirect_texture_compression.c ++++ b/glx/indirect_texture_compression.c +@@ -52,7 +52,7 @@ int __glXDisp_GetCompressedTexImageARB(struct __GLXclientStateRec *cl, GLbyte *p + const GLenum target = *(GLenum *)(pc + 0); + const GLint level = *(GLint *)(pc + 4); + GLint compsize = 0; +- char *answer, answerBuffer[200]; ++ char *answer = NULL, answerBuffer[200]; + + CALL_GetTexLevelParameteriv(GET_DISPATCH(), (target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compsize)); + +@@ -92,7 +92,7 @@ int __glXDispSwap_GetCompressedTexImageARB(struct __GLXclientStateRec *cl, GLbyt + const GLenum target = (GLenum) bswap_32( *(int *)(pc + 0) ); + const GLint level = (GLint ) bswap_32( *(int *)(pc + 4) ); + GLint compsize = 0; +- char *answer, answerBuffer[200]; ++ char *answer = NULL, answerBuffer[200]; + + CALL_GetTexLevelParameteriv(GET_DISPATCH(), (target, level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &compsize)); + +diff --git a/include/protocol-versions.h b/include/protocol-versions.h +index da9770c..d688c66 100644 +--- a/include/protocol-versions.h ++++ b/include/protocol-versions.h +@@ -61,7 +61,7 @@ + + /* GLX */ + #define SERVER_GLX_MAJOR_VERSION 1 +-#define SERVER_GLX_MINOR_VERSION 2 ++#define SERVER_GLX_MINOR_VERSION 4 + + /* Xinerama */ + #define SERVER_PANORAMIX_MAJOR_VERSION 1 +-- +1.6.5.rc2 + diff --git a/xserver-1.7.0-randr-gamma-restore.patch b/xserver-1.7.0-randr-gamma-restore.patch new file mode 100644 index 0000000..81e025f --- /dev/null +++ b/xserver-1.7.0-randr-gamma-restore.patch @@ -0,0 +1,65 @@ +From 18d2bd8cb513a0436739916620532247f13dbf03 Mon Sep 17 00:00:00 2001 +From: Fedora X Ninjas +Date: Thu, 8 Oct 2009 15:25:24 -0400 +Subject: [PATCH] randr gamma reload hack + +--- + hw/xfree86/loader/sdksyms.c | 4 ++++ + hw/xfree86/modes/xf86RandR12.c | 6 ++++++ + 2 files changed, 10 insertions(+), 0 deletions(-) + +diff --git a/hw/xfree86/loader/sdksyms.c b/hw/xfree86/loader/sdksyms.c +index 12af6b7..656d07b 100644 +--- a/hw/xfree86/loader/sdksyms.c ++++ b/hw/xfree86/loader/sdksyms.c +@@ -1056,6 +1056,8 @@ _X_HIDDEN void *xorg_symbols[] = { + (void *) &noXFree86VidModeExtension, + (void *) &noXFixesExtension, + (void *) &noPanoramiXExtension, ++ (void *) &noSELinuxExtension, ++ (void *) &selinuxEnforcingState, + (void *) &noXvExtension, + (void *) &noDRI2Extension, + (void *) &defaultTextFont, +@@ -1069,6 +1071,7 @@ _X_HIDDEN void *xorg_symbols[] = { + (void *) &defaultScreenSaverBlanking, + (void *) &defaultScreenSaverAllowExposures, + (void *) &display, ++ (void *) &displayfd, + (void *) &defaultBackingStore, + (void *) &disableBackingStore, + (void *) &enableBackingStore, +@@ -1078,6 +1081,7 @@ _X_HIDDEN void *xorg_symbols[] = { + (void *) &maxBigRequestSize, + (void *) &party_like_its_1989, + (void *) &whiteRoot, ++ (void *) &bgNoneRoot, + (void *) &CoreDump, + (void *) &DontPropagateMasks, + (void *) &screenIsSaved, +diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c +index 6ea9d26..41bac11 100644 +--- a/hw/xfree86/modes/xf86RandR12.c ++++ b/hw/xfree86/modes/xf86RandR12.c +@@ -1746,12 +1746,18 @@ xf86RandR12EnterVT (int screen_index, int flags) + { + ScreenPtr pScreen = screenInfo.screens[screen_index]; + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); ++ rrScrPrivPtr rp = rrGetScrPriv(pScreen); + + if (randrp->orig_EnterVT) { + if (!randrp->orig_EnterVT (screen_index, flags)) + return FALSE; + } + ++ /* reload gamma */ ++ int i; ++ for (i = 0; i < rp->numCrtcs; i++) ++ xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]); ++ + return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */ + } + +-- +1.6.5.rc2 + diff --git a/xserver-1.7.1-gamma-kdm-fix.patch b/xserver-1.7.1-gamma-kdm-fix.patch new file mode 100644 index 0000000..c62837e --- /dev/null +++ b/xserver-1.7.1-gamma-kdm-fix.patch @@ -0,0 +1,34 @@ +From acc64ce5be7383c09e88a23aab06ebc2403f2ca3 Mon Sep 17 00:00:00 2001 +From: Bill Nottingham +Date: Fri, 6 Nov 2009 10:32:27 +1000 +Subject: [PATCH] fix KDM gamma issue on vt switch + +--- + hw/xfree86/modes/xf86RandR12.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c +index 6ea9d26..ece12b9 100644 +--- a/hw/xfree86/modes/xf86RandR12.c ++++ b/hw/xfree86/modes/xf86RandR12.c +@@ -1761,6 +1761,7 @@ xf86RandR12Init12 (ScreenPtr pScreen) + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + rrScrPrivPtr rp = rrGetScrPriv(pScreen); + XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen); ++ int i; + + rp->rrGetInfo = xf86RandR12GetInfo12; + rp->rrScreenSetSize = xf86RandR12ScreenSetSize; +@@ -1790,6 +1791,9 @@ xf86RandR12Init12 (ScreenPtr pScreen) + */ + if (!xf86RandR12SetInfo12 (pScreen)) + return FALSE; ++ for (i = 0; i < rp->numCrtcs; i++) { ++ xf86RandR12CrtcGetGamma(pScreen, rp->crtcs[i]); ++ } + return TRUE; + } + +-- +1.6.5.1 + diff --git a/xserver-1.7.1-glx14-swrast.patch b/xserver-1.7.1-glx14-swrast.patch new file mode 100644 index 0000000..2c51802 --- /dev/null +++ b/xserver-1.7.1-glx14-swrast.patch @@ -0,0 +1,26 @@ +From 25a0107768c9f25e8edc5e423ca8b1d0813f2d04 Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Tue, 24 Nov 2009 13:38:46 -0500 +Subject: [PATCH] Enable GLX 1.4 for swrast + +--- + glx/glxdriswrast.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +diff --git a/glx/glxdriswrast.c b/glx/glxdriswrast.c +index 44f658f..20f9f90 100644 +--- a/glx/glxdriswrast.c ++++ b/glx/glxdriswrast.c +@@ -510,6 +510,9 @@ __glXDRIscreenProbe(ScreenPtr pScreen) + + __glXScreenInit(&screen->base, pScreen); + ++ screen->base.GLXmajor = 1; ++ screen->base.GLXminor = 4; ++ + LogMessage(X_INFO, + "AIGLX: Loaded and initialized %s\n", filename); + +-- +1.6.5.2 + diff --git a/xserver-1.7.1-libcrypto.patch b/xserver-1.7.1-libcrypto.patch new file mode 100644 index 0000000..c271855 --- /dev/null +++ b/xserver-1.7.1-libcrypto.patch @@ -0,0 +1,35 @@ +From 8875112f5c57ec5d575e717c5638fbc919145efb Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Mon, 16 Nov 2009 18:01:26 -0500 +Subject: [PATCH] configure: Only link against libcrypto + +openssl.pc will link you against libssl, which we don't need, and which +brings in another seven libraries we also don't need. This is still +bogus, we're really only trying to get a SHA1 routine, we could link it +statically and be even better off. +--- + configure.ac | 6 ------ + 1 files changed, 0 insertions(+), 6 deletions(-) + +diff --git a/configure.ac b/configure.ac +index f69f97e..254d33d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1297,14 +1297,8 @@ if test "x$SHA1_LIB" = "x" ; then + fi + + if test "x$SHA1_LIB" = "x" ; then +- PKG_CHECK_EXISTS([OPENSSL], [openssl], [HAVE_OPENSSL_PKC=yes], +- [HAVE_OPENSSL_PKC=no]) +- if test "x$HAVE_OPENSSL_PKC" = xyes; then +- REQUIRED_LIBS="$REQUIRED_LIBS openssl" +- else + AC_CHECK_LIB([crypto], [SHA1_Init], [SHA1_LIB="-lcrypto"], + [AC_MSG_ERROR([OpenSSL must be installed in order to build the X server.])]) +- fi + fi + + PKG_CHECK_MODULES([XSERVERCFLAGS], [$REQUIRED_MODULES $REQUIRED_LIBS]) +-- +1.6.5.2 + diff --git a/xserver-1.7.1-multilib.patch b/xserver-1.7.1-multilib.patch new file mode 100644 index 0000000..6435999 --- /dev/null +++ b/xserver-1.7.1-multilib.patch @@ -0,0 +1,55 @@ +From 6d9585ba6a5784328de479c6b648d7b7d6cec64c Mon Sep 17 00:00:00 2001 +From: Adam Jackson +Date: Thu, 29 Oct 2009 19:04:10 -0400 +Subject: [PATCH] multilib fix for -devel subpackage + +--- + include/colormapst.h | 4 ++-- + include/xorg-server.h.in | 7 ++++--- + 2 files changed, 6 insertions(+), 5 deletions(-) + +diff --git a/include/colormapst.h b/include/colormapst.h +index f1fc8eb..274cd65 100644 +--- a/include/colormapst.h ++++ b/include/colormapst.h +@@ -103,12 +103,12 @@ typedef struct _ColormapRec + { + VisualPtr pVisual; + short class; /* PseudoColor or DirectColor */ +-#if defined(_XSERVER64) ++#ifdef __LP64__ + short pad0; + XID pad1; + #endif + XID mid; /* client's name for colormap */ +-#if defined(_XSERVER64) && (X_BYTE_ORDER == X_LITTLE_ENDIAN) ++#if defined(__LP64__) && (X_BYTE_ORDER == X_LITTLE_ENDIAN) + XID pad2; + #endif + ScreenPtr pScreen; /* screen map is associated with */ +diff --git a/include/xorg-server.h.in b/include/xorg-server.h.in +index 76cab16..081b8f3 100644 +--- a/include/xorg-server.h.in ++++ b/include/xorg-server.h.in +@@ -157,9 +157,6 @@ + /* Name of X server */ + #undef __XSERVERNAME__ + +-/* Define to 1 if unsigned long is 64 bits. */ +-#undef _XSERVER64 +- + /* Building vgahw module */ + #undef WITH_VGAHW + +@@ -187,4 +184,8 @@ + /* X Access Control Extension */ + #undef XACE + ++#ifdef __LP64__ ++#define _XSERVER64 1 ++#endif ++ + #endif /* _XORG_SERVER_H_ */ +-- +1.6.5.2 + diff --git a/xserver-1.7.3-exa-master.patch b/xserver-1.7.3-exa-master.patch new file mode 100644 index 0000000..6203e93 --- /dev/null +++ b/xserver-1.7.3-exa-master.patch @@ -0,0 +1,2009 @@ +From 9f493b930ef99253ba7e37dc280daff6738b6401 Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Fri, 6 Nov 2009 10:29:49 +1000 +Subject: exa master + +produced with git diff xserver-1.7.3..master exa/ + +diff --git a/exa/exa.c b/exa/exa.c +index e264d44..b3c5bff 100644 +--- a/exa/exa.c ++++ b/exa/exa.c +@@ -233,19 +233,19 @@ exaPixmapIsPinned (PixmapPtr pPix) + } + + /** +- * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen ++ * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen + * memory, meaning that acceleration could probably be done to it, and that it + * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it + * with the CPU. + * + * Note that except for UploadToScreen()/DownloadFromScreen() (which explicitly + * deal with moving pixmaps in and out of system memory), EXA will give drivers +- * pixmaps as arguments for which exaPixmapIsOffscreen() is TRUE. ++ * pixmaps as arguments for which exaPixmapHasGpuCopy() is TRUE. + * + * @return TRUE if the given drawable is in framebuffer memory. + */ + Bool +-exaPixmapIsOffscreen(PixmapPtr pPixmap) ++exaPixmapHasGpuCopy(PixmapPtr pPixmap) + { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); +@@ -253,16 +253,16 @@ exaPixmapIsOffscreen(PixmapPtr pPixmap) + if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) + return FALSE; + +- return (*pExaScr->pixmap_is_offscreen)(pPixmap); ++ return (*pExaScr->pixmap_has_gpu_copy)(pPixmap); + } + + /** +- * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapIsOffscreen(). ++ * exaDrawableIsOffscreen() is a convenience wrapper for exaPixmapHasGpuCopy(). + */ + Bool + exaDrawableIsOffscreen (DrawablePtr pDrawable) + { +- return exaPixmapIsOffscreen (exaGetDrawablePixmap (pDrawable)); ++ return exaPixmapHasGpuCopy (exaGetDrawablePixmap (pDrawable)); + } + + /** +@@ -276,14 +276,14 @@ exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp) + + exaGetDrawableDeltas (pDrawable, pPixmap, xp, yp); + +- if (exaPixmapIsOffscreen (pPixmap)) ++ if (exaPixmapHasGpuCopy (pPixmap)) + return pPixmap; + else + return NULL; + } + + /** +- * Returns TRUE if pixmap can be accessed offscreen. ++ * Returns TRUE if the pixmap GPU copy is being accessed. + */ + Bool + ExaDoPrepareAccess(PixmapPtr pPixmap, int index) +@@ -291,7 +291,7 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv (pScreen); + ExaPixmapPriv(pPixmap); +- Bool offscreen; ++ Bool has_gpu_copy, ret; + int i; + + if (!(pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS)) +@@ -304,7 +304,7 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) + for (i = 0; i < EXA_NUM_PREPARE_INDICES; i++) { + if (pExaScr->access[i].pixmap == pPixmap) { + pExaScr->access[i].count++; +- return TRUE; ++ return pExaScr->access[i].retval; + } + } + +@@ -321,31 +321,35 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) + pPixmap->devPrivate.ptr)); + } + +- offscreen = exaPixmapIsOffscreen(pPixmap); ++ has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); + +- if (offscreen && pExaPixmap->fb_ptr) ++ if (has_gpu_copy && pExaPixmap->fb_ptr) { + pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; +- else ++ ret = TRUE; ++ } else { + pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; ++ ret = FALSE; ++ } + + /* Store so we can handle repeated / nested calls. */ + pExaScr->access[index].pixmap = pPixmap; + pExaScr->access[index].count = 1; + +- if (!offscreen) +- return FALSE; ++ if (!has_gpu_copy) ++ goto out; + + exaWaitSync (pScreen); + + if (pExaScr->info->PrepareAccess == NULL) +- return TRUE; ++ goto out; + + if (index >= EXA_PREPARE_AUX_DEST && + !(pExaScr->info->flags & EXA_SUPPORTS_PREPARE_AUX)) { + if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) + FatalError("Unsupported AUX indices used on a pinned pixmap.\n"); + exaMoveOutPixmap (pPixmap); +- return FALSE; ++ ret = FALSE; ++ goto out; + } + + if (!(*pExaScr->info->PrepareAccess) (pPixmap, index)) { +@@ -353,11 +357,15 @@ ExaDoPrepareAccess(PixmapPtr pPixmap, int index) + !(pExaScr->info->flags & EXA_MIXED_PIXMAPS)) + FatalError("Driver failed PrepareAccess on a pinned pixmap.\n"); + exaMoveOutPixmap (pPixmap); +- +- return FALSE; ++ ret = FALSE; ++ goto out; + } + +- return TRUE; ++ ret = TRUE; ++ ++out: ++ pExaScr->access[index].retval = ret; ++ return ret; + } + + /** +@@ -420,7 +428,7 @@ exaFinishAccess(DrawablePtr pDrawable, int index) + if (pExaScr->finish_access) + pExaScr->finish_access(pPixmap, index); + +- if (!pExaScr->info->FinishAccess || !exaPixmapIsOffscreen(pPixmap)) ++ if (!pExaScr->info->FinishAccess || !exaPixmapHasGpuCopy(pPixmap)) + return; + + if (i >= EXA_PREPARE_AUX_DEST && +@@ -480,57 +488,6 @@ const GCFuncs exaGCFuncs = { + exaCopyClip + }; + +-/* +- * This wrapper exists to allow fbValidateGC to work. +- * Note that we no longer assume newly created pixmaps to be in normal ram. +- * This assumption is certainly not garuanteed with driver allocated pixmaps. +- */ +-static PixmapPtr +-exaCreatePixmapWithPrepare(ScreenPtr pScreen, int w, int h, int depth, +- unsigned usage_hint) +-{ +- PixmapPtr pPixmap; +- ExaScreenPriv(pScreen); +- +- /* This swaps between this function and the real upper layer function. +- * Normally this would swap to the fb layer pointer, this is a very special case. +- */ +- swap(pExaScr, pScreen, CreatePixmap); +- pPixmap = pScreen->CreatePixmap(pScreen, w, h, depth, usage_hint); +- swap(pExaScr, pScreen, CreatePixmap); +- +- if (!pPixmap) +- return NULL; +- +- /* Note the usage of ExaDoPrepareAccess, this allowed because: +- * The pixmap is new, so not offscreen in the classic exa case. +- * For EXA_HANDLES_PIXMAPS the driver will handle whatever is needed. +- * We want to signal that the pixmaps will be used as destination. +- */ +- ExaDoPrepareAccess(pPixmap, EXA_PREPARE_AUX_DEST); +- +- return pPixmap; +-} +- +-static Bool +-exaDestroyPixmapWithFinish(PixmapPtr pPixmap) +-{ +- ScreenPtr pScreen = pPixmap->drawable.pScreen; +- ExaScreenPriv(pScreen); +- Bool ret; +- +- exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); +- +- /* This swaps between this function and the real upper layer function. +- * Normally this would swap to the fb layer pointer, this is a very special case. +- */ +- swap(pExaScr, pScreen, DestroyPixmap); +- ret = pScreen->DestroyPixmap(pPixmap); +- swap(pExaScr, pScreen, DestroyPixmap); +- +- return ret; +-} +- + static void + exaValidateGC(GCPtr pGC, + unsigned long changes, +@@ -542,20 +499,9 @@ exaValidateGC(GCPtr pGC, + + ScreenPtr pScreen = pDrawable->pScreen; + ExaScreenPriv(pScreen); +- CreatePixmapProcPtr old_ptr = NULL; +- DestroyPixmapProcPtr old_ptr2 = NULL; ++ ExaGCPriv(pGC); + PixmapPtr pTile = NULL; +- EXA_GC_PROLOGUE(pGC); +- +- /* save the "fb" pointer. */ +- old_ptr = pExaScr->SavedCreatePixmap; +- /* create a new upper layer pointer. */ +- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare); +- +- /* save the "fb" pointer. */ +- old_ptr2 = pExaScr->SavedDestroyPixmap; +- /* create a new upper layer pointer. */ +- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish); ++ Bool finish_current_tile = FALSE; + + /* Either of these conditions is enough to trigger access to a tile pixmap. */ + /* With pGC->tileIsPixel == 1, you run the risk of dereferencing an invalid tile pixmap pointer. */ +@@ -569,8 +515,10 @@ exaValidateGC(GCPtr pGC, + */ + if (pTile && pTile->drawable.depth != pDrawable->depth && !(changes & GCTile)) { + PixmapPtr pRotatedTile = fbGetRotatedPixmap(pGC); +- if (pRotatedTile->drawable.depth == pDrawable->depth) ++ if (pRotatedTile && pRotatedTile->drawable.depth == pDrawable->depth) + pTile = pRotatedTile; ++ else ++ finish_current_tile = TRUE; /* CreatePixmap will be called. */ + } + } + +@@ -579,42 +527,39 @@ exaValidateGC(GCPtr pGC, + if (pTile) + exaPrepareAccess(&pTile->drawable, EXA_PREPARE_SRC); + ++ /* Calls to Create/DestroyPixmap have to be identified as special. */ ++ pExaScr->fallback_counter++; ++ swap(pExaGC, pGC, funcs); + (*pGC->funcs->ValidateGC)(pGC, changes, pDrawable); ++ swap(pExaGC, pGC, funcs); ++ pExaScr->fallback_counter--; + + if (pTile) + exaFinishAccess(&pTile->drawable, EXA_PREPARE_SRC); ++ if (finish_current_tile && pGC->tile.pixmap) ++ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_AUX_DEST); + if (pGC->stipple) +- exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); +- +- /* switch back to the normal upper layer. */ +- unwrap(pExaScr, pScreen, CreatePixmap); +- /* restore copy of fb layer pointer. */ +- pExaScr->SavedCreatePixmap = old_ptr; +- +- /* switch back to the normal upper layer. */ +- unwrap(pExaScr, pScreen, DestroyPixmap); +- /* restore copy of fb layer pointer. */ +- pExaScr->SavedDestroyPixmap = old_ptr2; +- +- EXA_GC_EPILOGUE(pGC); ++ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); + } + + /* Is exaPrepareAccessGC() needed? */ + static void + exaDestroyGC(GCPtr pGC) + { +- EXA_GC_PROLOGUE (pGC); ++ ExaGCPriv(pGC); ++ swap(pExaGC, pGC, funcs); + (*pGC->funcs->DestroyGC)(pGC); +- EXA_GC_EPILOGUE (pGC); ++ swap(pExaGC, pGC, funcs); + } + + static void + exaChangeGC (GCPtr pGC, + unsigned long mask) + { +- EXA_GC_PROLOGUE (pGC); ++ ExaGCPriv(pGC); ++ swap(pExaGC, pGC, funcs); + (*pGC->funcs->ChangeGC) (pGC, mask); +- EXA_GC_EPILOGUE (pGC); ++ swap(pExaGC, pGC, funcs); + } + + static void +@@ -622,9 +567,10 @@ exaCopyGC (GCPtr pGCSrc, + unsigned long mask, + GCPtr pGCDst) + { +- EXA_GC_PROLOGUE (pGCDst); ++ ExaGCPriv(pGCDst); ++ swap(pExaGC, pGCDst, funcs); + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); +- EXA_GC_EPILOGUE (pGCDst); ++ swap(pExaGC, pGCDst, funcs); + } + + static void +@@ -633,25 +579,28 @@ exaChangeClip (GCPtr pGC, + pointer pvalue, + int nrects) + { +- EXA_GC_PROLOGUE (pGC); ++ ExaGCPriv(pGC); ++ swap(pExaGC, pGC, funcs); + (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); +- EXA_GC_EPILOGUE (pGC); ++ swap(pExaGC, pGC, funcs); + } + + static void + exaCopyClip(GCPtr pGCDst, GCPtr pGCSrc) + { +- EXA_GC_PROLOGUE (pGCDst); ++ ExaGCPriv(pGCDst); ++ swap(pExaGC, pGCDst, funcs); + (*pGCDst->funcs->CopyClip)(pGCDst, pGCSrc); +- EXA_GC_EPILOGUE (pGCDst); ++ swap(pExaGC, pGCDst, funcs); + } + + static void + exaDestroyClip(GCPtr pGC) + { +- EXA_GC_PROLOGUE (pGC); ++ ExaGCPriv(pGC); ++ swap(pExaGC, pGC, funcs); + (*pGC->funcs->DestroyClip)(pGC); +- EXA_GC_EPILOGUE (pGC); ++ swap(pExaGC, pGC, funcs); + } + + /** +@@ -682,18 +631,6 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) + Bool ret; + ScreenPtr pScreen = pWin->drawable.pScreen; + ExaScreenPriv(pScreen); +- CreatePixmapProcPtr old_ptr = NULL; +- DestroyPixmapProcPtr old_ptr2 = NULL; +- +- /* save the "fb" pointer. */ +- old_ptr = pExaScr->SavedCreatePixmap; +- /* create a new upper layer pointer. */ +- wrap(pExaScr, pScreen, CreatePixmap, exaCreatePixmapWithPrepare); +- +- /* save the "fb" pointer. */ +- old_ptr2 = pExaScr->SavedDestroyPixmap; +- /* create a new upper layer pointer. */ +- wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmapWithFinish); + + if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) + exaPrepareAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); +@@ -701,25 +638,17 @@ exaChangeWindowAttributes(WindowPtr pWin, unsigned long mask) + if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) + exaPrepareAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); + ++ pExaScr->fallback_counter++; + swap(pExaScr, pScreen, ChangeWindowAttributes); + ret = pScreen->ChangeWindowAttributes(pWin, mask); + swap(pExaScr, pScreen, ChangeWindowAttributes); ++ pExaScr->fallback_counter--; + + if ((mask & CWBackPixmap) && pWin->backgroundState == BackgroundPixmap) + exaFinishAccess(&pWin->background.pixmap->drawable, EXA_PREPARE_SRC); + if ((mask & CWBorderPixmap) && pWin->borderIsPixel == FALSE) + exaFinishAccess(&pWin->border.pixmap->drawable, EXA_PREPARE_MASK); + +- /* switch back to the normal upper layer. */ +- unwrap(pExaScr, pScreen, CreatePixmap); +- /* restore copy of fb layer pointer. */ +- pExaScr->SavedCreatePixmap = old_ptr; +- +- /* switch back to the normal upper layer. */ +- unwrap(pExaScr, pScreen, DestroyPixmap); +- /* restore copy of fb layer pointer. */ +- pExaScr->SavedDestroyPixmap = old_ptr2; +- + return ret; + } + +@@ -774,10 +703,18 @@ ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout, + ScreenPtr pScreen = screenInfo.screens[screenNum]; + ExaScreenPriv(pScreen); + ++ /* Move any deferred results from a software fallback to the driver pixmap */ ++ if (pExaScr->deferred_mixed_pixmap) ++ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap); ++ + unwrap(pExaScr, pScreen, BlockHandler); + (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask); + wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler); + ++ /* The rest only applies to classic EXA */ ++ if (pExaScr->info->flags & EXA_HANDLES_PIXMAPS) ++ return; ++ + /* Try and keep the offscreen memory area tidy every now and then (at most + * once per second) when the server has been idle for at least 100ms. + */ +@@ -991,10 +928,12 @@ exaDriverInit (ScreenPtr pScreen, + * Replace various fb screen functions + */ + if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) && +- !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) { ++ (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) || ++ (pExaScr->info->flags & EXA_MIXED_PIXMAPS))) + wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler); ++ if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) && ++ !(pExaScr->info->flags & EXA_HANDLES_PIXMAPS)) + wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler); +- } + wrap(pExaScr, pScreen, CreateGC, exaCreateGC); + wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen); + wrap(pExaScr, pScreen, GetImage, exaGetImage); +@@ -1038,7 +977,7 @@ exaDriverInit (ScreenPtr pScreen, + wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_mixed); + wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_mixed); + pExaScr->do_migration = exaDoMigration_mixed; +- pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_mixed; ++ pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_mixed; + pExaScr->do_move_in_pixmap = exaMoveInPixmap_mixed; + pExaScr->do_move_out_pixmap = NULL; + pExaScr->prepare_access_reg = exaPrepareAccessReg_mixed; +@@ -1048,7 +987,7 @@ exaDriverInit (ScreenPtr pScreen, + wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_driver); + wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_driver); + pExaScr->do_migration = NULL; +- pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_driver; ++ pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_driver; + pExaScr->do_move_in_pixmap = NULL; + pExaScr->do_move_out_pixmap = NULL; + pExaScr->prepare_access_reg = NULL; +@@ -1059,7 +998,7 @@ exaDriverInit (ScreenPtr pScreen, + wrap(pExaScr, pScreen, DestroyPixmap, exaDestroyPixmap_classic); + wrap(pExaScr, pScreen, ModifyPixmapHeader, exaModifyPixmapHeader_classic); + pExaScr->do_migration = exaDoMigration_classic; +- pExaScr->pixmap_is_offscreen = exaPixmapIsOffscreen_classic; ++ pExaScr->pixmap_has_gpu_copy = exaPixmapHasGpuCopy_classic; + pExaScr->do_move_in_pixmap = exaMoveInPixmap_classic; + pExaScr->do_move_out_pixmap = exaMoveOutPixmap_classic; + pExaScr->prepare_access_reg = exaPrepareAccessReg_classic; +diff --git a/exa/exa.h b/exa/exa.h +index 4b39473..8c93d15 100644 +--- a/exa/exa.h ++++ b/exa/exa.h +@@ -624,13 +624,13 @@ typedef struct _ExaDriver { + + /** + * PixmapIsOffscreen() is an optional driver replacement to +- * exaPixmapIsOffscreen(). Set to NULL if you want the standard behaviour +- * of exaPixmapIsOffscreen(). ++ * exaPixmapHasGpuCopy(). Set to NULL if you want the standard behaviour ++ * of exaPixmapHasGpuCopy(). + * + * @param pPix the pixmap + * @return TRUE if the given drawable is in framebuffer memory. + * +- * exaPixmapIsOffscreen() is used to determine if a pixmap is in offscreen ++ * exaPixmapHasGpuCopy() is used to determine if a pixmap is in offscreen + * memory, meaning that acceleration could probably be done to it, and that it + * will need to be wrapped by PrepareAccess()/FinishAccess() when accessing it + * with the CPU. +diff --git a/exa/exa_accel.c b/exa/exa_accel.c +index 7e2dd70..0f6e5f7 100644 +--- a/exa/exa_accel.c ++++ b/exa/exa_accel.c +@@ -51,7 +51,8 @@ exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, + int partX1, partX2; + int off_x, off_y; + +- if (pExaScr->swappedOut || ++ if (pExaScr->fallback_counter || ++ pExaScr->swappedOut || + pGC->fillStyle != FillSolid || + pExaPixmap->accel_blocked) + { +@@ -153,7 +154,7 @@ exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int bpp = pDrawable->bitsPerPixel; + Bool ret = TRUE; + +- if (pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) ++ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) + return FALSE; + + /* Don't bother with under 8bpp, XYPixmaps. */ +@@ -481,9 +482,9 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, + goto fallback; + } + +- if (exaPixmapIsOffscreen(pDstPixmap)) { ++ if (exaPixmapHasGpuCopy(pDstPixmap)) { + /* Normal blitting. */ +- if (exaPixmapIsOffscreen(pSrcPixmap)) { ++ if (exaPixmapHasGpuCopy(pSrcPixmap)) { + if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, + upsidedown ? -1 : 1, + pGC ? pGC->alu : GXcopy, +@@ -503,8 +504,11 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, + + (*pExaScr->info->DoneCopy) (pDstPixmap); + exaMarkSync (pDstDrawable->pScreen); +- /* UTS: mainly for SHM PutImage's secondary path. */ +- } else { ++ /* UTS: mainly for SHM PutImage's secondary path. ++ * ++ * Only taking this path for directly accessible pixmaps. ++ */ ++ } else if (!pDstExaPixmap->pDamage) { + int bpp = pSrcDrawable->bitsPerPixel; + int src_stride = exaGetPixmapPitch(pSrcPixmap); + CARD8 *src = NULL; +@@ -531,7 +535,8 @@ exaHWCopyNtoN (DrawablePtr pSrcDrawable, + + pbox++; + } +- } ++ } else ++ goto fallback; + } else + goto fallback; + +@@ -568,7 +573,8 @@ exaCopyNtoN (DrawablePtr pSrcDrawable, + { + ExaScreenPriv(pDstDrawable->pScreen); + +- if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) ++ if (pExaScr->fallback_counter || ++ (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)) + return; + + if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown)) +@@ -590,7 +596,7 @@ exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, + { + ExaScreenPriv (pDstDrawable->pScreen); + +- if (pExaScr->swappedOut) { ++ if (pExaScr->fallback_counter || pExaScr->swappedOut) { + return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC, + srcx, srcy, width, height, dstx, dsty); + } +@@ -604,13 +610,14 @@ static void + exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr ppt) + { ++ ExaScreenPriv (pDrawable->pScreen); + int i; + xRectangle *prect; + + /* If we can't reuse the current GC as is, don't bother accelerating the + * points. + */ +- if (pGC->fillStyle != FillSolid) { ++ if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) { + ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt); + return; + } +@@ -639,10 +646,16 @@ static void + exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr ppt) + { ++ ExaScreenPriv (pDrawable->pScreen); + xRectangle *prect; + int x1, x2, y1, y2; + int i; + ++ if (pExaScr->fallback_counter) { ++ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); ++ return; ++ } ++ + /* Don't try to do wide lines or non-solid fill style. */ + if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || + pGC->fillStyle != FillSolid) { +@@ -700,12 +713,13 @@ static void + exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, + xSegment *pSeg) + { ++ ExaScreenPriv (pDrawable->pScreen); + xRectangle *prect; + int i; + + /* Don't try to do wide lines or non-solid fill style. */ +- if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || +- pGC->fillStyle != FillSolid) ++ if (pExaScr->fallback_counter || pGC->lineWidth != 0 || ++ pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) + { + ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); + return; +@@ -782,7 +796,8 @@ exaPolyFillRect(DrawablePtr pDrawable, + + exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); + +- if (pExaScr->swappedOut || pExaPixmap->accel_blocked) ++ if (pExaScr->fallback_counter || pExaScr->swappedOut || ++ pExaPixmap->accel_blocked) + { + goto fallback; + } +@@ -823,7 +838,7 @@ exaPolyFillRect(DrawablePtr pDrawable, + exaDoMigration (pixmaps, 1, TRUE); + } + +- if (!exaPixmapIsOffscreen (pPixmap) || ++ if (!exaPixmapHasGpuCopy (pPixmap) || + !(*pExaScr->info->PrepareSolid) (pPixmap, + pGC->alu, + pGC->planemask, +@@ -956,12 +971,18 @@ exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) + -pPixmap->screen_x, -pPixmap->screen_y); + #endif + ++ if (pExaScr->fallback_counter) { ++ pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; ++ goto fallback; ++ } ++ + pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW; + miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, + NULL, + &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); + pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW; + ++fallback: + REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); + + if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) { +@@ -984,7 +1005,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, + exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); + REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); + +- if (pExaPixmap->accel_blocked) ++ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked) + goto out; + + if (pExaScr->do_migration) { +@@ -999,7 +1020,7 @@ exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, + exaDoMigration (pixmaps, 1, TRUE); + } + +- if (exaPixmapIsOffscreen (pPixmap) && ++ if (exaPixmapHasGpuCopy (pPixmap) && + (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) + { + int nbox; +@@ -1080,7 +1101,8 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, + pPixmap = exaGetDrawablePixmap (pDrawable); + pExaPixmap = ExaGetPixmapPriv (pPixmap); + +- if (pExaPixmap->accel_blocked || pTileExaPixmap->accel_blocked) ++ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || ++ pTileExaPixmap->accel_blocked) + return FALSE; + + if (pExaScr->do_migration) { +@@ -1101,7 +1123,7 @@ exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, + + pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); + +- if (!pPixmap || !exaPixmapIsOffscreen(pTile)) ++ if (!pPixmap || !exaPixmapHasGpuCopy(pTile)) + return FALSE; + + if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) +@@ -1238,7 +1260,7 @@ exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, + int xoff, yoff; + Bool ok; + +- if (pExaScr->swappedOut) ++ if (pExaScr->fallback_counter || pExaScr->swappedOut) + goto fallback; + + exaGetDrawableDeltas (pDrawable, pPix, &xoff, &yoff); +diff --git a/exa/exa_classic.c b/exa/exa_classic.c +index 1eff570..c31e2d4 100644 +--- a/exa/exa_classic.c ++++ b/exa/exa_classic.c +@@ -38,7 +38,7 @@ ExaGetPixmapAddress(PixmapPtr p) + { + ExaPixmapPriv(p); + +- if (pExaPixmap->offscreen && pExaPixmap->fb_ptr) ++ if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr) + return pExaPixmap->fb_ptr; + else + return pExaPixmap->sys_ptr; +@@ -90,7 +90,7 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, + pExaPixmap->sys_pitch = pPixmap->devKind; + + pPixmap->devPrivate.ptr = NULL; +- pExaPixmap->offscreen = FALSE; ++ pExaPixmap->use_gpu_copy = FALSE; + + pExaPixmap->fb_ptr = NULL; + exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); +@@ -137,6 +137,10 @@ exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, + exaSetAccelBlock(pExaScr, pExaPixmap, + w, h, bpp); + ++ /* During a fallback we must prepare access. */ ++ if (pExaScr->fallback_counter) ++ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); ++ + return pPixmap; + } + +@@ -164,7 +168,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept + + /* Classic EXA: + * - Framebuffer. +- * - Scratch pixmap with offscreen memory. ++ * - Scratch pixmap with gpu memory. + */ + if (pExaScr->info->memoryBase && pPixData) { + if ((CARD8 *)pPixData >= pExaScr->info->memoryBase && +@@ -172,7 +176,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept + pExaScr->info->memorySize) { + pExaPixmap->fb_ptr = pPixData; + pExaPixmap->fb_pitch = devKind; +- pExaPixmap->offscreen = TRUE; ++ pExaPixmap->use_gpu_copy = TRUE; + } + } + +@@ -185,7 +189,7 @@ exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int dept + } + + /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or +- * offscreen memory, so there's no need to track damage. ++ * gpu memory, so there's no need to track damage. + */ + if (pExaPixmap->pDamage) { + DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); +@@ -216,6 +220,10 @@ exaDestroyPixmap_classic (PixmapPtr pPixmap) + { + ExaPixmapPriv (pPixmap); + ++ /* During a fallback we must finish access, but we don't know the index. */ ++ if (pExaScr->fallback_counter) ++ exaFinishAccess(&pPixmap->drawable, -1); ++ + if (pExaPixmap->area) + { + DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n", +@@ -240,7 +248,7 @@ exaDestroyPixmap_classic (PixmapPtr pPixmap) + } + + Bool +-exaPixmapIsOffscreen_classic(PixmapPtr pPixmap) ++exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap) + { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); +@@ -252,7 +260,7 @@ exaPixmapIsOffscreen_classic(PixmapPtr pPixmap) + ret = pExaScr->info->PixmapIsOffscreen(pPixmap); + pPixmap->devPrivate.ptr = NULL; + } else +- ret = (pExaPixmap->offscreen && pExaPixmap->fb_ptr); ++ ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr); + + return ret; + } +diff --git a/exa/exa_driver.c b/exa/exa_driver.c +index a9165a1..dcf1a98 100644 +--- a/exa/exa_driver.c ++++ b/exa/exa_driver.c +@@ -71,8 +71,8 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, + + bpp = pPixmap->drawable.bitsPerPixel; + +- /* Set this before driver hooks, to allow for !offscreen pixmaps. +- * !offscreen pixmaps have a valid pointer at all times. ++ /* Set this before driver hooks, to allow for driver pixmaps without gpu ++ * memory to back it. These pixmaps have a valid pointer at all times. + */ + pPixmap->devPrivate.ptr = NULL; + +@@ -115,6 +115,10 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, + exaSetAccelBlock(pExaScr, pExaPixmap, + w, h, bpp); + ++ /* During a fallback we must prepare access. */ ++ if (pExaScr->fallback_counter) ++ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); ++ + return pPixmap; + } + +@@ -153,8 +157,9 @@ exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth + ret = pExaScr->info->ModifyPixmapHeader(pPixmap, width, height, depth, + bitsPerPixel, devKind, pPixData); + /* For EXA_HANDLES_PIXMAPS, we set pPixData to NULL. +- * If pPixmap->devPrivate.ptr is non-NULL, then we've got a non-offscreen pixmap. +- * We need to store the pointer, because PrepareAccess won't be called. ++ * If pPixmap->devPrivate.ptr is non-NULL, then we've got a ++ * !has_gpu_copy pixmap. We need to store the pointer, ++ * because PrepareAccess won't be called. + */ + if (!pPixData && pPixmap->devPrivate.ptr && pPixmap->devKind) { + pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; +@@ -187,6 +192,10 @@ exaDestroyPixmap_driver (PixmapPtr pPixmap) + { + ExaPixmapPriv (pPixmap); + ++ /* During a fallback we must finish access, but we don't know the index. */ ++ if (pExaScr->fallback_counter) ++ exaFinishAccess(&pPixmap->drawable, -1); ++ + if (pExaPixmap->driverPriv) + pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); + pExaPixmap->driverPriv = NULL; +@@ -200,7 +209,7 @@ exaDestroyPixmap_driver (PixmapPtr pPixmap) + } + + Bool +-exaPixmapIsOffscreen_driver(PixmapPtr pPixmap) ++exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap) + { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); +diff --git a/exa/exa_glyphs.c b/exa/exa_glyphs.c +index bf097c3..fd14e9b 100644 +--- a/exa/exa_glyphs.c ++++ b/exa/exa_glyphs.c +@@ -352,11 +352,11 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, + + /* The most efficient thing to way to upload the glyph to the screen + * is to use the UploadToScreen() driver hook; this allows us to +- * pipeline glyph uploads and to avoid creating offscreen pixmaps for ++ * pipeline glyph uploads and to avoid creating gpu backed pixmaps for + * glyphs that we'll never use again. + * +- * If we can't do it with UploadToScreen (because the glyph is offscreen, etc), +- * we fall back to CompositePicture. ++ * If we can't do it with UploadToScreen (because the glyph has a gpu copy, ++ * etc), we fall back to CompositePicture. + * + * We need to damage the cache pixmap manually in either case because the damage + * layer unwrapped the picture screen before calling exaGlyphs. +@@ -364,7 +364,8 @@ exaGlyphCacheHashRemove(ExaGlyphCachePtr cache, + static void + exaGlyphCacheUploadGlyph(ScreenPtr pScreen, + ExaGlyphCachePtr cache, +- int pos, ++ int x, ++ int y, + GlyphPtr pGlyph) + { + ExaScreenPriv(pScreen); +@@ -378,7 +379,7 @@ exaGlyphCacheUploadGlyph(ScreenPtr pScreen, + + /* If the glyph pixmap is already uploaded, no point in doing + * things this way */ +- if (exaPixmapIsOffscreen(pGlyphPixmap)) ++ if (exaPixmapHasGpuCopy(pGlyphPixmap)) + goto composite; + + /* UploadToScreen only works if bpp match */ +@@ -388,7 +389,7 @@ exaGlyphCacheUploadGlyph(ScreenPtr pScreen, + if (pExaScr->do_migration) { + ExaMigrationRec pixmaps[1]; + +- /* cache pixmap must be offscreen. */ ++ /* cache pixmap must have a gpu copy. */ + pixmaps[0].as_dst = TRUE; + pixmaps[0].as_src = FALSE; + pixmaps[0].pPix = pCachePixmap; +@@ -396,13 +397,13 @@ exaGlyphCacheUploadGlyph(ScreenPtr pScreen, + exaDoMigration (pixmaps, 1, TRUE); + } + +- if (!exaPixmapIsOffscreen(pCachePixmap)) ++ if (!exaPixmapHasGpuCopy(pCachePixmap)) + goto composite; + +- /* CACHE_{X,Y} are in pixmap coordinates, no need for cache{X,Y}off */ ++ /* x,y are in pixmap coordinates, no need for cache{X,Y}off */ + if (pExaScr->info->UploadToScreen(pCachePixmap, +- CACHE_X(pos), +- CACHE_Y(pos), ++ x, ++ y, + pGlyph->info.width, + pGlyph->info.height, + (char *)pExaPixmap->sys_ptr, +@@ -416,18 +417,18 @@ composite: + cache->picture, + 0, 0, + 0, 0, +- CACHE_X(pos), +- CACHE_Y(pos), ++ x, ++ y, + pGlyph->info.width, + pGlyph->info.height); + + damage: + /* The cache pixmap isn't a window, so no need to offset coordinates. */ + exaPixmapDirty (pCachePixmap, +- CACHE_X(pos), +- CACHE_Y(pos), +- CACHE_X(pos) + cache->glyphWidth, +- CACHE_Y(pos) + cache->glyphHeight); ++ x, ++ y, ++ x + cache->glyphWidth, ++ y + cache->glyphHeight); + } + + static ExaGlyphCacheResult +@@ -446,6 +447,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, + { + ExaCompositeRectPtr rect; + int pos; ++ int x, y; + + if (buffer->mask && buffer->mask != cache->picture) + return ExaGlyphNeedFlush; +@@ -462,10 +464,14 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, + pos = exaGlyphCacheHashLookup(cache, pGlyph); + if (pos != -1) { + DBG_GLYPH_CACHE((" found existing glyph at %d\n", pos)); ++ x = CACHE_X(pos); ++ y = CACHE_Y(pos); + } else { + if (cache->glyphCount < cache->size) { + /* Space remaining; we fill from the start */ + pos = cache->glyphCount; ++ x = CACHE_X(pos); ++ y = CACHE_Y(pos); + cache->glyphCount++; + DBG_GLYPH_CACHE((" storing glyph in free space at %d\n", pos)); + +@@ -477,14 +483,12 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, + * the cache + */ + pos = cache->evictionPosition; ++ x = CACHE_X(pos); ++ y = CACHE_Y(pos); + DBG_GLYPH_CACHE((" evicting glyph at %d\n", pos)); + if (buffer->count) { +- int x, y; + int i; + +- x = CACHE_X(pos); +- y = CACHE_Y(pos); +- + for (i = 0; i < buffer->count; i++) { + if (pSrc ? + (buffer->rects[i].xMask == x && buffer->rects[i].yMask == y) : +@@ -503,7 +507,7 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, + cache->evictionPosition = rand() % cache->size; + } + +- exaGlyphCacheUploadGlyph(pScreen, cache, pos, pGlyph); ++ exaGlyphCacheUploadGlyph(pScreen, cache, x, y, pGlyph); + } + + buffer->mask = cache->picture; +@@ -514,13 +518,13 @@ exaGlyphCacheBufferGlyph(ScreenPtr pScreen, + { + rect->xSrc = xSrc; + rect->ySrc = ySrc; +- rect->xMask = CACHE_X(pos); +- rect->yMask = CACHE_Y(pos); ++ rect->xMask = x; ++ rect->yMask = y; + } + else + { +- rect->xSrc = CACHE_X(pos); +- rect->ySrc = CACHE_Y(pos); ++ rect->xSrc = x; ++ rect->ySrc = y; + rect->xMask = 0; + rect->yMask = 0; + } +diff --git a/exa/exa_migration_classic.c b/exa/exa_migration_classic.c +index 6d7b9f5..95189be 100644 +--- a/exa/exa_migration_classic.c ++++ b/exa/exa_migration_classic.c +@@ -111,7 +111,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, + ExaPixmapPriv (pPixmap); + RegionPtr damage = DamageRegion (pExaPixmap->pDamage); + RegionRec CopyReg; +- Bool save_offscreen; ++ Bool save_use_gpu_copy; + int save_pitch; + BoxPtr pBox; + int nbox; +@@ -119,7 +119,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, + Bool need_sync = FALSE; + + /* Damaged bits are valid in current copy but invalid in other one */ +- if (pExaPixmap->offscreen) { ++ if (pExaPixmap->use_gpu_copy) { + REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB, + damage); + REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, +@@ -200,9 +200,9 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, + pBox = REGION_RECTS(&CopyReg); + nbox = REGION_NUM_RECTS(&CopyReg); + +- save_offscreen = pExaPixmap->offscreen; ++ save_use_gpu_copy = pExaPixmap->use_gpu_copy; + save_pitch = pPixmap->devKind; +- pExaPixmap->offscreen = TRUE; ++ pExaPixmap->use_gpu_copy = TRUE; + pPixmap->devKind = pExaPixmap->fb_pitch; + + while (nbox--) { +@@ -242,7 +242,7 @@ exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, + pBox++; + } + +- pExaPixmap->offscreen = save_offscreen; ++ pExaPixmap->use_gpu_copy = save_use_gpu_copy; + pPixmap->devKind = save_pitch; + + /* Try to prevent source valid region from growing too many rects by +@@ -351,7 +351,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate) + + exaCopyDirtyToFb (migrate); + +- if (exaPixmapIsOffscreen(pPixmap)) ++ if (exaPixmapHasGpuCopy(pPixmap)) + return; + + DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap, +@@ -361,7 +361,7 @@ exaDoMoveInPixmap (ExaMigrationPtr migrate) + pPixmap->drawable.height, + exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); + +- pExaPixmap->offscreen = TRUE; ++ pExaPixmap->use_gpu_copy = TRUE; + + pPixmap->devKind = pExaPixmap->fb_pitch; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; +@@ -392,7 +392,7 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate) + + exaCopyDirtyToSys (migrate); + +- if (exaPixmapIsOffscreen(pPixmap)) { ++ if (exaPixmapHasGpuCopy(pPixmap)) { + + DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap, + (void*)(ExaGetPixmapPriv(pPixmap)->area ? +@@ -401,7 +401,7 @@ exaDoMoveOutPixmap (ExaMigrationPtr migrate) + pPixmap->drawable.height, + exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); + +- pExaPixmap->offscreen = FALSE; ++ pExaPixmap->use_gpu_copy = FALSE; + + pPixmap->devKind = pExaPixmap->sys_pitch; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; +@@ -468,12 +468,12 @@ exaMigrateTowardFb (ExaMigrationPtr migrate) + pExaPixmap->score++; + + if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN && +- !exaPixmapIsOffscreen(pPixmap)) ++ !exaPixmapHasGpuCopy(pPixmap)) + { + exaDoMoveInPixmap(migrate); + } + +- if (exaPixmapIsOffscreen(pPixmap)) { ++ if (exaPixmapHasGpuCopy(pPixmap)) { + exaCopyDirtyToFb (migrate); + ExaOffscreenMarkUsed (pPixmap); + } else +@@ -504,7 +504,7 @@ exaMigrateTowardSys (ExaMigrationPtr migrate) + if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area) + exaDoMoveOutPixmap(migrate); + +- if (exaPixmapIsOffscreen(pPixmap)) { ++ if (exaPixmapHasGpuCopy(pPixmap)) { + exaCopyDirtyToFb (migrate); + ExaOffscreenMarkUsed (pPixmap); + } else +@@ -523,7 +523,7 @@ exaAssertNotDirty (PixmapPtr pPixmap) + RegionRec ValidReg; + int dst_pitch, src_pitch, cpp, y, nbox, save_pitch; + BoxPtr pBox; +- Bool ret = TRUE, save_offscreen; ++ Bool ret = TRUE, save_use_gpu_copy; + + if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL) + return ret; +@@ -542,9 +542,9 @@ exaAssertNotDirty (PixmapPtr pPixmap) + src_pitch = pExaPixmap->fb_pitch; + cpp = pPixmap->drawable.bitsPerPixel / 8; + +- save_offscreen = pExaPixmap->offscreen; ++ save_use_gpu_copy = pExaPixmap->use_gpu_copy; + save_pitch = pPixmap->devKind; +- pExaPixmap->offscreen = TRUE; ++ pExaPixmap->use_gpu_copy = TRUE; + pPixmap->devKind = pExaPixmap->fb_pitch; + + if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC)) +@@ -579,7 +579,7 @@ exaAssertNotDirty (PixmapPtr pPixmap) + skip: + exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); + +- pExaPixmap->offscreen = save_offscreen; ++ pExaPixmap->use_gpu_copy = save_use_gpu_copy; + pPixmap->devKind = save_pitch; + + out: +@@ -618,7 +618,7 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) + */ + for (i = 0; i < npixmaps; i++) { + if (exaPixmapIsPinned (pixmaps[i].pPix) && +- !exaPixmapIsOffscreen (pixmaps[i].pPix)) ++ !exaPixmapHasGpuCopy (pixmaps[i].pPix)) + { + EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix, + pixmaps[i].pPix->drawable.width, +@@ -680,7 +680,7 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) + } + + for (i = 0; i < npixmaps; i++) { +- if (exaPixmapIsOffscreen(pixmaps[i].pPix)) { ++ if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) { + /* Found one in FB, so move all to FB. */ + for (j = 0; j < npixmaps; j++) + exaMigrateTowardFb(pixmaps + i); +@@ -709,12 +709,12 @@ exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) + + /* If we couldn't fit everything in, abort */ + for (i = 0; i < npixmaps; i++) { +- if (!exaPixmapIsOffscreen(pixmaps[i].pPix)) { ++ if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) { + return; + } + } + +- /* Yay, everything's offscreen, mark memory as used */ ++ /* Yay, everything has a gpu copy, mark memory as used */ + for (i = 0; i < npixmaps; i++) { + ExaOffscreenMarkUsed (pixmaps[i].pPix); + } +diff --git a/exa/exa_migration_mixed.c b/exa/exa_migration_mixed.c +index f42c9c2..b755b83 100644 +--- a/exa/exa_migration_mixed.c ++++ b/exa/exa_migration_mixed.c +@@ -80,7 +80,7 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) + */ + for (i = 0; i < npixmaps; i++) { + if (exaPixmapIsPinned (pixmaps[i].pPix) && +- !exaPixmapIsOffscreen (pixmaps[i].pPix)) ++ !exaPixmapHasGpuCopy (pixmaps[i].pPix)) + { + can_accel = FALSE; + break; +@@ -98,12 +98,25 @@ exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) + if (!pExaPixmap->driverPriv) + exaCreateDriverPixmap_mixed(pPixmap); + +- if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) { ++ if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) { ++ ExaScreenPriv(pPixmap->drawable.pScreen); ++ ++ /* This pitch is needed for proper acceleration. For some reason ++ * there are pixmaps without pDamage and a bad fb_pitch value. ++ * So setting devKind when only exaPixmapHasGpuCopy() is true ++ * causes corruption. Pixmaps without pDamage are not migrated ++ * and should have a valid devKind at all times, so that's why this ++ * isn't causing problems. Pixmaps have their gpu pitch set the ++ * first time in the MPH call from exaCreateDriverPixmap_mixed(). ++ */ + pPixmap->devKind = pExaPixmap->fb_pitch; + exaCopyDirtyToFb(pixmaps + i); ++ ++ if (pExaScr->deferred_mixed_pixmap == pPixmap) ++ pExaScr->deferred_mixed_pixmap = NULL; + } + +- pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap); ++ pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap); + } + } + +@@ -128,9 +141,10 @@ exaMoveInPixmap_mixed(PixmapPtr pPixmap) + void + exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) + { ++ ExaPixmapPriv(pPixmap); ++ + if (!ExaDoPrepareAccess(pPixmap, index)) { +- ExaPixmapPriv(pPixmap); +- Bool is_offscreen = exaPixmapIsOffscreen(pPixmap); ++ Bool has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); + ExaMigrationRec pixmaps[1]; + + /* Do we need to allocate our system buffer? */ +@@ -152,7 +166,8 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) + pixmaps[0].pPix = pPixmap; + pixmaps[0].pReg = pReg; + +- if (!pExaPixmap->pDamage && (is_offscreen || !exaPixmapIsPinned(pPixmap))) { ++ if (!pExaPixmap->pDamage && ++ (has_gpu_copy || !exaPixmapIsPinned(pPixmap))) { + Bool as_dst = pixmaps[0].as_dst; + + /* Set up damage tracking */ +@@ -165,7 +180,7 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) + /* This is used by exa to optimize migration. */ + DamageSetReportAfterOp(pExaPixmap->pDamage, TRUE); + +- if (is_offscreen) { ++ if (has_gpu_copy) { + exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, + pPixmap->drawable.height); + +@@ -177,33 +192,60 @@ exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg) + pixmaps[0].as_src = TRUE; + pixmaps[0].pReg = NULL; + } +- pPixmap->devKind = pExaPixmap->fb_pitch; + exaCopyDirtyToSys(pixmaps); + } + + if (as_dst) + exaPixmapDirty(pPixmap, 0, 0, pPixmap->drawable.width, + pPixmap->drawable.height); +- } else if (is_offscreen) { +- pPixmap->devKind = pExaPixmap->fb_pitch; ++ } else if (has_gpu_copy) + exaCopyDirtyToSys(pixmaps); +- } + + pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; + pPixmap->devKind = pExaPixmap->sys_pitch; +- pExaPixmap->offscreen = FALSE; ++ pExaPixmap->use_gpu_copy = FALSE; ++ /* We have a gpu pixmap that can be accessed, we don't need the cpu copy ++ * anymore. Drivers that prefer DFS, should fail prepare access. */ ++ } else if (pExaPixmap->pDamage && exaPixmapHasGpuCopy(pPixmap)) { ++ ExaScreenPriv(pPixmap->drawable.pScreen); ++ ++ /* Copy back any deferred content if needed. */ ++ if (pExaScr->deferred_mixed_pixmap && ++ pExaScr->deferred_mixed_pixmap == pPixmap) ++ exaMoveInPixmap_mixed(pPixmap); ++ ++ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); ++ DamageDestroy(pExaPixmap->pDamage); ++ pExaPixmap->pDamage = NULL; ++ ++ free(pExaPixmap->sys_ptr); ++ pExaPixmap->sys_ptr = NULL; + } + } + + /* Move back results of software rendering on system memory copy of mixed driver + * pixmap (see exaPrepareAccessReg_mixed). ++ * ++ * Defer moving the destination back into the driver pixmap, to try and save ++ * overhead on multiple consequent software fallbacks. + */ + void exaFinishAccess_mixed(PixmapPtr pPixmap, int index) + { + ExaPixmapPriv(pPixmap); + +- if (pExaPixmap->pDamage && exaPixmapIsOffscreen(pPixmap)) { ++ if (pExaPixmap->pDamage && !pExaPixmap->use_gpu_copy && ++ exaPixmapHasGpuCopy(pPixmap)) { + DamageRegionProcessPending(&pPixmap->drawable); +- exaMoveInPixmap_mixed(pPixmap); ++ ++ if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { ++ ExaScreenPriv(pPixmap->drawable.pScreen); ++ ++ if (pExaScr->deferred_mixed_pixmap && ++ pExaScr->deferred_mixed_pixmap != pPixmap) ++ exaMoveInPixmap_mixed(pExaScr->deferred_mixed_pixmap); ++ pExaScr->deferred_mixed_pixmap = pPixmap; ++ pPixmap->devKind = pExaPixmap->fb_pitch; ++ } else ++ exaMoveInPixmap_mixed(pPixmap); + } + } +diff --git a/exa/exa_mixed.c b/exa/exa_mixed.c +index ff02f27..155ed47 100644 +--- a/exa/exa_mixed.c ++++ b/exa/exa_mixed.c +@@ -93,9 +93,13 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, + /* A scratch pixmap will become a driver pixmap right away. */ + if (!w || !h) { + exaCreateDriverPixmap_mixed(pPixmap); +- pExaPixmap->offscreen = exaPixmapIsOffscreen(pPixmap); ++ pExaPixmap->use_gpu_copy = exaPixmapHasGpuCopy(pPixmap); + } else +- pExaPixmap->offscreen = FALSE; ++ pExaPixmap->use_gpu_copy = FALSE; ++ ++ /* During a fallback we must prepare access. */ ++ if (pExaScr->fallback_counter) ++ exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); + + return pPixmap; + } +@@ -107,7 +111,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPrivPtr pExaScr; + ExaPixmapPrivPtr pExaPixmap; +- Bool ret, is_offscreen; ++ Bool ret, has_gpu_copy; + + if (!pPixmap) + return FALSE; +@@ -127,22 +131,58 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, + pExaPixmap->driverPriv = NULL; + } + +- pExaPixmap->offscreen = FALSE; ++ pExaPixmap->use_gpu_copy = FALSE; + pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; + } + +- if (pExaPixmap->driverPriv) { +- if (width > 0 && height > 0 && bitsPerPixel > 0) { ++ has_gpu_copy = exaPixmapHasGpuCopy(pPixmap); ++ ++ if (width <= 0) ++ width = pPixmap->drawable.width; ++ ++ if (height <= 0) ++ height = pPixmap->drawable.height; ++ ++ if (bitsPerPixel <= 0) { ++ if (depth <= 0) ++ bitsPerPixel = pPixmap->drawable.bitsPerPixel; ++ else ++ bitsPerPixel = BitsPerPixel(depth); ++ } ++ ++ if (depth <= 0) ++ depth = pPixmap->drawable.depth; ++ ++ if (width != pPixmap->drawable.width || ++ height != pPixmap->drawable.height || ++ depth != pPixmap->drawable.depth || ++ bitsPerPixel != pPixmap->drawable.bitsPerPixel) { ++ if (pExaPixmap->driverPriv) { + exaSetFbPitch(pExaScr, pExaPixmap, + width, height, bitsPerPixel); + + exaSetAccelBlock(pExaScr, pExaPixmap, + width, height, bitsPerPixel); ++ REGION_EMPTY(pScreen, &pExaPixmap->validFB); + } ++ ++ /* Need to re-create system copy if there's also a GPU copy */ ++ if (has_gpu_copy && pExaPixmap->sys_ptr) { ++ free(pExaPixmap->sys_ptr); ++ pExaPixmap->sys_ptr = NULL; ++ pExaPixmap->sys_pitch = devKind > 0 ? devKind : ++ PixmapBytePad(width, depth); ++ DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); ++ DamageDestroy(pExaPixmap->pDamage); ++ pExaPixmap->pDamage = NULL; ++ REGION_EMPTY(pScreen, &pExaPixmap->validSys); ++ ++ if (pExaScr->deferred_mixed_pixmap == pPixmap) ++ pExaScr->deferred_mixed_pixmap = NULL; ++ } + } + +- is_offscreen = exaPixmapIsOffscreen(pPixmap); +- if (is_offscreen) { ++ if (has_gpu_copy) { + pPixmap->devPrivate.ptr = pExaPixmap->fb_ptr; + pPixmap->devKind = pExaPixmap->fb_pitch; + } else { +@@ -164,7 +204,7 @@ exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, + swap(pExaScr, pScreen, ModifyPixmapHeader); + + out: +- if (is_offscreen) { ++ if (has_gpu_copy) { + pExaPixmap->fb_ptr = pPixmap->devPrivate.ptr; + pExaPixmap->fb_pitch = pPixmap->devKind; + } else { +@@ -188,6 +228,13 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap) + { + ExaPixmapPriv (pPixmap); + ++ /* During a fallback we must finish access, but we don't know the index. */ ++ if (pExaScr->fallback_counter) ++ exaFinishAccess(&pPixmap->drawable, -1); ++ ++ if (pExaScr->deferred_mixed_pixmap == pPixmap) ++ pExaScr->deferred_mixed_pixmap = NULL; ++ + if (pExaPixmap->driverPriv) + pExaScr->info->DestroyPixmap(pScreen, pExaPixmap->driverPriv); + pExaPixmap->driverPriv = NULL; +@@ -208,7 +255,7 @@ exaDestroyPixmap_mixed(PixmapPtr pPixmap) + } + + Bool +-exaPixmapIsOffscreen_mixed(PixmapPtr pPixmap) ++exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap) + { + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); +diff --git a/exa/exa_offscreen.c b/exa/exa_offscreen.c +index eb53b2a..e3a9ab2 100644 +--- a/exa/exa_offscreen.c ++++ b/exa/exa_offscreen.c +@@ -169,7 +169,7 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, + { + ExaOffscreenArea *area; + ExaScreenPriv (pScreen); +- int real_size = 0, free_total = 0, largest_avail = 0; ++ int real_size = 0, largest_avail = 0; + #if DEBUG_OFFSCREEN + static int number = 0; + ErrorF("================= ============ allocating a new pixmap %d\n", ++number); +@@ -208,33 +208,10 @@ exaOffscreenAlloc (ScreenPtr pScreen, int size, int align, + if (real_size <= area->size) + break; + +- free_total += area->size; +- + if (area->size > largest_avail) + largest_avail = area->size; + } + +- if (!area && free_total >= size) { +- CARD32 now = GetTimeInMillis(); +- +- /* Don't defragment more than once per second, to avoid adding more +- * overhead than we're trying to prevent +- */ +- if (abs((INT32) (now - pExaScr->lastDefragment)) > 1000) { +- area = ExaOffscreenDefragment(pScreen); +- pExaScr->lastDefragment = now; +- +- if (area) { +- /* adjust size to match alignment requirement */ +- real_size = size + (area->base_offset + area->size - size) % align; +- +- /* does it fit? */ +- if (real_size > area->size) +- area = NULL; +- } +- } +- } +- + if (!area) + { + area = exaFindAreaToEvict(pExaScr, size, align); +@@ -522,7 +499,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen) + return NULL; + + pExaDstPix = ExaGetPixmapPriv (pDstPix); +- pExaDstPix->offscreen = TRUE; ++ pExaDstPix->use_gpu_copy = TRUE; + + for (area = pExaScr->info->offScreenAreas->prev; + area != pExaScr->info->offScreenAreas; +@@ -531,7 +508,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen) + ExaOffscreenArea *prev = area->prev; + PixmapPtr pSrcPix; + ExaPixmapPrivPtr pExaSrcPix; +- Bool save_offscreen; ++ Bool save_use_gpu_copy; + int save_pitch; + + if (area->state != ExaOffscreenAvail || +@@ -576,10 +553,10 @@ ExaOffscreenDefragment (ScreenPtr pScreen) + continue; + } + +- save_offscreen = pExaSrcPix->offscreen; ++ save_use_gpu_copy = pExaSrcPix->use_gpu_copy; + save_pitch = pSrcPix->devKind; + +- pExaSrcPix->offscreen = TRUE; ++ pExaSrcPix->use_gpu_copy = TRUE; + pSrcPix->devKind = pExaSrcPix->fb_pitch; + + pDstPix->drawable.width = pSrcPix->drawable.width; +@@ -589,7 +566,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen) + pDstPix->drawable.bitsPerPixel = pSrcPix->drawable.bitsPerPixel; + + if (!pExaScr->info->PrepareCopy (pSrcPix, pDstPix, -1, -1, GXcopy, ~0)) { +- pExaSrcPix->offscreen = save_offscreen; ++ pExaSrcPix->use_gpu_copy = save_use_gpu_copy; + pSrcPix->devKind = save_pitch; + area = prev; + continue; +@@ -646,7 +623,7 @@ ExaOffscreenDefragment (ScreenPtr pScreen) + #endif + + pExaSrcPix->fb_ptr = pExaDstPix->fb_ptr; +- pExaSrcPix->offscreen = save_offscreen; ++ pExaSrcPix->use_gpu_copy = save_use_gpu_copy; + pSrcPix->devKind = save_pitch; + } + +diff --git a/exa/exa_priv.h b/exa/exa_priv.h +index 1aec8e9..0852355 100644 +--- a/exa/exa_priv.h ++++ b/exa/exa_priv.h +@@ -173,7 +173,7 @@ typedef struct { + AddTrapsProcPtr SavedAddTraps; + #endif + void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); +- Bool (*pixmap_is_offscreen) (PixmapPtr pPixmap); ++ Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap); + void (*do_move_in_pixmap) (PixmapPtr pPixmap); + void (*do_move_out_pixmap) (PixmapPtr pPixmap); + void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg); +@@ -188,15 +188,18 @@ typedef struct { + unsigned numOffscreenAvailable; + CARD32 lastDefragment; + CARD32 nextDefragment; ++ PixmapPtr deferred_mixed_pixmap; + + /* Reference counting for accessed pixmaps */ + struct { + PixmapPtr pixmap; + int count; ++ Bool retval; + } access[EXA_NUM_PREPARE_INDICES]; + + /* Holds information on fallbacks that cannot be relayed otherwise. */ + unsigned int fallback_flags; ++ unsigned int fallback_counter; + + ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; + } ExaScreenPrivRec, *ExaScreenPrivPtr; +@@ -240,13 +243,21 @@ extern DevPrivateKey exaGCPrivateKey; + real->mem = tmp; \ + } + +-#define EXA_GC_PROLOGUE(_gc_) \ ++#define EXA_PRE_FALLBACK(_screen_) \ ++ ExaScreenPriv(_screen_); \ ++ pExaScr->fallback_counter++; ++ ++#define EXA_POST_FALLBACK(_screen_) \ ++ pExaScr->fallback_counter--; ++ ++#define EXA_PRE_FALLBACK_GC(_gc_) \ ++ ExaScreenPriv(_gc_->pScreen); \ + ExaGCPriv(_gc_); \ +- swap(pExaGC, _gc_, funcs); \ ++ pExaScr->fallback_counter++; \ + swap(pExaGC, _gc_, ops); + +-#define EXA_GC_EPILOGUE(_gc_) \ +- swap(pExaGC, _gc_, funcs); \ ++#define EXA_POST_FALLBACK_GC(_gc_) \ ++ pExaScr->fallback_counter--; \ + swap(pExaGC, _gc_, ops); + + /** Align an offset to an arbitrary alignment */ +@@ -273,7 +284,7 @@ extern DevPrivateKey exaGCPrivateKey; + typedef struct { + ExaOffscreenArea *area; + int score; /**< score for the move-in vs move-out heuristic */ +- Bool offscreen; ++ Bool use_gpu_copy; + + CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */ + int sys_pitch; /**< pitch of pixmap in system memory */ +@@ -529,7 +540,7 @@ exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap, + int *xp, int *yp); + + Bool +-exaPixmapIsOffscreen(PixmapPtr p); ++exaPixmapHasGpuCopy(PixmapPtr p); + + PixmapPtr + exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); +@@ -566,7 +577,7 @@ Bool + exaDestroyPixmap_classic (PixmapPtr pPixmap); + + Bool +-exaPixmapIsOffscreen_classic(PixmapPtr pPixmap); ++exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap); + + /* exa_driver.c */ + PixmapPtr +@@ -581,7 +592,7 @@ Bool + exaDestroyPixmap_driver (PixmapPtr pPixmap); + + Bool +-exaPixmapIsOffscreen_driver(PixmapPtr pPixmap); ++exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap); + + /* exa_mixed.c */ + PixmapPtr +@@ -596,7 +607,7 @@ Bool + exaDestroyPixmap_mixed(PixmapPtr pPixmap); + + Bool +-exaPixmapIsOffscreen_mixed(PixmapPtr pPixmap); ++exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap); + + /* exa_migration_mixed.c */ + void +diff --git a/exa/exa_render.c b/exa/exa_render.c +index db355d6..1b68e1c 100644 +--- a/exa/exa_render.c ++++ b/exa/exa_render.c +@@ -320,7 +320,7 @@ exaTryDriverSolidFill(PicturePtr pSrc, + exaDoMigration(pixmaps, 1, TRUE); + } + +- if (!exaPixmapIsOffscreen(pDstPix)) { ++ if (!exaPixmapHasGpuCopy(pDstPix)) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } +@@ -540,7 +540,7 @@ exaCompositeRects(CARD8 op, + /* We have to manage the damage ourselves, since CompositeRects isn't + * something in the screen that can be managed by the damage extension, + * and EXA depends on damage to track what needs to be migrated between +- * offscreen and onscreen. ++ * the gpu and the cpu. + */ + + /* Compute the overall extents of the composited region - we're making +@@ -752,7 +752,7 @@ exaTryDriverComposite(CARD8 op, + } + } + +- if (!exaPixmapIsOffscreen(pDstPix)) { ++ if (!exaPixmapHasGpuCopy(pDstPix)) { + REGION_UNINIT(pDst->pDrawable->pScreen, ®ion); + return 0; + } +diff --git a/exa/exa_unaccel.c b/exa/exa_unaccel.c +index c8f0172..eee14da 100644 +--- a/exa/exa_unaccel.c ++++ b/exa/exa_unaccel.c +@@ -74,26 +74,26 @@ void + ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, + DDXPointPtr ppt, int *pwidth, int fSorted) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); + exaPrepareAccessGC (pGC); + pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void + ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); + pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void +@@ -103,9 +103,8 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, + { + PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); + ExaPixmapPriv(pPixmap); +- ExaScreenPriv(pDrawable->pScreen); + +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage || + exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, +@@ -116,7 +115,7 @@ ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, + DamagePendingRegion(pExaPixmap->pDamage)); + pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void +@@ -124,7 +123,7 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, + exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); + exaPrepareAccess (pDst, EXA_PREPARE_DEST); +@@ -137,7 +136,7 @@ ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + } + exaFinishAccess (pSrc, EXA_PREPARE_SRC); + exaFinishAccess (pDst, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + RegionPtr +@@ -146,7 +145,7 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + { + RegionPtr ret; + +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, + exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); + exaPrepareAccess (pDst, EXA_PREPARE_DEST); +@@ -154,7 +153,7 @@ ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); + exaFinishAccess (pSrc, EXA_PREPARE_SRC); + exaFinishAccess (pDst, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + + return ret; + } +@@ -166,7 +165,7 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + { + RegionPtr ret; + +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, + exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); + exaPrepareAccess (pDst, EXA_PREPARE_DEST); +@@ -175,7 +174,7 @@ ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + bitPlane); + exaFinishAccess (pSrc, EXA_PREPARE_SRC); + exaFinishAccess (pDst, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + + return ret; + } +@@ -184,19 +183,19 @@ void + ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); + pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void + ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr ppt) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", + pDrawable, exaDrawableLocation(pDrawable), + pGC->lineWidth, mode, npt)); +@@ -206,14 +205,14 @@ ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, + pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void + ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, + int nsegInit, xSegment *pSegInit) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, + exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit)); + +@@ -222,14 +221,14 @@ ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, + pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void + ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *pArcs) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); +@@ -237,14 +236,14 @@ ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, + pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void + ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, + int nrect, xRectangle *prect) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); +@@ -252,7 +251,7 @@ ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, + pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void +@@ -260,7 +259,7 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c)\n", pDrawable, + exaDrawableLocation(pDrawable))); + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); +@@ -268,7 +267,7 @@ ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void +@@ -276,7 +275,7 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, + exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu)); + exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); +@@ -284,7 +283,7 @@ ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); + exaFinishAccessGC (pGC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void +@@ -292,7 +291,7 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, + int w, int h, int x, int y) + { +- EXA_GC_PROLOGUE(pGC); ++ EXA_PRE_FALLBACK_GC(pGC); + EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, + exaDrawableLocation(&pBitmap->drawable), + exaDrawableLocation(pDrawable))); +@@ -303,7 +302,7 @@ ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, + exaFinishAccessGC (pGC); + exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC); + exaFinishAccess (pDrawable, EXA_PREPARE_DEST); +- EXA_GC_EPILOGUE(pGC); ++ EXA_POST_FALLBACK_GC(pGC); + } + + void +@@ -311,7 +310,7 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) + { + DrawablePtr pDrawable = &pWin->drawable; + ScreenPtr pScreen = pDrawable->pScreen; +- ExaScreenPriv(pScreen); ++ EXA_PRE_FALLBACK(pScreen); + EXA_FALLBACK(("from %p\n", pWin)); + + /* being both src and dest, src is safest. */ +@@ -320,6 +319,7 @@ ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) + pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc); + swap(pExaScr, pScreen, CopyWindow); + exaFinishAccess (pDrawable, EXA_PREPARE_SRC); ++ EXA_POST_FALLBACK(pScreen); + } + + void +@@ -328,8 +328,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, + { + ScreenPtr pScreen = pDrawable->pScreen; + PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); +- ExaScreenPriv(pScreen); +- ++ EXA_PRE_FALLBACK(pScreen); + EXA_FALLBACK(("from %p (%c)\n", pDrawable, + exaDrawableLocation(pDrawable))); + +@@ -355,6 +354,7 @@ ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, + pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d); + swap(pExaScr, pScreen, GetImage); + exaFinishAccess (pDrawable, EXA_PREPARE_SRC); ++ EXA_POST_FALLBACK(pScreen); + } + + void +@@ -366,14 +366,15 @@ ExaCheckGetSpans (DrawablePtr pDrawable, + char *pdstStart) + { + ScreenPtr pScreen = pDrawable->pScreen; +- ExaScreenPriv(pScreen); + ++ EXA_PRE_FALLBACK(pScreen); + EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); + exaPrepareAccess (pDrawable, EXA_PREPARE_SRC); + swap(pExaScr, pScreen, GetSpans); + pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + swap(pExaScr, pScreen, GetSpans); + exaFinishAccess (pDrawable, EXA_PREPARE_SRC); ++ EXA_POST_FALLBACK(pScreen); + } + + void +@@ -394,9 +395,9 @@ ExaCheckComposite (CARD8 op, + #ifdef RENDER + PictureScreenPtr ps = GetPictureScreen(pScreen); + #endif /* RENDER */ +- ExaScreenPriv(pScreen); + RegionRec region; + int xoff, yoff; ++ EXA_PRE_FALLBACK(pScreen); + + REGION_NULL(pScreen, ®ion); + +@@ -413,7 +414,9 @@ ExaCheckComposite (CARD8 op, + PixmapPtr pDstPix; + + if (!miComputeCompositeRegion (®ion, pSrc, pMask, pDst, +- xSrc, ySrc, xMask, yMask, xDst, yDst, ++ xSrc, ySrc, xMask, yMask, ++ xDst + pDst->pDrawable->x, ++ yDst + pDst->pDrawable->y, + width, height)) + goto skip; + +@@ -471,6 +474,7 @@ skip: + exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); + + REGION_UNINIT(pScreen, ®ion); ++ EXA_POST_FALLBACK(pScreen); + } + + void +@@ -484,7 +488,7 @@ ExaCheckAddTraps (PicturePtr pPicture, + #ifdef RENDER + PictureScreenPtr ps = GetPictureScreen(pScreen); + #endif /* RENDER */ +- ExaScreenPriv(pScreen); ++ EXA_PRE_FALLBACK(pScreen); + + EXA_FALLBACK(("to pict %p (%c)\n", + exaDrawableLocation(pPicture->pDrawable))); +@@ -495,6 +499,7 @@ ExaCheckAddTraps (PicturePtr pPicture, + swap(pExaScr, ps, AddTraps); + #endif /* RENDER */ + exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); ++ EXA_POST_FALLBACK(pScreen); + } + + /** diff --git a/xserver-1.7.3-fb-backport.patch b/xserver-1.7.3-fb-backport.patch new file mode 100644 index 0000000..51e17e0 --- /dev/null +++ b/xserver-1.7.3-fb-backport.patch @@ -0,0 +1,339 @@ +From 85577ae6bad8fd8673b9abc81e7f2531ae64fcec Mon Sep 17 00:00:00 2001 +From: Dave Airlie +Date: Mon, 21 Dec 2009 11:47:19 +1000 +Subject: [PATCH] fb: backport fb changes from master for src window operations. + +This rolls up the following commits and also keeps the image_from_pict +API compatiblity. It introduces a new image_from_pict_18 API that is +used by the server leaving the old API alone. + +I've rolled this up as I don't want to introduce ABI breaks in bisection. + +a72c65e9176c51de95db2fdbf4c5d946a4911695 fb: Adjust transform or composite coordinates for pixman operations +bd567061c8b84b268d9bbb01bc4d8981feefb862 Split fbGetDrawable into fbGetDrawablePixmap and fbGetPixmapBitsData +61335052972a78d67c0ba74f902273b34c63a198 Revert "Fix clipping when windows are used as sources" +071b3c1810d9f2602173acc8578caac20e0b771e Revert "Use IncludeInferiors when copying windows before compositing." +8e640d6b131d2865a9725d8997023865b0ef3d69 Revert "Reserve space for two GC values in copy_drawable()." + +Signed-off-by: Dave Airlie +--- + fb/fb.h | 76 ++++++++++++++++++++++++++++--------------------- + fb/fbpict.c | 85 +++++++++++++++++++++++++++++++++++++++---------------- + fb/fbtrap.c | 6 ++- + fb/wfbrename.h | 1 + + 4 files changed, 108 insertions(+), 60 deletions(-) + +diff --git a/fb/fb.h b/fb/fb.h +index 37de71e..8b2839a 100644 +--- a/fb/fb.h ++++ b/fb/fb.h +@@ -700,38 +700,41 @@ typedef struct { + #define __fbPixOffXPix(pPix) (__fbPixDrawableX(pPix)) + #define __fbPixOffYPix(pPix) (__fbPixDrawableY(pPix)) + +-#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ +- PixmapPtr _pPix; \ +- if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ +- _pPix = fbGetWindowPixmap(pDrawable); \ +- (xoff) = __fbPixOffXWin(_pPix); \ +- (yoff) = __fbPixOffYWin(_pPix); \ +- } else { \ +- _pPix = (PixmapPtr) (pDrawable); \ +- (xoff) = __fbPixOffXPix(_pPix); \ +- (yoff) = __fbPixOffYPix(_pPix); \ +- } \ +- fbPrepareAccess(pDrawable); \ +- (pointer) = (FbBits *) _pPix->devPrivate.ptr; \ +- (stride) = ((int) _pPix->devKind) / sizeof (FbBits); (void)(stride); \ +- (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \ ++#define fbGetDrawablePixmap(pDrawable, pixmap, xoff, yoff) { \ ++ if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ ++ (pixmap) = fbGetWindowPixmap(pDrawable); \ ++ (xoff) = __fbPixOffXWin(pixmap); \ ++ (yoff) = __fbPixOffYWin(pixmap); \ ++ } else { \ ++ (pixmap) = (PixmapPtr) (pDrawable); \ ++ (xoff) = __fbPixOffXPix(pixmap); \ ++ (yoff) = __fbPixOffYPix(pixmap); \ ++ } \ ++ fbPrepareAccess(pDrawable); \ + } + +-#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ +- PixmapPtr _pPix; \ +- if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ +- _pPix = fbGetWindowPixmap(pDrawable); \ +- (xoff) = __fbPixOffXWin(_pPix); \ +- (yoff) = __fbPixOffYWin(_pPix); \ +- } else { \ +- _pPix = (PixmapPtr) (pDrawable); \ +- (xoff) = __fbPixOffXPix(_pPix); \ +- (yoff) = __fbPixOffYPix(_pPix); \ +- } \ +- fbPrepareAccess(pDrawable); \ +- (pointer) = (FbStip *) _pPix->devPrivate.ptr; \ +- (stride) = ((int) _pPix->devKind) / sizeof (FbStip); (void)(stride); \ +- (bpp) = _pPix->drawable.bitsPerPixel; (void)(bpp); \ ++#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ ++ (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ ++ (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride); \ ++ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ ++} ++ ++#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ ++ (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ ++ (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride); \ ++ (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ ++} ++ ++#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ ++ PixmapPtr _pPix; \ ++ fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ ++ fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ ++} ++ ++#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ ++ PixmapPtr _pPix; \ ++ fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ ++ fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ + } + + /* +@@ -2079,9 +2082,16 @@ fbFillRegionSolid (DrawablePtr pDrawable, + FbBits xor); + + extern _X_EXPORT pixman_image_t * +-image_from_pict (PicturePtr pict, +- Bool has_clip, +- Bool is_src); ++image_from_pict (PicturePtr pict, ++ Bool has_clip, ++ Bool is_src); ++ ++extern _X_EXPORT pixman_image_t * ++image_from_pict_18 (PicturePtr pict, ++ Bool has_clip, ++ int *xoff, ++ int *yoff); ++ + extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *); + + #endif /* _FB_H_ */ +diff --git a/fb/fbpict.c b/fb/fbpict.c +index 8fdaa58..f9f4343 100644 +--- a/fb/fbpict.c ++++ b/fb/fbpict.c +@@ -158,19 +158,24 @@ fbComposite (CARD8 op, + CARD16 height) + { + pixman_image_t *src, *mask, *dest; ++ int src_xoff, src_yoff; ++ int msk_xoff, msk_yoff; ++ int dst_xoff, dst_yoff; + +- miCompositeSourceValidate (pSrc, xSrc, ySrc, width, height); ++ miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height); + if (pMask) +- miCompositeSourceValidate (pMask, xMask, yMask, width, height); ++ miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height); + +- src = image_from_pict (pSrc, TRUE, TRUE); +- mask = image_from_pict (pMask, TRUE, TRUE); +- dest = image_from_pict (pDst, TRUE, FALSE); ++ src = image_from_pict_18 (pSrc, FALSE, &src_xoff, &src_yoff); ++ mask = image_from_pict_18 (pMask, FALSE, &msk_xoff, &msk_yoff); ++ dest = image_from_pict_18 (pDst, TRUE, &dst_xoff, &dst_yoff); + + if (src && dest && !(pMask && !mask)) + { + pixman_image_composite (op, src, mask, dest, +- xSrc, ySrc, xMask, yMask, xDst, yDst, ++ xSrc + src_xoff, ySrc + src_yoff, ++ xMask + msk_xoff, yMask + msk_yoff, ++ xDst + dst_xoff, yDst + dst_yoff, + width, height); + } + +@@ -270,22 +275,22 @@ create_conical_gradient_image (PictGradient *gradient) + + static pixman_image_t * + create_bits_picture (PicturePtr pict, +- Bool has_clip) ++ Bool has_clip, ++ int *xoff, ++ int *yoff) + { ++ PixmapPtr pixmap; + FbBits *bits; + FbStride stride; +- int bpp, xoff, yoff; ++ int bpp; + pixman_image_t *image; + +- fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff); +- +- bits = (FbBits*)((CARD8*)bits + +- (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) + +- (pict->pDrawable->x + xoff) * (bpp / 8)); ++ fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff); ++ fbGetPixmapBitsData(pixmap, bits, stride, bpp); + + image = pixman_image_create_bits ( + pict->format, +- pict->pDrawable->width, pict->pDrawable->height, ++ pixmap->drawable.width, pixmap->drawable.height, + (uint32_t *)bits, stride * sizeof (FbStride)); + + +@@ -311,30 +316,52 @@ create_bits_picture (PicturePtr pict, + if (pict->clientClipType != CT_NONE) + pixman_image_set_has_client_clip (image, TRUE); + +- pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y); ++ if (*xoff || *yoff) ++ pixman_region_translate (pict->pCompositeClip, *xoff, *yoff); + + pixman_image_set_clip_region (image, pict->pCompositeClip); + +- pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y); ++ if (*xoff || *yoff) ++ pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff); + } + + /* Indexed table */ + if (pict->pFormat->index.devPrivate) + pixman_image_set_indexed (image, pict->pFormat->index.devPrivate); + ++ /* Add in drawable origin to position within the image */ ++ *xoff += pict->pDrawable->x; ++ *yoff += pict->pDrawable->y; ++ + return image; + } + + static void +-set_image_properties (pixman_image_t *image, PicturePtr pict) ++set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff) + { + pixman_repeat_t repeat; + pixman_filter_t filter; + + if (pict->transform) + { +- pixman_image_set_transform ( +- image, (pixman_transform_t *)pict->transform); ++ /* For source images, adjust the transform to account ++ * for the drawable offset within the pixman image, ++ * then set the offset to 0 as it will be used ++ * to compute positions within the transformed image. ++ */ ++ if (!has_clip) { ++ struct pixman_transform adjusted; ++ ++ adjusted = *pict->transform; ++ pixman_transform_translate(&adjusted, ++ NULL, ++ pixman_int_to_fixed(*xoff), ++ pixman_int_to_fixed(*yoff)); ++ pixman_image_set_transform (image, &adjusted); ++ *xoff = 0; ++ *yoff = 0; ++ } else ++ pixman_image_set_transform (image, pict->transform); + } + + switch (pict->repeatType) +@@ -361,7 +388,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict) + + if (pict->alphaMap) + { +- pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, TRUE, TRUE); ++ int alpha_xoff, alpha_yoff; ++ pixman_image_t *alpha_map = image_from_pict_18 (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff); + + pixman_image_set_alpha_map ( + image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y); +@@ -393,10 +421,9 @@ set_image_properties (pixman_image_t *image, PicturePtr pict) + pixman_image_set_source_clipping (image, TRUE); + } + ++ + pixman_image_t * +-image_from_pict (PicturePtr pict, +- Bool has_clip, +- Bool is_src) ++image_from_pict_18 (PicturePtr pict, Bool has_clip, int *xoff, int *yoff) + { + pixman_image_t *image = NULL; + +@@ -405,7 +432,7 @@ image_from_pict (PicturePtr pict, + + if (pict->pDrawable) + { +- image = create_bits_picture (pict, has_clip); ++ image = create_bits_picture (pict, has_clip, xoff, yoff); + } + else if (pict->pSourcePict) + { +@@ -429,11 +456,18 @@ image_from_pict (PicturePtr pict, + } + + if (image) +- set_image_properties (image, pict); ++ set_image_properties (image, pict, has_clip, xoff, yoff); + + return image; + } + ++pixman_image_t * ++image_from_pict (PicturePtr pict, Bool has_clip, Bool is_src) ++{ ++ int xoff = 0, yoff = 0; ++ return image_from_pict_18(pict, has_clip, &xoff, &yoff); ++} ++ + void + free_pixman_pict (PicturePtr pict, pixman_image_t *image) + { +@@ -463,3 +497,4 @@ fbPictureInit (ScreenPtr pScreen, PictFormatPtr formats, int nformats) + + return TRUE; + } ++ +diff --git a/fb/fbtrap.c b/fb/fbtrap.c +index b1e1eff..5b5aeae 100644 +--- a/fb/fbtrap.c ++++ b/fb/fbtrap.c +@@ -40,7 +40,8 @@ fbAddTraps (PicturePtr pPicture, + int ntrap, + xTrap *traps) + { +- pixman_image_t *image = image_from_pict (pPicture, FALSE, FALSE); ++ int image_xoff, image_yoff; ++ pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &image_xoff, &image_yoff); + + if (!image) + return; +@@ -56,7 +57,8 @@ fbRasterizeTrapezoid (PicturePtr pPicture, + int x_off, + int y_off) + { +- pixman_image_t *image = image_from_pict (pPicture, FALSE, FALSE); ++ int mask_xoff, mask_yoff; ++ pixman_image_t *image = image_from_pict_18 (pPicture, FALSE, &mask_xoff, &mask_yoff); + + if (!image) + return; +diff --git a/fb/wfbrename.h b/fb/wfbrename.h +index 73ee510..e9cdca8 100644 +--- a/fb/wfbrename.h ++++ b/fb/wfbrename.h +@@ -187,4 +187,5 @@ + #define fbZeroSegment wfbZeroSegment + #define free_pixman_pict wfb_free_pixman_pict + #define image_from_pict wfb_image_from_pict ++#define image_from_pict_18 wfb_image_from_pict_18 + #define composeFunctions wfbComposeFunctions +-- +1.6.5.2 +