summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Evan Rosky <erosky@google.com> 2019-01-25 17:46:06 -0800
committer Evan Rosky <erosky@google.com> 2019-02-05 23:33:39 +0000
commitef876c9c6bb5118c457c9146964d76de854c11fc (patch)
tree5704e98cea15fb2204408c0932eb0e911b8652d8
parentc0f4a2edd57ec26335ac52efd4584552cea19f2c (diff)
Merge metadata from transaction instead of replace
This was replacing metadata when set in transactions rather than merging. To fix this, merge has been augmented to also report if a change occurred and to erase empty entries (as a mechanism to "unset" metadata) Bug: 122925737 Test: Added more unittests Change-Id: Ia854cbcc1ddd334f18ffacea667cbb98778ec210
-rw-r--r--libs/gui/LayerMetadata.cpp17
-rw-r--r--libs/gui/include/gui/LayerMetadata.h4
-rw-r--r--services/surfaceflinger/Layer.cpp6
-rw-r--r--services/surfaceflinger/Layer.h2
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp2
-rw-r--r--services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp41
6 files changed, 54 insertions, 18 deletions
diff --git a/libs/gui/LayerMetadata.cpp b/libs/gui/LayerMetadata.cpp
index 745433a605..04d2871c77 100644
--- a/libs/gui/LayerMetadata.cpp
+++ b/libs/gui/LayerMetadata.cpp
@@ -31,10 +31,23 @@ LayerMetadata::LayerMetadata(const LayerMetadata& other) = default;
LayerMetadata::LayerMetadata(LayerMetadata&& other) = default;
-void LayerMetadata::merge(const LayerMetadata& other) {
+bool LayerMetadata::merge(const LayerMetadata& other, bool eraseEmpty) {
+ bool changed = false;
for (const auto& entry : other.mMap) {
- mMap[entry.first] = entry.second;
+ auto it = mMap.find(entry.first);
+ if (it != mMap.cend() && it->second != entry.second) {
+ if (eraseEmpty && entry.second.empty()) {
+ mMap.erase(it);
+ } else {
+ it->second = entry.second;
+ }
+ changed = true;
+ } else if (it == mMap.cend() && !entry.second.empty()) {
+ mMap[entry.first] = entry.second;
+ changed = true;
+ }
}
+ return changed;
}
status_t LayerMetadata::writeToParcel(Parcel* parcel) const {
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h
index 3ae10e461d..47f0cede3a 100644
--- a/libs/gui/include/gui/LayerMetadata.h
+++ b/libs/gui/include/gui/LayerMetadata.h
@@ -34,7 +34,9 @@ struct LayerMetadata : public Parcelable {
LayerMetadata& operator=(const LayerMetadata& other);
LayerMetadata& operator=(LayerMetadata&& other);
- void merge(const LayerMetadata& other);
+ // Merges other into this LayerMetadata. If eraseEmpty is true, any entries in
+ // in this whose keys are paired with empty values in other will be erased.
+ bool merge(const LayerMetadata& other, bool eraseEmpty = false);
status_t writeToParcel(Parcel* parcel) const override;
status_t readFromParcel(const Parcel* parcel) override;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 2de169dcb1..646402ccad 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1334,10 +1334,8 @@ bool Layer::setOverrideScalingMode(int32_t scalingMode) {
return true;
}
-bool Layer::setMetadata(LayerMetadata data) {
- bool changed = data.mMap != mCurrentState.metadata.mMap;
- if (!changed) return false;
- mCurrentState.metadata = std::move(data);
+bool Layer::setMetadata(const LayerMetadata& data) {
+ if (!mCurrentState.metadata.merge(data, true /* eraseEmpty */)) return false;
mCurrentState.sequence++;
mCurrentState.modified = true;
setTransactionFlags(eTransactionNeeded);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f099df613b..367129aa70 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -290,7 +290,7 @@ public:
uint64_t frameNumber);
virtual void deferTransactionUntil_legacy(const sp<Layer>& barrierLayer, uint64_t frameNumber);
virtual bool setOverrideScalingMode(int32_t overrideScalingMode);
- virtual bool setMetadata(LayerMetadata data);
+ virtual bool setMetadata(const LayerMetadata& data);
virtual bool reparentChildren(const sp<IBinder>& layer);
virtual void setChildrenDrawingParent(const sp<Layer>& layer);
virtual bool reparent(const sp<IBinder>& newParentHandle);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9d03ae7f5f..b5b0108b2d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -4116,7 +4116,7 @@ status_t SurfaceFlinger::createLayer(const String8& name, const sp<Client>& clie
}
}
- layer->setMetadata(std::move(metadata));
+ layer->setMetadata(metadata);
bool addToCurrentState = callingThreadHasUnscopedSurfaceFlingerAccess();
result = addClientLayer(client, *handle, *gbp, layer, *parent,
diff --git a/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp b/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp
index 92c9f92bf1..75a061bf77 100644
--- a/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerMetadataTest.cpp
@@ -62,24 +62,47 @@ TEST_F(LayerMetadataTest, testLayerMetadata) {
metadata.mMap[2] = std::vector<uint8_t>{'a', 'b'};
ASSERT_EQ(0, metadata.getInt32(2, 0));
+ Parcel p;
+ metadata.writeToParcel(&p);
+ LayerMetadata reconstructed;
+ reconstructed.setInt32(3, 1); // to make sure it gets replaced
+ p.setDataPosition(0);
+ reconstructed.readFromParcel(&p);
+ ASSERT_EQ(metadata.mMap, reconstructed.mMap);
+}
+
+TEST_F(LayerMetadataTest, merge) {
+ LayerMetadata metadata;
+ metadata.setInt32(4, 2);
+ metadata.mMap[2] = std::vector<uint8_t>{'a', 'b'};
+
LayerMetadata second;
std::vector<uint8_t> someData{'c', 'd', '\0'};
second.mMap[2] = someData;
second.setInt32(6, 5);
- metadata.merge(second);
+ second.mMap[4].clear(); // will not delete if eraseEmpty is false
+ bool changed = metadata.merge(second);
+ ASSERT_TRUE(changed);
ASSERT_EQ(3, metadata.mMap.size());
ASSERT_EQ(someData, second.mMap[2]);
ASSERT_EQ(5, metadata.getInt32(6, 0));
- ASSERT_EQ(2, metadata.getInt32(4, 0));
+ ASSERT_TRUE(metadata.mMap.at(4).empty());
- Parcel p;
- metadata.writeToParcel(&p);
- LayerMetadata reconstructed;
- reconstructed.setInt32(3, 1); // to make sure it gets replaced
- p.setDataPosition(0);
- reconstructed.readFromParcel(&p);
- ASSERT_EQ(metadata.mMap, reconstructed.mMap);
+ LayerMetadata withErase;
+ withErase.mMap[6].clear();
+ changed = metadata.merge(withErase, true /* eraseEmpty */);
+ ASSERT_TRUE(changed);
+ ASSERT_EQ(2, metadata.mMap.size());
+ ASSERT_EQ(someData, second.mMap[2]);
+ ASSERT_EQ(true, metadata.has(4));
+
+ // test for change detection
+ LayerMetadata third;
+ third.mMap[2] = someData;
+ third.mMap[5].clear();
+ changed = metadata.merge(third);
+ ASSERT_FALSE(changed);
}
} // namespace