Use FenceTime to share fence times and reduce open fds.
FenceTimes are created and shared for each Fence that
FrameTimestampHistory and FrameTracker care about.
On the consumer side, the FenceTimes are also added to
shared timelines that are owned by SurfaceFlinger or
unshared timelines owned by Layer. The timelines are
checked at the end of every frame to minimize the number
of file descriptors open.
On the producer side, the FenceTimes are added to
the ConsumerFrameEventHistory instead, since the timelines
that would be tracked by SurfaceFlinger are not shared
with anyone else in the consumer's process. The timelines
are checked just after a frame is queued to minimize
the number of file descriptors open.
Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*
Change-Id: Ifd4301affe1b24705b2bee7608c5a2c09dfb4041
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index c82b0c4..034a394 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -602,7 +602,7 @@
return mDisplayData[displayId].lastPresentFence;
}
-bool HWComposer::retireFenceRepresentsStartOfScanout() const {
+bool HWComposer::presentFenceRepresentsStartOfScanout() const {
return mAdapter ? false : true;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index e63bdd4..2713505 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -121,10 +121,10 @@
// get the present fence received from the last call to present.
sp<Fence> getPresentFence(int32_t displayId) const;
- // Returns true if the retire fence represents the start of the display
+ // Returns true if the present fence represents the start of the display
// controller's scan out. This should be true for all HWC2 implementations,
// except for the wrapper around HWC1 implementations.
- bool retireFenceRepresentsStartOfScanout() const;
+ bool presentFenceRepresentsStartOfScanout() const;
// Get last release fence for the given layer
sp<Fence> getLayerReleaseFence(int32_t displayId,
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 0511df2..6a98f03 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -281,7 +281,7 @@
#endif
&qbo);
if (result == NO_ERROR) {
- updateQueueBufferOutput(qbo);
+ updateQueueBufferOutput(std::move(qbo));
}
} else {
// If the surface hadn't actually been updated, then we only went
@@ -516,7 +516,8 @@
mOutputFence = mFbFence;
}
- *output = mQueueBufferOutput;
+ // This moves the frame timestamps and keeps a copy of all other fields.
+ *output = std::move(mQueueBufferOutput);
return NO_ERROR;
}
@@ -555,8 +556,9 @@
status_t result = mSource[SOURCE_SINK]->connect(listener, api,
producerControlledByApp, &qbo);
if (result == NO_ERROR) {
- updateQueueBufferOutput(qbo);
- *output = mQueueBufferOutput;
+ updateQueueBufferOutput(std::move(qbo));
+ // This moves the frame timestamps and keeps a copy of all other fields.
+ *output = std::move(mQueueBufferOutput);
}
return result;
}
@@ -615,8 +617,8 @@
}
void VirtualDisplaySurface::updateQueueBufferOutput(
- const QueueBufferOutput& qbo) {
- mQueueBufferOutput = qbo;
+ QueueBufferOutput&& qbo) {
+ mQueueBufferOutput = std::move(qbo);
mQueueBufferOutput.transformHint = 0;
}
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index b435bf5..d37dc0a 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -136,7 +136,7 @@
static Source fbSourceForCompositionType(CompositionType type);
status_t dequeueBuffer(Source source, PixelFormat format, uint32_t usage,
int* sslot, sp<Fence>* fence);
- void updateQueueBufferOutput(const QueueBufferOutput& qbo);
+ void updateQueueBufferOutput(QueueBufferOutput&& qbo);
void resetPerFrameState();
status_t refreshOutputBuffer();
@@ -181,6 +181,8 @@
// The QueueBufferOutput with the latest info from the sink, and with the
// transform hint cleared. Since we defer queueBuffer from the GLES driver
// to the sink, we have to return the previous version.
+ // Moves instead of copies are performed to avoid duplicate
+ // FrameEventHistoryDeltas.
QueueBufferOutput mQueueBufferOutput;
// Details of the current sink buffer. These become valid when a buffer is