Loading include/gui/FrameTimestamps.h +18 −16 Original line number Diff line number Diff line Loading @@ -22,23 +22,25 @@ namespace android { struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { FrameTimestamps() : frameNumber(0), requestedPresentTime(0), acquireTime(0), refreshStartTime(0), glCompositionDoneTime(0), displayRetireTime(0), releaseTime(0) {} enum class SupportableFrameTimestamps { REQUESTED_PRESENT, ACQUIRE, REFRESH_START, GL_COMPOSITION_DONE_TIME, DISPLAY_PRESENT_TIME, DISPLAY_RETIRE_TIME, RELEASE_TIME, }; uint64_t frameNumber; nsecs_t requestedPresentTime; nsecs_t acquireTime; nsecs_t refreshStartTime; nsecs_t glCompositionDoneTime; nsecs_t displayRetireTime; nsecs_t releaseTime; struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { uint64_t frameNumber{0}; nsecs_t requestedPresentTime{0}; nsecs_t acquireTime{0}; nsecs_t refreshStartTime{0}; nsecs_t glCompositionDoneTime{0}; nsecs_t displayPresentTime{0}; nsecs_t displayRetireTime{0}; nsecs_t releaseTime{0}; }; } // namespace android Loading include/gui/ISurfaceComposer.h +9 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceComposerClient.h> #include <vector> namespace android { // ---------------------------------------------------------------------------- Loading @@ -43,6 +45,7 @@ class HdrCapabilities; class IDisplayEventConnection; class IMemoryHeap; class Rect; enum class SupportableFrameTimestamps; /* * This class defines the Binder IPC interface for accessing various Loading Loading @@ -112,6 +115,11 @@ public: virtual bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& surface) const = 0; /* Returns the frame timestamps supported by SurfaceFlinger. */ virtual status_t getSupportedFrameTimestamps( std::vector<SupportableFrameTimestamps>* 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 Loading @@ -193,6 +201,7 @@ public: GET_BUILT_IN_DISPLAY, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, GET_SUPPORTED_FRAME_TIMESTAMPS, GET_DISPLAY_CONFIGS, GET_ACTIVE_CONFIG, SET_ACTIVE_CONFIG, Loading include/gui/Surface.h +10 −2 Original line number Diff line number Diff line Loading @@ -135,10 +135,11 @@ public: sp<Fence>* outFence, float outTransformMatrix[16]); // See IGraphicBufferProducer::getFrameTimestamps bool getFrameTimestamps(uint64_t frameNumber, status_t getFrameTimestamps(uint64_t frameNumber, nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime); nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime); status_t getUniqueId(uint64_t* outId) const; Loading Loading @@ -238,6 +239,8 @@ protected: enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; private: void querySupportedTimestampsLocked() const; void freeAllBuffers(); int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; Loading Loading @@ -380,6 +383,11 @@ private: Condition mQueueBufferCondition; uint64_t mNextFrameNumber; // Mutable because ANativeWindow::query needs this class const. mutable bool mQueriedSupportedTimestamps; mutable bool mFrameTimestampsSupportsPresent; mutable bool mFrameTimestampsSupportsRetire; }; namespace view { Loading libs/gui/ISurfaceComposer.cpp +63 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,50 @@ public: return result != 0; } virtual status_t getSupportedFrameTimestamps( std::vector<SupportableFrameTimestamps>* 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<SupportableFrameTimestamps>(s)); } return NO_ERROR; } virtual sp<IDisplayEventConnection> createDisplayEventConnection() { Parcel data, reply; Loading Loading @@ -520,6 +564,25 @@ status_t BnSurfaceComposer::onTransact( reply->writeInt32(result); return NO_ERROR; } case GET_SUPPORTED_FRAME_TIMESTAMPS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); std::vector<SupportableFrameTimestamps> 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 (SupportableFrameTimestamps 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 +87 −27 Original line number Diff line number Diff line Loading @@ -49,7 +49,10 @@ Surface::Surface( mAutoRefresh(false), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), mSharedBufferHasBeenQueued(false), mNextFrameNumber(1) mNextFrameNumber(1), mQueriedSupportedTimestamps(false), mFrameTimestampsSupportsPresent(false), mFrameTimestampsSupportsRetire(false) { // Initialize the ANativeWindow function pointers. ANativeWindow::setSwapInterval = hook_setSwapInterval; Loading Loading @@ -135,16 +138,34 @@ status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, outTransformMatrix); } bool Surface::getFrameTimestamps(uint64_t frameNumber, status_t Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime) { nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime) { ATRACE_CALL(); { Mutex::Autolock lock(mMutex); // Verify the requested timestamps are supported. querySupportedTimestampsLocked(); if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { return BAD_VALUE; } if (outDisplayRetireTime != nullptr && !mFrameTimestampsSupportsRetire) { return BAD_VALUE; } } FrameTimestamps timestamps; bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber, ×tamps); if (found) { if (!found) { return NAME_NOT_FOUND; } if (outRequestedPresentTime) { *outRequestedPresentTime = timestamps.requestedPresentTime; } Loading @@ -157,15 +178,17 @@ bool Surface::getFrameTimestamps(uint64_t frameNumber, if (outGlCompositionDoneTime) { *outGlCompositionDoneTime = timestamps.glCompositionDoneTime; } if (outDisplayPresentTime) { *outDisplayPresentTime = timestamps.displayPresentTime; } if (outDisplayRetireTime) { *outDisplayRetireTime = timestamps.displayRetireTime; } if (outReleaseTime) { *outReleaseTime = timestamps.releaseTime; } return true; } return false; return NO_ERROR; } int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { Loading Loading @@ -533,6 +556,32 @@ 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<SupportableFrameTimestamps> supportedFrameTimestamps; sp<ISurfaceComposer> composer(ComposerService::getComposerService()); status_t err = composer->getSupportedFrameTimestamps( &supportedFrameTimestamps); if (err != NO_ERROR) { return; } for (auto sft : supportedFrameTimestamps) { if (sft == SupportableFrameTimestamps::DISPLAY_PRESENT_TIME) { mFrameTimestampsSupportsPresent = true; } else if (sft == SupportableFrameTimestamps::DISPLAY_RETIRE_TIME) { mFrameTimestampsSupportsRetire = true; } } } int Surface::query(int what, int* value) const { ATRACE_CALL(); ALOGV("Surface::query"); Loading Loading @@ -595,6 +644,16 @@ 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_FRAME_TIMESTAMPS_SUPPORTS_RETIRE: { querySupportedTimestampsLocked(); *value = mFrameTimestampsSupportsRetire ? 1 : 0; return NO_ERROR; } } } return mGraphicBufferProducer->query(what, value); Loading Loading @@ -799,12 +858,13 @@ int Surface::dispatchGetFrameTimestamps(va_list args) { nsecs_t* outAcquireTime = va_arg(args, int64_t*); nsecs_t* outRefreshStartTime = va_arg(args, int64_t*); nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*); nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*); nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*); nsecs_t* outReleaseTime = va_arg(args, int64_t*); bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo, return getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo, outRequestedPresentTime, outAcquireTime, outRefreshStartTime, outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime); return ret ? NO_ERROR : BAD_VALUE; outGlCompositionDoneTime, outDisplayPresentTime, outDisplayRetireTime, outReleaseTime); } int Surface::connect(int api) { Loading Loading
include/gui/FrameTimestamps.h +18 −16 Original line number Diff line number Diff line Loading @@ -22,23 +22,25 @@ namespace android { struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { FrameTimestamps() : frameNumber(0), requestedPresentTime(0), acquireTime(0), refreshStartTime(0), glCompositionDoneTime(0), displayRetireTime(0), releaseTime(0) {} enum class SupportableFrameTimestamps { REQUESTED_PRESENT, ACQUIRE, REFRESH_START, GL_COMPOSITION_DONE_TIME, DISPLAY_PRESENT_TIME, DISPLAY_RETIRE_TIME, RELEASE_TIME, }; uint64_t frameNumber; nsecs_t requestedPresentTime; nsecs_t acquireTime; nsecs_t refreshStartTime; nsecs_t glCompositionDoneTime; nsecs_t displayRetireTime; nsecs_t releaseTime; struct FrameTimestamps : public LightFlattenablePod<FrameTimestamps> { uint64_t frameNumber{0}; nsecs_t requestedPresentTime{0}; nsecs_t acquireTime{0}; nsecs_t refreshStartTime{0}; nsecs_t glCompositionDoneTime{0}; nsecs_t displayPresentTime{0}; nsecs_t displayRetireTime{0}; nsecs_t releaseTime{0}; }; } // namespace android Loading
include/gui/ISurfaceComposer.h +9 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ #include <gui/IGraphicBufferAlloc.h> #include <gui/ISurfaceComposerClient.h> #include <vector> namespace android { // ---------------------------------------------------------------------------- Loading @@ -43,6 +45,7 @@ class HdrCapabilities; class IDisplayEventConnection; class IMemoryHeap; class Rect; enum class SupportableFrameTimestamps; /* * This class defines the Binder IPC interface for accessing various Loading Loading @@ -112,6 +115,11 @@ public: virtual bool authenticateSurfaceTexture( const sp<IGraphicBufferProducer>& surface) const = 0; /* Returns the frame timestamps supported by SurfaceFlinger. */ virtual status_t getSupportedFrameTimestamps( std::vector<SupportableFrameTimestamps>* 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 Loading @@ -193,6 +201,7 @@ public: GET_BUILT_IN_DISPLAY, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, GET_SUPPORTED_FRAME_TIMESTAMPS, GET_DISPLAY_CONFIGS, GET_ACTIVE_CONFIG, SET_ACTIVE_CONFIG, Loading
include/gui/Surface.h +10 −2 Original line number Diff line number Diff line Loading @@ -135,10 +135,11 @@ public: sp<Fence>* outFence, float outTransformMatrix[16]); // See IGraphicBufferProducer::getFrameTimestamps bool getFrameTimestamps(uint64_t frameNumber, status_t getFrameTimestamps(uint64_t frameNumber, nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime); nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime); status_t getUniqueId(uint64_t* outId) const; Loading Loading @@ -238,6 +239,8 @@ protected: enum { DEFAULT_FORMAT = PIXEL_FORMAT_RGBA_8888 }; private: void querySupportedTimestampsLocked() const; void freeAllBuffers(); int getSlotFromBufferLocked(android_native_buffer_t* buffer) const; Loading Loading @@ -380,6 +383,11 @@ private: Condition mQueueBufferCondition; uint64_t mNextFrameNumber; // Mutable because ANativeWindow::query needs this class const. mutable bool mQueriedSupportedTimestamps; mutable bool mFrameTimestampsSupportsPresent; mutable bool mFrameTimestampsSupportsRetire; }; namespace view { Loading
libs/gui/ISurfaceComposer.cpp +63 −0 Original line number Diff line number Diff line Loading @@ -158,6 +158,50 @@ public: return result != 0; } virtual status_t getSupportedFrameTimestamps( std::vector<SupportableFrameTimestamps>* 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<SupportableFrameTimestamps>(s)); } return NO_ERROR; } virtual sp<IDisplayEventConnection> createDisplayEventConnection() { Parcel data, reply; Loading Loading @@ -520,6 +564,25 @@ status_t BnSurfaceComposer::onTransact( reply->writeInt32(result); return NO_ERROR; } case GET_SUPPORTED_FRAME_TIMESTAMPS: { CHECK_INTERFACE(ISurfaceComposer, data, reply); std::vector<SupportableFrameTimestamps> 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 (SupportableFrameTimestamps 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 +87 −27 Original line number Diff line number Diff line Loading @@ -49,7 +49,10 @@ Surface::Surface( mAutoRefresh(false), mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT), mSharedBufferHasBeenQueued(false), mNextFrameNumber(1) mNextFrameNumber(1), mQueriedSupportedTimestamps(false), mFrameTimestampsSupportsPresent(false), mFrameTimestampsSupportsRetire(false) { // Initialize the ANativeWindow function pointers. ANativeWindow::setSwapInterval = hook_setSwapInterval; Loading Loading @@ -135,16 +138,34 @@ status_t Surface::getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer, outTransformMatrix); } bool Surface::getFrameTimestamps(uint64_t frameNumber, status_t Surface::getFrameTimestamps(uint64_t frameNumber, nsecs_t* outRequestedPresentTime, nsecs_t* outAcquireTime, nsecs_t* outRefreshStartTime, nsecs_t* outGlCompositionDoneTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime) { nsecs_t* outDisplayPresentTime, nsecs_t* outDisplayRetireTime, nsecs_t* outReleaseTime) { ATRACE_CALL(); { Mutex::Autolock lock(mMutex); // Verify the requested timestamps are supported. querySupportedTimestampsLocked(); if (outDisplayPresentTime != nullptr && !mFrameTimestampsSupportsPresent) { return BAD_VALUE; } if (outDisplayRetireTime != nullptr && !mFrameTimestampsSupportsRetire) { return BAD_VALUE; } } FrameTimestamps timestamps; bool found = mGraphicBufferProducer->getFrameTimestamps(frameNumber, ×tamps); if (found) { if (!found) { return NAME_NOT_FOUND; } if (outRequestedPresentTime) { *outRequestedPresentTime = timestamps.requestedPresentTime; } Loading @@ -157,15 +178,17 @@ bool Surface::getFrameTimestamps(uint64_t frameNumber, if (outGlCompositionDoneTime) { *outGlCompositionDoneTime = timestamps.glCompositionDoneTime; } if (outDisplayPresentTime) { *outDisplayPresentTime = timestamps.displayPresentTime; } if (outDisplayRetireTime) { *outDisplayRetireTime = timestamps.displayRetireTime; } if (outReleaseTime) { *outReleaseTime = timestamps.releaseTime; } return true; } return false; return NO_ERROR; } int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) { Loading Loading @@ -533,6 +556,32 @@ 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<SupportableFrameTimestamps> supportedFrameTimestamps; sp<ISurfaceComposer> composer(ComposerService::getComposerService()); status_t err = composer->getSupportedFrameTimestamps( &supportedFrameTimestamps); if (err != NO_ERROR) { return; } for (auto sft : supportedFrameTimestamps) { if (sft == SupportableFrameTimestamps::DISPLAY_PRESENT_TIME) { mFrameTimestampsSupportsPresent = true; } else if (sft == SupportableFrameTimestamps::DISPLAY_RETIRE_TIME) { mFrameTimestampsSupportsRetire = true; } } } int Surface::query(int what, int* value) const { ATRACE_CALL(); ALOGV("Surface::query"); Loading Loading @@ -595,6 +644,16 @@ 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_FRAME_TIMESTAMPS_SUPPORTS_RETIRE: { querySupportedTimestampsLocked(); *value = mFrameTimestampsSupportsRetire ? 1 : 0; return NO_ERROR; } } } return mGraphicBufferProducer->query(what, value); Loading Loading @@ -799,12 +858,13 @@ int Surface::dispatchGetFrameTimestamps(va_list args) { nsecs_t* outAcquireTime = va_arg(args, int64_t*); nsecs_t* outRefreshStartTime = va_arg(args, int64_t*); nsecs_t* outGlCompositionDoneTime = va_arg(args, int64_t*); nsecs_t* outDisplayPresentTime = va_arg(args, int64_t*); nsecs_t* outDisplayRetireTime = va_arg(args, int64_t*); nsecs_t* outReleaseTime = va_arg(args, int64_t*); bool ret = getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo, return getFrameTimestamps(getNextFrameNumber() - 1 - framesAgo, outRequestedPresentTime, outAcquireTime, outRefreshStartTime, outGlCompositionDoneTime, outDisplayRetireTime, outReleaseTime); return ret ? NO_ERROR : BAD_VALUE; outGlCompositionDoneTime, outDisplayPresentTime, outDisplayRetireTime, outReleaseTime); } int Surface::connect(int api) { Loading