Пример #1
0
/**
 * Implements CopyArea from the GPU to the CPU using glReadPixels from the
 * source FBO.
 */
static Bool
glamor_copy_fbo_cpu(DrawablePtr src,
                    DrawablePtr dst,
                    GCPtr gc,
                    BoxPtr box,
                    int nbox,
                    int dx,
                    int dy,
                    Bool reverse,
                    Bool upsidedown,
                    Pixel bitplane,
                    void *closure)
{
    ScreenPtr screen = dst->pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    PixmapPtr src_pixmap = glamor_get_drawable_pixmap(src);
    FbBits *dst_bits;
    FbStride dst_stride;
    int dst_bpp;
    int src_xoff, src_yoff;
    int dst_xoff, dst_yoff;

    if (gc && gc->alu != GXcopy)
        goto bail;

    if (gc && !glamor_pm_is_solid(dst, gc->planemask))
        goto bail;

    glamor_make_current(glamor_priv);
    glamor_prepare_access(dst, GLAMOR_ACCESS_RW);

    glamor_get_drawable_deltas(src, src_pixmap, &src_xoff, &src_yoff);

    fbGetDrawable(dst, dst_bits, dst_stride, dst_bpp, dst_xoff, dst_yoff);

    glamor_download_boxes(src_pixmap, box, nbox, src_xoff + dx, src_yoff + dy,
                          dst_xoff, dst_yoff,
                          (uint8_t *) dst_bits, dst_stride * sizeof (FbBits));
    glamor_finish_access(dst);

    return TRUE;

bail:
    return FALSE;
}
Пример #2
0
void
fbFillRegionSolid(DrawablePtr pDrawable,
                  RegionPtr pRegion, FbBits and, FbBits xor)
{
    FbBits *dst;
    FbStride dstStride;
    int dstBpp;
    int dstXoff, dstYoff;
    int n = RegionNumRects(pRegion);
    BoxPtr pbox = RegionRects(pRegion);

#ifndef FB_ACCESS_WRAPPER
    int try_mmx = 0;

    if (!and)
        try_mmx = 1;
#endif

    fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);

    while (n--) {
#ifndef FB_ACCESS_WRAPPER
        if (!try_mmx || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
                                     pbox->x1 + dstXoff, pbox->y1 + dstYoff,
                                     (pbox->x2 - pbox->x1),
                                     (pbox->y2 - pbox->y1), xor)) {
#endif
            fbSolid(dst + (pbox->y1 + dstYoff) * dstStride,
                    dstStride,
                    (pbox->x1 + dstXoff) * dstBpp,
                    dstBpp,
                    (pbox->x2 - pbox->x1) * dstBpp,
                    pbox->y2 - pbox->y1, and, xor);
#ifndef FB_ACCESS_WRAPPER
        }
#endif
        fbValidateDrawable(pDrawable);
        pbox++;
    }

    fbFinishAccess(pDrawable);
}
Пример #3
0
void
fbImageGlyphBlt(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 = 0;

    FbStride dstStride = 0;

    int dstBpp = 0;

    int dstXoff = 0, dstYoff = 0;

    glyph = 0;
    if (pPriv->and == 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);
        fbSolidBoxClipped(pDrawable,
                          fbGetCompositeClip(pGC),
                          xBack,
                          yBack,
                          xBack + widthBack,
                          yBack + heightBack,
                          fbAnd(GXcopy, pPriv->bg, pPriv->pm),
                          fbXor(GXcopy, pPriv->bg, pPriv->pm));
        opaque = FALSE;
    }

    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;
    }
}
Пример #4
0
void
fbPolyGlyphBlt(DrawablePtr pDrawable,
               GCPtr pGC,
               int x,
               int y,
               unsigned int nglyph, CharInfoPtr * ppci, pointer pglyphBase)
{
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);

    CharInfoPtr pci;

    unsigned char *pglyph;      /* pointer bits in glyph */

    int gx, gy;

    int gWidth, gHeight;        /* width and height of glyph */

    FbStride gStride;           /* stride of glyph */

    void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);

    FbBits *dst = 0;

    FbStride dstStride = 0;

    int dstBpp = 0;

    int dstXoff = 0, dstYoff = 0;

    glyph = 0;
    if (pGC->fillStyle == FillSolid && pPriv->and == 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;

    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->xor, gx + dstXoff, gHeight);
            }
            else
            {
                gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
                fbPushImage(pDrawable,
                            pGC,
                            (FbStip *) pglyph,
                            gStride, 0, gx, gy, gWidth, gHeight);
            }
        }
        x += pci->metrics.characterWidth;
    }
}
Пример #5
0
void
fbGetImage (DrawablePtr	    pDrawable,
	    int		    x,
	    int		    y,
	    int		    w,
	    int		    h,
	    unsigned int    format,
	    unsigned long   planeMask,
	    char	    *d)
{
    FbBits	    *src;
    FbStride	    srcStride;
    int		    srcBpp;
    int		    srcXoff, srcYoff;
    FbStip	    *dst;
    FbStride	    dstStride;
    
    /*
     * XFree86 DDX empties the root borderClip when the VT is
     * switched away; this checks for that case
     */
    if (!fbDrawableEnabled(pDrawable))
	return;
    
#ifdef FB_24_32BIT
    if (format == ZPixmap &&
	pDrawable->bitsPerPixel != BitsPerPixel (pDrawable->depth))
    {
	fb24_32GetImage (pDrawable, x, y, w, h, format, planeMask, d);
	return;
    }
#endif
    
    fbGetDrawable (pDrawable, src, srcStride, srcBpp, srcXoff, srcYoff);
    
    x += pDrawable->x;
    y += pDrawable->y;
    
    dst = (FbStip *) d;
    if (format == ZPixmap || srcBpp == 1)
    {
	FbBits	pm;

	pm = fbReplicatePixel (planeMask, srcBpp);
	dstStride = PixmapBytePad(w, pDrawable->depth);
	if (pm != FB_ALLONES)
	    memset (d, 0, dstStride * h);
	dstStride /= sizeof (FbStip);
	fbBltStip ((FbStip *) (src + (y + srcYoff) * srcStride), 
		   FbBitsStrideToStipStride(srcStride),
		   (x + srcXoff) * srcBpp,
		   
		   dst,
		   dstStride,
		   0,
		   
		   w * srcBpp, h,

		   GXcopy,
		   pm,
		   srcBpp);
    }
    else
    {
	dstStride = BitmapBytePad(w) / sizeof (FbStip);
	fbBltPlane (src + (y + srcYoff) * srcStride,
		    srcStride, 
		    (x + srcXoff) * srcBpp,
		    srcBpp,

		    dst,
		    dstStride,
		    0,
		    
		    w * srcBpp, h,

		    fbAndStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
		    fbXorStip(GXcopy,FB_STIP_ALLONES,FB_STIP_ALLONES),
		    fbAndStip(GXcopy,0,FB_STIP_ALLONES),
		    fbXorStip(GXcopy,0,FB_STIP_ALLONES),
		    planeMask);
    }
}
Пример #6
0
void
fbPutXYImage (DrawablePtr	pDrawable,
	      RegionPtr		pClip,
	      FbBits		fg,
	      FbBits		bg,
	      FbBits		pm,
	      int		alu,
	      Bool		opaque,
	      
	      int		x,
	      int		y,
	      int		width,
	      int		height,

	      FbStip		*src,
	      FbStride		srcStride,
	      int		srcX)
{
    FbBits	*dst;
    FbStride	dstStride;
    int		dstBpp;
    int		dstXoff, dstYoff;
    int		nbox;
    BoxPtr	pbox;
    int		x1, y1, x2, y2;
    FbBits	fgand = 0, fgxor = 0, bgand = 0, bgxor = 0;

    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);

    if (dstBpp == 1)
    {
	if (opaque)
	    alu = FbOpaqueStipple1Rop(alu,fg,bg);
	else
	    alu = FbStipple1Rop(alu,fg);
    }
    else
    {
	fgand = fbAnd(alu,fg,pm);
	fgxor = fbXor(alu,fg,pm);
	if (opaque)
	{
	    bgand = fbAnd(alu,bg,pm);
	    bgxor = fbXor(alu,bg,pm);
	}
	else
	{
	    bgand = fbAnd(GXnoop,(FbBits)0,FB_ALLONES);
	    bgxor = fbXor(GXnoop,(FbBits)0,FB_ALLONES);
	}
    }

    for (nbox = REGION_NUM_RECTS (pClip),
	 pbox = REGION_RECTS(pClip);
	 nbox--;
	 pbox++)
    {
	x1 = x;
	y1 = y;
	x2 = x + width;
	y2 = y + height;
	if (x1 < pbox->x1)
	    x1 = pbox->x1;
	if (y1 < pbox->y1)
	    y1 = pbox->y1;
	if (x2 > pbox->x2)
	    x2 = pbox->x2;
	if (y2 > pbox->y2)
	    y2 = pbox->y2;
	if (x1 >= x2 || y1 >= y2)
	    continue;
	if (dstBpp == 1)
	{
	    fbBltStip (src + (y1 - y) * srcStride,
		       srcStride,
		       (x1 - x) + srcX,

		       (FbStip *) (dst + (y1 + dstYoff) * dstStride),
		       FbBitsStrideToStipStride(dstStride),
		       (x1 + dstXoff) * dstBpp,

		       (x2 - x1) * dstBpp,
		       (y2 - y1),

		       alu,
		       pm,
		       dstBpp);
	}
	else
	{
	    fbBltOne (src + (y1 - y) * srcStride,
		      srcStride,
		      (x1 - x) + srcX,

		      dst + (y1 + dstYoff) * dstStride,
		      dstStride,
		      (x1 + dstXoff) * dstBpp,
		      dstBpp,

		      (x2 - x1) * dstBpp,
		      (y2 - y1),

		      fgand, fgxor, bgand, bgxor);
	}
    }
}
Пример #7
0
Файл: fbpush.c Проект: aosm/X11
void
fbPushFill (DrawablePtr	pDrawable,
	    GCPtr	pGC,

	    FbStip	*src,
	    FbStride	srcStride,
	    int		srcX,
	    
	    int		x,
	    int		y,
	    int		width,
	    int		height)
{
    FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
    
    if (pGC->fillStyle == FillSolid)
    {
	FbBits	    *dst;
	FbStride    dstStride;
	int	    dstBpp;
	int	    dstXoff, dstYoff;
	int	    dstX;
	int	    dstWidth;

	fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
	dst = dst + (y + dstYoff) * dstStride;
	dstX = (x + dstXoff) * dstBpp;
	dstWidth = width * dstBpp;
	if (dstBpp == 1)
	{
	    fbBltStip (src,
		       srcStride,
		       srcX,
    
		       (FbStip *) dst,
		       FbBitsStrideToStipStride (dstStride),
		       dstX,
    
		       dstWidth,
		       height,
    
		       FbStipple1Rop(pGC->alu,pGC->fgPixel),
		       pPriv->pm,
		       dstBpp);
	}
	else
	{
	    fbBltOne (src,
		      srcStride,
		      srcX,
    
		      dst,
		      dstStride,
		      dstX,
		      dstBpp,
    
		      dstWidth,
		      height,
    
		      pPriv->and, pPriv->xor,
		      fbAnd(GXnoop,(FbBits) 0,FB_ALLONES),
		      fbXor(GXnoop,(FbBits) 0,FB_ALLONES));
	}
    }
    else
    {
	fbPushPattern (pDrawable, pGC, src, srcStride, srcX,
		       x, y, width, height);
    }
}
Пример #8
0
void
fbAddTraps (PicturePtr	pPicture,
	    INT16	x_off,
	    INT16	y_off,
	    int		ntrap,
	    xTrap	*traps)
{
    FbBits	*buf;
    int		bpp;
    int		width;
    int		stride;
    int		height;
    int		pxoff, pyoff;

    xFixed	x_off_fixed;
    xFixed	y_off_fixed;
    RenderEdge  l, r;
    xFixed	t, b;

    fbGetDrawable (pPicture->pDrawable, buf, stride, bpp, pxoff, pyoff);

    width = pPicture->pDrawable->width;
    height = pPicture->pDrawable->height;
    x_off += pxoff;
    y_off += pyoff;

    x_off_fixed = IntToxFixed(y_off);
    y_off_fixed = IntToxFixed(y_off);

    while (ntrap--)
    {
	t = traps->top.y + y_off_fixed;
	if (t < 0)
	    t = 0;
	t = RenderSampleCeilY (t, bpp);

	b = traps->bot.y + y_off_fixed;
	if (xFixedToInt (b) >= height)
	    b = IntToxFixed (height) - 1;
	b = RenderSampleFloorY (b, bpp);

	if (b >= t)
	{
	    /* initialize edge walkers */
	    RenderEdgeInit (&l, bpp, t,
			    traps->top.l + x_off_fixed,
			    traps->top.y + y_off_fixed,
			    traps->bot.l + x_off_fixed,
			    traps->bot.y + y_off_fixed);

	    RenderEdgeInit (&r, bpp, t,
			    traps->top.r + x_off_fixed,
			    traps->top.y + y_off_fixed,
			    traps->bot.r + x_off_fixed,
			    traps->bot.y + y_off_fixed);

	    fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
	}
	traps++;
    }
}
Пример #9
0
void
fbPolyArc (DrawablePtr	pDrawable,
	   GCPtr	pGC,
	   int		narcs,
	   xArc		*parcs)
{
    FbArc	arc;
    
    if (pGC->lineWidth == 0)
    {
#ifndef FBNOPIXADDR
	arc = 0;
	if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid)
	{
	    switch (pDrawable->bitsPerPixel)
	    {
	    case 8:	arc = fbArc8; break;
	    case 16:    arc = fbArc16; break;
#ifdef FB_24BIT
	    case 24:	arc = fbArc24; break;
#endif
	    case 32:    arc = fbArc32; break;
	    }
	}
	if (arc)
	{
	    FbGCPrivPtr	pPriv = fbGetGCPrivate (pGC);
	    FbBits	*dst;
	    FbStride	dstStride;
	    int		dstBpp;
	    int		dstXoff, dstYoff;
	    BoxRec	box;
	    int		x2, y2;
	    RegionPtr	cclip;
	    
	    cclip = fbGetCompositeClip (pGC);
	    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
	    while (narcs--)
	    {
		if (miCanZeroArc (parcs))
		{
		    box.x1 = parcs->x + pDrawable->x;
		    box.y1 = parcs->y + pDrawable->y;
		    /*
		     * Because box.x2 and box.y2 get truncated to 16 bits, and the
		     * RECT_IN_REGION test treats the resulting number as a signed
		     * integer, the RECT_IN_REGION test alone can go the wrong way.
		     * This can result in a server crash because the rendering
		     * routines in this file deal directly with cpu addresses
		     * of pixels to be stored, and do not clip or otherwise check
		     * that all such addresses are within their respective pixmaps.
		     * So we only allow the RECT_IN_REGION test to be used for
		     * values that can be expressed correctly in a signed short.
		     */
		    x2 = box.x1 + (int)parcs->width + 1;
		    box.x2 = x2;
		    y2 = box.y1 + (int)parcs->height + 1;
		    box.y2 = y2;
		    if ( (x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
			(RECT_IN_REGION(pDrawable->pScreen, cclip, &box) == rgnIN) )
			(*arc) (dst, dstStride, dstBpp, 
				parcs, pDrawable->x + dstXoff, pDrawable->y + dstYoff, 
				pPriv->and, pPriv->xor);
		    else
			miZeroPolyArc(pDrawable, pGC, 1, parcs);
		}
		else
		    miPolyArc(pDrawable, pGC, 1, parcs);
		parcs++;
	    }
	}
	else
#endif
	    miZeroPolyArc (pDrawable, pGC, narcs, parcs);
    }
    else
	miPolyArc (pDrawable, pGC, narcs, parcs);
}
Пример #10
0
void
tridentComposite (CARD8      op,
		  PicturePtr pSrc,
		  PicturePtr pMask,
		  PicturePtr pDst,
		  INT16      xSrc,
		  INT16      ySrc,
		  INT16      xMask,
		  INT16      yMask,
		  INT16      xDst,
		  INT16      yDst,
		  CARD16     width,
		  CARD16     height)
{
    SetupTrident (pDst->pDrawable->pScreen);
    tridentScreenInfo(pScreenPriv);
    RegionRec	region;
    int		n;
    BoxPtr	pbox;
    CARD32	rgb;
    CARD8	*msk, *mskLine;
    FbBits	*mskBits;
    FbStride	mskStride;
    int		mskBpp;
    int		mskXoff, mskYoff;
    CARD32	*src, *srcLine;
    CARD32	*off, *offLine;
    FbBits	*srcBits;
    FbStride	srcStride;
    int		srcXoff, srcYoff;
    FbStride	offStride;
    int		srcBpp;
    int		x_msk, y_msk, x_src, y_src, x_dst, y_dst;
    int		x2;
    int		w, h, w_this, h_this, w_remain;
    CARD32	*off_screen;
    int		off_size = tridents->off_screen_size >> 2;
    int		off_width, off_height;
    int		stride = pScreenPriv->screen->fb[0].pixelStride;
    int		mskExtra;
    CARD32	off_screen_offset = tridents->off_screen - tridents->screen;
    int		mode;
    
#define MODE_NONE   0
#define MODE_IMAGE  1
#define MODE_MASK   2
    
    rgb = *((CARD32 *) ((PixmapPtr) (pSrc->pDrawable))->devPrivate.ptr);
    if (pMask && 
	!pMask->repeat &&
	pMask->format == PICT_a8 &&
        op == PictOpOver &&
	pSrc->repeat &&
	pSrc->pDrawable->width == 1 &&
	pSrc->pDrawable->height == 1 &&
	PICT_FORMAT_BPP(pSrc->format) == 32 &&
	(PICT_FORMAT_A(pSrc->format) == 0 ||
	 (rgb & 0xff000000) == 0xff000000) &&
	pDst->pDrawable->bitsPerPixel == 32 &&
	pDst->pDrawable->type == DRAWABLE_WINDOW)
    {
	mode = MODE_MASK;
    }
    else if (!pMask &&
	     op == PictOpOver &&
	     !pSrc->repeat &&
	     PICT_FORMAT_A(pSrc->format) == 8 &&
	     PICT_FORMAT_BPP(pSrc->format) == 32 &&
	     pDst->pDrawable->bitsPerPixel == 32 &&
	     pDst->pDrawable->type == DRAWABLE_WINDOW)
    {
	mode = MODE_IMAGE;
    }
    else
	mode = MODE_NONE;
    
    if (mode != MODE_NONE)
    {
	xDst += pDst->pDrawable->x;
	yDst += pDst->pDrawable->y;
	xSrc += pSrc->pDrawable->x;
	ySrc += pSrc->pDrawable->y;
	
	fbGetDrawable (pSrc->pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff);
	
	if (pMask)
	{
	    xMask += pMask->pDrawable->x;
	    yMask += pMask->pDrawable->y;
	    fbGetDrawable (pMask->pDrawable, mskBits, mskStride, mskBpp, mskXoff, mskYoff);
	    mskStride = mskStride * sizeof (FbBits) / sizeof (CARD8);
	}
	
	if (!miComputeCompositeRegion (&region,
				       pSrc,
				       pMask,
				       pDst,
				       xSrc,
				       ySrc,
				       xMask,
				       yMask,
				       xDst,
				       yDst,
				       width,
				       height))
	    return;
	
	_tridentInit(cop,tridentc);
	
	cop->multi = COP_MULTI_PATTERN;
	cop->src_offset = off_screen_offset;
	
	if (mode == MODE_IMAGE)
	{
	    cop->multi = (COP_MULTI_ALPHA |
			  COP_ALPHA_BLEND_ENABLE |
			  COP_ALPHA_WRITE_ENABLE |
			  0x7 << 16 |
			  COP_ALPHA_DST_BLEND_1_SRC_A |
			  COP_ALPHA_SRC_BLEND_1);
	}
	else
	{
	    rgb &= 0xffffff;
	    cop->multi = (COP_MULTI_ALPHA |
			  COP_ALPHA_BLEND_ENABLE |
			  COP_ALPHA_WRITE_ENABLE |
			  0x7 << 16 |
			  COP_ALPHA_DST_BLEND_1_SRC_A |
			  COP_ALPHA_SRC_BLEND_SRC_A);
	}
	
	n = REGION_NUM_RECTS (&region);
	pbox = REGION_RECTS (&region);
	
	while (n--)
	{
	    h = pbox->y2 - pbox->y1;
	    w = pbox->x2 - pbox->x1;
	    
	    offStride = (w + 7) & ~7;
	    off_height = off_size / offStride;
	    if (off_height > h)
		off_height = h;
	    
	    cop->multi = COP_MULTI_STRIDE | (stride << 16) | offStride;
	    
	    y_dst = pbox->y1;
	    y_src = y_dst - yDst + ySrc;
	    y_msk = y_dst - yDst + yMask;
	    
	    x_dst = pbox->x1;
	    x_src = x_dst - xDst + xSrc;
	    x_msk = x_dst - xDst + xMask;
	
	    if (mode == MODE_IMAGE)
		srcLine = (CARD32 *) srcBits + (y_src - srcYoff) * srcStride + (x_src - srcXoff);
	    else
		mskLine = (CARD8 *) mskBits + (y_msk - mskYoff) * mskStride + (x_msk - mskXoff);

	    while (h)
	    {
		h_this = h;
		if (h_this > off_height)
		    h_this = off_height;
		h -= h_this;
		
		offLine = (CARD32 *) tridents->off_screen;
		
		_tridentWaitDone(cop);
		
		cop->dst_start_xy = TRI_XY(x_dst, y_dst);
		cop->dst_end_xy = TRI_XY(x_dst + w - 1, y_dst + h_this - 1);
		cop->src_start_xy = TRI_XY(0,0);
		cop->src_end_xy = TRI_XY(w - 1, h_this - 1);
					 
		if (mode == MODE_IMAGE)
		{
		    while (h_this--)
		    {
			w_remain = w;
			src = srcLine;
			srcLine += srcStride;
			off = offLine;
			offLine += offStride;
			while (w_remain--)
			    *off++ = *src++;
		    }
		}
		else
		{
		    while (h_this--)
		    {
			w_remain = w;
			msk = mskLine;
			mskLine += mskStride;
			off = offLine;
			offLine += offStride;
			while (w_remain--)
			    *off++ = rgb | (*msk++ << 24);
		    }
		}
		
		cop->command = (COP_OP_BLT |
				COP_SCL_OPAQUE |
				COP_OP_FB);
	    }
	    pbox++;
	}
	cop->src_offset = 0;
	
	KdMarkSync (pDst->pDrawable->pScreen);
    }
    else
    {
	KdCheckComposite (op,
			  pSrc,
			  pMask,
			  pDst,
			  xSrc,
			  ySrc,
			  xMask,
			  yMask,
			  xDst,
			  yDst,
			  width,
			  height);
    }
}
Пример #11
0
void
qtShadowUpdate (ScreenPtr pScreen, 
		    shadowBufPtr pBuf)
{
	qtScreenPriv(pScreen);
	qtScreenInfo		*pScreenInfo = pScreenPriv->pScreenInfo;
	RegionPtr		damage = &pBuf->damage;
	DWORD			dwBox = REGION_NUM_RECTS (damage);
	BoxPtr			pBox = REGION_RECTS (damage);
	int			x, y, w, h;

	FbBits			*shaBase;
	FbStride		shaStride;
	int			shaBpp;
	int			shaXoff, shaYoff; /* assumed to be zero */

	/*
	 * Return immediately if the app is not active
	 * and we are fullscreen, or if we have a bad display depth
	 */
	if ((!pScreenPriv->fActive && pScreenInfo->fFullScreen)
	    || pScreenPriv->fBadDepth) return;

	/*
	 * get shadow pixmap
	 */
	fbGetDrawable(&pBuf->pPixmap->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);

	/*
	 * Handle small regions with multiple blits,
	 * handle large regions by creating a clipping region and 
	 * doing a single blit constrained to that clipping region.
	 */
	if (pScreenInfo->dwClipUpdatesNBoxes == 0
	    || dwBox < pScreenInfo->dwClipUpdatesNBoxes)
	{
		/* Loop through all boxes in the damaged region */
		while (dwBox--)
		{
			/*
			 * Calculate x offset, y offset, width, and height for
			 * current damage box
			 */
			x = pBox->x1;
			y = pBox->y1;
			w = pBox->x2 - pBox->x1;
			h = pBox->y2 - pBox->y1;

			/* redraw */
			qtRedrawScreen(x, y, w, h,
				       shaBase, shaStride*sizeof(FbBits), shaBpp,
				       pBuf->randr);

			/* Get a pointer to the next box */
			++pBox;
		}
	}
	else
	{
		int x1, y1, x2, y2;

		/* 
		   複数の damage box を merge して BitBlt してやる必要がある。
		   WIN32の場合は region を使うことができるが、Qt にはないので、
		   全ボックスを囲むボックスを計算しないといけない。
		*/
		x1 = pBox->x1; y1 = pBox->y1;
		x2 = pBox->x2; y2 = pBox->y2;

		dwBox--;
		pBox++;
		while (dwBox--)
		{
			if (pBox->x1 < x1) x1 = pBox->x1;
			if (pBox->x2 > x2) x2 = pBox->x2;
			if (pBox->y1 < y1) y1 = pBox->y1;
			if (pBox->y2 > y2) y2 = pBox->y2;
			pBox++;
		}
      
		/* redraw */
		qtRedrawScreen(x, y, w, h, 
			       shaBase, shaStride*sizeof(FbBits), shaBpp,
			       pBuf->randr);
	}

	/* Redraw all windows */
#if 0	/* ### */	
	if (pScreenInfo->fMultiWindow) EnumWindows(winRedrawAllProcShadow, 0);
#endif
}
Пример #12
0
void
fbFill (DrawablePtr pDrawable,
	GCPtr	    pGC,
	int	    x,
	int	    y,
	int	    width,
	int	    height)
{
    FbBits	    *dst;
    FbStride	    dstStride;
    int		    dstBpp;
    int		    dstXoff, dstYoff;
    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
    
    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);

    switch (pGC->fillStyle) {
    case FillSolid:
	fbSolid (dst + (y + dstYoff) * dstStride, 
		 dstStride, 
		 (x + dstXoff) * dstBpp,
		 dstBpp,
		 width * dstBpp, height,
		 pPriv->and, pPriv->xor);
	break;
    case FillStippled:
    case FillOpaqueStippled: {
	PixmapPtr   pStip = pGC->stipple;
	int	    stipWidth = pStip->drawable.width;
	int	    stipHeight = pStip->drawable.height;
	
	if (dstBpp == 1)
	{
	    int		alu;
	    FbBits	*stip;
	    FbStride    stipStride;
	    int		stipBpp;
	    int		stipXoff, stipYoff; /* XXX assumed to be zero */

	    if (pGC->fillStyle == FillStippled)
		alu = FbStipple1Rop(pGC->alu,pGC->fgPixel);
	    else
		alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel);
	    fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
	    fbTile (dst + (y + dstYoff) * dstStride,
		    dstStride,
		    x + dstXoff,
		    width, height,
		    stip,
		    stipStride,
		    stipWidth,
		    stipHeight,
		    alu,
		    pPriv->pm,
		    dstBpp,
		    
		    (pGC->patOrg.x + pDrawable->x),
		    pGC->patOrg.y + pDrawable->y - y);
	}
	else
	{
	    FbStip	*stip;
	    FbStride    stipStride;
	    int		stipBpp;
	    int		stipXoff, stipYoff; /* XXX assumed to be zero */
	    FbBits	fgand, fgxor, bgand, bgxor;

	    fgand = pPriv->and;
	    fgxor = pPriv->xor;
	    if (pGC->fillStyle == FillStippled)
	    {
		bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES);
		bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES);
	    }
	    else
	    {
		bgand = pPriv->bgand;
		bgxor = pPriv->bgxor;
	    }

	    fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff);
	    fbStipple (dst + y * dstStride, 
		       dstStride, 
		       x * dstBpp,
		       dstBpp,
		       width * dstBpp, height,
		       stip,
		       stipStride,
		       stipWidth,
		       stipHeight,
		       pPriv->evenStipple,
		       fgand, fgxor,
		       bgand, bgxor,
		       pGC->patOrg.x + pDrawable->x,
		       pGC->patOrg.y + pDrawable->y - y);
	}
	break;
    }
    case FillTiled: {
	PixmapPtr   pTile = pGC->tile.pixmap;
	FbBits	    *tile;
	FbStride    tileStride;
	int	    tileBpp;
	int	    tileWidth;
	int	    tileHeight;
	int	    tileXoff, tileYoff; /* XXX assumed to be zero */
	
	fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff);
	tileWidth = pTile->drawable.width;
	tileHeight = pTile->drawable.height;
	fbTile (dst + (y + dstYoff) * dstStride, 
		dstStride, 
		(x + dstXoff) * dstBpp, 
		width * dstBpp, height,
		tile,
		tileStride,
		tileWidth * tileBpp,
		tileHeight,
		pGC->alu,
		pPriv->pm,
		dstBpp,
		(pGC->patOrg.x + pDrawable->x) * dstBpp,
		pGC->patOrg.y + pDrawable->y - y);
	break;
    }
    }
    fbValidateDrawable (pDrawable);
}
Пример #13
0
/**
 * Implements CopyPlane and CopyArea from the GPU to the GPU by using
 * the source as a texture and painting that into the destination.
 *
 * This requires that source and dest are different textures, or that
 * (if the copy area doesn't overlap), GL_NV_texture_barrier is used
 * to ensure that the caches are flushed at the right times.
 */
static Bool
glamor_copy_cpu_fbo(DrawablePtr src,
                    DrawablePtr dst,
                    GCPtr gc,
                    BoxPtr box,
                    int nbox,
                    int dx,
                    int dy,
                    Bool reverse,
                    Bool upsidedown,
                    Pixel bitplane,
                    void *closure)
{
    ScreenPtr screen = dst->pScreen;
    glamor_screen_private *glamor_priv = glamor_get_screen_private(screen);
    PixmapPtr dst_pixmap = glamor_get_drawable_pixmap(dst);
    FbBits *src_bits;
    FbStride src_stride;
    int src_bpp;
    int src_xoff, src_yoff;
    int dst_xoff, dst_yoff;

    if (gc && gc->alu != GXcopy)
        goto bail;

    if (gc && !glamor_pm_is_solid(gc->depth, gc->planemask))
        goto bail;

    glamor_make_current(glamor_priv);
    glamor_prepare_access(src, GLAMOR_ACCESS_RO);

    glamor_get_drawable_deltas(dst, dst_pixmap, &dst_xoff, &dst_yoff);

    if (bitplane) {
        PixmapPtr src_pix = fbCreatePixmap(screen, dst_pixmap->drawable.width,
                                           dst_pixmap->drawable.height,
                                           dst->depth, 0);

        if (!src_pix) {
            glamor_finish_access(src);
            goto bail;
        }

        src_pix->drawable.x = -dst->x;
        src_pix->drawable.y = -dst->y;

        fbGetDrawable(&src_pix->drawable, src_bits, src_stride, src_bpp, src_xoff,
                      src_yoff);

        if (src->bitsPerPixel > 1)
            fbCopyNto1(src, &src_pix->drawable, gc, box, nbox, dx, dy,
                       reverse, upsidedown, bitplane, closure);
        else
            fbCopy1toN(src, &src_pix->drawable, gc, box, nbox, dx, dy,
                       reverse, upsidedown, bitplane, closure);

        glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff, src_yoff,
                            dst_xoff, dst_yoff, (uint8_t *) src_bits,
                            src_stride * sizeof(FbBits));
        fbDestroyPixmap(src_pix);
    } else {
        fbGetDrawable(src, src_bits, src_stride, src_bpp, src_xoff, src_yoff);
        glamor_upload_boxes(dst_pixmap, box, nbox, src_xoff + dx, src_yoff + dy,
                            dst_xoff, dst_yoff,
                            (uint8_t *) src_bits, src_stride * sizeof (FbBits));
    }
    glamor_finish_access(src);

    return TRUE;

bail:
    return FALSE;
}
Пример #14
0
void
fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc,
                int x, int y,
                unsigned int nglyph, CharInfoPtr * ppciInit, pointer glyphs)
{
	FbGCPrivPtr pgc = fb_gc(gc);
	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 (*raster)(FbBits *, FbStride, int, FbStip *, FbBits, int, int);
	FbBits *dst = 0;
	FbStride dstStride = 0;
	int dstBpp = 0;
	int dstXoff = 0, dstYoff = 0;

	DBG(("%s x %d\n", __FUNCTION__, nglyph));

	raster = 0;
	if (pgc->and == 0) {
		dstBpp = drawable->bitsPerPixel;
		switch (dstBpp) {
		case 8:
			raster = fbGlyph8;
			break;
		case 16:
			raster = fbGlyph16;
			break;
		case 32:
			raster = fbGlyph32;
			break;
		}
	}

	x += drawable->x;
	y += drawable->y;

	if (TERMINALFONT(gc->font) && !raster) {
		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(gc->font);
		heightBack = FONTASCENT(gc->font) + FONTDESCENT(gc->font);
		fbSolidBoxClipped(drawable, gc,
				  xBack, yBack,
				  xBack + widthBack,
				  yBack + heightBack);
		opaque = FALSE;
	}

	ppci = ppciInit;
	while (nglyph--) {
		pci = *ppci++;
		pglyph = FONTGLYPHBITS(glyphs, pci);
		gWidth = GLYPHWIDTHPIXELS(pci);
		gHeight = GLYPHHEIGHTPIXELS(pci);
		if (gWidth && gHeight) {
			gx = x + pci->metrics.leftSideBearing;
			gy = y - pci->metrics.ascent;
			if (raster && gWidth <= sizeof(FbStip) * 8 &&
			    fbGlyphIn(gc, gx, gy, gWidth, gHeight)) {
				fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff,
					      dstYoff);
				raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
				       (FbStip *) pglyph, pgc->fg, gx + dstXoff, gHeight);
			} else {
				gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
				fbPutXYImage(drawable, gc,
					     pgc->fg, pgc->bg, pgc->pm,
					     GXcopy, opaque,
					     gx, gy, gWidth, gHeight,
					     (FbStip *) pglyph, gStride, 0);
			}
		}
		x += pci->metrics.characterWidth;
	}
}
Пример #15
0
void
fbPolyGlyphBlt(DrawablePtr drawable, GCPtr gc,
               int x, int y,
               unsigned int nglyph, CharInfoPtr * ppci, pointer glyphs)
{
	FbGCPrivPtr pgc = fb_gc(gc);
	CharInfoPtr pci;
	unsigned char *pglyph;      /* pointer bits in glyph */
	int gx, gy;
	int gWidth, gHeight;        /* width and height of glyph */
	FbStride gStride;           /* stride of glyph */
	void (*raster) (FbBits *, FbStride, int, FbStip *, FbBits, int, int);
	FbBits *dst = 0;
	FbStride dstStride = 0;
	int dstBpp = 0;
	int dstXoff = 0, dstYoff = 0;

	DBG(("%s x %d\n", __FUNCTION__, nglyph));

	raster = 0;
	if (gc->fillStyle == FillSolid && pgc->and == 0) {
		dstBpp = drawable->bitsPerPixel;
		switch (dstBpp) {
		case 8:
			raster = fbGlyph8;
			break;
		case 16:
			raster = fbGlyph16;
			break;
		case 32:
			raster = fbGlyph32;
			break;
		}
	}
	x += drawable->x;
	y += drawable->y;

	while (nglyph--) {
		pci = *ppci++;
		pglyph = FONTGLYPHBITS(glyphs, pci);
		gWidth = GLYPHWIDTHPIXELS(pci);
		gHeight = GLYPHHEIGHTPIXELS(pci);
		if (gWidth && gHeight) {
			gx = x + pci->metrics.leftSideBearing;
			gy = y - pci->metrics.ascent;
			if (raster && gWidth <= sizeof(FbStip) * 8 &&
			    fbGlyphIn(gc, gx, gy, gWidth, gHeight)) {
				fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff,
					      dstYoff);
				raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp,
					  (FbStip *) pglyph, pgc->xor, gx + dstXoff, gHeight);
			} else {
				gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip);
				fbPushImage(drawable, gc,
					    (FbStip *)pglyph,
					    gStride, 0, gx, gy, gWidth, gHeight);
			}
		}
		x += pci->metrics.characterWidth;
	}
}