xserver: Branch 'master' - 4 commits

Adam Jackson ajax at kemper.freedesktop.org
Tue Sep 13 15:41:26 UTC 2016


 hw/xfree86/drivers/modesetting/dri2.c   |   84 +++++++++++++++++++++++---------
 hw/xfree86/drivers/modesetting/vblank.c |   38 +++++++++++++-
 2 files changed, 97 insertions(+), 25 deletions(-)

New commits:
commit d8e05c04758cbcd7b5c11362cb28ce017d50098b
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Aug 24 15:00:13 2016 +0200

    modesetting: Fall back to primary crtc for vblank for drawables on slave outputs
    
    This fixes glxgears running at 1 fps when fully covering a slave-output
    and the modesetting driver is used for the master gpu.
    
    Reported-by: Peter Wu <peter at lekensteyn.nl>
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 35924c3..04a8952 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -128,6 +128,32 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
             best_coverage = coverage;
         }
     }
+
+    /* Fallback to primary crtc for drawable's on slave outputs */
+    if (best_crtc == NULL && !pScreen->isGPU) {
+        RROutputPtr primary_output = NULL;
+        ScreenPtr slave;
+
+        if (dixPrivateKeyRegistered(rrPrivKey))
+            primary_output = RRFirstOutput(scrn->pScreen);
+        if (!primary_output || !primary_output->crtc)
+            return NULL;
+
+        crtc = primary_output->crtc->devPrivate;
+        if (!ms_crtc_on(crtc))
+            return NULL;
+
+        xorg_list_for_each_entry(slave, &pScreen->slave_list, slave_head) {
+            if (!slave->is_output_slave)
+                continue;
+
+            if (ms_covering_crtc(slave, box, FALSE)) {
+                /* The drawable is on a slave output, return primary crtc */
+                return crtc;
+            }
+        }
+    }
+
     return best_crtc;
 }
 
commit 7ade8ba10e1e767bb510343c86573bc5d4804b92
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Wed Aug 24 14:55:27 2016 +0200

    modesetting: ms_covering_crtc: Allow calling on non modesetting Screens
    
    99% of the code in ms_covering_crtc is video-driver agnostic. Add a
    screen_is_ms parameter when when FALSE skips the one ms specific check,
    this will allow calling ms_covering_crtc on slave GPUs.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/vblank.c b/hw/xfree86/drivers/modesetting/vblank.c
index 6547d9d..35924c3 100644
--- a/hw/xfree86/drivers/modesetting/vblank.c
+++ b/hw/xfree86/drivers/modesetting/vblank.c
@@ -96,7 +96,7 @@ ms_crtc_on(xf86CrtcPtr crtc)
  */
 
 static xf86CrtcPtr
-ms_covering_crtc(ScreenPtr pScreen, BoxPtr box)
+ms_covering_crtc(ScreenPtr pScreen, BoxPtr box, Bool screen_is_ms)
 {
     ScrnInfoPtr scrn = xf86ScreenToScrn(pScreen);
     xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -104,14 +104,20 @@ ms_covering_crtc(ScreenPtr pScreen, BoxPtr box)
     int coverage, best_coverage;
     int c;
     BoxRec crtc_box, cover_box;
+    Bool crtc_on;
 
     best_crtc = NULL;
     best_coverage = 0;
     for (c = 0; c < xf86_config->num_crtc; c++) {
         crtc = xf86_config->crtc[c];
 
+        if (screen_is_ms)
+            crtc_on = ms_crtc_on(crtc);
+        else
+            crtc_on = crtc->enabled;
+
         /* If the CRTC is off, treat it as not covering */
-        if (!ms_crtc_on(crtc))
+        if (!crtc_on)
             continue;
 
         ms_crtc_box(crtc, &crtc_box);
@@ -136,7 +142,7 @@ ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
     box.x2 = box.x1 + pDraw->width;
     box.y2 = box.y1 + pDraw->height;
 
-    return ms_covering_crtc(pScreen, &box);
+    return ms_covering_crtc(pScreen, &box, TRUE);
 }
 
 static Bool
commit 238248d67e6a422f31e8864c0b15d693a658cdac
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Aug 15 12:02:54 2016 +0200

    modesetting: Implement DRI2InfoRec version 9 callbacks
    
    Implement the CreateBuffer2 / DestroyBuffer2 / CopyRegion2 DRI2InfoRec
    version 9 callbacks, this is necessary for being an offload source
    provider with DRI2.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index 6ab6481..8944ef1 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -119,10 +119,9 @@ get_drawable_pixmap(DrawablePtr drawable)
 }
 
 static DRI2Buffer2Ptr
-ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
-                      unsigned int format)
+ms_dri2_create_buffer2(ScreenPtr screen, DrawablePtr drawable,
+                       unsigned int attachment, unsigned int format)
 {
-    ScreenPtr screen = drawable->pScreen;
     ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
     DRI2Buffer2Ptr buffer;
     PixmapPtr pixmap;
@@ -219,6 +218,14 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
     return buffer;
 }
 
+static DRI2Buffer2Ptr
+ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
+                      unsigned int format)
+{
+    return ms_dri2_create_buffer2(drawable->pScreen, drawable, attachment,
+                                  format);
+}
+
 static void
 ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
 {
@@ -228,7 +235,8 @@ ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
     }
 }
 
-static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
+static void ms_dri2_destroy_buffer2(ScreenPtr unused, DrawablePtr unused2,
+                                    DRI2Buffer2Ptr buffer)
 {
     if (!buffer)
         return;
@@ -246,28 +254,55 @@ static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
     }
 }
 
+static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
+{
+    ms_dri2_destroy_buffer2(NULL, drawable, buffer);
+}
+
 static void
-ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
-                    DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
+ms_dri2_copy_region2(ScreenPtr screen, DrawablePtr drawable, RegionPtr pRegion,
+                     DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
 {
     ms_dri2_buffer_private_ptr src_priv = sourceBuffer->driverPrivate;
     ms_dri2_buffer_private_ptr dst_priv = destBuffer->driverPrivate;
     PixmapPtr src_pixmap = src_priv->pixmap;
     PixmapPtr dst_pixmap = dst_priv->pixmap;
-    ScreenPtr screen = drawable->pScreen;
     DrawablePtr src = (sourceBuffer->attachment == DRI2BufferFrontLeft)
         ? drawable : &src_pixmap->drawable;
     DrawablePtr dst = (destBuffer->attachment == DRI2BufferFrontLeft)
         ? drawable : &dst_pixmap->drawable;
+    int off_x = 0, off_y = 0;
+    Bool translate = FALSE;
     RegionPtr pCopyClip;
     GCPtr gc;
 
+    if (destBuffer->attachment == DRI2BufferFrontLeft &&
+             drawable->pScreen != screen) {
+        dst = DRI2UpdatePrime(drawable, destBuffer);
+        if (!dst)
+            return;
+        if (dst != drawable)
+            translate = TRUE;
+    }
+
+    if (translate && drawable->type == DRAWABLE_WINDOW) {
+#ifdef COMPOSITE
+        PixmapPtr pixmap = get_drawable_pixmap(drawable);
+        off_x = -pixmap->screen_x;
+        off_y = -pixmap->screen_y;
+#endif
+        off_x += drawable->x;
+        off_y += drawable->y;
+    }
+
     gc = GetScratchGC(dst->depth, screen);
     if (!gc)
         return;
 
     pCopyClip = REGION_CREATE(screen, NULL, 0);
     REGION_COPY(screen, pCopyClip, pRegion);
+    if (translate)
+        REGION_TRANSLATE(screen, pCopyClip, off_x, off_y);
     (*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0);
     ValidateGC(dst, gc);
 
@@ -283,11 +318,19 @@ ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
     gc->ops->CopyArea(src, dst, gc,
                       0, 0,
                       drawable->width, drawable->height,
-                      0, 0);
+                      off_x, off_y);
 
     FreeScratchGC(gc);
 }
 
+static void
+ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
+                    DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
+{
+    ms_dri2_copy_region2(drawable->pScreen, drawable, pRegion, destBuffer,
+                         sourceBuffer);
+}
+
 static uint64_t
 gettime_us(void)
 {
@@ -1046,13 +1089,16 @@ ms_dri2_screen_init(ScreenPtr screen)
     info.driverName = NULL; /* Compat field, unused. */
     info.deviceName = drmGetDeviceNameFromFd(ms->fd);
 
-    info.version = 4;
+    info.version = 9;
     info.CreateBuffer = ms_dri2_create_buffer;
     info.DestroyBuffer = ms_dri2_destroy_buffer;
     info.CopyRegion = ms_dri2_copy_region;
     info.ScheduleSwap = ms_dri2_schedule_swap;
     info.GetMSC = ms_dri2_get_msc;
     info.ScheduleWaitMSC = ms_dri2_schedule_wait_msc;
+    info.CreateBuffer2 = ms_dri2_create_buffer2;
+    info.DestroyBuffer2 = ms_dri2_destroy_buffer2;
+    info.CopyRegion2 = ms_dri2_copy_region2;
 
     /* These two will be filled in by dri2.c */
     info.numDrivers = 0;
commit 03a7c50202f61030830ff639fccf52091e02156c
Author: Hans de Goede <hdegoede at redhat.com>
Date:   Mon Aug 15 10:44:57 2016 +0200

    modesetting: ms_dri2_create_buffer: check screen of existing front buffers
    
    If a frontbuffer drawable already has a pixmap, make sure it was created
    on the right screen.
    
    Reviewed-by: Adam Jackson <ajax at redhat.com>
    Signed-off-by: Hans de Goede <hdegoede at redhat.com>

diff --git a/hw/xfree86/drivers/modesetting/dri2.c b/hw/xfree86/drivers/modesetting/dri2.c
index cbef2e6..6ab6481 100644
--- a/hw/xfree86/drivers/modesetting/dri2.c
+++ b/hw/xfree86/drivers/modesetting/dri2.c
@@ -118,17 +118,6 @@ get_drawable_pixmap(DrawablePtr drawable)
         return screen->GetWindowPixmap((WindowPtr) drawable);
 }
 
-static PixmapPtr
-get_front_buffer(DrawablePtr drawable)
-{
-    PixmapPtr pixmap;
-
-    pixmap = get_drawable_pixmap(drawable);
-    pixmap->refcnt++;
-
-    return pixmap;
-}
-
 static DRI2Buffer2Ptr
 ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
                       unsigned int format)
@@ -152,8 +141,13 @@ ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
     }
 
     pixmap = NULL;
-    if (attachment == DRI2BufferFrontLeft)
-        pixmap = get_front_buffer(drawable);
+    if (attachment == DRI2BufferFrontLeft) {
+        pixmap = get_drawable_pixmap(drawable);
+        if (pixmap && pixmap->drawable.pScreen != screen)
+            pixmap = NULL;
+        if (pixmap)
+            pixmap->refcnt++;
+    }
 
     if (pixmap == NULL) {
         int pixmap_width = drawable->width;


More information about the xorg-commit mailing list