Esempio n. 1
0
/*
 * Initialize one edge structure given a line, starting y value
 * and a pixel offset for the line
 */
void
RenderLineFixedEdgeInit (RenderEdge *e,
			 int	    n,
			 xFixed	    y,
			 xLineFixed *line,
			 int	    x_off,
			 int	    y_off)
{
    xFixed	x_off_fixed = IntToxFixed(x_off);
    xFixed	y_off_fixed = IntToxFixed(y_off);
    xPointFixed	*top, *bot;

    if (line->p1.y <= line->p2.y)
    {
	top = &line->p1;
	bot = &line->p2;
    }
    else
    {
	top = &line->p2;
	bot = &line->p1;
    }
    RenderEdgeInit (e, n, y,
		    top->x + x_off_fixed,
		    top->y + y_off_fixed,
		    bot->x + x_off_fixed,
		    bot->y + y_off_fixed);
}
Esempio n. 2
0
bool
sna_transform_is_integer_translation(const PictTransform *t, int16_t *tx, int16_t *ty)
{
	if (t == NULL) {
		*tx = *ty = 0;
		return true;
	}

	if (t->matrix[0][0] != IntToxFixed(1) ||
	    t->matrix[0][1] != 0 ||
	    t->matrix[1][0] != 0 ||
	    t->matrix[1][1] != IntToxFixed(1) ||
	    t->matrix[2][0] != 0 ||
	    t->matrix[2][1] != 0 ||
	    t->matrix[2][2] != IntToxFixed(1))
		return false;

	if (pixman_fixed_fraction(t->matrix[0][2]) ||
	    pixman_fixed_fraction(t->matrix[1][2]))
		return false;

	*tx = pixman_fixed_to_int(t->matrix[0][2]);
	*ty = pixman_fixed_to_int(t->matrix[1][2]);
	return true;
}
Esempio n. 3
0
bool
sna_transform_is_imprecise_integer_translation(const PictTransform *t,
					       int filter, bool precise,
					       int16_t *tx, int16_t *ty)
{
	if (t == NULL) {
		DBG(("%s: no transform\n", __FUNCTION__));
		*tx = *ty = 0;
		return true;
	}

	DBG(("%s: FilterNearest?=%d, precise?=%d, transform=[%f %f %f, %f %f %f, %f %f %f]\n",
	     __FUNCTION__, filter==PictFilterNearest, precise,
	     t->matrix[0][0]/65536., t->matrix[0][1]/65536., t->matrix[0][2]/65536.,
	     t->matrix[1][0]/65536., t->matrix[1][1]/65536., t->matrix[1][2]/65536.,
	     t->matrix[2][0]/65536., t->matrix[2][1]/65536., t->matrix[2][2]/65536.));

	if (t->matrix[0][0] != IntToxFixed(1) ||
	    t->matrix[0][1] != 0 ||
	    t->matrix[1][0] != 0 ||
	    t->matrix[1][1] != IntToxFixed(1) ||
	    t->matrix[2][0] != 0 ||
	    t->matrix[2][1] != 0 ||
	    t->matrix[2][2] != IntToxFixed(1)) {
		DBG(("%s: not unity scaling\n", __FUNCTION__));
		return false;
	}

	if (filter != PictFilterNearest) {
		if (precise) {
			if (pixman_fixed_fraction(t->matrix[0][2]) ||
			    pixman_fixed_fraction(t->matrix[1][2])) {
				DBG(("%s: precise, fractional translation\n", __FUNCTION__));
				return false;
			}
		} else {
			int f;

			f = pixman_fixed_fraction(t->matrix[0][2]);
			if (f > IntToxFixed(1)/4 && f < IntToxFixed(3)/4) {
				DBG(("%s: imprecise, fractional translation X: %x\n", __FUNCTION__, f));
				return false;
			}

			f = pixman_fixed_fraction(t->matrix[1][2]);
			if (f > IntToxFixed(1)/4 && f < IntToxFixed(3)/4) {
				DBG(("%s: imprecise, fractional translation Y: %x\n", __FUNCTION__, f));
				return false;
			}
		}
	}

	*tx = pixman_fixed_to_int(t->matrix[0][2] + IntToxFixed(1)/2);
	*ty = pixman_fixed_to_int(t->matrix[1][2] + IntToxFixed(1)/2);
	return true;
}
Esempio n. 4
0
void
fbRasterizeTrapezoid (PicturePtr    pPicture,
		      xTrapezoid  *trap,
		      int	    x_off,
		      int	    y_off)
{
    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;
    
    if (!xTrapezoidValid (trap))
	return;

    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(x_off);
    y_off_fixed = IntToxFixed(y_off);
    t = trap->top + y_off_fixed;
    if (t < 0)
	t = 0;
    t = RenderSampleCeilY (t, bpp);

    b = trap->bottom + y_off_fixed;
    if (xFixedToInt (b) >= height)
	b = IntToxFixed (height) - 1;
    b = RenderSampleFloorY (b, bpp);
    
    if (b >= t)
    {
	/* initialize edge walkers */
	RenderLineFixedEdgeInit (&l, bpp, t, &trap->left, x_off, y_off);
	RenderLineFixedEdgeInit (&r, bpp, t, &trap->right, x_off, y_off);
	
	fbRasterizeEdges (buf, bpp, width, stride, &l, &r, t, b);
    }
}
Esempio n. 5
0
static inline void
NV40EXATransformCoord(PictTransformPtr t, int x, int y, float sx, float sy,
					  float *x_ret, float *y_ret)
{
	if (t) {
		PictVector v;
		v.vector[0] = IntToxFixed(x);
		v.vector[1] = IntToxFixed(y);
		v.vector[2] = xFixed1;
		PictureTransformPoint(t, &v);
		*x_ret = xFixedToFloat(v.vector[0]) / sx;
		*y_ret = xFixedToFloat(v.vector[1]) / sy;
	} else {
		*x_ret = (float)x / sx;
		*y_ret = (float)y / sy;
	}
}
Esempio n. 6
0
bool
sna_transform_is_translation(const PictTransform *t,
			     pixman_fixed_t *tx,
			     pixman_fixed_t *ty)
{
	if (t == NULL) {
		*tx = *ty = 0;
		return true;
	}

	if (t->matrix[0][0] != IntToxFixed(1) ||
	    t->matrix[0][1] != 0 ||
	    t->matrix[1][0] != 0 ||
	    t->matrix[1][1] != IntToxFixed(1) ||
	    t->matrix[2][0] != 0 ||
	    t->matrix[2][1] != 0 ||
	    t->matrix[2][2] != IntToxFixed(1))
		return false;

	*tx = t->matrix[0][2];
	*ty = t->matrix[1][2];
	return true;
}
Esempio n. 7
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++;
    }
}
Esempio n. 8
0
/*
 * We want to detect the case where we add the same value to a long
 * span of pixels.  The triangles on the end are filled in while we
 * count how many sub-pixel scanlines contribute to the middle section.
 *
 *                 +--------------------------+
 *  fill_height =|   \                      /
 *                     +------------------+
 *                      |================|
 *                   fill_start       fill_end
 */
static void
fbRasterizeEdges8 (FbBits	*buf,
		   int		width,
		   int		stride,
		   RenderEdge	*l,
		   RenderEdge	*r,
		   xFixed	t,
		   xFixed	b)
{
    xFixed  y = t;
    FbBits  *line;
    int fill_start = -1, fill_end = -1;
    int fill_size = 0;

    line = buf + xFixedToInt (y) * stride;

    for (;;)
    {
        CARD8 *ap = (CARD8 *) line;
	xFixed	lx, rx;
	int	lxi, rxi;
	
	/* clip X */
	lx = l->x;
	if (lx < 0)
	    lx = 0;
	rx = r->x;
	if (xFixedToInt (rx) >= width)
	    rx = IntToxFixed (width);
	
	/* Skip empty (or backwards) sections */
	if (rx > lx)
	{
            int lxs, rxs;

	    /* Find pixel bounds for span. */
	    lxi = xFixedToInt (lx);
	    rxi = xFixedToInt (rx);

            /* Sample coverage for edge pixels */
            lxs = RenderSamplesX (lx, 8);
            rxs = RenderSamplesX (rx, 8);

            /* Add coverage across row */
            if (lxi == rxi)
            {
                ap[lxi] = clip255 (ap[lxi] + rxs - lxs);
            }
            else
            {
                ap[lxi] = clip255 (ap[lxi] + N_X_FRAC(8) - lxs);

                /* Move forward so that lxi/rxi is the pixel span */
                lxi++;

                /* Don't bother trying to optimize the fill unless
                 * the span is longer than 4 pixels. */
                if (rxi - lxi > 4)
                {
                    if (fill_start < 0)
                    {
                        fill_start = lxi;
                        fill_end = rxi;
                        fill_size++;
                    }
                    else
                    {
                        if (lxi >= fill_end || rxi < fill_start)
                        {
                            /* We're beyond what we saved, just fill it */
                            add_saturate_8 (ap + fill_start,
                                            fill_size * N_X_FRAC(8),
                                            fill_end - fill_start);
                            fill_start = lxi;
                            fill_end = rxi;
                            fill_size = 1;
                        }
                        else
                        {
                            /* Update fill_start */
                            if (lxi > fill_start)
                            {
                                add_saturate_8 (ap + fill_start,
                                                fill_size * N_X_FRAC(8),
                                                lxi - fill_start);
                                fill_start = lxi;
                            }
                            else if (lxi < fill_start)
                            {
                                add_saturate_8 (ap + lxi, N_X_FRAC(8),
                                                fill_start - lxi);
                            }

                            /* Update fill_end */
                            if (rxi < fill_end)
                            {
                                add_saturate_8 (ap + rxi,
                                                fill_size * N_X_FRAC(8),
                                                fill_end - rxi);
                                fill_end = rxi;
                            }
                            else if (fill_end < rxi)
                            {
                                add_saturate_8 (ap + fill_end,
                                                N_X_FRAC(8),
                                                rxi - fill_end);
                            }
                            fill_size++;
                        }
                    }
                }
                else
                {
                    add_saturate_8 (ap + lxi, N_X_FRAC(8), rxi - lxi);
                }

                /* Do not add in a 0 alpha here. This check is
                 * necessary to avoid a buffer overrun, (when rx
                 * is exactly on a pixel boundary). */
                if (rxs)
                    ap[rxi] = clip255 (ap[rxi] + rxs);
            }
	}

	if (y == b) {
            /* We're done, make sure we clean up any remaining fill. */
            if (fill_start != fill_end) {
                if (fill_size == N_Y_FRAC(8))
                {
                    memset (ap + fill_start, 0xff, fill_end - fill_start);
                }
                else
                {
                    add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
                                    fill_end - fill_start);
                }
            }
	    break;
        }

	if (xFixedFrac (y) != Y_FRAC_LAST(8))
	{
	    RenderEdgeStepSmall (l);
	    RenderEdgeStepSmall (r);
	    y += STEP_Y_SMALL(8);
	}
	else
	{
	    RenderEdgeStepBig (l);
	    RenderEdgeStepBig (r);
	    y += STEP_Y_BIG(8);
            if (fill_start != fill_end)
            {
                if (fill_size == N_Y_FRAC(8))
                {
                    memset (ap + fill_start, 0xff, fill_end - fill_start);
                }
                else
                {
                    add_saturate_8 (ap + fill_start, fill_size * N_X_FRAC(8),
                                    fill_end - fill_start);
                }
                fill_start = fill_end = -1;
                fill_size = 0;
            }
	    line += stride;
	}
    }
}
Esempio n. 9
0
static void
xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
{
    ScrnInfoPtr		scrn = crtc->scrn;
    ScreenPtr		screen = scrn->pScreen;
    WindowPtr		root = WindowTable[screen->myNum];
    PixmapPtr		dst_pixmap = crtc->rotatedPixmap;
    PictFormatPtr	format = compWindowFormat (WindowTable[screen->myNum]);
    int			error;
    PicturePtr		src, dst;
    PictTransform	transform;
    int			n = REGION_NUM_RECTS(region);
    BoxPtr		b = REGION_RECTS(region);
    XID			include_inferiors = IncludeInferiors;
    
    src = CreatePicture (None,
			 &root->drawable,
			 format,
			 CPSubwindowMode,
			 &include_inferiors,
			 serverClient,
			 &error);
    if (!src)
	return;

    dst = CreatePicture (None,
			 &dst_pixmap->drawable,
			 format,
			 0L,
			 NULL,
			 serverClient,
			 &error);
    if (!dst)
	return;

    memset (&transform, '\0', sizeof (transform));
    transform.matrix[2][2] = IntToxFixed(1);
    transform.matrix[0][2] = IntToxFixed(crtc->x);
    transform.matrix[1][2] = IntToxFixed(crtc->y);
    switch (crtc->rotation & 0xf) {
    default:
    case RR_Rotate_0:
	transform.matrix[0][0] = IntToxFixed(1);
	transform.matrix[1][1] = IntToxFixed(1);
	break;
    case RR_Rotate_90:
	transform.matrix[0][1] = IntToxFixed(-1);
	transform.matrix[1][0] = IntToxFixed(1);
	transform.matrix[0][2] += IntToxFixed(crtc->mode.VDisplay);
	break;
    case RR_Rotate_180:
	transform.matrix[0][0] = IntToxFixed(-1);
	transform.matrix[1][1] = IntToxFixed(-1);
	transform.matrix[0][2] += IntToxFixed(crtc->mode.HDisplay);
	transform.matrix[1][2] += IntToxFixed(crtc->mode.VDisplay);
	break;
    case RR_Rotate_270:
	transform.matrix[0][1] = IntToxFixed(1);
	transform.matrix[1][0] = IntToxFixed(-1);
	transform.matrix[1][2] += IntToxFixed(crtc->mode.HDisplay);
	break;
    }

    /* handle reflection */
    if (crtc->rotation & RR_Reflect_X)
    {
	/* XXX figure this out */
    }
    if (crtc->rotation & RR_Reflect_Y)
    {
	/* XXX figure this out too */
    }

    error = SetPictureTransform (src, &transform);
    if (error)
	return;

    while (n--)
    {
	BoxRec	dst_box;

	xf86TransformBox (&dst_box, b, crtc->rotation,
			  crtc->x, crtc->y,
			  crtc->mode.HDisplay, crtc->mode.VDisplay);
	CompositePicture (PictOpSrc,
			  src, NULL, dst,
			  dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
			  dst_box.x2 - dst_box.x1,
			  dst_box.y2 - dst_box.y1);
	b++;
    }
    FreePicture (src, None);
    FreePicture (dst, None);
}