Not getting expected performance improvement after accelerating bitBlit through KAA

prudhvi raj prudhviraj.v at gmail.com
Fri Oct 30 00:42:47 PDT 2009


Thanks for the response mr. Daniel.

According to my understanding KDrive has been developed with more focus on
embedded systems. So why do u want me to go for XOrg ( u mean XAA??) instead
of KDrive??

I think the code which handles whether to call a hardware accelerated
operation or software callback lies inside Kdrive code itself know. That
code is already present in the Xserver/hw/kdrive/src folder.

Anyway for you reference i am posting the perticular code block below. In
that i have added my hw accelerated blit call in (*pKaaScr->info->Copy)
callback which will get called from KaaCopyNtoN() function.

Do u have any ided why the mapping    pScreen->PaintWindowBackground =
kaaPaintWindow;
has been removed in the next versions?? and
why is the function kaaFillRegionTiled() is left unimplemented and
commented??

please let me know if u want any more specific information.

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "kdrive.h"
#include "kaa.h"
#include "dixfontstr.h"

#define DEBUG_MIGRATE 0
#define DEBUG_PIXMAP 0
#if DEBUG_MIGRATE
#define DBG_MIGRATE(a) ErrorF a
#else
#define DBG_MIGRATE(a)
#endif
#if DEBUG_PIXMAP
#define DBG_PIXMAP(a) ErrorF a
#else
#define DBG_PIXMAP(a)
#endif

int kaaGeneration;
int kaaScreenPrivateIndex;
int kaaPixmapPrivateIndex;

#define KAA_PIXMAP_SCORE_MOVE_IN    10
#define KAA_PIXMAP_SCORE_MAX        20
#define KAA_PIXMAP_SCORE_MOVE_OUT   -10
#define KAA_PIXMAP_SCORE_MIN        -20
#define KAA_PIXMAP_SCORE_PINNED        1000
#define KAA_PIXMAP_SCORE_INIT        1001

void
kaaDrawableDirty (DrawablePtr pDrawable)
{
    PixmapPtr pPixmap;
    KaaPixmapPrivPtr pKaaPixmap;

    if (pDrawable->type == DRAWABLE_WINDOW)
    pPixmap = (*pDrawable->pScreen->GetWindowPixmap)((WindowPtr) pDrawable);
    else
    pPixmap = (PixmapPtr)pDrawable;

    pKaaPixmap = KaaGetPixmapPriv(pPixmap);
    if (pKaaPixmap != NULL)
    pKaaPixmap->dirty = TRUE;
}

static void
kaaPixmapSave (ScreenPtr pScreen, KdOffscreenArea *area)
{
    PixmapPtr pPixmap = area->privData;
    KaaPixmapPriv(pPixmap);
    int dst_pitch, src_pitch, bytes;
    unsigned char *dst, *src;
    int i;

    DBG_MIGRATE (("Save 0x%08x (0x%x) (%dx%d)\n",
          pPixmap->drawable.id,
          KaaGetPixmapPriv(pPixmap)->area ?
          KaaGetPixmapPriv(pPixmap)->area->offset : -1,
          pPixmap->drawable.width,
          pPixmap->drawable.height));

    src_pitch = pPixmap->devKind;
    dst_pitch = pKaaPixmap->devKind;

    src = pPixmap->devPrivate.ptr;
    dst = pKaaPixmap->devPrivate.ptr;

    pPixmap->devKind = dst_pitch;
    pPixmap->devPrivate.ptr = dst;
    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
    pKaaPixmap->area = NULL;

#if 0
    if (!pKaaPixmap->dirty)
    return;
#endif

    kaaWaitSync (pPixmap->drawable.pScreen);

    bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;

    i = pPixmap->drawable.height;
    while (i--) {
    memcpy (dst, src, bytes);
    dst += dst_pitch;
    src += src_pitch;
    }
}

static int
kaaLog2(int val)
{
    int bits;

    if (!val)
    return 0;
    for (bits = 0; val != 0; bits++)
    val >>= 1;
    return bits - 1;
}

static Bool
kaaPixmapAllocArea (PixmapPtr pPixmap)
{
    ScreenPtr    pScreen = pPixmap->drawable.pScreen;
    KaaScreenPriv (pScreen);
    KaaPixmapPriv (pPixmap);
    KdScreenPriv  (pScreen);
    int        bpp = pPixmap->drawable.bitsPerPixel;
    CARD16    h = pPixmap->drawable.height;
    CARD16    w = pPixmap->drawable.width;
    int        pitch;

    if (pKaaScr->info->flags & KAA_OFFSCREEN_ALIGN_POT && w != 1)
    w = 1 << (kaaLog2(w - 1) + 1);
    pitch = (w * bpp / 8 + pKaaScr->info->pitchAlign - 1) &
            ~(pKaaScr->info->pitchAlign - 1);

    pKaaPixmap->devKind = pPixmap->devKind;
    pKaaPixmap->devPrivate = pPixmap->devPrivate;
    pKaaPixmap->area = KdOffscreenAlloc (pScreen, pitch * h,
                     pKaaScr->info->offsetAlign,
                     FALSE,
                     kaaPixmapSave, (pointer) pPixmap);
    if (!pKaaPixmap->area)
    return FALSE;

    DBG_PIXMAP(("++ 0x%08x (0x%x) (%dx%d)\n",
          pPixmap->drawable.id,
          KaaGetPixmapPriv(pPixmap)->area ?
          KaaGetPixmapPriv(pPixmap)->area->offset : -1,
          pPixmap->drawable.width,
          pPixmap->drawable.height));
    pPixmap->devKind = pitch;
    pPixmap->devPrivate.ptr = (pointer) ((CARD8 *)
pScreenPriv->screen->memory_base + pKaaPixmap->area->offset);
    pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
    return TRUE;
}

void
kaaMoveInPixmap (PixmapPtr pPixmap)
{
    ScreenPtr    pScreen = pPixmap->drawable.pScreen;
    KaaScreenPriv (pScreen);
    KaaPixmapPriv (pPixmap);
    int dst_pitch, src_pitch, bytes;
    unsigned char *dst, *src;
    int i;

    DBG_MIGRATE (("-> 0x%08x (0x%x) (%dx%d)\n",
          pPixmap->drawable.id,
          KaaGetPixmapPriv(pPixmap)->area ?
          KaaGetPixmapPriv(pPixmap)->area->offset : -1,
          pPixmap->drawable.width,
          pPixmap->drawable.height));

    src = pPixmap->devPrivate.ptr;
    src_pitch = pPixmap->devKind;

    if (!kaaPixmapAllocArea (pPixmap))
    return;

    pKaaPixmap->dirty = FALSE;

    if (pKaaScr->info->UploadToScreen)
    {
    if (pKaaScr->info->UploadToScreen(pPixmap, src, src_pitch))
        return;
    }

    dst = pPixmap->devPrivate.ptr;
    dst_pitch = pPixmap->devKind;

    bytes = src_pitch < dst_pitch ? src_pitch : dst_pitch;

    kaaWaitSync (pPixmap->drawable.pScreen);

    i = pPixmap->drawable.height;
    while (i--) {
    memcpy (dst, src, bytes);
    dst += dst_pitch;
    src += src_pitch;
    }
}

static void
kaaMoveOutPixmap (PixmapPtr pPixmap)
{
    KaaPixmapPriv (pPixmap);
    KdOffscreenArea *area = pKaaPixmap->area;

    DBG_MIGRATE (("<- 0x%08x (0x%x) (%dx%d)\n",
          pPixmap->drawable.id,
          KaaGetPixmapPriv(pPixmap)->area ?
          KaaGetPixmapPriv(pPixmap)->area->offset : -1,
          pPixmap->drawable.width,
          pPixmap->drawable.height));
    if (area)
    {
    kaaPixmapSave (pPixmap->drawable.pScreen, area);
    KdOffscreenFree (pPixmap->drawable.pScreen, area);
    }
}

void
kaaPixmapUseScreen (PixmapPtr pPixmap)
{
    KaaPixmapPriv (pPixmap);

    if (pKaaPixmap == NULL)
           return;

    if (pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED)
    return;

    if (pKaaPixmap->score == KAA_PIXMAP_SCORE_INIT) {
    kaaMoveInPixmap(pPixmap);
    pKaaPixmap->score = 0;
    }

    if (pKaaPixmap->score < KAA_PIXMAP_SCORE_MAX)
    {
    pKaaPixmap->score++;
    if (!kaaPixmapIsOffscreen(pPixmap) &&
        pKaaPixmap->score >= KAA_PIXMAP_SCORE_MOVE_IN)
        kaaMoveInPixmap (pPixmap);
    }
    KdOffscreenMarkUsed (pPixmap);
}

void
kaaPixmapUseMemory (PixmapPtr pPixmap)
{
    KaaPixmapPriv (pPixmap);

    if (pKaaPixmap == NULL)
           return;

    if (pKaaPixmap->score == KAA_PIXMAP_SCORE_PINNED)
    return;

    if (pKaaPixmap->score == KAA_PIXMAP_SCORE_INIT)
    pKaaPixmap->score = 0;

    if (pKaaPixmap->score > KAA_PIXMAP_SCORE_MIN)
    {
    pKaaPixmap->score--;
    if (pKaaPixmap->area &&
        pKaaPixmap->score <= KAA_PIXMAP_SCORE_MOVE_OUT)
        kaaMoveOutPixmap (pPixmap);
    }
}

static Bool
kaaDestroyPixmap (PixmapPtr pPixmap)
{
    if (pPixmap->refcnt == 1)
    {
    KaaPixmapPriv (pPixmap);
    if (pKaaPixmap->area)
    {
        DBG_PIXMAP(("-- 0x%08x (0x%x) (%dx%d)\n",
             pPixmap->drawable.id,
             KaaGetPixmapPriv(pPixmap)->area->offset,
             pPixmap->drawable.width,
             pPixmap->drawable.height));
        /* Free the offscreen area */
        KdOffscreenFree (pPixmap->drawable.pScreen, pKaaPixmap->area);
        pPixmap->devPrivate = pKaaPixmap->devPrivate;
        pPixmap->devKind = pKaaPixmap->devKind;
    }
    }
    return fbDestroyPixmap (pPixmap);
}

static PixmapPtr
kaaCreatePixmap(ScreenPtr pScreen, int w, int h, int depth)
{
    PixmapPtr        pPixmap;
    KaaPixmapPrivPtr    pKaaPixmap;
    int            bpp;

    bpp = BitsPerPixel (depth);
    if (bpp == 32 && depth == 24)
    {
    int fb;
    KdScreenPriv (pScreen);

    for (fb = 0; fb < KD_MAX_FB && pScreenPriv->screen->fb[fb].depth; fb++)
        if (pScreenPriv->screen->fb[fb].depth == 24)
        {
        bpp = pScreenPriv->screen->fb[fb].bitsPerPixel;
        break;
        }
    }

    pPixmap = fbCreatePixmapBpp (pScreen, w, h, depth, bpp);
    if (!pPixmap)
    return NULL;
    pKaaPixmap = KaaGetPixmapPriv(pPixmap);
    if (!w || !h)
    pKaaPixmap->score = KAA_PIXMAP_SCORE_PINNED;
    else
    pKaaPixmap->score = KAA_PIXMAP_SCORE_INIT;

    pKaaPixmap->area = NULL;
    pKaaPixmap->dirty = FALSE;

    return pPixmap;
}

Bool
kaaPixmapIsOffscreen(PixmapPtr p)
{
    ScreenPtr    pScreen = p->drawable.pScreen;
    KdScreenPriv(pScreen);

    return ((unsigned long) ((CARD8 *) p->devPrivate.ptr -
                 (CARD8 *) pScreenPriv->screen->memory_base) <
        pScreenPriv->screen->memory_size);
}

PixmapPtr
kaaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp)
{
    PixmapPtr    pPixmap;
    int        x, y;

    if (pDrawable->type == DRAWABLE_WINDOW) {
    pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr)
pDrawable);
#ifdef COMPOSITE
    x = -pPixmap->screen_x;
    y = -pPixmap->screen_y;
#else
    x = 0;
    y = 0;
#endif
    }
    else
    {
    pPixmap = (PixmapPtr) pDrawable;
    x = 0;
    y = 0;
    }
    *xp = x;
    *yp = y;
    if (kaaPixmapIsOffscreen (pPixmap))
    return pPixmap;
    else
    return NULL;
}

Bool
kaaDrawableIsOffscreen (DrawablePtr pDrawable)
{
    PixmapPtr    pPixmap;
    if (pDrawable->type == DRAWABLE_WINDOW)
    pPixmap = (*pDrawable->pScreen->GetWindowPixmap) ((WindowPtr)
pDrawable);
    else
    pPixmap = (PixmapPtr) pDrawable;
    return kaaPixmapIsOffscreen (pPixmap);
}

#if 0
static void
kaaFillTiled(int    dst_x,
         int    dst_y,
         int    width,
         int    height,
         int    src_x,
         int    src_y,
         int    src_width,
         int    src_height,
         void    (*Copy) (int    srcX,
                 int    srcY,
                 int    dstX,
                 int    dstY,
                 int    width,
                 int    height))
{
    modulus (src_x, src_width, src_x);
    modulus (src_y, src_height, src_y);

    while (height)
    {
    int dst_x_tmp = dst_x;
    int src_x_tmp = src_x;
    int width_tmp = width;
    int height_left = src_height - src_y;
    int height_this = min (height, height_left);

    while (width_tmp)
    {
        int width_left = src_width - src_x_tmp;
        int width_this = min (width_tmp, width_left);

        (*Copy) (src_x_tmp, src_y,
             dst_x_tmp, dst_y,
             width_this, height_this);

        width_tmp -= width_this;
        dst_x_tmp += width_this;
    }
    height -= height_this;
    dst_y += height_this;
    src_y = 0;
    }
}
#endif

static void
kaaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
         DDXPointPtr ppt, int *pwidth, int fSorted)
{
    ScreenPtr        pScreen = pDrawable->pScreen;
    KdScreenPriv (pScreen);
    KaaScreenPriv (pScreen);
    RegionPtr        pClip = fbGetCompositeClip(pGC);
    PixmapPtr        pPixmap;
    BoxPtr        pextent, pbox;
    int            nbox;
    int            extentX1, extentX2, extentY1, extentY2;
    int            fullX1, fullX2, fullY1;
    int            partX1, partX2;
    int            off_x, off_y;

    if (!pScreenPriv->enabled ||
    pGC->fillStyle != FillSolid ||
    !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
    !(*pKaaScr->info->PrepareSolid) (pPixmap,
                     pGC->alu,
                     pGC->planemask,
                     pGC->fgPixel))
    {
    KdCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
    return;
    }

    pextent = REGION_EXTENTS(pGC->pScreen, pClip);
    extentX1 = pextent->x1;
    extentY1 = pextent->y1;
    extentX2 = pextent->x2;
    extentY2 = pextent->y2;
    while (n--)
    {
    fullX1 = ppt->x;
    fullY1 = ppt->y;
    fullX2 = fullX1 + (int) *pwidth;
    ppt++;
    pwidth++;

    if (fullY1 < extentY1 || extentY2 <= fullY1)
        continue;

    if (fullX1 < extentX1)
        fullX1 = extentX1;

    if (fullX2 > extentX2)
        fullX2 = extentX2;

    if (fullX1 >= fullX2)
        continue;

    nbox = REGION_NUM_RECTS (pClip);
    if (nbox == 1)
    {
        (*pKaaScr->info->Solid) (fullX1 + off_x, fullY1 + off_y,
                     fullX2 + off_x, fullY1 + 1 + off_y);
    }
    else
    {
        pbox = REGION_RECTS(pClip);
        while(nbox--)
        {
        if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
        {
            partX1 = pbox->x1;
            if (partX1 < fullX1)
            partX1 = fullX1;
            partX2 = pbox->x2;
            if (partX2 > fullX2)
            partX2 = fullX2;
            if (partX2 > partX1)
            (*pKaaScr->info->Solid) (partX1 + off_x, fullY1 + off_y,
                         partX2 + off_x, fullY1 + 1 + off_y);
        }
        pbox++;
        }
    }
    }
    (*pKaaScr->info->DoneSolid) ();
    kaaDrawableDirty (pDrawable);
    kaaMarkSync (pDrawable->pScreen);
}

void
kaaCopyNtoN (DrawablePtr    pSrcDrawable,
         DrawablePtr    pDstDrawable,
         GCPtr        pGC,
         BoxPtr        pbox,
         int        nbox,
         int        dx,
         int        dy,
         Bool        reverse,
         Bool        upsidedown,
         Pixel        bitplane,
         void        *closure)
{
    KdScreenPriv (pDstDrawable->pScreen);
    KaaScreenPriv (pDstDrawable->pScreen);
    PixmapPtr pSrcPixmap, pDstPixmap;
    int        src_off_x, src_off_y;
    int        dst_off_x, dst_off_y;

    /* Migrate pixmaps to same place as destination */
    if (pScreenPriv->enabled && pSrcDrawable->type == DRAWABLE_PIXMAP) {
    if (kaaDrawableIsOffscreen (pDstDrawable))
        kaaPixmapUseScreen ((PixmapPtr) pSrcDrawable);
    else
        kaaPixmapUseMemory ((PixmapPtr) pSrcDrawable);
    }

    if (pScreenPriv->enabled &&
    (pSrcPixmap = kaaGetOffscreenPixmap (pSrcDrawable, &src_off_x,
&src_off_y)) &&
    (pDstPixmap = kaaGetOffscreenPixmap (pDstDrawable, &dst_off_x,
&dst_off_y)) &&
    (*pKaaScr->info->PrepareCopy) (pSrcPixmap,
                       pDstPixmap,
                       dx,
                       dy,
                       pGC ? pGC->alu : GXcopy,
                       pGC ? pGC->planemask : FB_ALLONES))
    {
    while (nbox--)
    {
        (*pKaaScr->info->Copy) (pbox->x1 + dx + src_off_x,
                    pbox->y1 + dy + src_off_y,
                    pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
                    pbox->x2 - pbox->x1,
                    pbox->y2 - pbox->y1);
        pbox++;
    }
    (*pKaaScr->info->DoneCopy) ();
    kaaMarkSync (pDstDrawable->pScreen);
    }
    else
    {
    kaaWaitSync (pDstDrawable->pScreen);
    fbCopyNtoN (pSrcDrawable, pDstDrawable, pGC,
            pbox, nbox, dx, dy, reverse, upsidedown,
            bitplane, closure);
    }
    kaaDrawableDirty (pDstDrawable);
}

static RegionPtr
kaaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
        int srcx, int srcy, int width, int height, int dstx, int dsty)
{
    return fbDoCopy (pSrcDrawable, pDstDrawable, pGC,
             srcx, srcy, width, height,
             dstx, dsty, kaaCopyNtoN, 0, 0);
}

static void
kaaPolyFillRect(DrawablePtr pDrawable,
        GCPtr        pGC,
        int        nrect,
        xRectangle  *prect)
{
    KdScreenPriv (pDrawable->pScreen);
    KaaScreenPriv (pDrawable->pScreen);
    RegionPtr        pClip = fbGetCompositeClip(pGC);
    PixmapPtr        pPixmap;
    register BoxPtr pbox;
    BoxPtr        pextent;
    int            extentX1, extentX2, extentY1, extentY2;
    int            fullX1, fullX2, fullY1, fullY2;
    int            partX1, partX2, partY1, partY2;
    int            xoff, yoff;
    int            xorg, yorg;
    int            n;

    if (!pScreenPriv->enabled ||
    pGC->fillStyle != FillSolid ||
    !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
    !(*pKaaScr->info->PrepareSolid) (pPixmap,
                     pGC->alu,
                     pGC->planemask,
                     pGC->fgPixel))
    {
    KdCheckPolyFillRect (pDrawable, pGC, nrect, prect);
    return;
    }

    xorg = pDrawable->x;
    yorg = pDrawable->y;

    pextent = REGION_EXTENTS(pGC->pScreen, pClip);
    extentX1 = pextent->x1;
    extentY1 = pextent->y1;
    extentX2 = pextent->x2;
    extentY2 = pextent->y2;
    while (nrect--)
    {
    fullX1 = prect->x + xorg;
    fullY1 = prect->y + yorg;
    fullX2 = fullX1 + (int) prect->width;
    fullY2 = fullY1 + (int) prect->height;
    prect++;

    if (fullX1 < extentX1)
        fullX1 = extentX1;

    if (fullY1 < extentY1)
        fullY1 = extentY1;

    if (fullX2 > extentX2)
        fullX2 = extentX2;

    if (fullY2 > extentY2)
        fullY2 = extentY2;

    if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
        continue;
    n = REGION_NUM_RECTS (pClip);
    if (n == 1)
    {
        (*pKaaScr->info->Solid) (fullX1 + xoff, fullY1 + yoff,
                     fullX2 + xoff, fullY2 + yoff);
    }
    else
    {
        pbox = REGION_RECTS(pClip);
        /*
         * clip the rectangle to each box in the clip region
         * this is logically equivalent to calling Intersect()
         */
        while(n--)
        {
        partX1 = pbox->x1;
        if (partX1 < fullX1)
            partX1 = fullX1;
        partY1 = pbox->y1;
        if (partY1 < fullY1)
            partY1 = fullY1;
        partX2 = pbox->x2;
        if (partX2 > fullX2)
            partX2 = fullX2;
        partY2 = pbox->y2;
        if (partY2 > fullY2)
            partY2 = fullY2;

        pbox++;

        if (partX1 < partX2 && partY1 < partY2)
            (*pKaaScr->info->Solid) (partX1 + xoff, partY1 + yoff,
                         partX2 + xoff, partY2 + yoff);
        }
    }
    }
    (*pKaaScr->info->DoneSolid) ();
    kaaDrawableDirty (pDrawable);
    kaaMarkSync (pDrawable->pScreen);
}

static void
kaaSolidBoxClipped (DrawablePtr    pDrawable,
            RegionPtr    pClip,
            FbBits    pm,
            FbBits    fg,
            int        x1,
            int        y1,
            int        x2,
            int        y2)
{
    KdScreenPriv (pDrawable->pScreen);
    KaaScreenPriv (pDrawable->pScreen);
    PixmapPtr   pPixmap;
    BoxPtr    pbox;
    int        nbox;
    int        xoff, yoff;
    int        partX1, partX2, partY1, partY2;

    if (!pScreenPriv->enabled ||
    !(pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) ||
    !(*pKaaScr->info->PrepareSolid) (pPixmap, GXcopy, pm, fg))
    {
    kaaWaitSync (pDrawable->pScreen);
    fg = fbReplicatePixel (fg, pDrawable->bitsPerPixel);
    fbSolidBoxClipped (pDrawable, pClip, x1, y1, x2, y2,
               fbAnd (GXcopy, fg, pm),
               fbXor (GXcopy, fg, pm));
    kaaDrawableDirty (pDrawable);
    return;
    }
    for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip);
     nbox--;
     pbox++)
    {
    partX1 = pbox->x1;
    if (partX1 < x1)
        partX1 = x1;

    partX2 = pbox->x2;
    if (partX2 > x2)
        partX2 = x2;

    if (partX2 <= partX1)
        continue;

    partY1 = pbox->y1;
    if (partY1 < y1)
        partY1 = y1;

    partY2 = pbox->y2;
    if (partY2 > y2)
        partY2 = y2;

    if (partY2 <= partY1)
        continue;

    (*pKaaScr->info->Solid) (partX1 + xoff, partY1 + yoff,
                 partX2 + xoff, partY2 + yoff);
    }
    (*pKaaScr->info->DoneSolid) ();
    kaaDrawableDirty (pDrawable);
    kaaMarkSync (pDrawable->pScreen);
}

static void
kaaImageGlyphBlt (DrawablePtr    pDrawable,
          GCPtr        pGC,
          int        x,
          int        y,
          unsigned int    nglyph,
          CharInfoPtr    *ppciInit,
          pointer    pglyphBase)
{
    FbGCPrivPtr        pPriv = fbGetGCPrivate(pGC);
    CharInfoPtr        *ppci;
    CharInfoPtr        pci;
    unsigned char   *pglyph;        /* pointer bits in glyph */
    int            gWidth, gHeight;    /* width and height of glyph */
    FbStride        gStride;        /* stride of glyph */
    Bool        opaque;
    int            n;
    int            gx, gy;
    void        (*glyph) (FbBits *,
                  FbStride,
                  int,
                  FbStip *,
                  FbBits,
                  int,
                  int);
    FbBits        *dst;
    FbStride        dstStride;
    int            dstBpp;
    int            dstXoff, dstYoff;
    FbBits        depthMask;

    depthMask = FbFullMask(pDrawable->depth);
    if ((pGC->planemask & depthMask) != depthMask)
    {
    KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit,
pglyphBase);
    return;
    }
    glyph = 0;
    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    switch (dstBpp) {
    case 8:    glyph = fbGlyph8; break;
    case 16:    glyph = fbGlyph16; break;
    case 24:    glyph = fbGlyph24; break;
    case 32:    glyph = fbGlyph32; break;
    }

    x += pDrawable->x;
    y += pDrawable->y;

    if (TERMINALFONT (pGC->font) && !glyph)
    {
    opaque = TRUE;
    }
    else
    {
    int        xBack, widthBack;
    int        yBack, heightBack;

    ppci = ppciInit;
    n = nglyph;
    widthBack = 0;
    while (n--)
        widthBack += (*ppci++)->metrics.characterWidth;

        xBack = x;
    if (widthBack < 0)
    {
        xBack += widthBack;
        widthBack = -widthBack;
    }
    yBack = y - FONTASCENT(pGC->font);
    heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
        kaaSolidBoxClipped (pDrawable,
                fbGetCompositeClip(pGC),
                pGC->planemask,
                pGC->bgPixel,
                xBack,
                yBack,
                xBack + widthBack,
                yBack + heightBack);
    opaque = FALSE;
    }

    kaaWaitSync (pDrawable->pScreen);
    kaaDrawableDirty (pDrawable);

    ppci = ppciInit;
    while (nglyph--)
    {
    pci = *ppci++;
    pglyph = FONTGLYPHBITS(pglyphBase, pci);
    gWidth = GLYPHWIDTHPIXELS(pci);
    gHeight = GLYPHHEIGHTPIXELS(pci);
    if (gWidth && gHeight)
    {
        gx = x + pci->metrics.leftSideBearing;
        gy = y - pci->metrics.ascent;
        if (glyph && gWidth <= sizeof (FbStip) * 8 &&
        fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
        {
        (*glyph) (dst + (gy + dstYoff) * dstStride,
              dstStride,
              dstBpp,
              (FbStip *) pglyph,
              pPriv->fg,
              gx + dstXoff,
              gHeight);
        }
        else
        {
        gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
        fbPutXYImage (pDrawable,
                  fbGetCompositeClip(pGC),
                  pPriv->fg,
                  pPriv->bg,
                  pPriv->pm,
                  GXcopy,
                  opaque,

                  gx,
                  gy,
                  gWidth, gHeight,

                  (FbStip *) pglyph,
                  gStride,
                  0);
        }
    }
    x += pci->metrics.characterWidth;
    }
}

static const GCOps    kaaOps = {
    kaaFillSpans,
    KdCheckSetSpans,
    KdCheckPutImage,
    kaaCopyArea,
    KdCheckCopyPlane,
    KdCheckPolyPoint,
    KdCheckPolylines,
    KdCheckPolySegment,
    miPolyRectangle,
    KdCheckPolyArc,
    miFillPolygon,
    kaaPolyFillRect,
    miPolyFillArc,
    miPolyText8,
    miPolyText16,
    miImageText8,
    miImageText16,
    kaaImageGlyphBlt,
    KdCheckPolyGlyphBlt,
    KdCheckPushPixels,
#ifdef NEED_LINEHELPER
    ,NULL
#endif
};

static void
kaaValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
{
    fbValidateGC (pGC, changes, pDrawable);

    if (kaaDrawableIsOffscreen (pDrawable))
    pGC->ops = (GCOps *) &kaaOps;
    else
    pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
}

GCFuncs    kaaGCFuncs = {
    kaaValidateGC,
    miChangeGC,
    miCopyGC,
    miDestroyGC,
    miChangeClip,
    miDestroyClip,
    miCopyClip
};

static int
kaaCreateGC (GCPtr pGC)
{
    if (!fbCreateGC (pGC))
    return FALSE;

    pGC->funcs = &kaaGCFuncs;

    return TRUE;
}


static void
kaaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
{
    RegionRec    rgnDst;
    int        dx, dy;
    PixmapPtr    pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap)
(pWin);

    dx = ptOldOrg.x - pWin->drawable.x;
    dy = ptOldOrg.y - pWin->drawable.y;
    REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);

    REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);

    REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip,
prgnSrc);
#ifdef COMPOSITE
    if (pPixmap->screen_x || pPixmap->screen_y)
    REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
              -pPixmap->screen_x, -pPixmap->screen_y);
#endif

    fbCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
          0,
          &rgnDst, dx, dy, kaaCopyNtoN, 0, 0);

    REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
}

static void
kaaFillRegionSolid (DrawablePtr    pDrawable,
            RegionPtr    pRegion,
            Pixel    pixel)
{
    KdScreenPriv(pDrawable->pScreen);
    KaaScreenPriv(pDrawable->pScreen);
    PixmapPtr pPixmap;
    int xoff, yoff;

    if (pScreenPriv->enabled &&
    (pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
    (*pKaaScr->info->PrepareSolid) (pPixmap, GXcopy, FB_ALLONES, pixel))
    {
    int    nbox = REGION_NUM_RECTS (pRegion);
    BoxPtr    pBox = REGION_RECTS (pRegion);

    while (nbox--)
    {
        (*pKaaScr->info->Solid) (pBox->x1 + xoff, pBox->y1 + yoff,
                     pBox->x2 + xoff, pBox->y2 + yoff);
        pBox++;
    }
    (*pKaaScr->info->DoneSolid) ();
    kaaMarkSync (pDrawable->pScreen);
    }
    else
    {
    kaaWaitSync (pDrawable->pScreen);
    fbFillRegionSolid (pDrawable, pRegion, 0,
               fbReplicatePixel (pixel, pDrawable->bitsPerPixel));
    }
    kaaDrawableDirty (pDrawable);
}

#if 0
static void
kaaFillRegionTiled (DrawablePtr pDrawable,
            RegionPtr    pRegion,
            PixmapPtr    pTile)
{
    KdScreenPriv(pDrawable->pScreen);
    KaaScreenPriv(pDrawable->pScreen);
    PixmapPtr pPixmap;
    int xoff, yoff;
    int tileWidth, tileHeight;
    int nbox = REGION_NUM_RECTS (pRegion);
    BoxPtr pBox = REGION_RECTS (pRegion);
    Bool ret = FALSE;

    tileWidth = pTile->drawable.width;
    tileHeight = pTile->drawable.height;

    /* If we're filling with a solid color, grab it out and go to
     * FillRegionSolid, saving numerous copies.
     */
    if (tileWidth == 1 && tileHeight == 1)
    return kaaFillRegionSolid(pDrawable, pRegion,
                  exaGetPixmapFirstPixel (pTile), planemask,
                 alu);

     REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);


  if (pScreenPriv->enabled &&
    (pPixmap = kaaGetOffscreenPixmap (pDrawable, &xoff, &yoff)) &&
    (*pKaaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1,     GXcopy,
FB_ALLONES))
    {

    if ((*pKaaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu,
planemask))
    {
    while (nbox--)
    {
        int height = pBox->y2 - pBox->y1;
        int dstY = pBox->y1;
        int tileY;

           modulus(dstY - yoff - pDrawable->y -
(WindowPtr)pDrawable->origin.y, tileHeight, tileY);

        while (height > 0) {
        int width = pBox->x2 - pBox->x1;
        int dstX = pBox->x1;
        int tileX;
        int h = tileHeight - tileY;

        if (h > height)
            h = height;
        height -= h;

        modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
            tileX);

        while (width > 0) {
            int w = tileWidth - tileX;
            if (w > width)
            w = width;
            width -= w;

            (*pKaaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
                        w, h);
            dstX += w;
            tileX = 0;
        }
        dstY += h;
        tileY = 0;
        }
        pBox++;
    }
    (*pKaaScr->info->DoneCopy) (pPixmap);
    kaaMarkSync(pDrawable->pScreen);

    ret = TRUE;
    }

    return ret;
}
#endif

static void
kaaPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
{

    if (!REGION_NUM_RECTS(pRegion))
    return;
    switch (what) {
    case PW_BACKGROUND:
    switch (pWin->backgroundState) {
    case None:
        return;
    case ParentRelative:
        do {
        pWin = pWin->parent;
        } while (pWin->backgroundState == ParentRelative);
        (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
                                 what);
        return;
    case BackgroundPixel:
        kaaFillRegionSolid((DrawablePtr)pWin, pRegion,
pWin->background.pixel);
        return;
#if 0
    case BackgroundPixmap:
        kaaFillRegionTiled((DrawablePtr)pWin, pRegion,
pWin->background.pixmap);
        return;
#endif
        }
        break;
    case PW_BORDER:
    if (pWin->borderIsPixel)
    {
        kaaFillRegionSolid((DrawablePtr)pWin, pRegion, pWin->border.pixel);
        return;
    }
#if 0
    else
    {
        kaaFillRegionTiled((DrawablePtr)pWin, pRegion, pWin->border.pixmap);
        return;
    }
#endif
    break;
    }
    KdCheckPaintWindow (pWin, pRegion, what);
}

Bool
kaaDrawInit (ScreenPtr        pScreen,
         KaaScreenInfoPtr    pScreenInfo)
{
    KaaScreenPrivPtr pKaaScr;
    KdScreenPriv(pScreen);
    KdScreenInfo *screen = pScreenPriv->screen;
#ifdef RENDER
    PictureScreenPtr    ps = GetPictureScreenIfSet(pScreen);
#endif

    if (kaaGeneration != serverGeneration)
    {
    kaaScreenPrivateIndex = AllocateScreenPrivateIndex();
    kaaPixmapPrivateIndex = AllocatePixmapPrivateIndex();
    kaaGeneration = serverGeneration;
    }

    pKaaScr = xalloc (sizeof (KaaScreenPrivRec));

    if (!pKaaScr)
    return FALSE;

    pKaaScr->info = pScreenInfo;

    pScreen->devPrivates[kaaScreenPrivateIndex].ptr = (pointer) pKaaScr;

    /*
     * Hook up asynchronous drawing
     */
    KdScreenInitAsync (pScreen);
    /*
     * Replace various fb screen functions
     */
    pScreen->CreateGC = kaaCreateGC;
    pScreen->CopyWindow = kaaCopyWindow;
    pScreen->PaintWindowBackground = kaaPaintWindow;
    pScreen->PaintWindowBorder = kaaPaintWindow;
#ifdef RENDER
    if (ps) {
    ps->Composite = kaaComposite;
    ps->RasterizeTrapezoid = kaaRasterizeTrapezoid;
    }
#endif

    /*
     * Hookup offscreen pixmaps
     */
    if ((pKaaScr->info->flags & KAA_OFFSCREEN_PIXMAPS) &&
    screen->off_screen_base < screen->memory_size)
    {
    if (!AllocatePixmapPrivate(pScreen, kaaPixmapPrivateIndex,
                   sizeof (KaaPixmapPrivRec)))
        return FALSE;
    pScreen->CreatePixmap = kaaCreatePixmap;
    pScreen->DestroyPixmap = kaaDestroyPixmap;
    }
    else
    {
    if (!AllocatePixmapPrivate(pScreen, kaaPixmapPrivateIndex, 0))
        return FALSE;
    }

    return TRUE;
}

void
kaaDrawFini (ScreenPtr pScreen)
{
    KaaScreenPriv(pScreen);

    xfree (pKaaScr);
}

void
kaaMarkSync (ScreenPtr pScreen)
{
    KdScreenPriv(pScreen);
    KaaScreenPriv(pScreen);

    pScreenPriv->card->needSync = TRUE;
    if (pKaaScr->info->markSync != NULL) {
    pScreenPriv->card->lastMarker = (*pKaaScr->info->markSync) (pScreen);
    }
}

void
kaaWaitSync (ScreenPtr pScreen)
{
    KdScreenPriv(pScreen);
    KaaScreenPriv(pScreen);
    KdCardInfo *card = pScreenPriv->card;

    if (card->needSync) {
    (*pKaaScr->info->waitMarker) (pScreen, card->lastMarker);
    card->needSync = FALSE;
    }
}


On Fri, Oct 30, 2009 at 12:45 PM, Daniel Stone <daniel at fooishbar.org> wrote:

> Hi,
>
> On Fri, Oct 30, 2009 at 11:04:57AM +0530, prudhvi raj wrote:
> > I have added the acceleration support to the Xfbdev server (in X windows
> > version 11 release 7.4) in order to improve the performance on ARM 11
> board.
> > Among the accelerated hooks supported by KAA we have implemented
> > polyFillRect and CopyArea.
> >
> > But when we run some client application on this accelerated server the
> calls
> > to the accelerated copyArea (which internally calls the hardware bitBlit
> > function) are coming very less frequently compared to the software blit
> > calls.
> >
> > During my observation i have found some partially implemented functions
> like
> > kaaFillRegionTiled() etc which may internally call the blit operation
> > through (*pKaaScr->info->Copy) hook.
> >
> > If at all this function could help to improve the performance of blit,
> can
> > you provide the fully implemented kaaFillRegionTiled().
> >
> > When i have run one sample client application (gtkDemo) the fbBlt()
> function
> > got called around 40000 times where as the hardware accelerated blit
> > function called through kaaCopyNtoN (which calls (*pKaaScr->info->Copy)
> > internally) very few times (around 2500 times only) compared to fbBlt.
> >
> > Can you provide more clarity why are most of the Blit calls are routed
> > through software fallbacks.
>
> Firstly, we very strongly recommend using Xorg instead of KDrive, and
> also secondly, it's really very hard to debug your code without having
> access to it.  Are you able to post it somewhere?
>
> Cheers,
> Daniel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.x.org/archives/xorg-devel/attachments/20091030/6a7bce91/attachment-0001.html 


More information about the xorg-devel mailing list