1 /*
2  * Copyright 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #undef LOG_TAG
18 #define LOG_TAG "CommitTest"
19 
20 #include <DisplayHardware/HWComposer.h>
21 #include <FrontEnd/LayerCreationArgs.h>
22 #include <FrontEnd/RequestedLayerState.h>
23 #include <compositionengine/CompositionEngine.h>
24 #include <compositionengine/Feature.h>
25 #include <compositionengine/mock/CompositionEngine.h>
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
28 #include <gui/LayerMetadata.h>
29 #include <gui/SurfaceComposerClient.h>
30 #include <mock/DisplayHardware/MockComposer.h>
31 #include <renderengine/mock/RenderEngine.h>
32 #include "TestableSurfaceFlinger.h"
33 
34 namespace android {
35 
36 class CommitTest : public testing::Test {
37 protected:
38     TestableSurfaceFlinger mFlinger;
39     renderengine::mock::RenderEngine* mRenderEngine = new renderengine::mock::RenderEngine();
40 
flinger_setup()41     void flinger_setup() {
42         mFlinger.setupMockScheduler();
43         mFlinger.setupComposer(std::make_unique<Hwc2::mock::Composer>());
44         mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
45     }
46 
createArgs(uint32_t id,LayerMetadata metadata,uint32_t parentId)47     LayerCreationArgs createArgs(uint32_t id, LayerMetadata metadata, uint32_t parentId) {
48         LayerCreationArgs args(mFlinger.flinger(), nullptr, "layer",
49                                gui::ISurfaceComposerClient::eNoColorFill, metadata, id);
50         args.parentId = parentId;
51         return args;
52     }
53 };
54 
55 namespace {
56 
TEST_F(CommitTest,noUpdatesDoesNotScheduleComposite)57 TEST_F(CommitTest, noUpdatesDoesNotScheduleComposite) {
58     flinger_setup();
59     bool unused;
60     bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
61                                                        /*transactionsFlushed=*/0, unused);
62     EXPECT_FALSE(mustComposite);
63 }
64 
65 // Ensure that we handle eTransactionNeeded correctly
TEST_F(CommitTest,eTransactionNeededFlagSchedulesComposite)66 TEST_F(CommitTest, eTransactionNeededFlagSchedulesComposite) {
67     flinger_setup();
68     // update display level color matrix
69     mFlinger.setDaltonizerType(ColorBlindnessType::Deuteranomaly);
70     bool unused;
71     bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
72                                                        /*transactionsFlushed=*/0, unused);
73     EXPECT_TRUE(mustComposite);
74 }
75 
TEST_F(CommitTest,metadataNotIncluded)76 TEST_F(CommitTest, metadataNotIncluded) {
77     mFlinger.setupMockScheduler();
78     mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
79     compositionengine::mock::CompositionEngine* mCompositionEngine =
80             new compositionengine::mock::CompositionEngine();
81 
82     // CompositionEngine setup with unset flag
83     compositionengine::FeatureFlags flags;
84     impl::HWComposer hwc = impl::HWComposer(std::make_unique<Hwc2::mock::Composer>());
85 
86     EXPECT_CALL(*mCompositionEngine, getFeatureFlags).WillOnce(testing::Return(flags));
87     EXPECT_THAT(flags.test(compositionengine::Feature::kSnapshotLayerMetadata), false);
88 
89     EXPECT_CALL(*mCompositionEngine, getHwComposer).WillOnce(testing::ReturnRef(hwc));
90 
91     mFlinger.setupCompositionEngine(
92             std::unique_ptr<compositionengine::CompositionEngine>(mCompositionEngine));
93 
94     // Create a parent layer with metadata and a child layer without. Metadata should not
95     // be included in the child layer when the flag is not set.
96     std::unordered_map<uint32_t, std::vector<uint8_t>> metadata = {{1, {'a', 'b'}}};
97     auto parentArgs = createArgs(1, LayerMetadata(metadata), UNASSIGNED_LAYER_ID);
98     auto parent = std::make_unique<frontend::RequestedLayerState>(parentArgs);
99     mFlinger.addLayer(parent);
100     mFlinger.injectLegacyLayer(sp<Layer>::make(parentArgs));
101 
102     auto childArgs = createArgs(11, LayerMetadata(), 1);
103     auto child = std::make_unique<frontend::RequestedLayerState>(childArgs);
104     mFlinger.addLayer(child);
105     mFlinger.injectLegacyLayer(sp<Layer>::make(childArgs));
106 
107     bool unused;
108     bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
109                                                        /*transactionsFlushed=*/1, unused);
110     EXPECT_TRUE(mustComposite);
111 
112     auto parentMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(1)->layerMetadata.mMap;
113     auto childMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(11)->layerMetadata.mMap;
114 
115     EXPECT_EQ(metadata.at(1), parentMetadata.at(1));
116     EXPECT_NE(parentMetadata, childMetadata);
117 }
118 
TEST_F(CommitTest,metadataIsIncluded)119 TEST_F(CommitTest, metadataIsIncluded) {
120     mFlinger.setupMockScheduler();
121     mFlinger.setupRenderEngine(std::unique_ptr<renderengine::RenderEngine>(mRenderEngine));
122     compositionengine::mock::CompositionEngine* mCompositionEngine =
123             new compositionengine::mock::CompositionEngine();
124 
125     // CompositionEngine setup with set flag
126     compositionengine::FeatureFlags flags;
127     flags |= compositionengine::Feature::kSnapshotLayerMetadata;
128     impl::HWComposer hwc = impl::HWComposer(std::make_unique<Hwc2::mock::Composer>());
129 
130     EXPECT_CALL(*mCompositionEngine, getFeatureFlags).WillOnce(testing::Return(flags));
131     EXPECT_THAT(flags.test(compositionengine::Feature::kSnapshotLayerMetadata), true);
132 
133     EXPECT_CALL(*mCompositionEngine, getHwComposer).WillOnce(testing::ReturnRef(hwc));
134 
135     mFlinger.setupCompositionEngine(
136             std::unique_ptr<compositionengine::CompositionEngine>(mCompositionEngine));
137 
138     // Create a parent layer with metadata and a child layer without. Metadata from the
139     // parent should be included in the child layer when the flag is set.
140     std::unordered_map<uint32_t, std::vector<uint8_t>> metadata = {{1, {'a', 'b'}}};
141     auto parentArgs = createArgs(1, LayerMetadata(metadata), UNASSIGNED_LAYER_ID);
142     auto parent = std::make_unique<frontend::RequestedLayerState>(parentArgs);
143     mFlinger.addLayer(parent);
144     mFlinger.injectLegacyLayer(sp<Layer>::make(parentArgs));
145 
146     auto childArgs = createArgs(11, LayerMetadata(), 1);
147     auto child = std::make_unique<frontend::RequestedLayerState>(childArgs);
148     mFlinger.addLayer(child);
149     mFlinger.injectLegacyLayer(sp<Layer>::make(childArgs));
150 
151     bool unused;
152     bool mustComposite = mFlinger.updateLayerSnapshots(VsyncId{1}, /*frameTimeNs=*/0,
153                                                        /*transactionsFlushed=*/1, unused);
154     EXPECT_TRUE(mustComposite);
155 
156     auto parentMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(1)->layerMetadata.mMap;
157     auto childMetadata = mFlinger.mutableLayerSnapshotBuilder().getSnapshot(11)->layerMetadata.mMap;
158 
159     EXPECT_EQ(metadata.at(1), parentMetadata.at(1));
160     EXPECT_EQ(parentMetadata, childMetadata);
161 }
162 
163 } // namespace
164 } // namespace android
165