diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-03-20 14:15:07 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2011-03-20 15:12:22 -0400 |
commit | b8b8754421f98cc6edc7993e5b65b9228102bcd1 (patch) | |
tree | 5962841442cfccf2c4c7a39e19a5118fd468535f | |
parent | ae165af1ad3fed9d6443f5733afecfb3b577a1aa (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.h | 3 | ||||
-rw-r--r-- | src/qxl_driver.c | 26 | ||||
-rw-r--r-- | src/uxa/uxa.c | 7 | ||||
-rw-r--r-- | src/uxa/uxa.h | 1 |
4 files changed, 34 insertions, 3 deletions
@@ -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 |