Patchwork Xorg on Fujitsu "Lime" with MPC5200b?

login
register
mail settings
Submitter Roman Fietze
Date April 16, 2010, 6:14 a.m.
Message ID <201004160814.01037.roman.fietze@telemotive.de>
Download mbox | patch
Permalink /patch/50310/
State Not Applicable
Headers show

Comments

Roman Fietze - April 16, 2010, 6:14 a.m.
Hello Bill,

On Thursday 15 April 2010 18:07:03 Bill Gatliff wrote:

> I would love it if you posted your code! Thanks!!

In this source file I just added my own routines:

        if (fPtr->shadowFB && 
            (!shadowSetup(pScreen) || !shadowAdd(pScreen, NULL,


--------------------------------

And here's my complete programs/Xserver/miext/shadow/shpacked.c


/*
 * $XFree86: xc/programs/Xserver/miext/shadow/shpacked.c,v 1.5 2001/10/28 03:34:16 tsi Exp $
 *
 * Copyright © 2000 Keith Packard
 *
 * Permission to use, copy, modify, distribute, and sell this software and its
 * documentation for any purpose is hereby granted without fee, provided that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of Keith Packard not be used in
 * advertising or publicity pertaining to distribution of the software without
 * specific, written prior permission.  Keith Packard makes no
 * representations about the suitability of this software for any purpose.  It
 * is provided "as is" without express or implied warranty.
 *
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#include    <byteswap.h>
#include    <unistd.h>

#include    "X.h"
#include    "scrnintstr.h"
#include    "windowstr.h"
#include    "font.h"
#include    "dixfontstr.h"
#include    "fontstruct.h"
#include    "mi.h"
#include    "regionstr.h"
#include    "globals.h"
#include    "gcstruct.h"
#include    "shadow.h"
#include    "fb.h"

void
shadowUpdatePacked (ScreenPtr	    pScreen,
		    shadowBufPtr    pBuf)
{
    RegionPtr	damage = &pBuf->damage;
    PixmapPtr	pShadow = pBuf->pPixmap;
    int		nbox = REGION_NUM_RECTS (damage);
    BoxPtr	pbox = REGION_RECTS (damage);
    FbBits	*shaBase, *shaLine, *sha;
    FbStride	shaStride;
    int		scrBase, scrLine, scr;
    int		shaBpp;
    int		shaXoff, shaYoff; /* XXX assumed to be zero */
    int		x, y, w, h, width;
    int         i;
    FbBits	*winBase = NULL, *win;
    CARD32      winSize;

    fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
    while (nbox--)
    {
	x = pbox->x1 * shaBpp;
	y = pbox->y1;
	w = (pbox->x2 - pbox->x1) * shaBpp;
	h = pbox->y2 - pbox->y1;

	scrLine = (x >> FB_SHIFT);
	shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
				   
	x &= FB_MASK;
	w = (w + x + FB_MASK) >> FB_SHIFT;
	
	while (h--)
	{
	    winSize = 0;
	    scrBase = 0;
	    width = w;
	    scr = scrLine;
	    sha = shaLine;
	    while (width) {
		/* how much remains in this window */
		i = scrBase + winSize - scr;
		if (i <= 0 || scr < scrBase)
		{
		    winBase = (FbBits *) (*pBuf->window) (pScreen,
							  y,
							  scr * sizeof (FbBits),
							  SHADOW_WINDOW_WRITE,
							  &winSize,
							  pBuf->closure);
		    if(!winBase)
			return;
		    scrBase = scr;
		    winSize /= sizeof (FbBits);
		    i = winSize;
		}
		win = winBase + (scr - scrBase);
		if (i > width)
		    i = width;
		width -= i;
		scr += i;

		while (i--)
		    *win++ = *sha++;
	    }
	    shaLine += shaStride;
	    y++;
	}
	pbox++;
    }
}


/* Swap frame buffer bytes in 32 bit value.  */
static __inline unsigned int
fbbits_swap32(unsigned int __bsx)
{
    return ((((__bsx) & 0xff000000) >> 8) | (((__bsx) & 0x00ff0000) << 8) |
	    (((__bsx) & 0x0000ff00) >> 8) | (((__bsx) & 0x000000ff) << 8));
}

void
shadowUpdatePackedSwapped16 (ScreenPtr	    pScreen,
			     shadowBufPtr    pBuf)
{
    RegionPtr	damage = &pBuf->damage;
    PixmapPtr	pShadow = pBuf->pPixmap;
    int		nbox = REGION_NUM_RECTS (damage);
    BoxPtr	pbox = REGION_RECTS (damage);
    FbBits	*shaBase, *shaLine, *sha;
    FbStride	shaStride;
    int		scrBase, scrLine, scr;
    int		shaBpp;
    int		shaXoff, shaYoff; /* XXX assumed to be zero */
    int		x, y, w, h, width;
    int         i;
    FbBits	*winBase = NULL, *win;
    CARD32      winSize;

    /* fprintf(stderr, "#### %s() nbox=%d sizof(*win)=%u\n", __FUNCTION__, nbox, sizeof(*win)); */

    fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
    while (nbox--)
    {
	x = pbox->x1 * shaBpp;
	y = pbox->y1;
	w = (pbox->x2 - pbox->x1) * shaBpp;
	h = pbox->y2 - pbox->y1;

	/* fprintf(stderr, "####\t%s: x=%d y=%d w=%d h=%d\n", __FUNCTION__, x, y, w, h); */

	scrLine = (x >> FB_SHIFT);
	shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
				   
	x &= FB_MASK;
	w = (w + x + FB_MASK) >> FB_SHIFT;
	
	while (h--)
	{
	    winSize = 0;
	    scrBase = 0;
	    width = w;
	    scr = scrLine;
	    sha = shaLine;
	    while (width) {
		/* how much remains in this window */
		i = scrBase + winSize - scr;
		if (i <= 0 || scr < scrBase)
		{
		    winBase = (FbBits *) (*pBuf->window) (pScreen,
							  y,
							  scr * sizeof (FbBits),
							  SHADOW_WINDOW_WRITE,
							  &winSize,
							  pBuf->closure);
		    if(!winBase)
			return;
		    scrBase = scr;
		    winSize /= sizeof (FbBits);
		    i = winSize;
		}
		win = winBase + (scr - scrBase);
		if (i > width)
		    i = width;
		width -= i;
		scr += i;

#if 1
		/* TODO: check which one of these solutions is
		 * faster. Allthough swab probably uses optimized PPC
		 * operations, the fbbits_swap32 solution uses 32 bit
		 * PCI accesses, so the result isn't that clear.
		 */
		while (i--)
		    *win++ = fbbits_swap32(*sha++);
#else
		swab(sha, win, i * sizeof(*win));
#endif
	    }
	    shaLine += shaStride;
	    y++;
	}
	pbox++;
    }
}


void
shadowUpdatePackedSwapped32 (ScreenPtr	    pScreen,
			     shadowBufPtr    pBuf)
{
    RegionPtr	damage = &pBuf->damage;
    PixmapPtr	pShadow = pBuf->pPixmap;
    int		nbox = REGION_NUM_RECTS (damage);
    BoxPtr	pbox = REGION_RECTS (damage);
    FbBits	*shaBase, *shaLine, *sha;
    FbStride	shaStride;
    int		scrBase, scrLine, scr;
    int		shaBpp;
    int		shaXoff, shaYoff; /* XXX assumed to be zero */
    int		x, y, w, h, width;
    int         i;
    FbBits	*winBase = NULL, *win;
    CARD32      winSize;

    /* fprintf(stderr, "#### %s() nbox=%d sizof(*win)=%u\n", __FUNCTION__, nbox, sizeof(*win)); */

    fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
    while (nbox--)
    {
	x = pbox->x1 * shaBpp;
	y = pbox->y1;
	w = (pbox->x2 - pbox->x1) * shaBpp;
	h = pbox->y2 - pbox->y1;

	/* fprintf(stderr, "####\t%s: x=%d y=%d w=%d h=%d\n", __FUNCTION__, x, y, w, h); */

	scrLine = (x >> FB_SHIFT);
	shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
				   
	x &= FB_MASK;
	w = (w + x + FB_MASK) >> FB_SHIFT;
	
	while (h--)
	{
	    winSize = 0;
	    scrBase = 0;
	    width = w;
	    scr = scrLine;
	    sha = shaLine;
	    while (width) {
		/* how much remains in this window */
		i = scrBase + winSize - scr;
		if (i <= 0 || scr < scrBase)
		{
		    winBase = (FbBits *) (*pBuf->window) (pScreen,
							  y,
							  scr * sizeof (FbBits),
							  SHADOW_WINDOW_WRITE,
							  &winSize,
							  pBuf->closure);
		    if(!winBase)
			return;
		    scrBase = scr;
		    winSize /= sizeof (FbBits);
		    i = winSize;
		}
		win = winBase + (scr - scrBase);
		if (i > width)
		    i = width;
		width -= i;
		scr += i;

		while (i--)
		    *win++ = bswap_32(*sha++);
	    }
	    shaLine += shaStride;
	    y++;
	}
	pbox++;
    }
}


Roman
Michel Dänzer - April 16, 2010, 8:30 a.m.
On Fre, 2010-04-16 at 08:14 +0200, Roman Fietze wrote: 
> 
> On Thursday 15 April 2010 18:07:03 Bill Gatliff wrote:
> 
> > I would love it if you posted your code! Thanks!!
> 
> In this source file I just added my own routines:
> 
> Index: programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c
> ===================================================================
> --- programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c   (revision 6)
> +++ programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c   (revision 7)
> @@ -139,8 +139,8 @@
>         "shadowInit",
>         "shadowSetup",
>         "shadowUpdatePacked",
> -       "shadowUpdatePackedSwapped16Weak",
> -       "shadowUpdatePackedSwapped32Weak",
> +       "shadowUpdatePackedSwapped16",
> +       "shadowUpdatePackedSwapped32",
>         "shadowUpdateRotatePacked",
>         NULL
>  };
> @@ -619,6 +619,7 @@
>         ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
>         FBDevPtr fPtr = FBDEVPTR(pScrn);
>         VisualPtr visual;
> +       ShadowUpdateProc pupdate;
>         int init_picture = 0;
>         int ret,flags,width,height;
>  
> @@ -794,7 +795,7 @@
>                 xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
>                            "RENDER extension initialisation failed.\n");
>  
> -       pupdate = pScrn->bitsPerPixel > 16 ? shadowUpdatePackedSwapped32Weak() :
>  shadowUpdatePackedSwapped16Weak();
> +       pupdate = pScrn->bitsPerPixel > 16 ? shadowUpdatePackedSwapped32 : shado
> wUpdatePackedSwapped16;
>  
>         if (fPtr->shadowFB && 
>             (!shadowSetup(pScreen) || !shadowAdd(pScreen, NULL,

I hope you're aware that this really just hacks around the kernel
framebuffer device not exposing the framebuffer to userspace according
to the fbdev interface (see struct fb_bitfield
in /usr/include/linux/fb.h), and this will affect everything else using
the framebuffer device as well.

It would be better to handle this in the kernel framebuffer device,
either via hardware byte swapping facilities if available, or otherwise
e.g. via FB_DEFERRED_IO.

Patch

Index: programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c
===================================================================
--- programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c   (revision 6)
+++ programs/Xserver/hw/xfree86/drivers/fbdev/fbdev.c   (revision 7)
@@ -139,8 +139,8 @@ 
        "shadowInit",
        "shadowSetup",
        "shadowUpdatePacked",
-       "shadowUpdatePackedSwapped16Weak",
-       "shadowUpdatePackedSwapped32Weak",
+       "shadowUpdatePackedSwapped16",
+       "shadowUpdatePackedSwapped32",
        "shadowUpdateRotatePacked",
        NULL
 };
@@ -619,6 +619,7 @@ 
        ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
        FBDevPtr fPtr = FBDEVPTR(pScrn);
        VisualPtr visual;
+       ShadowUpdateProc pupdate;
        int init_picture = 0;
        int ret,flags,width,height;
 
@@ -794,7 +795,7 @@ 
                xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
                           "RENDER extension initialisation failed.\n");
 
-       pupdate = pScrn->bitsPerPixel > 16 ? shadowUpdatePackedSwapped32Weak() :
 shadowUpdatePackedSwapped16Weak();
+       pupdate = pScrn->bitsPerPixel > 16 ? shadowUpdatePackedSwapped32 : shado
wUpdatePackedSwapped16;