Add RandR reflection support.
Replace the ad-hoc transformation mechanisms with matrices. Prepares for more general transformation as well.
This commit is contained in:
		
							parent
							
								
									8773ad023e
								
							
						
					
					
						commit
						393171034c
					
				| 
						 | 
				
			
			@ -676,7 +676,8 @@ xf86CrtcScreenInit (ScreenPtr screen)
 | 
			
		|||
    }
 | 
			
		||||
    if (c == config->num_crtc)
 | 
			
		||||
	xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
 | 
			
		||||
				 RR_Rotate_180 | RR_Rotate_270);
 | 
			
		||||
				 RR_Rotate_180 | RR_Rotate_270 |
 | 
			
		||||
				 RR_Reflect_X | RR_Reflect_Y);
 | 
			
		||||
    else
 | 
			
		||||
	xf86RandR12SetRotations (screen, RR_Rotate_0);
 | 
			
		||||
    
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -279,6 +279,17 @@ struct _xf86Crtc {
 | 
			
		|||
     * Track state of cursor associated with this CRTC
 | 
			
		||||
     */
 | 
			
		||||
    Bool	    cursor_shown;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Current transformation matrix
 | 
			
		||||
     */
 | 
			
		||||
    PictTransform   crtc_to_framebuffer;
 | 
			
		||||
    PictTransform   framebuffer_to_crtc;
 | 
			
		||||
    Bool	    transform_in_use;
 | 
			
		||||
    /**
 | 
			
		||||
     * Bounding box in screen space
 | 
			
		||||
     */
 | 
			
		||||
    BoxRec	    bounds;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct _xf86OutputFuncs {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,29 +58,73 @@ xf86_crtc_rotate_coord (Rotation    rotation,
 | 
			
		|||
			int	    *x_src,
 | 
			
		||||
			int	    *y_src)
 | 
			
		||||
{
 | 
			
		||||
    int t;
 | 
			
		||||
    
 | 
			
		||||
    switch (rotation & 0xf) {
 | 
			
		||||
    case RR_Rotate_0:
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_90:
 | 
			
		||||
	t = x_dst;
 | 
			
		||||
	x_dst = height - y_dst - 1;
 | 
			
		||||
	y_dst = t;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_180:
 | 
			
		||||
	x_dst = width - x_dst - 1;
 | 
			
		||||
	y_dst = height - y_dst - 1;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_270:
 | 
			
		||||
	t = x_dst;
 | 
			
		||||
	x_dst = y_dst;
 | 
			
		||||
	y_dst = width - t - 1;
 | 
			
		||||
	break;
 | 
			
		||||
    }
 | 
			
		||||
    if (rotation & RR_Reflect_X)
 | 
			
		||||
	x_dst = width - x_dst - 1;
 | 
			
		||||
    if (rotation & RR_Reflect_Y)
 | 
			
		||||
	y_dst = height - y_dst - 1;
 | 
			
		||||
    *x_src = x_dst;
 | 
			
		||||
    *y_src = y_dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Given a cursor source  coordinate, rotate to a screen coordinate
 | 
			
		||||
 */
 | 
			
		||||
static void
 | 
			
		||||
xf86_crtc_rotate_coord_back (Rotation    rotation,
 | 
			
		||||
			     int	    width,
 | 
			
		||||
			     int	    height,
 | 
			
		||||
			     int	    x_dst,
 | 
			
		||||
			     int	    y_dst,
 | 
			
		||||
			     int	    *x_src,
 | 
			
		||||
			     int	    *y_src)
 | 
			
		||||
{
 | 
			
		||||
    int t;
 | 
			
		||||
    
 | 
			
		||||
    if (rotation & RR_Reflect_X)
 | 
			
		||||
	x_dst = width - x_dst - 1;
 | 
			
		||||
    if (rotation & RR_Reflect_Y)
 | 
			
		||||
	y_dst = height - y_dst - 1;
 | 
			
		||||
 | 
			
		||||
    switch (rotation & 0xf) {
 | 
			
		||||
    case RR_Rotate_0:
 | 
			
		||||
	*x_src = x_dst;
 | 
			
		||||
	*y_src = y_dst;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_90:
 | 
			
		||||
	*x_src = height - y_dst - 1;
 | 
			
		||||
	*y_src = x_dst;
 | 
			
		||||
	t = x_dst;
 | 
			
		||||
	x_dst = y_dst;
 | 
			
		||||
	y_dst = width - t - 1;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_180:
 | 
			
		||||
	*x_src = width - x_dst - 1;
 | 
			
		||||
	*y_src = height - y_dst - 1;
 | 
			
		||||
	x_dst = width - x_dst - 1;
 | 
			
		||||
	y_dst = height - y_dst - 1;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_270:
 | 
			
		||||
	*x_src = y_dst;
 | 
			
		||||
	*y_src = width - x_dst - 1;
 | 
			
		||||
	t = x_dst;
 | 
			
		||||
	x_dst = height - y_dst - 1;
 | 
			
		||||
	y_dst = t;
 | 
			
		||||
	break;
 | 
			
		||||
    }
 | 
			
		||||
    *x_src = x_dst;
 | 
			
		||||
    *y_src = y_dst;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			@ -261,49 +305,33 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 | 
			
		|||
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 | 
			
		||||
    xf86CursorInfoPtr	cursor_info = xf86_config->cursor_info;
 | 
			
		||||
    DisplayModePtr	mode = &crtc->mode;
 | 
			
		||||
    int			x_temp;
 | 
			
		||||
    int			y_temp;
 | 
			
		||||
    Bool		in_range;
 | 
			
		||||
    int			dx, dy;
 | 
			
		||||
 | 
			
		||||
    /* 
 | 
			
		||||
     * Move to crtc coordinate space
 | 
			
		||||
     */
 | 
			
		||||
    x -= crtc->x;
 | 
			
		||||
    y -= crtc->y;
 | 
			
		||||
    
 | 
			
		||||
    /*
 | 
			
		||||
     * Rotate
 | 
			
		||||
     * Transform position of cursor on screen
 | 
			
		||||
     */
 | 
			
		||||
    switch ((crtc->rotation) & 0xf) {
 | 
			
		||||
    case RR_Rotate_0:
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_90:
 | 
			
		||||
	x_temp = y;
 | 
			
		||||
	y_temp = mode->VDisplay - cursor_info->MaxWidth - x;
 | 
			
		||||
	x = x_temp;
 | 
			
		||||
	y = y_temp;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_180:
 | 
			
		||||
	x_temp = mode->HDisplay - cursor_info->MaxWidth - x;
 | 
			
		||||
	y_temp = mode->VDisplay - cursor_info->MaxHeight - y;
 | 
			
		||||
	x = x_temp;
 | 
			
		||||
	y = y_temp;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_270:
 | 
			
		||||
	x_temp = mode->HDisplay - cursor_info->MaxHeight -  y;
 | 
			
		||||
	y_temp = x;
 | 
			
		||||
	x = x_temp;
 | 
			
		||||
	y = y_temp;
 | 
			
		||||
	break;
 | 
			
		||||
    if (crtc->transform_in_use)
 | 
			
		||||
    {
 | 
			
		||||
	PictVector	v;
 | 
			
		||||
	v.vector[0] = IntToxFixed (x); v.vector[1] = IntToxFixed (y); v.vector[2] = IntToxFixed(1);
 | 
			
		||||
	PictureTransformPoint (&crtc->framebuffer_to_crtc, &v);
 | 
			
		||||
	x = xFixedToInt (v.vector[0]); y = xFixedToInt (v.vector[1]);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
	x -= crtc->x;
 | 
			
		||||
	y -= crtc->y;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /*
 | 
			
		||||
     * Reflect
 | 
			
		||||
     * Transform position of cursor upper left corner
 | 
			
		||||
     */
 | 
			
		||||
    if (crtc->rotation & RR_Reflect_X)
 | 
			
		||||
	x = mode->HDisplay - cursor_info->MaxWidth - x;
 | 
			
		||||
    if (crtc->rotation & RR_Reflect_Y)
 | 
			
		||||
	y = mode->VDisplay - cursor_info->MaxHeight - y;
 | 
			
		||||
    xf86_crtc_rotate_coord_back (crtc->rotation,
 | 
			
		||||
				 cursor_info->MaxWidth,
 | 
			
		||||
				 cursor_info->MaxHeight,
 | 
			
		||||
				 0, 0, &dx, &dy);
 | 
			
		||||
    x -= dx;
 | 
			
		||||
    y -= dy;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Disable the cursor when it is outside the viewport
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,57 +68,204 @@ compWindowFormat (WindowPtr pWin)
 | 
			
		|||
			       compGetWindowVisual (pWin));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define F(x)	IntToxFixed(x)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xf86TranslateBox (BoxPtr b, int dx, int dy)
 | 
			
		||||
PictureTransformIdentity (PictTransformPtr matrix)
 | 
			
		||||
{
 | 
			
		||||
    b->x1 += dx;
 | 
			
		||||
    b->y1 += dy;
 | 
			
		||||
    b->x2 += dx;
 | 
			
		||||
    b->y2 += dy;
 | 
			
		||||
    int	i;
 | 
			
		||||
    memset (matrix, '\0', sizeof (PictTransform));
 | 
			
		||||
    for (i = 0; i < 3; i++)
 | 
			
		||||
	matrix->matrix[i][i] = F(1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
PictureTransformMultiply (PictTransformPtr dst, PictTransformPtr l, PictTransformPtr r)
 | 
			
		||||
{
 | 
			
		||||
    PictTransform   d;
 | 
			
		||||
    int		    dx, dy;
 | 
			
		||||
    int		    o;
 | 
			
		||||
 | 
			
		||||
    for (dy = 0; dy < 3; dy++)
 | 
			
		||||
	for (dx = 0; dx < 3; dx++)
 | 
			
		||||
	{
 | 
			
		||||
	    xFixed_48_16    v;
 | 
			
		||||
	    xFixed_32_32    partial;
 | 
			
		||||
	    v = 0;
 | 
			
		||||
	    for (o = 0; o < 3; o++)
 | 
			
		||||
	    {
 | 
			
		||||
		partial = (xFixed_32_32) l->matrix[dy][o] * (xFixed_32_32) r->matrix[o][dx];
 | 
			
		||||
		v += partial >> 16;
 | 
			
		||||
	    }
 | 
			
		||||
	    if (v > MAX_FIXED_48_16 || v < MIN_FIXED_48_16)
 | 
			
		||||
		return FALSE;
 | 
			
		||||
	    d.matrix[dy][dx] = (xFixed) v;
 | 
			
		||||
	}
 | 
			
		||||
    *dst = d;
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
xf86TransformBox (BoxPtr dst, BoxPtr src, Rotation rotation,
 | 
			
		||||
		  int xoff, int yoff,
 | 
			
		||||
		  int dest_width, int dest_height)
 | 
			
		||||
PictureTransformInitScale (PictTransformPtr t, xFixed sx, xFixed sy)
 | 
			
		||||
{
 | 
			
		||||
    BoxRec  stmp = *src;
 | 
			
		||||
    memset (t, '\0', sizeof (PictTransform));
 | 
			
		||||
    t->matrix[0][0] = sx;
 | 
			
		||||
    t->matrix[1][1] = sy;
 | 
			
		||||
    t->matrix[2][2] = F (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static xFixed
 | 
			
		||||
fixed_inverse (xFixed x)
 | 
			
		||||
{
 | 
			
		||||
    return (xFixed) ((((xFixed_48_16) F(1)) * F(1)) / x);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
PictureTransformScale (PictTransformPtr forward,
 | 
			
		||||
		       PictTransformPtr reverse,
 | 
			
		||||
		       xFixed sx, xFixed sy)
 | 
			
		||||
{
 | 
			
		||||
    PictTransform   t;
 | 
			
		||||
    
 | 
			
		||||
    xf86TranslateBox (&stmp, -xoff, -yoff);
 | 
			
		||||
    switch (rotation & 0xf) {
 | 
			
		||||
    default:
 | 
			
		||||
    case RR_Rotate_0:
 | 
			
		||||
	*dst = stmp;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_90:
 | 
			
		||||
	dst->x1 = stmp.y1;
 | 
			
		||||
	dst->y1 = dest_height - stmp.x2;
 | 
			
		||||
	dst->x2 = stmp.y2;
 | 
			
		||||
	dst->y2 = dest_height - stmp.x1;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_180:
 | 
			
		||||
	dst->x1 = dest_width - stmp.x2;
 | 
			
		||||
	dst->y1 = dest_height - stmp.y2;
 | 
			
		||||
	dst->x2 = dest_width - stmp.x1;
 | 
			
		||||
	dst->y2 = dest_height - stmp.y1;
 | 
			
		||||
	break;
 | 
			
		||||
    case RR_Rotate_270:
 | 
			
		||||
	dst->x1 = dest_width - stmp.y2;
 | 
			
		||||
	dst->y1 = stmp.x1;
 | 
			
		||||
	dst->y2 = stmp.x2;
 | 
			
		||||
	dst->x2 = dest_width - stmp.y1;
 | 
			
		||||
	break;
 | 
			
		||||
    PictureTransformInitScale (&t, sx, sy);
 | 
			
		||||
    if (!PictureTransformMultiply (forward, &t, forward))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    PictureTransformInitScale (&t, fixed_inverse (sx), fixed_inverse (sy));
 | 
			
		||||
    if (!PictureTransformMultiply (reverse, reverse, &t))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
PictureTransformInitRotate (PictTransformPtr t, xFixed c, xFixed s)
 | 
			
		||||
{
 | 
			
		||||
    memset (t, '\0', sizeof (PictTransform));
 | 
			
		||||
    t->matrix[0][0] = c;
 | 
			
		||||
    t->matrix[0][1] = -s;
 | 
			
		||||
    t->matrix[1][0] = s;
 | 
			
		||||
    t->matrix[1][1] = c;
 | 
			
		||||
    t->matrix[2][2] = F (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
PictureTransformRotate (PictTransformPtr forward,
 | 
			
		||||
			PictTransformPtr reverse,
 | 
			
		||||
			xFixed c, xFixed s)
 | 
			
		||||
{
 | 
			
		||||
    PictTransform   t;
 | 
			
		||||
    PictureTransformInitRotate (&t, c, s);
 | 
			
		||||
    if (!PictureTransformMultiply (forward, &t, forward))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    
 | 
			
		||||
    PictureTransformInitRotate (&t, c, -s);
 | 
			
		||||
    if (!PictureTransformMultiply (reverse, reverse, &t))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
PictureTransformInitTranslate (PictTransformPtr t, xFixed tx, xFixed ty)
 | 
			
		||||
{
 | 
			
		||||
    memset (t, '\0', sizeof (PictTransform));
 | 
			
		||||
    t->matrix[0][0] = F (1);
 | 
			
		||||
    t->matrix[0][2] = tx;
 | 
			
		||||
    t->matrix[1][1] = F (1);
 | 
			
		||||
    t->matrix[1][2] = ty;
 | 
			
		||||
    t->matrix[2][2] = F (1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
PictureTransformTranslate (PictTransformPtr forward,
 | 
			
		||||
			   PictTransformPtr reverse,
 | 
			
		||||
			   xFixed tx, xFixed ty)
 | 
			
		||||
{
 | 
			
		||||
    PictTransform   t;
 | 
			
		||||
    PictureTransformInitTranslate (&t, tx, ty);
 | 
			
		||||
    if (!PictureTransformMultiply (forward, &t, forward))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    
 | 
			
		||||
    PictureTransformInitTranslate (&t, -tx, -ty);
 | 
			
		||||
    if (!PictureTransformMultiply (reverse, reverse, &t))
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
PictureTransformBounds (BoxPtr b, PictTransformPtr matrix)
 | 
			
		||||
{
 | 
			
		||||
    PictVector	v[4];
 | 
			
		||||
    int		i;
 | 
			
		||||
    int		x1, y1, x2, y2;
 | 
			
		||||
 | 
			
		||||
    v[0].vector[0] = F (b->x1);    v[0].vector[1] = F (b->y1);	v[0].vector[2] = F(1);
 | 
			
		||||
    v[1].vector[0] = F (b->x2);    v[1].vector[1] = F (b->y1);	v[1].vector[2] = F(1);
 | 
			
		||||
    v[2].vector[0] = F (b->x2);    v[2].vector[1] = F (b->y2);	v[2].vector[2] = F(1);
 | 
			
		||||
    v[3].vector[0] = F (b->x1);    v[3].vector[1] = F (b->y2);	v[3].vector[2] = F(1);
 | 
			
		||||
    for (i = 0; i < 4; i++)
 | 
			
		||||
    {
 | 
			
		||||
	PictureTransformPoint (matrix, &v[i]);
 | 
			
		||||
	x1 = xFixedToInt (v[i].vector[0]);
 | 
			
		||||
	y1 = xFixedToInt (v[i].vector[1]);
 | 
			
		||||
	x2 = xFixedToInt (xFixedCeil (v[i].vector[0]));
 | 
			
		||||
	y2 = xFixedToInt (xFixedCeil (v[i].vector[1]));
 | 
			
		||||
	if (i == 0)
 | 
			
		||||
	{
 | 
			
		||||
	    b->x1 = x1; b->y1 = y1;
 | 
			
		||||
	    b->x2 = x2; b->y2 = y2;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
	    if (x1 < b->x1) b->x1 = x1;
 | 
			
		||||
	    if (y1 < b->y1) b->y1 = y1;
 | 
			
		||||
	    if (x2 > b->x2) b->x2 = x2;
 | 
			
		||||
	    if (y2 > b->y2) b->y2 = y2;
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
    if (rotation & RR_Reflect_X) {
 | 
			
		||||
	int x1 = dst->x1;
 | 
			
		||||
	dst->x1 = dest_width - dst->x2;
 | 
			
		||||
	dst->x2 = dest_width - x1;
 | 
			
		||||
    }
 | 
			
		||||
    if (rotation & RR_Reflect_Y) {
 | 
			
		||||
	int y1 = dst->y1;
 | 
			
		||||
	dst->y1 = dest_height - dst->y2;
 | 
			
		||||
	dst->y2 = dest_height - y1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
PictureTransformIsIdentity(PictTransform *t)
 | 
			
		||||
{
 | 
			
		||||
    return ((t->matrix[0][0] == t->matrix[1][1]) &&
 | 
			
		||||
            (t->matrix[0][0] == t->matrix[2][2]) &&
 | 
			
		||||
            (t->matrix[0][0] != 0) &&
 | 
			
		||||
            (t->matrix[0][1] == 0) &&
 | 
			
		||||
            (t->matrix[0][2] == 0) &&
 | 
			
		||||
            (t->matrix[1][0] == 0) &&
 | 
			
		||||
            (t->matrix[1][2] == 0) &&
 | 
			
		||||
            (t->matrix[2][0] == 0) &&
 | 
			
		||||
            (t->matrix[2][1] == 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#define toF(x)	((float) (x) / 65536.0f)
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
PictureTransformErrorF (PictTransform *t)
 | 
			
		||||
{
 | 
			
		||||
    ErrorF ("{ { %f %f %f } { %f %f %f } { %f %f %f } }",
 | 
			
		||||
	    toF(t->matrix[0][0]), toF(t->matrix[0][1]), toF(t->matrix[0][2]), 
 | 
			
		||||
	    toF(t->matrix[1][0]), toF(t->matrix[1][1]), toF(t->matrix[1][2]), 
 | 
			
		||||
	    toF(t->matrix[2][0]), toF(t->matrix[2][1]), toF(t->matrix[2][2]));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static Bool
 | 
			
		||||
PictureTransformIsInverse (char *where, PictTransform *a, PictTransform *b)
 | 
			
		||||
{
 | 
			
		||||
    PictTransform   t;
 | 
			
		||||
 | 
			
		||||
    PictureTransformMultiply (&t, a, b);
 | 
			
		||||
    if (!PictureTransformIsIdentity (&t))
 | 
			
		||||
    {
 | 
			
		||||
	ErrorF ("%s: ", where);
 | 
			
		||||
	PictureTransformErrorF (a);
 | 
			
		||||
	ErrorF (" * ");
 | 
			
		||||
	PictureTransformErrorF (b);
 | 
			
		||||
	ErrorF (" = ");
 | 
			
		||||
	PictureTransformErrorF (a);
 | 
			
		||||
	ErrorF ("\n");
 | 
			
		||||
	return FALSE;
 | 
			
		||||
    }
 | 
			
		||||
    return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
| 
						 | 
				
			
			@ -131,7 +278,6 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
 | 
			
		|||
    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;
 | 
			
		||||
| 
						 | 
				
			
			@ -156,45 +302,7 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
 | 
			
		|||
    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);
 | 
			
		||||
    error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
 | 
			
		||||
    if (error)
 | 
			
		||||
	return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -202,9 +310,8 @@ xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
 | 
			
		|||
    {
 | 
			
		||||
	BoxRec	dst_box;
 | 
			
		||||
 | 
			
		||||
	xf86TransformBox (&dst_box, b, crtc->rotation,
 | 
			
		||||
			  crtc->x, crtc->y,
 | 
			
		||||
			  crtc->mode.HDisplay, crtc->mode.VDisplay);
 | 
			
		||||
	dst_box = *b;
 | 
			
		||||
	PictureTransformBounds (&dst_box, &crtc->framebuffer_to_crtc);
 | 
			
		||||
	CompositePicture (PictOpSrc,
 | 
			
		||||
			  src, NULL, dst,
 | 
			
		||||
			  dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
 | 
			
		||||
| 
						 | 
				
			
			@ -296,15 +403,10 @@ xf86RotateRedisplay(ScreenPtr pScreen)
 | 
			
		|||
 | 
			
		||||
	    if (crtc->rotation != RR_Rotate_0 && crtc->enabled)
 | 
			
		||||
	    {
 | 
			
		||||
		BoxRec	    box;
 | 
			
		||||
		RegionRec   crtc_damage;
 | 
			
		||||
 | 
			
		||||
		/* compute portion of damage that overlaps crtc */
 | 
			
		||||
		box.x1 = crtc->x;
 | 
			
		||||
		box.x2 = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
 | 
			
		||||
		box.y1 = crtc->y;
 | 
			
		||||
		box.y2 = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
 | 
			
		||||
		REGION_INIT(pScreen, &crtc_damage, &box, 1);
 | 
			
		||||
		REGION_INIT(pScreen, &crtc_damage, &crtc->bounds, 1);
 | 
			
		||||
		REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
 | 
			
		||||
		
 | 
			
		||||
		/* update damaged region */
 | 
			
		||||
| 
						 | 
				
			
			@ -393,13 +495,93 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
 | 
			
		|||
    ScrnInfoPtr		pScrn = crtc->scrn;
 | 
			
		||||
    xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 | 
			
		||||
    ScreenPtr		pScreen = pScrn->pScreen;
 | 
			
		||||
    PictTransform	crtc_to_fb, fb_to_crtc;
 | 
			
		||||
    
 | 
			
		||||
    if (rotation == RR_Rotate_0)
 | 
			
		||||
    PictureTransformIdentity (&crtc_to_fb);
 | 
			
		||||
    PictureTransformIdentity (&fb_to_crtc);
 | 
			
		||||
    PictureTransformIsInverse ("identity", &crtc_to_fb, &fb_to_crtc);
 | 
			
		||||
    if (rotation != RR_Rotate_0)
 | 
			
		||||
    {
 | 
			
		||||
	xFixed	rot_cos, rot_sin, rot_dx, rot_dy;
 | 
			
		||||
	xFixed	scale_x, scale_y, scale_dx, scale_dy;
 | 
			
		||||
	int	mode_w = crtc->mode.HDisplay;
 | 
			
		||||
	int	mode_h = crtc->mode.VDisplay;
 | 
			
		||||
	
 | 
			
		||||
	/* rotation */
 | 
			
		||||
	switch (rotation & 0xf) {
 | 
			
		||||
	default:
 | 
			
		||||
	case RR_Rotate_0:
 | 
			
		||||
	    rot_cos = F ( 1);	    rot_sin = F ( 0);
 | 
			
		||||
	    rot_dx  = F ( 0);	    rot_dy  = F ( 0);
 | 
			
		||||
	    break;
 | 
			
		||||
	case RR_Rotate_90:
 | 
			
		||||
	    rot_cos = F ( 0);	    rot_sin = F ( 1);
 | 
			
		||||
	    rot_dx =  F ( mode_h);  rot_dy  = F (0);
 | 
			
		||||
	    break;
 | 
			
		||||
	case RR_Rotate_180:
 | 
			
		||||
	    rot_cos = F (-1);	    rot_sin = F ( 0);
 | 
			
		||||
	    rot_dx  = F (mode_w);   rot_dy  = F ( mode_h);
 | 
			
		||||
	    break;
 | 
			
		||||
	case RR_Rotate_270:
 | 
			
		||||
	    rot_cos = F ( 0);	    rot_sin = F (-1);
 | 
			
		||||
	    rot_dx  = F ( 0);	    rot_dy  = F ( mode_w);
 | 
			
		||||
	    break;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	PictureTransformRotate (&crtc_to_fb, &fb_to_crtc, rot_cos, rot_sin);
 | 
			
		||||
	PictureTransformIsInverse ("rotate", &crtc_to_fb, &fb_to_crtc);
 | 
			
		||||
 | 
			
		||||
	PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, rot_dx, rot_dy);
 | 
			
		||||
	PictureTransformIsInverse ("rotate translate", &crtc_to_fb, &fb_to_crtc);
 | 
			
		||||
 | 
			
		||||
	/* reflection */
 | 
			
		||||
	scale_x = F (1);
 | 
			
		||||
	scale_dx = 0;
 | 
			
		||||
	scale_y = F (1);
 | 
			
		||||
	scale_dy = 0;
 | 
			
		||||
	if (rotation & RR_Reflect_X)
 | 
			
		||||
	{
 | 
			
		||||
	    scale_x = F(-1);
 | 
			
		||||
	    if (rotation & (RR_Rotate_0|RR_Rotate_180))
 | 
			
		||||
		scale_dx = F(mode_w);
 | 
			
		||||
	    else
 | 
			
		||||
		scale_dx = F(mode_h);
 | 
			
		||||
	}
 | 
			
		||||
	if (rotation & RR_Reflect_Y)
 | 
			
		||||
	{
 | 
			
		||||
	    scale_y = F(-1);
 | 
			
		||||
	    if (rotation & (RR_Rotate_0|RR_Rotate_180))
 | 
			
		||||
		scale_dy = F(mode_h);
 | 
			
		||||
	    else
 | 
			
		||||
		scale_dy = F(mode_w);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	PictureTransformScale (&crtc_to_fb, &fb_to_crtc, scale_x, scale_y);
 | 
			
		||||
	PictureTransformIsInverse ("scale", &crtc_to_fb, &fb_to_crtc);
 | 
			
		||||
 | 
			
		||||
	PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, scale_dx, scale_dy);
 | 
			
		||||
	PictureTransformIsInverse ("scale translate", &crtc_to_fb, &fb_to_crtc);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /*
 | 
			
		||||
     * If the untranslated transformation is the identity,
 | 
			
		||||
     * disable the shadow buffer
 | 
			
		||||
     */
 | 
			
		||||
    if (PictureTransformIsIdentity (&crtc_to_fb))
 | 
			
		||||
    {
 | 
			
		||||
	crtc->transform_in_use = FALSE;
 | 
			
		||||
	PictureTransformInitTranslate (&crtc->crtc_to_framebuffer, 
 | 
			
		||||
				       F (-crtc->x), F (-crtc->y));
 | 
			
		||||
	PictureTransformInitTranslate (&crtc->framebuffer_to_crtc,
 | 
			
		||||
				       F ( crtc->x), F ( crtc->y));
 | 
			
		||||
	xf86RotateDestroy (crtc);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
	PictureTransformTranslate (&crtc_to_fb, &fb_to_crtc, crtc->x, crtc->y);
 | 
			
		||||
	PictureTransformIsInverse ("offset", &crtc_to_fb, &fb_to_crtc);
 | 
			
		||||
	
 | 
			
		||||
	/* 
 | 
			
		||||
	 * these are the size of the shadow pixmap, which
 | 
			
		||||
	 * matches the mode, not the pre-rotated copy in the
 | 
			
		||||
| 
						 | 
				
			
			@ -448,14 +630,14 @@ xf86CrtcRotate (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation)
 | 
			
		|||
	}
 | 
			
		||||
	if (0)
 | 
			
		||||
	{
 | 
			
		||||
bail2:
 | 
			
		||||
    bail2:
 | 
			
		||||
	    if (shadow || shadowData)
 | 
			
		||||
	    {
 | 
			
		||||
		crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
 | 
			
		||||
		crtc->rotatedPixmap = NULL;
 | 
			
		||||
		crtc->rotatedData = NULL;
 | 
			
		||||
	    }
 | 
			
		||||
bail1:
 | 
			
		||||
    bail1:
 | 
			
		||||
	    if (old_width && old_height)
 | 
			
		||||
		crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
 | 
			
		||||
								  NULL,
 | 
			
		||||
| 
						 | 
				
			
			@ -463,6 +645,14 @@ bail1:
 | 
			
		|||
								  old_height);
 | 
			
		||||
	    return FALSE;
 | 
			
		||||
	}
 | 
			
		||||
	crtc->transform_in_use = TRUE;
 | 
			
		||||
	crtc->crtc_to_framebuffer = crtc_to_fb;
 | 
			
		||||
	crtc->framebuffer_to_crtc = fb_to_crtc;
 | 
			
		||||
	crtc->bounds.x1 = 0;
 | 
			
		||||
	crtc->bounds.x2 = crtc->mode.HDisplay;
 | 
			
		||||
	crtc->bounds.y1 = 0;
 | 
			
		||||
	crtc->bounds.y2 = crtc->mode.VDisplay;
 | 
			
		||||
	PictureTransformBounds (&crtc->bounds, &crtc_to_fb);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /* All done */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue