Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
egl-wayland: Fix an unbounded array growth issue
We do not seem to shrink the dynamically allocated streamImages array that we use for storing the resources associated with the swapchain images. When an entry in this array is destroyed in the destroy_stream_image() function, its fields are simply reverted to default/invalid values. Later on, the entries in this array are tried to be recycled in the add_surface_image() function. However, this approach is error-prone since we keep valid and invalid entries together, which requires us to check the validity of the entries every time we access them. Also, when explicit sync is in use, this array just keeps growing over time, especially during the application window resizes, due to a bug in the entry destruction logic. So, to solve these problems, this change converts the dynamically allocated streamImages array into a linked list for simplified insertions and deletions. Each entry in this linked list is removed from the list and deallocated once they are no longer needed. So, all of the entries in the list stay valid. Per-entry mutexes are replaced with a single mutex that guards accesses to the entire list to make sure that the linked list does not get corrupted when it is accessed from multiple threads. This only happens when explicit sync is not in use. The sizes of the critical sections that are protected by this new mutex are very small. To test to see if this change creates lock contention issues, weston-simple-egl application with swap interval of 0 was run on a Wayland compositor that does not support explicit sync to create as much lock contention as possible. However, no measurable difference in performance was observed after this change was applied. As a side effect of this change, a bug in the wlEglSurfaceCheckReleasePoints() function, where we wrongly assumed that all the entries in the streamImages array were valid, is fixed. This bug caused us to pass destroyed DRM syncobjs to the drmSyncobjTimelineWait() function, which led to random application freezes as a result in some cases since it prevented images from being released back to the EGL stream. Another side effect of this change is that, it makes the maximum number of entries in this list known when explicit sync is in use, allowing us to avoid dynamically allocating the arrays for the list of DRM syncobjs and timeline points in wlEglSurfaceCheckReleasePoints(). This fixes a memory leak issue that can happen if only one of these allocations fails.
- Loading branch information