diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-13 09:34:53 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-07-13 10:09:38 +0100 |
commit | 5de1b74d64f807b59c730871d4cb171484db9780 (patch) | |
tree | 39a4eca409890b339b75d817a16957683f3d0137 | |
parent | 3a7c25ff8ddd45c9d9eca5cc2228552847ca9e7d (diff) |
modes: There may be more than one crtc and output... DESTROY THEM ALL!
In order to cleanup all CRTCs and outputs on shutdown, we need to keep a
list of the individual structures and iterate over that list on
shutdown.
Also, the output and crtcs are configured just once and not for each
screen generation so move the shutdown to the termination and not on
CloseScreen. Oops.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
-rw-r--r-- | src/drmmode_display.c | 80 | ||||
-rw-r--r-- | src/intel.h | 8 | ||||
-rw-r--r-- | src/intel_driver.c | 58 |
3 files changed, 81 insertions, 65 deletions
diff --git a/src/drmmode_display.c b/src/drmmode_display.c index 37463ffa..e892dff9 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -48,11 +48,14 @@ typedef struct { uint32_t fb_id; drmModeResPtr mode_res; int cpp; - + drmEventContext event_context; void *event_data; int old_fb_id; int flip_count; + + struct list outputs; + struct list crtcs; } drmmode_rec, *drmmode_ptr; typedef struct { @@ -63,6 +66,8 @@ typedef struct { dri_bo *rotate_bo; uint32_t rotate_pitch; uint32_t rotate_fb_id; + xf86CrtcPtr crtc; + struct list link; } drmmode_crtc_private_rec, *drmmode_crtc_private_ptr; typedef struct { @@ -89,6 +94,8 @@ typedef struct { char *backlight_iface; int backlight_active_level; int backlight_max; + xf86OutputPtr output; + struct list link; } drmmode_output_private_rec, *drmmode_output_private_ptr; static void @@ -603,6 +610,11 @@ drmmode_crtc_destroy(xf86CrtcPtr crtc) drm_intel_bo_unreference(drmmode_crtc->cursor); drmmode_crtc->cursor = NULL; + + list_del(&drmmode_crtc->link); + free(drmmode_crtc); + + crtc->driver_private = NULL; } static const xf86CrtcFuncsRec drmmode_crtc_funcs = { @@ -643,7 +655,8 @@ drmmode_crtc_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) GTT_PAGE_SIZE); drm_intel_bo_disable_reuse(drmmode_crtc->cursor); - intel->crtc = crtc; + drmmode_crtc->crtc = crtc; + list_add(&drmmode_crtc->link, &drmmode->crtcs); } static xf86OutputStatus @@ -838,7 +851,10 @@ drmmode_output_destroy(xf86OutputPtr output) } if (drmmode_output->backlight_iface) drmmode_backlight_set(output, drmmode_output->backlight_active_level); + + list_del(&drmmode_output->link); free(drmmode_output); + output->driver_private = NULL; } @@ -1194,7 +1210,6 @@ static const char *output_names[] = { "None", static void drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) { - intel_screen_private *intel = intel_get_screen_private(scrn); xf86OutputPtr output; drmModeConnectorPtr koutput; drmModeEncoderPtr kencoder; @@ -1258,7 +1273,8 @@ drmmode_output_init(ScrnInfoPtr scrn, drmmode_ptr drmmode, int num) output->possible_crtcs = kencoder->possible_crtcs; output->possible_clones = kencoder->possible_clones; - intel->output = output; + drmmode_output->output = output; + list_add(&drmmode_output->link, &drmmode->outputs); } static Bool @@ -1448,6 +1464,9 @@ Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) drmmode->fd = fd; drmmode->fb_id = 0; + list_init(&drmmode->crtcs); + list_init(&drmmode->outputs); + xf86CrtcConfigInit(scrn, &drmmode_xf86crtc_config_funcs); drmmode->cpp = cpp; @@ -1486,21 +1505,45 @@ Bool drmmode_pre_init(ScrnInfoPtr scrn, int fd, int cpp) drm_wakeup_handler, drmmode); } + intel->modes = drmmode; return TRUE; } void -drmmode_close_screen(intel_screen_private *intel) +drmmode_remove_fb(intel_screen_private *intel) +{ + drmmode_ptr drmmode = intel->modes; + + if (drmmode->fb_id) { + drmModeRmFB(drmmode->fd, drmmode->fb_id); + drmmode->fb_id = 0; + } +} + +void +drmmode_fini(intel_screen_private *intel) { - if (intel->crtc) { - xf86CrtcDestroy(intel->crtc); - intel->crtc = NULL; + drmmode_ptr drmmode = intel->modes; + + while(!list_is_empty(&drmmode->crtcs)) { + xf86CrtcDestroy(list_first_entry(&drmmode->crtcs, + drmmode_crtc_private_rec, + link)->crtc); } - if (intel->output) { - xf86OutputDestroy(intel->output); - intel->output = NULL; + while(!list_is_empty(&drmmode->outputs)) { + xf86OutputDestroy(list_first_entry(&drmmode->outputs, + drmmode_output_private_rec, + link)->output); } + + if (drmmode->fb_id) + drmModeRmFB(drmmode->fd, drmmode->fb_id); + + /* drmmode->rotate_fb_id should have been destroyed already */ + + free(drmmode); + intel->modes = NULL; } int @@ -1519,18 +1562,3 @@ drmmode_crtc_id(xf86CrtcPtr crtc) return drmmode_crtc->mode_crtc->crtc_id; } - -void drmmode_closefb(ScrnInfoPtr scrn) -{ - xf86CrtcConfigPtr xf86_config; - drmmode_crtc_private_ptr drmmode_crtc; - drmmode_ptr drmmode; - - xf86_config = XF86_CRTC_CONFIG_PTR(scrn); - - drmmode_crtc = xf86_config->crtc[0]->driver_private; - drmmode = drmmode_crtc->drmmode; - - drmModeRmFB(drmmode->fd, drmmode->fb_id); - drmmode->fb_id = 0; -} diff --git a/src/intel.h b/src/intel.h index 5342dca1..2f43b0e9 100644 --- a/src/intel.h +++ b/src/intel.h @@ -132,7 +132,7 @@ list_is_empty(struct list *head) #ifndef container_of #define container_of(ptr, type, member) \ - (type *)((char *)(ptr) - (char *) &((type *)0)->member) + ((type *)((char *)(ptr) - (char *) &((type *)0)->member)) #endif #ifndef list_entry @@ -278,8 +278,7 @@ typedef struct intel_screen_private { long FbMapSize; long GTTMapSize; - xf86OutputPtr output; - xf86CrtcPtr crtc; + void *modes; drm_intel_bo *front_buffer; dri_bufmgr *bufmgr; @@ -438,7 +437,8 @@ enum { }; extern Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp); -extern void drmmode_close_screen(intel_screen_private *intel); +extern void drmmode_remove_fb(intel_screen_private *intel); +extern void drmmode_fini(intel_screen_private *intel); extern int drmmode_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc); extern int drmmode_output_dpms_status(xf86OutputPtr output); extern Bool drmmode_do_pageflip(ScreenPtr screen, dri_bo *new_front, void *data); diff --git a/src/intel_driver.c b/src/intel_driver.c index 2ced844f..c02b0040 100644 --- a/src/intel_driver.c +++ b/src/intel_driver.c @@ -157,26 +157,6 @@ const OptionInfoRec *intel_uxa_available_options(int chipid, int busid) return I830Options; } -static Bool I830GetRec(ScrnInfoPtr scrn) -{ - if (scrn->driverPrivate) - return TRUE; - scrn->driverPrivate = xnfcalloc(sizeof(intel_screen_private), 1); - - return TRUE; -} - -static void I830FreeRec(ScrnInfoPtr scrn) -{ - if (!scrn) - return; - if (!scrn->driverPrivate) - return; - - free(scrn->driverPrivate); - scrn->driverPrivate = NULL; -} - static void I830LoadPalette(ScrnInfoPtr scrn, int numColors, int *indices, LOCO * colors, VisualPtr pVisual) @@ -273,7 +253,11 @@ static Bool i830CreateScreenResources(ScreenPtr screen) static void PreInitCleanup(ScrnInfoPtr scrn) { - I830FreeRec(scrn); + if (!scrn || !scrn->driverPrivate) + return; + + free(scrn->driverPrivate); + scrn->driverPrivate = NULL; } /* @@ -453,9 +437,8 @@ static Bool intel_open_drm_master(ScrnInfoPtr scrn) return TRUE; } -static void intel_close_drm_master(ScrnInfoPtr scrn) +static void intel_close_drm_master(intel_screen_private *intel) { - intel_screen_private *intel = intel_get_screen_private(scrn); if (intel && intel->drmSubFD > 0) { drmClose(intel->drmSubFD); intel->drmSubFD = -1; @@ -563,11 +546,14 @@ static Bool I830PreInit(ScrnInfoPtr scrn, int flags) if (flags & PROBE_DETECT) return TRUE; - /* Allocate driverPrivate */ - if (!I830GetRec(scrn)) - return FALSE; - intel = intel_get_screen_private(scrn); + if (intel == NULL) { + intel = xnfcalloc(sizeof(intel_screen_private), 1); + if (intel == NULL) + return FALSE; + + scrn->driverPrivate = intel; + } intel->pEnt = pEnt; scrn->displayWidth = 640; /* default it */ @@ -1044,10 +1030,16 @@ static void i830AdjustFrame(int scrnIndex, int x, int y, int flags) static void I830FreeScreen(int scrnIndex, int flags) { ScrnInfoPtr scrn = xf86Screens[scrnIndex]; + intel_screen_private *intel = intel_get_screen_private(scrn); - intel_close_drm_master(scrn); + if (intel) { + drmmode_fini(intel); + intel_close_drm_master(intel); + + free(intel); + scrn->driverPrivate = NULL; + } - I830FreeRec(xf86Screens[scrnIndex]); if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) vgaHWFreeHWRec(xf86Screens[scrnIndex]); } @@ -1117,9 +1109,10 @@ static Bool I830CloseScreen(int scrnIndex, ScreenPtr screen) free(intel->uxa_driver); intel->uxa_driver = NULL; } + if (intel->front_buffer) { intel_set_pixmap_bo(screen->GetScreenPixmap(screen), NULL); - drmmode_closefb(scrn); + drmmode_remove_fb(intel); drm_intel_bo_unreference(intel->front_buffer); intel->front_buffer = NULL; } @@ -1131,16 +1124,11 @@ static Bool I830CloseScreen(int scrnIndex, ScreenPtr screen) xf86_cursors_fini(screen); - drm_intel_bo_unreference(intel->front_buffer); - intel->front_buffer = NULL; - i965_free_video(scrn); screen->CloseScreen = intel->CloseScreen; (*screen->CloseScreen) (scrnIndex, screen); - drmmode_close_screen(intel); - if (intel->directRenderingOpen && intel->directRenderingType == DRI_DRI2) { intel->directRenderingOpen = FALSE; |