diff options
-rw-r--r-- | include/gui/ISurfaceComposer.h | 18 | ||||
-rw-r--r-- | include/gui/ISurfaceComposerClient.h | 11 | ||||
-rw-r--r-- | include/gui/SurfaceComposerClient.h | 7 | ||||
-rw-r--r-- | include/gui/SurfaceControl.h | 10 | ||||
-rw-r--r-- | include/ui/FrameStats.h | 63 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposer.cpp | 29 | ||||
-rw-r--r-- | libs/gui/ISurfaceComposerClient.cpp | 39 | ||||
-rw-r--r-- | libs/gui/SurfaceComposerClient.cpp | 23 | ||||
-rw-r--r-- | libs/gui/SurfaceControl.cpp | 14 | ||||
-rw-r--r-- | libs/ui/Android.mk | 1 | ||||
-rw-r--r-- | libs/ui/FrameStats.cpp | 84 | ||||
-rw-r--r-- | services/surfaceflinger/Client.cpp | 18 | ||||
-rw-r--r-- | services/surfaceflinger/Client.h | 4 | ||||
-rw-r--r-- | services/surfaceflinger/FrameTracker.cpp | 31 | ||||
-rw-r--r-- | services/surfaceflinger/FrameTracker.h | 11 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 12 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.h | 6 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 22 | ||||
-rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 2 |
19 files changed, 384 insertions, 21 deletions
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h index 35dcd4e..efde5db 100644 --- a/include/gui/ISurfaceComposer.h +++ b/include/gui/ISurfaceComposer.h @@ -22,9 +22,12 @@ #include <utils/RefBase.h> #include <utils/Errors.h> +#include <utils/Timers.h> +#include <utils/Vector.h> #include <binder/IInterface.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> #include <gui/IGraphicBufferAlloc.h> @@ -122,6 +125,19 @@ public: uint32_t reqWidth, uint32_t reqHeight, uint32_t minLayerZ, uint32_t maxLayerZ, bool useIdentityTransform) = 0; + + + /* Clears the frame statistics for animations. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t clearAnimationFrameStats() = 0; + + /* Gets the frame statistics for animations. + * + * Requires the ACCESS_SURFACE_FLINGER permission. + */ + virtual status_t getAnimationFrameStats(FrameStats* outStats) const = 0; }; // ---------------------------------------------------------------------------- @@ -145,6 +161,8 @@ public: GET_DISPLAY_INFO, CONNECT_DISPLAY, CAPTURE_SCREEN, + CLEAR_ANIMATION_FRAME_STATS, + GET_ANIMATION_FRAME_STATS }; virtual status_t onTransact(uint32_t code, const Parcel& data, diff --git a/include/gui/ISurfaceComposerClient.h b/include/gui/ISurfaceComposerClient.h index cb9816f..58c1f6a 100644 --- a/include/gui/ISurfaceComposerClient.h +++ b/include/gui/ISurfaceComposerClient.h @@ -25,6 +25,7 @@ #include <binder/IInterface.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> namespace android { @@ -65,6 +66,16 @@ public: * Requires ACCESS_SURFACE_FLINGER permission */ virtual status_t destroySurface(const sp<IBinder>& handle) = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0; + + /* + * Requires ACCESS_SURFACE_FLINGER permission + */ + virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h index ac53f02..6a53ccb 100644 --- a/include/gui/SurfaceComposerClient.h +++ b/include/gui/SurfaceComposerClient.h @@ -28,6 +28,7 @@ #include <utils/SortedVector.h> #include <utils/threads.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> #include <gui/CpuConsumer.h> @@ -125,6 +126,12 @@ public: status_t setLayerStack(const sp<IBinder>& id, uint32_t layerStack); status_t destroySurface(const sp<IBinder>& id); + status_t clearLayerFrameStats(const sp<IBinder>& token) const; + status_t getLayerFrameStats(const sp<IBinder>& token, FrameStats* outStats) const; + + static status_t clearAnimationFrameStats(); + static status_t getAnimationFrameStats(FrameStats* outStats); + static void setDisplaySurface(const sp<IBinder>& token, const sp<IGraphicBufferProducer>& bufferProducer); static void setDisplayLayerStack(const sp<IBinder>& token, diff --git a/include/gui/SurfaceControl.h b/include/gui/SurfaceControl.h index f27754c..84fb9f9 100644 --- a/include/gui/SurfaceControl.h +++ b/include/gui/SurfaceControl.h @@ -24,6 +24,7 @@ #include <utils/RefBase.h> #include <utils/threads.h> +#include <ui/FrameStats.h> #include <ui/PixelFormat.h> #include <ui/Region.h> @@ -52,10 +53,10 @@ public: static bool isSameSurface( const sp<SurfaceControl>& lhs, const sp<SurfaceControl>& rhs); - + // release surface data from java void clear(); - + status_t setLayerStack(int32_t layerStack); status_t setLayer(int32_t layer); status_t setPosition(float x, float y); @@ -73,6 +74,9 @@ public: sp<Surface> getSurface() const; + status_t clearLayerFrameStats() const; + status_t getLayerFrameStats(FrameStats* outStats) const; + private: // can't be copied SurfaceControl& operator = (SurfaceControl& rhs); @@ -90,7 +94,7 @@ private: status_t validate() const; void destroy(); - + sp<SurfaceComposerClient> mClient; sp<IBinder> mHandle; sp<IGraphicBufferProducer> mGraphicBufferProducer; diff --git a/include/ui/FrameStats.h b/include/ui/FrameStats.h new file mode 100644 index 0000000..5fdf94d --- /dev/null +++ b/include/ui/FrameStats.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ANDROID_UI_FRAME_STATS_H +#define ANDROID_UI_FRAME_STATS_H + +#include <utils/Flattenable.h> +#include <utils/Timers.h> +#include <utils/Vector.h> + +namespace android { + +class FrameStats : public LightFlattenable<FrameStats> { +public: + + /* + * Approximate refresh time, in nanoseconds. + */ + nsecs_t refreshPeriodNano; + + /* + * The times in nanoseconds for when the frame contents were posted by the producer (e.g. + * the application). They are either explicitly set or defaulted to the time when + * Surface::queueBuffer() was called. + */ + Vector<nsecs_t> desiredPresentTimesNano; + + /* + * The times in milliseconds for when the frame contents were presented on the screen. + */ + Vector<nsecs_t> actualPresentTimesNano; + + /* + * The times in nanoseconds for when the frame contents were ready to be presented. Note that + * a frame can be posted and still it contents being rendered asynchronously in GL. In such a + * case these are the times when the frame contents were completely rendered (i.e. their fences + * signaled). + */ + Vector<nsecs_t> frameReadyTimesNano; + + // LightFlattenable + bool isFixedSize() const; + size_t getFlattenedSize() const; + status_t flatten(void* buffer, size_t size) const; + status_t unflatten(void const* buffer, size_t size); +}; + +}; // namespace android + +#endif // ANDROID_UI_FRAME_STATS_H diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index e96cc54..c067244 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -229,6 +229,21 @@ public: memcpy(info, reply.readInplace(sizeof(DisplayInfo)), sizeof(DisplayInfo)); return reply.readInt32(); } + + virtual status_t clearAnimationFrameStats() { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + remote()->transact(BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS, data, &reply); + return reply.readInt32(); + } + + virtual status_t getAnimationFrameStats(FrameStats* outStats) const { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + remote()->transact(BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, data, &reply); + reply.read(*outStats); + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer"); @@ -351,6 +366,20 @@ status_t BnSurfaceComposer::onTransact( reply->writeInt32(result); return NO_ERROR; } + case CLEAR_ANIMATION_FRAME_STATS: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + status_t result = clearAnimationFrameStats(); + reply->writeInt32(result); + return NO_ERROR; + } + case GET_ANIMATION_FRAME_STATS: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + FrameStats stats; + status_t result = getAnimationFrameStats(&stats); + reply->write(stats); + reply->writeInt32(result); + return NO_ERROR; + } default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp index 1adc134..3da6423 100644 --- a/libs/gui/ISurfaceComposerClient.cpp +++ b/libs/gui/ISurfaceComposerClient.cpp @@ -39,7 +39,9 @@ namespace android { enum { CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION, - DESTROY_SURFACE + DESTROY_SURFACE, + CLEAR_LAYER_FRAME_STATS, + GET_LAYER_FRAME_STATS }; class BpSurfaceComposerClient : public BpInterface<ISurfaceComposerClient> @@ -73,6 +75,23 @@ public: remote()->transact(DESTROY_SURFACE, data, &reply); return reply.readInt32(); } + + virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); + data.writeStrongBinder(handle); + remote()->transact(CLEAR_LAYER_FRAME_STATS, data, &reply); + return reply.readInt32(); + } + + virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor()); + data.writeStrongBinder(handle); + remote()->transact(GET_LAYER_FRAME_STATS, data, &reply); + reply.read(*outStats); + return reply.readInt32(); + } }; IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient"); @@ -101,7 +120,23 @@ status_t BnSurfaceComposerClient::onTransact( } break; case DESTROY_SURFACE: { CHECK_INTERFACE(ISurfaceComposerClient, data, reply); - reply->writeInt32( destroySurface( data.readStrongBinder() ) ); + reply->writeInt32(destroySurface( data.readStrongBinder() ) ); + return NO_ERROR; + } break; + case CLEAR_LAYER_FRAME_STATS: { + CHECK_INTERFACE(ISurfaceComposerClient, data, reply); + sp<IBinder> handle = data.readStrongBinder(); + status_t result = clearLayerFrameStats(handle); + reply->writeInt32(result); + return NO_ERROR; + } break; + case GET_LAYER_FRAME_STATS: { + CHECK_INTERFACE(ISurfaceComposerClient, data, reply); + sp<IBinder> handle = data.readStrongBinder(); + FrameStats stats; + status_t result = getLayerFrameStats(handle, &stats); + reply->write(stats); + reply->writeInt32(result); return NO_ERROR; } break; default: diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index 6b20eaf..b7af415 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -515,6 +515,21 @@ status_t SurfaceComposerClient::destroySurface(const sp<IBinder>& sid) { return err; } +status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) const { + if (mStatus != NO_ERROR) { + return mStatus; + } + return mClient->clearLayerFrameStats(token); +} + +status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token, + FrameStats* outStats) const { + if (mStatus != NO_ERROR) { + return mStatus; + } + return mClient->getLayerFrameStats(token, outStats); +} + inline Composer& SurfaceComposerClient::getComposer() { return mComposer; } @@ -622,6 +637,14 @@ void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) { ComposerService::getComposerService()->unblank(token); } +status_t SurfaceComposerClient::clearAnimationFrameStats() { + return ComposerService::getComposerService()->clearAnimationFrameStats(); +} + +status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) { + return ComposerService::getComposerService()->getAnimationFrameStats(outStats); +} + // ---------------------------------------------------------------------------- status_t ScreenshotClient::capture( diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp index de182ee..7c6dfb8 100644 --- a/libs/gui/SurfaceControl.cpp +++ b/libs/gui/SurfaceControl.cpp @@ -156,6 +156,20 @@ status_t SurfaceControl::setCrop(const Rect& crop) { return client->setCrop(mHandle, crop); } +status_t SurfaceControl::clearLayerFrameStats() const { + status_t err = validate(); + if (err < 0) return err; + const sp<SurfaceComposerClient>& client(mClient); + return client->clearLayerFrameStats(mHandle); +} + +status_t SurfaceControl::getLayerFrameStats(FrameStats* outStats) const { + status_t err = validate(); + if (err < 0) return err; + const sp<SurfaceComposerClient>& client(mClient); + return client->getLayerFrameStats(mHandle, outStats); +} + status_t SurfaceControl::validate() const { if (mHandle==0 || mClient==0) { diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk index 008446b..eec97be 100644 --- a/libs/ui/Android.mk +++ b/libs/ui/Android.mk @@ -18,6 +18,7 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ Fence.cpp \ FramebufferNativeWindow.cpp \ + FrameStats.cpp \ GraphicBuffer.cpp \ GraphicBufferAllocator.cpp \ GraphicBufferMapper.cpp \ diff --git a/libs/ui/FrameStats.cpp b/libs/ui/FrameStats.cpp new file mode 100644 index 0000000..acbe27e --- /dev/null +++ b/libs/ui/FrameStats.cpp @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <ui/FrameStats.h> + +namespace android { + +bool FrameStats::isFixedSize() const { + return false; +} + +size_t FrameStats::getFlattenedSize() const { + const size_t timestampSize = sizeof(nsecs_t); + + size_t size = timestampSize; + size += 3 * desiredPresentTimesNano.size() * timestampSize; + + return size; +} + +status_t FrameStats::flatten(void* buffer, size_t size) const { + if (size < getFlattenedSize()) { + return NO_MEMORY; + } + + nsecs_t* timestamps = reinterpret_cast<nsecs_t*>(buffer); + const size_t timestampSize = sizeof(nsecs_t); + size_t frameCount = desiredPresentTimesNano.size(); + + memcpy(timestamps, &refreshPeriodNano, timestampSize); + timestamps += 1; + + memcpy(timestamps, desiredPresentTimesNano.array(), frameCount * timestampSize); + timestamps += frameCount; + + memcpy(timestamps, actualPresentTimesNano.array(), frameCount * timestampSize); + timestamps += frameCount; + + memcpy(timestamps, frameReadyTimesNano.array(), frameCount * timestampSize); + + return NO_ERROR; +} + +status_t FrameStats::unflatten(void const* buffer, size_t size) { + const size_t timestampSize = sizeof(nsecs_t); + + if (size < timestampSize) { + return NO_MEMORY; + } + + nsecs_t const* timestamps = reinterpret_cast<nsecs_t const*>(buffer); + size_t frameCount = (size - timestampSize) / (3 * timestampSize); + + memcpy(&refreshPeriodNano, timestamps, timestampSize); + timestamps += 1; + + desiredPresentTimesNano.resize(frameCount); + memcpy(desiredPresentTimesNano.editArray(), timestamps, frameCount * timestampSize); + timestamps += frameCount; + + actualPresentTimesNano.resize(frameCount); + memcpy(actualPresentTimesNano.editArray(), timestamps, frameCount * timestampSize); + timestamps += frameCount; + + frameReadyTimesNano.resize(frameCount); + memcpy(frameReadyTimesNano.editArray(), timestamps, frameCount * timestampSize); + + return NO_ERROR; +} + +} // namespace android diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index 975631c..f7d32d0 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -155,5 +155,23 @@ status_t Client::destroySurface(const sp<IBinder>& handle) { return mFlinger->onLayerRemoved(this, handle); } +status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const { + sp<Layer> layer = getLayerUser(handle); + if (layer == NULL) { + return NAME_NOT_FOUND; + } + layer->clearFrameStats(); + return NO_ERROR; +} + +status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const { + sp<Layer> layer = getLayerUser(handle); + if (layer == NULL) { + return NAME_NOT_FOUND; + } + layer->getFrameStats(outStats); + return NO_ERROR; +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index 84e649f..b6d7381 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -60,6 +60,10 @@ private: virtual status_t destroySurface(const sp<IBinder>& handle); + virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const; + + virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const; + virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); diff --git a/services/surfaceflinger/FrameTracker.cpp b/services/surfaceflinger/FrameTracker.cpp index 2fb665e..c09bbe4 100644 --- a/services/surfaceflinger/FrameTracker.cpp +++ b/services/surfaceflinger/FrameTracker.cpp @@ -22,6 +22,7 @@ #include <cutils/log.h> #include <ui/Fence.h> +#include <ui/FrameStats.h> #include <utils/String8.h> @@ -100,7 +101,7 @@ void FrameTracker::advanceFrame() { processFencesLocked(); } -void FrameTracker::clear() { +void FrameTracker::clearStats() { Mutex::Autolock lock(mMutex); for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) { mFrameRecords[i].desiredPresentTime = 0; @@ -115,6 +116,32 @@ void FrameTracker::clear() { mFrameRecords[mOffset].actualPresentTime = INT64_MAX; } +void FrameTracker::getStats(FrameStats* outStats) const { + Mutex::Autolock lock(mMutex); + processFencesLocked(); + + outStats->refreshPeriodNano = mDisplayPeriod; + + const size_t offset = mOffset; + for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) { + const size_t index = (offset + i) % NUM_FRAME_RECORDS; + + // Skip frame records with no data (if buffer not yet full). + if (mFrameRecords[index].desiredPresentTime == 0) { + continue; + } + + nsecs_t desiredPresentTimeNano = mFrameRecords[index].desiredPresentTime; + outStats->desiredPresentTimesNano.push_back(desiredPresentTimeNano); + + nsecs_t actualPresentTimeNano = mFrameRecords[index].actualPresentTime; + outStats->actualPresentTimesNano.push_back(actualPresentTimeNano); + + nsecs_t frameReadyTimeNano = mFrameRecords[index].frameReadyTime; + outStats->frameReadyTimesNano.push_back(frameReadyTimeNano); + } +} + void FrameTracker::logAndResetStats(const String8& name) { Mutex::Autolock lock(mMutex); logStatsLocked(name); @@ -206,7 +233,7 @@ bool FrameTracker::isFrameValidLocked(size_t idx) const { mFrameRecords[idx].actualPresentTime < INT64_MAX; } -void FrameTracker::dump(String8& result) const { +void FrameTracker::dumpStats(String8& result) const { Mutex::Autolock lock(mMutex); processFencesLocked(); diff --git a/services/surfaceflinger/FrameTracker.h b/services/surfaceflinger/FrameTracker.h index 9233247..cd5e3f3 100644 --- a/services/surfaceflinger/FrameTracker.h +++ b/services/surfaceflinger/FrameTracker.h @@ -78,15 +78,18 @@ public: // advanceFrame advances the frame tracker to the next frame. void advanceFrame(); - // clear resets all the tracked frame data to zero. - void clear(); + // clearStats clears the tracked frame stats. + void clearStats(); + + // getStats gets the tracked frame stats. + void getStats(FrameStats* outStats) const; // logAndResetStats dumps the current statistics to the binary event log // and then resets the accumulated statistics to their initial values. void logAndResetStats(const String8& name); - // dump appends the current frame display time history to the result string. - void dump(String8& result) const; + // dumpStats dump appends the current frame display time history to the result string. + void dumpStats(String8& result) const; private: struct FrameRecord { diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 7f2ee2a..9920525 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -1244,18 +1244,22 @@ void Layer::dump(String8& result, Colorizer& colorizer) const } } -void Layer::dumpStats(String8& result) const { - mFrameTracker.dump(result); +void Layer::dumpFrameStats(String8& result) const { + mFrameTracker.dumpStats(result); } -void Layer::clearStats() { - mFrameTracker.clear(); +void Layer::clearFrameStats() { + mFrameTracker.clearStats(); } void Layer::logFrameStats() { mFrameTracker.logAndResetStats(mName); } +void Layer::getFrameStats(FrameStats* outStats) const { + mFrameTracker.getStats(outStats); +} + // --------------------------------------------------------------------------- Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger, diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index 8f8989e..62970c3 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -27,6 +27,7 @@ #include <utils/String8.h> #include <utils/Timers.h> +#include <ui/FrameStats.h> #include <ui/GraphicBuffer.h> #include <ui/PixelFormat.h> #include <ui/Region.h> @@ -288,9 +289,10 @@ public: /* always call base class first */ void dump(String8& result, Colorizer& colorizer) const; - void dumpStats(String8& result) const; - void clearStats(); + void dumpFrameStats(String8& result) const; + void clearFrameStats(); void logFrameStats(); + void getFrameStats(FrameStats* outStats) const; protected: // constant diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index d084bf5..a346520 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -574,6 +574,18 @@ status_t SurfaceFlinger::getDisplayInfo(const sp<IBinder>& display, DisplayInfo* return NO_ERROR; } +status_t SurfaceFlinger::clearAnimationFrameStats() { + Mutex::Autolock _l(mStateLock); + mAnimFrameTracker.clearStats(); + return NO_ERROR; +} + +status_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const { + Mutex::Autolock _l(mStateLock); + mAnimFrameTracker.getStats(outStats); + return NO_ERROR; +} + // ---------------------------------------------------------------------------- sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() { @@ -2255,14 +2267,14 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index result.appendFormat("%" PRId64 "\n", period); if (name.isEmpty()) { - mAnimFrameTracker.dump(result); + mAnimFrameTracker.dumpStats(result); } else { const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const size_t count = currentLayers.size(); for (size_t i=0 ; i<count ; i++) { const sp<Layer>& layer(currentLayers[i]); if (name == layer->getName()) { - layer->dumpStats(result); + layer->dumpFrameStats(result); } } } @@ -2282,11 +2294,11 @@ void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& inde for (size_t i=0 ; i<count ; i++) { const sp<Layer>& layer(currentLayers[i]); if (name.isEmpty() || (name == layer->getName())) { - layer->clearStats(); + layer->clearFrameStats(); } } - mAnimFrameTracker.clear(); + mAnimFrameTracker.clearStats(); } // This should only be called from the main thread. Otherwise it would need @@ -2500,6 +2512,8 @@ status_t SurfaceFlinger::onTransact( case BOOT_FINISHED: case BLANK: case UNBLANK: + case CLEAR_ANIMATION_FRAME_STATS: + case GET_ANIMATION_FRAME_STATS: { // codes that require permission check IPCThreadState* ipc = IPCThreadState::self(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 630f4b7..717ee66 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -210,6 +210,8 @@ private: // called when screen is turning back on virtual void unblank(const sp<IBinder>& display); virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info); + virtual status_t clearAnimationFrameStats(); + virtual status_t getAnimationFrameStats(FrameStats* outStats) const; /* ------------------------------------------------------------------------ * DeathRecipient interface |