diff options
author | Chris Wilson <chris@chris-wilson.co.uk> | 2012-05-04 09:50:19 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2012-05-06 12:51:23 +0100 |
commit | 450592f989efd0d3bc9ef2de245fce0a180e91a2 (patch) | |
tree | 45c3fa3a9edff9cfd352d971de00e704a0b1081a /src/sna | |
parent | 29d035279b2fe98d5ba9cf01125faea34d36fb76 (diff) |
sna: Cache the framebuffer id
Also fixup a weakness of only tracking scanout with a single bit, as we
used to clear it forcibly after every flip.
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'src/sna')
-rw-r--r-- | src/sna/kgem.c | 32 | ||||
-rw-r--r-- | src/sna/kgem.h | 2 | ||||
-rw-r--r-- | src/sna/sna.h | 2 | ||||
-rw-r--r-- | src/sna/sna_display.c | 141 | ||||
-rw-r--r-- | src/sna/sna_dri.c | 16 | ||||
-rw-r--r-- | src/sna/sna_driver.c | 3 |
6 files changed, 78 insertions, 118 deletions
diff --git a/src/sna/kgem.c b/src/sna/kgem.c index 666a23f0..6e0c3d0a 100644 --- a/src/sna/kgem.c +++ b/src/sna/kgem.c @@ -1088,6 +1088,25 @@ inline static void kgem_bo_remove_from_active(struct kgem *kgem, assert(list_is_empty(&bo->vma)); } +static void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo) +{ + if (!bo->scanout) + return; + + assert(bo->proxy == NULL); + + DBG(("%s: handle=%d, fb=%d\n", __FUNCTION__, bo->handle, bo->delta)); + if (bo->delta) { + drmModeRmFB(kgem->fd, bo->delta); + bo->delta = 0; + } + + bo->scanout = false; + bo->needs_flush = true; + bo->flush = false; + bo->reusable = true; +} + static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) { DBG(("%s: handle=%d\n", __FUNCTION__, bo->handle)); @@ -1096,6 +1115,7 @@ static void __kgem_bo_destroy(struct kgem *kgem, struct kgem_bo *bo) assert(bo->refcnt == 0); bo->binding.offset = 0; + kgem_bo_clear_scanout(kgem, bo); if (NO_CACHE) goto destroy; @@ -4151,18 +4171,6 @@ void kgem_bo_set_binding(struct kgem_bo *bo, uint32_t format, uint16_t offset) } } -void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo) -{ - bo->needs_flush = true; - bo->flush = false; - - if (!bo->scanout) - return; - - bo->scanout = false; - bo->reusable = true; -} - struct kgem_bo * kgem_replace_bo(struct kgem *kgem, struct kgem_bo *src, diff --git a/src/sna/kgem.h b/src/sna/kgem.h index 9eac68e9..186eaa04 100644 --- a/src/sna/kgem.h +++ b/src/sna/kgem.h @@ -509,8 +509,6 @@ struct kgem_bo *kgem_create_buffer_2d(struct kgem *kgem, bool kgem_buffer_is_inplace(struct kgem_bo *bo); void kgem_buffer_read_sync(struct kgem *kgem, struct kgem_bo *bo); -void kgem_bo_clear_scanout(struct kgem *kgem, struct kgem_bo *bo); - void kgem_throttle(struct kgem *kgem); #define MAX_INACTIVE_TIME 10 bool kgem_expire_cache(struct kgem *kgem); diff --git a/src/sna/sna.h b/src/sna/sna.h index 5272a083..e07a115b 100644 --- a/src/sna/sna.h +++ b/src/sna/sna.h @@ -318,8 +318,6 @@ extern int sna_page_flip(struct sna *sna, extern PixmapPtr sna_set_screen_pixmap(struct sna *sna, PixmapPtr pixmap); -void sna_mode_delete_fb(struct sna *sna, uint32_t fb); - constant static inline struct sna * to_sna(ScrnInfoPtr scrn) { diff --git a/src/sna/sna_display.c b/src/sna/sna_display.c index 5275d4ae..6287cd9d 100644 --- a/src/sna/sna_display.c +++ b/src/sna/sna_display.c @@ -151,6 +151,40 @@ int sna_crtc_to_plane(xf86CrtcPtr crtc) return sna_crtc->plane; } +static unsigned get_fb(struct sna *sna, struct kgem_bo *bo, + int width, int height) +{ + ScrnInfoPtr scrn = sna->scrn; + int ret; + + assert(bo->proxy == NULL); + if (bo->delta) { + DBG(("%s: reusing fb=%d for handle=%d\n", + __FUNCTION__, bo->delta, bo->handle)); + return bo->delta; + } + + DBG(("%s: create fb %dx%d@%d/%d\n", + __FUNCTION__, width, height, scrn->depth, scrn->bitsPerPixel)); + + assert(bo->tiling != I915_TILING_Y); + ret = drmModeAddFB(sna->kgem.fd, + width, height, + scrn->depth, scrn->bitsPerPixel, + bo->pitch, bo->handle, + &bo->delta); + if (ret < 0) { + ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n", + __FUNCTION__, + width, height, + scrn->depth, scrn->bitsPerPixel, bo->pitch); + return 0; + } + + bo->scanout = true; + return bo->delta; +} + static uint32_t gem_create(int fd, int size) { struct drm_i915_gem_create create; @@ -434,10 +468,6 @@ sna_crtc_restore(struct sna *sna) if (!bo) return; - assert(bo->tiling != I915_TILING_Y); - bo->scanout = true; - bo->domain = DOMAIN_NONE; - DBG(("%s: create fb %dx%d@%d/%d\n", __FUNCTION__, sna->front->drawable.width, @@ -446,13 +476,10 @@ sna_crtc_restore(struct sna *sna) sna->front->drawable.bitsPerPixel)); sna_mode_remove_fb(sna); - if (drmModeAddFB(sna->kgem.fd, - sna->front->drawable.width, - sna->front->drawable.height, - sna->front->drawable.depth, - sna->front->drawable.bitsPerPixel, - bo->pitch, bo->handle, - &sna->mode.fb_id)) + sna->mode.fb_id = get_fb(sna, bo, + sna->front->drawable.width, + sna->front->drawable.height); + if (sna->mode.fb_id == 0) return; DBG(("%s: handle %d attached to fb %d\n", @@ -468,6 +495,7 @@ sna_crtc_restore(struct sna *sna) return; } + bo->domain = DOMAIN_NONE; scrn->displayWidth = bo->pitch / sna->mode.cpp; sna->mode.fb_pixmap = sna->front->drawable.serialNumber; } @@ -652,28 +680,16 @@ sna_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, if (!bo) return FALSE; - DBG(("%s: create fb %dx%d@%d/%d\n", - __FUNCTION__, - scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel)); - - assert(bo->tiling != I915_TILING_Y); - ret = drmModeAddFB(sna->kgem.fd, - scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, - bo->pitch, bo->handle, - &sna_mode->fb_id); - if (ret < 0) { - ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n", - __FUNCTION__, - scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, bo->pitch); + /* recreate the fb in case the size has changed */ + assert(bo->delta == 0); + sna_mode->fb_id = get_fb(sna, bo, + scrn->virtualX, scrn->virtualY); + if (sna_mode->fb_id == 0) return FALSE; - } DBG(("%s: handle %d attached to fb %d\n", __FUNCTION__, bo->handle, sna_mode->fb_id)); - bo->scanout = true; + bo->domain = DOMAIN_NONE; sna_mode->fb_pixmap = sna->front->drawable.serialNumber; } @@ -773,22 +789,14 @@ sna_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height) return NULL; } - assert(bo->tiling != I915_TILING_Y); - if (drmModeAddFB(sna->kgem.fd, - width, height, scrn->depth, scrn->bitsPerPixel, - bo->pitch, bo->handle, - &sna_crtc->shadow_fb_id)) { - ErrorF("%s: failed to add rotate fb: %dx%d depth=%d, bpp=%d, pitch=%d\n", - __FUNCTION__, - width, height, - scrn->depth, scrn->bitsPerPixel, bo->pitch); + sna_crtc->shadow_fb_id = get_fb(sna, bo, width, height); + if (sna_crtc->shadow_fb_id == 0) { scrn->pScreen->DestroyPixmap(shadow); return NULL; } DBG(("%s: attached handle %d to fb %d\n", __FUNCTION__, bo->handle, sna_crtc->shadow_fb_id)); - bo->scanout = true; bo->domain = DOMAIN_NONE; return sna_crtc->shadow = shadow; } @@ -813,10 +821,8 @@ sna_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr pixmap, void *data) DBG(("%s(fb=%d, handle=%d)\n", __FUNCTION__, sna_crtc->shadow_fb_id, sna_pixmap_get_bo(pixmap)->handle)); - drmModeRmFB(sna->kgem.fd, sna_crtc->shadow_fb_id); sna_crtc->shadow_fb_id = 0; - kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(pixmap)); pixmap->drawable.pScreen->DestroyPixmap(pixmap); sna_crtc->shadow = NULL; } @@ -1702,23 +1708,16 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height) if (!bo) goto fail; - assert(bo->tiling != I915_TILING_Y); - if (drmModeAddFB(sna->kgem.fd, width, height, - scrn->depth, scrn->bitsPerPixel, - bo->pitch, bo->handle, - &mode->fb_id)) { - ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n", - __FUNCTION__, - width, height, - scrn->depth, scrn->bitsPerPixel, bo->pitch); + assert(bo->delta == 0); + + mode->fb_id = get_fb(sna, bo, width, height); + if (mode->fb_id == 0) goto fail; - } DBG(("%s: handle %d, pixmap serial %lu attached to fb %d\n", __FUNCTION__, bo->handle, sna->front->drawable.serialNumber, mode->fb_id)); - bo->scanout = true; for (i = 0; i < xf86_config->num_crtc; i++) { xf86CrtcPtr crtc = xf86_config->crtc[i]; @@ -1739,17 +1738,12 @@ sna_crtc_resize(ScrnInfoPtr scrn, int width, int height) assert(scrn->pScreen->GetScreenPixmap(scrn->pScreen) == sna->front); assert(scrn->pScreen->GetWindowPixmap(scrn->pScreen->root) == sna->front); - if (old_fb_id) - drmModeRmFB(sna->kgem.fd, old_fb_id); - kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(old_front)); scrn->pScreen->DestroyPixmap(old_front); return TRUE; fail: DBG(("%s: restoring original front pixmap and fb\n", __FUNCTION__)); - if (old_fb_id != mode->fb_id) - drmModeRmFB(sna->kgem.fd, mode->fb_id); mode->fb_id = old_fb_id; if (sna->front) @@ -1843,15 +1837,9 @@ sna_page_flip(struct sna *sna, /* * Create a new handle for the back buffer */ - assert(bo->tiling != I915_TILING_Y); - if (drmModeAddFB(sna->kgem.fd, scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, - bo->pitch, bo->handle, - &mode->fb_id)) { - ErrorF("%s: failed to add fb: %dx%d depth=%d, bpp=%d, pitch=%d\n", - __FUNCTION__, - scrn->virtualX, scrn->virtualY, - scrn->depth, scrn->bitsPerPixel, bo->pitch); + mode->fb_id = get_fb(sna, bo, scrn->virtualX, scrn->virtualY); + if (mode->fb_id == 0) { + mode->fb_id = *old_fb; return 0; } @@ -1871,23 +1859,14 @@ sna_page_flip(struct sna *sna, */ count = do_page_flip(sna, data, ref_crtc_hw_id); DBG(("%s: page flipped %d crtcs\n", __FUNCTION__, count)); - if (count) { - bo->scanout = true; + if (count) bo->domain = DOMAIN_NONE; - } else { - drmModeRmFB(sna->kgem.fd, mode->fb_id); + else mode->fb_id = *old_fb; - } return count; } -void sna_mode_delete_fb(struct sna *sna, uint32_t fb) -{ - if (fb) - drmModeRmFB(sna->kgem.fd, fb); -} - static const xf86CrtcConfigFuncsRec sna_crtc_config_funcs = { sna_crtc_resize }; @@ -1932,11 +1911,8 @@ sna_mode_remove_fb(struct sna *sna) DBG(("%s: deleting fb id %d for pixmap serial %d\n", __FUNCTION__, mode->fb_id,mode->fb_pixmap)); - if (mode->fb_id) { - drmModeRmFB(sna->kgem.fd, mode->fb_id); - mode->fb_id = 0; - mode->fb_pixmap = 0; - } + mode->fb_id = 0; + mode->fb_pixmap = 0; } void @@ -1957,7 +1933,6 @@ sna_mode_fini(struct sna *sna) #endif sna_mode_remove_fb(sna); - kgem_bo_clear_scanout(&sna->kgem, sna_pixmap_get_bo(sna->front)); /* mode->shadow_fb_id should have been destroyed already */ } diff --git a/src/sna/sna_dri.c b/src/sna/sna_dri.c index d5eefcbd..32602d56 100644 --- a/src/sna/sna_dri.c +++ b/src/sna/sna_dri.c @@ -336,7 +336,6 @@ static void _sna_dri_destroy_buffer(struct sna *sna, DRI2Buffer2Ptr buffer) } private->bo->flush = 0; - kgem_bo_clear_scanout(&sna->kgem, private->bo); /* paranoia */ kgem_bo_destroy(&sna->kgem, private->bo); free(buffer); @@ -392,7 +391,6 @@ static void set_bo(PixmapPtr pixmap, struct kgem_bo *bo) sna_damage_destroy(&priv->cpu_damage); priv->undamaged = false; - kgem_bo_clear_scanout(&sna->kgem, priv->gpu_bo); /* paranoia */ kgem_bo_destroy(&sna->kgem, priv->gpu_bo); priv->gpu_bo = ref(bo); } @@ -860,18 +858,10 @@ sna_dri_add_frame_event(struct sna_dri_frame_event *info) static void sna_dri_frame_event_release_bo(struct kgem *kgem, struct kgem_bo *bo) { - kgem_bo_clear_scanout(kgem, bo); kgem_bo_destroy(kgem, bo); } static void -sna_dri_frame_event_finish(struct sna_dri_frame_event *info) -{ - sna_mode_delete_fb(info->sna, info->old_fb); - kgem_bo_clear_scanout(&info->sna->kgem, info->old_front.bo); -} - -static void sna_dri_frame_event_info_free(struct sna_dri_frame_event *info) { DBG(("%s: del[%p] (%p, %ld)\n", __FUNCTION__, @@ -1177,13 +1167,10 @@ static void sna_dri_flip_event(struct sna *sna, flip->event_data); } - sna_dri_frame_event_finish(flip); sna_dri_frame_event_info_free(flip); break; case DRI2_FLIP_THROTTLE: - sna_dri_frame_event_finish(flip); - assert(sna->dri.flip_pending[flip->pipe] == flip); sna->dri.flip_pending[flip->pipe] = NULL; @@ -1221,8 +1208,6 @@ static void sna_dri_flip_event(struct sna *sna, flip->front->name != flip->old_front.name)); assert(sna->dri.flip_pending[flip->pipe] == flip); - sna_dri_frame_event_finish(flip); - if (flip->front->name != flip->next_front.name) { DBG(("%s: async flip continuing\n", __FUNCTION__)); @@ -1801,7 +1786,6 @@ blit: } info->front->name = info->back->name; get_private(info->front)->bo = get_private(info->back)->bo; - __kgem_flush(&sna->kgem, get_private(info->back)->bo); } if (bo == NULL) { diff --git a/src/sna/sna_driver.c b/src/sna/sna_driver.c index 7b3cfcee..150e973e 100644 --- a/src/sna/sna_driver.c +++ b/src/sna/sna_driver.c @@ -784,9 +784,6 @@ static Bool sna_close_screen(int scrnIndex, ScreenPtr screen) sna_mode_remove_fb(sna); if (sna->front) { - struct kgem_bo *bo = sna_pixmap_get_bo(sna->front); - if (bo) - kgem_bo_clear_scanout(&sna->kgem, bo); /* valgrind */ screen->DestroyPixmap(sna->front); sna->front = NULL; } |