xserver: Branch 'master' - 13 commits
Keith Packard
keithp at kemper.freedesktop.org
Mon Dec 6 20:40:28 PST 2010
Xext/sync.c | 4
configure.ac | 2
hw/xfree86/common/xf86Helper.c | 6
hw/xfree86/modes/xf86Crtc.c | 139 ++++++----
hw/xfree86/modes/xf86Crtc.h | 119 ++++++++
hw/xfree86/modes/xf86Cursors.c | 4
hw/xfree86/modes/xf86RandR12.c | 387 ++++++++++++++++++++++------
hw/xfree86/modes/xf86Rotate.c | 44 +++
include/protocol-versions.h | 2
randr/Makefile.am | 6
randr/mirrcrtc.c | 174 ++++++++++++
randr/randr.c | 15 +
randr/randrstr.h | 207 +++++++++++++--
randr/rrcrtc.c | 562 ++++++++++++++++++++++++++++++++++++-----
randr/rrdispatch.c | 6
randr/rrinfo.c | 2
randr/rrpixmap.c | 154 +++++++++++
randr/rrscreen.c | 32 ++
randr/rrsdispatch.c | 132 +++++++++
randr/rrsprite.c | 104 +++++++
randr/rrtransform.c | 64 ++++
randr/rrtransform.h | 15 -
22 files changed, 1943 insertions(+), 237 deletions(-)
New commits:
commit 435361bd73b9fc733f093d81af6b839953e35176
Author: Keith Packard <keithp at keithp.com>
Date: Mon Dec 6 20:38:14 2010 -0800
sync: syncObject may be None in SyncInitTrigger
And often is, especially when called from ProcSyncCreateAlarm.
Crashing in this case seems unwise.
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/Xext/sync.c b/Xext/sync.c
index ce00755..ab8f20d 100644
--- a/Xext/sync.c
+++ b/Xext/sync.c
@@ -296,7 +296,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
/* if system counter, ask it what the current value is */
- if (SYNC_COUNTER == pSync->type)
+ if (pSync && SYNC_COUNTER == pSync->type)
{
pCounter = (SyncCounter *)pSync;
@@ -320,7 +320,7 @@ SyncInitTrigger(ClientPtr client, SyncTrigger *pTrigger, XID syncObject,
if (changes & XSyncCATestType)
{
- if (SYNC_FENCE == pSync->type)
+ if (pSync && SYNC_FENCE == pSync->type)
{
pTrigger->CheckTrigger = SyncCheckTriggerFence;
}
commit 0d01b66df9081ef48843b3bad81c56bb2cd1ae69
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 5 23:35:28 2010 -0800
randr: handle RRSetCrtcConfigs request with zero configs
Need to actually return a reply in this case.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 0fc8188..5fe6900 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1750,9 +1750,6 @@ ProcRRSetCrtcConfigs (ClientPtr client)
screen_config.mm_width = stuff->widthInMillimeters;
screen_config.mm_height = stuff->heightInMillimeters;
- if (num_configs == 0)
- return Success;
-
output_ids = (RROutput *) (x_configs + num_configs);
/*
@@ -1760,7 +1757,7 @@ ProcRRSetCrtcConfigs (ClientPtr client)
* server crtc configurations
*/
configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
- if (!configs)
+ if (num_configs > 0 && configs == NULL)
return BadAlloc;
for (i = 0; i < num_configs; i++) {
rc = RRConvertCrtcConfig(client, screen, &screen_config,
@@ -1773,7 +1770,8 @@ ProcRRSetCrtcConfigs (ClientPtr client)
output_ids += x_configs[i].nOutput;
}
- if (!RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
+ if (num_configs &&
+ !RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
{
rep.status = RRSetConfigFailed;
goto sendReply;
commit b0f4bd61f0caf80f3be9a176f1f7a707bc6628d8
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 5 21:53:25 2010 -0800
ProcRRSetCrtcConfigs uses 'configs' without being initialized
If the client sends invalid data for this request, the server
will jump to 'sendReply' and call RRFreeCrtcConfigs, passing it the
uninitialized 'configs' and 'num_configs' values.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 97aa3d7..0fc8188 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -1682,9 +1682,9 @@ ProcRRSetCrtcConfigs (ClientPtr client)
rrScrPrivPtr scr_priv;
xRRCrtcConfig *x_configs;
RRScreenConfigRec screen_config;
- RRCrtcConfigPtr configs;
+ RRCrtcConfigPtr configs = NULL;
RROutput *output_ids;
- int num_configs;
+ int num_configs = 0;
int rc, i;
int extra_len;
int num_output_ids;
commit 752c368421c1c824752cf467fba9318d75d2ca2c
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 5 20:57:47 2010 -0800
Separate out screen size and screen pixmap sizes in RRScreenSizeSet
This provides for separate sizes for the screen scanout and rendering
buffer and the application-visible screen size.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/common/xf86Helper.c b/hw/xfree86/common/xf86Helper.c
index ea0acbf..01f9864 100644
--- a/hw/xfree86/common/xf86Helper.c
+++ b/hw/xfree86/common/xf86Helper.c
@@ -1038,7 +1038,12 @@ xf86SetRootClip (ScreenPtr pScreen, Bool enable)
RegionInit(&pWin->winSize, &box, 1);
RegionInit(&pWin->borderSize, &box, 1);
if (WasViewable)
+ {
+ PixmapPtr pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ box.x2 = pPixmap->drawable.width;
+ box.y2 = pPixmap->drawable.height;
RegionReset(&pWin->borderClip, &box);
+ }
pWin->drawable.width = pScreen->width;
pWin->drawable.height = pScreen->height;
RegionBreak(&pWin->clipList);
@@ -1116,7 +1121,6 @@ xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
*/
if (!xf86Resetting)
xf86SetRootClip (pScreen, TRUE);
-
}
else
{
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index dfe2cc3..407bf35 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -659,10 +659,12 @@ xf86RandR12SetConfig (ScreenPtr pScreen,
static Bool
xf86RandR12ScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight)
+ CARD16 width,
+ CARD16 height,
+ CARD16 pixWidth,
+ CARD16 pixHeight,
+ CARD32 mmWidth,
+ CARD32 mmHeight)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
@@ -670,6 +672,8 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
WindowPtr pRoot = pScreen->root;
PixmapPtr pScrnPix;
Bool ret = FALSE;
+ Bool pixSizeChanged = FALSE;
+ Bool winSizeChanged = FALSE;
int c;
if (xf86RandR12Key) {
@@ -677,46 +681,85 @@ xf86RandR12ScreenSetSize (ScreenPtr pScreen,
{
randrp->virtualX = pScrn->virtualX;
randrp->virtualY = pScrn->virtualY;
+ pixSizeChanged = TRUE;
}
}
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- /* Let the driver update virtualX and virtualY */
- if (!(*config->funcs->resize)(pScrn, width, height))
- goto finish;
+ pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
+ if (pixWidth != pScrnPix->drawable.width ||
+ pixHeight != pScrnPix->drawable.height)
+ pixSizeChanged = TRUE;
+
+ if (width != pScreen->width || height != pScreen->height)
+ winSizeChanged = TRUE;
+
+ if (pixSizeChanged)
+ {
+ if (pRoot && pScrn->vtSema)
+ (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+
+ /* Let the driver update virtualX and virtualY */
+ if (!(*config->funcs->resize)(pScrn, pixWidth, pixHeight))
+ goto finish;
+ }
ret = TRUE;
- /* Update panning information */
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTotalArea.x2 += width - pScreen->width;
- if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTotalArea.y2 += height - pScreen->height;
- if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTrackingArea.x2 += width - pScreen->width;
- if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTrackingArea.y2 += height - pScreen->height;
- xf86RandR13VerifyPanningArea (crtc, width, height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+
+ if (winSizeChanged)
+ {
+ /* Update panning information */
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTotalArea.x2 += width - pScreen->width;
+ if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTotalArea.y2 += height - pScreen->height;
+ if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTrackingArea.x2 += width - pScreen->width;
+ if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTrackingArea.y2 += height - pScreen->height;
+ xf86RandR13VerifyPanningArea (crtc, width, height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ }
}
}
pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
- pScreen->width = pScrnPix->drawable.width = width;
- pScreen->height = pScrnPix->drawable.height = height;
+ pScreen->width = width;
+ pScreen->height = height;
+ if (pRoot)
+ {
+ BoxRec box;
+
+ pRoot->drawable.width = width;
+ pRoot->drawable.height = height;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = width;
+ box.y2 = height;
+ RegionInit(&pRoot->winSize, &box, 1);
+ RegionInit(&pRoot->borderSize, &box, 1);
+ }
+ pScrnPix->drawable.width = pixWidth;
+ pScrnPix->drawable.height = pixHeight;
randrp->mmWidth = pScreen->mmWidth = mmWidth;
randrp->mmHeight = pScreen->mmHeight = mmHeight;
- xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
- xf86SetViewport (pScreen, 0, 0);
+ if (winSizeChanged)
+ {
+ xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
+ xf86SetViewport (pScreen, 0, 0);
+ }
finish:
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ if (pixSizeChanged)
+ {
+ if (pRoot && pScrn->vtSema)
+ (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ }
+
#if RANDR_12_INTERFACE
if (xf86RandR12Key && pScreen->root && ret)
RRScreenSizeNotify (pScreen);
@@ -818,6 +861,8 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
xf86RandR12ScreenSetSize (pScreen,
width,
height,
+ width,
+ height,
mmWidth,
mmHeight);
}
diff --git a/randr/mirrcrtc.c b/randr/mirrcrtc.c
index d493a0e..a9ee6b4 100644
--- a/randr/mirrcrtc.c
+++ b/randr/mirrcrtc.c
@@ -28,11 +28,6 @@ miRRSetScreenConfig(ScreenPtr screen,
{
RRScreenConfigRec old_screen_config;
- /* XXX deal with separate pixmap/screen sizes */
- if (screen_config->screen_pixmap_width != screen_config->screen_width ||
- screen_config->screen_pixmap_height != screen_config->screen_height)
- return FALSE;
-
RRScreenCurrentConfig(screen, &old_screen_config);
/* Check and see if nothing has changed */
@@ -47,6 +42,8 @@ miRRSetScreenConfig(ScreenPtr screen,
return RRScreenSizeSet(screen,
screen_config->screen_width,
screen_config->screen_height,
+ screen_config->screen_pixmap_width,
+ screen_config->screen_pixmap_height,
screen_config->mm_width,
screen_config->mm_height);
}
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 8240824..7c553f2 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -191,6 +191,8 @@ struct _rrOutput {
typedef Bool (*RRScreenSetSizeProcPtr) (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
+ CARD16 pixWidth,
+ CARD16 pixHeight,
CARD32 mmWidth,
CARD32 mmHeight);
@@ -478,6 +480,8 @@ extern _X_EXPORT Bool
RRScreenSizeSet (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
+ CARD16 pixWidth,
+ CARD16 pixHeight,
CARD32 mmWidth,
CARD32 mmHeight);
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 0b2bc28..97aa3d7 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -435,10 +435,9 @@ RRCrtcCurrentConfig(RRCrtcPtr crtc,
crtc_config->sprite_position_f_transform = crtc->client_sprite_f_position_transform;
crtc_config->sprite_image_f_transform = crtc->client_sprite_f_image_transform;
- /* XXX add pixmap stuff */
- crtc_config->pixmap = NULL;
- crtc_config->pixmap_x = 0;
- crtc_config->pixmap_y = 0;
+ crtc_config->pixmap = crtc->scanoutPixmap;
+ crtc_config->pixmap_x = crtc->x;
+ crtc_config->pixmap_y = crtc->y;
return TRUE;
}
@@ -1510,6 +1509,8 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
if (x->pixmap == None)
pixmap = NULL;
+ else if (x->pixmap == RR_CurrentScanoutPixmap)
+ pixmap = crtc->scanoutPixmap;
else
{
rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap,
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index 0c52347..292163f 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -168,6 +168,8 @@ Bool
RRScreenSizeSet (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
+ CARD16 pixWidth,
+ CARD16 pixHeight,
CARD32 mmWidth,
CARD32 mmHeight)
{
@@ -178,6 +180,7 @@ RRScreenSizeSet (ScreenPtr pScreen,
{
return (*pScrPriv->rrScreenSetSize) (pScreen,
width, height,
+ pixWidth, pixHeight,
mmWidth, mmHeight);
}
#endif
@@ -318,6 +321,7 @@ ProcRRSetScreenSize (ClientPtr client)
}
if (!RRScreenSizeSet (pScreen,
stuff->width, stuff->height,
+ stuff->width, stuff->height,
stuff->widthInMillimeters,
stuff->heightInMillimeters))
{
@@ -949,7 +953,7 @@ ProcRRSetScreenConfig (ClientPtr client)
goto sendReply;
}
}
- if (!RRScreenSizeSet (pScreen, width, height,
+ if (!RRScreenSizeSet (pScreen, width, height, width, height,
pScreen->mmWidth, pScreen->mmHeight))
{
rep.status = RRSetConfigFailed;
commit a88d70fb20a2bc3152b84adff4380857e6cfadf5
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 5 20:55:46 2010 -0800
Set sprite transforms from RRSetCrtcConfigs
These were getting ignored.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index b0eabdd..dfe2cc3 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1819,8 +1819,8 @@ xf86RRConvertCrtcConfig(xf86CrtcSetConfigPtr xf86_config,
return FALSE;
for (o = 0; o < rr_config->numOutputs; o++)
xf86_config->outputs[o] = rr_config->outputs[o]->devPrivate;
- xf86_config->sprite_position_transform = rr_config->sprite_position_transform;
- xf86_config->sprite_image_transform = rr_config->sprite_image_transform;
+ xf86_config->sprite_position_transform = rr_config->sprite_position_f_transform;
+ xf86_config->sprite_image_transform = rr_config->sprite_image_f_transform;
xf86_config->pixmap = rr_config->pixmap;
xf86_config->pixmap_x = rr_config->pixmap_x;
xf86_config->pixmap_y = rr_config->pixmap_y;
diff --git a/randr/mirrcrtc.c b/randr/mirrcrtc.c
index cc76797..d493a0e 100644
--- a/randr/mirrcrtc.c
+++ b/randr/mirrcrtc.c
@@ -60,14 +60,21 @@ miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config)
x = crtc_config->pixmap_x;
y = crtc_config->pixmap_y;
}
- return RRCrtcSet(crtc_config->crtc,
- crtc_config->mode,
- x,
- y,
- crtc_config->rotation,
- crtc_config->numOutputs,
- crtc_config->outputs,
- crtc_config->pixmap);
+ if (!RRCrtcSet(crtc_config->crtc,
+ crtc_config->mode,
+ x,
+ y,
+ crtc_config->rotation,
+ crtc_config->numOutputs,
+ crtc_config->outputs,
+ crtc_config->pixmap))
+ return FALSE;
+ RRCrtcSpriteTransformSet(crtc_config->crtc,
+ &crtc_config->sprite_position_transform,
+ &crtc_config->sprite_image_transform,
+ &crtc_config->sprite_position_f_transform,
+ &crtc_config->sprite_image_f_transform);
+ return TRUE;
}
Bool
diff --git a/randr/randrstr.h b/randr/randrstr.h
index c231972..8240824 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -154,8 +154,10 @@ struct _rrCrtcConfig {
Rotation rotation;
int numOutputs;
RROutputPtr *outputs;
- struct pict_f_transform sprite_position_transform;
- struct pict_f_transform sprite_image_transform;
+ PictTransform sprite_position_transform;
+ PictTransform sprite_image_transform;
+ struct pict_f_transform sprite_position_f_transform;
+ struct pict_f_transform sprite_image_f_transform;
PixmapPtr pixmap;
int pixmap_x, pixmap_y;
};
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 12982a8..0b2bc28 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -430,8 +430,10 @@ RRCrtcCurrentConfig(RRCrtcPtr crtc,
if (!crtc_config->outputs)
return FALSE;
memcpy(crtc_config->outputs, crtc->outputs, crtc->numOutputs * sizeof (RROutputPtr));
- crtc_config->sprite_position_transform = crtc->client_sprite_f_position_transform;
- crtc_config->sprite_image_transform = crtc->client_sprite_f_image_transform;
+ crtc_config->sprite_position_transform = crtc->client_sprite_position_transform;
+ crtc_config->sprite_image_transform = crtc->client_sprite_image_transform;
+ crtc_config->sprite_position_f_transform = crtc->client_sprite_f_position_transform;
+ crtc_config->sprite_image_f_transform = crtc->client_sprite_f_image_transform;
/* XXX add pixmap stuff */
crtc_config->pixmap = NULL;
@@ -718,8 +720,8 @@ RRScreenCoversCrtc(RRScreenConfigPtr screen_config,
crtc_config->mode->mode.width, crtc_config->mode->mode.height,
crtc_config->rotation,
client_transform,
- &crtc_config->sprite_position_transform,
- &crtc_config->sprite_image_transform,
+ &crtc_config->sprite_position_f_transform,
+ &crtc_config->sprite_image_f_transform,
NULL, &f_transform, NULL, NULL, NULL, NULL);
RRModeGetScanoutSize (crtc_config->mode, &f_transform,
@@ -1469,15 +1471,6 @@ ProcRRGetCrtcTransform (ClientPtr client)
return Success;
}
-static void
-pixman_f_transform_from_xRenderTransform(struct pixman_f_transform *f_transform,
- xRenderTransform *x_transform)
-{
- struct pixman_transform transform;
- PictTransform_from_xRenderTransform(&transform, x_transform);
- pixman_f_transform_from_pixman_transform(f_transform, &transform);
-}
-
static int
RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
RRScreenConfigPtr screen_config,
@@ -1594,10 +1587,14 @@ RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
config->rotation = x->rotation;
config->numOutputs = x->nOutput;
config->outputs = outputs;
- pixman_f_transform_from_xRenderTransform(&config->sprite_position_transform,
+ PictTransform_from_xRenderTransform(&config->sprite_position_transform,
&x->spritePositionTransform);
- pixman_f_transform_from_xRenderTransform(&config->sprite_image_transform,
+ PictTransform_from_xRenderTransform(&config->sprite_image_transform,
&x->spriteImageTransform);
+ pixman_f_transform_from_pixman_transform(&config->sprite_position_f_transform,
+ &config->sprite_position_transform);
+ pixman_f_transform_from_pixman_transform(&config->sprite_image_f_transform,
+ &config->sprite_image_transform);
config->pixmap = pixmap;
config->pixmap_x = x->xPixmap;
config->pixmap_y = x->yPixmap;
commit 96b4d4787bf82edd9d06eb9a6e94bc45412c7df2
Author: Keith Packard <keithp at keithp.com>
Date: Sun Dec 5 20:49:19 2010 -0800
DIX is responsible for ref counting scanout pixmaps.
Remove some extra ref counting inside hw/xfree86/modes
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 5bf12f0..08d384f 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -414,10 +414,6 @@ done:
crtc->active = TRUE;
if (scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
- if (crtc->scanoutPixmap)
- ++crtc->scanoutPixmap->refcnt;
- if (saved_scanout_pixmap)
- (*scrn->pScreen->DestroyPixmap)(saved_scanout_pixmap);
if (scrn->ModeSet)
scrn->ModeSet(scrn);
} else {
commit afb6ebf1d5829346c40fe1053c9f50afe926e6c6
Author: Keith Packard <keithp at keithp.com>
Date: Fri Dec 3 13:04:37 2010 -0800
randr: Hook up the new RandR 1.4 functionality
This bumps the supported RandR protocol version and adds the dispatch
hooks needed to call the new functions
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/include/protocol-versions.h b/include/protocol-versions.h
index 1d33bdd..c8c7f5f 100644
--- a/include/protocol-versions.h
+++ b/include/protocol-versions.h
@@ -65,7 +65,7 @@
/* RandR */
#define SERVER_RANDR_MAJOR_VERSION 1
-#define SERVER_RANDR_MINOR_VERSION 3
+#define SERVER_RANDR_MINOR_VERSION 4
/* Record */
#define SERVER_RECORD_MAJOR_VERSION 1
diff --git a/randr/rrdispatch.c b/randr/rrdispatch.c
index ebfda57..aed746b 100644
--- a/randr/rrdispatch.c
+++ b/randr/rrdispatch.c
@@ -224,5 +224,11 @@ int (*ProcRandrVector[RRNumberRequests])(ClientPtr) = {
ProcRRSetPanning, /* 29 */
ProcRRSetOutputPrimary, /* 30 */
ProcRRGetOutputPrimary, /* 31 */
+/* V1.4 additions */
+ ProcRRQueryScanoutPixmaps, /* 32 */
+ ProcRRCreateScanoutPixmap, /* 33 */
+ ProcRRSetCrtcSpriteTransform,/* 34 */
+ ProcRRGetCrtcSpriteTransform,/* 35 */
+ ProcRRSetCrtcConfigs, /* 36 */
};
diff --git a/randr/rrsdispatch.c b/randr/rrsdispatch.c
index e16090a..c848f91 100644
--- a/randr/rrsdispatch.c
+++ b/randr/rrsdispatch.c
@@ -461,6 +461,132 @@ SProcRRGetOutputPrimary (ClientPtr client)
return ProcRandrVector[stuff->randrReqType](client);
}
+static int
+SProcRRQueryScanoutPixmaps (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRQueryScanoutPixmapsReq);
+
+ REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRCreateScanoutPixmap (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRCreateScanoutPixmapReq);
+
+ REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->format, n);
+ swaps(&stuff->rotations, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static void
+swap_transform(xRenderTransform *t)
+{
+ int n;
+ swapl(&t->matrix11, n);
+ swapl(&t->matrix12, n);
+ swapl(&t->matrix13, n);
+ swapl(&t->matrix21, n);
+ swapl(&t->matrix22, n);
+ swapl(&t->matrix23, n);
+ swapl(&t->matrix31, n);
+ swapl(&t->matrix32, n);
+ swapl(&t->matrix33, n);
+}
+
+static int
+SProcRRSetCrtcSpriteTransform (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetCrtcSpriteTransformReq);
+
+ REQUEST_SIZE_MATCH(xRRSetCrtcSpriteTransformReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ swap_transform(&stuff->positionTransform);
+ swap_transform(&stuff->imageTransform);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRGetCrtcSpriteTransform (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRGetCrtcSpriteTransformReq);
+
+ REQUEST_SIZE_MATCH(xRRGetCrtcSpriteTransformReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->crtc, n);
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
+static int
+SProcRRSetCrtcConfigs (ClientPtr client)
+{
+ int n;
+ REQUEST(xRRSetCrtcConfigsReq);
+ int c;
+ int extra_len;
+ int num_configs;
+ int num_output_ids;
+ xRRCrtcConfig *x_configs;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->screenPixmapWidth, n);
+ swaps(&stuff->screenPixmapHeight, n);
+ swaps(&stuff->screenWidth, n);
+ swaps(&stuff->screenHeight, n);
+ swapl(&stuff->widthInMillimeters, n);
+ swapl(&stuff->heightInMillimeters, n);
+ swaps(&stuff->nConfigs, n);
+
+ extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq));
+
+ num_configs = stuff->nConfigs;
+
+ /* Check request length against number of configs specified */
+ if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len)
+ return BadLength;
+
+ x_configs = (xRRCrtcConfig *) (stuff + 1);
+ for (c = 0; c < num_configs; c++) {
+ swapl(&x_configs->crtc, n);
+ swaps(&x_configs->x, n);
+ swaps(&x_configs->y, n);
+ swapl(&x_configs->mode, n);
+ swaps(&x_configs->rotation, n);
+ swaps(&x_configs->nOutput, n);
+ swap_transform(&x_configs->spritePositionTransform);
+ swap_transform(&x_configs->spriteImageTransform);
+ swapl(&x_configs->pixmap, n);
+ swaps(&x_configs->xPixmap, n);
+ swaps(&x_configs->yPixmap, n);
+ x_configs++;
+ }
+
+ /* Let the other dispatch function deal with verifying that
+ * the right number of output ids are present, just
+ * swap whatever is here
+ */
+ num_output_ids = extra_len - (num_configs * (sizeof (xRRCrtcConfig)) >> 2);
+ SwapLongs((CARD32 *) x_configs, num_output_ids);
+
+ return ProcRandrVector[stuff->randrReqType](client);
+}
+
int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRQueryVersion, /* 0 */
/* we skip 1 to make old clients fail pretty immediately */
@@ -499,5 +625,11 @@ int (*SProcRandrVector[RRNumberRequests])(ClientPtr) = {
SProcRRSetPanning, /* 29 */
SProcRRSetOutputPrimary, /* 30 */
SProcRRGetOutputPrimary, /* 31 */
+/* V1.4 additions */
+ SProcRRQueryScanoutPixmaps, /* 32 */
+ SProcRRCreateScanoutPixmap, /* 33 */
+ SProcRRSetCrtcSpriteTransform,/* 34 */
+ SProcRRGetCrtcSpriteTransform,/* 35 */
+ SProcRRSetCrtcConfigs, /* 36 */
};
commit 82612045e11f2b882ae132e184a9629f43f1c424
Author: Keith Packard <keithp at keithp.com>
Date: Fri Dec 3 13:00:46 2010 -0800
randr: Add per-crtc pixmaps
This adds new driver hooks to allocate scanout pixmaps and
changes the mode setting APIs to pass the new scanout pixmaps
along from DIX. DIX is responsible for reference counting the pixmaps
by tracking them through RRCrtcNotify.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 3fccaea..5bf12f0 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -82,6 +82,17 @@ xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
config->maxHeight = maxHeight;
}
+void
+xf86CrtcSetScanoutFormats(ScrnInfoPtr scrn,
+ int num_formats,
+ xf86CrtcScanoutFormat *formats)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ config->num_scanout_formats = num_formats;
+ config->scanout_formats = formats;
+}
+
/*
* Crtc functions
*/
@@ -265,6 +276,7 @@ xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set)
Rotation saved_rotation;
RRTransformRec saved_transform;
Bool saved_transform_present;
+ PixmapPtr saved_scanout_pixmap;
crtc->enabled = xf86CrtcInUse (crtc);
@@ -284,6 +296,7 @@ xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set)
saved_x = crtc->x;
saved_y = crtc->y;
saved_rotation = crtc->rotation;
+ saved_scanout_pixmap = crtc->scanoutPixmap;
if (crtc->transformPresent) {
RRTransformInit (&saved_transform);
RRTransformCopy (&saved_transform, &crtc->transform);
@@ -301,6 +314,8 @@ xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set)
}
if (set->flags & XF86CrtcSetRotation)
crtc->rotation = set->rotation;
+ if (set->flags & XF86CrtcSetScanoutPixmap)
+ crtc->scanoutPixmap = set->scanout_pixmap;
if (set->flags & XF86CrtcSetTransform) {
if (set->transform) {
@@ -399,6 +414,10 @@ done:
crtc->active = TRUE;
if (scrn->pScreen)
xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
+ if (crtc->scanoutPixmap)
+ ++crtc->scanoutPixmap->refcnt;
+ if (saved_scanout_pixmap)
+ (*scrn->pScreen->DestroyPixmap)(saved_scanout_pixmap);
if (scrn->ModeSet)
scrn->ModeSet(scrn);
} else {
@@ -409,6 +428,7 @@ done:
if (saved_transform_present)
RRTransformCopy (&crtc->transform, &saved_transform);
crtc->transformPresent = saved_transform_present;
+ crtc->scanoutPixmap = saved_scanout_pixmap;
}
if (adjusted_mode) {
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index c2e8131..9a520fc 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -79,6 +79,7 @@ typedef enum _xf86CrtcSetFlags {
XF86CrtcSetTransform = 8, /* transform */
XF86CrtcSetRotation = 16, /* rotation */
XF86CrtcSetProperty = 32, /* output property */
+ XF86CrtcSetScanoutPixmap = 64, /* scanout pixmap */
} xf86CrtcSetFlags;
typedef struct _xf86CrtcSet {
@@ -87,6 +88,7 @@ typedef struct _xf86CrtcSet {
Rotation rotation;
RRTransformPtr transform;
int x, y;
+ PixmapPtr scanout_pixmap;
} xf86CrtcSetRec;
typedef struct _xf86CrtcFuncs {
@@ -277,6 +279,7 @@ struct _xf86Crtc {
Rotation rotation;
PixmapPtr rotatedPixmap;
void *rotatedData;
+ PixmapPtr scanoutPixmap;
/**
* Position on screen
@@ -670,6 +673,14 @@ typedef struct _xf86CrtcSetConfig {
int pixmap_x, pixmap_y;
} xf86CrtcSetConfigRec, *xf86CrtcSetConfigPtr;
+typedef struct _xf86CrtcScanoutFormat {
+ int depth;
+ int bitsPerPixel;
+ int maxWidth, maxHeight;
+ Rotation rotations;
+ PictFormatShort format;
+} xf86CrtcScanoutFormat;
+
typedef struct _xf86CrtcConfigFuncs {
/**
* Requests that the driver resize the screen.
@@ -693,6 +704,17 @@ typedef struct _xf86CrtcConfigFuncs {
RRScreenConfigPtr screen_config,
xf86CrtcSetConfigPtr crtc_configs,
int num_configs);
+
+ /**
+ * Create a scanout pixmap
+ */
+ PixmapPtr
+ (*create_scanout_pixmap)(ScrnInfoPtr scrn,
+ int width,
+ int height,
+ Rotation rotations,
+ xf86CrtcScanoutFormat *format);
+
} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
@@ -752,6 +774,11 @@ typedef struct _xf86CrtcConfig {
/* callback when crtc configuration changes */
xf86_crtc_notify_proc_ptr xf86_crtc_notify;
+ /*
+ * Supported scanout pixmap formats
+ */
+ int num_scanout_formats;
+ xf86CrtcScanoutFormat *scanout_formats;
} xf86CrtcConfigRec, *xf86CrtcConfigPtr;
extern _X_EXPORT int xf86CrtcConfigPrivateIndex;
@@ -797,6 +824,11 @@ xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
int minWidth, int minHeight,
int maxWidth, int maxHeight);
+extern _X_EXPORT void
+xf86CrtcSetScanoutFormats (ScrnInfoPtr scrn,
+ int num_formats,
+ xf86CrtcScanoutFormat *formats);
+
/*
* Crtc functions
*/
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index e3330f4..b0eabdd 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1083,7 +1083,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
rotation,
crtc->transformPresent ? &crtc->transform : NULL,
- numOutputs, randr_outputs);
+ numOutputs, randr_outputs, crtc->scanoutPixmap);
free(randr_outputs);
return ret;
}
@@ -1126,7 +1126,8 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
int y,
Rotation rotation,
int num_randr_outputs,
- RROutputPtr *randr_outputs)
+ RROutputPtr *randr_outputs,
+ PixmapPtr scanout_pixmap)
{
XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
@@ -1157,6 +1158,9 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
sizeof (transform->transform)) != 0)
flags |= XF86CrtcSetTransform;
+ if (scanout_pixmap != crtc->scanoutPixmap)
+ flags |= XF86CrtcSetScanoutPixmap;
+
if (x != crtc->x || y != crtc->y)
flags |= XF86CrtcSetOrigin;
for (o = 0; o < config->num_output; o++)
@@ -1203,6 +1207,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
set.transform = transform;
set.x = x;
set.y = y;
+ set.scanout_pixmap = scanout_pixmap;
set.flags = flags;
if (!xf86CrtcSet(crtc, &set))
{
@@ -1732,6 +1737,54 @@ xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
return Success;
}
+static RRScanoutPixmapInfo *
+xf86RRQueryScanoutPixmaps(ScreenPtr screen, int *n_info)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ RRScanoutPixmapInfo *info;
+ int f;
+
+ info = calloc(config->num_scanout_formats, sizeof (RRScanoutPixmapInfo));
+ if (config->num_scanout_formats && !info) {
+ *n_info = 0;
+ return NULL;
+ }
+ for (f = 0; f < config->num_scanout_formats; f++) {
+ info[f].maxWidth = config->scanout_formats[f].maxWidth;
+ info[f].maxHeight = config->scanout_formats[f].maxHeight;
+ info[f].depth = config->scanout_formats[f].depth;
+ info[f].rotations = config->scanout_formats[f].rotations;
+ info[f].format = PictureMatchFormat (screen, info[f].depth,
+ config->scanout_formats[f].format);
+ }
+ *n_info = config->num_scanout_formats;
+ return info;
+}
+
+static PixmapPtr
+xf86RRCreateScanoutPixmap(ScreenPtr screen,
+ int width, int height, int depth,
+ Rotation rotations,
+ PictFormatPtr format)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int f;
+
+ if (!config->funcs->create_scanout_pixmap)
+ return NullPixmap;
+
+ for (f = 0; f < config->num_scanout_formats; f++)
+ if (config->scanout_formats[f].depth == depth &&
+ (config->scanout_formats[f].format & 0xffffff) == format->format) {
+ return (*config->funcs->create_scanout_pixmap) (scrn, width, height,
+ rotations,
+ &config->scanout_formats[f]);
+ }
+ return NullPixmap;
+}
+
static void
xf86RandR14SetCrtcSpriteTransform(ScreenPtr pScreen,
RRCrtcPtr randr_crtc,
@@ -1893,17 +1946,17 @@ xf86RandR12Init12 (ScreenPtr pScreen)
rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
-#if RANDR_13_INTERFACE
rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
rp->rrGetPanning = xf86RandR13GetPanning;
rp->rrSetPanning = xf86RandR13SetPanning;
-#endif
rp->rrModeDestroy = xf86RandR12ModeDestroy;
rp->rrSetConfig = NULL;
pScrn->PointerMoved = xf86RandR12PointerMoved;
pScrn->ChangeGamma = xf86RandR12ChangeGamma;
rp->rrSetCrtcSpriteTransform = xf86RandR14SetCrtcSpriteTransform;
rp->rrSetCrtcConfigs = xf86RRSetCrtcConfigs;
+ rp->rrQueryScanoutPixmaps = xf86RRQueryScanoutPixmaps;
+ rp->rrCreateScanoutPixmap = xf86RRCreateScanoutPixmap;
randrp->orig_EnterVT = pScrn->EnterVT;
pScrn->EnterVT = xf86RandR12EnterVT;
diff --git a/randr/Makefile.am b/randr/Makefile.am
index a1c88dc..b7664c6 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -16,6 +16,7 @@ librandr_la_SOURCES = \
rrinfo.c \
rrmode.c \
rroutput.c \
+ rrpixmap.c \
rrpointer.c \
rrproperty.c \
rrscreen.c \
diff --git a/randr/mirrcrtc.c b/randr/mirrcrtc.c
index b1e2c9f..cc76797 100644
--- a/randr/mirrcrtc.c
+++ b/randr/mirrcrtc.c
@@ -66,7 +66,8 @@ miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config)
y,
crtc_config->rotation,
crtc_config->numOutputs,
- crtc_config->outputs);
+ crtc_config->outputs,
+ crtc_config->pixmap);
}
Bool
diff --git a/randr/randr.c b/randr/randr.c
index 6077705..c22657e 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -98,6 +98,7 @@ RRCloseScreen (int i, ScreenPtr pScreen)
free(pScrPriv->crtcs);
free(pScrPriv->outputs);
+ free(pScrPriv->scanout_info);
free(pScrPriv);
RRNScreens -= 1; /* ok, one fewer screen with RandR running */
return (*pScreen->CloseScreen) (i, pScreen);
@@ -248,6 +249,8 @@ Bool RRScreenInit(ScreenPtr pScreen)
pScrPriv->rrCrtcSet = NULL;
pScrPriv->rrCrtcSetGamma = NULL;
#endif
+ pScrPriv->scanout_info = NULL;
+ pScrPriv->n_scanout_info = 0;
#if RANDR_10_INTERFACE
pScrPriv->rrSetConfig = 0;
pScrPriv->rotations = RR_Rotate_0;
@@ -482,6 +485,18 @@ RRVerticalRefresh (xRRModeInfo *mode)
return (CARD16) refresh;
}
+RRScanoutPixmapInfo *
+RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info)
+{
+ rrScrPriv(screen);
+
+ if (!pScrPriv->scanout_info && pScrPriv->rrQueryScanoutPixmaps)
+ pScrPriv->scanout_info = pScrPriv->rrQueryScanoutPixmaps(screen,
+ &pScrPriv->n_scanout_info);
+ *n_info = pScrPriv->n_scanout_info;
+ return pScrPriv->scanout_info;
+}
+
static int
ProcRRDispatch (ClientPtr client)
{
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 2fe9602..c231972 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -123,6 +123,7 @@ struct _rrCrtc {
CARD16 *gammaGreen;
void *devPrivate;
Bool transforms;
+ PixmapPtr scanoutPixmap;
RRTransformRec client_pending_transform;
RRTransformRec client_current_transform;
PictTransform client_sprite_position_transform;
@@ -198,7 +199,8 @@ typedef Bool (*RRCrtcSetProcPtr) (ScreenPtr pScreen,
int y,
Rotation rotation,
int numOutputs,
- RROutputPtr *outputs);
+ RROutputPtr *outputs,
+ PixmapPtr scanout_pixmap);
typedef Bool (*RRCrtcSetGammaProcPtr) (ScreenPtr pScreen,
RRCrtcPtr crtc);
@@ -264,6 +266,20 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
#endif
+typedef struct {
+ PictFormatPtr format;
+ int maxWidth, maxHeight;
+ int depth;
+ Rotation rotations;
+} RRScanoutPixmapInfo;
+
+typedef RRScanoutPixmapInfo *(*RRQueryScanoutPixmapsPtr) (ScreenPtr pScreen,
+ int *num_info);
+
+typedef PixmapPtr (*RRCreateScanoutPixmapPtr) (ScreenPtr pScreen,
+ int width, int height, int depth,
+ Rotation rotations,
+ PictFormatPtr format);
typedef void (*RRSetCrtcSpriteTransformPtr) (ScreenPtr pScreen,
RRCrtcPtr randr_crtc,
@@ -303,6 +319,8 @@ typedef struct _rrScrPriv {
RRGetPanningProcPtr rrGetPanning;
RRSetPanningProcPtr rrSetPanning;
#endif
+ RRQueryScanoutPixmapsPtr rrQueryScanoutPixmaps;
+ RRCreateScanoutPixmapPtr rrCreateScanoutPixmap;
RRSetCrtcSpriteTransformPtr rrSetCrtcSpriteTransform;
RRGetCrtcSpriteTransformPtr rrGetCrtcSpriteTransform;
RRSetCrtcConfigsPtr rrSetCrtcConfigs;
@@ -333,6 +351,8 @@ typedef struct _rrScrPriv {
/* Last known pointer position */
RRCrtcPtr pointerCrtc;
+ RRScanoutPixmapInfo *scanout_info;
+ int n_scanout_info;
#ifdef RANDR_10_INTERFACE
/*
* Configuration information
@@ -347,6 +367,7 @@ typedef struct _rrScrPriv {
int rate;
int size;
#endif
+
} rrScrPrivRec, *rrScrPrivPtr;
extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
@@ -521,6 +542,9 @@ RRGetRotation (ScreenPtr pScreen);
extern _X_EXPORT CARD16
RRVerticalRefresh (xRRModeInfo *mode);
+extern _X_EXPORT RRScanoutPixmapInfo *
+RRQueryScanoutPixmapInfo(ScreenPtr screen, int *n_info);
+
#ifdef RANDR_10_INTERFACE
/*
* This is the old interface, deprecated but left
@@ -599,7 +623,8 @@ RRCrtcNotify (RRCrtcPtr crtc,
Rotation rotation,
RRTransformPtr transform,
int numOutputs,
- RROutputPtr *outputs);
+ RROutputPtr *outputs,
+ PixmapPtr scanoutPixmap);
extern _X_EXPORT void
RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc);
@@ -614,7 +639,8 @@ RRCrtcSet (RRCrtcPtr crtc,
int y,
Rotation rotation,
int numOutput,
- RROutputPtr *outputs);
+ RROutputPtr *outputs,
+ PixmapPtr scanout_pixmap);
/*
* Request that the Crtc gamma be changed
@@ -643,6 +669,10 @@ RRCrtcGammaGet(RRCrtcPtr crtc);
extern _X_EXPORT Bool
RRCrtcGammaNotify (RRCrtcPtr crtc);
+void
+RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform,
+ int *width, int *height);
+
/*
* Set the size of the gamma table at server startup time
*/
@@ -778,11 +808,23 @@ RRCrtcSpriteTransformSet(RRCrtcPtr crtc,
struct pict_f_transform *f_image_transform);
int
+ProcRRQueryScanoutPixmaps (ClientPtr client);
+
+int
+ProcRRCreateScanoutPixmap (ClientPtr client);
+
+int
+ProcRRSetCrtcPixmapConfig (ClientPtr client);
+
+int
ProcRRSetCrtcSpriteTransform (ClientPtr client);
int
ProcRRGetCrtcSpriteTransform (ClientPtr client);
+int
+ProcRRSetCrtcConfigs (ClientPtr client);
+
/* rrdispatch.c */
extern _X_EXPORT Bool
RRClientKnowsRates (ClientPtr pClient);
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 1f8f2e6..12982a8 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -138,7 +138,8 @@ RRCrtcNotify (RRCrtcPtr crtc,
Rotation rotation,
RRTransformPtr transform,
int numOutputs,
- RROutputPtr *outputs)
+ RROutputPtr *outputs,
+ PixmapPtr scanoutPixmap)
{
int i, j;
@@ -236,6 +237,15 @@ RRCrtcNotify (RRCrtcPtr crtc,
RRCrtcChanged (crtc, TRUE);
}
+ if (scanoutPixmap != crtc->scanoutPixmap)
+ {
+ if (scanoutPixmap)
+ ++scanoutPixmap->refcnt;
+ if (crtc->scanoutPixmap)
+ (*crtc->scanoutPixmap->drawable.pScreen->DestroyPixmap) (crtc->scanoutPixmap);
+ crtc->scanoutPixmap = scanoutPixmap;
+ }
+
if (crtc->changed && mode)
{
RRTransformCompute (x, y,
@@ -312,7 +322,8 @@ RRCrtcSet (RRCrtcPtr crtc,
int y,
Rotation rotation,
int numOutputs,
- RROutputPtr *outputs)
+ RROutputPtr *outputs,
+ PixmapPtr scanout_pixmap)
{
ScreenPtr pScreen = crtc->pScreen;
Bool ret = FALSE;
@@ -326,7 +337,8 @@ RRCrtcSet (RRCrtcPtr crtc,
crtc->numOutputs == numOutputs &&
!memcmp (crtc->outputs, outputs, numOutputs * sizeof (RROutputPtr)) &&
!RRCrtcPendingProperties (crtc) &&
- !RRCrtcPendingTransform (crtc))
+ !RRCrtcPendingTransform (crtc) &&
+ crtc->scanoutPixmap == scanout_pixmap)
{
ret = TRUE;
}
@@ -336,7 +348,7 @@ RRCrtcSet (RRCrtcPtr crtc,
if (pScrPriv->rrCrtcSet)
{
ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
- rotation, numOutputs, outputs);
+ rotation, numOutputs, outputs, scanout_pixmap);
}
else
#endif
@@ -349,7 +361,7 @@ RRCrtcSet (RRCrtcPtr crtc,
if (!mode)
{
- RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL);
+ RRCrtcNotify (crtc, NULL, x, y, rotation, NULL, 0, NULL, scanout_pixmap);
ret = TRUE;
}
else
@@ -375,7 +387,7 @@ RRCrtcSet (RRCrtcPtr crtc,
*/
if (ret)
{
- RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs);
+ RRCrtcNotify (crtc, mode, x, y, rotation, NULL, 1, outputs, scanout_pixmap);
RRScreenSizeNotify (pScreen);
}
}
@@ -573,7 +585,10 @@ RRCrtcGammaNotify (RRCrtcPtr crtc)
return TRUE; /* not much going on here */
}
-static void
+/*
+ * Compute overall scanout buffer requirements for the specified mode
+ */
+void
RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform,
int *width, int *height)
{
@@ -1049,7 +1064,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
}
if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
- rotation, numOutputs, outputs))
+ rotation, numOutputs, outputs, NULL))
{
rep.status = RRSetConfigFailed;
goto sendReply;
diff --git a/randr/rrinfo.c b/randr/rrinfo.c
index fdf3726..549ebcc 100644
--- a/randr/rrinfo.c
+++ b/randr/rrinfo.c
@@ -168,7 +168,7 @@ RRScanOldConfig (ScreenPtr pScreen, Rotation rotations)
/* notice current mode */
if (newMode)
RRCrtcNotify (crtc, newMode, 0, 0, pScrPriv->rotation,
- NULL, 1, &output);
+ NULL, 1, &output, NULL);
}
#endif
diff --git a/randr/rrpixmap.c b/randr/rrpixmap.c
new file mode 100644
index 0000000..7d4543c
--- /dev/null
+++ b/randr/rrpixmap.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright © 2010 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+#include "xace.h"
+
+int
+ProcRRQueryScanoutPixmaps (ClientPtr client)
+{
+ REQUEST(xRRQueryScanoutPixmapsReq);
+ xRRQueryScanoutPixmapsReply rep;
+ RRScanoutPixmapInfo *info;
+ xRRScanoutPixmapInfo *x_info;
+ int n_info;
+ int rc;
+ DrawablePtr drawable;
+ ScreenPtr screen;
+ rrScrPrivPtr screen_priv;
+ int n, s;
+
+ REQUEST_SIZE_MATCH(xRRQueryScanoutPixmapsReq);
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->drawable;
+ return rc;
+ }
+
+ screen = drawable->pScreen;
+ screen_priv = rrGetScrPriv(screen);
+
+ rep.type = X_Reply;
+ /* rep.status has already been filled in */
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ info = RRQueryScanoutPixmapInfo(screen, &n_info);
+ x_info = calloc(n_info, sizeof (xRRScanoutPixmapInfo));
+ if (n_info && !x_info)
+ return BadAlloc;
+ rep.length += (n_info * sizeof (xRRScanoutPixmapInfo)) >> 2;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ for (s = 0; s < n_info; s++) {
+ x_info[s].format = info[s].format->id;
+ x_info[s].maxWidth = info[s].maxWidth;
+ x_info[s].maxHeight = info[s].maxHeight;
+ x_info[s].rotations = info[s].rotations;
+ if (client->swapped) {
+ swapl(&x_info[s].format, n);
+ swaps(&x_info[s].maxWidth, n);
+ swaps(&x_info[s].maxHeight, n);
+ swaps(&x_info[s].rotations, n);
+ }
+ }
+
+ WriteToClient(client, sizeof(rep), (char *)&rep);
+ if (n_info)
+ WriteToClient(client, n_info * sizeof (xRRScanoutPixmapInfo),
+ (char *) x_info);
+ return Success;
+}
+
+int
+ProcRRCreateScanoutPixmap (ClientPtr client)
+{
+ REQUEST(xRRCreateScanoutPixmapReq);
+ int rc;
+ DrawablePtr drawable;
+ ScreenPtr screen;
+ rrScrPrivPtr screen_priv;
+ PixmapPtr pixmap;
+ int n_info;
+ RRScanoutPixmapInfo *info;
+ int s;
+
+ REQUEST_SIZE_MATCH(xRRCreateScanoutPixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->drawable;
+ return rc;
+ }
+ screen = drawable->pScreen;
+ screen_priv = rrGetScrPriv(screen);
+ if (!screen_priv)
+ return BadValue;
+
+ info = RRQueryScanoutPixmapInfo(screen, &n_info);
+ for (s = 0; s < n_info; s++) {
+ if (info[s].format->id == stuff->format)
+ break;
+ }
+ if (s == n_info || !screen_priv->rrCreateScanoutPixmap) {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+ info = &info[s];
+ if (!stuff->width || stuff->width > info->maxWidth) {
+ client->errorValue = stuff->width;
+ return BadValue;
+ }
+ if (!stuff->height || stuff->height > info->maxHeight) {
+ client->errorValue = stuff->height;
+ return BadValue;
+ }
+ if ((stuff->rotations & info->rotations) != stuff->rotations) {
+ client->errorValue = stuff->rotations;
+ return BadValue;
+ }
+
+ pixmap = screen_priv->rrCreateScanoutPixmap (screen,
+ stuff->width, stuff->height,
+ info->depth,
+ stuff->rotations,
+ info->format);
+ if (!pixmap)
+ return BadAlloc;
+
+ pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pixmap->drawable.id = stuff->pid;
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
+ pixmap, RT_NONE, NULL, DixCreateAccess);
+ if (rc != Success) {
+ screen->DestroyPixmap(pixmap);
+ return rc;
+ }
+ if (!AddResource(stuff->pid, RT_PIXMAP, pixmap))
+ return BadAlloc;
+ return Success;
+}
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index 62ea2b6..0c52347 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -794,8 +794,10 @@ ProcRRSetScreenConfig (ClientPtr client)
}
rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
- if (rc != Success)
+ if (rc != Success) {
+ client->errorValue = stuff->drawable;
return rc;
+ }
pScreen = pDraw->pScreen;
@@ -940,7 +942,7 @@ ProcRRSetScreenConfig (ClientPtr client)
for (c = 0; c < pScrPriv->numCrtcs; c++)
{
if (!RRCrtcSet (pScrPriv->crtcs[c], NULL, 0, 0, RR_Rotate_0,
- 0, NULL))
+ 0, NULL, NULL))
{
rep.status = RRSetConfigFailed;
/* XXX recover from failure */
@@ -956,7 +958,7 @@ ProcRRSetScreenConfig (ClientPtr client)
}
}
- if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output))
+ if (!RRCrtcSet (crtc, mode, 0, 0, stuff->rotation, 1, &output, NULL))
rep.status = RRSetConfigFailed;
else {
pScrPriv->lastSetTime = time;
commit 86c489c319c705f710bee3897fe27600ce15008e
Author: Keith Packard <keithp at keithp.com>
Date: Sat Dec 4 20:12:26 2010 -0800
hw/xfree86/modes: Add optional driver API for RRSetCrtcConfigs
This provides a driver hook which can either completely replace, or
just validate the parameters for, the RRSetCrtcConfigs request.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 8b42efc..c2e8131 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -647,6 +647,29 @@ struct _xf86Output {
INT16 initialBorder[4];
};
+typedef enum _xf86SetConfigResponse {
+ xf86SetConfigFailed, /* set_config failed */
+ xf86SetConfigChecked, /* set_config validated the configuration */
+ xf86SetConfigDone, /* set_config finished the work */
+} xf86SetConfigResponse;
+
+typedef struct _xf86CrtcSetConfig {
+ xf86CrtcPtr crtc;
+ int x, y;
+ DisplayModeRec mode;
+ Rotation rotation;
+ int numOutputs;
+ xf86OutputPtr *outputs;
+ struct pict_f_transform sprite_position_transform;
+ struct pict_f_transform sprite_image_transform;
+
+ /* Probably want some internal structure for the pixmap so that
+ * this can be set before the server is running
+ */
+ PixmapPtr pixmap;
+ int pixmap_x, pixmap_y;
+} xf86CrtcSetConfigRec, *xf86CrtcSetConfigPtr;
+
typedef struct _xf86CrtcConfigFuncs {
/**
* Requests that the driver resize the screen.
@@ -664,6 +687,12 @@ typedef struct _xf86CrtcConfigFuncs {
(*resize)(ScrnInfoPtr scrn,
int width,
int height);
+
+ xf86SetConfigResponse
+ (*set_config) (ScrnInfoPtr scrn,
+ RRScreenConfigPtr screen_config,
+ xf86CrtcSetConfigPtr crtc_configs,
+ int num_configs);
} xf86CrtcConfigFuncsRec, *xf86CrtcConfigFuncsPtr;
typedef void (*xf86_crtc_notify_proc_ptr) (ScreenPtr pScreen);
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index ac58135..e3330f4 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -758,7 +758,7 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
xf86CrtcPtr crtc = config->crtc[c];
int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
-
+
if (crtc->enabled) {
if (crtc_width > width)
width = crtc_width;
@@ -770,13 +770,13 @@ xf86RandR12CreateScreenResources (ScreenPtr pScreen)
height = crtc->panningTotalArea.y2;
}
}
-
+
if (width && height)
{
/*
* Compute physical size of screen
*/
- if (monitorResolution)
+ if (monitorResolution)
{
mmWidth = width * 25.4 / monitorResolution;
mmHeight = height * 25.4 / monitorResolution;
@@ -1007,7 +1007,7 @@ xf86RandRModeMatches (RRModePtr randr_mode,
if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
}
#endif
-
+
/* check for same timings */
if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
if (randr_mode->mode.width != mode->HDisplay) return FALSE;
@@ -1019,11 +1019,11 @@ xf86RandRModeMatches (RRModePtr randr_mode,
if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
-
+
/* check for same flags (using only the XF86 valid flag bits) */
if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
return FALSE;
-
+
/* everything matches */
return TRUE;
}
@@ -1063,7 +1063,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
randr_output = output->randr_output;
randr_outputs[numOutputs++] = randr_output;
/*
- * We make copies of modes, so pointer equality
+ * We make copies of modes, so pointer equality
* isn't sufficient
*/
for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
@@ -1071,7 +1071,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
RRModePtr m = (j < randr_output->numModes ?
randr_output->modes[j] :
randr_output->userModes[j-randr_output->numModes]);
-
+
if (xf86RandRModeMatches (m, mode))
{
randr_mode = m;
@@ -1081,7 +1081,7 @@ xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
}
}
ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation,
+ rotation,
crtc->transformPresent ? &crtc->transform : NULL,
numOutputs, randr_outputs);
free(randr_outputs);
@@ -1100,13 +1100,13 @@ xf86RandRModeConvert (ScrnInfoPtr scrn,
mode->status = MODE_OK;
mode->Clock = randr_mode->mode.dotClock / 1000;
-
+
mode->HDisplay = randr_mode->mode.width;
mode->HSyncStart = randr_mode->mode.hSyncStart;
mode->HSyncEnd = randr_mode->mode.hSyncEnd;
mode->HTotal = randr_mode->mode.hTotal;
mode->HSkew = randr_mode->mode.hSkew;
-
+
mode->VDisplay = randr_mode->mode.height;
mode->VSyncStart = randr_mode->mode.vSyncStart;
mode->VSyncEnd = randr_mode->mode.vSyncEnd;
@@ -1146,7 +1146,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
flags |= XF86CrtcSetMode;
else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
flags |= XF86CrtcSetMode;
-
+
if (rotation != crtc->rotation)
flags |= XF86CrtcSetRotation;
@@ -1159,18 +1159,18 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
if (x != crtc->x || y != crtc->y)
flags |= XF86CrtcSetOrigin;
- for (o = 0; o < config->num_output; o++)
+ for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
xf86CrtcPtr new_crtc;
save_crtcs[o] = output->crtc;
-
+
if (output->crtc == crtc)
new_crtc = NULL;
else
new_crtc = output->crtc;
- for (ro = 0; ro < num_randr_outputs; ro++)
+ for (ro = 0; ro < num_randr_outputs; ro++)
if (output->randr_output == randr_outputs[ro])
{
new_crtc = crtc;
@@ -1182,7 +1182,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
output->crtc = new_crtc;
}
}
- for (ro = 0; ro < num_randr_outputs; ro++)
+ for (ro = 0; ro < num_randr_outputs; ro++)
if (randr_outputs[ro]->pendingProperties)
flags |= XF86CrtcSetProperty;
@@ -1385,7 +1385,7 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
if (nmode) {
rrmodes = malloc(nmode * sizeof (RRModePtr));
-
+
if (!rrmodes)
return FALSE;
nmode = 0;
@@ -1395,7 +1395,7 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
xRRModeInfo modeInfo;
RRModePtr rrmode;
-
+
modeInfo.nameLength = strlen (mode->name);
modeInfo.width = mode->HDisplay;
modeInfo.dotClock = mode->Clock * 1000;
@@ -1419,7 +1419,7 @@ xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
}
}
}
-
+
ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
free(rrmodes);
return ret;
@@ -1439,13 +1439,13 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
int o, c, l;
RRCrtcPtr randr_crtc;
int nclone;
-
+
clones = malloc(config->num_output * sizeof (RROutputPtr));
crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr));
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
-
+
ncrtc = 0;
for (c = 0; c < config->num_crtc; c++)
if (output->possible_crtcs & (1 << c))
@@ -1463,7 +1463,7 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
return FALSE;
}
- RROutputSetPhysicalSize(output->randr_output,
+ RROutputSetPhysicalSize(output->randr_output,
output->mm_width,
output->mm_height);
xf86RROutputSetModes (output->randr_output, output->probed_modes);
@@ -1489,7 +1489,7 @@ xf86RandR12SetInfo12 (ScreenPtr pScreen)
for (l = 0; l < config->num_output; l++)
{
xf86OutputPtr clone = config->output[l];
-
+
if (l != o && (output->possible_clones & (1 << l)))
clones[nclone++] = clone->randr_output;
}
@@ -1530,7 +1530,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
int c;
int o;
-
+
if (!RRInit ())
return FALSE;
@@ -1540,7 +1540,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
-
+
crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
RRCrtcGammaSetSize (crtc->randr_crtc, 256);
}
@@ -1551,7 +1551,7 @@ xf86RandR12CreateObjects12 (ScreenPtr pScreen)
{
xf86OutputPtr output = config->output[o];
- output->randr_output = RROutputCreate (pScreen, output->name,
+ output->randr_output = RROutputCreate (pScreen, output->name,
strlen (output->name),
output);
@@ -1574,7 +1574,7 @@ xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
for (c = 0; c < config->num_crtc; c++)
xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
+
RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
config->maxWidth, config->maxHeight);
return TRUE;
@@ -1747,6 +1747,112 @@ xf86RandR14SetCrtcSpriteTransform(ScreenPtr pScreen,
}
static Bool
+xf86RRConvertCrtcConfig(xf86CrtcSetConfigPtr xf86_config,
+ RRCrtcConfigPtr rr_config)
+{
+ RRCrtcPtr rr_crtc = rr_config->crtc;
+ xf86CrtcPtr crtc = rr_crtc->devPrivate;
+ ScrnInfoPtr scrn = xf86Screens[rr_crtc->pScreen->myNum];
+ int o;
+
+ xf86_config->crtc = crtc;
+ xf86_config->x = rr_config->x;
+ xf86_config->y = rr_config->y;
+ xf86RandRModeConvert(scrn, rr_config->mode, &xf86_config->mode);
+ xf86_config->rotation = rr_config->rotation;
+ xf86_config->numOutputs = rr_config->numOutputs;
+ xf86_config->outputs = calloc(rr_config->numOutputs, sizeof (xf86OutputPtr));
+ if (!xf86_config->outputs)
+ return FALSE;
+ for (o = 0; o < rr_config->numOutputs; o++)
+ xf86_config->outputs[o] = rr_config->outputs[o]->devPrivate;
+ xf86_config->sprite_position_transform = rr_config->sprite_position_transform;
+ xf86_config->sprite_image_transform = rr_config->sprite_image_transform;
+ xf86_config->pixmap = rr_config->pixmap;
+ xf86_config->pixmap_x = rr_config->pixmap_x;
+ xf86_config->pixmap_y = rr_config->pixmap_y;
+ return TRUE;
+}
+
+static void
+xf86FreeCrtcSetConfigs(xf86CrtcSetConfigPtr xf86_crtc_configs, int num_configs)
+{
+ int i;
+
+ for (i = 0; i < num_configs; i++)
+ free(xf86_crtc_configs[i].outputs);
+ free(xf86_crtc_configs);
+}
+
+static Bool
+xf86RRSetCrtcConfigs(ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_configs,
+ int num_configs)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (config->funcs->set_config) {
+ xf86CrtcSetConfigPtr xf86_crtc_configs;
+ int i;
+ xf86SetConfigResponse response;
+
+ /*
+ * Convert RRCrtcConfigRecs to xf86CrtcSetConfigs
+ */
+ xf86_crtc_configs = calloc(num_configs, sizeof (xf86CrtcSetConfigRec));
+ if (!xf86_crtc_configs)
+ return FALSE;
+ for (i = 0; i < num_configs; i++)
+ if (!xf86RRConvertCrtcConfig(&xf86_crtc_configs[i], &crtc_configs[i])) {
+ xf86FreeCrtcSetConfigs(xf86_crtc_configs, num_configs);
+ return FALSE;
+ }
+
+ /*
+ * Ask the driver to set the configuration
+ */
+ response = (*config->funcs->set_config)(scrn,
+ screen_config,
+ xf86_crtc_configs,
+ num_configs);
+ xf86FreeCrtcSetConfigs(xf86_crtc_configs, num_configs);
+
+ /*
+ * The driver is allowed to answer with one of three
+ * responses:
+ */
+ switch (response) {
+ case xf86SetConfigFailed:
+
+ /* The configuration isn't usable, or some error
+ * occurred while setting it. Everything has been
+ * cleaned up and we're ready to return an error
+ * back to the client
+ */
+ return FALSE;
+ case xf86SetConfigDone:
+
+ /* The configuration was acceptable, and the whole
+ * mode setting experience is over. Nothing more to do
+ * here.
+ */
+ return TRUE;
+ case xf86SetConfigChecked:
+
+ /* The configuration was acceptable, but the driver
+ * didn't actually do anything. Go ask the DIX code
+ * to do the mode setting operation using the simpler
+ * interfaces
+ */
+ break;
+ }
+ }
+ return miRRSetCrtcConfigs(screen, screen_config, crtc_configs, num_configs);
+}
+
+static Bool
xf86RandR12EnterVT (int screen_index, int flags)
{
ScreenPtr pScreen = screenInfo.screens[screen_index];
@@ -1797,7 +1903,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
pScrn->PointerMoved = xf86RandR12PointerMoved;
pScrn->ChangeGamma = xf86RandR12ChangeGamma;
rp->rrSetCrtcSpriteTransform = xf86RandR14SetCrtcSpriteTransform;
- rp->rrSetCrtcConfigs = miRRSetCrtcConfigs;
+ rp->rrSetCrtcConfigs = xf86RRSetCrtcConfigs;
randrp->orig_EnterVT = pScrn->EnterVT;
pScrn->EnterVT = xf86RandR12EnterVT;
commit d94a035ea9eb3167fc4f35b2d9f0d53f8807014c
Author: Keith Packard <keithp at keithp.com>
Date: Sat Dec 4 19:22:11 2010 -0800
randr: Implement RRSetCrtcConfigs
This provides a driver-independent implementation of the
RRSetCrtcConfigs API by simply using the existing interfaces.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index bbf28cd..ac58135 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1797,6 +1797,7 @@ xf86RandR12Init12 (ScreenPtr pScreen)
pScrn->PointerMoved = xf86RandR12PointerMoved;
pScrn->ChangeGamma = xf86RandR12ChangeGamma;
rp->rrSetCrtcSpriteTransform = xf86RandR14SetCrtcSpriteTransform;
+ rp->rrSetCrtcConfigs = miRRSetCrtcConfigs;
randrp->orig_EnterVT = pScrn->EnterVT;
pScrn->EnterVT = xf86RandR12EnterVT;
diff --git a/randr/Makefile.am b/randr/Makefile.am
index 4b38e52..a1c88dc 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -22,7 +22,9 @@ librandr_la_SOURCES = \
rrsdispatch.c \
rrsprite.c \
rrtransform.h \
- rrtransform.c
+ rrtransform.c \
+ mirrcrtc.c
+
if XINERAMA
librandr_la_SOURCES += ${XINERAMA_SRCS}
diff --git a/randr/mirrcrtc.c b/randr/mirrcrtc.c
new file mode 100644
index 0000000..b1e2c9f
--- /dev/null
+++ b/randr/mirrcrtc.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright © 2010 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+
+Bool
+miRRSetScreenConfig(ScreenPtr screen,
+ RRScreenConfigPtr screen_config)
+{
+ RRScreenConfigRec old_screen_config;
+
+ /* XXX deal with separate pixmap/screen sizes */
+ if (screen_config->screen_pixmap_width != screen_config->screen_width ||
+ screen_config->screen_pixmap_height != screen_config->screen_height)
+ return FALSE;
+
+ RRScreenCurrentConfig(screen, &old_screen_config);
+
+ /* Check and see if nothing has changed */
+ if (old_screen_config.screen_width == screen_config->screen_width &&
+ old_screen_config.screen_height == screen_config->screen_height &&
+ old_screen_config.screen_pixmap_width == screen_config->screen_pixmap_width &&
+ old_screen_config.screen_pixmap_height == screen_config->screen_pixmap_height &&
+ old_screen_config.mm_width == screen_config->mm_width &&
+ old_screen_config.mm_height == screen_config->mm_height)
+ return TRUE;
+
+ return RRScreenSizeSet(screen,
+ screen_config->screen_width,
+ screen_config->screen_height,
+ screen_config->mm_width,
+ screen_config->mm_height);
+}
+
+Bool
+miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config)
+{
+ int x = crtc_config->x, y = crtc_config->y;
+
+ if (crtc_config->pixmap) {
+ x = crtc_config->pixmap_x;
+ y = crtc_config->pixmap_y;
+ }
+ return RRCrtcSet(crtc_config->crtc,
+ crtc_config->mode,
+ x,
+ y,
+ crtc_config->rotation,
+ crtc_config->numOutputs,
+ crtc_config->outputs);
+}
+
+Bool
+miRRDisableCrtc(RRCrtcPtr crtc)
+{
+ RRCrtcConfigRec off_config;
+
+ memset(&off_config, '\0', sizeof (RRCrtcConfigRec));
+ off_config.crtc = crtc;
+ return miRRSetCrtcConfig(&off_config);
+}
+
+/*
+ * If the current crtc configuration doesn't fit
+ * with the new screen config, disable it
+ */
+Bool
+miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config,
+ RRCrtcConfigPtr old_crtc_config)
+{
+ RRCrtcPtr crtc = old_crtc_config->crtc;
+
+ /* If it's already disabled, we're done */
+ if (!old_crtc_config->mode)
+ return TRUE;
+
+ /* If the crtc isn't scanning from the screen pixmap,
+ * we're done
+ */
+ if (old_crtc_config->pixmap)
+ return TRUE;
+
+ /* If the new screen configuration covers the existing CRTC space,
+ * we're done
+ */
+ if (RRScreenCoversCrtc(new_screen_config, old_crtc_config,
+ &crtc->client_current_transform, NULL))
+ return TRUE;
+
+ /* Disable the crtc and let it get re-enabled */
+ return miRRDisableCrtc(crtc);
+}
+
+Bool
+miRRSetCrtcConfigs(ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_configs,
+ int num_configs)
+{
+ RRScreenConfigRec old_screen_config;
+ RRCrtcConfigPtr old_crtc_configs;
+ int i;
+
+ /*
+ * Save existing state
+ */
+
+ RRScreenCurrentConfig(screen, &old_screen_config);
+ old_crtc_configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
+ if (!old_crtc_configs)
+ return FALSE;
+
+ for (i = 0; i < num_configs; i++)
+ if (!RRCrtcCurrentConfig(crtc_configs[i].crtc, &old_crtc_configs[i]))
+ goto fail_save;
+ /*
+ * Set the new configuration. If anything goes wrong,
+ * bail and restore the old configuration
+ */
+ for (i = 0; i < num_configs; i++)
+ if (!miRRCheckDisableCrtc(screen_config, &old_crtc_configs[i]))
+ goto fail_disable;
+
+ if (!miRRSetScreenConfig(screen, screen_config))
+ goto fail_set_screen;
+
+ for (i = 0; i < num_configs; i++)
+ if (!miRRSetCrtcConfig(&crtc_configs[i]))
+ goto fail_set_crtc;
+
+ RRFreeCrtcConfigs(old_crtc_configs, num_configs);
+ return TRUE;
+
+fail_set_crtc:
+ /*
+ * Restore the previous configuration. Ignore any errors
+ * as we just need to hope that the driver can manage to
+ * get back to the previous state without trouble.
+ */
+ for (i = 0; i < num_configs; i++)
+ (void) miRRDisableCrtc(old_crtc_configs[i].crtc);
+ (void) miRRSetScreenConfig(screen, &old_screen_config);
+fail_set_screen:
+fail_disable:
+ for (i = 0; i < num_configs; i++)
+ (void) miRRSetCrtcConfig(&old_crtc_configs[i]);
+fail_save:
+ RRFreeCrtcConfigs(old_crtc_configs, num_configs);
+ return FALSE;
+}
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 5e2a351..2fe9602 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -78,6 +78,8 @@ typedef struct _rrMode RRModeRec, *RRModePtr;
typedef struct _rrPropertyValue RRPropertyValueRec, *RRPropertyValuePtr;
typedef struct _rrProperty RRPropertyRec, *RRPropertyPtr;
typedef struct _rrCrtc RRCrtcRec, *RRCrtcPtr;
+typedef struct _rrScreenConfig RRScreenConfigRec, *RRScreenConfigPtr;
+typedef struct _rrCrtcConfig RRCrtcConfigRec, *RRCrtcConfigPtr;
typedef struct _rrOutput RROutputRec, *RROutputPtr;
struct _rrMode {
@@ -135,6 +137,28 @@ struct _rrCrtc {
struct pict_f_transform f_sprite_image_inverse; /* image from crtc */
};
+struct _rrScreenConfig {
+ CARD16 screen_pixmap_width;
+ CARD16 screen_pixmap_height;
+ CARD16 screen_width;
+ CARD16 screen_height;
+ CARD32 mm_width;
+ CARD32 mm_height;
+};
+
+struct _rrCrtcConfig {
+ RRCrtcPtr crtc;
+ int x, y;
+ RRModePtr mode;
+ Rotation rotation;
+ int numOutputs;
+ RROutputPtr *outputs;
+ struct pict_f_transform sprite_position_transform;
+ struct pict_f_transform sprite_image_transform;
+ PixmapPtr pixmap;
+ int pixmap_x, pixmap_y;
+};
+
struct _rrOutput {
RROutput id;
ScreenPtr pScreen;
@@ -251,6 +275,11 @@ typedef void (*RRGetCrtcSpriteTransformPtr) (ScreenPtr pScreen,
struct pict_f_transform *position_transform,
struct pict_f_transform *image_transform);
+typedef Bool (*RRSetCrtcConfigsPtr) (ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_configs,
+ int num_configs);
+
typedef struct _rrScrPriv {
/*
* 'public' part of the structure; DDXen fill this in
@@ -276,6 +305,7 @@ typedef struct _rrScrPriv {
#endif
RRSetCrtcSpriteTransformPtr rrSetCrtcSpriteTransform;
RRGetCrtcSpriteTransformPtr rrGetCrtcSpriteTransform;
+ RRSetCrtcConfigsPtr rrSetCrtcConfigs;
/*
* Private part of the structure; not considered part of the ABI
@@ -428,6 +458,10 @@ RRScreenSizeSet (ScreenPtr pScreen,
CARD32 mmWidth,
CARD32 mmHeight);
+extern _X_EXPORT void
+RRScreenCurrentConfig(ScreenPtr screen,
+ RRScreenConfigPtr screen_config);
+
/*
* Send ConfigureNotify event to root window when 'something' happens
*/
@@ -671,6 +705,38 @@ extern _X_EXPORT void
RRCrtcInitErrorValue (void);
/*
+ * Free a set of crtc configs and their attached output arrays
+ */
+void
+RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs);
+
+/*
+ * Convert the current crtc configuration into an RRCrtcConfig
+ */
+extern _X_EXPORT Bool
+RRCrtcCurrentConfig(RRCrtcPtr crtc,
+ RRCrtcConfigPtr crtc_config);
+
+/*
+ * Figure out whether the specific crtc_config can fit
+ * within the screen_config
+ */
+Bool
+RRScreenCoversCrtc(RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_config,
+ RRTransformPtr client_transform,
+ XID *errorValue);
+
+/*
+ * Set a screen and set of crtc configurations in one operation
+ */
+Bool
+RRSetCrtcConfigs(ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_configs,
+ int num_configs);
+
+/*
* Crtc dispatch
*/
@@ -695,6 +761,9 @@ ProcRRSetCrtcTransform (ClientPtr client);
extern _X_EXPORT int
ProcRRGetCrtcTransform (ClientPtr client);
+extern _X_EXPORT int
+ProcRRSetCrtcConfigs (ClientPtr client);
+
int
ProcRRGetPanning (ClientPtr client);
@@ -916,6 +985,27 @@ extern _X_EXPORT void
RRXineramaExtensionInit(void);
#endif
+/* mirrcrtc.c */
+Bool
+miRRSetScreenConfig(ScreenPtr screen,
+ RRScreenConfigPtr screen_config);
+
+Bool
+miRRSetCrtcConfig(RRCrtcConfigPtr crtc_config);
+
+Bool
+miRRDisableCrtc(RRCrtcPtr crtc);
+
+Bool
+miRRCheckDisableCrtc(RRScreenConfigPtr new_screen_config,
+ RRCrtcConfigPtr old_crtc_config);
+
+Bool
+miRRSetCrtcConfigs(ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_configs,
+ int num_configs);
+
#endif /* _RANDRSTR_H_ */
/*
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index c2f6963..1f8f2e6 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -37,7 +37,7 @@ RRCrtcChanged (RRCrtcPtr crtc, Bool layoutChanged)
if (pScreen)
{
rrScrPriv(pScreen);
-
+
pScrPriv->changed = TRUE;
/*
* Send ConfigureNotify on any layout change
@@ -59,19 +59,19 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
if (!RRInit())
return NULL;
-
+
pScrPriv = rrGetScrPriv(pScreen);
/* make space for the crtc pointer */
if (pScrPriv->numCrtcs)
- crtcs = realloc(pScrPriv->crtcs,
+ crtcs = realloc(pScrPriv->crtcs,
(pScrPriv->numCrtcs + 1) * sizeof (RRCrtcPtr));
else
crtcs = malloc(sizeof (RRCrtcPtr));
if (!crtcs)
return FALSE;
pScrPriv->crtcs = crtcs;
-
+
crtc = calloc(1, sizeof (RRCrtcRec));
if (!crtc)
return NULL;
@@ -90,6 +90,8 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
crtc->devPrivate = devPrivate;
RRTransformInit (&crtc->client_pending_transform);
RRTransformInit (&crtc->client_current_transform);
+ pixman_transform_init_identity (&crtc->client_sprite_position_transform);
+ pixman_transform_init_identity (&crtc->client_sprite_image_transform);
pixman_transform_init_identity (&crtc->transform);
pixman_f_transform_init_identity (&crtc->f_transform);
pixman_f_transform_init_identity (&crtc->f_inverse);
@@ -102,7 +104,7 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
/* attach the screen and crtc together */
crtc->pScreen = pScreen;
pScrPriv->crtcs[pScrPriv->numCrtcs++] = crtc;
-
+
return crtc;
}
@@ -139,7 +141,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
RROutputPtr *outputs)
{
int i, j;
-
+
/*
* Check to see if any of the new outputs were
* not in the old list and mark them as changed
@@ -179,7 +181,7 @@ RRCrtcNotify (RRCrtcPtr crtc,
if (numOutputs != crtc->numOutputs)
{
RROutputPtr *newoutputs;
-
+
if (numOutputs)
{
if (crtc->numOutputs)
@@ -258,7 +260,7 @@ RRDeliverCrtcEvent (ClientPtr client, WindowPtr pWin, RRCrtcPtr crtc)
rrScrPriv (pScreen);
xRRCrtcChangeNotifyEvent ce;
RRModePtr mode = crtc->mode;
-
+
ce.type = RRNotify + RREventBase;
ce.subCode = RRNotify_CrtcChange;
ce.timestamp = pScrPriv->lastSetTime.milliseconds;
@@ -333,7 +335,7 @@ RRCrtcSet (RRCrtcPtr crtc,
#if RANDR_12_INTERFACE
if (pScrPriv->rrCrtcSet)
{
- ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
+ ret = (*pScrPriv->rrCrtcSet) (pScreen, crtc, mode, x, y,
rotation, numOutputs, outputs);
}
else
@@ -392,6 +394,59 @@ RRCrtcSet (RRCrtcPtr crtc,
return ret;
}
+void
+RRFreeCrtcConfigs(RRCrtcConfigPtr configs, int num_configs)
+{
+ int i;
+
+ for (i = 0; i < num_configs; i++)
+ free(configs[i].outputs);
+ free(configs);
+}
+
+Bool
+RRCrtcCurrentConfig(RRCrtcPtr crtc,
+ RRCrtcConfigPtr crtc_config)
+{
+ crtc_config->crtc = crtc;
+ crtc_config->x = crtc->x;
+ crtc_config->y = crtc->y;
+ crtc_config->mode = crtc->mode;
+ crtc_config->rotation = crtc->rotation;
+ crtc_config->numOutputs = crtc->numOutputs;
+ crtc_config->outputs = calloc(crtc->numOutputs, sizeof (RROutputPtr));
+ if (!crtc_config->outputs)
+ return FALSE;
+ memcpy(crtc_config->outputs, crtc->outputs, crtc->numOutputs * sizeof (RROutputPtr));
+ crtc_config->sprite_position_transform = crtc->client_sprite_f_position_transform;
+ crtc_config->sprite_image_transform = crtc->client_sprite_f_image_transform;
+
+ /* XXX add pixmap stuff */
+ crtc_config->pixmap = NULL;
+ crtc_config->pixmap_x = 0;
+ crtc_config->pixmap_y = 0;
+ return TRUE;
+}
+
+
+/*
+ * Request that a set of crtcs be configured at the same
+ * time on a single screen
+ */
+
+Bool
+RRSetCrtcConfigs(ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_configs,
+ int num_configs)
+{
+ rrScrPrivPtr scr_priv = rrGetScrPriv(screen);
+
+ if (!scr_priv)
+ return FALSE;
+ return (*scr_priv->rrSetCrtcConfigs)(screen, screen_config, crtc_configs, num_configs);
+}
+
/*
* Return crtc transform
*/
@@ -435,7 +490,7 @@ RRCrtcDestroyResource (pointer value, XID pid)
{
rrScrPriv(pScreen);
int i;
-
+
for (i = 0; i < pScrPriv->numCrtcs; i++)
{
if (pScrPriv->crtcs[i] == crtc)
@@ -468,7 +523,7 @@ RRCrtcGammaSet (RRCrtcPtr crtc,
#if RANDR_12_INTERFACE
ScreenPtr pScreen = crtc->pScreen;
#endif
-
+
memcpy (crtc->gammaRed, red, crtc->gammaSize * sizeof (CARD16));
memcpy (crtc->gammaGreen, green, crtc->gammaSize * sizeof (CARD16));
memcpy (crtc->gammaBlue, blue, crtc->gammaSize * sizeof (CARD16));
@@ -631,6 +686,44 @@ RRCrtcTransformSet (RRCrtcPtr crtc,
}
/*
+ * Figure out whether the specific crtc_config can fit
+ * within the screen_config
+ */
+Bool
+RRScreenCoversCrtc(RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr crtc_config,
+ RRTransformPtr client_transform,
+ XID *errorValue)
+{
+ int source_width;
+ int source_height;
+ struct pixman_f_transform f_transform;
+
+ RRTransformCompute (crtc_config->x, crtc_config->y,
+ crtc_config->mode->mode.width, crtc_config->mode->mode.height,
+ crtc_config->rotation,
+ client_transform,
+ &crtc_config->sprite_position_transform,
+ &crtc_config->sprite_image_transform,
+ NULL, &f_transform, NULL, NULL, NULL, NULL);
+
+ RRModeGetScanoutSize (crtc_config->mode, &f_transform,
+ &source_width, &source_height);
+ if (crtc_config->x + source_width > screen_config->screen_pixmap_width) {
+ if (errorValue)
+ *errorValue = crtc_config->x;
+ return FALSE;
+ }
+
+ if (crtc_config->y + source_height > screen_config->screen_pixmap_height) {
+ if (errorValue)
+ *errorValue = crtc_config->y;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
* Initialize crtc type
*/
Bool
@@ -639,7 +732,7 @@ RRCrtcInit (void)
RRCrtcType = CreateNewResourceType (RRCrtcDestroyResource, "CRTC");
if (!RRCrtcType)
return FALSE;
-
+
return TRUE;
}
@@ -668,7 +761,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
int i, j, k, n;
int width, height;
BoxRec panned_area;
-
+
REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
@@ -679,7 +772,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
pScrPriv = rrGetScrPriv(pScreen);
mode = crtc->mode;
-
+
rep.type = X_Reply;
rep.status = RRSetConfigSuccess;
rep.sequenceNumber = client->sequence;
@@ -712,7 +805,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
if (pScrPriv->outputs[i]->crtcs[j] == crtc)
k++;
rep.nPossibleOutput = k;
-
+
rep.length = rep.nOutput + rep.nPossibleOutput;
extraLen = rep.length << 2;
@@ -727,7 +820,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
outputs = (RROutput *) extra;
possible = (RROutput *) (outputs + rep.nOutput);
-
+
for (i = 0; i < crtc->numOutputs; i++)
{
outputs[i] = crtc->outputs[i]->id;
@@ -744,7 +837,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
swapl (&possible[k], n);
k++;
}
-
+
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
@@ -765,7 +858,7 @@ ProcRRGetCrtcInfo (ClientPtr client)
WriteToClient (client, extraLen, (char *) extra);
free(extra);
}
-
+
return Success;
}
@@ -785,10 +878,10 @@ ProcRRSetCrtcConfig (ClientPtr client)
TimeStamp time;
Rotation rotation;
int rc, i, j;
-
+
REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
numOutputs = (stuff->length - bytes_to_int32(SIZEOF (xRRSetCrtcConfigReq)));
-
+
VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);
if (stuff->mode == None)
@@ -811,7 +904,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
}
else
outputs = NULL;
-
+
outputIds = (RROutput *) (stuff + 1);
for (i = 0; i < numOutputs; i++)
{
@@ -834,7 +927,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
/* validate mode for this output */
for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
{
- RRModePtr m = (j < outputs[i]->numModes ?
+ RRModePtr m = (j < outputs[i]->numModes ?
outputs[i]->modes[j] :
outputs[i]->userModes[j - outputs[i]->numModes]);
if (m == mode)
@@ -869,17 +962,17 @@ ProcRRSetCrtcConfig (ClientPtr client)
pScreen = crtc->pScreen;
pScrPriv = rrGetScrPriv(pScreen);
-
+
time = ClientTimeToServerTime(stuff->timestamp);
configTime = ClientTimeToServerTime(stuff->configTimestamp);
-
+
if (!pScrPriv)
{
time = currentTime;
rep.status = RRSetConfigFailed;
goto sendReply;
}
-
+
/*
* Validate requested rotation
*/
@@ -912,7 +1005,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
free(outputs);
return BadMatch;
}
-
+
#ifdef RANDR_12_INTERFACE
/*
* Check screen size bounds if the DDX provides a 1.2 interface
@@ -944,7 +1037,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
free(outputs);
return BadValue;
}
-
+
if (stuff->y + source_height > pScreen->height)
{
client->errorValue = stuff->y;
@@ -954,7 +1047,7 @@ ProcRRSetCrtcConfig (ClientPtr client)
}
#endif
}
-
+
if (!RRCrtcSet (crtc, mode, stuff->x, stuff->y,
rotation, numOutputs, outputs))
{
@@ -963,17 +1056,17 @@ ProcRRSetCrtcConfig (ClientPtr client)
}
rep.status = RRSetConfigSuccess;
pScrPriv->lastSetTime = time;
-
+
sendReply:
free(outputs);
-
+
rep.type = X_Reply;
/* rep.status has already been filled in */
rep.length = 0;
rep.sequenceNumber = client->sequence;
rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;
- if (client->swapped)
+ if (client->swapped)
{
int n;
swaps(&rep.sequenceNumber, n);
@@ -981,7 +1074,7 @@ sendReply:
swapl(&rep.newTimestamp, n);
}
WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *)&rep);
-
+
return Success;
}
@@ -997,7 +1090,7 @@ ProcRRGetPanning (ClientPtr client)
BoxRec tracking;
INT16 border[4];
int n;
-
+
REQUEST_SIZE_MATCH(xRRGetPanningReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
@@ -1067,7 +1160,7 @@ ProcRRSetPanning (ClientPtr client)
BoxRec tracking;
INT16 border[4];
int n;
-
+
REQUEST_SIZE_MATCH(xRRSetPanningReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
@@ -1082,9 +1175,9 @@ ProcRRSetPanning (ClientPtr client)
rep.status = RRSetConfigFailed;
goto sendReply;
}
-
+
time = ClientTimeToServerTime(stuff->timestamp);
-
+
if (!pScrPriv->rrGetPanning)
return RRErrorBase + BadRRCrtc;
@@ -1160,7 +1253,7 @@ ProcRRGetCrtcGamma (ClientPtr client)
int n;
unsigned long len;
char *extra = NULL;
-
+
REQUEST_SIZE_MATCH(xRRGetCrtcGammaReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
@@ -1169,7 +1262,7 @@ ProcRRGetCrtcGamma (ClientPtr client)
return RRErrorBase + BadRRCrtc;
len = crtc->gammaSize * 3 * 2;
-
+
if (crtc->gammaSize) {
extra = malloc(len);
if (!extra)
@@ -1203,21 +1296,21 @@ ProcRRSetCrtcGamma (ClientPtr client)
RRCrtcPtr crtc;
unsigned long len;
CARD16 *red, *green, *blue;
-
+
REQUEST_AT_LEAST_SIZE(xRRSetCrtcGammaReq);
VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
-
+
len = client->req_len - bytes_to_int32(sizeof (xRRSetCrtcGammaReq));
if (len < (stuff->size * 3 + 1) >> 1)
return BadLength;
if (stuff->size != crtc->gammaSize)
return BadMatch;
-
+
red = (CARD16 *) (stuff + 1);
green = red + crtc->gammaSize;
blue = green + crtc->gammaSize;
-
+
RRCrtcGammaSet (crtc, red, green, blue);
return Success;
@@ -1258,7 +1351,7 @@ ProcRRSetCrtcTransform (ClientPtr client)
#define CrtcTransformExtra (SIZEOF(xRRGetCrtcTransformReply) - 32)
-
+
static int
transform_filter_length (RRTransformPtr transform)
{
@@ -1360,3 +1453,336 @@ ProcRRGetCrtcTransform (ClientPtr client)
free(reply);
return Success;
}
+
+static void
+pixman_f_transform_from_xRenderTransform(struct pixman_f_transform *f_transform,
+ xRenderTransform *x_transform)
+{
+ struct pixman_transform transform;
+ PictTransform_from_xRenderTransform(&transform, x_transform);
+ pixman_f_transform_from_pixman_transform(f_transform, &transform);
+}
+
+static int
+RRConvertCrtcConfig(ClientPtr client, ScreenPtr screen,
+ RRScreenConfigPtr screen_config,
+ RRCrtcConfigPtr config, xRRCrtcConfig *x,
+ RROutput *outputIds)
+{
+ RRCrtcPtr crtc;
+ RROutputPtr *outputs;
+ rrScrPrivPtr scr_priv;
+ RRModePtr mode;
+ PixmapPtr pixmap;
+ int rc, i, j;
+ Rotation rotation;
+
+ VERIFY_RR_CRTC(x->crtc, crtc, DixSetAttrAccess);
+
+ if (x->mode == None)
+ {
+ mode = NULL;
+ if (x->nOutput > 0)
+ return BadMatch;
+ }
+ else
+ {
+ VERIFY_RR_MODE(x->mode, mode, DixSetAttrAccess);
+ if (x->nOutput == 0)
+ return BadMatch;
+ }
+ if (x->nOutput)
+ {
+ outputs = malloc(x->nOutput * sizeof (RROutputPtr));
+ if (!outputs)
+ return BadAlloc;
+ }
+ else
+ outputs = NULL;
+
+ if (x->pixmap == None)
+ pixmap = NULL;
+ else
+ {
+ rc = dixLookupResourceByType((pointer *) &pixmap, x->pixmap,
+ RT_PIXMAP, client, DixWriteAccess);
+ if (rc != Success) {
+ free(outputs);
+ return rc;
+ }
+ /* XXX check to make sure this is a scanout pixmap */
+ }
+
+ for (i = 0; i < x->nOutput; i++)
+ {
+ rc = dixLookupResourceByType((pointer *)(outputs + i), outputIds[i],
+ RROutputType, client, DixSetAttrAccess);
+ if (rc != Success)
+ {
+ free(outputs);
+ return rc;
+ }
+ /* validate crtc for this output */
+ for (j = 0; j < outputs[i]->numCrtcs; j++)
+ if (outputs[i]->crtcs[j] == crtc)
+ break;
+ if (j == outputs[i]->numCrtcs)
+ {
+ free(outputs);
+ return BadMatch;
+ }
+ /* validate mode for this output */
+ for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++)
+ {
+ RRModePtr m = (j < outputs[i]->numModes ?
+ outputs[i]->modes[j] :
+ outputs[i]->userModes[j - outputs[i]->numModes]);
+ if (m == mode)
+ break;
+ }
+ if (j == outputs[i]->numModes + outputs[i]->numUserModes)
+ {
+ free(outputs);
+ return BadMatch;
+ }
+ }
+ /* validate clones */
+ for (i = 0; i < x->nOutput; i++)
+ {
+ for (j = 0; j < x->nOutput; j++)
+ {
+ int k;
+ if (i == j)
+ continue;
+ for (k = 0; k < outputs[i]->numClones; k++)
+ {
+ if (outputs[i]->clones[k] == outputs[j])
+ break;
+ }
+ if (k == outputs[i]->numClones)
+ {
+ free(outputs);
+ return BadMatch;
+ }
+ }
+ }
+
+ if (crtc->pScreen != screen)
+ return BadMatch;
+
+ scr_priv = rrGetScrPriv(screen);
+
+ config->crtc = crtc;
+ config->x = x->x;
+ config->y = x->y;
+ config->mode = mode;
+ config->rotation = x->rotation;
+ config->numOutputs = x->nOutput;
+ config->outputs = outputs;
+ pixman_f_transform_from_xRenderTransform(&config->sprite_position_transform,
+ &x->spritePositionTransform);
+ pixman_f_transform_from_xRenderTransform(&config->sprite_image_transform,
+ &x->spriteImageTransform);
+ config->pixmap = pixmap;
+ config->pixmap_x = x->xPixmap;
+ config->pixmap_y = x->yPixmap;
+
+ /*
+ * Validate requested rotation
+ */
+ rotation = (Rotation) x->rotation;
+
+ /* test the rotation bits only! */
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_90:
+ case RR_Rotate_180:
+ case RR_Rotate_270:
+ break;
+ default:
+ /*
+ * Invalid rotation
+ */
+ client->errorValue = x->rotation;
+ free(outputs);
+ return BadValue;
+ }
+
+ if (mode)
+ {
+ if ((~crtc->rotations) & rotation)
+ {
+ /*
+ * requested rotation or reflection not supported by screen
+ */
+ client->errorValue = x->rotation;
+ free(outputs);
+ return BadMatch;
+ }
+
+ /*
+ * If scanning out from another pixmap, make sure the mode
+ * fits
+ */
+ if (pixmap)
+ {
+ if (x->xPixmap + mode->mode.width > pixmap->drawable.width) {
+ client->errorValue = x->xPixmap;
+ free(outputs);
+ return BadValue;
+ }
+ if (x->yPixmap + mode->mode.height > pixmap->drawable.height) {
+ client->errorValue = x->yPixmap;
+ free(outputs);
+ return BadValue;
+ }
+ }
+ /*
+ * Check screen size bounds if the DDX provides a 1.2 interface
+ * for setting screen size. Else, assume the CrtcSet sets
+ * the size along with the mode. If the driver supports transforms,
+ * then it must allow crtcs to display a subset of the screen, so
+ * only do this check for drivers without transform support.
+ */
+ else if (scr_priv->rrScreenSetSize && !crtc->transforms)
+ {
+ if (!RRScreenCoversCrtc(screen_config, config,
+ &crtc->client_pending_transform,
+ &client->errorValue))
+ {
+ free(outputs);
+ return BadValue;
+ }
+ }
+ }
+
+ return Success;
+}
+
+int
+ProcRRSetCrtcConfigs (ClientPtr client)
+{
+ REQUEST(xRRSetCrtcConfigsReq);
+ xRRSetCrtcConfigsReply rep;
+ DrawablePtr drawable;
+ ScreenPtr screen;
+ rrScrPrivPtr scr_priv;
+ xRRCrtcConfig *x_configs;
+ RRScreenConfigRec screen_config;
+ RRCrtcConfigPtr configs;
+ RROutput *output_ids;
+ int num_configs;
+ int rc, i;
+ int extra_len;
+ int num_output_ids;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigsReq);
+
+ extra_len = client->req_len - bytes_to_int32(sizeof(xRRSetCrtcConfigsReq));
+
+ num_configs = stuff->nConfigs;
+
+ /* Check request length against number of configs specified */
+ if (num_configs * (sizeof (xRRCrtcConfig) >> 2) > extra_len)
+ return BadLength;
+
+ extra_len -= num_configs * (sizeof (xRRCrtcConfig) >> 2);
+ x_configs = (xRRCrtcConfig *) (stuff + 1);
+
+ /* Check remaining request length against number of outputs */
+ num_output_ids = 0;
+ for (i = 0; i < num_configs; i++)
+ num_output_ids += x_configs[i].nOutput;
+
+ if (extra_len != num_output_ids)
+ return BadLength;
+
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ screen = drawable->pScreen;
+
+ scr_priv = rrGetScrPriv(screen);
+
+ if (!scr_priv)
+ {
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+
+ if (stuff->widthInMillimeters == 0 || stuff->heightInMillimeters == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ if (stuff->screenPixmapWidth < scr_priv->minWidth ||
+ scr_priv->maxWidth < stuff->screenPixmapWidth)
+ {
+ client->errorValue = stuff->screenPixmapWidth;
+ return BadValue;
+ }
+ if (stuff->screenPixmapHeight < scr_priv->minHeight ||
+ scr_priv->maxHeight < stuff->screenPixmapHeight)
+ {
+ client->errorValue = stuff->screenPixmapHeight;
+ return BadValue;
+ }
+
+ screen_config.screen_pixmap_width = stuff->screenPixmapWidth;
+ screen_config.screen_pixmap_height = stuff->screenPixmapHeight;
+ screen_config.screen_width = stuff->screenWidth;
+ screen_config.screen_height = stuff->screenHeight;
+ screen_config.mm_width = stuff->widthInMillimeters;
+ screen_config.mm_height = stuff->heightInMillimeters;
+
+ if (num_configs == 0)
+ return Success;
+
+ output_ids = (RROutput *) (x_configs + num_configs);
+
+ /*
+ * Convert protocol crtc configurations into
+ * server crtc configurations
+ */
+ configs = calloc(num_configs, sizeof (RRCrtcConfigRec));
+ if (!configs)
+ return BadAlloc;
+ for (i = 0; i < num_configs; i++) {
+ rc = RRConvertCrtcConfig(client, screen, &screen_config,
+ &configs[i],
+ &x_configs[i], output_ids);
+ if (rc != Success) {
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ output_ids += x_configs[i].nOutput;
+ }
+
+ if (!RRSetCrtcConfigs (screen, &screen_config, configs, num_configs))
+ {
+ rep.status = RRSetConfigFailed;
+ goto sendReply;
+ }
+ rep.status = RRSetConfigSuccess;
+ scr_priv->lastSetTime = currentTime;
+
+sendReply:
+ RRFreeCrtcConfigs(configs, num_configs);
+
+ rep.type = X_Reply;
+ /* rep.status has already been filled in */
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (client->swapped)
+ {
+ int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xRRSetCrtcConfigsReply), (char *)&rep);
+
+ return Success;
+}
diff --git a/randr/rrscreen.c b/randr/rrscreen.c
index f58e657..62ea2b6 100644
--- a/randr/rrscreen.c
+++ b/randr/rrscreen.c
@@ -191,6 +191,24 @@ RRScreenSizeSet (ScreenPtr pScreen,
}
/*
+ * Compute an RRScreenConfig from the current screen information
+ */
+void
+RRScreenCurrentConfig(ScreenPtr screen,
+ RRScreenConfigPtr screen_config)
+{
+ PixmapPtr screen_pixmap = screen->GetScreenPixmap(screen);
+ WindowPtr root = screen->root;
+
+ screen_config->screen_pixmap_width = screen_pixmap->drawable.width;
+ screen_config->screen_pixmap_height = screen_pixmap->drawable.height;
+ screen_config->screen_width = root->drawable.width;
+ screen_config->screen_height = root->drawable.height;
+ screen_config->mm_width = screen->mmWidth;
+ screen_config->mm_height = screen->mmHeight;
+}
+
+/*
* Retrieve valid screen size range
*/
int
commit 66294afcab7b7a82f7dd897767e46c48a94b8ee8
Author: Keith Packard <keithp at keithp.com>
Date: Fri Dec 3 22:08:06 2010 -0800
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 at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 4573f62..3fccaea 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -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));
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index f43e0a7..8b42efc 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -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.
diff --git a/hw/xfree86/modes/xf86Cursors.c b/hw/xfree86/modes/xf86Cursors.c
index 0667447..7b43bcb 100644
--- a/hw/xfree86/modes/xf86Cursors.c
+++ b/hw/xfree86/modes/xf86Cursors.c
@@ -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]);
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index d60ee3c..bbf28cd 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -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;
diff --git a/hw/xfree86/modes/xf86Rotate.c b/hw/xfree86/modes/xf86Rotate.c
index 57c3499..ddc6d4c 100644
--- a/hw/xfree86/modes/xf86Rotate.c
+++ b/hw/xfree86/modes/xf86Rotate.c
@@ -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;
diff --git a/randr/Makefile.am b/randr/Makefile.am
index de338b9..4b38e52 100644
--- a/randr/Makefile.am
+++ b/randr/Makefile.am
@@ -20,6 +20,7 @@ librandr_la_SOURCES = \
rrproperty.c \
rrscreen.c \
rrsdispatch.c \
+ rrsprite.c \
rrtransform.h \
rrtransform.c
diff --git a/randr/randrstr.h b/randr/randrstr.h
index 7ea6080..5e2a351 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -55,9 +55,10 @@
#define RANDR_10_INTERFACE 1
#define RANDR_12_INTERFACE 1
#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
+#define RANDR_14_INTERFACE 1 /* requires RANDR_13_INTERFACE */
#define RANDR_GET_CRTC_INTERFACE 1
-#define RANDR_INTERFACE_VERSION 0x0103
+#define RANDR_INTERFACE_VERSION 0x0104
typedef XID RRMode;
typedef XID RROutput;
@@ -122,9 +123,16 @@ struct _rrCrtc {
Bool transforms;
RRTransformRec client_pending_transform;
RRTransformRec client_current_transform;
+ PictTransform client_sprite_position_transform;
+ PictTransform client_sprite_image_transform;
+ struct pict_f_transform client_sprite_f_position_transform;
+ struct pict_f_transform client_sprite_f_image_transform;
+
PictTransform transform;
struct pict_f_transform f_transform;
struct pict_f_transform f_inverse;
+ struct pict_f_transform f_sprite_position; /* crtc from screen */
+ struct pict_f_transform f_sprite_image_inverse; /* image from crtc */
};
struct _rrOutput {
@@ -233,6 +241,16 @@ typedef Bool (*RRSetConfigProcPtr) (ScreenPtr pScreen,
#endif
+typedef void (*RRSetCrtcSpriteTransformPtr) (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ struct pict_f_transform *position_transform,
+ struct pict_f_transform *image_transform);
+
+typedef void (*RRGetCrtcSpriteTransformPtr) (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ struct pict_f_transform *position_transform,
+ struct pict_f_transform *image_transform);
+
typedef struct _rrScrPriv {
/*
* 'public' part of the structure; DDXen fill this in
@@ -256,7 +274,9 @@ typedef struct _rrScrPriv {
RRGetPanningProcPtr rrGetPanning;
RRSetPanningProcPtr rrSetPanning;
#endif
-
+ RRSetCrtcSpriteTransformPtr rrSetCrtcSpriteTransform;
+ RRGetCrtcSpriteTransformPtr rrGetCrtcSpriteTransform;
+
/*
* Private part of the structure; not considered part of the ABI
*/
@@ -606,25 +626,6 @@ extern _X_EXPORT void
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height);
/*
- * Compute the complete transformation matrix including
- * client-specified transform, rotation/reflection values and the crtc
- * offset.
- *
- * Return TRUE if the resulting transform is not a simple translation.
- */
-extern _X_EXPORT Bool
-RRTransformCompute (int x,
- int y,
- int width,
- int height,
- Rotation rotation,
- RRTransformPtr rr_transform,
-
- PictTransformPtr transform,
- struct pict_f_transform *f_transform,
- struct pict_f_transform *f_inverse);
-
-/*
* Return crtc transform
*/
extern _X_EXPORT RRTransformPtr
@@ -700,6 +701,19 @@ ProcRRGetPanning (ClientPtr client);
int
ProcRRSetPanning (ClientPtr client);
+void
+RRCrtcSpriteTransformSet(RRCrtcPtr crtc,
+ PictTransform *position_transform,
+ PictTransform *image_transform,
+ struct pict_f_transform *f_position_transform,
+ struct pict_f_transform *f_image_transform);
+
+int
+ProcRRSetCrtcSpriteTransform (ClientPtr client);
+
+int
+ProcRRGetCrtcSpriteTransform (ClientPtr client);
+
/* rrdispatch.c */
extern _X_EXPORT Bool
RRClientKnowsRates (ClientPtr pClient);
@@ -889,6 +903,13 @@ ProcRRConfigureOutputProperty (ClientPtr client);
extern _X_EXPORT int
ProcRRDeleteOutputProperty (ClientPtr client);
+/* rrsprite.c */
+extern _X_EXPORT int
+ProcRRSetCrtcSpriteTransform (ClientPtr client);
+
+extern _X_EXPORT int
+ProcRRGetCrtcSpriteTransform (ClientPtr client);
+
/* rrxinerama.c */
#ifdef XINERAMA
extern _X_EXPORT void
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 98206a2..c2f6963 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -93,6 +93,8 @@ RRCrtcCreate (ScreenPtr pScreen, void *devPrivate)
pixman_transform_init_identity (&crtc->transform);
pixman_f_transform_init_identity (&crtc->f_transform);
pixman_f_transform_init_identity (&crtc->f_inverse);
+ pixman_f_transform_init_identity (&crtc->f_sprite_position);
+ pixman_f_transform_init_identity (&crtc->f_sprite_image_inverse);
if (!AddResource (crtc->id, RRCrtcType, (pointer) crtc))
return NULL;
@@ -231,15 +233,21 @@ RRCrtcNotify (RRCrtcPtr crtc,
RRTransformCopy (&crtc->client_current_transform, transform);
RRCrtcChanged (crtc, TRUE);
}
+
if (crtc->changed && mode)
{
RRTransformCompute (x, y,
mode->mode.width, mode->mode.height,
rotation,
&crtc->client_current_transform,
+ &crtc->client_sprite_f_position_transform,
+ &crtc->client_sprite_f_image_transform,
&crtc->transform, &crtc->f_transform,
- &crtc->f_inverse);
+ &crtc->f_inverse, &crtc->f_sprite_position,
+ &crtc->f_sprite_image_inverse,
+ NULL);
}
+
return TRUE;
}
@@ -511,7 +519,7 @@ RRCrtcGammaNotify (RRCrtcPtr crtc)
}
static void
-RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
+RRModeGetScanoutSize (RRModePtr mode, struct pixman_f_transform *transform,
int *width, int *height)
{
BoxRec box;
@@ -527,7 +535,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
box.x2 = mode->mode.width;
box.y2 = mode->mode.height;
- pixman_transform_bounds (transform, &box);
+ pixman_f_transform_bounds (transform, &box);
*width = box.x2 - box.x1;
*height = box.y2 - box.y1;
}
@@ -538,7 +546,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform,
void
RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height)
{
- return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height);
+ RRModeGetScanoutSize (crtc->mode, &crtc->f_transform, width, height);
}
/*
@@ -924,9 +932,12 @@ ProcRRSetCrtcConfig (ClientPtr client)
mode->mode.width, mode->mode.height,
rotation,
&crtc->client_pending_transform,
- &transform, &f_transform, &f_inverse);
+ &crtc->client_sprite_f_position_transform,
+ &crtc->client_sprite_f_image_transform,
+ &transform, &f_transform, &f_inverse, NULL, NULL, NULL);
- RRModeGetScanoutSize (mode, &transform, &source_width, &source_height);
+ RRModeGetScanoutSize (mode, &f_transform,
+ &source_width, &source_height);
if (stuff->x + source_width > pScreen->width)
{
client->errorValue = stuff->x;
diff --git a/randr/rrsprite.c b/randr/rrsprite.c
new file mode 100644
index 0000000..5bf312c
--- /dev/null
+++ b/randr/rrsprite.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright © 2010 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include "randrstr.h"
+#include "swaprep.h"
+
+void
+RRCrtcSpriteTransformSet(RRCrtcPtr crtc,
+ PictTransform *position_transform,
+ PictTransform *image_transform,
+ struct pict_f_transform *f_position_transform,
+ struct pict_f_transform *f_image_transform)
+{
+ ScreenPtr pScreen;
+ rrScrPrivPtr pScrPriv;
+
+ pScreen = crtc->pScreen;
+ pScrPriv = rrGetScrPriv(pScreen);
+ crtc->client_sprite_position_transform = *position_transform;
+ crtc->client_sprite_image_transform = *image_transform;
+ crtc->client_sprite_f_position_transform = *f_position_transform;
+ crtc->client_sprite_f_image_transform = *f_image_transform;
+ if (pScrPriv->rrSetCrtcSpriteTransform)
+ (*pScrPriv->rrSetCrtcSpriteTransform) (pScreen, crtc,
+ &crtc->client_sprite_f_position_transform,
+ &crtc->client_sprite_f_image_transform);
+}
+
+int
+ProcRRSetCrtcSpriteTransform (ClientPtr client)
+{
+ REQUEST(xRRSetCrtcSpriteTransformReq);
+ RRCrtcPtr crtc;
+ PictTransform position_transform, image_transform;
+ struct pixman_f_transform f_position_transform, f_image_transform;
+
+ REQUEST_AT_LEAST_SIZE(xRRSetCrtcSpriteTransformReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ PictTransform_from_xRenderTransform (&position_transform, &stuff->positionTransform);
+ PictTransform_from_xRenderTransform (&image_transform, &stuff->imageTransform);
+ pixman_f_transform_from_pixman_transform (&f_position_transform, &position_transform);
+ pixman_f_transform_from_pixman_transform (&f_image_transform, &image_transform);
+
+ RRCrtcSpriteTransformSet (crtc, &position_transform, &image_transform,
+ &f_position_transform, &f_image_transform);
+ return Success;
+}
+
+#define CrtcSpriteTransformExtra (SIZEOF(xRRGetCrtcSpriteTransformReply) - 32)
+
+int
+ProcRRGetCrtcSpriteTransform (ClientPtr client)
+{
+ REQUEST(xRRGetCrtcSpriteTransformReq);
+ xRRGetCrtcSpriteTransformReply *reply;
+ RRCrtcPtr crtc;
+ int n;
+ char *extra;
+
+ REQUEST_SIZE_MATCH (xRRGetCrtcSpriteTransformReq);
+ VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);
+
+ reply = malloc(sizeof (xRRGetCrtcSpriteTransformReply));
+ if (!reply)
+ return BadAlloc;
+
+ extra = (char *) (reply + 1);
+ reply->type = X_Reply;
+ reply->sequenceNumber = client->sequence;
+ reply->length = bytes_to_int32(CrtcSpriteTransformExtra);
+
+ xRenderTransform_from_PictTransform(&reply->positionTransform, &crtc->client_sprite_position_transform);
+ xRenderTransform_from_PictTransform(&reply->imageTransform, &crtc->client_sprite_image_transform);
+
+ if (client->swapped) {
+ swaps (&reply->sequenceNumber, n);
+ swapl (&reply->length, n);
+ SwapLongs((CARD32 *) &reply->positionTransform, bytes_to_int32(sizeof(xRenderTransform)));
+ SwapLongs((CARD32 *) &reply->imageTransform, bytes_to_int32(sizeof(xRenderTransform)));
+ }
+ WriteToClient (client, sizeof (xRRGetCrtcSpriteTransformReply), (char *) reply);
+ free(reply);
+ return Success;
+}
diff --git a/randr/rrtransform.c b/randr/rrtransform.c
index e162049..3eda5f3 100644
--- a/randr/rrtransform.c
+++ b/randr/rrtransform.c
@@ -134,6 +134,24 @@ RRTransformRescale(struct pixman_f_transform *f_transform, double limit)
f_transform->m[j][i] *= scale;
}
+#define EPSILON (1e-20)
+#define IS_F_SAME(a,b) (fabs((a)-(b)) < EPSILON)
+#define IS_F_ZERO(a) (fabs(a) < EPSILON)
+
+static Bool
+pict_f_transform_is_identity (const struct pixman_f_transform *t)
+{
+ return (IS_F_SAME (t->m[0][0], t->m[1][1]) &&
+ IS_F_SAME (t->m[0][0], t->m[2][2]) &&
+ !IS_F_ZERO (t->m[0][0]) &&
+ IS_F_ZERO (t->m[0][1]) &&
+ IS_F_ZERO (t->m[0][2]) &&
+ IS_F_ZERO (t->m[1][0]) &&
+ IS_F_ZERO (t->m[1][2]) &&
+ IS_F_ZERO (t->m[2][0]) &&
+ IS_F_ZERO (t->m[2][1]));
+}
+
/*
* Compute the complete transformation matrix including
* client-specified transform, rotation/reflection values and the crtc
@@ -148,23 +166,39 @@ RRTransformCompute (int x,
int height,
Rotation rotation,
RRTransformPtr rr_transform,
+ struct pixman_f_transform *sprite_position_transform,
+ struct pixman_f_transform *sprite_image_transform,
PictTransformPtr transform,
struct pixman_f_transform *f_transform,
- struct pixman_f_transform *f_inverse)
+ struct pixman_f_transform *f_inverse,
+ struct pixman_f_transform *f_fb_to_sprite,
+ struct pixman_f_transform *f_sprite_to_image,
+ Bool *sprite_transform_in_use)
{
PictTransform t_transform, inverse;
struct pixman_f_transform tf_transform, tf_inverse;
+ struct pixman_f_transform sf_position_transform, sf_image_transform;
+ struct pixman_f_transform f_image_to_sprite;
Bool overflow = FALSE;
+ Bool ret = TRUE;
if (!transform) transform = &t_transform;
if (!f_transform) f_transform = &tf_transform;
if (!f_inverse) f_inverse = &tf_inverse;
+ if (!f_fb_to_sprite) f_fb_to_sprite = &sf_position_transform;
+ if (!f_sprite_to_image) f_sprite_to_image = &sf_image_transform;
+
+ /* invert the sprite image transform to have it go from dest to source */
+ if (!pixman_f_transform_invert (&f_image_to_sprite, f_sprite_to_image))
+ pixman_f_transform_init_identity(&f_image_to_sprite);
pixman_transform_init_identity (transform);
pixman_transform_init_identity (&inverse);
pixman_f_transform_init_identity (f_transform);
pixman_f_transform_init_identity (f_inverse);
+ pixman_f_transform_init_identity (f_fb_to_sprite);
+ pixman_f_transform_init_identity (f_sprite_to_image);
if (rotation != RR_Rotate_0)
{
double f_rot_cos, f_rot_sin, f_rot_dx, f_rot_dy;
@@ -246,7 +280,14 @@ RRTransformCompute (int x,
pixman_f_transform_translate (f_transform, f_inverse, f_scale_dx, f_scale_dy);
}
-#ifdef RANDR_12_INTERFACE
+ /*
+ * Sprite position is affected by the transform matrix,
+ * but the image is not
+ */
+ pixman_f_transform_multiply(f_sprite_to_image,
+ f_transform,
+ &f_image_to_sprite);
+
if (rr_transform)
{
if (!pixman_transform_multiply (transform, &rr_transform->transform, transform))
@@ -254,7 +295,7 @@ RRTransformCompute (int x,
pixman_f_transform_multiply (f_transform, &rr_transform->f_transform, f_transform);
pixman_f_transform_multiply (f_inverse, f_inverse, &rr_transform->f_inverse);
}
-#endif
+
/*
* Compute the class of the resulting transform
*/
@@ -264,7 +305,7 @@ RRTransformCompute (int x,
pixman_f_transform_init_translate (f_transform, x, y);
pixman_f_transform_init_translate (f_inverse, -x, -y);
- return FALSE;
+ ret = FALSE;
}
else
{
@@ -278,6 +319,19 @@ RRTransformCompute (int x,
RRTransformRescale(&f_scaled, 16384.0);
pixman_transform_from_pixman_f_transform(transform, &f_scaled);
}
- return TRUE;
+ ret = TRUE;
}
+
+ /*
+ * Sprite position is affected by the transform matrix,
+ * but the image is not
+ */
+ pixman_f_transform_multiply(f_fb_to_sprite,
+ f_inverse,
+ sprite_position_transform);
+ if (sprite_transform_in_use)
+ *sprite_transform_in_use = ret || !pict_f_transform_is_identity(f_fb_to_sprite);
+ return ret;
}
+
+
diff --git a/randr/rrtransform.h b/randr/rrtransform.h
index 561762d..5cfcf8d 100644
--- a/randr/rrtransform.h
+++ b/randr/rrtransform.h
@@ -59,6 +59,13 @@ RRTransformSetFilter (RRTransformPtr dst,
extern _X_EXPORT Bool
RRTransformCopy (RRTransformPtr dst, RRTransformPtr src);
+/*
+ * Compute the complete transformation matrix including
+ * client-specified transform, rotation/reflection values and the crtc
+ * offset.
+ *
+ * Return TRUE if the resulting transform is not a simple translation.
+ */
extern _X_EXPORT Bool
RRTransformCompute (int x,
int y,
@@ -66,10 +73,14 @@ RRTransformCompute (int x,
int height,
Rotation rotation,
RRTransformPtr rr_transform,
+ struct pict_f_transform *sprite_position_transform,
+ struct pict_f_transform *sprite_image_transform,
PictTransformPtr transform,
struct pict_f_transform *f_transform,
- struct pict_f_transform *f_inverse);
-
+ struct pict_f_transform *f_inverse,
+ struct pict_f_transform *f_fb_to_sprite,
+ struct pict_f_transform *f_sprite_to_image,
+ Bool *sprite_transform_in_use);
#endif /* _RRTRANSFORM_H_ */
commit c8bc25fd7629df10f2825b7cc713b031ae78f223
Author: Keith Packard <keithp at keithp.com>
Date: Mon Dec 6 19:40:30 2010 -0800
Require RandR protocol version 1.4 or newer
Signed-off-by: Keith Packard <keithp at keithp.com>
diff --git a/configure.ac b/configure.ac
index 3021bdd..d1fc379 100644
--- a/configure.ac
+++ b/configure.ac
@@ -788,7 +788,7 @@ WINDOWSWMPROTO="windowswmproto"
APPLEWMPROTO="applewmproto >= 1.4"
dnl Core modules for most extensions, et al.
-SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.2.99.3] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto"
+SDK_REQUIRED_MODULES="[xproto >= 7.0.17] [randrproto >= 1.4] [renderproto >= 0.11] [xextproto >= 7.1.99] [inputproto >= 1.9.99.902] [kbproto >= 1.0.3] fontsproto"
# Make SDK_REQUIRED_MODULES available for inclusion in xorg-server.pc
AC_SUBST(SDK_REQUIRED_MODULES)
commit 8b35118c03590a7ad3786d3284bafb3f40fcb8cc
Author: Keith Packard <keithp at keithp.com>
Date: Sun Jun 6 15:23:37 2010 -0700
Replace huge argument list in xf86CrtcSetModeTransform with struct
xf86CrtcSetModeTransform was starting to get ridiculous with 6
arguments, this change has it take a single structure that contains
all of those values along with a set of flags that says which have
changed.
Signed-off-by: Keith Packard <keithp at keithp.com>
Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index b94bc09..4573f62 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -247,15 +247,14 @@ xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
* Sets the given video mode on the given crtc
*/
Bool
-xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- RRTransformPtr transform, int x, int y)
+xf86CrtcSet(xf86CrtcPtr crtc, xf86CrtcSetRec *set)
{
ScrnInfoPtr scrn = crtc->scrn;
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
int i;
Bool ret = FALSE;
Bool didLock = FALSE;
- DisplayModePtr adjusted_mode;
+ DisplayModePtr adjusted_mode = NULL;
DisplayModeRec saved_mode;
int saved_x, saved_y;
Rotation saved_rotation;
@@ -272,8 +271,9 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
return TRUE;
}
- adjusted_mode = xf86DuplicateMode(mode);
-
+ /* See if nothing has changed */
+ if (!set->flags)
+ return TRUE;
saved_mode = crtc->mode;
saved_x = crtc->x;
@@ -288,21 +288,44 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
/* Update crtc values up front so the driver can rely on them for mode
* setting.
*/
- crtc->mode = *mode;
- crtc->x = x;
- crtc->y = y;
- crtc->rotation = rotation;
- if (transform) {
- RRTransformCopy (&crtc->transform, transform);
- crtc->transformPresent = TRUE;
- } else
- crtc->transformPresent = FALSE;
+ if (set->flags & XF86CrtcSetMode)
+ crtc->mode = *set->mode;
+ if (set->flags & XF86CrtcSetOrigin) {
+ crtc->x = set->x;
+ crtc->y = set->y;
+ }
+ if (set->flags & XF86CrtcSetRotation)
+ crtc->rotation = set->rotation;
+
+ if (set->flags & XF86CrtcSetTransform) {
+ if (set->transform) {
+ RRTransformCopy (&crtc->transform, set->transform);
+ crtc->transformPresent = TRUE;
+ } else
+ crtc->transformPresent = FALSE;
+ }
+
+ if (crtc->funcs->set) {
+ ret = crtc->funcs->set(crtc, set->flags);
+ goto done;
+ }
+
+ if (set->flags == XF86CrtcSetOrigin && crtc->funcs->set_origin) {
+ ret = xf86CrtcRotate(crtc);
+ if (ret)
+ crtc->funcs->set_origin(crtc, crtc->x, crtc->y);
+ goto done;
+ }
if (crtc->funcs->set_mode_major) {
- ret = crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
+ ret = crtc->funcs->set_mode_major(crtc, &crtc->mode,
+ crtc->rotation,
+ crtc->x, crtc->y);
goto done;
}
+ adjusted_mode = xf86DuplicateMode(&crtc->mode);
+
didLock = crtc->funcs->lock (crtc);
/* Pass our mode to the outputs and the CRTC to give them a chance to
* adjust it according to limitations or output properties, and also
@@ -314,12 +337,12 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
if (output->crtc != crtc)
continue;
- if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
+ if (!output->funcs->mode_fixup(output, &crtc->mode, adjusted_mode)) {
goto done;
}
}
- if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
+ if (!crtc->funcs->mode_fixup(crtc, &crtc->mode, adjusted_mode)) {
goto done;
}
@@ -342,12 +365,12 @@ xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotati
/* Set up the DPLL and any output state that needs to adjust or depend
* on the DPLL.
*/
- crtc->funcs->mode_set(crtc, mode, adjusted_mode, crtc->x, crtc->y);
+ crtc->funcs->mode_set(crtc, &crtc->mode, adjusted_mode, crtc->x, crtc->y);
for (i = 0; i < xf86_config->num_output; i++)
{
xf86OutputPtr output = xf86_config->output[i];
if (output->crtc == crtc)
- output->funcs->mode_set(output, mode, adjusted_mode);
+ output->funcs->mode_set(output, &crtc->mode, adjusted_mode);
}
/* Only upload when needed, to avoid unneeded delays. */
@@ -383,8 +406,10 @@ done:
crtc->transformPresent = saved_transform_present;
}
- free(adjusted_mode->name);
- free(adjusted_mode);
+ if (adjusted_mode) {
+ free(adjusted_mode->name);
+ free(adjusted_mode);
+ }
if (didLock)
crtc->funcs->unlock (crtc);
@@ -393,35 +418,19 @@ done:
}
/**
- * Sets the given video mode on the given crtc, but without providing
- * a transform
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- int x, int y)
-{
- return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
-}
-
-/**
* Pans the screen, does not change the mode
*/
void
xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
{
- ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcSetRec set;
- crtc->x = x;
- crtc->y = y;
- if (crtc->funcs->set_origin) {
- if (!xf86CrtcRotate (crtc))
- return;
- crtc->funcs->set_origin (crtc, x, y);
- if (scrn->ModeSet)
- scrn->ModeSet(scrn);
+ if (x != crtc->x || y != crtc->y) {
+ set.x = x;
+ set.y = y;
+ set.flags = XF86CrtcSetOrigin;
+ (void) xf86CrtcSet(crtc, &set);
}
- else
- xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
}
/*
@@ -2617,6 +2626,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
for (c = 0; c < config->num_crtc; c++)
{
xf86OutputPtr output = NULL;
+ xf86CrtcSetRec set;
int o;
RRTransformPtr transform;
@@ -2660,8 +2670,15 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
transform = &crtc->desiredTransform;
else
transform = NULL;
- if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation,
- transform, crtc->desiredX, crtc->desiredY))
+ set.mode = &crtc->desiredMode;
+ set.rotation = crtc->desiredRotation;
+ set.transform = transform;
+ set.x = crtc->desiredX;
+ set.y = crtc->desiredY;
+ set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput |
+ XF86CrtcSetOrigin | XF86CrtcSetTransform |
+ XF86CrtcSetRotation);
+ if (!xf86CrtcSet(crtc, &set))
return FALSE;
}
@@ -2765,6 +2782,7 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
xf86CrtcPtr crtc = config->crtc[c];
DisplayModePtr crtc_mode = NULL;
int o;
+ xf86CrtcSetRec set;
if (!crtc->enabled)
continue;
@@ -2792,7 +2810,15 @@ xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
crtc->enabled = FALSE;
continue;
}
- if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
+ set.mode = crtc_mode;
+ set.rotation = rotation;
+ set.transform = NULL;
+ set.x = 0;
+ set.y = 0;
+ set.flags = (XF86CrtcSetMode | XF86CrtcSetOutput |
+ XF86CrtcSetOrigin | XF86CrtcSetTransform |
+ XF86CrtcSetRotation);
+ if (!xf86CrtcSet (crtc, &set))
ok = FALSE;
else
{
diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h
index 68a968c..f43e0a7 100644
--- a/hw/xfree86/modes/xf86Crtc.h
+++ b/hw/xfree86/modes/xf86Crtc.h
@@ -72,6 +72,23 @@ typedef enum _xf86OutputStatus {
XF86OutputStatusUnknown
} xf86OutputStatus;
+typedef enum _xf86CrtcSetFlags {
+ XF86CrtcSetMode = 1, /* mode */
+ XF86CrtcSetOutput = 2, /* outputs */
+ XF86CrtcSetOrigin = 4, /* x/y */
+ XF86CrtcSetTransform = 8, /* transform */
+ XF86CrtcSetRotation = 16, /* rotation */
+ XF86CrtcSetProperty = 32, /* output property */
+} xf86CrtcSetFlags;
+
+typedef struct _xf86CrtcSet {
+ xf86CrtcSetFlags flags;
+ DisplayModePtr mode;
+ Rotation rotation;
+ RRTransformPtr transform;
+ int x, y;
+} xf86CrtcSetRec;
+
typedef struct _xf86CrtcFuncs {
/**
* Turns the crtc on/off, or sets intermediate power levels if available.
@@ -221,6 +238,12 @@ typedef struct _xf86CrtcFuncs {
void
(*set_origin)(xf86CrtcPtr crtc, int x, int y);
+ /**
+ * General mode setting entry point that does everything
+ */
+ Bool
+ (*set)(xf86CrtcPtr crtc, xf86CrtcSetFlags flags);
+
} xf86CrtcFuncsRec, *xf86CrtcFuncsPtr;
#define XF86_CRTC_VERSION 3
@@ -738,18 +761,12 @@ xf86CrtcCreate (ScrnInfoPtr scrn,
extern _X_EXPORT void
xf86CrtcDestroy (xf86CrtcPtr crtc);
-
/**
- * Sets the given video mode on the given crtc
+ * Change a crtc configuration (modes, outputs, etc)
*/
extern _X_EXPORT Bool
-xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- RRTransformPtr transform, int x, int y);
-
-extern _X_EXPORT Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- int x, int y);
+xf86CrtcSet (xf86CrtcPtr crtc, xf86CrtcSetRec *set);
extern _X_EXPORT void
xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y);
diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 2fe0c47..d60ee3c 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -1133,7 +1133,7 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
xf86CrtcPtr crtc = randr_crtc->devPrivate;
RRTransformPtr transform;
- Bool changed = FALSE;
+ xf86CrtcSetFlags flags = 0;
int o, ro;
xf86CrtcPtr *save_crtcs;
Bool save_enabled = crtc->enabled;
@@ -1143,22 +1143,22 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
if ((randr_mode != NULL) != crtc->enabled)
- changed = TRUE;
+ flags |= XF86CrtcSetMode;
else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
- changed = TRUE;
+ flags |= XF86CrtcSetMode;
if (rotation != crtc->rotation)
- changed = TRUE;
+ flags |= XF86CrtcSetRotation;
transform = RRCrtcGetTransform (randr_crtc);
if ((transform != NULL) != crtc->transformPresent)
- changed = TRUE;
+ flags |= XF86CrtcSetTransform;
else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
sizeof (transform->transform)) != 0)
- changed = TRUE;
+ flags |= XF86CrtcSetTransform;
if (x != crtc->x || y != crtc->y)
- changed = TRUE;
+ flags |= XF86CrtcSetOrigin;
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
@@ -1178,16 +1178,16 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
}
if (new_crtc != output->crtc)
{
- changed = TRUE;
+ flags |= XF86CrtcSetOutput;
output->crtc = new_crtc;
}
}
for (ro = 0; ro < num_randr_outputs; ro++)
if (randr_outputs[ro]->pendingProperties)
- changed = TRUE;
+ flags |= XF86CrtcSetProperty;
/* XXX need device-independent mode setting code through an API */
- if (changed)
+ if (flags)
{
crtc->enabled = randr_mode != NULL;
@@ -1195,9 +1195,16 @@ xf86RandR12CrtcSet (ScreenPtr pScreen,
{
DisplayModeRec mode;
RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
+ xf86CrtcSetRec set;
xf86RandRModeConvert (pScrn, randr_mode, &mode);
- if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
+ set.mode = &mode;
+ set.rotation = rotation;
+ set.transform = transform;
+ set.x = x;
+ set.y = y;
+ set.flags = flags;
+ if (!xf86CrtcSet(crtc, &set))
{
crtc->enabled = save_enabled;
for (o = 0; o < config->num_output; o++)
More information about the xorg-commit
mailing list