From: Dave Airlie <airl...@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 <airl...@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 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel