Plumbing for getting FenceTracker timestamps
Change-Id: I1ebee9e42e28658bd3a2b161fdaabb7da756d8f3
diff --git a/services/surfaceflinger/FenceTracker.cpp b/services/surfaceflinger/FenceTracker.cpp
index d415bd5..3ff9bbf 100644
--- a/services/surfaceflinger/FenceTracker.cpp
+++ b/services/surfaceflinger/FenceTracker.cpp
@@ -26,7 +26,9 @@
FenceTracker::FenceTracker() :
mFrameCounter(0),
mOffset(0),
- mFrames() {}
+ mFrames(),
+ mMutex() {
+}
void FenceTracker::dump(String8* outString) {
Mutex::Autolock lock(mMutex);
@@ -135,7 +137,7 @@
nsecs_t postedTime;
sp<Fence> acquireFence;
sp<Fence> prevReleaseFence;
- int32_t key = layers[i]->getSequence();
+ int32_t layerId = layers[i]->getSequence();
layers[i]->getFenceData(&name, &frameNumber, &glesComposition,
&postedTime, &acquireFence, &prevReleaseFence);
@@ -144,13 +146,17 @@
frame.layers.emplace(std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(name, frameNumber, glesComposition,
- postedTime, 0, 0, acquireFence, prevReleaseFence));
+ postedTime, FrameTimestamps::INVALID_TIME,
+ FrameTimestamps::INVALID_TIME, acquireFence,
+ prevReleaseFence));
wasGlesCompositionDone = true;
} else {
frame.layers.emplace(std::piecewise_construct,
std::forward_as_tuple(key),
std::forward_as_tuple(name, frameNumber, glesComposition,
- postedTime, 0, 0, acquireFence, Fence::NO_FENCE));
+ postedTime, FrameTimestamps::INVALID_TIME,
+ FrameTimestamps::INVALID_TIME, acquireFence,
+ Fence::NO_FENCE));
auto prevLayer = prevFrame.layers.find(key);
if (prevLayer != prevFrame.layers.end()) {
@@ -159,7 +165,7 @@
}
#else
frame.layers.emplace(std::piecewise_construct,
- std::forward_as_tuple(key),
+ std::forward_as_tuple(layerId),
std::forward_as_tuple(name, frameNumber, glesComposition,
postedTime, 0, 0, acquireFence,
glesComposition ? Fence::NO_FENCE : prevReleaseFence));
@@ -168,7 +174,7 @@
}
#endif
frame.layers.emplace(std::piecewise_construct,
- std::forward_as_tuple(key),
+ std::forward_as_tuple(layerId),
std::forward_as_tuple(name, frameNumber, glesComposition,
postedTime, 0, 0, acquireFence, prevReleaseFence));
}
@@ -186,4 +192,33 @@
mFrameCounter++;
}
+bool FenceTracker::getFrameTimestamps(const Layer& layer,
+ uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+ Mutex::Autolock lock(mMutex);
+ checkFencesForCompletion();
+ int32_t layerId = layer.getSequence();
+
+ size_t i = 0;
+ for (; i < MAX_FRAME_HISTORY; i++) {
+ if (mFrames[i].layers.count(layerId) &&
+ mFrames[i].layers[layerId].frameNumber == frameNumber) {
+ break;
+ }
+ }
+ if (i == MAX_FRAME_HISTORY) {
+ return false;
+ }
+
+ const FrameRecord& frameRecord = mFrames[i];
+ const LayerRecord& layerRecord = mFrames[i].layers[layerId];
+ outTimestamps->frameNumber = frameNumber;
+ outTimestamps->postedTime = layerRecord.postedTime;
+ outTimestamps->acquireTime = layerRecord.acquireTime;
+ outTimestamps->refreshStartTime = frameRecord.refreshStartTime;
+ outTimestamps->glCompositionDoneTime = frameRecord.glesCompositionDoneTime;
+ outTimestamps->displayRetireTime = frameRecord.retireTime;
+ outTimestamps->releaseTime = layerRecord.releaseTime;
+ return true;
+}
+
} // namespace android
diff --git a/services/surfaceflinger/FenceTracker.h b/services/surfaceflinger/FenceTracker.h
index 2fcc314..4cb14a5 100644
--- a/services/surfaceflinger/FenceTracker.h
+++ b/services/surfaceflinger/FenceTracker.h
@@ -29,7 +29,7 @@
namespace android {
class Layer;
-
+struct FrameTimestamps;
/*
* Keeps a circular buffer of fence/timestamp data for the last N frames in
* SurfaceFlinger. Gets timestamps for fences after they have signaled.
@@ -40,6 +40,8 @@
void dump(String8* outString);
void addFrame(nsecs_t refreshStartTime, sp<Fence> retireFence,
const Vector<sp<Layer>>& layers, sp<Fence> glDoneFence);
+ bool getFrameTimestamps(const Layer& layer, uint64_t frameNumber,
+ FrameTimestamps* outTimestamps);
protected:
static constexpr size_t MAX_FRAME_HISTORY = 8;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index abf0e6c..15e5615 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -154,7 +154,8 @@
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
mProducer = new MonitoredProducer(producer, mFlinger);
- mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
+ mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName,
+ this);
mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
mSurfaceFlingerConsumer->setContentsChangedListener(this);
mSurfaceFlingerConsumer->setName(mName);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 79750a6..fef2d98 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -409,6 +409,11 @@
std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush);
+ bool getFrameTimestamps(uint64_t frameNumber,
+ FrameTimestamps* outTimestamps) const {
+ return mFlinger->getFrameTimestamps(*this, frameNumber, outTimestamps);
+ }
+
protected:
// constant
sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0276d38..0dc04eb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3606,6 +3606,11 @@
}
}
+bool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
+ uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+ return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
+}
+
// ---------------------------------------------------------------------------
SurfaceFlinger::LayerVector::LayerVector() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8263994..28666e2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -440,6 +440,9 @@
std::vector<OccupancyTracker::Segment>&& history);
void dumpBufferingStats(String8& result) const;
+ bool getFrameTimestamps(const Layer& layer, uint64_t frameNumber,
+ FrameTimestamps* outTimestamps);
+
/* ------------------------------------------------------------------------
* Attributes
*/
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index c71b3bc..ba0a527 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -18,6 +18,7 @@
//#define LOG_NDEBUG 0
#include "SurfaceFlingerConsumer.h"
+#include "Layer.h"
#include <private/gui/SyncFeatures.h>
@@ -251,6 +252,12 @@
}
}
+bool SurfaceFlingerConsumer::getFrameTimestamps(uint64_t frameNumber,
+ FrameTimestamps* outTimestamps) const {
+ sp<const Layer> l = mLayer.promote();
+ return l.get() ? l->getFrameTimestamps(frameNumber, outTimestamps) : false;
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 51b002f..3762659 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -23,6 +23,8 @@
namespace android {
// ----------------------------------------------------------------------------
+class Layer;
+
/*
* This is a thin wrapper around GLConsumer.
*/
@@ -35,10 +37,10 @@
};
SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
- uint32_t tex)
+ uint32_t tex, const Layer* layer)
: GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
mTransformToDisplayInverse(false), mSurfaceDamage(),
- mPrevReleaseFence(Fence::NO_FENCE)
+ mPrevReleaseFence(Fence::NO_FENCE), mLayer(layer)
{}
class BufferRejecter {
@@ -82,6 +84,9 @@
void releasePendingBuffer();
#endif
+ virtual bool getFrameTimestamps(uint64_t frameNumber,
+ FrameTimestamps* outTimestamps) const override;
+
private:
virtual void onSidebandStreamChanged();
@@ -103,6 +108,9 @@
// The release fence of the already displayed buffer (previous frame).
sp<Fence> mPrevReleaseFence;
+
+ // The layer for this SurfaceFlingerConsumer
+ wp<const Layer> mLayer;
};
// ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 71d7cf9..f4061e7 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -3593,6 +3593,11 @@
return result;
}
+bool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
+ uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+ return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
+}
+
void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
if (DEBUG_SCREENSHOTS) {