BLASTBufferQueue: Support setFrameTimelineVsync
Surface::setFrameTimelineVsync calls through to SurfaceFlinger
using the IGBP as a token. But of course in the case of BBQ
we have no IGBP on the server side, and this will produce errors.
To fix this we continue overriding Surface methods in the BBQSurface
, and forward through to the SurfaceControl variants of the function.
Unlike the previous CL for setFrameRate, this is a currently un-released
API, and so I'd also like to investigate as a follow-up...can we go
SurfaceControl path only?
Bug: 170890018
Test: Existing tests pass
Change-Id: I5316c38f462c3808d5769ede6666594b911c8242
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 6ae6df1..c8e1f3d 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -381,6 +381,10 @@
}
return mBbq->setFrameRate(frameRate, compatibility);
}
+
+ status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId) override {
+ return mBbq->setFrameTimelineVsync(frameTimelineVsyncId);
+ }
};
// TODO: Can we coalesce this with frame updates? Need to confirm
@@ -393,6 +397,14 @@
.apply();
}
+status_t BLASTBufferQueue::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
+ std::unique_lock _lock{mMutex};
+ SurfaceComposerClient::Transaction t;
+
+ return t.setFrameTimelineVsync(mSurfaceControl, frameTimelineVsyncId)
+ .apply();
+}
+
sp<Surface> BLASTBufferQueue::getSurface() {
return new BBQSurface(mProducer, true, this);
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 2e4d279..4333126 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -146,6 +146,7 @@
SAFE_PARCEL(output.writeByte, frameRateCompatibility);
SAFE_PARCEL(output.writeUint32, fixedTransformHint);
SAFE_PARCEL(output.writeUint64, frameNumber);
+ SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId);
return NO_ERROR;
}
@@ -250,6 +251,7 @@
SAFE_PARCEL(input.readUint32, &tmpUint32);
fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
SAFE_PARCEL(input.readUint64, &frameNumber);
+ SAFE_PARCEL(input.readInt64, &frameTimelineVsyncId);
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 9ce8442..167bef1 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1521,7 +1521,7 @@
auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t));
ALOGV("Surface::dispatchSetFrameTimelineVsync");
- return composerService()->setFrameTimelineVsync(mGraphicBufferProducer, frameTimelineVsyncId);
+ return setFrameTimelineVsync(frameTimelineVsyncId);
}
bool Surface::transformToDisplayInverse() {
@@ -2288,4 +2288,9 @@
return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility);
}
+status_t Surface::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
+ return composerService()->setFrameTimelineVsync(mGraphicBufferProducer,
+ frameTimelineVsyncId);
+}
+
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 105969b..791750f 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1510,6 +1510,19 @@
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync(
+ const sp<SurfaceControl>& sc, int64_t frameTimelineVsyncId) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ s->what |= layer_state_t::eFrameTimelineVsyncChanged;
+ s->frameTimelineVsyncId = frameTimelineVsyncId;
+ return *this;
+}
+
// ---------------------------------------------------------------------------
DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index d477bea..1410b12 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -86,6 +86,7 @@
void flushShadowQueue() { mFlushShadowQueue = true; }
status_t setFrameRate(float frameRate, int8_t compatibility);
+ status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId);
virtual ~BLASTBufferQueue() = default;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 5942fd0..ff3a87d 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -127,6 +127,7 @@
eProducerDisconnect = 0x100'00000000,
eFixedTransformHintChanged = 0x200'00000000,
eFrameNumberChanged = 0x400'00000000,
+ eFrameTimelineVsyncChanged = 0x800'00000000,
};
layer_state_t();
@@ -227,6 +228,8 @@
// Used by BlastBufferQueue to forward the framenumber generated by the
// graphics producer.
uint64_t frameNumber;
+
+ int64_t frameTimelineVsyncId;
};
struct ComposerState {
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 6a1eaa2..c2b5ec4 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -180,6 +180,7 @@
status_t getConsumerUsage(uint64_t* outUsage) const;
virtual status_t setFrameRate(float frameRate, int8_t compatibility);
+ virtual status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId);
protected:
virtual ~Surface();
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index ce1a0a5..138f82c 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -532,6 +532,9 @@
// Sets the frame timeline vsync id received from choreographer that corresponds
// to the transaction.
Transaction& setFrameTimelineVsync(int64_t frameTimelineVsyncId);
+ // Variant that only applies to a specific SurfaceControl.
+ Transaction& setFrameTimelineVsync(const sp<SurfaceControl>& sc,
+ int64_t frameTimelineVsyncId);
status_t setDisplaySurface(const sp<IBinder>& token,
const sp<IGraphicBufferProducer>& bufferProducer);