diff options
author | Dave Airlie <airlied@redhat.com> | 2016-05-03 06:54:56 +1000 |
---|---|---|
committer | Adam Jackson <ajax@redhat.com> | 2016-05-02 18:21:10 -0400 |
commit | caabc4e85540dcd4225f2780b5616f7d870fbb06 (patch) | |
tree | 33f17d4c28be36372d8c586ae141b632abb83b49 | |
parent | c33250945b45adc447154239f0cf48fb9b2d7335 (diff) |
modesetting: add support for background none.
This adds support using glamor for background None.
loosely based off the amdgpu code. relies on the glamor_finish code.
Acked-by: Eric Anholt <eric@anholt.net>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.c | 24 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/driver.h | 2 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.c | 102 | ||||
-rw-r--r-- | hw/xfree86/drivers/modesetting/drmmode_display.h | 4 |
4 files changed, 106 insertions, 26 deletions
diff --git a/hw/xfree86/drivers/modesetting/driver.c b/hw/xfree86/drivers/modesetting/driver.c index 8f60eae57..6c4bac3fa 100644 --- a/hw/xfree86/drivers/modesetting/driver.c +++ b/hw/xfree86/drivers/modesetting/driver.c @@ -1098,6 +1098,25 @@ SetMaster(ScrnInfoPtr pScrn) return ret == 0; } +/* When the root window is created, initialize the screen contents from + * console if -background none was specified on the command line + */ +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) { @@ -1206,6 +1225,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 5e1c5d988..3a604497a 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 262e01507..e0d624f60 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 fca68a6fe..a648d89c5 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 |