Merge changes I8bded1ea,I7478293e
* changes: SurfaceFlinger: add win anim frame time tracking SurfaceFlinger: remove a driver bug workaround
This commit is contained in:
commit
351c294173
|
@ -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++) {
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 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.isEmpty()) {
|
||||
snprintf(buffer, SIZE, "%s\n", layer->getName().string());
|
||||
result.append(buffer);
|
||||
}
|
||||
if (name.isEmpty() || (name == layer->getName())) {
|
||||
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)
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue