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) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].desiredPresentTime = presentTime;
}
void FrameTracker::setFrameReadyTime(nsecs_t readyTime) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].frameReadyTime = readyTime;
}
void FrameTracker::setFrameReadyFence(const sp<Fence>& readyFence) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].frameReadyFence = readyFence;
mNumFences++;
}
void FrameTracker::setActualPresentTime(nsecs_t presentTime) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].actualPresentTime = presentTime;
}
void FrameTracker::setActualPresentFence(const sp<Fence>& readyFence) {
Mutex::Autolock lock(mMutex);
mFrameRecords[mOffset].actualPresentFence = readyFence;
mNumFences++;
}
void FrameTracker::advanceFrame() {
Mutex::Autolock lock(mMutex);
mOffset = (mOffset+1) % NUM_FRAME_RECORDS;
mFrameRecords[mOffset].desiredPresentTime = 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
// this process reasonable.
processFences();
processFencesLocked();
}
void FrameTracker::clear() {
Mutex::Autolock lock(mMutex);
for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) {
mFrameRecords[i].desiredPresentTime = 0;
mFrameRecords[i].frameReadyTime = 0;
@ -86,9 +93,12 @@ void FrameTracker::clear() {
mFrameRecords[i].actualPresentFence.clear();
}
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);
int& numFences = const_cast<int&>(mNumFences);
@ -116,7 +126,8 @@ void FrameTracker::processFences() const {
}
void FrameTracker::dump(String8& result) const {
processFences();
Mutex::Autolock lock(mMutex);
processFencesLocked();
const size_t o = mOffset;
for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {

View File

@ -19,6 +19,7 @@
#include <stddef.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
#include <utils/RefBase.h>
@ -96,7 +97,7 @@ private:
// This method is const because although it modifies the frame records it
// does so in such a way that the information represented should not
// 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
// frame.
@ -113,6 +114,9 @@ private:
// The number of fences is tracked so that the run time of processFences
// doesn't grow with NUM_FRAME_RECORDS.
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();
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) {
mFrameTracker.setActualPresentFence(presentFence);
} 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
{
LayerBaseClient::dumpStats(result, buffer, SIZE);
const nsecs_t period =
mFlinger->getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
result.appendFormat("%lld\n", period);
mFrameTracker.dump(result);
}

View File

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

View File

@ -93,6 +93,7 @@ SurfaceFlinger::SurfaceFlinger()
mBootTime(systemTime()),
mVisibleRegionsDirty(false),
mHwWorkListDirty(false),
mAnimCompositionPending(false),
mDebugRegion(0),
mDebugDDMS(0),
mDebugDisableHWC(0),
@ -885,6 +886,22 @@ void SurfaceFlinger::postComposition()
for (size_t i=0 ; i<count ; i++) {
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() {
@ -1301,6 +1318,10 @@ void SurfaceFlinger::commitTransaction()
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;
mTransactionPending = false;
mAnimTransactionPending = false;
@ -2264,22 +2285,26 @@ void SurfaceFlinger::dumpStatsLocked(const Vector<String16>& args, size_t& index
index++;
}
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
if (name.isEmpty()) {
snprintf(buffer, SIZE, "%s\n", layer->getName().string());
result.append(buffer);
}
if (name.isEmpty() || (name == layer->getName())) {
layer->dumpStats(result, buffer, SIZE);
const nsecs_t period =
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
result.appendFormat("%lld\n", period);
if (name.isEmpty()) {
mAnimFrameTracker.dump(result);
} else {
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.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,
String8& result, char* buffer, size_t SIZE) const
String8& result, char* buffer, size_t SIZE)
{
String8 name;
if (index < args.size()) {
@ -2295,6 +2320,8 @@ void SurfaceFlinger::clearStatsLocked(const Vector<String16>& args, size_t& inde
layer->clearStats();
}
}
mAnimFrameTracker.clear();
}
/*static*/ void SurfaceFlinger::appendSfConfigString(String8& result)

View File

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