[PATCH] modesetting: add support for background none.

Dave Airlie airlied at gmail.com
Wed Feb 10 05:45:24 UTC 2016


From: Dave Airlie <airlied at redhat.com>

This adds support using glamor for background None.

loosely based off the amdgpu code. relies on the
glamor_finish code.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 hw/xfree86/drivers/modesetting/driver.c          |  21 +++++
 hw/xfree86/drivers/modesetting/driver.h          |   2 +-
 hw/xfree86/drivers/modesetting/drmmode_display.c | 102 +++++++++++++++++------
 hw/xfree86/drivers/modesetting/drmmode_display.h |   4 +-
 4 files changed, 103 insertions(+), 26 deletions(-)

diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c
index 8f60eae..3895aca 100644
--- a/hw/xfree86/drivers/modesetting/driver.c
+++ b/hw/xfree86/drivers/modesetting/driver.c
@@ -1099,6 +1099,22 @@ SetMaster(ScrnInfoPtr pScrn)
 }
 
 static Bool
+CreateWindow_oneshot(WindowPtr pWin)
+{
+    ScreenPtr pScreen = pWin->drawable.pScreen;
+    ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+    modesettingPtr ms = modesettingPTR(pScrn);
+    Bool ret;
+
+    pScreen->CreateWindow = ms->CreateWindow;
+    ret = pScreen->CreateWindow(pWin);
+
+    if (ret)
+        drmmode_copy_fb(pScrn, &ms->drmmode);
+    return ret;
+}
+
+static Bool
 ScreenInit(ScreenPtr pScreen, int argc, char **argv)
 {
     ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
@@ -1206,6 +1222,11 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
      * later memory should be bound when allocating, e.g rotate_mem */
     pScrn->vtSema = TRUE;
 
+    if (serverGeneration == 1 && bgNoneRoot && ms->drmmode.glamor) {
+        ms->CreateWindow = pScreen->CreateWindow;
+        pScreen->CreateWindow = CreateWindow_oneshot;
+    }
+
     pScreen->SaveScreen = xf86SaveScreen;
     ms->CloseScreen = pScreen->CloseScreen;
     pScreen->CloseScreen = CloseScreen;
diff --git a/hw/xfree86/drivers/modesetting/driver.h b/hw/xfree86/drivers/modesetting/driver.h
index 5e1c5d9..3a60449 100644
--- a/hw/xfree86/drivers/modesetting/driver.h
+++ b/hw/xfree86/drivers/modesetting/driver.h
@@ -97,7 +97,7 @@ typedef struct _modesettingRec {
 
     Bool noAccel;
     CloseScreenProcPtr CloseScreen;
-
+    CreateWindowProcPtr CreateWindow;
     unsigned int SaveGeneration;
 
     CreateScreenResourcesProcPtr createScreenResources;
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.c b/hw/xfree86/drivers/modesetting/drmmode_display.c
index 0d34ca1..f0e36fa 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.c
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.c
@@ -51,7 +51,9 @@
 #include "driver.h"
 
 static Bool drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height);
-
+static PixmapPtr drmmode_create_pixmap_header(ScreenPtr pScreen, int width, int height,
+                                              int depth, int bitsPerPixel, int devKind,
+                                              void *pPixData);
 static Bool
 drmmode_zaphod_string_matches(ScrnInfoPtr scrn, const char *s, char *output_name)
 {
@@ -285,49 +287,101 @@ drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
     drmmode_crtc->dpms_mode = mode;
 }
 
-#if 0
 static PixmapPtr
-create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int crtc_id)
+create_pixmap_for_fbcon(drmmode_ptr drmmode, ScrnInfoPtr pScrn, int fbcon_id)
 {
-    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
-    drmmode_crtc_private_ptr drmmode_crtc;
-    ScreenPtr pScreen = pScrn->pScreen;
-    PixmapPtr pixmap;
-    struct radeon_bo *bo;
+    PixmapPtr pixmap = drmmode->fbcon_pixmap;
     drmModeFBPtr fbcon;
     struct drm_gem_flink flink;
+    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+    Bool ret;
 
-    drmmode_crtc = xf86_config->crtc[crtc_id]->driver_private;
+    if (pixmap)
+        return pixmap;
 
-    fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id);
+    fbcon = drmModeGetFB(drmmode->fd, fbcon_id);
     if (fbcon == NULL)
         return NULL;
 
+    if (fbcon->depth != pScrn->depth ||
+        fbcon->width != pScrn->virtualX ||
+        fbcon->height != pScrn->virtualY)
+        goto out_free_fb;
+
     flink.handle = fbcon->handle;
     if (ioctl(drmmode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
         xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Couldn't flink fbcon handle\n");
-        return NULL;
-    }
-
-    bo = radeon_bo_open(drmmode->bufmgr, flink.name, 0, 0, 0, 0);
-    if (bo == NULL) {
-        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
-                   "Couldn't allocate bo for fbcon handle\n");
-        return NULL;
+        goto out_free_fb;
     }
 
-    pixmap = drmmode_create_bo_pixmap(pScreen, fbcon->width, fbcon->height,
-                                      fbcon->depth, fbcon->bpp,
-                                      fbcon->pitch, bo);
+    pixmap = drmmode_create_pixmap_header(pScreen, fbcon->width,
+                                          fbcon->height, fbcon->depth,
+                                          fbcon->bpp, fbcon->pitch, NULL);
     if (!pixmap)
-        return NULL;
+        goto out_free_fb;
+
+    ret = glamor_egl_create_textured_pixmap(pixmap, fbcon->handle, fbcon->pitch);
+    if (!ret) {
+      FreePixmap(pixmap);
+      pixmap = NULL;
+    }
 
-    radeon_bo_unref(bo);
+    drmmode->fbcon_pixmap = pixmap;
+out_free_fb:
     drmModeFreeFB(fbcon);
     return pixmap;
 }
 
-#endif
+void
+drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode)
+{
+    xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+    ScreenPtr pScreen = xf86ScrnToScreen(pScrn);
+    PixmapPtr src, dst;
+    int fbcon_id = 0;
+    GCPtr gc;
+    int i;
+
+    for (i = 0; i < xf86_config->num_crtc; i++) {
+        drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[i]->driver_private;
+        if (drmmode_crtc->mode_crtc->buffer_id)
+            fbcon_id = drmmode_crtc->mode_crtc->buffer_id;
+    }
+
+    if (!fbcon_id)
+        return;
+
+    if (fbcon_id == drmmode->fb_id) {
+        /* in some rare case there might be no fbcon and we might already
+         * be the one with the current fb to avoid a false deadlck in
+         * kernel ttm code just do nothing as anyway there is nothing
+         * to do
+         */
+        return;
+    }
+
+    src = create_pixmap_for_fbcon(drmmode, pScrn, fbcon_id);
+    if (!src)
+        return;
+
+    dst = pScreen->GetScreenPixmap(pScreen);
+
+    gc = GetScratchGC(pScrn->depth, pScreen);
+    ValidateGC(&dst->drawable, gc);
+
+    (*gc->ops->CopyArea)(&src->drawable, &dst->drawable, gc, 0, 0,
+                         pScrn->virtualX, pScrn->virtualY, 0, 0);
+
+    FreeScratchGC(gc);
+
+    glamor_finish(pScreen);
+
+    pScreen->canDoBGNoneRoot = TRUE;
+
+    if (drmmode->fbcon_pixmap)
+        pScrn->pScreen->DestroyPixmap(drmmode->fbcon_pixmap);
+    drmmode->fbcon_pixmap = NULL;
+}
 
 static Bool
 drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
diff --git a/hw/xfree86/drivers/modesetting/drmmode_display.h b/hw/xfree86/drivers/modesetting/drmmode_display.h
index fca68a6..a648d89 100644
--- a/hw/xfree86/drivers/modesetting/drmmode_display.h
+++ b/hw/xfree86/drivers/modesetting/drmmode_display.h
@@ -87,6 +87,8 @@ typedef struct {
     Bool reverse_prime_offload_mode;
 
     Bool is_secondary;
+
+    PixmapPtr fbcon_pixmap;
 } drmmode_rec, *drmmode_ptr;
 
 typedef struct {
@@ -174,7 +176,7 @@ void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
                              int *depth, int *bpp);
 
-
+void drmmode_copy_fb(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
 #ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
 #define DRM_CAP_DUMB_PREFERRED_DEPTH 3
 #endif
-- 
2.5.0



More information about the xorg-devel mailing list