Re-enable frame dropping for non-auto timestamps
This change adds an entire field to note whether the timestamp was auto-generated by Surface or supplied by the application. The value is used when deciding whether or not to drop frames based on buffer presentation timestamps. If a desired presentation time was set explicitly, BufferQueue will use that value to decide if a frame should be dropped. If the timestamp was generated by Surface at the time the buffer was queued, the timestamp is ignored. Bug 10151804 Change-Id: Ibd571a7578351063b813cbdad2ddbeed70655ba5
This commit is contained in:
parent
a33b62cc47
commit
3c25621ad7
@ -72,6 +72,10 @@ public:
|
||||
// to set by queueBuffer each time this slot is queued.
|
||||
int64_t mTimestamp;
|
||||
|
||||
// mIsAutoTimestamp indicates whether mTimestamp was generated
|
||||
// automatically when the buffer was queued.
|
||||
bool mIsAutoTimestamp;
|
||||
|
||||
// mFrameNumber is the number of the queued frame for this slot.
|
||||
uint64_t mFrameNumber;
|
||||
|
||||
|
@ -108,15 +108,17 @@ public:
|
||||
struct QueueBufferInput : public Flattenable<QueueBufferInput> {
|
||||
friend class Flattenable<QueueBufferInput>;
|
||||
inline QueueBufferInput(const Parcel& parcel);
|
||||
inline QueueBufferInput(int64_t timestamp,
|
||||
inline QueueBufferInput(int64_t timestamp, bool isAutoTimestamp,
|
||||
const Rect& crop, int scalingMode, uint32_t transform, bool async,
|
||||
const sp<Fence>& fence)
|
||||
: timestamp(timestamp), crop(crop), scalingMode(scalingMode),
|
||||
transform(transform), async(async), fence(fence) { }
|
||||
inline void deflate(int64_t* outTimestamp, Rect* outCrop,
|
||||
int* outScalingMode, uint32_t* outTransform, bool* outAsync,
|
||||
sp<Fence>* outFence) const {
|
||||
: timestamp(timestamp), isAutoTimestamp(isAutoTimestamp), crop(crop),
|
||||
scalingMode(scalingMode), transform(transform), async(async),
|
||||
fence(fence) { }
|
||||
inline void deflate(int64_t* outTimestamp, bool* outIsAutoTimestamp,
|
||||
Rect* outCrop, int* outScalingMode, uint32_t* outTransform,
|
||||
bool* outAsync, sp<Fence>* outFence) const {
|
||||
*outTimestamp = timestamp;
|
||||
*outIsAutoTimestamp = bool(isAutoTimestamp);
|
||||
*outCrop = crop;
|
||||
*outScalingMode = scalingMode;
|
||||
*outTransform = transform;
|
||||
@ -132,6 +134,7 @@ public:
|
||||
|
||||
private:
|
||||
int64_t timestamp;
|
||||
int isAutoTimestamp;
|
||||
Rect crop;
|
||||
int scalingMode;
|
||||
uint32_t transform;
|
||||
|
@ -475,10 +475,12 @@ status_t BufferQueue::queueBuffer(int buf,
|
||||
uint32_t transform;
|
||||
int scalingMode;
|
||||
int64_t timestamp;
|
||||
bool isAutoTimestamp;
|
||||
bool async;
|
||||
sp<Fence> fence;
|
||||
|
||||
input.deflate(×tamp, &crop, &scalingMode, &transform, &async, &fence);
|
||||
input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
|
||||
&async, &fence);
|
||||
|
||||
if (fence == NULL) {
|
||||
ST_LOGE("queueBuffer: fence is NULL");
|
||||
@ -558,6 +560,7 @@ status_t BufferQueue::queueBuffer(int buf,
|
||||
item.mTransform = transform;
|
||||
item.mScalingMode = scalingMode;
|
||||
item.mTimestamp = timestamp;
|
||||
item.mIsAutoTimestamp = isAutoTimestamp;
|
||||
item.mFrameNumber = mFrameCounter;
|
||||
item.mBuf = buf;
|
||||
item.mFence = fence;
|
||||
@ -860,7 +863,12 @@ status_t BufferQueue::acquireBuffer(BufferItem *buffer, nsecs_t expectedPresent)
|
||||
//
|
||||
// NOTE: code assumes monotonic time values from the system clock are
|
||||
// positive.
|
||||
while (false && mQueue.size() > 1) {
|
||||
|
||||
// Start by checking to see if we can drop frames. We skip this check
|
||||
// if the timestamps are being auto-generated by Surface -- if the
|
||||
// app isn't generating timestamps explicitly, they probably don't
|
||||
// want frames to be discarded based on them.
|
||||
while (mQueue.size() > 1 && !mQueue[0].mIsAutoTimestamp) {
|
||||
// If entry[1] is timely, drop entry[0] (and repeat). We apply
|
||||
// an additional criteria here: we only drop the earlier buffer if
|
||||
// our desiredPresent falls within +/- 1 second of the expected
|
||||
|
@ -43,6 +43,7 @@ IGraphicBufferConsumer::BufferItem::BufferItem() :
|
||||
mTransform(0),
|
||||
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
|
||||
mTimestamp(0),
|
||||
mIsAutoTimestamp(false),
|
||||
mFrameNumber(0),
|
||||
mBuf(INVALID_BUFFER_SLOT),
|
||||
mIsDroppable(false),
|
||||
@ -55,6 +56,7 @@ size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
|
||||
sizeof(mTransform) +
|
||||
sizeof(mScalingMode) +
|
||||
sizeof(mTimestamp) +
|
||||
sizeof(mIsAutoTimestamp) +
|
||||
sizeof(mFrameNumber) +
|
||||
sizeof(mBuf) +
|
||||
sizeof(mIsDroppable) +
|
||||
@ -123,6 +125,7 @@ status_t IGraphicBufferConsumer::BufferItem::flatten(
|
||||
FlattenableUtils::write(buffer, size, mTransform);
|
||||
FlattenableUtils::write(buffer, size, mScalingMode);
|
||||
FlattenableUtils::write(buffer, size, mTimestamp);
|
||||
FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
|
||||
FlattenableUtils::write(buffer, size, mFrameNumber);
|
||||
FlattenableUtils::write(buffer, size, mBuf);
|
||||
FlattenableUtils::write(buffer, size, mIsDroppable);
|
||||
@ -163,6 +166,7 @@ status_t IGraphicBufferConsumer::BufferItem::unflatten(
|
||||
FlattenableUtils::read(buffer, size, mTransform);
|
||||
FlattenableUtils::read(buffer, size, mScalingMode);
|
||||
FlattenableUtils::read(buffer, size, mTimestamp);
|
||||
FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
|
||||
FlattenableUtils::read(buffer, size, mFrameNumber);
|
||||
FlattenableUtils::read(buffer, size, mBuf);
|
||||
FlattenableUtils::read(buffer, size, mIsDroppable);
|
||||
|
@ -269,6 +269,7 @@ IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel)
|
||||
|
||||
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
|
||||
return sizeof(timestamp)
|
||||
+ sizeof(isAutoTimestamp)
|
||||
+ sizeof(crop)
|
||||
+ sizeof(scalingMode)
|
||||
+ sizeof(transform)
|
||||
@ -287,6 +288,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(
|
||||
return NO_MEMORY;
|
||||
}
|
||||
FlattenableUtils::write(buffer, size, timestamp);
|
||||
FlattenableUtils::write(buffer, size, isAutoTimestamp);
|
||||
FlattenableUtils::write(buffer, size, crop);
|
||||
FlattenableUtils::write(buffer, size, scalingMode);
|
||||
FlattenableUtils::write(buffer, size, transform);
|
||||
@ -299,6 +301,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
|
||||
{
|
||||
size_t minNeeded =
|
||||
sizeof(timestamp)
|
||||
+ sizeof(isAutoTimestamp)
|
||||
+ sizeof(crop)
|
||||
+ sizeof(scalingMode)
|
||||
+ sizeof(transform)
|
||||
@ -309,6 +312,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
|
||||
}
|
||||
|
||||
FlattenableUtils::read(buffer, size, timestamp);
|
||||
FlattenableUtils::read(buffer, size, isAutoTimestamp);
|
||||
FlattenableUtils::read(buffer, size, crop);
|
||||
FlattenableUtils::read(buffer, size, scalingMode);
|
||||
FlattenableUtils::read(buffer, size, transform);
|
||||
|
@ -262,8 +262,10 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
|
||||
ALOGV("Surface::queueBuffer");
|
||||
Mutex::Autolock lock(mMutex);
|
||||
int64_t timestamp;
|
||||
bool isAutoTimestamp = false;
|
||||
if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
|
||||
timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
|
||||
isAutoTimestamp = true;
|
||||
ALOGV("Surface::queueBuffer making up timestamp: %.2f ms",
|
||||
timestamp / 1000000.f);
|
||||
} else {
|
||||
@ -281,8 +283,8 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
|
||||
|
||||
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
|
||||
IGraphicBufferProducer::QueueBufferOutput output;
|
||||
IGraphicBufferProducer::QueueBufferInput input(timestamp, crop, mScalingMode,
|
||||
mTransform, mSwapIntervalZero, fence);
|
||||
IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
|
||||
crop, mScalingMode, mTransform, mSwapIntervalZero, fence);
|
||||
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
|
||||
if (err != OK) {
|
||||
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
|
||||
|
@ -185,7 +185,7 @@ void VirtualDisplaySurface::onFrameCommitted() {
|
||||
sp<Fence> outFence = mHwc.getLastRetireFence(mDisplayId);
|
||||
VDS_LOGV("onFrameCommitted: queue sink sslot=%d", sslot);
|
||||
status_t result = mSource[SOURCE_SINK]->queueBuffer(sslot,
|
||||
QueueBufferInput(systemTime(),
|
||||
QueueBufferInput(systemTime(), false,
|
||||
Rect(mSinkBufferWidth, mSinkBufferHeight),
|
||||
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, outFence),
|
||||
&qbo);
|
||||
@ -309,12 +309,13 @@ status_t VirtualDisplaySurface::queueBuffer(int pslot,
|
||||
|
||||
// Extract the GLES release fence for HWC to acquire
|
||||
int64_t timestamp;
|
||||
bool isAutoTimestamp;
|
||||
Rect crop;
|
||||
int scalingMode;
|
||||
uint32_t transform;
|
||||
bool async;
|
||||
input.deflate(×tamp, &crop, &scalingMode, &transform,
|
||||
&async, &mFbFence);
|
||||
input.deflate(×tamp, &isAutoTimestamp, &crop, &scalingMode,
|
||||
&transform, &async, &mFbFence);
|
||||
|
||||
mFbProducerSlot = pslot;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user