diff options
author | Ray Smith <raymond.smith@arm.com> | 2013-03-13 10:08:36 +0000 |
---|---|---|
committer | Ray Smith <raymond.smith@arm.com> | 2013-07-23 15:00:39 +0100 |
commit | b4299f81bc02f7c8536aa5d49f47e5d73f517ce0 (patch) | |
tree | da28d80960c6471c704aafc6375eb92f0422d2b2 /src | |
parent | 4d37be3492bb1d3af52b550fdb233f411b004d70 (diff) |
Fallback to blitting when out of scanout memory
If DRM can't allocate a scanout buffer for a flippable
window's back buffer, we now attempt to allocate a
non-scanout buffer and blit the window rather than
fail the DRI2 buffer allocation completely.
Note that this fallback is only suitable for back
buffers - if reallocating the front buffer (on
res change etc.) failed, we can't fall back to a
non-scanout buffer.
Change-Id: I9614dde01e80fd3dc03a37afee1a38d00dd55348
Diffstat (limited to 'src')
-rw-r--r-- | src/armsoc_dri2.c | 14 | ||||
-rw-r--r-- | src/armsoc_dumb.c | 1 | ||||
-rw-r--r-- | src/armsoc_exa.c | 29 | ||||
-rw-r--r-- | src/drmmode_display.c | 30 |
4 files changed, 60 insertions, 14 deletions
diff --git a/src/armsoc_dri2.c b/src/armsoc_dri2.c index a2e71ca..ae8b05e 100644 --- a/src/armsoc_dri2.c +++ b/src/armsoc_dri2.c @@ -229,16 +229,16 @@ ARMSOCDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment, goto fail; } - /* Q: how to know across ARMSOC generations what formats the display - * can support directly? - * A: attempt to create a drm_framebuffer, and if that fails then the - * hw must not support.. then fall back to blitting - */ if (canflip(pDraw) && attachment != DRI2BufferFrontLeft) { + /* Create an fb around this buffer. This will fail and we will + * fall back to blitting if the display controller hardware + * cannot scan out this buffer (for example, if it doesn't + * support the format or there was insufficient scanout memory + * at buffer creation time). */ int ret = armsoc_bo_add_fb(bo); if (ret) { - /* to-bad, so-sad, we can't flip */ - WARNING_MSG("could not create fb: %d", ret); + WARNING_MSG( + "Falling back to blitting a flippable window"); } } diff --git a/src/armsoc_dumb.c b/src/armsoc_dumb.c index d395b89..a1fd800 100644 --- a/src/armsoc_dumb.c +++ b/src/armsoc_dumb.c @@ -350,7 +350,6 @@ int armsoc_bo_add_fb(struct armsoc_bo *bo) ret = drmModeAddFB(bo->dev->fd, bo->width, bo->height, bo->depth, bo->bpp, bo->pitch, bo->handle, &bo->fb_id); if (ret < 0) { - xf86DrvMsg(-1, X_ERROR, "Could not add fb to bo %d\n", ret); bo->fb_id = 0; return ret; } diff --git a/src/armsoc_exa.c b/src/armsoc_exa.c index 8aaa297..879c605 100644 --- a/src/armsoc_exa.c +++ b/src/armsoc_exa.c @@ -96,6 +96,21 @@ ARMSOCCreatePixmap2(ScreenPtr pScreen, int width, int height, height, depth, bitsPerPixel, buf_type); + + if ((!priv->bo) && ARMSOC_BO_SCANOUT == buf_type) { + /* Tried to create a scanout but failed. Attempt to + * fall back to non-scanout instead. + */ + WARNING_MSG( + "Scanout buffer allocation failed, falling back to non-scanout"); + buf_type = ARMSOC_BO_NON_SCANOUT; + priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev, + width, + height, + depth, + bitsPerPixel, buf_type); + } + if (!priv->bo) { ERROR_MSG("failed to allocate %dx%d bo, buf_type = %d", width, height, buf_type); @@ -204,6 +219,20 @@ ARMSOCModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, pPixmap->drawable.depth, pPixmap->drawable.bitsPerPixel, buf_type); + if ((!priv->bo) && ARMSOC_BO_SCANOUT == buf_type) { + /* Tried to create a scanout but failed. Attempt to + * fall back to non-scanout instead. + */ + WARNING_MSG( + "Scanout buffer allocation failed, falling back to non-scanout"); + buf_type = ARMSOC_BO_NON_SCANOUT; + priv->bo = armsoc_bo_new_with_dim(pARMSOC->dev, + pPixmap->drawable.width, + pPixmap->drawable.height, + pPixmap->drawable.depth, + pPixmap->drawable.bitsPerPixel, + buf_type); + } if (!priv->bo) { ERROR_MSG("failed to allocate %dx%d bo, buf_type = %d", pPixmap->drawable.width, diff --git a/src/drmmode_display.c b/src/drmmode_display.c index f805e29..ba6d439 100644 --- a/src/drmmode_display.c +++ b/src/drmmode_display.c @@ -200,8 +200,11 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode, pScrn->virtualX, pScrn->virtualY); ret = armsoc_bo_add_fb(pARMSOC->scanout); - if (ret) + if (ret) { + ERROR_MSG( + "Failed to add framebuffer to the scanout buffer"); return FALSE; + } fb_id = armsoc_bo_get_fb(pARMSOC->scanout); if (0 == fb_id) @@ -1144,24 +1147,39 @@ drmmode_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height) /* Resize the bo */ if (armsoc_bo_resize(pARMSOC->scanout, width, height)) { armsoc_bo_clear(pARMSOC->scanout); - armsoc_bo_add_fb(pARMSOC->scanout); + if (armsoc_bo_add_fb(pARMSOC->scanout)) + ERROR_MSG( + "Failed to add framebuffer to the existing scanout buffer"); return FALSE; } + /* Add new fb to the bo */ - if (armsoc_bo_clear(pARMSOC->scanout) || - armsoc_bo_add_fb(pARMSOC->scanout)) + if (armsoc_bo_clear(pARMSOC->scanout)) + return FALSE; + + if (armsoc_bo_add_fb(pARMSOC->scanout)) { + ERROR_MSG( + "Failed to add framebuffer to the existing scanout buffer"); return FALSE; + } pitch = armsoc_bo_pitch(pARMSOC->scanout); } else { DEBUG_MSG("allocated new scanout buffer okay"); pitch = armsoc_bo_pitch(new_scanout); /* clear new BO and add FB */ - if (armsoc_bo_clear(new_scanout) || - armsoc_bo_add_fb(new_scanout)) { + if (armsoc_bo_clear(new_scanout)) { + armsoc_bo_unreference(new_scanout); + return FALSE; + } + + if (armsoc_bo_add_fb(new_scanout)) { + ERROR_MSG( + "Failed to add framebuffer to the new scanout buffer"); armsoc_bo_unreference(new_scanout); return FALSE; } + /* Handle dma_buf fd that may be attached to old bo */ if (armsoc_bo_has_dmabuf(pARMSOC->scanout)) { int res; |