OSDN Git Service

SurfaceFlinger: Update parent pointer while performing transaction.
authorRobert Carr <racarr@google.com>
Thu, 1 Jun 2017 21:59:25 +0000 (14:59 -0700)
committerRobert Carr <racarr@google.com>
Fri, 2 Jun 2017 18:31:17 +0000 (11:31 -0700)
commit98b0fd5fc28b07b6b488bc599a3448ebcacb6acc
treec3c22012beaae9f4da8e1bea5ad78e04bb299c28
parentc523409f0fd03aa498cedc486f85e9a4b7257f3a
SurfaceFlinger: Update parent pointer while performing transaction.

To understand the change at a high level, notice that all the usage
of getParent() is assosciated with the drawing state. We see in this way
that the parent is a part of the drawing state and should only be updated
when transactions occurs.

More specifically we can consider the following scenario:

1. Imagine that we have a visible surface, with a visible child surface
2. Now imagine we create a new surface, which is hidden, and post a buffer to it.
   It is configured such that it would be visible if it were not hidden.
3. We open a transaction
4. We reparent the child from the old surface to the new one
5. We show the new surface
6. We close the transaction

At this point we would expect the child to remain visible, as it is atomically
reparented with the visibility change of the parent. However prior to this CL
we see a flash, as the sequence can continue as follows:

7. Closing the transaction triggers setClientState, causing Layer::reparentChildren
   which would call setParent updating the parent pointer.
8. setClientState updates the current but not drawing visibility of the new parent and marks
   a transaction to occur.
9. We return to the main thread, MESSAGE_REFRESH occurs before MESSAGE_TRANSACTION
   and we render a frame
10. We observe the child window as invisible, as it has the new parent
    but it's new parent is not yet visible.

We simply have to ensure the parent pointer is updated at transaction time.
I chose a location in commitChildList where mDrawingChildren was copied
from mCurrentChildren as it seemed to express the intent well.

Test: Difficult to automatically test. Manually try resizing Chrome/Youtube/etc in docked stack before flicker should be ~1/10 after flicker should be <1/100 (I haven't seen one yet)
Bug: 62099658
Change-Id: I3721d16361b53128146510d3fda43e1c12f93223
services/surfaceflinger/Layer.cpp