• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2021 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 #include "DisplayHardware/Hal.h"
18 #undef LOG_TAG
19 #define LOG_TAG "PredictorTest"
20 
21 #include <compositionengine/impl/planner/Predictor.h>
22 #include <compositionengine/mock/LayerFE.h>
23 #include <compositionengine/mock/OutputLayer.h>
24 #include <gtest/gtest.h>
25 #include <log/log.h>
26 
27 #include <aidl/android/hardware/graphics/composer3/Composition.h>
28 
29 using aidl::android::hardware::graphics::composer3::Composition;
30 
31 namespace android::compositionengine::impl::planner {
32 namespace {
33 
34 const FloatRect sFloatRectOne = FloatRect(100.f, 200.f, 300.f, 400.f);
35 const FloatRect sFloatRectTwo = FloatRect(400.f, 300.f, 200.f, 100.f);
36 const Rect sRectOne = Rect(1, 2, 3, 4);
37 const Rect sRectTwo = Rect(4, 3, 2, 1);
38 const constexpr float sAlphaOne = 0.25f;
39 const constexpr float sAlphaTwo = 0.5f;
40 const Region sRegionOne = Region(sRectOne);
41 const Region sRegionTwo = Region(sRectTwo);
42 const mat4 sMat4One = mat4::scale(vec4(2.f, 3.f, 1.f, 1.f));
43 
44 using testing::Return;
45 using testing::ReturnRef;
46 
47 const std::string sDebugName = std::string("Test LayerFE");
48 const constexpr int32_t sSequenceId = 12345;
49 
setupMocksForLayer(mock::OutputLayer & layer,mock::LayerFE & layerFE,const OutputLayerCompositionState & outputLayerState,const LayerFECompositionState & layerFEState)50 void setupMocksForLayer(mock::OutputLayer& layer, mock::LayerFE& layerFE,
51                         const OutputLayerCompositionState& outputLayerState,
52                         const LayerFECompositionState& layerFEState) {
53     EXPECT_CALL(layer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
54     EXPECT_CALL(layer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
55     EXPECT_CALL(layerFE, getSequence()).WillRepeatedly(Return(sSequenceId));
56     EXPECT_CALL(layerFE, getDebugName()).WillRepeatedly(Return(sDebugName.c_str()));
57     EXPECT_CALL(layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
58 }
59 
60 struct LayerStackTest : public testing::Test {
LayerStackTestandroid::compositionengine::impl::planner::__anon944e45fa0111::LayerStackTest61     LayerStackTest() {
62         const ::testing::TestInfo* const test_info =
63                 ::testing::UnitTest::GetInstance()->current_test_info();
64         ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
65     }
66 
~LayerStackTestandroid::compositionengine::impl::planner::__anon944e45fa0111::LayerStackTest67     ~LayerStackTest() {
68         const ::testing::TestInfo* const test_info =
69                 ::testing::UnitTest::GetInstance()->current_test_info();
70         ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
71     }
72 };
73 
TEST_F(LayerStackTest,getApproximateMatch_doesNotMatchSizeDifferences)74 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchSizeDifferences) {
75     mock::OutputLayer outputLayerOne;
76     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
77     OutputLayerCompositionState outputLayerCompositionStateOne;
78     LayerFECompositionState layerFECompositionStateOne;
79     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
80                        layerFECompositionStateOne);
81     LayerState layerStateOne(&outputLayerOne);
82 
83     mock::OutputLayer outputLayerTwo;
84     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
85     OutputLayerCompositionState outputLayerCompositionStateTwo;
86     LayerFECompositionState layerFECompositionStateTwo;
87     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
88                        layerFECompositionStateTwo);
89     LayerState layerStateTwo(&outputLayerTwo);
90 
91     mock::OutputLayer outputLayerThree;
92     sp<mock::LayerFE> layerFEThree = sp<mock::LayerFE>::make();
93     OutputLayerCompositionState outputLayerCompositionStateThree;
94     LayerFECompositionState layerFECompositionStateThree;
95     setupMocksForLayer(outputLayerThree, *layerFEThree, outputLayerCompositionStateThree,
96                        layerFECompositionStateThree);
97     LayerState layerStateThree(&outputLayerThree);
98 
99     LayerStack stack({&layerStateOne});
100 
101     EXPECT_FALSE(stack.getApproximateMatch({}));
102     EXPECT_FALSE(stack.getApproximateMatch({&layerStateOne, &layerStateThree}));
103 }
104 
TEST_F(LayerStackTest,getApproximateMatch_doesNotMatchDifferentCompositionTypes)105 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchDifferentCompositionTypes) {
106     mock::OutputLayer outputLayerOne;
107     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
108     OutputLayerCompositionState outputLayerCompositionStateOne;
109     LayerFECompositionState layerFECompositionStateOne;
110     layerFECompositionStateOne.compositionType = Composition::DEVICE;
111     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
112                        layerFECompositionStateOne);
113     LayerState layerStateOne(&outputLayerOne);
114 
115     mock::OutputLayer outputLayerTwo;
116     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
117     OutputLayerCompositionState outputLayerCompositionStateTwo;
118     LayerFECompositionState layerFECompositionStateTwo;
119     layerFECompositionStateTwo.compositionType = Composition::SOLID_COLOR;
120     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
121                        layerFECompositionStateTwo);
122     LayerState layerStateTwo(&outputLayerTwo);
123 
124     LayerStack stack({&layerStateOne});
125 
126     EXPECT_FALSE(stack.getApproximateMatch({&layerStateTwo}));
127 }
128 
TEST_F(LayerStackTest,getApproximateMatch_matchesSingleDifferenceInSingleLayer)129 TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInSingleLayer) {
130     mock::OutputLayer outputLayerOne;
131     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
132     OutputLayerCompositionState outputLayerCompositionStateOne{
133             .sourceCrop = sFloatRectOne,
134     };
135     LayerFECompositionState layerFECompositionStateOne;
136     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
137                        layerFECompositionStateOne);
138     LayerState layerStateOne(&outputLayerOne);
139 
140     mock::OutputLayer outputLayerTwo;
141     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
142     OutputLayerCompositionState outputLayerCompositionStateTwo{
143             .sourceCrop = sFloatRectTwo,
144     };
145     LayerFECompositionState layerFECompositionStateTwo;
146     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
147                        layerFECompositionStateTwo);
148     LayerState layerStateTwo(&outputLayerTwo);
149 
150     LayerStack stack({&layerStateOne});
151 
152     const auto match = stack.getApproximateMatch({&layerStateTwo});
153     EXPECT_TRUE(match);
154     LayerStack::ApproximateMatch expectedMatch;
155     expectedMatch.differingIndex = 0;
156     expectedMatch.differingFields = LayerStateField::SourceCrop;
157     EXPECT_EQ(expectedMatch, *match);
158 }
159 
TEST_F(LayerStackTest,getApproximateMatch_matchesSingleDifferenceInMultiLayerStack)160 TEST_F(LayerStackTest, getApproximateMatch_matchesSingleDifferenceInMultiLayerStack) {
161     mock::OutputLayer outputLayerOne;
162     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
163     OutputLayerCompositionState outputLayerCompositionStateOne{
164             .sourceCrop = sFloatRectOne,
165     };
166     LayerFECompositionState layerFECompositionStateOne;
167     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
168                        layerFECompositionStateOne);
169     LayerState layerStateOne(&outputLayerOne);
170 
171     mock::OutputLayer outputLayerTwo;
172     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
173     OutputLayerCompositionState outputLayerCompositionStateTwo{
174             .sourceCrop = sFloatRectTwo,
175     };
176     LayerFECompositionState layerFECompositionStateTwo;
177     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
178                        layerFECompositionStateTwo);
179     LayerState layerStateTwo(&outputLayerTwo);
180 
181     LayerStack stack({&layerStateOne, &layerStateOne});
182 
183     const auto match = stack.getApproximateMatch({&layerStateOne, &layerStateTwo});
184     EXPECT_TRUE(match);
185     LayerStack::ApproximateMatch expectedMatch;
186     expectedMatch.differingIndex = 1;
187     expectedMatch.differingFields = LayerStateField::SourceCrop;
188     EXPECT_EQ(expectedMatch, *match);
189 }
190 
TEST_F(LayerStackTest,getApproximateMatch_doesNotMatchManyDifferences)191 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchManyDifferences) {
192     mock::OutputLayer outputLayerOne;
193     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
194     OutputLayerCompositionState outputLayerCompositionStateOne{
195             .visibleRegion = sRegionOne,
196             .displayFrame = sRectOne,
197             .sourceCrop = sFloatRectOne,
198             .dataspace = ui::Dataspace::SRGB,
199     };
200     LayerFECompositionState layerFECompositionStateOne;
201     layerFECompositionStateOne.alpha = sAlphaOne;
202     layerFECompositionStateOne.colorTransformIsIdentity = true;
203     layerFECompositionStateOne.blendMode = hal::BlendMode::NONE;
204     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
205                        layerFECompositionStateOne);
206     LayerState layerStateOne(&outputLayerOne);
207 
208     mock::OutputLayer outputLayerTwo;
209     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
210     OutputLayerCompositionState outputLayerCompositionStateTwo{
211             .visibleRegion = sRegionTwo,
212             .displayFrame = sRectTwo,
213             .sourceCrop = sFloatRectTwo,
214             .dataspace = ui::Dataspace::DISPLAY_P3,
215     };
216     LayerFECompositionState layerFECompositionStateTwo;
217     layerFECompositionStateTwo.alpha = sAlphaTwo;
218     layerFECompositionStateTwo.colorTransformIsIdentity = false;
219     layerFECompositionStateTwo.colorTransform = sMat4One;
220     layerFECompositionStateTwo.blendMode = hal::BlendMode::PREMULTIPLIED;
221     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
222                        layerFECompositionStateTwo);
223     LayerState layerStateTwo(&outputLayerTwo);
224 
225     LayerStack stack({&layerStateOne});
226 
227     EXPECT_FALSE(stack.getApproximateMatch({&layerStateTwo}));
228 }
229 
TEST_F(LayerStackTest,getApproximateMatch_exactMatchesSameBuffer)230 TEST_F(LayerStackTest, getApproximateMatch_exactMatchesSameBuffer) {
231     sp<GraphicBuffer> buffer = new GraphicBuffer();
232     mock::OutputLayer outputLayerOne;
233     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
234     OutputLayerCompositionState outputLayerCompositionStateOne;
235     LayerFECompositionState layerFECompositionStateOne;
236     layerFECompositionStateOne.buffer = buffer;
237     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
238                        layerFECompositionStateOne);
239     LayerState layerStateOne(&outputLayerOne);
240 
241     mock::OutputLayer outputLayerTwo;
242     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
243     OutputLayerCompositionState outputLayerCompositionStateTwo;
244     LayerFECompositionState layerFECompositionStateTwo;
245     layerFECompositionStateTwo.buffer = buffer;
246     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
247                        layerFECompositionStateTwo);
248     LayerState layerStateTwo(&outputLayerTwo);
249 
250     LayerStack stack({&layerStateOne});
251 
252     const auto match = stack.getApproximateMatch({&layerStateTwo});
253     EXPECT_TRUE(match);
254     LayerStack::ApproximateMatch expectedMatch;
255     expectedMatch.differingIndex = 0;
256     expectedMatch.differingFields = LayerStateField::None;
257     EXPECT_EQ(expectedMatch, *match);
258 }
259 
TEST_F(LayerStackTest,getApproximateMatch_alwaysMatchesClientComposition)260 TEST_F(LayerStackTest, getApproximateMatch_alwaysMatchesClientComposition) {
261     mock::OutputLayer outputLayerOne;
262     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
263     OutputLayerCompositionState outputLayerCompositionStateOne{
264             .visibleRegion = sRegionOne,
265             .forceClientComposition = true,
266             .displayFrame = sRectOne,
267             .sourceCrop = sFloatRectOne,
268             .dataspace = ui::Dataspace::SRGB,
269     };
270     LayerFECompositionState layerFECompositionStateOne;
271     layerFECompositionStateOne.buffer = new GraphicBuffer();
272     layerFECompositionStateOne.alpha = sAlphaOne;
273     layerFECompositionStateOne.colorTransformIsIdentity = true;
274     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
275                        layerFECompositionStateOne);
276     LayerState layerStateOne(&outputLayerOne);
277 
278     mock::OutputLayer outputLayerTwo;
279     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
280     OutputLayerCompositionState outputLayerCompositionStateTwo{
281             .visibleRegion = sRegionTwo,
282             .forceClientComposition = true,
283             .displayFrame = sRectTwo,
284             .sourceCrop = sFloatRectTwo,
285             .dataspace = ui::Dataspace::DISPLAY_P3,
286     };
287     LayerFECompositionState layerFECompositionStateTwo;
288     layerFECompositionStateTwo.buffer = new GraphicBuffer();
289     layerFECompositionStateTwo.alpha = sAlphaTwo;
290     layerFECompositionStateTwo.colorTransformIsIdentity = false;
291     layerFECompositionStateTwo.colorTransform = sMat4One;
292     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
293                        layerFECompositionStateTwo);
294     LayerState layerStateTwo(&outputLayerTwo);
295 
296     LayerStack stack({&layerStateOne});
297 
298     const auto match = stack.getApproximateMatch({&layerStateTwo});
299     EXPECT_TRUE(match);
300     LayerStack::ApproximateMatch expectedMatch;
301     expectedMatch.differingIndex = 0;
302     expectedMatch.differingFields = LayerStateField::None;
303     EXPECT_EQ(expectedMatch, *match);
304 }
305 
TEST_F(LayerStackTest,getApproximateMatch_doesNotMatchMultipleApproximations)306 TEST_F(LayerStackTest, getApproximateMatch_doesNotMatchMultipleApproximations) {
307     mock::OutputLayer outputLayerOne;
308     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
309     OutputLayerCompositionState outputLayerCompositionStateOne{
310             .sourceCrop = sFloatRectOne,
311     };
312     LayerFECompositionState layerFECompositionStateOne;
313     layerFECompositionStateOne.buffer = new GraphicBuffer();
314     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
315                        layerFECompositionStateOne);
316     LayerState layerStateOne(&outputLayerOne);
317 
318     mock::OutputLayer outputLayerTwo;
319     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
320     OutputLayerCompositionState outputLayerCompositionStateTwo{
321             .sourceCrop = sFloatRectTwo,
322     };
323     LayerFECompositionState layerFECompositionStateTwo;
324     layerFECompositionStateTwo.buffer = new GraphicBuffer();
325     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
326                        layerFECompositionStateTwo);
327     LayerState layerStateTwo(&outputLayerTwo);
328 
329     EXPECT_TRUE(LayerStack({&layerStateOne}).getApproximateMatch({&layerStateTwo}));
330 
331     LayerStack stack({&layerStateOne, &layerStateOne});
332     EXPECT_FALSE(stack.getApproximateMatch({&layerStateTwo, &layerStateTwo}));
333 }
334 
335 struct PredictionTest : public testing::Test {
PredictionTestandroid::compositionengine::impl::planner::__anon944e45fa0111::PredictionTest336     PredictionTest() {
337         const ::testing::TestInfo* const test_info =
338                 ::testing::UnitTest::GetInstance()->current_test_info();
339         ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
340     }
341 
~PredictionTestandroid::compositionengine::impl::planner::__anon944e45fa0111::PredictionTest342     ~PredictionTest() {
343         const ::testing::TestInfo* const test_info =
344                 ::testing::UnitTest::GetInstance()->current_test_info();
345         ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
346     }
347 };
348 
TEST_F(LayerStackTest,reorderingChangesNonBufferHash)349 TEST_F(LayerStackTest, reorderingChangesNonBufferHash) {
350     mock::OutputLayer outputLayerOne;
351     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
352     OutputLayerCompositionState outputLayerCompositionStateOne{
353             .sourceCrop = sFloatRectOne,
354     };
355     LayerFECompositionState layerFECompositionStateOne;
356     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
357                        layerFECompositionStateOne);
358     LayerState layerStateOne(&outputLayerOne);
359 
360     mock::OutputLayer outputLayerTwo;
361     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
362     OutputLayerCompositionState outputLayerCompositionStateTwo{
363             .sourceCrop = sFloatRectTwo,
364     };
365     LayerFECompositionState layerFECompositionStateTwo;
366     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
367                        layerFECompositionStateTwo);
368     LayerState layerStateTwo(&outputLayerTwo);
369 
370     NonBufferHash hash = getNonBufferHash({&layerStateOne, &layerStateTwo});
371     NonBufferHash hashReverse = getNonBufferHash({&layerStateTwo, &layerStateOne});
372     EXPECT_NE(hash, hashReverse);
373 }
374 
TEST_F(PredictionTest,constructPrediction)375 TEST_F(PredictionTest, constructPrediction) {
376     Plan plan;
377     plan.addLayerType(Composition::DEVICE);
378 
379     Prediction prediction({}, plan);
380 
381     EXPECT_EQ(plan, prediction.getPlan());
382 
383     // check that dump doesn't crash
384     std::string result;
385     prediction.dump(result);
386 }
387 
TEST_F(PredictionTest,recordHits)388 TEST_F(PredictionTest, recordHits) {
389     Prediction prediction({}, {});
390 
391     const constexpr uint32_t kExactMatches = 2;
392     for (uint32_t i = 0; i < kExactMatches; i++) {
393         prediction.recordHit(Prediction::Type::Exact);
394     }
395 
396     const constexpr uint32_t kApproximateMatches = 3;
397     for (uint32_t i = 0; i < kApproximateMatches; i++) {
398         prediction.recordHit(Prediction::Type::Approximate);
399     }
400 
401     EXPECT_EQ(kExactMatches, prediction.getHitCount(Prediction::Type::Exact));
402     EXPECT_EQ(kApproximateMatches, prediction.getHitCount(Prediction::Type::Approximate));
403     EXPECT_EQ(kExactMatches + kApproximateMatches, prediction.getHitCount(Prediction::Type::Total));
404 }
405 
TEST_F(PredictionTest,recordMisses)406 TEST_F(PredictionTest, recordMisses) {
407     Prediction prediction({}, {});
408 
409     const constexpr uint32_t kExactMatches = 2;
410     for (uint32_t i = 0; i < kExactMatches; i++) {
411         prediction.recordMiss(Prediction::Type::Exact);
412     }
413 
414     const constexpr uint32_t kApproximateMatches = 3;
415     for (uint32_t i = 0; i < kApproximateMatches; i++) {
416         prediction.recordMiss(Prediction::Type::Approximate);
417     }
418 
419     EXPECT_EQ(kExactMatches, prediction.getMissCount(Prediction::Type::Exact));
420     EXPECT_EQ(kApproximateMatches, prediction.getMissCount(Prediction::Type::Approximate));
421     EXPECT_EQ(kExactMatches + kApproximateMatches,
422               prediction.getMissCount(Prediction::Type::Total));
423 }
424 
425 struct PredictorTest : public testing::Test {
PredictorTestandroid::compositionengine::impl::planner::__anon944e45fa0111::PredictorTest426     PredictorTest() {
427         const ::testing::TestInfo* const test_info =
428                 ::testing::UnitTest::GetInstance()->current_test_info();
429         ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
430     }
431 
~PredictorTestandroid::compositionengine::impl::planner::__anon944e45fa0111::PredictorTest432     ~PredictorTest() {
433         const ::testing::TestInfo* const test_info =
434                 ::testing::UnitTest::GetInstance()->current_test_info();
435         ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
436     }
437 };
438 
TEST_F(PredictorTest,getPredictedPlan_emptyLayersWithoutExactMatch_returnsNullopt)439 TEST_F(PredictorTest, getPredictedPlan_emptyLayersWithoutExactMatch_returnsNullopt) {
440     Predictor predictor;
441     EXPECT_FALSE(predictor.getPredictedPlan({}, 0));
442 }
443 
TEST_F(PredictorTest,getPredictedPlan_recordCandidateAndRetrieveExactMatch)444 TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveExactMatch) {
445     mock::OutputLayer outputLayerOne;
446     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
447     OutputLayerCompositionState outputLayerCompositionStateOne;
448     LayerFECompositionState layerFECompositionStateOne;
449     layerFECompositionStateOne.compositionType = Composition::DEVICE;
450     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
451                        layerFECompositionStateOne);
452     LayerState layerStateOne(&outputLayerOne);
453 
454     Plan plan;
455     plan.addLayerType(Composition::DEVICE);
456 
457     Predictor predictor;
458 
459     NonBufferHash hash = getNonBufferHash({&layerStateOne});
460 
461     predictor.recordResult(std::nullopt, hash, {&layerStateOne}, false, plan);
462 
463     auto predictedPlan = predictor.getPredictedPlan({}, hash);
464     EXPECT_TRUE(predictedPlan);
465     Predictor::PredictedPlan expectedPlan{hash, plan, Prediction::Type::Exact};
466     EXPECT_EQ(expectedPlan, predictedPlan);
467 }
468 
TEST_F(PredictorTest,getPredictedPlan_recordCandidateAndRetrieveApproximateMatch)469 TEST_F(PredictorTest, getPredictedPlan_recordCandidateAndRetrieveApproximateMatch) {
470     mock::OutputLayer outputLayerOne;
471     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
472     OutputLayerCompositionState outputLayerCompositionStateOne{
473             .sourceCrop = sFloatRectOne,
474     };
475     LayerFECompositionState layerFECompositionStateOne;
476     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
477                        layerFECompositionStateOne);
478     LayerState layerStateOne(&outputLayerOne);
479 
480     mock::OutputLayer outputLayerTwo;
481     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
482     OutputLayerCompositionState outputLayerCompositionStateTwo{
483             .sourceCrop = sFloatRectTwo,
484     };
485     LayerFECompositionState layerFECompositionStateTwo;
486     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
487                        layerFECompositionStateTwo);
488     LayerState layerStateTwo(&outputLayerTwo);
489 
490     Plan plan;
491     plan.addLayerType(Composition::DEVICE);
492 
493     Predictor predictor;
494 
495     NonBufferHash hashOne = getNonBufferHash({&layerStateOne});
496     NonBufferHash hashTwo = getNonBufferHash({&layerStateTwo});
497 
498     predictor.recordResult(std::nullopt, hashOne, {&layerStateOne}, false, plan);
499 
500     auto predictedPlan = predictor.getPredictedPlan({&layerStateTwo}, hashTwo);
501     EXPECT_TRUE(predictedPlan);
502     Predictor::PredictedPlan expectedPlan{hashOne, plan, Prediction::Type::Approximate};
503     EXPECT_EQ(expectedPlan, predictedPlan);
504 }
505 
TEST_F(PredictorTest,recordMissedPlan_skipsApproximateMatch)506 TEST_F(PredictorTest, recordMissedPlan_skipsApproximateMatch) {
507     mock::OutputLayer outputLayerOne;
508     sp<mock::LayerFE> layerFEOne = sp<mock::LayerFE>::make();
509     OutputLayerCompositionState outputLayerCompositionStateOne{
510             .sourceCrop = sFloatRectOne,
511     };
512     LayerFECompositionState layerFECompositionStateOne;
513     setupMocksForLayer(outputLayerOne, *layerFEOne, outputLayerCompositionStateOne,
514                        layerFECompositionStateOne);
515     LayerState layerStateOne(&outputLayerOne);
516 
517     mock::OutputLayer outputLayerTwo;
518     sp<mock::LayerFE> layerFETwo = sp<mock::LayerFE>::make();
519     OutputLayerCompositionState outputLayerCompositionStateTwo{
520             .sourceCrop = sFloatRectTwo,
521     };
522     LayerFECompositionState layerFECompositionStateTwo;
523     setupMocksForLayer(outputLayerTwo, *layerFETwo, outputLayerCompositionStateTwo,
524                        layerFECompositionStateTwo);
525     LayerState layerStateTwo(&outputLayerTwo);
526 
527     Plan plan;
528     plan.addLayerType(Composition::DEVICE);
529 
530     Predictor predictor;
531 
532     NonBufferHash hashOne = getNonBufferHash({&layerStateOne});
533     NonBufferHash hashTwo = getNonBufferHash({&layerStateTwo});
534 
535     predictor.recordResult(std::nullopt, hashOne, {&layerStateOne}, false, plan);
536 
537     auto predictedPlan = predictor.getPredictedPlan({&layerStateTwo}, hashTwo);
538     ASSERT_TRUE(predictedPlan);
539     EXPECT_EQ(Prediction::Type::Approximate, predictedPlan->type);
540 
541     Plan planTwo;
542     planTwo.addLayerType(Composition::CLIENT);
543     predictor.recordResult(predictedPlan, hashTwo, {&layerStateTwo}, false, planTwo);
544     // Now trying to retrieve the predicted plan again returns a nullopt instead.
545     // TODO(b/158790260): Even though this is enforced in this test, we might want to reassess this.
546     // One of the implications around this implementation is that if we miss a prediction then we
547     // can never actually correct our mistake if we see the same layer stack again, which doesn't
548     // seem robust.
549     auto predictedPlanTwo = predictor.getPredictedPlan({&layerStateTwo}, hashTwo);
550     EXPECT_FALSE(predictedPlanTwo);
551 }
552 
553 } // namespace
554 } // namespace android::compositionengine::impl::planner
555