[Xf86-video-armsoc] [PATCH 2/3] Allocate framebuffer on unflippable-to-flippable transition

Paul Geary armsoc-bugs at arm.com
Mon Nov 17 01:55:45 PST 2014


I have tried to apply this change to git server:
http://mpd-gerrit.cambridge.arm.com/#/c/6133/
but some of the tests failed (winsys_x11_flip_when_moved, winsys_x11_unmapped_window_create_surface_flippable)
http://mpdti2.euhpc.arm.com/tables/chain/658905/results/red
the root cause of these failures maybe like this (I am not very sure):
1. before this change, when a window is moved and can be flipped, armsoc will destroy the old buffer and create a new one, so the fb_id is changed. But after this change, the fb_id is not changed 2. update_drm_flipflag function will only return " buffer_flipped = TRUE" if the previous fb_id and current one is different.


Regards
Sunny
-----Original Message-----
From: Xf86-video-armsoc [mailto:xf86-video-armsoc-bounces at lists.freedesktop.org] On Behalf Of Daniel Drake
Sent: Saturday, November 15, 2014 2:31 AM
To: xf86-video-armsoc at lists.freedesktop.org
Subject: [Xf86-video-armsoc] [PATCH 2/3] Allocate framebuffer on unflippable-to-flippable transition

The previous_canflip system that was in place no longer works, because DRI2 on the X side no longer checks serial numbers, as of xserver commit 77e51d5bbb97eb5c9d9dbff9a7c44d7e53620e68.

We need a new way to detect the situation where a framebuffer was not created at CreateBuffer time (because the window wasn't mapped) but then later becomes mapped and flippable.

After some experimentation I have settled on the assumption that Mali always sends a GetBuffers request when such a transition happens, which means we can hook into ReuseBufferNotify to be called at that time and create the framebuffer.

This fixes a test case of running `glmark2-es2 --fullscreen` under metacity with a modern X server. Previously it was falling back to CopyRegion (fb never allocated), now we allocate the fb once the window gets mapped shortly after launch.
---
 src/armsoc_dri2.c | 103 +++++++++++++++++++++++++++++++++---------------------
 1 file changed, 64 insertions(+), 39 deletions(-)

diff --git a/src/armsoc_dri2.c b/src/armsoc_dri2.c index 2e8571a..e548f67 100644
--- a/src/armsoc_dri2.c
+++ b/src/armsoc_dri2.c
@@ -80,19 +80,12 @@ struct ARMSOCDRI2BufferRec {
        int refcnt;

        /**
-        * The value of canflip() for the previous frame. Used so that we can
-        * tell whether the buffer should be re-allocated, e.g into scanout-able
-        * memory if the buffer can now be flipped.
-        *
-        * We don't want to re-allocate every frame because it is unnecessary
-        * overhead most of the time apart from when we switch from flipping
-        * to blitting or vice versa.
-        *
-        * We should bump the serial number of the drawable if canflip() returns
-        * something different to what is stored here, so that the DRI2 buffers
-        * will get re-allocated.
-        */
-       int previous_canflip;
+         * We don't want to overdo attempting fb allocation for mapped
+         * scanout buffers, to behave nice under low memory conditions.
+         * Instead we use this flag to attempt the allocation just once
+         * every time the window is mapped.
+         */
+       int attempted_fb_alloc;

 };

@@ -249,7 +242,6 @@ ARMSOCDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment,
        DRIBUF(buf)->format = format;
        DRIBUF(buf)->flags = 0;
        buf->refcnt = 1;
-       buf->previous_canflip = canflip(pDraw);

        ret = armsoc_bo_get_name(bo, &DRIBUF(buf)->name);
        if (ret) {
@@ -262,8 +254,13 @@ ARMSOCDRI2CreateBuffer(DrawablePtr pDraw, unsigned int attachment,
                 * 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). */
+                * at buffer creation time).
+                *
+                * If the window is not mapped at this time, we will not hit
+                * this codepath, but ARMSOCDRI2ReuseBufferNotify will create
+                * a framebuffer if it gets mapped later on. */
                int ret = armsoc_bo_add_fb(bo);
+               buf->attempted_fb_alloc = TRUE;
                if (ret) {
                        WARNING_MSG(
                                        "Falling back to blitting a flippable window"); @@ -296,6 +293,56 @@ fail:
        return NULL;
 }

+/* Called when DRI2 is handling a GetBuffers request and is going to
+ * reuse a buffer that we created earlier.
+ * Our interest in this situation is that we might have omitted 
+creating
+ * a framebuffer for a backbuffer due to it not being flippable at 
+creation
+ * time (e.g. because the window wasn't mapped yet).
+ * But if GetBuffers has been called because the window is now mapped,
+ * we are going to need a framebuffer so that we can page flip it later.
+ * We avoid creating a framebuffer when it is not necessary in order to 
+save
+ * on scanout memory which is potentially scarce.
+ *
+ * Mali r4p0 is generally light on calling GetBuffers (e.g. it doesn't 
+do it
+ * in response to an InvalidateBuffers event) but we have determined
+ * experimentally that it does always seem to call GetBuffers upon a
+ * unmapped-to-mapped transition.
+ */
+static void
+ARMSOCDRI2ReuseBufferNotify(DrawablePtr pDraw, DRI2BufferPtr buffer) {
+       struct ARMSOCDRI2BufferRec *buf = ARMSOCBUF(buffer);
+       struct armsoc_bo *bo;
+       Bool flippable;
+       int fb_id;
+
+       if (buffer->attachment == DRI2BufferFrontLeft)
+               return;
+
+       bo = ARMSOCPixmapBo(buf->pPixmaps[0]);
+       fb_id = armsoc_bo_get_fb(bo);
+       flippable = canflip(pDraw);
+
+       /* Detect unflippable-to-flippable transition:
+        * Window is flippable, but we haven't yet tried to allocate a
+        * framebuffer for it, and it doesn't already have a framebuffer.
+        * This can happen when CreateBuffer was called before the window
+        * was mapped, and we have now been mapped. */
+       if (flippable && !buf->attempted_fb_alloc && fb_id == 0) {
+               armsoc_bo_add_fb(bo);
+               buf->attempted_fb_alloc = TRUE;
+       }
+
+       /* Detect flippable-to-unflippable transition:
+        * Window is now unflippable, but we have a framebuffer allocated for
+        * it. Now we can free the framebuffer to save on scanout memory, and
+        * reset state in case it gets mapped again later. */
+       if (!flippable && fb_id != 0) {
+               buf->attempted_fb_alloc = FALSE;
+               armsoc_bo_rm_fb(bo);
+       }
+}
+
 /**
  * Destroy Buffer
  */
@@ -355,7 +402,6 @@ ARMSOCDRI2CopyRegion(DrawablePtr pDraw, RegionPtr pRegion,

        DEBUG_MSG("pDraw=%p, pDstBuffer=%p (%p), pSrcBuffer=%p (%p)",
                        pDraw, pDstBuffer, pSrcDraw, pSrcBuffer, pDstDraw);
-
        pGC = GetScratchGC(pDstDraw->depth, pScreen);
        if (!pGC)
                return;
@@ -716,12 +762,10 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
        ScreenPtr pScreen = pDraw->pScreen;
        ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
        struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
-       struct ARMSOCDRI2BufferRec *src = ARMSOCBUF(pSrcBuffer);
-       struct ARMSOCDRI2BufferRec *dst = ARMSOCBUF(pDstBuffer);
        struct ARMSOCDRISwapCmd *cmd;
        struct armsoc_bo *src_bo, *dst_bo;
        int src_fb_id, dst_fb_id;
-       int new_canflip, ret, do_flip;
+       int ret, do_flip;
        unsigned int idx;
        RegionRec region;
        PixmapPtr pDstPixmap = draw2pix(dri2draw(pDraw, pDstBuffer)); @@ -773,26 +817,6 @@ ARMSOCDRI2ScheduleSwap(ClientPtr client, DrawablePtr pDraw,
        DEBUG_MSG("SWAP %d SCHEDULED : %d -> %d ", cmd->swap_id,
                                pSrcBuffer->attachment, pDstBuffer->attachment);

-       new_canflip = canflip(pDraw);
-       if ((src->previous_canflip != new_canflip) ||
-           (dst->previous_canflip != new_canflip)) {
-               /* The drawable has transitioned between being flippable and
-                * non-flippable or vice versa. Bump the serial number to force
-                * the DRI2 buffers to be re-allocated during the next frame so
-                * that:
-                * - It is able to be scanned out
-                *        (if drawable is now flippable), or
-                * - It is not taking up possibly scarce scanout-able memory
-                *        (if drawable is now not flippable)
-                */
-
-               PixmapPtr pPix = pScreen->GetWindowPixmap((WindowPtr)pDraw);
-               pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-       }
-
-       src->previous_canflip = new_canflip;
-       dst->previous_canflip = new_canflip;
-
        do_flip = src_fb_id && dst_fb_id && canflip(pDraw);

        /* After a resolution change the back buffer (src) will still be @@ -947,6 +971,7 @@ ARMSOCDRI2ScreenInit(ScreenPtr pScreen)
                .AuthMagic         = drmAuthMagic,
 #if DRI2INFOREC_VERSION >= 6
                .SwapLimitValidate = ARMSOCDRI2SwapLimitValidate,
+               .ReuseBufferNotify = ARMSOCDRI2ReuseBufferNotify,
 #endif
        };
        int minor = 1, major = 0;
--
1.8.1.2

_______________________________________________
Xf86-video-armsoc mailing list
Xf86-video-armsoc at lists.freedesktop.org
http://lists.x.org/mailman/listinfo/xf86-video-armsoc





More information about the Xf86-video-armsoc mailing list