blob: 74b3adaa95cb31c80c1ce5722a41538532a45d59 [file] [log] [blame]
Lloyd Pique45a165a2018-10-19 11:54:47 -07001/*
2 * Copyright 2019 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
Lloyd Pique45a165a2018-10-19 11:54:47 -070017#include <cmath>
18
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070019#include <compositionengine/DisplayColorProfileCreationArgs.h>
Lloyd Pique45a165a2018-10-19 11:54:47 -070020#include <compositionengine/DisplayCreationArgs.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070021#include <compositionengine/DisplaySurface.h>
22#include <compositionengine/RenderSurfaceCreationArgs.h>
Lloyd Pique45a165a2018-10-19 11:54:47 -070023#include <compositionengine/impl/Display.h>
24#include <compositionengine/mock/CompositionEngine.h>
Lloyd Piquef5275482019-01-29 18:42:42 -080025#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquedf336d92019-03-07 21:38:42 -080026#include <compositionengine/mock/Layer.h>
27#include <compositionengine/mock/LayerFE.h>
chaviw8beb4142019-04-11 13:09:05 -070028#include <compositionengine/mock/NativeWindow.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080029#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070030#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070031#include <gtest/gtest.h>
Lloyd Pique45a165a2018-10-19 11:54:47 -070032
Lloyd Pique66d68602019-02-13 14:23:31 -080033#include "MockHWC2.h"
Lloyd Pique45a165a2018-10-19 11:54:47 -070034#include "MockHWComposer.h"
Lloyd Pique688abd42019-02-15 15:42:24 -080035#include "MockPowerAdvisor.h"
Lloyd Pique45a165a2018-10-19 11:54:47 -070036
37namespace android::compositionengine {
38namespace {
39
Lloyd Piquef5275482019-01-29 18:42:42 -080040using testing::_;
Lloyd Pique66d68602019-02-13 14:23:31 -080041using testing::DoAll;
Lloyd Pique31cb2942018-10-19 17:23:03 -070042using testing::Return;
Lloyd Pique45a165a2018-10-19 11:54:47 -070043using testing::ReturnRef;
Lloyd Pique66d68602019-02-13 14:23:31 -080044using testing::Sequence;
45using testing::SetArgPointee;
Lloyd Pique45a165a2018-10-19 11:54:47 -070046using testing::StrictMock;
47
48constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
49
Lloyd Pique66d68602019-02-13 14:23:31 -080050struct DisplayTest : public testing::Test {
51 DisplayTest() {
52 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
53 EXPECT_CALL(*mLayer1, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer1));
54 EXPECT_CALL(*mLayer2, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer2));
55 EXPECT_CALL(*mLayer3, getHwcLayer()).WillRepeatedly(Return(nullptr));
56
57 std::vector<std::unique_ptr<OutputLayer>> layers;
58 layers.emplace_back(mLayer1);
59 layers.emplace_back(mLayer2);
60 layers.emplace_back(mLayer3);
61 mDisplay.setOutputLayersOrderedByZ(std::move(layers));
62 }
Lloyd Pique45a165a2018-10-19 11:54:47 -070063
64 StrictMock<android::mock::HWComposer> mHwComposer;
Lloyd Pique688abd42019-02-15 15:42:24 -080065 StrictMock<Hwc2::mock::PowerAdvisor> mPowerAdvisor;
Lloyd Pique45a165a2018-10-19 11:54:47 -070066 StrictMock<mock::CompositionEngine> mCompositionEngine;
chaviw8beb4142019-04-11 13:09:05 -070067 sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
Lloyd Pique66d68602019-02-13 14:23:31 -080068 StrictMock<HWC2::mock::Layer> mHWC2Layer1;
69 StrictMock<HWC2::mock::Layer> mHWC2Layer2;
70 StrictMock<HWC2::mock::Layer> mHWC2LayerUnknown;
71 mock::OutputLayer* mLayer1 = new StrictMock<mock::OutputLayer>();
72 mock::OutputLayer* mLayer2 = new StrictMock<mock::OutputLayer>();
73 mock::OutputLayer* mLayer3 = new StrictMock<mock::OutputLayer>();
Lloyd Pique45a165a2018-10-19 11:54:47 -070074 impl::Display mDisplay{mCompositionEngine,
Lloyd Pique688abd42019-02-15 15:42:24 -080075 DisplayCreationArgsBuilder()
76 .setDisplayId(DEFAULT_DISPLAY_ID)
77 .setPowerAdvisor(&mPowerAdvisor)
78 .build()};
Lloyd Pique45a165a2018-10-19 11:54:47 -070079};
80
Lloyd Pique66d68602019-02-13 14:23:31 -080081/*
Lloyd Pique45a165a2018-10-19 11:54:47 -070082 * Basic construction
83 */
84
85TEST_F(DisplayTest, canInstantiateDisplay) {
86 {
87 constexpr DisplayId display1 = DisplayId{123u};
88 auto display =
89 impl::createDisplay(mCompositionEngine,
90 DisplayCreationArgsBuilder().setDisplayId(display1).build());
91 EXPECT_FALSE(display->isSecure());
92 EXPECT_FALSE(display->isVirtual());
93 EXPECT_EQ(display1, display->getId());
94 }
95
96 {
97 constexpr DisplayId display2 = DisplayId{546u};
98 auto display = impl::createDisplay(mCompositionEngine,
99 DisplayCreationArgsBuilder()
100 .setIsSecure(true)
101 .setDisplayId(display2)
102 .build());
103 EXPECT_TRUE(display->isSecure());
104 EXPECT_FALSE(display->isVirtual());
105 EXPECT_EQ(display2, display->getId());
106 }
107
108 {
109 constexpr DisplayId display3 = DisplayId{789u};
110 auto display = impl::createDisplay(mCompositionEngine,
111 DisplayCreationArgsBuilder()
112 .setIsVirtual(true)
113 .setDisplayId(display3)
114 .build());
115 EXPECT_FALSE(display->isSecure());
116 EXPECT_TRUE(display->isVirtual());
117 EXPECT_EQ(display3, display->getId());
118 }
119}
120
Lloyd Pique66d68602019-02-13 14:23:31 -0800121/*
Lloyd Pique45a165a2018-10-19 11:54:47 -0700122 * Display::disconnect()
123 */
124
125TEST_F(DisplayTest, disconnectDisconnectsDisplay) {
Lloyd Pique45a165a2018-10-19 11:54:47 -0700126 // The first call to disconnect will disconnect the display with the HWC and
127 // set mHwcId to -1.
128 EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
129 mDisplay.disconnect();
130 EXPECT_FALSE(mDisplay.getId());
131
132 // Subsequent calls will do nothing,
133 EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
134 mDisplay.disconnect();
135 EXPECT_FALSE(mDisplay.getId());
136}
137
Lloyd Pique66d68602019-02-13 14:23:31 -0800138/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700139 * Display::setColorTransform()
140 */
141
142TEST_F(DisplayTest, setColorTransformSetsTransform) {
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800143 // No change does nothing
144 CompositionRefreshArgs refreshArgs;
145 refreshArgs.colorTransformMatrix = std::nullopt;
146 mDisplay.setColorTransform(refreshArgs);
147
Lloyd Pique32cbe282018-10-19 13:09:22 -0700148 // Identity matrix sets an identity state value
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800149 const mat4 kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700150
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800151 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kIdentity)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800153 refreshArgs.colorTransformMatrix = kIdentity;
154 mDisplay.setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700155
156 // Non-identity matrix sets a non-identity state value
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800157 const mat4 kNonIdentity = mat4() * 2;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700158
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800159 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kNonIdentity)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700160
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800161 refreshArgs.colorTransformMatrix = kNonIdentity;
162 mDisplay.setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700163}
164
Lloyd Pique66d68602019-02-13 14:23:31 -0800165/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700166 * Display::setColorMode()
167 */
168
169TEST_F(DisplayTest, setColorModeSetsModeUnlessNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800170 using ColorProfile = Output::ColorProfile;
171
Lloyd Pique31cb2942018-10-19 17:23:03 -0700172 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
173 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Piquef5275482019-01-29 18:42:42 -0800174 mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
175 mDisplay.setDisplayColorProfileForTest(std::unique_ptr<DisplayColorProfile>(colorProfile));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700176
Lloyd Piquef5275482019-01-29 18:42:42 -0800177 EXPECT_CALL(*colorProfile, getTargetDataspace(_, _, _))
178 .WillRepeatedly(Return(ui::Dataspace::UNKNOWN));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700179
180 // These values are expected to be the initial state.
181 ASSERT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
182 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
183 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800184 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700185
Lloyd Piquef5275482019-01-29 18:42:42 -0800186 // If the set values are unchanged, nothing happens
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800187 mDisplay.setColorProfile(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
188 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700189
190 EXPECT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
191 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
192 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800193 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700194
195 // Otherwise if the values are different, updates happen
Lloyd Piqueef958122019-02-05 18:00:12 -0800196 EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700197 EXPECT_CALL(mHwComposer,
Lloyd Piqueef958122019-02-05 18:00:12 -0800198 setActiveColorMode(DEFAULT_DISPLAY_ID, ui::ColorMode::DISPLAY_P3,
Lloyd Pique32cbe282018-10-19 13:09:22 -0700199 ui::RenderIntent::TONE_MAP_COLORIMETRIC))
200 .Times(1);
201
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800202 mDisplay.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
203 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
204 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700205
Lloyd Piqueef958122019-02-05 18:00:12 -0800206 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay.getState().colorMode);
207 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay.getState().dataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800209 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210}
211
212TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800213 using ColorProfile = Output::ColorProfile;
214
Lloyd Pique32cbe282018-10-19 13:09:22 -0700215 impl::Display virtualDisplay{mCompositionEngine,
216 DisplayCreationArgs{false, true, DEFAULT_DISPLAY_ID}};
217
Lloyd Piquef5275482019-01-29 18:42:42 -0800218 mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
219 virtualDisplay.setDisplayColorProfileForTest(
220 std::unique_ptr<DisplayColorProfile>(colorProfile));
221
222 EXPECT_CALL(*colorProfile,
223 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
224 ui::Dataspace::UNKNOWN))
225 .WillOnce(Return(ui::Dataspace::UNKNOWN));
226
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800227 virtualDisplay.setColorProfile(
228 ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
229 ui::RenderIntent::TONE_MAP_COLORIMETRIC, ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
231 EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay.getState().colorMode);
232 EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay.getState().dataspace);
233 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, virtualDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800234 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235}
236
Lloyd Pique66d68602019-02-13 14:23:31 -0800237/*
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700238 * Display::createDisplayColorProfile()
239 */
240
241TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) {
242 EXPECT_TRUE(mDisplay.getDisplayColorProfile() == nullptr);
243 mDisplay.createDisplayColorProfile(
244 DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0,
245 DisplayColorProfileCreationArgs::HwcColorModes()});
246 EXPECT_TRUE(mDisplay.getDisplayColorProfile() != nullptr);
247}
248
Lloyd Pique66d68602019-02-13 14:23:31 -0800249/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700250 * Display::createRenderSurface()
251 */
252
253TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) {
chaviw8beb4142019-04-11 13:09:05 -0700254 EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700255 EXPECT_TRUE(mDisplay.getRenderSurface() == nullptr);
chaviw8beb4142019-04-11 13:09:05 -0700256 mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
Lloyd Pique31cb2942018-10-19 17:23:03 -0700257 EXPECT_TRUE(mDisplay.getRenderSurface() != nullptr);
258}
259
Lloyd Pique66d68602019-02-13 14:23:31 -0800260/*
Lloyd Piquedf336d92019-03-07 21:38:42 -0800261 * Display::createOutputLayer()
262 */
263
264TEST_F(DisplayTest, createOutputLayerSetsHwcLayer) {
265 sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
266 auto layer = std::make_shared<StrictMock<mock::Layer>>();
267 StrictMock<HWC2::mock::Layer> hwcLayer;
268
269 EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
270
271 auto outputLayer = mDisplay.createOutputLayer(layer, layerFE);
272
273 EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
274
275 EXPECT_CALL(mHwComposer, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
276 outputLayer.reset();
277}
278
279/*
Lloyd Piquec29e4c62019-03-07 21:48:19 -0800280 * Display::setReleasedLayers()
281 */
282
283TEST_F(DisplayTest, setReleasedLayersDoesNothingIfNotHwcDisplay) {
284 std::shared_ptr<impl::Display> nonHwcDisplay{
285 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
286
287 sp<mock::LayerFE> layerXLayerFE = new StrictMock<mock::LayerFE>();
288 mock::Layer layerXLayer;
289
290 {
291 Output::ReleasedLayers releasedLayers;
292 releasedLayers.emplace_back(layerXLayerFE);
293 nonHwcDisplay->setReleasedLayers(std::move(releasedLayers));
294 }
295
296 CompositionRefreshArgs refreshArgs;
297 refreshArgs.layersWithQueuedFrames.push_back(&layerXLayer);
298
299 nonHwcDisplay->setReleasedLayers(refreshArgs);
300
301 const auto& releasedLayers = nonHwcDisplay->getReleasedLayersForTest();
302 ASSERT_EQ(1, releasedLayers.size());
303}
304
305TEST_F(DisplayTest, setReleasedLayersDoesNothingIfNoLayersWithQueuedFrames) {
306 sp<mock::LayerFE> layerXLayerFE = new StrictMock<mock::LayerFE>();
307
308 {
309 Output::ReleasedLayers releasedLayers;
310 releasedLayers.emplace_back(layerXLayerFE);
311 mDisplay.setReleasedLayers(std::move(releasedLayers));
312 }
313
314 CompositionRefreshArgs refreshArgs;
315 mDisplay.setReleasedLayers(refreshArgs);
316
317 const auto& releasedLayers = mDisplay.getReleasedLayersForTest();
318 ASSERT_EQ(1, releasedLayers.size());
319}
320
321TEST_F(DisplayTest, setReleasedLayers) {
322 sp<mock::LayerFE> layer1LayerFE = new StrictMock<mock::LayerFE>();
323 sp<mock::LayerFE> layer2LayerFE = new StrictMock<mock::LayerFE>();
324 sp<mock::LayerFE> layer3LayerFE = new StrictMock<mock::LayerFE>();
325 sp<mock::LayerFE> layerXLayerFE = new StrictMock<mock::LayerFE>();
326 mock::Layer layer1Layer;
327 mock::Layer layer2Layer;
328 mock::Layer layer3Layer;
329 mock::Layer layerXLayer;
330
331 EXPECT_CALL(*mLayer1, getLayer()).WillRepeatedly(ReturnRef(layer1Layer));
332 EXPECT_CALL(*mLayer1, getLayerFE()).WillRepeatedly(ReturnRef(*layer1LayerFE.get()));
333 EXPECT_CALL(*mLayer2, getLayer()).WillRepeatedly(ReturnRef(layer2Layer));
334 EXPECT_CALL(*mLayer2, getLayerFE()).WillRepeatedly(ReturnRef(*layer2LayerFE.get()));
335 EXPECT_CALL(*mLayer3, getLayer()).WillRepeatedly(ReturnRef(layer3Layer));
336 EXPECT_CALL(*mLayer3, getLayerFE()).WillRepeatedly(ReturnRef(*layer3LayerFE.get()));
337
338 CompositionRefreshArgs refreshArgs;
339 refreshArgs.layersWithQueuedFrames.push_back(&layer1Layer);
340 refreshArgs.layersWithQueuedFrames.push_back(&layer2Layer);
341 refreshArgs.layersWithQueuedFrames.push_back(&layerXLayer);
342 refreshArgs.layersWithQueuedFrames.push_back(nullptr);
343
344 mDisplay.setReleasedLayers(refreshArgs);
345
346 const auto& releasedLayers = mDisplay.getReleasedLayersForTest();
347 ASSERT_EQ(2, releasedLayers.size());
348 ASSERT_EQ(layer1LayerFE.get(), releasedLayers[0].promote().get());
349 ASSERT_EQ(layer2LayerFE.get(), releasedLayers[1].promote().get());
350}
351
352/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800353 * Display::chooseCompositionStrategy()
354 */
355
356struct DisplayChooseCompositionStrategyTest : public testing::Test {
357 struct DisplayPartialMock : public impl::Display {
358 DisplayPartialMock(const compositionengine::CompositionEngine& compositionEngine,
359 compositionengine::DisplayCreationArgs&& args)
360 : impl::Display(compositionEngine, std::move(args)) {}
361
362 // Sets up the helper functions called by chooseCompositionStrategy to
363 // use a mock implementations.
364 MOCK_CONST_METHOD0(anyLayersRequireClientComposition, bool());
365 MOCK_CONST_METHOD0(allLayersRequireClientComposition, bool());
366 MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&));
367 MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&));
368 MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&));
369 };
370
371 DisplayChooseCompositionStrategyTest() {
372 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
373 }
374
375 StrictMock<android::mock::HWComposer> mHwComposer;
376 StrictMock<mock::CompositionEngine> mCompositionEngine;
377 StrictMock<DisplayPartialMock>
378 mDisplay{mCompositionEngine,
379 DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()};
380};
381
382TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) {
383 impl::Display nonHwcDisplay{mCompositionEngine, DisplayCreationArgsBuilder().build()};
384 EXPECT_FALSE(nonHwcDisplay.getId());
385
386 nonHwcDisplay.chooseCompositionStrategy();
387
388 auto& state = nonHwcDisplay.getState();
389 EXPECT_TRUE(state.usesClientComposition);
390 EXPECT_FALSE(state.usesDeviceComposition);
391}
392
393TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
394 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
395 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
396 .WillOnce(Return(INVALID_OPERATION));
397
398 mDisplay.chooseCompositionStrategy();
399
400 auto& state = mDisplay.getState();
401 EXPECT_TRUE(state.usesClientComposition);
402 EXPECT_FALSE(state.usesDeviceComposition);
403}
404
405TEST_F(DisplayChooseCompositionStrategyTest, normalOperation) {
406 // Since two calls are made to anyLayersRequireClientComposition with different return values,
407 // use a Sequence to control the matching so the values are returned in a known order.
408 Sequence s;
409 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
410 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
411 .InSequence(s)
412 .WillOnce(Return(false));
413
414 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
415 .WillOnce(Return(NO_ERROR));
416 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
417
418 mDisplay.chooseCompositionStrategy();
419
420 auto& state = mDisplay.getState();
421 EXPECT_FALSE(state.usesClientComposition);
422 EXPECT_TRUE(state.usesDeviceComposition);
423}
424
425TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) {
426 android::HWComposer::DeviceRequestedChanges changes{
427 {{nullptr, HWC2::Composition::Client}},
428 HWC2::DisplayRequest::FlipClientTarget,
429 {{nullptr, HWC2::LayerRequest::ClearClientTarget}},
430 };
431
432 // Since two calls are made to anyLayersRequireClientComposition with different return values,
433 // use a Sequence to control the matching so the values are returned in a known order.
434 Sequence s;
435 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
436 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
437 .InSequence(s)
438 .WillOnce(Return(false));
439
440 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
441 .WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
442 EXPECT_CALL(mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
443 EXPECT_CALL(mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
444 EXPECT_CALL(mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1);
445 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
446
447 mDisplay.chooseCompositionStrategy();
448
449 auto& state = mDisplay.getState();
450 EXPECT_FALSE(state.usesClientComposition);
451 EXPECT_TRUE(state.usesDeviceComposition);
452}
453
454/*
Lloyd Pique688abd42019-02-15 15:42:24 -0800455 * Display::getSkipColorTransform()
456 */
457
458TEST_F(DisplayTest, getSkipColorTransformDoesNothingIfNonHwcDisplay) {
459 auto nonHwcDisplay{
460 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
461 EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform());
462}
463
464TEST_F(DisplayTest, getSkipColorTransformChecksHwcCapability) {
465 EXPECT_CALL(mHwComposer,
466 hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
467 HWC2::DisplayCapability::SkipClientColorTransform))
468 .WillOnce(Return(true));
469 EXPECT_TRUE(mDisplay.getSkipColorTransform());
470}
471
472/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800473 * Display::anyLayersRequireClientComposition()
474 */
475
476TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) {
477 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
478 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
479 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(false));
480
481 EXPECT_FALSE(mDisplay.anyLayersRequireClientComposition());
482}
483
484TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) {
485 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
486 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
487
488 EXPECT_TRUE(mDisplay.anyLayersRequireClientComposition());
489}
490
491/*
492 * Display::allLayersRequireClientComposition()
493 */
494
495TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) {
496 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
497 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
498 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(true));
499
500 EXPECT_TRUE(mDisplay.allLayersRequireClientComposition());
501}
502
503TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) {
504 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
505 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
506
507 EXPECT_FALSE(mDisplay.allLayersRequireClientComposition());
508}
509
510/*
511 * Display::applyChangedTypesToLayers()
512 */
513
514TEST_F(DisplayTest, applyChangedTypesToLayersTakesEarlyOutIfNoChangedLayers) {
515 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes());
516}
517
518TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) {
519 EXPECT_CALL(*mLayer1,
520 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT))
521 .Times(1);
522 EXPECT_CALL(*mLayer2,
523 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::DEVICE))
524 .Times(1);
525
526 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes{
527 {&mHWC2Layer1, HWC2::Composition::Client},
528 {&mHWC2Layer2, HWC2::Composition::Device},
529 {&mHWC2LayerUnknown, HWC2::Composition::SolidColor},
530 });
531}
532
533/*
534 * Display::applyDisplayRequests()
535 */
536
537TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesNoRequests) {
538 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
539
540 auto& state = mDisplay.getState();
541 EXPECT_FALSE(state.flipClientTarget);
542}
543
544TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesFlipClientTarget) {
545 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
546
547 auto& state = mDisplay.getState();
548 EXPECT_TRUE(state.flipClientTarget);
549}
550
551TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesWriteClientTargetToOutput) {
552 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
553
554 auto& state = mDisplay.getState();
555 EXPECT_FALSE(state.flipClientTarget);
556}
557
558TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) {
559 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
560
561 auto& state = mDisplay.getState();
562 EXPECT_TRUE(state.flipClientTarget);
563}
564
565/*
566 * Display::applyLayerRequestsToLayers()
567 */
568
569TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) {
570 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
571 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
572 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
573
574 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests());
575}
576
577TEST_F(DisplayTest, applyLayerRequestsToLayers2) {
578 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
579 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
580 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
581
582 EXPECT_CALL(*mLayer1,
583 applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET))
584 .Times(1);
585
586 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests{
587 {&mHWC2Layer1, HWC2::LayerRequest::ClearClientTarget},
588 {&mHWC2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
589 });
590}
591
Lloyd Pique35fca9d2019-02-13 14:24:11 -0800592/*
593 * Display::presentAndGetFrameFences()
594 */
595
596TEST_F(DisplayTest, presentAndGetFrameFencesReturnsNoFencesOnNonHwcDisplay) {
597 auto nonHwcDisplay{
598 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
599
600 auto result = nonHwcDisplay->presentAndGetFrameFences();
601
602 ASSERT_TRUE(result.presentFence.get());
603 EXPECT_FALSE(result.presentFence->isValid());
604 EXPECT_EQ(0u, result.layerFences.size());
605}
606
607TEST_F(DisplayTest, presentAndGetFrameFencesReturnsPresentAndLayerFences) {
608 sp<Fence> presentFence = new Fence();
609 sp<Fence> layer1Fence = new Fence();
610 sp<Fence> layer2Fence = new Fence();
611
612 EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
613 EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
614 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer1))
615 .WillOnce(Return(layer1Fence));
616 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer2))
617 .WillOnce(Return(layer2Fence));
618 EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
619
620 auto result = mDisplay.presentAndGetFrameFences();
621
622 EXPECT_EQ(presentFence, result.presentFence);
623
624 EXPECT_EQ(2u, result.layerFences.size());
625 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer1));
626 EXPECT_EQ(layer1Fence, result.layerFences[&mHWC2Layer1]);
627 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer2));
628 EXPECT_EQ(layer2Fence, result.layerFences[&mHWC2Layer2]);
629}
630
Lloyd Pique688abd42019-02-15 15:42:24 -0800631/*
632 * Display::setExpensiveRenderingExpected()
633 */
634
635TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) {
636 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, true)).Times(1);
637 mDisplay.setExpensiveRenderingExpected(true);
638
639 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, false)).Times(1);
640 mDisplay.setExpensiveRenderingExpected(false);
641}
642
Lloyd Piqued3d69882019-02-28 16:03:46 -0800643/*
644 * Display::finishFrame()
645 */
646
647TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) {
648 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
649 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
650
651 // We expect no calls to queueBuffer if composition was skipped.
652 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
653
654 mDisplay.editState().isEnabled = true;
655 mDisplay.editState().usesClientComposition = false;
656 mDisplay.editState().viewport = Rect(0, 0, 1, 1);
657 mDisplay.editState().dirtyRegion = Region::INVALID_REGION;
658
659 CompositionRefreshArgs refreshArgs;
660 refreshArgs.repaintEverything = false;
661
662 mDisplay.finishFrame(refreshArgs);
663}
664
665TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) {
666 std::shared_ptr<impl::Display> nonHwcDisplay{
667 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
668
669 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
670 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
671
672 // We expect no calls to queueBuffer if composition was skipped.
673 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0);
674
675 nonHwcDisplay->editState().isEnabled = true;
676 nonHwcDisplay->editState().usesClientComposition = false;
677 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
678 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
679
680 CompositionRefreshArgs refreshArgs;
681 refreshArgs.repaintEverything = false;
682
683 nonHwcDisplay->finishFrame(refreshArgs);
684}
685
686TEST_F(DisplayTest, finishFramePerformsCompositionIfDirty) {
687 std::shared_ptr<impl::Display> nonHwcDisplay{
688 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
689
690 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
691 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
692
693 // We expect a single call to queueBuffer when composition is not skipped.
694 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
695
696 nonHwcDisplay->editState().isEnabled = true;
697 nonHwcDisplay->editState().usesClientComposition = false;
698 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
699 nonHwcDisplay->editState().dirtyRegion = Region(Rect(0, 0, 1, 1));
700
701 CompositionRefreshArgs refreshArgs;
702 refreshArgs.repaintEverything = false;
703
704 nonHwcDisplay->finishFrame(refreshArgs);
705}
706
707TEST_F(DisplayTest, finishFramePerformsCompositionIfRepaintEverything) {
708 std::shared_ptr<impl::Display> nonHwcDisplay{
709 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
710
711 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
712 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
713
714 // We expect a single call to queueBuffer when composition is not skipped.
715 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
716
717 nonHwcDisplay->editState().isEnabled = true;
718 nonHwcDisplay->editState().usesClientComposition = false;
719 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
720 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
721
722 CompositionRefreshArgs refreshArgs;
723 refreshArgs.repaintEverything = true;
724
725 nonHwcDisplay->finishFrame(refreshArgs);
726}
727
Lloyd Pique45a165a2018-10-19 11:54:47 -0700728} // namespace
729} // namespace android::compositionengine