summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-05-03 06:54:56 +1000
committerAdam Jackson <ajax@redhat.com>2016-05-02 18:21:10 -0400
commitcaabc4e85540dcd4225f2780b5616f7d870fbb06 (patch)
tree33f17d4c28be36372d8c586ae141b632abb83b49
parentc33250945b45adc447154239f0cf48fb9b2d7335 (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.c24
-rw-r--r--hw/xfree86/drivers/modesetting/driver.h2
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.c102
-rw-r--r--hw/xfree86/drivers/modesetting/drmmode_display.h4
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