Loading include/gui/BufferQueue.h +3 −2 Original line number Diff line number Diff line Loading @@ -66,8 +66,9 @@ public: virtual void onFrameReplaced(const BufferItem& item) override; virtual void onBuffersReleased() override; virtual void onSidebandStreamChanged() override; virtual bool getFrameTimestamps(uint64_t frameNumber, FrameTimestamps* outTimestamps) const override; virtual bool addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, uint64_t frameNumber, FrameTimestamps* outTimestamps) override; private: // mConsumerListener is a weak reference to the IConsumerListener. This is // the raison d'etre of ProxyConsumerListener. Loading include/gui/BufferQueueProducer.h +5 −1 Original line number Diff line number Diff line Loading @@ -178,7 +178,7 @@ public: // See IGraphicBufferProducer::getFrameTimestamps virtual bool getFrameTimestamps(uint64_t frameNumber, FrameTimestamps* outTimestamps) const override; FrameTimestamps* outTimestamps) override; // See IGraphicBufferProducer::getUniqueId virtual status_t getUniqueId(uint64_t* outId) const override; Loading @@ -195,6 +195,10 @@ private: // BufferQueueCore::INVALID_BUFFER_SLOT otherwise int getFreeSlotLocked() const; bool addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, uint64_t frameNumber, FrameTimestamps* outTimestamps); // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may // block if there are no available slots and we are not in non-blocking // mode (producer and consumer controlled by the application). If it blocks, Loading include/gui/FrameTimestamps.h +83 −1 Original line number Diff line number Diff line Loading @@ -17,11 +17,20 @@ #ifndef ANDROID_GUI_FRAMETIMESTAMPS_H #define ANDROID_GUI_FRAMETIMESTAMPS_H #include <utils/Timers.h> #include <ui/Fence.h> #include <utils/Flattenable.h> #include <utils/StrongPointer.h> #include <utils/Timers.h> #include <array> namespace android { struct FrameEvents; class String8; enum class SupportableFrameTimestamps { REQUESTED_PRESENT, ACQUIRE, Loading @@ -32,8 +41,14 @@ enum class SupportableFrameTimestamps { RELEASE_TIME, }; // The timestamps the consumer sends to the producer over binder. struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { FrameTimestamps() = default; explicit FrameTimestamps(const FrameEvents& fences); uint64_t frameNumber{0}; nsecs_t postedTime{0}; nsecs_t requestedPresentTime{0}; nsecs_t acquireTime{0}; nsecs_t refreshStartTime{0}; Loading @@ -43,5 +58,72 @@ struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { nsecs_t releaseTime{0}; }; // A collection of timestamps corresponding to a single frame. struct FrameEvents { void checkFencesForCompletion(); void dump(String8& outString) const; bool valid{false}; uint64_t frameNumber{0}; // Whether or not certain points in the frame's life cycle have been // encountered help us determine if timestamps aren't available because // a) we'll just never get them or b) they're not ready yet. bool addPostCompositeCalled{false}; bool addRetireCalled{false}; nsecs_t postedTime{0}; nsecs_t requestedPresentTime{0}; nsecs_t latchTime{0}; nsecs_t firstRefreshStartTime{0}; nsecs_t lastRefreshStartTime{0}; nsecs_t acquireTime{0}; nsecs_t gpuCompositionDoneTime{0}; nsecs_t displayPresentTime{0}; nsecs_t displayRetireTime{0}; nsecs_t releaseTime{0}; sp<Fence> acquireFence{Fence::NO_FENCE}; sp<Fence> gpuCompositionDoneFence{Fence::NO_FENCE}; sp<Fence> displayPresentFence{Fence::NO_FENCE}; sp<Fence> displayRetireFence{Fence::NO_FENCE}; sp<Fence> releaseFence{Fence::NO_FENCE}; }; struct NewFrameEventsEntry { uint64_t frameNumber{0}; nsecs_t postedTime{0}; nsecs_t requestedPresentTime{0}; sp<Fence> acquireFence{Fence::NO_FENCE}; }; class FrameEventHistory { public: FrameEvents* getFrame(uint64_t frameNumber); FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint); void checkFencesForCompletion(); void dump(String8& outString) const; void addQueue(const NewFrameEventsEntry& newFrameEntry); void addLatch(uint64_t frameNumber, nsecs_t latchTime); void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime); void addPostComposition(uint64_t frameNumber, sp<Fence> gpuCompositionDone, sp<Fence> displayPresent); void addRetire(uint64_t frameNumber, sp<Fence> displayRetire); void addRelease(uint64_t frameNumber, sp<Fence> release); private: static constexpr size_t MAX_FRAME_HISTORY = 8; std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames; size_t mQueueOffset{0}; size_t mCompositionOffset{0}; size_t mRetireOffset{0}; size_t mReleaseOffset{0}; }; } // namespace android #endif include/gui/IConsumerListener.h +7 −4 Original line number Diff line number Diff line Loading @@ -82,10 +82,13 @@ public: // different stream. virtual void onSidebandStreamChanged() = 0; /* Asynchronous */ // See IGraphicBufferProducer::getFrameTimestamps // This queries the consumer for the timestamps virtual bool getFrameTimestamps(uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) const { return false; } // Notifies the consumer of any new producer-side events and then queries // the consumer timestamps virtual bool addAndGetFrameTimestamps( const NewFrameEventsEntry* /*newTimestamps*/, uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) { return false; } }; Loading include/gui/IGraphicBufferProducer.h +1 −1 Original line number Diff line number Diff line Loading @@ -594,7 +594,7 @@ public: // // If a fence has not yet signaled the timestamp returned will be 0; virtual bool getFrameTimestamps(uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) const { return false; } FrameTimestamps* /*outTimestamps*/) { return false; } // Returns a unique id for this BufferQueue virtual status_t getUniqueId(uint64_t* outId) const = 0; Loading Loading
include/gui/BufferQueue.h +3 −2 Original line number Diff line number Diff line Loading @@ -66,8 +66,9 @@ public: virtual void onFrameReplaced(const BufferItem& item) override; virtual void onBuffersReleased() override; virtual void onSidebandStreamChanged() override; virtual bool getFrameTimestamps(uint64_t frameNumber, FrameTimestamps* outTimestamps) const override; virtual bool addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, uint64_t frameNumber, FrameTimestamps* outTimestamps) override; private: // mConsumerListener is a weak reference to the IConsumerListener. This is // the raison d'etre of ProxyConsumerListener. Loading
include/gui/BufferQueueProducer.h +5 −1 Original line number Diff line number Diff line Loading @@ -178,7 +178,7 @@ public: // See IGraphicBufferProducer::getFrameTimestamps virtual bool getFrameTimestamps(uint64_t frameNumber, FrameTimestamps* outTimestamps) const override; FrameTimestamps* outTimestamps) override; // See IGraphicBufferProducer::getUniqueId virtual status_t getUniqueId(uint64_t* outId) const override; Loading @@ -195,6 +195,10 @@ private: // BufferQueueCore::INVALID_BUFFER_SLOT otherwise int getFreeSlotLocked() const; bool addAndGetFrameTimestamps( const NewFrameEventsEntry* newTimestamps, uint64_t frameNumber, FrameTimestamps* outTimestamps); // waitForFreeSlotThenRelock finds the oldest slot in the FREE state. It may // block if there are no available slots and we are not in non-blocking // mode (producer and consumer controlled by the application). If it blocks, Loading
include/gui/FrameTimestamps.h +83 −1 Original line number Diff line number Diff line Loading @@ -17,11 +17,20 @@ #ifndef ANDROID_GUI_FRAMETIMESTAMPS_H #define ANDROID_GUI_FRAMETIMESTAMPS_H #include <utils/Timers.h> #include <ui/Fence.h> #include <utils/Flattenable.h> #include <utils/StrongPointer.h> #include <utils/Timers.h> #include <array> namespace android { struct FrameEvents; class String8; enum class SupportableFrameTimestamps { REQUESTED_PRESENT, ACQUIRE, Loading @@ -32,8 +41,14 @@ enum class SupportableFrameTimestamps { RELEASE_TIME, }; // The timestamps the consumer sends to the producer over binder. struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { FrameTimestamps() = default; explicit FrameTimestamps(const FrameEvents& fences); uint64_t frameNumber{0}; nsecs_t postedTime{0}; nsecs_t requestedPresentTime{0}; nsecs_t acquireTime{0}; nsecs_t refreshStartTime{0}; Loading @@ -43,5 +58,72 @@ struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { nsecs_t releaseTime{0}; }; // A collection of timestamps corresponding to a single frame. struct FrameEvents { void checkFencesForCompletion(); void dump(String8& outString) const; bool valid{false}; uint64_t frameNumber{0}; // Whether or not certain points in the frame's life cycle have been // encountered help us determine if timestamps aren't available because // a) we'll just never get them or b) they're not ready yet. bool addPostCompositeCalled{false}; bool addRetireCalled{false}; nsecs_t postedTime{0}; nsecs_t requestedPresentTime{0}; nsecs_t latchTime{0}; nsecs_t firstRefreshStartTime{0}; nsecs_t lastRefreshStartTime{0}; nsecs_t acquireTime{0}; nsecs_t gpuCompositionDoneTime{0}; nsecs_t displayPresentTime{0}; nsecs_t displayRetireTime{0}; nsecs_t releaseTime{0}; sp<Fence> acquireFence{Fence::NO_FENCE}; sp<Fence> gpuCompositionDoneFence{Fence::NO_FENCE}; sp<Fence> displayPresentFence{Fence::NO_FENCE}; sp<Fence> displayRetireFence{Fence::NO_FENCE}; sp<Fence> releaseFence{Fence::NO_FENCE}; }; struct NewFrameEventsEntry { uint64_t frameNumber{0}; nsecs_t postedTime{0}; nsecs_t requestedPresentTime{0}; sp<Fence> acquireFence{Fence::NO_FENCE}; }; class FrameEventHistory { public: FrameEvents* getFrame(uint64_t frameNumber); FrameEvents* getFrame(uint64_t frameNumber, size_t* iHint); void checkFencesForCompletion(); void dump(String8& outString) const; void addQueue(const NewFrameEventsEntry& newFrameEntry); void addLatch(uint64_t frameNumber, nsecs_t latchTime); void addPreComposition(uint64_t frameNumber, nsecs_t refreshStartTime); void addPostComposition(uint64_t frameNumber, sp<Fence> gpuCompositionDone, sp<Fence> displayPresent); void addRetire(uint64_t frameNumber, sp<Fence> displayRetire); void addRelease(uint64_t frameNumber, sp<Fence> release); private: static constexpr size_t MAX_FRAME_HISTORY = 8; std::array<FrameEvents, MAX_FRAME_HISTORY> mFrames; size_t mQueueOffset{0}; size_t mCompositionOffset{0}; size_t mRetireOffset{0}; size_t mReleaseOffset{0}; }; } // namespace android #endif
include/gui/IConsumerListener.h +7 −4 Original line number Diff line number Diff line Loading @@ -82,10 +82,13 @@ public: // different stream. virtual void onSidebandStreamChanged() = 0; /* Asynchronous */ // See IGraphicBufferProducer::getFrameTimestamps // This queries the consumer for the timestamps virtual bool getFrameTimestamps(uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) const { return false; } // Notifies the consumer of any new producer-side events and then queries // the consumer timestamps virtual bool addAndGetFrameTimestamps( const NewFrameEventsEntry* /*newTimestamps*/, uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) { return false; } }; Loading
include/gui/IGraphicBufferProducer.h +1 −1 Original line number Diff line number Diff line Loading @@ -594,7 +594,7 @@ public: // // If a fence has not yet signaled the timestamp returned will be 0; virtual bool getFrameTimestamps(uint64_t /*frameNumber*/, FrameTimestamps* /*outTimestamps*/) const { return false; } FrameTimestamps* /*outTimestamps*/) { return false; } // Returns a unique id for this BufferQueue virtual status_t getUniqueId(uint64_t* outId) const = 0; Loading