示例#1
0
Bool
tridentPrepareCopy (DrawablePtr	pSrcDrawable,
		    DrawablePtr	pDstDrawable,
		    int		dx,
		    int		dy,
		    int		alu,
		    Pixel	pm)
{
    FbBits  depthMask = FbFullMask(pDstDrawable->depth);
    
    if ((pm & depthMask) == depthMask)
    {
	KdScreenPriv(pDstDrawable->pScreen);
	tridentCardInfo(pScreenPriv);
	cop = tridentc->cop;
	_tridentInit(cop,tridentc);
	cop->multi = COP_MULTI_PATTERN;
	cop->multi = COP_MULTI_ROP | tridentRop[alu];
	cmd = COP_OP_BLT | COP_SCL_OPAQUE | COP_OP_ROP | COP_OP_FB;
	if (dx < 0 || dy < 0)
	    cmd |= COP_X_REVERSE;
	return TRUE;
    }
    else
	return FALSE;
}
示例#2
0
Bool
GLAMOExaPrepareCopy(PixmapPtr       pSrc,
		    PixmapPtr       pDst,
		    int             dx,
		    int             dy,
		    int             alu,
		    Pixel           pm)
{
	ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
	GlamoPtr pGlamo = GlamoPTR(pScrn);

    RING_LOCALS;

    FbBits mask;

    CARD32 src_offset, dst_offset;
    CARD16 src_pitch, dst_pitch;
    CARD16 op;

	if (pSrc->drawable.bitsPerPixel != 16 ||
	    pDst->drawable.bitsPerPixel != 16)
		GLAMO_FALLBACK(("Only 16bpp is supported"));

	mask = FbFullMask(16);
	if ((pm & mask) != mask) {
		GLAMO_FALLBACK(("Can't do planemask 0x%08x",
				(unsigned int) pm));
	}

	src_offset = exaGetPixmapOffset(pSrc);
	src_pitch = pSrc->devKind;

	dst_offset = exaGetPixmapOffset(pDst);
	dst_pitch = pDst->devKind;

	op = GLAMOBltRop[alu] << 8;

    BEGIN_CMDQ(20);
    OUT_REG(GLAMO_REG_2D_SRC_ADDRL, src_offset & 0xffff);
	OUT_REG(GLAMO_REG_2D_SRC_ADDRH, (src_offset >> 16) & 0x7f);
	OUT_REG(GLAMO_REG_2D_SRC_PITCH, src_pitch & 0x7ff);

	OUT_REG(GLAMO_REG_2D_DST_ADDRL, dst_offset & 0xffff);
	OUT_REG(GLAMO_REG_2D_DST_ADDRH, (dst_offset >> 16) & 0x7f);
	OUT_REG(GLAMO_REG_2D_DST_PITCH, dst_pitch & 0x7ff);
	OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pDst->drawable.height);

	OUT_REG(GLAMO_REG_2D_COMMAND2, op);
	OUT_REG(GLAMO_REG_2D_ID1, 0);
	OUT_REG(GLAMO_REG_2D_ID2, 0);
	END_CMDQ();


	return TRUE;
}
示例#3
0
pixman_bits_t
fbReplicatePixel (Pixel p, int bpp)
{
    pixman_bits_t  b = p;

    b &= FbFullMask (bpp);
    while (bpp < FB_UNIT)
    {
	b |= b << bpp;
	bpp <<= 1;
    }
    return b;
}
示例#4
0
static Bool
smiPrepareSolid (PixmapPtr    pPixmap,
		 int		alu,
		 Pixel		pm,
		 Pixel		fg)
{
    if (~pm & FbFullMask(pPixmap->drawable.depth))
	return FALSE;
    
    if (!smiSetup (pPixmap->drawable.pScreen, 3))
	return FALSE;
    
    accel_cmd = smiSolidRop[alu] | SMI_BITBLT | SMI_START_ENGINE;
    dpr->fg = fg;
    dpr->mask3 = 0xffffffff;
    dpr->mask4 = 0xffffffff;
    return TRUE;
}
示例#5
0
static Bool
nvidiaPrepareSolid (PixmapPtr   pPixmap,
                    int		alu,
                    Pixel	pm,
                    Pixel	fg)
{
    ScreenPtr pScreen = pPixmap->drawable.pScreen;
    KdScreenPriv(pScreen);
    nvidiaCardInfo(pScreenPriv);

    card = nvidiac;
    if (~pm & FbFullMask(pPixmap->drawable.depth))
        return FALSE;
    nvidiaWait (nvidiac, &nvidiac->rop->FifoFree, 1);
    nvidiac->rop->Rop3 = nvidiaRop[alu];
    nvidiaWait (nvidiac, &nvidiac->rect->FifoFree, 1);
    nvidiac->rect->Color1A = fg;
    return TRUE;
}
示例#6
0
static Bool
nvidiaPrepareCopy (PixmapPtr	pSrcPixmap,
                   PixmapPtr	pDstPixmap,
                   int		dx,
                   int		dy,
                   int		alu,
                   Pixel	pm)
{
    ScreenPtr pScreen = pDstPixmap->drawable.pScreen;
    KdScreenPriv(pScreen);
    nvidiaCardInfo(pScreenPriv);

    card = nvidiac;
    if (~pm & FbFullMask(pDstPixmap->drawable.depth))
        return FALSE;
    nvidiaWait (nvidiac, &card->rop->FifoFree, 1);
    nvidiac->rop->Rop3 = nvidiaRop[alu];
    return TRUE;
}
示例#7
0
Bool
tridentPrepareSolid (DrawablePtr    pDrawable,
		     int	    alu,
		     Pixel	    pm,
		     Pixel	    fg)
{
    FbBits  depthMask = FbFullMask(pDrawable->depth);
    
    if ((pm & depthMask) != depthMask)
	return FALSE;
    else
    {
	KdScreenPriv(pDrawable->pScreen);
	tridentCardInfo(pScreenPriv);
	cop = tridentc->cop;
	
	tridentFillPix(pDrawable->bitsPerPixel,fg);
	_tridentInit(cop,tridentc);
	_tridentSetSolidRect(cop,fg,alu,cmd);
	return TRUE;
    }
}
示例#8
0
static Bool
smiPrepareCopy (PixmapPtr	pSrcPixmap,
		PixmapPtr	pDstPixmap,
		int		dx,
		int		dy,
		int		alu,
		Pixel		pm)
{
    if (~pm & FbFullMask(pSrcPixmap->drawable.depth))
	return FALSE;
    
    if (!smiSetup (pSrcPixmap->drawable.pScreen, 0))
	return FALSE;
    
    accel_cmd = smiBltRop[alu] | SMI_BITBLT | SMI_START_ENGINE;
    
    copyDx = dx;
    copyDy = dy;
    if (dy < 0 || (dy == 0 && dx < 0))
	accel_cmd |= SMI_RIGHT_TO_LEFT;
    return TRUE;
}
示例#9
0
Bool
GLAMOExaPrepareSolid(PixmapPtr      pPix,
		     int            alu,
		     Pixel          pm,
		     Pixel          fg)
{
	ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
	GlamoPtr pGlamo = GlamoPTR(pScrn);

	CARD32 offset;
    CARD16 op, pitch;
	FbBits mask;
	RING_LOCALS;

	if (pPix->drawable.bitsPerPixel != 16)
		GLAMO_FALLBACK(("Only 16bpp is supported\n"));

	mask = FbFullMask(16);
	if ((pm & mask) != mask)
		GLAMO_FALLBACK(("Can't do planemask 0x%08x\n",
				(unsigned int) pm));

	op = GLAMOSolidRop[alu] << 8;
	offset = exaGetPixmapOffset(pPix);
	pitch = pPix->devKind;

	BEGIN_CMDQ(16);
	OUT_REG(GLAMO_REG_2D_DST_ADDRL, offset & 0xffff);
	OUT_REG(GLAMO_REG_2D_DST_ADDRH, (offset >> 16) & 0x7f);
	OUT_REG(GLAMO_REG_2D_DST_PITCH, pitch & 0x7ff);
	OUT_REG(GLAMO_REG_2D_DST_HEIGHT, pPix->drawable.height);
	OUT_REG(GLAMO_REG_2D_PAT_FG, fg);
	OUT_REG(GLAMO_REG_2D_COMMAND2, op);
	OUT_REG(GLAMO_REG_2D_ID1, 0);
	OUT_REG(GLAMO_REG_2D_ID2, 0);
	END_CMDQ();

	return TRUE;
}
示例#10
0
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;
    }
}
示例#11
0
void
xglValidateGC (GCPtr	     pGC,
	       unsigned long changes,
	       DrawablePtr   pDrawable)
{
    XGL_GC_PRIV (pGC);

    if (changes & GCTile)
    {
	if (!pGC->tileIsPixel &&
	    FbEvenTile (pGC->tile.pixmap->drawable.width *
			pDrawable->bitsPerPixel))
	    xglSyncBits (&pGC->tile.pixmap->drawable, NULL);
    }

    if (changes & GCStipple)
    {
	if (pGC->stipple)
	    xglSyncBits (&pGC->stipple->drawable, NULL);
    }

    XGL_GC_UNWRAP (funcs);
    XGL_GC_UNWRAP (ops);
    (*pGC->funcs->ValidateGC) (pGC, changes, pDrawable);
    XGL_GC_WRAP (funcs, (GCFuncs *) &xglGCFuncs);
    XGL_GC_WRAP (ops, (GCOps *) &xglGCOps);

    if (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
    {
	XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

	if (pPixmapPriv->pVisual && pPixmapPriv->pVisual->format.surface)
	{
	    glitz_format_t *format;

	    format = pPixmapPriv->pVisual->format.surface;
	    if (format->id != pGCPriv->id)
	    {
		XGL_SCREEN_PRIV (pDrawable->pScreen);

		pGCPriv->flags |= xglGCSoftwareDrawableFlag;

		if (pGCPriv->fg)
		    glitz_surface_destroy (pGCPriv->fg);

		pGCPriv->fg = glitz_surface_create (pScreenPriv->drawable,
						    format, 1, 1, 0, NULL);
		if (pGCPriv->fg)
		    glitz_surface_set_fill (pGCPriv->fg, GLITZ_FILL_REPEAT);

		if (pGCPriv->bg)
		    glitz_surface_destroy (pGCPriv->bg);

		pGCPriv->bg = glitz_surface_create (pScreenPriv->drawable,
						    format, 1, 1, 0, NULL);
		if (pGCPriv->bg)
		    glitz_surface_set_fill (pGCPriv->bg, GLITZ_FILL_REPEAT);

		pGCPriv->id = format->id;

		if (pGCPriv->fg && pGCPriv->bg)
		{
		    changes |= (GCForeground | GCBackground);
		    pGCPriv->flags &= ~xglGCSoftwareDrawableFlag;
		}
	    }
	}
	else
	    pGCPriv->flags |= xglGCSoftwareDrawableFlag;
    }

    if (changes & GCFunction)
    {
	switch (pGC->alu) {
	case GXclear:
	    pGCPriv->op = GLITZ_OPERATOR_CLEAR;
	    pGCPriv->flags &= ~xglGCBadFunctionFlag;
	    break;
	case GXcopy:
	    pGCPriv->op = GLITZ_OPERATOR_SRC;
	    pGCPriv->flags &= ~xglGCBadFunctionFlag;
	    break;
	case GXnoop:
	    pGCPriv->op = GLITZ_OPERATOR_DST;
	    pGCPriv->flags &= ~xglGCBadFunctionFlag;
	    break;
	default:
	    pGCPriv->flags |= xglGCBadFunctionFlag;
	    break;
	}
    }

    if (changes & GCPlaneMask)
    {
	FbBits mask;

	mask = FbFullMask (pDrawable->depth);

	if ((pGC->planemask & mask) != mask)
	    pGCPriv->flags |= xglGCPlaneMaskFlag;
	else
	    pGCPriv->flags &= ~xglGCPlaneMaskFlag;
    }

    if (!(pGCPriv->flags & xglGCSoftwareDrawableFlag))
    {
	if (changes & (GCForeground | GCBackground))
	{
	    glitz_pixel_format_t format;
	    glitz_buffer_t	 *buffer;
	    CARD32		 pixel;

	    XGL_DRAWABLE_PIXMAP_PRIV (pDrawable);

	    format.fourcc	  = GLITZ_FOURCC_RGB;
	    format.masks	  = pPixmapPriv->pVisual->pPixel->masks;
	    format.xoffset	  = 0;
	    format.skip_lines     = 0;
	    format.bytes_per_line = sizeof (CARD32);
	    format.scanline_order = GLITZ_PIXEL_SCANLINE_ORDER_BOTTOM_UP;

	    buffer = glitz_buffer_create_for_data (&pixel);

	    if (changes & GCForeground)
	    {
		pixel = pGC->fgPixel;
		glitz_set_pixels (pGCPriv->fg, 0, 0, 1, 1, &format, buffer);
	    }

	    if (changes & GCBackground)
	    {
		pixel = pGC->bgPixel;
		glitz_set_pixels (pGCPriv->bg, 0, 0, 1, 1, &format, buffer);
	    }

	    glitz_buffer_destroy (buffer);
	}
    }
}
示例#12
0
void
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    FbBits mask;

    /*
     * if the client clip is different or moved OR the subwindowMode has
     * changed OR the window's clip has changed since the last validation
     * we need to recompute the composite clip 
     */

    if ((changes &
         (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
        ) {
        miComputeCompositeClip(pGC, pDrawable);
    }

    if (pPriv->bpp != pDrawable->bitsPerPixel) {
        changes |= GCStipple | GCForeground | GCBackground | GCPlaneMask;
        pPriv->bpp = pDrawable->bitsPerPixel;
    }
    if ((changes & GCTile) && fbGetRotatedPixmap(pGC)) {
        (*pGC->pScreen->DestroyPixmap) (fbGetRotatedPixmap(pGC));
        fbGetRotatedPixmap(pGC) = 0;
    }

    if (pGC->fillStyle == FillTiled) {
        PixmapPtr pOldTile, pNewTile;

        pOldTile = pGC->tile.pixmap;
        if (pOldTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
            pNewTile = fbGetRotatedPixmap(pGC);
            if (!pNewTile ||
                pNewTile->drawable.bitsPerPixel != pDrawable->bitsPerPixel) {
                if (pNewTile)
                    (*pGC->pScreen->DestroyPixmap) (pNewTile);
                pNewTile =
                    fb24_32ReformatTile(pOldTile, pDrawable->bitsPerPixel);
            }
            if (pNewTile) {
                fbGetRotatedPixmap(pGC) = pOldTile;
                pGC->tile.pixmap = pNewTile;
                changes |= GCTile;
            }
        }
    }
    if (changes & GCTile) {
        if (!pGC->tileIsPixel &&
            FbEvenTile(pGC->tile.pixmap->drawable.width *
                       pDrawable->bitsPerPixel))
            fbPadPixmap(pGC->tile.pixmap);
    }
    if (changes & GCStipple) {
        pPriv->evenStipple = FALSE;

        if (pGC->stipple) {

            /* can we do an even stipple ?? */
            if (FbEvenStip(pGC->stipple->drawable.width,
                           pDrawable->bitsPerPixel) &&
                (fbCanEvenStipple(pGC->stipple, pDrawable->bitsPerPixel)))
                pPriv->evenStipple = TRUE;

            if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
                FB_UNIT)
                fbPadPixmap(pGC->stipple);
        }
    }
    /*
     * Recompute reduced rop values
     */
    if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
        int s;
        FbBits depthMask;

        mask = FbFullMask(pDrawable->bitsPerPixel);
        depthMask = FbFullMask(pDrawable->depth);

        pPriv->fg = pGC->fgPixel & mask;
        pPriv->bg = pGC->bgPixel & mask;

        if ((pGC->planemask & depthMask) == depthMask)
            pPriv->pm = mask;
        else
            pPriv->pm = pGC->planemask & mask;

        s = pDrawable->bitsPerPixel;
        while (s < FB_UNIT) {
            pPriv->fg |= pPriv->fg << s;
            pPriv->bg |= pPriv->bg << s;
            pPriv->pm |= pPriv->pm << s;
            s <<= 1;
        }
        pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
        pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
    }
    if (changes & GCDashList) {
        unsigned short n = pGC->numInDashList;
        unsigned char *dash = pGC->dash;
        unsigned int dashLength = 0;

        while (n--)
            dashLength += (unsigned int) *dash++;
        pPriv->dashLength = dashLength;
    }
}
示例#13
0
/* Optimized version of fbCompositeSolidMask_nx8x8888 */
void
SafeAlphaCompositeSolidMask_nx8x8888(
    CARD8      op,
    PicturePtr pSrc,
    PicturePtr pMask,
    PicturePtr pDst,
    INT16      xSrc,
    INT16      ySrc,
    INT16      xMask,
    INT16      yMask,
    INT16      xDst,
    INT16      yDst,
    CARD16     width,
    CARD16     height)
{
    CARD32	src, srca;
    CARD32	*dstLine, *dst, d, dstMask;
    CARD8	*maskLine, *mask, m;
    FbStride	dstStride, maskStride;
    CARD16	w;

    fbComposeGetSolid(pSrc, src, pDst->format);

    dstMask = FbFullMask (pDst->pDrawable->depth);
    srca = src >> 24;
    if (src == 0)
        return;

    fbComposeGetStart (pDst, xDst, yDst, CARD32, dstStride, dstLine, 1);
    fbComposeGetStart (pMask, xMask, yMask, CARD8, maskStride, maskLine, 1);

    if (dstMask == FB_ALLONES && pDst->pDrawable->bitsPerPixel == 32 &&
            width * height > rootless_CompositePixels_threshold &&
            SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels)
    {
        void *srcp[2], *destp[2];
        unsigned int dest_rowbytes[2];
        unsigned int fn;

        srcp[0] = &src;
        srcp[1] = &src;
        /* null rowbytes pointer means use first value as a constant */
        destp[0] = dstLine;
        destp[1] = dstLine;
        dest_rowbytes[0] = dstStride * 4;
        dest_rowbytes[1] = dest_rowbytes[0];
        fn = RL_COMPOSITE_FUNCTION(RL_COMPOSITE_OVER, RL_DEPTH_ARGB8888,
                                   RL_DEPTH_A8, RL_DEPTH_ARGB8888);

        if (SCREENREC(pDst->pDrawable->pScreen)->imp->CompositePixels(
                    width, height, fn, srcp, NULL,
                    maskLine, maskStride,
                    destp, dest_rowbytes) == Success)
        {
            return;
        }
    }

    while (height--)
    {
        dst = dstLine;
        dstLine += dstStride;
        mask = maskLine;
        maskLine += maskStride;
        w = width;

        while (w--)
        {
            m = *mask++;
            if (m == 0xff)
            {
                if (srca == 0xff)
                    *dst = src & dstMask;
                else
                    *dst = fbOver (src, *dst) & dstMask;
            }
            else if (m)
            {
                d = fbIn (src, m);
                *dst = fbOver (d, *dst) & dstMask;
            }
            dst++;
        }
    }
}
示例#14
0
文件: fbgc.c 项目: mirror/xserver
void
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    FbBits mask;

    /*
     * if the client clip is different or moved OR the subwindowMode has
     * changed OR the window's clip has changed since the last validation
     * we need to recompute the composite clip
     */

    if ((changes &
         (GCClipXOrigin | GCClipYOrigin | GCClipMask | GCSubwindowMode)) ||
        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
        ) {
        miComputeCompositeClip(pGC, pDrawable);
    }

    if (changes & GCTile) {
        if (!pGC->tileIsPixel &&
            FbEvenTile(pGC->tile.pixmap->drawable.width *
                       pDrawable->bitsPerPixel))
            fbPadPixmap(pGC->tile.pixmap);
    }
    if (changes & GCStipple) {
        if (pGC->stipple) {
            if (pGC->stipple->drawable.width * pDrawable->bitsPerPixel <
                FB_UNIT)
                fbPadPixmap(pGC->stipple);
        }
    }
    /*
     * Recompute reduced rop values
     */
    if (changes & (GCForeground | GCBackground | GCPlaneMask | GCFunction)) {
        int s;
        FbBits depthMask;

        mask = FbFullMask(pDrawable->bitsPerPixel);
        depthMask = FbFullMask(pDrawable->depth);

        pPriv->fg = pGC->fgPixel & mask;
        pPriv->bg = pGC->bgPixel & mask;

        if ((pGC->planemask & depthMask) == depthMask)
            pPriv->pm = mask;
        else
            pPriv->pm = pGC->planemask & mask;

        s = pDrawable->bitsPerPixel;
        while (s < FB_UNIT) {
            pPriv->fg |= pPriv->fg << s;
            pPriv->bg |= pPriv->bg << s;
            pPriv->pm |= pPriv->pm << s;
            s <<= 1;
        }
        pPriv->and = fbAnd(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->xor = fbXor(pGC->alu, pPriv->fg, pPriv->pm);
        pPriv->bgand = fbAnd(pGC->alu, pPriv->bg, pPriv->pm);
        pPriv->bgxor = fbXor(pGC->alu, pPriv->bg, pPriv->pm);
    }
    if (changes & GCDashList) {
        unsigned short n = pGC->numInDashList;
        unsigned char *dash = pGC->dash;
        unsigned int dashLength = 0;

        while (n--)
            dashLength += (unsigned int) *dash++;
        pPriv->dashLength = dashLength;
    }
}