void
fbPolySegment (DrawablePtr  pDrawable,
	       GCPtr	    pGC,
	       int	    nseg,
	       xSegment	    *pseg)
{
    void    (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment *pseg);

    if (pGC->lineWidth == 0)
    {
	seg = fbZeroSegment;
#ifndef FBNOPIXADDR
	if (pGC->fillStyle == FillSolid &&
	    pGC->lineStyle == LineSolid &&
	    REGION_NUM_RECTS (fbGetCompositeClip(pGC)) == 1)
	{
	    switch (pDrawable->bitsPerPixel) {
	    case 8:  seg = fbPolySegment8; break;
	    case 16: seg = fbPolySegment16; break;
#ifdef FB_24BIT
	    case 24: seg = fbPolySegment24; break;
#endif
	    case 32: seg = fbPolySegment32; break;
	    }
	}
#endif
    }
    else
    {
	seg = miPolySegment;
    }
    (*seg) (pDrawable, pGC, nseg, pseg);
}
Example #2
0
void
fbPushImage(DrawablePtr pDrawable,
            GCPtr pGC,
            FbStip * src,
            FbStride srcStride, int srcX, int x, int y, int width, int height)
{
    RegionPtr pClip = fbGetCompositeClip(pGC);
    int nbox;
    BoxPtr pbox;
    int x1, y1, x2, y2;

    for (nbox = RegionNumRects(pClip),
         pbox = RegionRects(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;
        fbPushFill(pDrawable,
                   pGC,
                   src + (y1 - y) * srcStride,
                   srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
    }
}
Example #3
0
void
fbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg)
{
    void (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg);

    if (pGC->lineWidth == 0) {
        seg = fbZeroSegment;
        if (pGC->fillStyle == FillSolid &&
            pGC->lineStyle == LineSolid &&
            RegionNumRects(fbGetCompositeClip(pGC)) == 1) {
            switch (pDrawable->bitsPerPixel) {
            case 8:
                seg = fbPolySegment8;
                break;
            case 16:
                seg = fbPolySegment16;
                break;
            case 32:
                seg = fbPolySegment32;
                break;
            }
        }
    }
    else {
        seg = miPolySegment;
    }
    (*seg) (pDrawable, pGC, nseg, pseg);
}
Example #4
0
static GCOps *
s3MatchCommon (DrawablePtr pDraw, GCPtr pGC, FbGCPrivPtr fbPriv)
{
    KdScreenPriv (pDraw->pScreen);

    if (!REGION_NOTEMPTY(pDraw->pScreen,fbGetCompositeClip(pGC)))
    {
	DRAW_DEBUG ((DEBUG_CLIP, "Empty composite clip, clipping all ops"));
	return &kdNoopOps;
    }

    if (pDraw->type != DRAWABLE_WINDOW)
	return (GCOps *) &kdAsyncPixmapGCOps;
    
    if (pGC->lineWidth != 0)
	return 0;
    if (pGC->lineStyle != LineSolid)
	return 0;
    if (pGC->fillStyle != FillSolid)
	return 0;
    if (fbPriv->and != 0)
	return 0;
    if (pGC->font)
    {
	if (TERMINALFONT(pGC->font))
	    return (GCOps *) &s3TEOps;
	else
	    return (GCOps *) &s3NonTEOps;
    }
    return 0;
}
Example #5
0
void
fbPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
{
    void (*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt);

    if (pGC->lineWidth == 0) {
        line = fbZeroLine;
        if (pGC->fillStyle == FillSolid &&
            pGC->lineStyle == LineSolid &&
            RegionNumRects(fbGetCompositeClip(pGC)) == 1) {
            switch (pDrawable->bitsPerPixel) {
            case 8:
                line = fbPolyline8;
                break;
            case 16:
                line = fbPolyline16;
                break;
            case 32:
                line = fbPolyline32;
                break;
            }
        }
    }
    else {
        if (pGC->lineStyle != LineSolid)
            line = miWideDash;
        else
            line = miWideLine;
    }
    (*line) (pDrawable, pGC, mode, npt, ppt);
}
Example #6
0
Bool
fbCreateGC(GCPtr pGC)
{
    pGC->clientClip = NULL;
    pGC->clientClipType = CT_NONE;

    pGC->ops = (GCOps *) &fbGCOps;
    pGC->funcs = (GCFuncs *) &fbGCFuncs;

    /* fb wants to translate before scan conversion */
    pGC->miTranslate = 1;

    fbGetRotatedPixmap(pGC) = 0;
    fbGetExpose(pGC) = 1;
    fbGetFreeCompClip(pGC) = 0;
    fbGetCompositeClip(pGC) = 0;
    fbGetGCPrivate(pGC)->bpp = BitsPerPixel (pGC->depth);
    return TRUE;
}
void
fbPolyLine (DrawablePtr	pDrawable,
	    GCPtr	pGC,
	    int		mode,
	    int		npt,
	    DDXPointPtr	ppt)
{
    void	(*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt);
    
    if (pGC->lineWidth == 0)
    {
	line = fbZeroLine;
#ifndef FBNOPIXADDR
	if (pGC->fillStyle == FillSolid &&
	    pGC->lineStyle == LineSolid &&
	    REGION_NUM_RECTS (fbGetCompositeClip(pGC)) == 1)
	{
	    switch (pDrawable->bitsPerPixel) {
	    case 8:  line = fbPolyline8; break;
	    case 16: line = fbPolyline16; break;
#ifdef FB_24BIT
	    case 24: line = fbPolyline24; break;
#endif
	    case 32: line = fbPolyline32; break;
	    }
	}
#endif
    }
    else
    {
	if (pGC->lineStyle != LineSolid)
	    line = miWideDash;
	else
	    line = miWideLine;
    }
    (*line) (pDrawable, pGC, mode, npt, ppt);
}
Example #8
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);
}
Example #9
0
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);
}
Example #10
0
void
fbFillSpans (DrawablePtr    pDrawable,
	     GCPtr	    pGC,
	     int	    n,
	     DDXPointPtr    ppt,
	     int	    *pwidth,
	     int	    fSorted)
{
    RegionPtr	    pClip = fbGetCompositeClip(pGC);
    BoxPtr	    pextent, pbox;
    int		    nbox;
    int		    extentX1, extentX2, extentY1, extentY2;
    int		    fullX1, fullX2, fullY1;
    int		    partX1, partX2;
    
    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)
	{
	    fbFill (pDrawable,
		    pGC,
		    fullX1, fullY1, fullX2-fullX1, 1);
	}
	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)
		    {
			fbFill (pDrawable, pGC,
				partX1, fullY1,
				partX2 - partX1, 1);
		    }
		}
		pbox++;
	    }
	}
    }
}
Example #11
0
static Bool 
_glamor_put_image(DrawablePtr drawable, GCPtr gc, int depth, int x, int y,
		 int w, int h, int left_pad, int image_format, char *bits, Bool fallback)
{
	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
	glamor_pixmap_private *pixmap_priv =
	    glamor_get_pixmap_private(pixmap);
	RegionPtr clip;
	int x_off, y_off;
	Bool ret = FALSE;
	PixmapPtr temp_pixmap, sub_pixmap;
	glamor_pixmap_private *temp_pixmap_priv;
	BoxRec box;
	int stride;

	glamor_get_drawable_deltas(drawable, pixmap, &x_off, &y_off);
	clip = fbGetCompositeClip(gc);
	if (image_format == XYBitmap) {
		assert(depth == 1);
		goto fail;
	}

	if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(pixmap_priv)) {
		glamor_fallback("has no fbo.\n");
		goto fail;
	}

	if (image_format != ZPixmap) {
		glamor_fallback("non-ZPixmap\n");
		goto fail;
	}

	if (!glamor_set_planemask(pixmap, gc->planemask)) {
		goto fail;
	}
	/* create a temporary pixmap and upload the bits to that
	 * pixmap, then apply clip copy it to the destination pixmap.*/
	stride = PixmapBytePad(w, depth);
	box.x1 = x + drawable->x;
	box.y1 = y + drawable->y;
	box.x2 = x + w + drawable->x;
	box.y2 = y + h + drawable->y;

	if ((clip != NULL && RegionContainsRect(clip, &box) != rgnIN)
	     || gc->alu != GXcopy) {
		temp_pixmap = glamor_create_pixmap(drawable->pScreen, w, h, depth, 0);
		if (temp_pixmap == NULL)
			goto fail;

		temp_pixmap_priv = glamor_get_pixmap_private(temp_pixmap);

		if (GLAMOR_PIXMAP_PRIV_IS_PICTURE(pixmap_priv)) {
			temp_pixmap_priv->base.picture = pixmap_priv->base.picture;
			temp_pixmap_priv->base.is_picture = pixmap_priv->base.is_picture;
		}

		glamor_upload_sub_pixmap_to_texture(temp_pixmap, 0, 0, w, h,
		                                    stride, bits, 0);
		glamor_copy_area(&temp_pixmap->drawable, drawable, gc, 0, 0, w, h, x, y);
		glamor_destroy_pixmap(temp_pixmap);
	} else {
		glamor_upload_sub_pixmap_to_texture(pixmap, x + drawable->x + x_off, y + drawable->y + y_off,
		                                    w, h, stride, bits, 0);
	}
	ret = TRUE;
	goto done;

fail:
	glamor_set_planemask(pixmap, ~0);

	if (!fallback
	    && glamor_ddx_fallback_check_pixmap(&pixmap->drawable))
		goto done;

	glamor_fallback("to %p (%c)\n",
			drawable, glamor_get_drawable_location(drawable));

	sub_pixmap = glamor_get_sub_pixmap(pixmap, x + x_off + drawable->x,
					   y + y_off + drawable->y, w, h,
					   GLAMOR_ACCESS_RW);
	if (sub_pixmap) {
		if (clip != NULL)
			pixman_region_translate (clip, -x - drawable->x, -y - drawable->y);

		fbPutImage(&sub_pixmap->drawable, gc, depth, 0, 0, w, h,
			   left_pad, image_format, bits);

		glamor_put_sub_pixmap(sub_pixmap, pixmap,
				      x + x_off + drawable->x,
				      y + y_off + drawable->y,
				      w, h, GLAMOR_ACCESS_RW);
		if (clip != NULL)
			pixman_region_translate (clip, x + drawable->x, y + drawable->y);
	} else
		fbPutImage(drawable, gc, depth, x, y, w, h,
			   left_pad, image_format, bits);
	ret = TRUE;

done:
	return ret;
}
Example #12
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;
    }
}
Example #13
0
static void
exaPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nrect, xRectangle *prect)
{
    ExaScreenPriv(pDrawable->pScreen);
    RegionPtr pClip = fbGetCompositeClip(pGC);
    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);

    ExaPixmapPriv(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;
    RegionPtr pReg = RegionFromRects(nrect, prect, CT_UNSORTED);

    /* Compute intersection of rects and clip region */
    RegionTranslate(pReg, pDrawable->x, pDrawable->y);
    RegionIntersect(pReg, pClip, pReg);

    if (!RegionNumRects(pReg)) {
        goto out;
    }

    exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);

    if (pExaScr->fallback_counter || pExaScr->swappedOut ||
        pExaPixmap->accel_blocked) {
        goto fallback;
    }

    /* For ROPs where overlaps don't matter, convert rectangles to region and
     * call exaFillRegion{Solid,Tiled}.
     */
    if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
        (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
         pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
         pGC->alu == GXset)) {
        if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
             exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
                                pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
                                pGC->alu, pGC->clientClip != NULL)) ||
            (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
             exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
                                pGC->planemask, pGC->alu,
                                pGC->clientClip != NULL))) {
            goto out;
        }
    }

    if (pGC->fillStyle != FillSolid &&
        !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) {
        goto fallback;
    }

    if (pExaScr->do_migration) {
        ExaMigrationRec pixmaps[1];

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pPixmap;
        pixmaps[0].pReg = NULL;

        exaDoMigration(pixmaps, 1, TRUE);
    }

    if (!exaPixmapHasGpuCopy(pPixmap) ||
        !(*pExaScr->info->PrepareSolid) (pPixmap,
                                         pGC->alu,
                                         pGC->planemask, pGC->fgPixel)) {
 fallback:
        ExaCheckPolyFillRect(pDrawable, pGC, nrect, prect);
        goto out;
    }

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

    pextent = RegionExtents(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 = RegionNumRects(pClip);
        if (n == 1) {
            (*pExaScr->info->Solid) (pPixmap,
                                     fullX1 + xoff, fullY1 + yoff,
                                     fullX2 + xoff, fullY2 + yoff);
        }
        else {
            pbox = RegionRects(pClip);
            /*
             * clip the rectangle to each box in the clip region
             * this is logically equivalent to calling Intersect(),
             * but rectangles may overlap each other here.
             */
            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) {
                    (*pExaScr->info->Solid) (pPixmap,
                                             partX1 + xoff, partY1 + yoff,
                                             partX2 + xoff, partY2 + yoff);
                }
            }
        }
    }
    (*pExaScr->info->DoneSolid) (pPixmap);
    exaMarkSync(pDrawable->pScreen);

 out:
    RegionUninit(pReg);
    RegionDestroy(pReg);
}
Example #14
0
static Bool
_glamor_set_spans(DrawablePtr drawable, GCPtr gc, char *src,
                  DDXPointPtr points, int *widths, int numPoints, int sorted,
                  Bool fallback)
{
    PixmapPtr dest_pixmap = glamor_get_drawable_pixmap(drawable);
    glamor_pixmap_private *dest_pixmap_priv;
    int i;
    uint8_t *drawpixels_src = (uint8_t *) src;
    RegionPtr clip = fbGetCompositeClip(gc);
    BoxRec *pbox;
    int x_off, y_off;
    Bool ret = FALSE;

    dest_pixmap_priv = glamor_get_pixmap_private(dest_pixmap);
    if (!GLAMOR_PIXMAP_PRIV_HAS_FBO(dest_pixmap_priv)) {
        glamor_fallback("pixmap has no fbo.\n");
        goto fail;
    }

    /* XXX Shall we set alu here? */
    if (!glamor_set_planemask(dest_pixmap, gc->planemask))
        goto fail;

    glamor_get_drawable_deltas(drawable, dest_pixmap, &x_off, &y_off);
    for (i = 0; i < numPoints; i++) {

        int n = REGION_NUM_RECTS(clip);

        pbox = REGION_RECTS(clip);
        while (n--) {
            int x1 = points[i].x;
            int x2 = x1 + widths[i];
            int y1 = points[i].y;

            if (pbox->y1 > points[i].y || pbox->y2 < points[i].y)
                break;
            x1 = x1 > pbox->x1 ? x1 : pbox->x1;
            x2 = x2 < pbox->x2 ? x2 : pbox->x2;
            if (x1 >= x2)
                continue;
            glamor_upload_sub_pixmap_to_texture(dest_pixmap, x1 + x_off,
                                                y1 + y_off, x2 - x1, 1,
                                                PixmapBytePad(widths[i],
                                                              drawable->depth),
                                                drawpixels_src, 0);
        }
        drawpixels_src += PixmapBytePad(widths[i], drawable->depth);
    }
    ret = TRUE;
    goto done;

 fail:
    if (!fallback && glamor_ddx_fallback_check_pixmap(drawable))
        goto done;

    glamor_fallback("to %p (%c)\n",
                    drawable, glamor_get_drawable_location(drawable));
    if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW)) {
        fbSetSpans(drawable, gc, src, points, widths, numPoints, sorted);
        glamor_finish_access(drawable, GLAMOR_ACCESS_RW);
    }
    ret = TRUE;

 done:
    return ret;
}
Example #15
0
void
fbPolyFillRect(DrawablePtr  pDrawable, 
	       GCPtr	    pGC, 
	       int	    nrect,
	       xRectangle   *prect)
{
    RegionPtr	    pClip = fbGetCompositeClip(pGC);
    register BoxPtr pbox;
    BoxPtr	    pextent;
    int		    extentX1, extentX2, extentY1, extentY2;
    int		    fullX1, fullX2, fullY1, fullY2;
    int		    partX1, partX2, partY1, partY2;
    int		    xorg, yorg;
    int		    n;

    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)
	{
	    fbFill (pDrawable,
		    pGC,
		    fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
	}
	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)
		    fbFill (pDrawable, pGC,
			    partX1, partY1,
			    partX2 - partX1, partY2 - partY1);
	    }
	}
    }
}
Example #16
0
void
fbSegment(DrawablePtr pDrawable,
          GCPtr pGC,
          int x1, int y1, int x2, int y2, Bool drawLast, int *dashOffset)
{
    FbBres *bres;
    RegionPtr pClip = fbGetCompositeClip(pGC);
    BoxPtr pBox;
    int nBox;
    int adx;                    /* abs values of dx and dy */
    int ady;
    int signdx;                 /* sign of dx and dy */
    int signdy;
    int e, e1, e2, e3;          /* bresenham error and increments */
    int len;                    /* length of segment */
    int axis;                   /* major axis */
    int octant;
    int dashoff;
    int doff;
    unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
    unsigned int oc1;           /* outcode of point 1 */
    unsigned int oc2;           /* outcode of point 2 */

    nBox = RegionNumRects(pClip);
    pBox = RegionRects(pClip);

    bres = fbSelectBres(pDrawable, pGC);

    CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy, 1, 1, octant);

    if (adx > ady) {
        axis = X_AXIS;
        e1 = ady << 1;
        e2 = e1 - (adx << 1);
        e = e1 - adx;
        len = adx;
    }
    else {
        axis = Y_AXIS;
        e1 = adx << 1;
        e2 = e1 - (ady << 1);
        e = e1 - ady;
        SetYMajorOctant(octant);
        len = ady;
    }

    FIXUP_ERROR(e, octant, bias);

    /*
     * Adjust error terms to compare against zero
     */
    e3 = e2 - e1;
    e = e - e1;

    /* we have bresenham parameters and two points.
       all we have to do now is clip and draw.
     */

    if (drawLast)
        len++;
    dashoff = *dashOffset;
    *dashOffset = dashoff + len;
    while (nBox--) {
        oc1 = 0;
        oc2 = 0;
        OUTCODES(oc1, x1, y1, pBox);
        OUTCODES(oc2, x2, y2, pBox);
        if ((oc1 | oc2) == 0) {
            (*bres) (pDrawable, pGC, dashoff,
                     signdx, signdy, axis, x1, y1, e, e1, e3, len);
            break;
        }
        else if (oc1 & oc2) {
            pBox++;
        }
        else {
            int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
            int clip1 = 0, clip2 = 0;
            int clipdx, clipdy;
            int err;

            if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2 - 1,
                               pBox->y2 - 1,
                               &new_x1, &new_y1, &new_x2, &new_y2,
                               adx, ady, &clip1, &clip2,
                               octant, bias, oc1, oc2) == -1) {
                pBox++;
                continue;
            }

            if (axis == X_AXIS)
                len = abs(new_x2 - new_x1);
            else
                len = abs(new_y2 - new_y1);
            if (clip2 != 0 || drawLast)
                len++;
            if (len) {
                /* unwind bresenham error term to first point */
                doff = dashoff;
                err = e;
                if (clip1) {
                    clipdx = abs(new_x1 - x1);
                    clipdy = abs(new_y1 - y1);
                    if (axis == X_AXIS) {
                        doff += clipdx;
                        err += e3 * clipdy + e1 * clipdx;
                    }
                    else {
                        doff += clipdy;
                        err += e3 * clipdx + e1 * clipdy;
                    }
                }
                (*bres) (pDrawable, pGC, doff,
                         signdx, signdy, axis, new_x1, new_y1,
                         err, e1, e3, len);
            }
            pBox++;
        }
    }                           /* while (nBox--) */
}
Example #17
0
void
fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
{
    FbGCPrivPtr	pPriv = fbGetGCPrivate(pGC);
    FbBits	mask;

    pGC->lastWinOrg.x = pDrawable->x;
    pGC->lastWinOrg.y = pDrawable->y;

    /*
     * 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);
	pPriv->oneRect = REGION_NUM_RECTS(fbGetCompositeClip(pGC)) == 1;
    }
    
#ifdef FB_24_32BIT    
    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;
	    }
	}
    }
#endif
    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;
    }
}
Example #18
0
static Bool
exaDoPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
              int w, int h, int format, char *bits, int src_stride)
{
    ExaScreenPriv(pDrawable->pScreen);
    PixmapPtr pPix = exaGetDrawablePixmap(pDrawable);

    ExaPixmapPriv(pPix);
    RegionPtr pClip;
    BoxPtr pbox;
    int nbox;
    int xoff, yoff;
    int bpp = pDrawable->bitsPerPixel;
    Bool ret = TRUE;

    if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
        !pExaScr->info->UploadToScreen)
        return FALSE;

    /* If there's a system copy, we want to save the result there */
    if (pExaPixmap->pDamage)
        return FALSE;

    /* Don't bother with under 8bpp, XYPixmaps. */
    if (format != ZPixmap || bpp < 8)
        return FALSE;

    /* Only accelerate copies: no rop or planemask. */
    if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
        return FALSE;

    if (pExaScr->swappedOut)
        return FALSE;

    if (pExaScr->do_migration) {
        ExaMigrationRec pixmaps[1];

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pPix;
        pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);

        exaDoMigration(pixmaps, 1, TRUE);
    }

    pPix = exaGetOffscreenPixmap(pDrawable, &xoff, &yoff);

    if (!pPix)
        return FALSE;

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

    pClip = fbGetCompositeClip(pGC);
    for (nbox = RegionNumRects(pClip),
         pbox = RegionRects(pClip); nbox--; pbox++) {
        int x1 = x;
        int y1 = y;
        int x2 = x + w;
        int y2 = y + h;
        char *src;
        Bool ok;

        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;

        src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
        ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
                                           x2 - x1, y2 - y1, src, src_stride);
        /* We have to fall back completely, and ignore what has already been completed.
         * Messing with the fb layer directly like we used to is completely unacceptable.
         */
        if (!ok) {
            ret = FALSE;
            break;
        }
    }

    if (ret)
        exaMarkSync(pDrawable->pScreen);

    return ret;
}
Example #19
0
static void
exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
             DDXPointPtr ppt, int *pwidth, int fSorted)
{
    ScreenPtr pScreen = pDrawable->pScreen;

    ExaScreenPriv(pScreen);
    RegionPtr pClip = fbGetCompositeClip(pGC);
    PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);

    ExaPixmapPriv(pPixmap);
    BoxPtr pextent, pbox;
    int nbox;
    int extentX1, extentX2, extentY1, extentY2;
    int fullX1, fullX2, fullY1;
    int partX1, partX2;
    int off_x, off_y;

    if (pExaScr->fallback_counter ||
        pExaScr->swappedOut ||
        pGC->fillStyle != FillSolid || pExaPixmap->accel_blocked) {
        ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted);
        return;
    }

    if (pExaScr->do_migration) {
        ExaMigrationRec pixmaps[1];

        pixmaps[0].as_dst = TRUE;
        pixmaps[0].as_src = FALSE;
        pixmaps[0].pPix = pPixmap;
        pixmaps[0].pReg = NULL;

        exaDoMigration(pixmaps, 1, TRUE);
    }

    if (!(pPixmap = exaGetOffscreenPixmap(pDrawable, &off_x, &off_y)) ||
        !(*pExaScr->info->PrepareSolid) (pPixmap,
                                         pGC->alu,
                                         pGC->planemask, pGC->fgPixel)) {
        ExaCheckFillSpans(pDrawable, pGC, n, ppt, pwidth, fSorted);
        return;
    }

    pextent = RegionExtents(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 = RegionNumRects(pClip);
        if (nbox == 1) {
            (*pExaScr->info->Solid) (pPixmap,
                                     fullX1 + off_x, fullY1 + off_y,
                                     fullX2 + off_x, fullY1 + 1 + off_y);
        }
        else {
            pbox = RegionRects(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) {
                        (*pExaScr->info->Solid) (pPixmap,
                                                 partX1 + off_x, fullY1 + off_y,
                                                 partX2 + off_x,
                                                 fullY1 + 1 + off_y);
                    }
                }
                pbox++;
            }
        }
    }
    (*pExaScr->info->DoneSolid) (pPixmap);
    exaMarkSync(pScreen);
}
Example #20
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);
}
Example #21
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;
    }
}
Example #22
0
static void
uxa_fill_spans(DrawablePtr pDrawable, GCPtr pGC, int n,
	       DDXPointPtr ppt, int *pwidth, int fSorted)
{
	ScreenPtr screen = pDrawable->pScreen;
	uxa_screen_t *uxa_screen = uxa_get_screen(screen);
	RegionPtr pClip = fbGetCompositeClip(pGC);
	PixmapPtr dst_pixmap;
	BoxPtr pbox;
	int nbox;
	int x1, x2, y;
	int off_x, off_y;

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok = 0;

		if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) {
			ok = glamor_fill_spans_nf(pDrawable,
						  pGC, n, ppt, pwidth, fSorted);
			uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
		}

		if (!ok)
			goto fallback;

		return;
	}

	if (uxa_screen->force_fallback)
		goto fallback;

	if (pGC->fillStyle != FillSolid)
		goto fallback;

	dst_pixmap = uxa_get_offscreen_pixmap(pDrawable, &off_x, &off_y);
	if (!dst_pixmap)
		goto fallback;

	if (uxa_screen->info->check_solid &&
	    !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask))
		goto fallback;

	if (!(*uxa_screen->info->prepare_solid) (dst_pixmap,
						 pGC->alu,
						 pGC->planemask,
						 pGC->fgPixel))
		goto fallback;

	while (n--) {
		x1 = ppt->x;
		y = ppt->y;
		x2 = x1 + (int)*pwidth;
		ppt++;
		pwidth++;

		nbox = REGION_NUM_RECTS(pClip);
		pbox = REGION_RECTS(pClip);
		while (nbox--) {
			int X1 = x1, X2 = x2;
			if (X1 < pbox->x1)
				X1 = pbox->x1;

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

			if (X2 > X1 && pbox->y1 <= y && pbox->y2 > y)
				(*uxa_screen->info->solid) (dst_pixmap,
							    X1 + off_x, y + off_y,
							    X2 + off_x, y + 1 + off_y);
			pbox++;
		}
	}
	(*uxa_screen->info->done_solid) (dst_pixmap);

	return;

fallback:
	uxa_check_fill_spans(pDrawable, pGC, n, ppt, pwidth, fSorted);
}
Example #23
0
static void
glamor_put_image_xybitmap(DrawablePtr drawable, GCPtr gc,
			  int x, int y, int w, int h, int left_pad,
			  int image_format, char *bits)
{
	ScreenPtr screen = drawable->pScreen;
	PixmapPtr pixmap = glamor_get_drawable_pixmap(drawable);
	glamor_screen_private *glamor_priv =
	    glamor_get_screen_private(screen);
	float fg[4], bg[4];
	GLuint tex;
	unsigned int stride = PixmapBytePad(1, w + left_pad);
	RegionPtr clip;
	BoxPtr box;
	int nbox;
	float dest_coords[8];
	const float bitmap_coords[8] = {
		0.0, 0.0,
		1.0, 0.0,
		1.0, 1.0,
		0.0, 1.0,
	};
	GLfloat xscale, yscale;
	glamor_pixmap_private *pixmap_priv;

	pixmap_priv = glamor_get_pixmap_private(pixmap);

	pixmap_priv_get_scale(pixmap_priv, &xscale, &yscale);

	glamor_set_normalize_vcoords(xscale, yscale,
				     x, y,
				     x + w, y + h,
				     glamor_priv->yInverted, dest_coords);

	glamor_fallback("glamor_put_image_xybitmap: disabled\n");
	goto fail;

	if (glamor_priv->put_image_xybitmap_prog == 0) {
		ErrorF("no program for xybitmap putimage\n");
		goto fail;
	}

	glamor_set_alu(gc->alu);
	if (!glamor_set_planemask(pixmap, gc->planemask))
		goto fail;

	dispatch->glUseProgram(glamor_priv->put_image_xybitmap_prog);

	glamor_get_color_4f_from_pixel(pixmap, gc->fgPixel, fg);
	dispatch->glUniform4fv
	    (glamor_priv->put_image_xybitmap_fg_uniform_location, 1, fg);
	glamor_get_color_4f_from_pixel(pixmap, gc->bgPixel, bg);
	dispatch->glUniform4fv
	    (glamor_priv->put_image_xybitmap_bg_uniform_location, 1, bg);

	dispatch->glGenTextures(1, &tex);
	dispatch->glActiveTexture(GL_TEXTURE0);
	dispatch->glBindTexture(GL_TEXTURE_2D, tex);
	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
				  GL_NEAREST);
	dispatch->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
				  GL_NEAREST);
	dispatch->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, stride * 8);
	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, left_pad);
	dispatch->glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA,
			       w, h, 0, GL_COLOR_INDEX, GL_BITMAP, bits);
	dispatch->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
	dispatch->glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);

	/* Now that we've set up our bitmap texture and the shader, shove
	 * the destination rectangle through the cliprects and run the
	 * shader on the resulting fragments.
	 */
	dispatch->glVertexPointer(2, GL_FLOAT, 0, dest_coords);
	dispatch->glEnableClientState(GL_VERTEX_ARRAY);
	dispatch->glClientActiveTexture(GL_TEXTURE0);
	dispatch->glTexCoordPointer(2, GL_FLOAT, 0, bitmap_coords);
	dispatch->glEnableClientState(GL_TEXTURE_COORD_ARRAY);

	dispatch->glEnable(GL_SCISSOR_TEST);
	clip = fbGetCompositeClip(gc);
	for (nbox = REGION_NUM_RECTS(clip),
	     box = REGION_RECTS(clip); nbox--; box++) {
		int x1 = x;
		int y1 = y;
		int x2 = x + w;
		int y2 = y + h;

		if (x1 < box->x1)
			x1 = box->x1;
		if (y1 < box->y1)
			y1 = box->y1;
		if (x2 > box->x2)
			x2 = box->x2;
		if (y2 > box->y2)
			y2 = box->y2;
		if (x1 >= x2 || y1 >= y2)
			continue;

		dispatch->glScissor(box->x1,
				    y_flip(pixmap, box->y1),
				    box->x2 - box->x1, box->y2 - box->y1);
		dispatch->glDrawArrays(GL_QUADS, 0, 4);
	}

	dispatch->glDisable(GL_SCISSOR_TEST);
	glamor_set_alu(GXcopy);
	glamor_set_planemask(pixmap, ~0);
	dispatch->glDeleteTextures(1, &tex);
	dispatch->glDisableClientState(GL_VERTEX_ARRAY);
	dispatch->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	return;
	glamor_set_alu(GXcopy);
	glamor_set_planemask(pixmap, ~0);
	glamor_fallback(": to %p (%c)\n",
			drawable, glamor_get_drawable_location(drawable));
fail:
	if (glamor_prepare_access(drawable, GLAMOR_ACCESS_RW) &&
	    glamor_prepare_access_gc(gc)) {
		fbPutImage(drawable, gc, 1, x, y, w, h, left_pad, XYBitmap,
			   bits);
	}
	glamor_finish_access_gc(gc);
	glamor_finish_access(drawable);
}
Example #24
0
void
fbPutImage (DrawablePtr	pDrawable,
	    GCPtr	pGC,
	    int		depth,
	    int		x,
	    int		y,
	    int		w,
	    int		h,
	    int		leftPad,
	    int		format,
	    char	*pImage)
{
    FbGCPrivPtr	    pPriv = fbGetGCPrivate(pGC);
    unsigned long   i;
    FbStride	    srcStride;
    FbStip	    *src = (FbStip *) pImage;
    
    x += pDrawable->x;
    y += pDrawable->y;
    
    switch (format)
    {
    case XYBitmap:
	srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
	fbPutXYImage (pDrawable,
		      fbGetCompositeClip(pGC),
		      pPriv->fg,
		      pPriv->bg,
		      pPriv->pm,
		      pGC->alu,
		      TRUE,
		      x, y, w, h,
		      src,
		      srcStride,
		      leftPad);
	break;
    case XYPixmap:
	srcStride = BitmapBytePad(w + leftPad) / sizeof (FbStip);
	for (i = 1 << (pDrawable->depth - 1); i; i >>= 1)
	{
	    if (i & pGC->planemask)
	    {
		fbPutXYImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      FB_ALLONES,
			      0,
			      fbReplicatePixel (i, pDrawable->bitsPerPixel),
			      pGC->alu,
			      TRUE,
			      x, y, w, h,
			      src,
			      srcStride,
			      leftPad);
		src += srcStride * h;
	    }
	}
	break;
    case ZPixmap:
#ifdef FB_24_32BIT
	if (pDrawable->bitsPerPixel != BitsPerPixel(pDrawable->depth))
	{
	    srcStride = PixmapBytePad(w, pDrawable->depth);
	    fb24_32PutZImage (pDrawable,
			      fbGetCompositeClip(pGC),
			      pGC->alu,
			      (FbBits) pGC->planemask,
			      x, y, w, h,
			      (CARD8 *) pImage,
			      srcStride);
	}
	else
#endif
	{
	    srcStride = PixmapBytePad(w, pDrawable->depth) / sizeof (FbStip);
	    fbPutZImage (pDrawable,
			 fbGetCompositeClip(pGC),
			 pGC->alu,
			 pPriv->pm,
			 x, y, w, h, 
			 src, srcStride);
	}
    }
}
Example #25
0
static Bool
uxa_do_put_image(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
		 int w, int h, int format, char *bits, int src_stride)
{
	uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen);
	PixmapPtr pPix;
	RegionPtr pClip;
	BoxPtr pbox;
	int nbox;
	int xoff, yoff;
	int bpp = pDrawable->bitsPerPixel;

	/* Don't bother with under 8bpp, XYPixmaps. */
	if (format != ZPixmap || bpp < 8)
		return FALSE;

	if (uxa_screen->force_fallback)
		return FALSE;

	if (!uxa_screen->info->put_image)
		return FALSE;

	/* Only accelerate copies: no rop or planemask. */
	if (!UXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
		return FALSE;

	pPix = uxa_get_offscreen_pixmap(pDrawable, &xoff, &yoff);
	if (!pPix)
		return FALSE;

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

	pClip = fbGetCompositeClip(pGC);
	for (nbox = REGION_NUM_RECTS(pClip),
	     pbox = REGION_RECTS(pClip); nbox--; pbox++) {
		int x1 = x;
		int y1 = y;
		int x2 = x + w;
		int y2 = y + h;
		char *src;
		Bool ok;

		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;

		src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
		ok = uxa_screen->info->put_image(pPix, x1 + xoff, y1 + yoff,
						 x2 - x1, y2 - y1, src,
						 src_stride);
		/* If we fail to accelerate the upload, fall back to using
		 * unaccelerated fb calls.
		 */
		if (!ok) {
			FbStip *dst;
			FbStride dst_stride;
			int dstBpp;
			int dstXoff, dstYoff;

			if (!uxa_prepare_access(pDrawable, UXA_ACCESS_RW))
				return FALSE;

			fbGetStipDrawable(pDrawable, dst, dst_stride, dstBpp,
					  dstXoff, dstYoff);

			fbBltStip((FbStip *) bits +
				  (y1 - y) * (src_stride / sizeof(FbStip)),
				  src_stride / sizeof(FbStip),
				  (x1 - x) * dstBpp,
				  dst + (y1 + dstYoff) * dst_stride, dst_stride,
				  (x1 + dstXoff) * dstBpp, (x2 - x1) * dstBpp,
				  y2 - y1, GXcopy, FB_ALLONES, dstBpp);

			uxa_finish_access(pDrawable, UXA_ACCESS_RW);
		}
	}


	return TRUE;
}
Example #26
0
static void
uxa_poly_fill_rect(DrawablePtr pDrawable,
		   GCPtr pGC, int nrect, xRectangle * prect)
{
	uxa_screen_t *uxa_screen = uxa_get_screen(pDrawable->pScreen);
	RegionPtr pClip = fbGetCompositeClip(pGC);
	PixmapPtr pPixmap;
	RegionPtr pReg;
	BoxPtr pbox;
	int fullX1, fullX2, fullY1, fullY2;
	int xoff, yoff;
	int xorg, yorg;
	int n;

	if (uxa_screen->info->flags & UXA_USE_GLAMOR) {
		int ok = 0;

		if (uxa_prepare_access(pDrawable, UXA_GLAMOR_ACCESS_RW)) {
			ok = glamor_poly_fill_rect_nf(pDrawable, pGC, nrect, prect);
			uxa_finish_access(pDrawable, UXA_GLAMOR_ACCESS_RW);
		}

		if (!ok)
			uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect);

		return;
	}

	/* Compute intersection of rects and clip region */
	pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
	REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
	REGION_INTERSECT(pScreen, pReg, pClip, pReg);

	if (!REGION_NUM_RECTS(pReg))
		goto out;

	if (uxa_screen->force_fallback)
		goto fallback;

	pPixmap = uxa_get_offscreen_pixmap (pDrawable, &xoff, &yoff);
	if (!pPixmap)
		goto fallback;

	/* For ROPs where overlaps don't matter, convert rectangles to region
	 * and call uxa_fill_region_{solid,tiled}.
	 */
	if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
	    (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
	     pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
	     pGC->alu == GXset)) {
		if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
		     uxa_fill_region_solid(pDrawable, pReg,
					   pGC->fillStyle ==
					   FillSolid ? pGC->fgPixel : pGC->tile.
					   pixel, pGC->planemask, pGC->alu))
		    || (pGC->fillStyle == FillTiled && !pGC->tileIsPixel
			&& uxa_fill_region_tiled(pDrawable, pReg,
						 pGC->tile.pixmap, &pGC->patOrg,
						 pGC->planemask, pGC->alu))) {
			goto out;
		}
	}

	if (pGC->fillStyle != FillSolid &&
	    !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) {
		goto fallback;
	}

	if (uxa_screen->info->check_solid &&
	    !uxa_screen->info->check_solid(pDrawable, pGC->alu, pGC->planemask)) {
		goto fallback;
	}

	if (!(*uxa_screen->info->prepare_solid) (pPixmap,
						 pGC->alu,
						 pGC->planemask,
						 pGC->fgPixel)) {
fallback:
		uxa_check_poly_fill_rect(pDrawable, pGC, nrect, prect);
		goto out;
	}

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

	while (nrect--) {
		fullX1 = prect->x + xorg;
		fullY1 = prect->y + yorg;
		fullX2 = fullX1 + (int)prect->width;
		fullY2 = fullY1 + (int)prect->height;
		prect++;

		n = REGION_NUM_RECTS(pClip);
		pbox = REGION_RECTS(pClip);
		/*
		 * clip the rectangle to each box in the clip region
		 * this is logically equivalent to calling Intersect(),
		 * but rectangles may overlap each other here.
		 */
		while (n--) {
			int x1 = fullX1;
			int x2 = fullX2;
			int y1 = fullY1;
			int y2 = fullY2;

			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++;

			if (x1 >= x2 || y1 >= y2)
				continue;

			(*uxa_screen->info->solid) (pPixmap,
						    x1 + xoff,
						    y1 + yoff,
						    x2 + xoff,
						    y2 + yoff);
		}
	}
	(*uxa_screen->info->done_solid) (pPixmap);

out:
	REGION_UNINIT(pScreen, pReg);
	REGION_DESTROY(pScreen, pReg);
}