summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSøren Sandmann Pedersen <ssp@redhat.com>2011-03-20 14:15:07 -0400
committerSøren Sandmann Pedersen <ssp@redhat.com>2011-03-20 15:12:22 -0400
commitb8b8754421f98cc6edc7993e5b65b9228102bcd1 (patch)
tree5962841442cfccf2c4c7a39e19a5118fd468535f
parentae165af1ad3fed9d6443f5733afecfb3b577a1aa (diff)
Fix VT switching
- Surfaces need to be evacuated before switching VT - The device must be reset - Framebuffer access must be turned off - Pixmaps created while switched away must be created in host memory.
-rw-r--r--src/qxl.h3
-rw-r--r--src/qxl_driver.c26
-rw-r--r--src/uxa/uxa.c7
-rw-r--r--src/uxa/uxa.h1
4 files changed, 34 insertions, 3 deletions
diff --git a/src/qxl.h b/src/qxl.h
index 1c79ec8..60a1046 100644
--- a/src/qxl.h
+++ b/src/qxl.h
@@ -153,6 +153,9 @@ struct _qxl_screen_t
uint8_t vram_mem_slot;
surface_cache_t * surface_cache;
+
+ /* Evacuated surfaces are stored here during VT switches */
+ void * vt_surfaces;
};
static inline uint64_t
diff --git a/src/qxl_driver.c b/src/qxl_driver.c
index d174d05..b8f2812 100644
--- a/src/qxl_driver.c
+++ b/src/qxl_driver.c
@@ -678,6 +678,9 @@ qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
#if 0
ErrorF ("Create pixmap: %d %d @ %d (usage: %d)\n", w, h, depth, usage);
#endif
+
+ if (uxa_swapped_out (screen))
+ goto fallback;
surface = qxl_surface_create (qxl->surface_cache, w, h, depth);
@@ -705,13 +708,13 @@ qxl_create_pixmap (ScreenPtr screen, int w, int h, int depth, unsigned usage)
ErrorF (" Couldn't allocate %d x %d @ %d surface in video memory\n",
w, h, depth);
#endif
-
+ fallback:
pixmap = fbCreatePixmap (screen, w, h, depth, usage);
#if 0
ErrorF ("Create pixmap %p without surface\n", pixmap);
#endif
-}
+ }
return pixmap;
}
@@ -961,10 +964,20 @@ static Bool
qxl_enter_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+
qxl_save_state(pScrn);
qxl_switch_mode(scrnIndex, pScrn->currentMode, 0);
+ if (qxl->vt_surfaces)
+ {
+ qxl_surface_cache_replace_all (qxl->surface_cache, qxl->vt_surfaces);
+
+ qxl->vt_surfaces = NULL;
+ }
+
+ pScrn->EnableDisableFBAccess (scrnIndex, TRUE);
+
return TRUE;
}
@@ -972,7 +985,14 @@ static void
qxl_leave_vt(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ qxl_screen_t *qxl = pScrn->driverPrivate;
+ pScrn->EnableDisableFBAccess (scrnIndex, FALSE);
+
+ qxl->vt_surfaces = qxl_surface_cache_evacuate_all (qxl->surface_cache);
+
+ outb(qxl->io_base + QXL_IO_RESET, 0);
+
qxl_restore_state(pScrn);
}
diff --git a/src/uxa/uxa.c b/src/uxa/uxa.c
index 71609fa..83e06cc 100644
--- a/src/uxa/uxa.c
+++ b/src/uxa/uxa.c
@@ -391,6 +391,13 @@ void uxa_set_force_fallback(ScreenPtr screen, Bool value)
uxa_screen->force_fallback = value;
}
+Bool uxa_swapped_out(ScreenPtr screen)
+{
+ uxa_screen_t *uxa_screen = uxa_get_screen (screen);
+
+ return uxa_screen->swappedOut;
+}
+
/**
* uxa_close_screen() unwraps its wrapped screen functions and tears down UXA's
* screen private, before calling down to the next CloseSccreen.
diff --git a/src/uxa/uxa.h b/src/uxa/uxa.h
index 379d384..2eb4041 100644
--- a/src/uxa/uxa.h
+++ b/src/uxa/uxa.h
@@ -572,6 +572,7 @@ uxa_get_color_for_pixmap (PixmapPtr pixmap,
void uxa_set_fallback_debug(ScreenPtr screen, Bool enable);
void uxa_set_force_fallback(ScreenPtr screen, Bool enable);
+Bool uxa_swapped_out (ScreenPtr screen);
/**
* Returns TRUE if the given planemask covers all the significant bits in the