From e65e1eeb74775ab98b9e8912e35fc7ad1af1ffb2 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Kristian=20H=C3=B8gsberg?= Date: Tue, 24 Feb 2009 10:49:45 -0500 Subject: [PATCH 2/2] Copy initial framebuffer contents when starting with -br. --- src/drmmode_display.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++- src/i830.h | 1 + src/i830_driver.c | 2 + 3 files changed, 89 insertions(+), 1 deletions(-) diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 5b48bda..527b293 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -29,6 +29,8 @@ #include "config.h" #endif +#include + #include "xorgVersion.h" #ifdef XF86DRM_MODE @@ -145,7 +147,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, unsigned int pitch = pScrn->displayWidth * pI830->cpp; if (drmmode->fb_id == 0) { - ret = drmModeAddFB(drmmode->fd, + ret = drmModeAddFB(drmmode->fd, pScrn->virtualX, pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel, pitch, pI830->front_buffer->bo->handle, @@ -733,6 +735,8 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp) xf86InitialConfiguration(pScrn, pI830->can_resize); + pScrn->canDoBGNoneRoot = TRUE; + return TRUE; } @@ -760,4 +764,85 @@ Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo) #endif } +static PixmapPtr +drmmode_create_pixmap_for_fbcon(ScrnInfoPtr pScrn) +{ + xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn); + drmmode_crtc_private_ptr + /* FIXME: Find currently active crtc */ + drmmode_crtc = xf86_config->crtc[1]->driver_private; + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + drmmode_ptr drmmode = drmmode_crtc->drmmode; + I830Ptr pI830 = I830PTR(pScrn); + drmModeFBPtr fbcon; + struct drm_gem_flink flink; + drm_intel_bo *bo; + PixmapPtr pixmap = NULL; + + fbcon = drmModeGetFB(drmmode->fd, drmmode_crtc->mode_crtc->buffer_id); + if (fbcon == NULL) + return NULL; + + 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 = drm_intel_bo_gem_create_from_name(pI830->bufmgr, + "fbcon", flink.name); + if (bo == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate bo for fbcon handle\n"); + return NULL; + } + + pixmap = GetScratchPixmapHeader(pScreen, + fbcon->width, fbcon->height, + fbcon->depth, fbcon->bpp, + fbcon->pitch, NULL); + if (pixmap == NULL) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Couldn't allocate pixmap fbcon contents\n"); + return NULL; + } + + i830_set_pixmap_bo(pixmap, bo); + drm_intel_bo_unreference(bo); + drmModeFreeFB(fbcon); + + return pixmap; +} +void drmmode_copy_fb(ScrnInfoPtr pScrn) +{ + ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex]; + I830Ptr pI830 = I830PTR(pScrn); + PixmapPtr src, dst; + unsigned int pitch = pScrn->displayWidth * pI830->cpp; + + src = drmmode_create_pixmap_for_fbcon(pScrn); + + /* We dont have a screen Pixmap yet */ + dst = GetScratchPixmapHeader(pScreen, + pScrn->virtualX, pScrn->virtualY, + pScrn->depth, pScrn->bitsPerPixel, + pitch, + NULL); + i830_set_pixmap_bo(dst, pI830->front_buffer->bo); + + pI830->uxa_driver->prepare_copy(src, dst, -1, -1, GXcopy, FB_ALLONES); + + pI830->uxa_driver->copy(dst, 0, 0, 0, 0, + pScrn->virtualX, pScrn->virtualY); + + pI830->uxa_driver->done_copy(dst); + + I830EmitFlush(pScrn); + intel_batch_flush(pScrn, TRUE); + + (*pScreen->DestroyPixmap)(src); + (*pScreen->DestroyPixmap)(dst); +} + #endif diff --git a/src/i830.h b/src/i830.h index 7904b9f..74b04e9 100644 --- a/src/i830.h +++ b/src/i830.h @@ -832,6 +832,7 @@ void I830DRI2CloseScreen(ScreenPtr pScreen); extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp); extern Bool drmmode_is_rotate_pixmap(ScrnInfoPtr pScrn, pointer pPixData, dri_bo **bo); +extern void drmmode_copy_fb(ScrnInfoPtr pScrn); #endif extern Bool I830AccelInit(ScreenPtr pScreen); diff --git a/src/i830_driver.c b/src/i830_driver.c index 0a8a9c6..8aa33b6 100644 --- a/src/i830_driver.c +++ b/src/i830_driver.c @@ -3690,6 +3690,8 @@ I830EnterVT(int scrnIndex, int flags) /* Clear the framebuffer */ memset(pI830->FbBase + pScrn->fbOffset, 0, pScrn->virtualY * pScrn->displayWidth * pI830->cpp); + } else { + drmmode_copy_fb(pScrn); } if (!xf86SetDesiredModes (pScrn)) -- 1.6.1.3