[PATCH] randr: attempt to fix primary on slave output (v2)
Dave Airlie
airlied at gmail.com
Mon Jan 26 13:20:27 PST 2015
Please merge this,
Thanks.
On 7 January 2015 at 09:19, Dave Airlie <airlied at gmail.com> wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> If the user wants to set one of the slave devices as
> the primary output, we shouldn't fail to do so,
> we were returning BadMatch which was tripping up
> gnome-settings-daemon and bad things ensues.
>
> Fix all the places we use primaryOutput to work
> out primaryCrtc and take it into a/c when slave
> gpus are in use.
>
> v2: review from Aaron, fix indent, unhide has_primary from
> macro. I left the int vs Bool alone to be consistent with
> code below, a future patch could fix both.
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
> Reviewed-by: Aaron Plattner <aplattner at nvidia.com>
> ---
> randr/rroutput.c | 6 +++++-
> randr/rrscreen.c | 22 ++++++++++++++++++----
> randr/rrxinerama.c | 12 ++++++++++--
> 3 files changed, 33 insertions(+), 7 deletions(-)
>
> diff --git a/randr/rroutput.c b/randr/rroutput.c
> index f824f50..1649309 100644
> --- a/randr/rroutput.c
> +++ b/randr/rroutput.c
> @@ -540,7 +540,11 @@ ProcRRSetOutputPrimary(ClientPtr client)
> if (stuff->output) {
> VERIFY_RR_OUTPUT(stuff->output, output, DixReadAccess);
>
> - if (output->pScreen != pWin->drawable.pScreen) {
> + if (!output->pScreen->isGPU && output->pScreen != pWin->drawable.pScreen) {
> + client->errorValue = stuff->window;
> + return BadMatch;
> + }
> + if (output->pScreen->isGPU && output->pScreen->current_master != pWin->drawable.pScreen) {
> client->errorValue = stuff->window;
> return BadMatch;
> }
> diff --git a/randr/rrscreen.c b/randr/rrscreen.c
> index 36179ae..e7ea49d 100644
> --- a/randr/rrscreen.c
> +++ b/randr/rrscreen.c
> @@ -322,8 +322,13 @@ static inline void swap_modeinfos(xRRModeInfo *modeinfos, int i)
> swapl(&modeinfos[i].modeFlags);
> }
>
> -#define update_arrays(gpuscreen, pScrPriv) do { \
> +#define update_arrays(gpuscreen, pScrPriv, primary_crtc, has_primary) do { \
> for (j = 0; j < pScrPriv->numCrtcs; j++) { \
> + if (has_primary && \
> + primary_crtc == pScrPriv->crtcs[j]) { \
> + has_primary = 0; \
> + continue; \
> + }\
> crtcs[crtc_count] = pScrPriv->crtcs[j]->id; \
> if (client->swapped) \
> swapl(&crtcs[crtc_count]); \
> @@ -366,9 +371,11 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
> unsigned long extraLen;
> CARD8 *extra;
> RRCrtc *crtcs;
> + RRCrtcPtr primary_crtc = NULL;
> RROutput *outputs;
> xRRModeInfo *modeinfos;
> CARD8 *names;
> + int has_primary = 0;
>
> /* we need to iterate all the GPU masters and all their output slaves */
> total_crtcs = 0;
> @@ -426,18 +433,25 @@ rrGetMultiScreenResources(ClientPtr client, Bool query, ScreenPtr pScreen)
> modeinfos = (xRRModeInfo *)(outputs + total_outputs);
> names = (CARD8 *)(modeinfos + total_modes);
>
> - /* TODO primary */
> crtc_count = 0;
> output_count = 0;
> mode_count = 0;
>
> pScrPriv = rrGetScrPriv(pScreen);
> - update_arrays(pScreen, pScrPriv);
> + if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
> + has_primary = 1;
> + primary_crtc = pScrPriv->primaryOutput->crtc;
> + crtcs[0] = pScrPriv->primaryOutput->crtc->id;
> + if (client->swapped)
> + swapl(&crtcs[0]);
> + crtc_count = 1;
> + }
> + update_arrays(pScreen, pScrPriv, primary_crtc, has_primary);
>
> xorg_list_for_each_entry(iter, &pScreen->output_slave_list, output_head) {
> pScrPriv = rrGetScrPriv(iter);
>
> - update_arrays(iter, pScrPriv);
> + update_arrays(iter, pScrPriv, primary_crtc, has_primary);
> }
>
> assert(bytes_to_int32((char *) names - (char *) extra) == rep.length);
> diff --git a/randr/rrxinerama.c b/randr/rrxinerama.c
> index 26894a6..b336bd7 100644
> --- a/randr/rrxinerama.c
> +++ b/randr/rrxinerama.c
> @@ -344,15 +344,17 @@ ProcRRXineramaQueryScreens(ClientPtr client)
> ScreenPtr slave;
> rrScrPriv(pScreen);
> int has_primary = 0;
> + RRCrtcPtr primary_crtc = NULL;
>
> if (pScrPriv->primaryOutput && pScrPriv->primaryOutput->crtc) {
> has_primary = 1;
> + primary_crtc = pScrPriv->primaryOutput->crtc;
> RRXineramaWriteCrtc(client, pScrPriv->primaryOutput->crtc);
> }
>
> for (i = 0; i < pScrPriv->numCrtcs; i++) {
> if (has_primary &&
> - pScrPriv->primaryOutput->crtc == pScrPriv->crtcs[i]) {
> + primary_crtc == pScrPriv->crtcs[i]) {
> has_primary = 0;
> continue;
> }
> @@ -362,8 +364,14 @@ ProcRRXineramaQueryScreens(ClientPtr client)
> xorg_list_for_each_entry(slave, &pScreen->output_slave_list, output_head) {
> rrScrPrivPtr pSlavePriv;
> pSlavePriv = rrGetScrPriv(slave);
> - for (i = 0; i < pSlavePriv->numCrtcs; i++)
> + for (i = 0; i < pSlavePriv->numCrtcs; i++) {
> + if (has_primary &&
> + primary_crtc == pSlavePriv->crtcs[i]) {
> + has_primary = 0;
> + continue;
> + }
> RRXineramaWriteCrtc(client, pSlavePriv->crtcs[i]);
> + }
> }
> }
>
> --
> 1.9.3
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
More information about the xorg-devel
mailing list