Use Transactions for RefreshRateOverlay
RefreshRateOverlay currently calls directly in Layer to update
properties. This is ends up adding confusing code to RefreshRateOverlay
since it needs to notify SF to handle the updates. It also creates
addtional confusion since there are multiple entries to layer
properties.
Instead, use the SCC Transaction requests to accomplish the same
behavior. This simplifies the code and also allows SF to handle the
updates instead of RefreshRateOverlay invoking force updates.
Test: RefreshRateOverlay works with rotation, different refresh rates
Test: RefreshRateOverlayTest
Bug: 200820757
Change-Id: I8503c61456c4c14ce6cbcdb2b27035a340fecbf5
diff --git a/services/surfaceflinger/ClientCache.cpp b/services/surfaceflinger/ClientCache.cpp
index 1ef8f78..e7b8995 100644
--- a/services/surfaceflinger/ClientCache.cpp
+++ b/services/surfaceflinger/ClientCache.cpp
@@ -82,10 +82,13 @@
return false;
}
- status_t err = token->linkToDeath(mDeathRecipient);
- if (err != NO_ERROR) {
- ALOGE("failed to cache buffer: could not link to death");
- return false;
+ // Only call linkToDeath if not a local binder
+ if (token->localBinder() == nullptr) {
+ status_t err = token->linkToDeath(mDeathRecipient);
+ if (err != NO_ERROR) {
+ ALOGE("failed to cache buffer: could not link to death");
+ return false;
+ }
}
auto [itr, success] =
mBuffers.emplace(processToken,
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index 0789e8d..ec81e63 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -30,6 +30,8 @@
#include <SkRect.h>
#include <SkSurface.h>
#include <gui/IProducerListener.h>
+#include <gui/SurfaceComposerClient.h>
+#include <gui/SurfaceControl.h>
#undef LOG_TAG
#define LOG_TAG "RefreshRateOverlay"
@@ -190,35 +192,30 @@
}
bool RefreshRateOverlay::createLayer() {
- int32_t layerId;
- const status_t ret =
- mFlinger.createLayer(String8("RefreshRateOverlay"), mClient,
- SevenSegmentDrawer::getWidth(), SevenSegmentDrawer::getHeight(),
- PIXEL_FORMAT_RGBA_8888,
- ISurfaceComposerClient::eFXSurfaceBufferState, LayerMetadata(),
- &mIBinder, &mGbp, nullptr, &layerId);
- if (ret) {
+ mSurfaceControl =
+ SurfaceComposerClient::getDefault()
+ ->createSurface(String8("RefreshRateOverlay"), SevenSegmentDrawer::getWidth(),
+ SevenSegmentDrawer::getHeight(), PIXEL_FORMAT_RGBA_8888,
+ ISurfaceComposerClient::eFXSurfaceBufferState);
+
+ if (!mSurfaceControl) {
ALOGE("failed to create buffer state layer");
return false;
}
- mLayer = mClient->getLayerUser(mIBinder);
- mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote));
- mLayer->setIsAtRoot(true);
-
- // setting Layer's Z requires resorting layersSortedByZ
- ssize_t idx = mFlinger.mDrawingState.layersSortedByZ.indexOf(mLayer);
- if (mLayer->setLayer(INT32_MAX - 2) && idx >= 0) {
- mFlinger.mDrawingState.layersSortedByZ.removeAt(idx);
- mFlinger.mDrawingState.layersSortedByZ.add(mLayer);
- }
+ SurfaceComposerClient::Transaction t;
+ t.setFrameRate(mSurfaceControl, 0.0f,
+ static_cast<int8_t>(Layer::FrameRateCompatibility::NoVote),
+ static_cast<int8_t>(scheduler::Seamlessness::OnlySeamless));
+ t.setLayer(mSurfaceControl, INT32_MAX - 2);
+ t.apply();
return true;
}
-const std::vector<std::shared_ptr<renderengine::ExternalTexture>>&
-RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
- ui::Transform::RotationFlags transformHint = mLayer->getTransformHint();
+const std::vector<sp<GraphicBuffer>>& RefreshRateOverlay::getOrCreateBuffers(uint32_t fps) {
+ ui::Transform::RotationFlags transformHint =
+ static_cast<ui::Transform::RotationFlags>(mSurfaceControl->getTransformHint());
// Tell SurfaceFlinger about the pre-rotation on the buffer.
const auto transform = [&] {
switch (transformHint) {
@@ -230,7 +227,10 @@
return ui::Transform::ROT_0;
}
}();
- mLayer->setTransform(transform);
+
+ SurfaceComposerClient::Transaction t;
+ t.setTransform(mSurfaceControl, transform);
+ t.apply();
if (mBufferCache.find(transformHint) == mBufferCache.end() ||
mBufferCache.at(transformHint).find(fps) == mBufferCache.at(transformHint).end()) {
@@ -249,16 +249,7 @@
colorBase.fA = ALPHA;
SkColor color = colorBase.toSkColor();
auto buffers = SevenSegmentDrawer::draw(fps, color, transformHint, mShowSpinner);
- std::vector<std::shared_ptr<renderengine::ExternalTexture>> textures;
- std::transform(buffers.begin(), buffers.end(), std::back_inserter(textures),
- [&](const auto& buffer) -> std::shared_ptr<renderengine::ExternalTexture> {
- return std::make_shared<
- renderengine::ExternalTexture>(buffer,
- mFlinger.getRenderEngine(),
- renderengine::ExternalTexture::
- Usage::READABLE);
- });
- mBufferCache[transformHint].emplace(fps, textures);
+ mBufferCache[transformHint].emplace(fps, buffers);
}
return mBufferCache[transformHint][fps];
@@ -271,30 +262,26 @@
Rect frame((3 * width) >> 4, height >> 5);
frame.offsetBy(width >> 5, height >> 4);
- layer_state_t::matrix22_t matrix;
- matrix.dsdx = frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth());
- matrix.dtdx = 0;
- matrix.dtdy = 0;
- matrix.dsdy = frame.getHeight() / static_cast<float>(SevenSegmentDrawer::getHeight());
- mLayer->setMatrix(matrix, true);
- mLayer->setPosition(frame.left, frame.top);
- mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+ SurfaceComposerClient::Transaction t;
+ t.setMatrix(mSurfaceControl,
+ frame.getWidth() / static_cast<float>(SevenSegmentDrawer::getWidth()), 0, 0,
+ frame.getHeight() / static_cast<float>(SevenSegmentDrawer::getHeight()));
+ t.setPosition(mSurfaceControl, frame.left, frame.top);
+ t.apply();
}
void RefreshRateOverlay::setLayerStack(ui::LayerStack stack) {
- mLayer->setLayerStack(stack);
- mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+ SurfaceComposerClient::Transaction t;
+ t.setLayerStack(mSurfaceControl, stack);
+ t.apply();
}
void RefreshRateOverlay::changeRefreshRate(const Fps& fps) {
mCurrentFps = fps.getIntValue();
auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
- mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
- mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */),
- std::nullopt /* dequeueTime */, FrameTimelineInfo{},
- nullptr /* releaseBufferListener */, nullptr /* releaseBufferEndpoint */);
-
- mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+ SurfaceComposerClient::Transaction t;
+ t.setBuffer(mSurfaceControl, buffer);
+ t.apply();
}
void RefreshRateOverlay::onInvalidate() {
@@ -303,12 +290,9 @@
const auto& buffers = getOrCreateBuffers(*mCurrentFps);
mFrame = (mFrame + 1) % buffers.size();
auto buffer = buffers[mFrame];
- mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, true, {},
- mLayer->getHeadFrameNumber(-1 /* expectedPresentTime */),
- std::nullopt /* dequeueTime */, FrameTimelineInfo{},
- nullptr /* releaseBufferListener */, nullptr /* releaseBufferEndpoint */);
-
- mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+ SurfaceComposerClient::Transaction t;
+ t.setBuffer(mSurfaceControl, buffer);
+ t.apply();
}
} // namespace android
diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h
index 63ae383..354510a 100644
--- a/services/surfaceflinger/RefreshRateOverlay.h
+++ b/services/surfaceflinger/RefreshRateOverlay.h
@@ -37,6 +37,7 @@
class IGraphicBufferProducer;
class Layer;
class SurfaceFlinger;
+class SurfaceControl;
class RefreshRateOverlay {
public:
@@ -70,18 +71,16 @@
};
bool createLayer();
- const std::vector<std::shared_ptr<renderengine::ExternalTexture>>& getOrCreateBuffers(
- uint32_t fps);
+
+ const std::vector<sp<GraphicBuffer>>& getOrCreateBuffers(uint32_t fps);
SurfaceFlinger& mFlinger;
const sp<Client> mClient;
- sp<Layer> mLayer;
sp<IBinder> mIBinder;
sp<IGraphicBufferProducer> mGbp;
- std::unordered_map<
- ui::Transform::RotationFlags,
- std::unordered_map<int, std::vector<std::shared_ptr<renderengine::ExternalTexture>>>>
+ std::unordered_map<ui::Transform::RotationFlags,
+ std::unordered_map<int, std::vector<sp<GraphicBuffer>>>>
mBufferCache;
std::optional<int> mCurrentFps;
int mFrame = 0;
@@ -94,6 +93,8 @@
// Interpolate the colors between these values.
const uint32_t mLowFps;
const uint32_t mHighFps;
+
+ sp<SurfaceControl> mSurfaceControl;
};
} // namespace android