Loading libs/gui/SurfaceComposerClient.cpp +14 −15 Original line number Diff line number Diff line Loading @@ -105,12 +105,11 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { for (auto const& state : other.mComposerStates) { ssize_t index = mComposerStates.indexOf(state); if (index < 0) { mComposerStates.add(state); for (auto const& kv : other.mComposerStates) { if (mComposerStates.count(kv.first) == 0) { mComposerStates[kv.first] = kv.second; } else { mComposerStates.editItemAt(static_cast<size_t>(index)).state.merge(state.state); mComposerStates[kv.first].state.merge(kv.second.state); } } other.mComposerStates.clear(); Loading Loading @@ -141,7 +140,10 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { mForceSynchronous |= synchronous; composerStates = mComposerStates; for (auto const& kv : mComposerStates){ composerStates.add(kv.second); } mComposerStates.clear(); displayStates = mDisplayStates; Loading Loading @@ -182,18 +184,15 @@ void SurfaceComposerClient::Transaction::setAnimationTransaction() { } layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) { if (mComposerStates.count(sc) == 0) { // we don't have it, add an initialized layer_state to our list ComposerState s; s.client = sc->getClient()->mClient; s.state.surface = sc->getHandle(); ssize_t index = mComposerStates.indexOf(s); if (index < 0) { // we don't have it, add an initialized layer_state to our list index = mComposerStates.add(s); mComposerStates[sc] = s; } ComposerState* const out = mComposerStates.editArray(); return &(out[index].state); return &(mComposerStates[sc].state); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( Loading libs/gui/include/gui/SurfaceComposerClient.h +8 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> #include <unordered_map> #include <binder/IBinder.h> Loading Loading @@ -127,8 +128,14 @@ public: static status_t injectVSync(nsecs_t when); struct SCHash { std::size_t operator()(const sp<SurfaceControl>& sc) const { return std::hash<SurfaceControl *>{}(sc.get()); } }; class Transaction { SortedVector<ComposerState> mComposerStates; std::unordered_map<sp<SurfaceControl>, ComposerState, SCHash> mComposerStates; SortedVector<DisplayState > mDisplayStates; uint32_t mForceSynchronous = 0; uint32_t mTransactionNestCount = 0; Loading services/surfaceflinger/tests/SurfaceFlinger_test.filter +1 −1 Original line number Diff line number Diff line { "presubmit": { "filter": "LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*" "filter": "LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:ScreenCaptureTest.*:DereferenceSurfaceControlTest.*" } } services/surfaceflinger/tests/Transaction_test.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -2460,4 +2460,49 @@ TEST_F(ScreenCaptureTest, CaptureInvalidLayer) { ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(redLayerHandle, &outBuffer, Rect::EMPTY_RECT, 1.0)); } class DereferenceSurfaceControlTest : public LayerTransactionTest { protected: void SetUp() override { LayerTransactionTest::SetUp(); bgLayer = createLayer("BG layer", 20, 20); fillLayerColor(bgLayer, Color::RED); fgLayer = createLayer("FG layer", 20, 20); fillLayerColor(fgLayer, Color::BLUE); Transaction().setLayer(fgLayer, mLayerZBase + 1).apply(); { SCOPED_TRACE("before anything"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, 20, 20), Color::BLUE); } } void TearDown() override { LayerTransactionTest::TearDown(); bgLayer = 0; fgLayer = 0; } sp<SurfaceControl> bgLayer; sp<SurfaceControl> fgLayer; }; TEST_F(DereferenceSurfaceControlTest, LayerNotInTransaction) { fgLayer = nullptr; { SCOPED_TRACE("after setting null"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, 20, 20), Color::RED); } } TEST_F(DereferenceSurfaceControlTest, LayerInTransaction) { auto transaction = Transaction().show(fgLayer); fgLayer = nullptr; { SCOPED_TRACE("after setting null"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, 20, 20), Color::BLUE); } } } // namespace android Loading
libs/gui/SurfaceComposerClient.cpp +14 −15 Original line number Diff line number Diff line Loading @@ -105,12 +105,11 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other) : } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) { for (auto const& state : other.mComposerStates) { ssize_t index = mComposerStates.indexOf(state); if (index < 0) { mComposerStates.add(state); for (auto const& kv : other.mComposerStates) { if (mComposerStates.count(kv.first) == 0) { mComposerStates[kv.first] = kv.second; } else { mComposerStates.editItemAt(static_cast<size_t>(index)).state.merge(state.state); mComposerStates[kv.first].state.merge(kv.second.state); } } other.mComposerStates.clear(); Loading Loading @@ -141,7 +140,10 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous) { mForceSynchronous |= synchronous; composerStates = mComposerStates; for (auto const& kv : mComposerStates){ composerStates.add(kv.second); } mComposerStates.clear(); displayStates = mDisplayStates; Loading Loading @@ -182,18 +184,15 @@ void SurfaceComposerClient::Transaction::setAnimationTransaction() { } layer_state_t* SurfaceComposerClient::Transaction::getLayerState(const sp<SurfaceControl>& sc) { if (mComposerStates.count(sc) == 0) { // we don't have it, add an initialized layer_state to our list ComposerState s; s.client = sc->getClient()->mClient; s.state.surface = sc->getHandle(); ssize_t index = mComposerStates.indexOf(s); if (index < 0) { // we don't have it, add an initialized layer_state to our list index = mComposerStates.add(s); mComposerStates[sc] = s; } ComposerState* const out = mComposerStates.editArray(); return &(out[index].state); return &(mComposerStates[sc].state); } SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition( Loading
libs/gui/include/gui/SurfaceComposerClient.h +8 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <stdint.h> #include <sys/types.h> #include <unordered_map> #include <binder/IBinder.h> Loading Loading @@ -127,8 +128,14 @@ public: static status_t injectVSync(nsecs_t when); struct SCHash { std::size_t operator()(const sp<SurfaceControl>& sc) const { return std::hash<SurfaceControl *>{}(sc.get()); } }; class Transaction { SortedVector<ComposerState> mComposerStates; std::unordered_map<sp<SurfaceControl>, ComposerState, SCHash> mComposerStates; SortedVector<DisplayState > mDisplayStates; uint32_t mForceSynchronous = 0; uint32_t mTransactionNestCount = 0; Loading
services/surfaceflinger/tests/SurfaceFlinger_test.filter +1 −1 Original line number Diff line number Diff line { "presubmit": { "filter": "LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*" "filter": "LayerTransactionTest.*:LayerUpdateTest.*:ChildLayerTest.*:SurfaceFlingerStress.*:CropLatchingTest.*:GeometryLatchingTest.*:ScreenCaptureTest.*:DereferenceSurfaceControlTest.*" } }
services/surfaceflinger/tests/Transaction_test.cpp +45 −0 Original line number Diff line number Diff line Loading @@ -2460,4 +2460,49 @@ TEST_F(ScreenCaptureTest, CaptureInvalidLayer) { ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(redLayerHandle, &outBuffer, Rect::EMPTY_RECT, 1.0)); } class DereferenceSurfaceControlTest : public LayerTransactionTest { protected: void SetUp() override { LayerTransactionTest::SetUp(); bgLayer = createLayer("BG layer", 20, 20); fillLayerColor(bgLayer, Color::RED); fgLayer = createLayer("FG layer", 20, 20); fillLayerColor(fgLayer, Color::BLUE); Transaction().setLayer(fgLayer, mLayerZBase + 1).apply(); { SCOPED_TRACE("before anything"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, 20, 20), Color::BLUE); } } void TearDown() override { LayerTransactionTest::TearDown(); bgLayer = 0; fgLayer = 0; } sp<SurfaceControl> bgLayer; sp<SurfaceControl> fgLayer; }; TEST_F(DereferenceSurfaceControlTest, LayerNotInTransaction) { fgLayer = nullptr; { SCOPED_TRACE("after setting null"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, 20, 20), Color::RED); } } TEST_F(DereferenceSurfaceControlTest, LayerInTransaction) { auto transaction = Transaction().show(fgLayer); fgLayer = nullptr; { SCOPED_TRACE("after setting null"); auto shot = screenshot(); shot->expectColor(Rect(0, 0, 20, 20), Color::BLUE); } } } // namespace android