Surface: Ensure synchronisation of copyBlt
The Surface::lock() function has an optimisation for copying the
previously drawn contents from the frontbuffer to the (current)
backbuffer, so that the client does not have to redraw the whole surface
contents. This logic was not using the sync fence FD from
dequeueBuffer() and so was not correctly synchronised with pending
operations on the backbuffer.
Change-Id: Ib44574d50f8bdb4a23078cd8da1c5c512c876320
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 8e6ab1c..7607b42 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -20,6 +20,13 @@
#include <android/native_window.h>
+// We would eliminate the non-conforming zero-length array, but we can't since
+// this is effectively included from the Linux kernel
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
+#include <sync/sync.h>
+#pragma clang diagnostic pop
+
#include <binder/Parcel.h>
#include <utils/Log.h>
@@ -1269,8 +1276,14 @@
if (canCopyBack) {
// copy the area that is invalid and not repainted this round
const Region copyback(mDirtyRegion.subtract(newDirtyRegion));
- if (!copyback.isEmpty())
+ if (!copyback.isEmpty()) {
+ if (fenceFd >= 0) {
+ sync_wait(fenceFd, -1);
+ close(fenceFd);
+ fenceFd = -1;
+ }
copyBlt(backBuffer, frontBuffer, copyback);
+ }
} else {
// if we can't copy-back anything, modify the user's dirty
// region to make sure they redraw the whole buffer