mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-09 23:22:22 +00:00
randr: Add sprite position transforms
This implements sprite position transformations. Sprite image transforms are passed all the way to the DDX layer, but the images are not yet manipulated before being passed to the drivers. Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Aaron Plattner <aplattner@nvidia.com>
This commit is contained in:
parent
c8bc25fd76
commit
66294afcab
11 changed files with 333 additions and 46 deletions
|
|
@ -106,12 +106,17 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
|
|||
pixman_transform_init_identity (&crtc->crtc_to_framebuffer);
|
||||
pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer);
|
||||
pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc);
|
||||
pixman_f_transform_init_identity (&crtc->f_screen_to_crtc);
|
||||
pixman_f_transform_init_identity (&crtc->user_sprite_position_transform);
|
||||
pixman_f_transform_init_identity (&crtc->f_crtc_to_cursor);
|
||||
pixman_f_transform_init_identity (&crtc->user_sprite_image_transform);
|
||||
crtc->filter = NULL;
|
||||
crtc->params = NULL;
|
||||
crtc->nparams = 0;
|
||||
crtc->filter_width = 0;
|
||||
crtc->filter_height = 0;
|
||||
crtc->transform_in_use = FALSE;
|
||||
crtc->sprite_transform_in_use = FALSE;
|
||||
crtc->transformPresent = FALSE;
|
||||
crtc->desiredTransformPresent = FALSE;
|
||||
memset (&crtc->bounds, '\0', sizeof (crtc->bounds));
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ struct _xf86Crtc {
|
|||
int filter_width; /* ABI 2 */
|
||||
int filter_height; /* ABI 2 */
|
||||
Bool transform_in_use;
|
||||
Bool sprite_transform_in_use;
|
||||
RRTransformRec transform; /* ABI 2 */
|
||||
Bool transformPresent; /* ABI 2 */
|
||||
RRTransformRec desiredTransform; /* ABI 2 */
|
||||
|
|
@ -384,6 +385,22 @@ struct _xf86Crtc {
|
|||
* Clear the shadow
|
||||
*/
|
||||
Bool shadowClear;
|
||||
|
||||
/**
|
||||
* Sprite position transforms
|
||||
*/
|
||||
|
||||
/* Transform a screen coordinate to a crtc coordinate */
|
||||
struct pixman_f_transform f_screen_to_crtc;
|
||||
|
||||
/* The user-specified portion of the screen to crtc conversion */
|
||||
struct pixman_f_transform user_sprite_position_transform;
|
||||
|
||||
/* Transform a hardware cursor coordinate to a cursor coordinate */
|
||||
struct pixman_f_transform f_crtc_to_cursor;
|
||||
|
||||
/* The user-specified portion of the cursor to hardware transform */
|
||||
struct pixman_f_transform user_sprite_image_transform;
|
||||
};
|
||||
|
||||
typedef struct _xf86OutputFuncs {
|
||||
|
|
@ -777,6 +794,14 @@ xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y);
|
|||
extern _X_EXPORT Bool
|
||||
xf86CrtcRotate (xf86CrtcPtr crtc);
|
||||
|
||||
|
||||
/*
|
||||
* Update cursor transform matrices after user changes
|
||||
* This is just the cursor subset of xf86CrtcRotate
|
||||
*/
|
||||
extern _X_EXPORT void
|
||||
xf86CrtcRotateCursor (xf86CrtcPtr crtc);
|
||||
|
||||
/*
|
||||
* Clean up any rotation data, used when a crtc is turned off
|
||||
* as well as when rotation is disabled.
|
||||
|
|
|
|||
|
|
@ -338,7 +338,7 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
|
|||
/*
|
||||
* Transform position of cursor on screen
|
||||
*/
|
||||
if (crtc->transform_in_use)
|
||||
if (crtc->sprite_transform_in_use)
|
||||
{
|
||||
ScreenPtr screen = scrn->pScreen;
|
||||
xf86CursorScreenPtr ScreenPriv =
|
||||
|
|
@ -349,7 +349,7 @@ xf86_crtc_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
|
|||
v.v[0] = (x + ScreenPriv->HotX) + 0.5;
|
||||
v.v[1] = (y + ScreenPriv->HotY) + 0.5;
|
||||
v.v[2] = 1;
|
||||
pixman_f_transform_point (&crtc->f_framebuffer_to_crtc, &v);
|
||||
pixman_f_transform_point (&crtc->f_screen_to_crtc, &v);
|
||||
/* cursor will have 0.5 added to it already so floor is sufficent */
|
||||
x = floor (v.v[0]);
|
||||
y = floor (v.v[1]);
|
||||
|
|
|
|||
|
|
@ -180,14 +180,14 @@ xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeigh
|
|||
*/
|
||||
|
||||
static void
|
||||
xf86ComputeCrtcPan (Bool transform_in_use,
|
||||
xf86ComputeCrtcPan (Bool sprite_transform_in_use,
|
||||
struct pixman_f_transform *m,
|
||||
double screen_x, double screen_y,
|
||||
double crtc_x, double crtc_y,
|
||||
int old_pan_x, int old_pan_y,
|
||||
int *new_pan_x, int *new_pan_y)
|
||||
{
|
||||
if (transform_in_use) {
|
||||
if (sprite_transform_in_use) {
|
||||
/*
|
||||
* Given the current transform, M, the current position
|
||||
* on the Screen, S, and the desired position on the CRTC,
|
||||
|
|
@ -374,8 +374,8 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
|
|||
c.v[0] = x;
|
||||
c.v[1] = y;
|
||||
c.v[2] = 1.0;
|
||||
if (crtc->transform_in_use) {
|
||||
pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
|
||||
if (crtc->sprite_transform_in_use) {
|
||||
pixman_f_transform_point(&crtc->f_screen_to_crtc, &c);
|
||||
} else {
|
||||
c.v[0] -= crtc->x;
|
||||
c.v[1] -= crtc->y;
|
||||
|
|
@ -402,8 +402,8 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
|
|||
}
|
||||
}
|
||||
if (panned)
|
||||
xf86ComputeCrtcPan (crtc->transform_in_use,
|
||||
&crtc->f_framebuffer_to_crtc,
|
||||
xf86ComputeCrtcPan (crtc->sprite_transform_in_use,
|
||||
&crtc->f_screen_to_crtc,
|
||||
x, y, c.v[0], c.v[1],
|
||||
newX, newY, &newX, &newY);
|
||||
}
|
||||
|
|
@ -414,7 +414,7 @@ xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
|
|||
* XXX This computation only works when we do not have a transform
|
||||
* in use.
|
||||
*/
|
||||
if (!crtc->transform_in_use)
|
||||
if (!crtc->sprite_transform_in_use)
|
||||
{
|
||||
/* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
|
||||
if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
|
||||
|
|
@ -1732,6 +1732,20 @@ xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
|
|||
return Success;
|
||||
}
|
||||
|
||||
static void
|
||||
xf86RandR14SetCrtcSpriteTransform(ScreenPtr pScreen,
|
||||
RRCrtcPtr randr_crtc,
|
||||
struct pixman_f_transform *f_position_transform,
|
||||
struct pixman_f_transform *f_image_transform)
|
||||
{
|
||||
xf86CrtcPtr crtc = randr_crtc->devPrivate;
|
||||
|
||||
crtc->user_sprite_position_transform = *f_position_transform;
|
||||
crtc->user_sprite_image_transform = *f_image_transform;
|
||||
xf86CrtcRotateCursor(crtc);
|
||||
xf86_reload_cursors(pScreen);
|
||||
}
|
||||
|
||||
static Bool
|
||||
xf86RandR12EnterVT (int screen_index, int flags)
|
||||
{
|
||||
|
|
@ -1740,6 +1754,7 @@ xf86RandR12EnterVT (int screen_index, int flags)
|
|||
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
|
||||
rrScrPrivPtr rp = rrGetScrPriv(pScreen);
|
||||
Bool ret;
|
||||
int i;
|
||||
|
||||
if (randrp->orig_EnterVT) {
|
||||
pScrn->EnterVT = randrp->orig_EnterVT;
|
||||
|
|
@ -1751,7 +1766,6 @@ xf86RandR12EnterVT (int screen_index, int flags)
|
|||
}
|
||||
|
||||
/* reload gamma */
|
||||
int i;
|
||||
for (i = 0; i < rp->numCrtcs; i++)
|
||||
xf86RandR12CrtcSetGamma(pScreen, rp->crtcs[i]);
|
||||
|
||||
|
|
@ -1782,6 +1796,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
|
|||
rp->rrSetConfig = NULL;
|
||||
pScrn->PointerMoved = xf86RandR12PointerMoved;
|
||||
pScrn->ChangeGamma = xf86RandR12ChangeGamma;
|
||||
rp->rrSetCrtcSpriteTransform = xf86RandR14SetCrtcSpriteTransform;
|
||||
|
||||
randrp->orig_EnterVT = pScrn->EnterVT;
|
||||
pScrn->EnterVT = xf86RandR12EnterVT;
|
||||
|
|
|
|||
|
|
@ -369,6 +369,39 @@ xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
|
|||
0 <= b.y1 && b.y2 <= pScrn->virtualY);
|
||||
}
|
||||
|
||||
/*
|
||||
* A subset of xf86CrtcRotate that just deals with
|
||||
* cursor image/position transforms. Used when changing
|
||||
* the cursor transform
|
||||
*/
|
||||
void
|
||||
xf86CrtcRotateCursor (xf86CrtcPtr crtc)
|
||||
{
|
||||
/* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
|
||||
RRTransformPtr transform = NULL;
|
||||
PictTransform crtc_to_fb;
|
||||
struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc, f_screen_to_crtc, f_crtc_to_cursor;
|
||||
|
||||
if (crtc->transformPresent)
|
||||
transform = &crtc->transform;
|
||||
|
||||
(void) RRTransformCompute (crtc->x, crtc->y,
|
||||
crtc->mode.HDisplay, crtc->mode.VDisplay,
|
||||
crtc->rotation,
|
||||
transform,
|
||||
&crtc->user_sprite_position_transform,
|
||||
&crtc->user_sprite_image_transform,
|
||||
|
||||
&crtc_to_fb,
|
||||
&f_crtc_to_fb,
|
||||
&f_fb_to_crtc,
|
||||
&f_screen_to_crtc,
|
||||
&f_crtc_to_cursor,
|
||||
&crtc->sprite_transform_in_use);
|
||||
crtc->f_screen_to_crtc = f_screen_to_crtc;
|
||||
crtc->f_crtc_to_cursor = f_crtc_to_cursor;
|
||||
}
|
||||
|
||||
Bool
|
||||
xf86CrtcRotate (xf86CrtcPtr crtc)
|
||||
{
|
||||
|
|
@ -377,7 +410,7 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
|
|||
/* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
|
||||
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
|
||||
PictTransform crtc_to_fb;
|
||||
struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
|
||||
struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc, f_screen_to_crtc, f_crtc_to_cursor;
|
||||
xFixed *new_params = NULL;
|
||||
int new_nparams = 0;
|
||||
PictFilterPtr new_filter = NULL;
|
||||
|
|
@ -393,10 +426,15 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
|
|||
crtc->mode.HDisplay, crtc->mode.VDisplay,
|
||||
crtc->rotation,
|
||||
transform,
|
||||
&crtc->user_sprite_position_transform,
|
||||
&crtc->user_sprite_image_transform,
|
||||
|
||||
&crtc_to_fb,
|
||||
&f_crtc_to_fb,
|
||||
&f_fb_to_crtc) &&
|
||||
&f_fb_to_crtc,
|
||||
&f_screen_to_crtc,
|
||||
&f_crtc_to_cursor,
|
||||
&crtc->sprite_transform_in_use) &&
|
||||
xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
|
||||
{
|
||||
/*
|
||||
|
|
@ -505,6 +543,8 @@ xf86CrtcRotate (xf86CrtcPtr crtc)
|
|||
crtc->crtc_to_framebuffer = crtc_to_fb;
|
||||
crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
|
||||
crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
|
||||
crtc->f_screen_to_crtc = f_screen_to_crtc;
|
||||
crtc->f_crtc_to_cursor = f_crtc_to_cursor;
|
||||
free(crtc->params);
|
||||
crtc->params = new_params;
|
||||
crtc->nparams = new_nparams;
|
||||
|
|
|
|||
Loading…
Reference in a new issue