Update producer's cache of frame events in de/queue
* Cache is only updated during queue and dequeue if
the getFrameTimestamps is enabled.
* The consumer avoids sending a copy of the acquire
fence back to the producer since the producer
already has a copy.
Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*
Change-Id: I6a8b965ae79441a40893b5df937f9ed004fe7359
diff --git a/include/gui/BufferQueueProducer.h b/include/gui/BufferQueueProducer.h
index e6ee6c6..5541468 100644
--- a/include/gui/BufferQueueProducer.h
+++ b/include/gui/BufferQueueProducer.h
@@ -80,9 +80,9 @@
//
// In both cases, the producer will need to call requestBuffer to get a
// GraphicBuffer handle for the returned slot.
- virtual status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence,
+ status_t dequeueBuffer(int *outSlot, sp<Fence>* outFence,
uint32_t width, uint32_t height, PixelFormat format,
- uint32_t usage);
+ uint32_t usage, FrameEventHistoryDelta* outTimestamps) override;
// See IGraphicBufferProducer::detachBuffer
virtual status_t detachBuffer(int slot);
diff --git a/include/gui/FrameTimestamps.h b/include/gui/FrameTimestamps.h
index 5076597..0e95ec3 100644
--- a/include/gui/FrameTimestamps.h
+++ b/include/gui/FrameTimestamps.h
@@ -226,7 +226,6 @@
nsecs_t mFirstRefreshStartTime{0};
nsecs_t mLastRefreshStartTime{0};
- sp<Fence> mAcquireFence{Fence::NO_FENCE};
sp<Fence> mGpuCompositionDoneFence{Fence::NO_FENCE};
sp<Fence> mDisplayPresentFence{Fence::NO_FENCE};
sp<Fence> mDisplayRetireFence{Fence::NO_FENCE};
@@ -234,13 +233,12 @@
// This is a static method with an auto return value so we can call
// it without needing const and non-const versions.
- template <typename ThisType>
- static inline auto allFences(ThisType fed) ->
- std::array<decltype(&fed->mAcquireFence), 5> {
+ template <typename ThisT>
+ static inline auto allFences(ThisT fed) ->
+ std::array<decltype(&fed->mReleaseFence), 4> {
return {{
- &fed->mAcquireFence, &fed->mGpuCompositionDoneFence,
- &fed->mDisplayPresentFence, &fed->mDisplayRetireFence,
- &fed->mReleaseFence
+ &fed->mGpuCompositionDoneFence, &fed->mDisplayPresentFence,
+ &fed->mDisplayRetireFence, &fed->mReleaseFence
}};
}
};
diff --git a/include/gui/IGraphicBufferProducer.h b/include/gui/IGraphicBufferProducer.h
index 612a902..492db35 100644
--- a/include/gui/IGraphicBufferProducer.h
+++ b/include/gui/IGraphicBufferProducer.h
@@ -190,7 +190,8 @@
// All other negative values are an unknown error returned downstream
// from the graphics allocator (typically errno).
virtual status_t dequeueBuffer(int* slot, sp<Fence>* fence, uint32_t w,
- uint32_t h, PixelFormat format, uint32_t usage) = 0;
+ uint32_t h, PixelFormat format, uint32_t usage,
+ FrameEventHistoryDelta* outTimestamps) = 0;
// detachBuffer attempts to remove all ownership of the buffer in the given
// slot from the buffer queue. If this call succeeds, the slot will be
@@ -306,20 +307,23 @@
// set this to Fence::NO_FENCE if the buffer is ready immediately
// sticky - the sticky transform set in Surface (only used by the LEGACY
// camera mode).
+ // getFrameTimestamps - whether or not the latest frame timestamps
+ // should be retrieved from the consumer.
inline QueueBufferInput(int64_t _timestamp, bool _isAutoTimestamp,
android_dataspace _dataSpace, const Rect& _crop,
int _scalingMode, uint32_t _transform, const sp<Fence>& _fence,
- uint32_t _sticky = 0)
+ uint32_t _sticky = 0, bool _getFrameTimestamps = false)
: timestamp(_timestamp), isAutoTimestamp(_isAutoTimestamp),
dataSpace(_dataSpace), crop(_crop), scalingMode(_scalingMode),
transform(_transform), stickyTransform(_sticky), fence(_fence),
- surfaceDamage() { }
+ surfaceDamage(), getFrameTimestamps(_getFrameTimestamps) { }
inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp,
android_dataspace* outDataSpace,
Rect* outCrop, int* outScalingMode,
uint32_t* outTransform, sp<Fence>* outFence,
- uint32_t* outStickyTransform = nullptr) const {
+ uint32_t* outStickyTransform = nullptr,
+ bool* outGetFrameTimestamps = nullptr) const {
*outTimestamp = timestamp;
*outIsAutoTimestamp = bool(isAutoTimestamp);
*outDataSpace = dataSpace;
@@ -330,9 +334,13 @@
if (outStickyTransform != NULL) {
*outStickyTransform = stickyTransform;
}
+ if (outGetFrameTimestamps) {
+ *outGetFrameTimestamps = getFrameTimestamps;
+ }
}
// Flattenable protocol
+ static constexpr size_t minFlattenedSize();
size_t getFlattenedSize() const;
size_t getFdCount() const;
status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
@@ -351,37 +359,12 @@
uint32_t stickyTransform{0};
sp<Fence> fence;
Region surfaceDamage;
+ bool getFrameTimestamps{false};
};
struct QueueBufferOutput : public Flattenable<QueueBufferOutput> {
- // outWidth - filled with default width applied to the buffer
- // outHeight - filled with default height applied to the buffer
- // outTransformHint - filled with default transform applied to the buffer
- // outNumPendingBuffers - num buffers queued that haven't yet been acquired
- // (counting the currently queued buffer)
- inline void deflate(uint32_t* outWidth,
- uint32_t* outHeight,
- uint32_t* outTransformHint,
- uint32_t* outNumPendingBuffers,
- uint64_t* outNextFrameNumber) const {
- *outWidth = width;
- *outHeight = height;
- *outTransformHint = transformHint;
- *outNumPendingBuffers = numPendingBuffers;
- *outNextFrameNumber = nextFrameNumber;
- }
-
- inline void inflate(uint32_t inWidth, uint32_t inHeight,
- uint32_t inTransformHint, uint32_t inNumPendingBuffers,
- uint64_t inNextFrameNumber) {
- width = inWidth;
- height = inHeight;
- transformHint = inTransformHint;
- numPendingBuffers = inNumPendingBuffers;
- nextFrameNumber = inNextFrameNumber;
- }
-
// Flattenable protocol
+ static constexpr size_t minFlattenedSize();
size_t getFlattenedSize() const;
size_t getFdCount() const;
status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
@@ -392,6 +375,7 @@
uint32_t transformHint{0};
uint32_t numPendingBuffers{0};
uint64_t nextFrameNumber{0};
+ FrameEventHistoryDelta frameTimestamps;
};
virtual status_t queueBuffer(int slot, const QueueBufferInput& input,
diff --git a/include/gui/Surface.h b/include/gui/Surface.h
index c12d452..a10dad1 100644
--- a/include/gui/Surface.h
+++ b/include/gui/Surface.h
@@ -134,6 +134,12 @@
status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
sp<Fence>* outFence, float outTransformMatrix[16]);
+ /* Enables or disables frame timestamp tracking. It is disabled by default
+ * to avoid overhead during queue and dequeue for applications that don't
+ * need the feature. If disabled, calls to getFrameTimestamps will fail.
+ */
+ void enableFrameTimestamps(bool enable);
+
// See IGraphicBufferProducer::getFrameTimestamps
status_t getFrameTimestamps(uint64_t frameNumber,
nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime,
@@ -192,6 +198,7 @@
int dispatchSetSurfaceDamage(va_list args);
int dispatchSetSharedBufferMode(va_list args);
int dispatchSetAutoRefresh(va_list args);
+ int dispatchEnableFrameTimestamps(va_list args);
int dispatchGetFrameTimestamps(va_list args);
protected:
@@ -390,6 +397,7 @@
mutable bool mFrameTimestampsSupportsRetire;
// A cached copy of the FrameEventHistory maintained by the consumer.
+ bool mEnableFrameTimestamps = false;
ProducerFrameEventHistory mFrameEventHistory;
};