[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