Loading include/gui/FrameTimestamps.h +1 −2 Original line number Diff line number Diff line Loading @@ -54,8 +54,7 @@ struct FrameEvents { static constexpr auto EVENT_COUNT = static_cast<size_t>(FrameEvent::EVENT_COUNT); static_assert(EVENT_COUNT <= 32, "Event count sanity check failed."); static constexpr nsecs_t TIMESTAMP_PENDING = std::numeric_limits<nsecs_t>::max(); static constexpr nsecs_t TIMESTAMP_PENDING = -2; static inline bool isValidTimestamp(nsecs_t time) { return time != TIMESTAMP_PENDING; Loading include/gui/ISurfaceComposer.h +5 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,11 @@ public: virtual bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& surface) const = 0; /* Returns the frame timestamps supported by SurfaceFlinger. */ virtual status_t getSupportedFrameTimestamps( std::vector<FrameEvent>* outSupported) const = 0; /* set display power mode. depending on the mode, it can either trigger * screen on, off or low power mode and wait for it to complete. * requires ACCESS_SURFACE_FLINGER permission. Loading include/gui/Surface.h +4 −0 Original line number Diff line number Diff line Loading @@ -426,6 +426,10 @@ protected: uint64_t mNextFrameNumber = 1; uint64_t mLastFrameNumber = 0; // Mutable because ANativeWindow::query needs this class const. mutable bool mQueriedSupportedTimestamps; mutable bool mFrameTimestampsSupportsPresent; // A cached copy of the FrameEventHistory maintained by the consumer. bool mEnableFrameTimestamps = false; std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory; Loading libs/gui/ISurfaceComposer.cpp +63 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,50 @@ public: return result != 0; } virtual status_t getSupportedFrameTimestamps( std::vector<FrameEvent>* outSupported) const { if (!outSupported) { return UNEXPECTED_NULL; } outSupported->clear(); Parcel data, reply; status_t err = data.writeInterfaceToken( ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { return err; } err = remote()->transact( BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS, data, &reply); if (err != NO_ERROR) { return err; } int32_t result = 0; err = reply.readInt32(&result); if (err != NO_ERROR) { return err; } if (result != NO_ERROR) { return result; } std::vector<int32_t> supported; err = reply.readInt32Vector(&supported); if (err != NO_ERROR) { return err; } outSupported->reserve(supported.size()); for (int32_t s : supported) { outSupported->push_back(static_cast<FrameEvent>(s)); } return NO_ERROR; } virtual sp<IDisplayEventConnection> createDisplayEventConnection() { Parcel data, reply; Loading Loading @@ -536,6 +580,25 @@ status_t BnSurfaceComposer::onTransact( reply->writeInt32(result); return NO_ERROR; } case GET_SUPPORTED_FRAME_TIMESTAMPS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); std::vector<FrameEvent> supportedTimestamps; status_t result = getSupportedFrameTimestamps(&supportedTimestamps); status_t err = reply->writeInt32(result); if (err != NO_ERROR) { return err; } if (result != NO_ERROR) { return result; } std::vector<int32_t> supported; supported.reserve(supportedTimestamps.size()); for (FrameEvent s : supportedTimestamps) { supported.push_back(static_cast<int32_t>(s)); } return reply->writeInt32Vector(supported); } case CREATE_DISPLAY_EVENT_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IDisplayEventConnection> connection(createDisplayEventConnection()); Loading libs/gui/Surface.cpp +62 −11 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ Surface::Surface( mAutoRefresh(false), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), mSharedBufferHasBeenQueued(false), mQueriedSupportedTimestamps(false), mFrameTimestampsSupportsPresent(false), mEnableFrameTimestamps(false), mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) { Loading Loading @@ -209,8 +211,8 @@ static bool checkConsumerForUpdates( bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) && !e->hasDisplayPresentInfo(); // LastRefreshStart, DequeueReady, and Release are never // available for the last frame. // LastRefreshStart, DequeueReady, and Release are never available for the // last frame. bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) && !e->hasLastRefreshStartInfo() && (e->frameNumber != lastFrameNumber); Loading @@ -227,14 +229,26 @@ static bool checkConsumerForUpdates( static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { if (dst != nullptr) { *dst = FrameEvents::isValidTimestamp(src) ? src : 0; // We always get valid timestamps for these eventually. *dst = (src == FrameEvents::TIMESTAMP_PENDING) ? NATIVE_WINDOW_TIMESTAMP_PENDING : src; } } static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src) { static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) { if (dst != nullptr) { if (!fenceShouldBeKnown) { *dst = NATIVE_WINDOW_TIMESTAMP_PENDING; return; } nsecs_t signalTime = src->getSignalTime(); *dst = Fence::isValidTimestamp(signalTime) ? signalTime : 0; *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ? NATIVE_WINDOW_TIMESTAMP_PENDING : (signalTime == Fence::SIGNAL_TIME_INVALID) ? NATIVE_WINDOW_TIMESTAMP_INVALID : signalTime; } } Loading @@ -252,6 +266,12 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, return INVALID_OPERATION; } // Verify the requested timestamps are supported. querySupportedTimestampsLocked(); if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { return BAD_VALUE; } FrameEvents* events = mFrameEventHistory->getFrame(frameNumber); if (events == nullptr) { // If the entry isn't available in the producer, it's definitely not Loading Loading @@ -282,12 +302,15 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime); getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime); getFrameTimestampFence(outAcquireTime, events->acquireFence); getFrameTimestampFence( outGpuCompositionDoneTime, events->gpuCompositionDoneFence); getFrameTimestampFence( outDisplayPresentTime, events->displayPresentFence); getFrameTimestampFence(outReleaseTime, events->releaseFence); getFrameTimestampFence(outAcquireTime, events->acquireFence, events->hasAcquireInfo()); getFrameTimestampFence(outGpuCompositionDoneTime, events->gpuCompositionDoneFence, events->hasGpuCompositionDoneInfo()); getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence, events->hasDisplayPresentInfo()); getFrameTimestampFence(outReleaseTime, events->releaseFence, events->hasReleaseInfo()); return NO_ERROR; } Loading Loading @@ -739,6 +762,29 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { return err; } void Surface::querySupportedTimestampsLocked() const { // mMutex must be locked when calling this method. if (mQueriedSupportedTimestamps) { return; } mQueriedSupportedTimestamps = true; std::vector<FrameEvent> supportedFrameTimestamps; status_t err = composerService()->getSupportedFrameTimestamps( &supportedFrameTimestamps); if (err != NO_ERROR) { return; } for (auto sft : supportedFrameTimestamps) { if (sft == FrameEvent::DISPLAY_PRESENT) { mFrameTimestampsSupportsPresent = true; } } } int Surface::query(int what, int* value) const { ATRACE_CALL(); ALOGV("Surface::query"); Loading Loading @@ -800,6 +846,11 @@ int Surface::query(int what, int* value) const { static_cast<int>(durationUs); return NO_ERROR; } case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: { querySupportedTimestampsLocked(); *value = mFrameTimestampsSupportsPresent ? 1 : 0; return NO_ERROR; } case NATIVE_WINDOW_IS_VALID: { *value = mGraphicBufferProducer != nullptr ? 1 : 0; return NO_ERROR; Loading Loading
include/gui/FrameTimestamps.h +1 −2 Original line number Diff line number Diff line Loading @@ -54,8 +54,7 @@ struct FrameEvents { static constexpr auto EVENT_COUNT = static_cast<size_t>(FrameEvent::EVENT_COUNT); static_assert(EVENT_COUNT <= 32, "Event count sanity check failed."); static constexpr nsecs_t TIMESTAMP_PENDING = std::numeric_limits<nsecs_t>::max(); static constexpr nsecs_t TIMESTAMP_PENDING = -2; static inline bool isValidTimestamp(nsecs_t time) { return time != TIMESTAMP_PENDING; Loading
include/gui/ISurfaceComposer.h +5 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,11 @@ public: virtual bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& surface) const = 0; /* Returns the frame timestamps supported by SurfaceFlinger. */ virtual status_t getSupportedFrameTimestamps( std::vector<FrameEvent>* outSupported) const = 0; /* set display power mode. depending on the mode, it can either trigger * screen on, off or low power mode and wait for it to complete. * requires ACCESS_SURFACE_FLINGER permission. Loading
include/gui/Surface.h +4 −0 Original line number Diff line number Diff line Loading @@ -426,6 +426,10 @@ protected: uint64_t mNextFrameNumber = 1; uint64_t mLastFrameNumber = 0; // Mutable because ANativeWindow::query needs this class const. mutable bool mQueriedSupportedTimestamps; mutable bool mFrameTimestampsSupportsPresent; // A cached copy of the FrameEventHistory maintained by the consumer. bool mEnableFrameTimestamps = false; std::unique_ptr<ProducerFrameEventHistory> mFrameEventHistory; Loading
libs/gui/ISurfaceComposer.cpp +63 −0 Original line number Diff line number Diff line Loading @@ -166,6 +166,50 @@ public: return result != 0; } virtual status_t getSupportedFrameTimestamps( std::vector<FrameEvent>* outSupported) const { if (!outSupported) { return UNEXPECTED_NULL; } outSupported->clear(); Parcel data, reply; status_t err = data.writeInterfaceToken( ISurfaceComposer::getInterfaceDescriptor()); if (err != NO_ERROR) { return err; } err = remote()->transact( BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS, data, &reply); if (err != NO_ERROR) { return err; } int32_t result = 0; err = reply.readInt32(&result); if (err != NO_ERROR) { return err; } if (result != NO_ERROR) { return result; } std::vector<int32_t> supported; err = reply.readInt32Vector(&supported); if (err != NO_ERROR) { return err; } outSupported->reserve(supported.size()); for (int32_t s : supported) { outSupported->push_back(static_cast<FrameEvent>(s)); } return NO_ERROR; } virtual sp<IDisplayEventConnection> createDisplayEventConnection() { Parcel data, reply; Loading Loading @@ -536,6 +580,25 @@ status_t BnSurfaceComposer::onTransact( reply->writeInt32(result); return NO_ERROR; } case GET_SUPPORTED_FRAME_TIMESTAMPS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); std::vector<FrameEvent> supportedTimestamps; status_t result = getSupportedFrameTimestamps(&supportedTimestamps); status_t err = reply->writeInt32(result); if (err != NO_ERROR) { return err; } if (result != NO_ERROR) { return result; } std::vector<int32_t> supported; supported.reserve(supportedTimestamps.size()); for (FrameEvent s : supportedTimestamps) { supported.push_back(static_cast<int32_t>(s)); } return reply->writeInt32Vector(supported); } case CREATE_DISPLAY_EVENT_CONNECTION: { CHECK_INTERFACE(ISurfaceComposer, data, reply); sp<IDisplayEventConnection> connection(createDisplayEventConnection()); Loading
libs/gui/Surface.cpp +62 −11 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ Surface::Surface( mAutoRefresh(false), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), mSharedBufferHasBeenQueued(false), mQueriedSupportedTimestamps(false), mFrameTimestampsSupportsPresent(false), mEnableFrameTimestamps(false), mFrameEventHistory(std::make_unique<ProducerFrameEventHistory>()) { Loading Loading @@ -209,8 +211,8 @@ static bool checkConsumerForUpdates( bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) && !e->hasDisplayPresentInfo(); // LastRefreshStart, DequeueReady, and Release are never // available for the last frame. // LastRefreshStart, DequeueReady, and Release are never available for the // last frame. bool checkForLastRefreshStart = (outLastRefreshStartTime != nullptr) && !e->hasLastRefreshStartInfo() && (e->frameNumber != lastFrameNumber); Loading @@ -227,14 +229,26 @@ static bool checkConsumerForUpdates( static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) { if (dst != nullptr) { *dst = FrameEvents::isValidTimestamp(src) ? src : 0; // We always get valid timestamps for these eventually. *dst = (src == FrameEvents::TIMESTAMP_PENDING) ? NATIVE_WINDOW_TIMESTAMP_PENDING : src; } } static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src) { static void getFrameTimestampFence(nsecs_t *dst, const std::shared_ptr<FenceTime>& src, bool fenceShouldBeKnown) { if (dst != nullptr) { if (!fenceShouldBeKnown) { *dst = NATIVE_WINDOW_TIMESTAMP_PENDING; return; } nsecs_t signalTime = src->getSignalTime(); *dst = Fence::isValidTimestamp(signalTime) ? signalTime : 0; *dst = (signalTime == Fence::SIGNAL_TIME_PENDING) ? NATIVE_WINDOW_TIMESTAMP_PENDING : (signalTime == Fence::SIGNAL_TIME_INVALID) ? NATIVE_WINDOW_TIMESTAMP_INVALID : signalTime; } } Loading @@ -252,6 +266,12 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, return INVALID_OPERATION; } // Verify the requested timestamps are supported. querySupportedTimestampsLocked(); if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { return BAD_VALUE; } FrameEvents* events = mFrameEventHistory->getFrame(frameNumber); if (events == nullptr) { // If the entry isn't available in the producer, it's definitely not Loading Loading @@ -282,12 +302,15 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, getFrameTimestamp(outLastRefreshStartTime, events->lastRefreshStartTime); getFrameTimestamp(outDequeueReadyTime, events->dequeueReadyTime); getFrameTimestampFence(outAcquireTime, events->acquireFence); getFrameTimestampFence( outGpuCompositionDoneTime, events->gpuCompositionDoneFence); getFrameTimestampFence( outDisplayPresentTime, events->displayPresentFence); getFrameTimestampFence(outReleaseTime, events->releaseFence); getFrameTimestampFence(outAcquireTime, events->acquireFence, events->hasAcquireInfo()); getFrameTimestampFence(outGpuCompositionDoneTime, events->gpuCompositionDoneFence, events->hasGpuCompositionDoneInfo()); getFrameTimestampFence(outDisplayPresentTime, events->displayPresentFence, events->hasDisplayPresentInfo()); getFrameTimestampFence(outReleaseTime, events->releaseFence, events->hasReleaseInfo()); return NO_ERROR; } Loading Loading @@ -739,6 +762,29 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) { return err; } void Surface::querySupportedTimestampsLocked() const { // mMutex must be locked when calling this method. if (mQueriedSupportedTimestamps) { return; } mQueriedSupportedTimestamps = true; std::vector<FrameEvent> supportedFrameTimestamps; status_t err = composerService()->getSupportedFrameTimestamps( &supportedFrameTimestamps); if (err != NO_ERROR) { return; } for (auto sft : supportedFrameTimestamps) { if (sft == FrameEvent::DISPLAY_PRESENT) { mFrameTimestampsSupportsPresent = true; } } } int Surface::query(int what, int* value) const { ATRACE_CALL(); ALOGV("Surface::query"); Loading Loading @@ -800,6 +846,11 @@ int Surface::query(int what, int* value) const { static_cast<int>(durationUs); return NO_ERROR; } case NATIVE_WINDOW_FRAME_TIMESTAMPS_SUPPORTS_PRESENT: { querySupportedTimestampsLocked(); *value = mFrameTimestampsSupportsPresent ? 1 : 0; return NO_ERROR; } case NATIVE_WINDOW_IS_VALID: { *value = mGraphicBufferProducer != nullptr ? 1 : 0; return NO_ERROR; Loading