Merge changes I8bded1ea,I7478293e

* changes:
  SurfaceFlinger: add win anim frame time tracking
  SurfaceFlinger: remove a driver bug workaround
This commit is contained in:
Jamie Gennis 2013-02-11 19:48:18 +00:00 committed by Android (Google) Code Review
commit 351c294173
6 changed files with 63 additions and 24 deletions

View File

@ -31,28 +31,34 @@ FrameTracker::FrameTracker() :
} }
void FrameTracker::setDesiredPresentTime(nsecs_t presentTime) { void FrameTracker::setDesiredPresentTime(nsecs_t presentTime) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].desiredPresentTime = presentTime; mFrameRecords[mOffset].desiredPresentTime = presentTime;
} }
void FrameTracker::setFrameReadyTime(nsecs_t readyTime) { void FrameTracker::setFrameReadyTime(nsecs_t readyTime) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].frameReadyTime = readyTime; mFrameRecords[mOffset].frameReadyTime = readyTime;
} }
void FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) { void FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].frameReadyFence = readyFence; mFrameRecords[mOffset].frameReadyFence = readyFence;
mNumFences++; mNumFences++;
} }
void FrameTracker::setActualPresentTime(nsecs_t presentTime) { void FrameTracker::setActualPresentTime(nsecs_t presentTime) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].actualPresentTime = presentTime; mFrameRecords[mOffset].actualPresentTime = presentTime;
} }
void FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) { void FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].actualPresentFence = readyFence; mFrameRecords[mOffset].actualPresentFence = readyFence;
mNumFences++; mNumFences++;
} }
void FrameTracker::advanceFrame() { void FrameTracker::advanceFrame() {
Mutex::Autolock lock(mMutex);
mOffset = (mOffset+1) % NUM_FRAME_RECORDS; mOffset = (mOffset+1) % NUM_FRAME_RECORDS;
mFrameRecords[mOffset].desiredPresentTime = INT64_MAX; mFrameRecords[mOffset].desiredPresentTime = INT64_MAX;
mFrameRecords[mOffset].frameReadyTime = INT64_MAX; mFrameRecords[mOffset].frameReadyTime = INT64_MAX;
@ -74,10 +80,11 @@ void FrameTracker::advanceFrame() {
// Clean up the signaled fences to keep the number of open fence FDs in // Clean up the signaled fences to keep the number of open fence FDs in
// this process reasonable. // this process reasonable.
processFences(); processFencesLocked();
} }
void FrameTracker::clear() { void FrameTracker::clear() {
Mutex::Autolock lock(mMutex);
for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) { for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) {
mFrameRecords[i].desiredPresentTime = 0; mFrameRecords[i].desiredPresentTime = 0;
mFrameRecords[i].frameReadyTime = 0; mFrameRecords[i].frameReadyTime = 0;
@ -86,9 +93,12 @@ void FrameTracker::clear() {
mFrameRecords[i].actualPresentFence.clear(); mFrameRecords[i].actualPresentFence.clear();
} }
mNumFences = 0; mNumFences = 0;
mFrameRecords[mOffset].desiredPresentTime = INT64_MAX;
mFrameRecords[mOffset].frameReadyTime = INT64_MAX;
mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
} }
void FrameTracker::processFences() const { void FrameTracker::processFencesLocked() const {
FrameRecord* records = const_cast<FrameRecord*>(mFrameRecords); FrameRecord* records = const_cast<FrameRecord*>(mFrameRecords);
int& numFences = const_cast<int&>(mNumFences); int& numFences = const_cast<int&>(mNumFences);
@ -116,7 +126,8 @@ void FrameTracker::processFences() const {
} }
void FrameTracker::dump(String8& result) const { void FrameTracker::dump(String8& result) const {
processFences(); Mutex::Autolock lock(mMutex);
processFencesLocked();
const size_t o = mOffset; const size_t o = mOffset;
for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) { for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {

View File

@ -19,6 +19,7 @@
#include <stddef.h> #include <stddef.h>
#include <utils/Mutex.h>
#include <utils/Timers.h> #include <utils/Timers.h>
#include <utils/RefBase.h> #include <utils/RefBase.h>
@ -96,7 +97,7 @@ private:
// This method is const because although it modifies the frame records it // This method is const because although it modifies the frame records it
// does so in such a way that the information represented should not // does so in such a way that the information represented should not
// change. This allows it to be called from the dump method. // change. This allows it to be called from the dump method.
void processFences() const; void processFencesLocked() const;
// mFrameRecords is the circular buffer storing the tracked data for each // mFrameRecords is the circular buffer storing the tracked data for each
// frame. // frame.
@ -113,6 +114,9 @@ private:
// The number of fences is tracked so that the run time of processFences // The number of fences is tracked so that the run time of processFences
// doesn't grow with NUM_FRAME_RECORDS. // doesn't grow with NUM_FRAME_RECORDS.
int mNumFences; int mNumFences;
// mMutex is used to protect access to all member variables.
mutable Mutex mMutex;
}; };
} }

View File

@ -536,9 +536,6 @@ void Layer::onPostComposition() {
const HWComposer& hwc = mFlinger->getHwComposer(); const HWComposer& hwc = mFlinger->getHwComposer();
sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY); sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
// XXX: Temporarily don't use the present fence from HWC to work
// around a driver bug.
presentFence.clear();
if (presentFence != NULL) { if (presentFence != NULL) {
mFrameTracker.setActualPresentFence(presentFence); mFrameTracker.setActualPresentFence(presentFence);
} else { } else {
@ -757,9 +754,6 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const
void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const void Layer::dumpStats(String8& result, char* buffer, size_t SIZE) const
{ {
LayerBaseClient::dumpStats(result, buffer, SIZE); LayerBaseClient::dumpStats(result, buffer, SIZE);
const nsecs_t period =
mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
result.appendFormat("%lld\n", period);
mFrameTracker.dump(result); mFrameTracker.dump(result);
} }

View File

@ -129,6 +129,7 @@ private:
// thread-safe // thread-safe
volatile int32_t mQueuedFrames; volatile int32_t mQueuedFrames;
FrameTracker mFrameTracker;
// main thread // main thread
sp<GraphicBuffer> mActiveBuffer; sp<GraphicBuffer> mActiveBuffer;
@ -138,7 +139,6 @@ private:
bool mCurrentOpacity; bool mCurrentOpacity;
bool mRefreshPending; bool mRefreshPending;
bool mFrameLatencyNeeded; bool mFrameLatencyNeeded;
FrameTracker mFrameTracker;
// constants // constants
PixelFormat mFormat; PixelFormat mFormat;

View File

@ -93,6 +93,7 @@ SurfaceFlinger::SurfaceFlinger()
mBootTime(systemTime()), mBootTime(systemTime()),
mVisibleRegionsDirty(false), mVisibleRegionsDirty(false),
mHwWorkListDirty(false), mHwWorkListDirty(false),
mAnimCompositionPending(false),
mDebugRegion(0), mDebugRegion(0),
mDebugDDMS(0), mDebugDDMS(0),
mDebugDisableHWC(0), mDebugDisableHWC(0),
@ -885,6 +886,22 @@ void SurfaceFlinger::postComposition()
for (size_t i=0 ; i<count ; i++) { for (size_t i=0 ; i<count ; i++) {
currentLayers[i]->onPostComposition(); currentLayers[i]->onPostComposition();
} }
if (mAnimCompositionPending) {
mAnimCompositionPending = false;
const HWComposer& hwc = getHwComposer();
sp<Fence> presentFence = hwc.getDisplayFence(HWC_DISPLAY_PRIMARY);
if (presentFence != NULL) {
mAnimFrameTracker.setActualPresentFence(presentFence);
} else {
// The HWC doesn't support present fences, so use the refresh
// timestamp instead.
nsecs_t presentTime = hwc.getRefreshTimestamp(HWC_DISPLAY_PRIMARY);
mAnimFrameTracker.setActualPresentTime(presentTime);
}
mAnimFrameTracker.advanceFrame();
}
} }
void SurfaceFlinger::rebuildLayerStacks() { void SurfaceFlinger::rebuildLayerStacks() {
@ -1301,6 +1318,10 @@ void SurfaceFlinger::commitTransaction()
mLayersPendingRemoval.clear(); mLayersPendingRemoval.clear();
} }
// If this transaction is part of a window animation then the next frame
// we composite should be considered an animation as well.
mAnimCompositionPending = mAnimTransactionPending;
mDrawingState = mCurrentState; mDrawingState = mCurrentState;
mTransactionPending = false; mTransactionPending = false;
mAnimTransactionPending = false; mAnimTransactionPending = false;
@ -2264,22 +2285,26 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
index++; index++;
} }
const LayerVector& currentLayers = mCurrentState.layersSortedByZ; const nsecs_t period =
const size_t count = currentLayers.size(); getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
for (size_t i=0 ; i<count ; i++) { result.appendFormat("%lld\n", period);
const sp<LayerBase>& layer(currentLayers[i]);
if (name.isEmpty()) { if (name.isEmpty()) {
snprintf(buffer, SIZE, "%s\n", layer->getName().string()); mAnimFrameTracker.dump(result);
result.append(buffer); } else {
} const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
if (name.isEmpty() || (name == layer->getName())) { const size_t count = currentLayers.size();
layer->dumpStats(result, buffer, SIZE); for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
if (name == layer->getName()) {
layer->dumpStats(result, buffer, SIZE);
}
} }
} }
} }
void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index, void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& index,
String8& result, char* buffer, size_t SIZE) const String8& result, char* buffer, size_t SIZE)
{ {
String8 name; String8 name;
if (index < args.size()) { if (index < args.size()) {
@ -2295,6 +2320,8 @@ void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& inde
layer->clearStats(); layer->clearStats();
} }
} }
mAnimFrameTracker.clear();
} }
/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result) /*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)

View File

@ -45,8 +45,9 @@
#include <private/gui/LayerState.h> #include <private/gui/LayerState.h>
#include "Barrier.h" #include "Barrier.h"
#include "MessageQueue.h"
#include "DisplayDevice.h" #include "DisplayDevice.h"
#include "FrameTracker.h"
#include "MessageQueue.h"
#include "DisplayHardware/HWComposer.h" #include "DisplayHardware/HWComposer.h"
@ -390,7 +391,7 @@ private:
void dumpStatsLocked(const Vector<String16>& args, size_t& index, void dumpStatsLocked(const Vector<String16>& args, size_t& index,
String8& result, char* buffer, size_t SIZE) const; String8& result, char* buffer, size_t SIZE) const;
void clearStatsLocked(const Vector<String16>& args, size_t& index, void clearStatsLocked(const Vector<String16>& args, size_t& index,
String8& result, char* buffer, size_t SIZE) const; String8& result, char* buffer, size_t SIZE);
void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const; void dumpAllLocked(String8& result, char* buffer, size_t SIZE) const;
bool startDdmConnection(); bool startDdmConnection();
static void appendSfConfigString(String8& result); static void appendSfConfigString(String8& result);
@ -432,6 +433,7 @@ private:
State mDrawingState; State mDrawingState;
bool mVisibleRegionsDirty; bool mVisibleRegionsDirty;
bool mHwWorkListDirty; bool mHwWorkListDirty;
bool mAnimCompositionPending;
// this may only be written from the main thread with mStateLock held // this may only be written from the main thread with mStateLock held
// it may be read from other threads with mStateLock held // it may be read from other threads with mStateLock held
@ -451,6 +453,7 @@ private:
// these are thread safe // these are thread safe
mutable MessageQueue mEventQueue; mutable MessageQueue mEventQueue;
mutable Barrier mReadyToRunBarrier; mutable Barrier mReadyToRunBarrier;
FrameTracker mAnimFrameTracker;
// protected by mDestroyedLayerLock; // protected by mDestroyedLayerLock;
mutable Mutex mDestroyedLayerLock; mutable Mutex mDestroyedLayerLock;