blob: 06e3a7066541aa019fb3b1bf42d5eeb921f830a5 [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>
chaviw8beb4142019-04-11 13:09:05 -070026#include <compositionengine/mock/NativeWindow.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080027#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070028#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <gtest/gtest.h>
Lloyd Pique45a165a2018-10-19 11:54:47 -070030
Lloyd Pique66d68602019-02-13 14:23:31 -080031#include "MockHWC2.h"
Lloyd Pique45a165a2018-10-19 11:54:47 -070032#include "MockHWComposer.h"
Lloyd Pique688abd42019-02-15 15:42:24 -080033#include "MockPowerAdvisor.h"
Lloyd Pique45a165a2018-10-19 11:54:47 -070034
35namespace android::compositionengine {
36namespace {
37
Lloyd Piquef5275482019-01-29 18:42:42 -080038using testing::_;
Lloyd Pique66d68602019-02-13 14:23:31 -080039using testing::DoAll;
Lloyd Pique31cb2942018-10-19 17:23:03 -070040using testing::Return;
Lloyd Pique45a165a2018-10-19 11:54:47 -070041using testing::ReturnRef;
Lloyd Pique66d68602019-02-13 14:23:31 -080042using testing::Sequence;
43using testing::SetArgPointee;
Lloyd Pique45a165a2018-10-19 11:54:47 -070044using testing::StrictMock;
45
46constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
47
Lloyd Pique66d68602019-02-13 14:23:31 -080048struct DisplayTest : public testing::Test {
49 DisplayTest() {
50 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
51 EXPECT_CALL(*mLayer1, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer1));
52 EXPECT_CALL(*mLayer2, getHwcLayer()).WillRepeatedly(Return(&mHWC2Layer2));
53 EXPECT_CALL(*mLayer3, getHwcLayer()).WillRepeatedly(Return(nullptr));
54
55 std::vector<std::unique_ptr<OutputLayer>> layers;
56 layers.emplace_back(mLayer1);
57 layers.emplace_back(mLayer2);
58 layers.emplace_back(mLayer3);
59 mDisplay.setOutputLayersOrderedByZ(std::move(layers));
60 }
Lloyd Pique45a165a2018-10-19 11:54:47 -070061
62 StrictMock<android::mock::HWComposer> mHwComposer;
Lloyd Pique688abd42019-02-15 15:42:24 -080063 StrictMock<Hwc2::mock::PowerAdvisor> mPowerAdvisor;
Lloyd Pique45a165a2018-10-19 11:54:47 -070064 StrictMock<mock::CompositionEngine> mCompositionEngine;
chaviw8beb4142019-04-11 13:09:05 -070065 sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
Lloyd Pique66d68602019-02-13 14:23:31 -080066 StrictMock<HWC2::mock::Layer> mHWC2Layer1;
67 StrictMock<HWC2::mock::Layer> mHWC2Layer2;
68 StrictMock<HWC2::mock::Layer> mHWC2LayerUnknown;
69 mock::OutputLayer* mLayer1 = new StrictMock<mock::OutputLayer>();
70 mock::OutputLayer* mLayer2 = new StrictMock<mock::OutputLayer>();
71 mock::OutputLayer* mLayer3 = new StrictMock<mock::OutputLayer>();
Lloyd Pique45a165a2018-10-19 11:54:47 -070072 impl::Display mDisplay{mCompositionEngine,
Lloyd Pique688abd42019-02-15 15:42:24 -080073 DisplayCreationArgsBuilder()
74 .setDisplayId(DEFAULT_DISPLAY_ID)
75 .setPowerAdvisor(&mPowerAdvisor)
76 .build()};
Lloyd Pique45a165a2018-10-19 11:54:47 -070077};
78
Lloyd Pique66d68602019-02-13 14:23:31 -080079/*
Lloyd Pique45a165a2018-10-19 11:54:47 -070080 * Basic construction
81 */
82
83TEST_F(DisplayTest, canInstantiateDisplay) {
84 {
85 constexpr DisplayId display1 = DisplayId{123u};
86 auto display =
87 impl::createDisplay(mCompositionEngine,
88 DisplayCreationArgsBuilder().setDisplayId(display1).build());
89 EXPECT_FALSE(display->isSecure());
90 EXPECT_FALSE(display->isVirtual());
91 EXPECT_EQ(display1, display->getId());
92 }
93
94 {
95 constexpr DisplayId display2 = DisplayId{546u};
96 auto display = impl::createDisplay(mCompositionEngine,
97 DisplayCreationArgsBuilder()
98 .setIsSecure(true)
99 .setDisplayId(display2)
100 .build());
101 EXPECT_TRUE(display->isSecure());
102 EXPECT_FALSE(display->isVirtual());
103 EXPECT_EQ(display2, display->getId());
104 }
105
106 {
107 constexpr DisplayId display3 = DisplayId{789u};
108 auto display = impl::createDisplay(mCompositionEngine,
109 DisplayCreationArgsBuilder()
110 .setIsVirtual(true)
111 .setDisplayId(display3)
112 .build());
113 EXPECT_FALSE(display->isSecure());
114 EXPECT_TRUE(display->isVirtual());
115 EXPECT_EQ(display3, display->getId());
116 }
117}
118
Lloyd Pique66d68602019-02-13 14:23:31 -0800119/*
Lloyd Pique45a165a2018-10-19 11:54:47 -0700120 * Display::disconnect()
121 */
122
123TEST_F(DisplayTest, disconnectDisconnectsDisplay) {
Lloyd Pique45a165a2018-10-19 11:54:47 -0700124 // The first call to disconnect will disconnect the display with the HWC and
125 // set mHwcId to -1.
126 EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
127 mDisplay.disconnect();
128 EXPECT_FALSE(mDisplay.getId());
129
130 // Subsequent calls will do nothing,
131 EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
132 mDisplay.disconnect();
133 EXPECT_FALSE(mDisplay.getId());
134}
135
Lloyd Pique66d68602019-02-13 14:23:31 -0800136/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700137 * Display::setColorTransform()
138 */
139
140TEST_F(DisplayTest, setColorTransformSetsTransform) {
141 // Identity matrix sets an identity state value
142 const mat4 identity;
143
Lloyd Pique32cbe282018-10-19 13:09:22 -0700144 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, identity)).Times(1);
145
146 mDisplay.setColorTransform(identity);
147
148 EXPECT_EQ(HAL_COLOR_TRANSFORM_IDENTITY, mDisplay.getState().colorTransform);
149
150 // Non-identity matrix sets a non-identity state value
151 const mat4 nonIdentity = mat4() * 2;
152
153 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, nonIdentity)).Times(1);
154
155 mDisplay.setColorTransform(nonIdentity);
156
157 EXPECT_EQ(HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX, mDisplay.getState().colorTransform);
158}
159
Lloyd Pique66d68602019-02-13 14:23:31 -0800160/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161 * Display::setColorMode()
162 */
163
164TEST_F(DisplayTest, setColorModeSetsModeUnlessNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800165 using ColorProfile = Output::ColorProfile;
166
Lloyd Pique31cb2942018-10-19 17:23:03 -0700167 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
168 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Piquef5275482019-01-29 18:42:42 -0800169 mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
170 mDisplay.setDisplayColorProfileForTest(std::unique_ptr<DisplayColorProfile>(colorProfile));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700171
Lloyd Piquef5275482019-01-29 18:42:42 -0800172 EXPECT_CALL(*colorProfile, getTargetDataspace(_, _, _))
173 .WillRepeatedly(Return(ui::Dataspace::UNKNOWN));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700174
175 // These values are expected to be the initial state.
176 ASSERT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
177 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
178 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800179 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700180
Lloyd Piquef5275482019-01-29 18:42:42 -0800181 // If the set values are unchanged, nothing happens
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800182 mDisplay.setColorProfile(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
183 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700184
185 EXPECT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
186 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
187 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800188 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700189
190 // Otherwise if the values are different, updates happen
Lloyd Piqueef958122019-02-05 18:00:12 -0800191 EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700192 EXPECT_CALL(mHwComposer,
Lloyd Piqueef958122019-02-05 18:00:12 -0800193 setActiveColorMode(DEFAULT_DISPLAY_ID, ui::ColorMode::DISPLAY_P3,
Lloyd Pique32cbe282018-10-19 13:09:22 -0700194 ui::RenderIntent::TONE_MAP_COLORIMETRIC))
195 .Times(1);
196
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800197 mDisplay.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
198 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
199 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700200
Lloyd Piqueef958122019-02-05 18:00:12 -0800201 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay.getState().colorMode);
202 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay.getState().dataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700203 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800204 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700205}
206
207TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800208 using ColorProfile = Output::ColorProfile;
209
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210 impl::Display virtualDisplay{mCompositionEngine,
211 DisplayCreationArgs{false, true, DEFAULT_DISPLAY_ID}};
212
Lloyd Piquef5275482019-01-29 18:42:42 -0800213 mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
214 virtualDisplay.setDisplayColorProfileForTest(
215 std::unique_ptr<DisplayColorProfile>(colorProfile));
216
217 EXPECT_CALL(*colorProfile,
218 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
219 ui::Dataspace::UNKNOWN))
220 .WillOnce(Return(ui::Dataspace::UNKNOWN));
221
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800222 virtualDisplay.setColorProfile(
223 ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
224 ui::RenderIntent::TONE_MAP_COLORIMETRIC, ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
226 EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay.getState().colorMode);
227 EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay.getState().dataspace);
228 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, virtualDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800229 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230}
231
Lloyd Pique66d68602019-02-13 14:23:31 -0800232/*
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700233 * Display::createDisplayColorProfile()
234 */
235
236TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) {
237 EXPECT_TRUE(mDisplay.getDisplayColorProfile() == nullptr);
238 mDisplay.createDisplayColorProfile(
239 DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0,
240 DisplayColorProfileCreationArgs::HwcColorModes()});
241 EXPECT_TRUE(mDisplay.getDisplayColorProfile() != nullptr);
242}
243
Lloyd Pique66d68602019-02-13 14:23:31 -0800244/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700245 * Display::createRenderSurface()
246 */
247
248TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) {
chaviw8beb4142019-04-11 13:09:05 -0700249 EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700250 EXPECT_TRUE(mDisplay.getRenderSurface() == nullptr);
chaviw8beb4142019-04-11 13:09:05 -0700251 mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
Lloyd Pique31cb2942018-10-19 17:23:03 -0700252 EXPECT_TRUE(mDisplay.getRenderSurface() != nullptr);
253}
254
Lloyd Pique66d68602019-02-13 14:23:31 -0800255/*
256 * Display::chooseCompositionStrategy()
257 */
258
259struct DisplayChooseCompositionStrategyTest : public testing::Test {
260 struct DisplayPartialMock : public impl::Display {
261 DisplayPartialMock(const compositionengine::CompositionEngine& compositionEngine,
262 compositionengine::DisplayCreationArgs&& args)
263 : impl::Display(compositionEngine, std::move(args)) {}
264
265 // Sets up the helper functions called by chooseCompositionStrategy to
266 // use a mock implementations.
267 MOCK_CONST_METHOD0(anyLayersRequireClientComposition, bool());
268 MOCK_CONST_METHOD0(allLayersRequireClientComposition, bool());
269 MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&));
270 MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&));
271 MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&));
272 };
273
274 DisplayChooseCompositionStrategyTest() {
275 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
276 }
277
278 StrictMock<android::mock::HWComposer> mHwComposer;
279 StrictMock<mock::CompositionEngine> mCompositionEngine;
280 StrictMock<DisplayPartialMock>
281 mDisplay{mCompositionEngine,
282 DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()};
283};
284
285TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) {
286 impl::Display nonHwcDisplay{mCompositionEngine, DisplayCreationArgsBuilder().build()};
287 EXPECT_FALSE(nonHwcDisplay.getId());
288
289 nonHwcDisplay.chooseCompositionStrategy();
290
291 auto& state = nonHwcDisplay.getState();
292 EXPECT_TRUE(state.usesClientComposition);
293 EXPECT_FALSE(state.usesDeviceComposition);
294}
295
296TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
297 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
298 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
299 .WillOnce(Return(INVALID_OPERATION));
300
301 mDisplay.chooseCompositionStrategy();
302
303 auto& state = mDisplay.getState();
304 EXPECT_TRUE(state.usesClientComposition);
305 EXPECT_FALSE(state.usesDeviceComposition);
306}
307
308TEST_F(DisplayChooseCompositionStrategyTest, normalOperation) {
309 // Since two calls are made to anyLayersRequireClientComposition with different return values,
310 // use a Sequence to control the matching so the values are returned in a known order.
311 Sequence s;
312 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
313 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
314 .InSequence(s)
315 .WillOnce(Return(false));
316
317 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
318 .WillOnce(Return(NO_ERROR));
319 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
320
321 mDisplay.chooseCompositionStrategy();
322
323 auto& state = mDisplay.getState();
324 EXPECT_FALSE(state.usesClientComposition);
325 EXPECT_TRUE(state.usesDeviceComposition);
326}
327
328TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) {
329 android::HWComposer::DeviceRequestedChanges changes{
330 {{nullptr, HWC2::Composition::Client}},
331 HWC2::DisplayRequest::FlipClientTarget,
332 {{nullptr, HWC2::LayerRequest::ClearClientTarget}},
333 };
334
335 // Since two calls are made to anyLayersRequireClientComposition with different return values,
336 // use a Sequence to control the matching so the values are returned in a known order.
337 Sequence s;
338 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
339 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
340 .InSequence(s)
341 .WillOnce(Return(false));
342
343 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
344 .WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
345 EXPECT_CALL(mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
346 EXPECT_CALL(mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
347 EXPECT_CALL(mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1);
348 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
349
350 mDisplay.chooseCompositionStrategy();
351
352 auto& state = mDisplay.getState();
353 EXPECT_FALSE(state.usesClientComposition);
354 EXPECT_TRUE(state.usesDeviceComposition);
355}
356
357/*
Lloyd Pique688abd42019-02-15 15:42:24 -0800358 * Display::getSkipColorTransform()
359 */
360
361TEST_F(DisplayTest, getSkipColorTransformDoesNothingIfNonHwcDisplay) {
362 auto nonHwcDisplay{
363 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
364 EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform());
365}
366
367TEST_F(DisplayTest, getSkipColorTransformChecksHwcCapability) {
368 EXPECT_CALL(mHwComposer,
369 hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
370 HWC2::DisplayCapability::SkipClientColorTransform))
371 .WillOnce(Return(true));
372 EXPECT_TRUE(mDisplay.getSkipColorTransform());
373}
374
375/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800376 * Display::anyLayersRequireClientComposition()
377 */
378
379TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) {
380 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
381 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
382 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(false));
383
384 EXPECT_FALSE(mDisplay.anyLayersRequireClientComposition());
385}
386
387TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) {
388 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
389 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
390
391 EXPECT_TRUE(mDisplay.anyLayersRequireClientComposition());
392}
393
394/*
395 * Display::allLayersRequireClientComposition()
396 */
397
398TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) {
399 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
400 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
401 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(true));
402
403 EXPECT_TRUE(mDisplay.allLayersRequireClientComposition());
404}
405
406TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) {
407 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
408 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
409
410 EXPECT_FALSE(mDisplay.allLayersRequireClientComposition());
411}
412
413/*
414 * Display::applyChangedTypesToLayers()
415 */
416
417TEST_F(DisplayTest, applyChangedTypesToLayersTakesEarlyOutIfNoChangedLayers) {
418 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes());
419}
420
421TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) {
422 EXPECT_CALL(*mLayer1,
423 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT))
424 .Times(1);
425 EXPECT_CALL(*mLayer2,
426 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::DEVICE))
427 .Times(1);
428
429 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes{
430 {&mHWC2Layer1, HWC2::Composition::Client},
431 {&mHWC2Layer2, HWC2::Composition::Device},
432 {&mHWC2LayerUnknown, HWC2::Composition::SolidColor},
433 });
434}
435
436/*
437 * Display::applyDisplayRequests()
438 */
439
440TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesNoRequests) {
441 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
442
443 auto& state = mDisplay.getState();
444 EXPECT_FALSE(state.flipClientTarget);
445}
446
447TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesFlipClientTarget) {
448 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
449
450 auto& state = mDisplay.getState();
451 EXPECT_TRUE(state.flipClientTarget);
452}
453
454TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesWriteClientTargetToOutput) {
455 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
456
457 auto& state = mDisplay.getState();
458 EXPECT_FALSE(state.flipClientTarget);
459}
460
461TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) {
462 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
463
464 auto& state = mDisplay.getState();
465 EXPECT_TRUE(state.flipClientTarget);
466}
467
468/*
469 * Display::applyLayerRequestsToLayers()
470 */
471
472TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) {
473 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
474 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
475 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
476
477 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests());
478}
479
480TEST_F(DisplayTest, applyLayerRequestsToLayers2) {
481 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
482 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
483 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
484
485 EXPECT_CALL(*mLayer1,
486 applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET))
487 .Times(1);
488
489 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests{
490 {&mHWC2Layer1, HWC2::LayerRequest::ClearClientTarget},
491 {&mHWC2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
492 });
493}
494
Lloyd Pique35fca9d2019-02-13 14:24:11 -0800495/*
496 * Display::presentAndGetFrameFences()
497 */
498
499TEST_F(DisplayTest, presentAndGetFrameFencesReturnsNoFencesOnNonHwcDisplay) {
500 auto nonHwcDisplay{
501 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
502
503 auto result = nonHwcDisplay->presentAndGetFrameFences();
504
505 ASSERT_TRUE(result.presentFence.get());
506 EXPECT_FALSE(result.presentFence->isValid());
507 EXPECT_EQ(0u, result.layerFences.size());
508}
509
510TEST_F(DisplayTest, presentAndGetFrameFencesReturnsPresentAndLayerFences) {
511 sp<Fence> presentFence = new Fence();
512 sp<Fence> layer1Fence = new Fence();
513 sp<Fence> layer2Fence = new Fence();
514
515 EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
516 EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
517 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer1))
518 .WillOnce(Return(layer1Fence));
519 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer2))
520 .WillOnce(Return(layer2Fence));
521 EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
522
523 auto result = mDisplay.presentAndGetFrameFences();
524
525 EXPECT_EQ(presentFence, result.presentFence);
526
527 EXPECT_EQ(2u, result.layerFences.size());
528 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer1));
529 EXPECT_EQ(layer1Fence, result.layerFences[&mHWC2Layer1]);
530 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer2));
531 EXPECT_EQ(layer2Fence, result.layerFences[&mHWC2Layer2]);
532}
533
Lloyd Pique688abd42019-02-15 15:42:24 -0800534/*
535 * Display::setExpensiveRenderingExpected()
536 */
537
538TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) {
539 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, true)).Times(1);
540 mDisplay.setExpensiveRenderingExpected(true);
541
542 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, false)).Times(1);
543 mDisplay.setExpensiveRenderingExpected(false);
544}
545
Lloyd Piqued3d69882019-02-28 16:03:46 -0800546/*
547 * Display::finishFrame()
548 */
549
550TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) {
551 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
552 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
553
554 // We expect no calls to queueBuffer if composition was skipped.
555 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
556
557 mDisplay.editState().isEnabled = true;
558 mDisplay.editState().usesClientComposition = false;
559 mDisplay.editState().viewport = Rect(0, 0, 1, 1);
560 mDisplay.editState().dirtyRegion = Region::INVALID_REGION;
561
562 CompositionRefreshArgs refreshArgs;
563 refreshArgs.repaintEverything = false;
564
565 mDisplay.finishFrame(refreshArgs);
566}
567
568TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) {
569 std::shared_ptr<impl::Display> nonHwcDisplay{
570 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
571
572 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
573 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
574
575 // We expect no calls to queueBuffer if composition was skipped.
576 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0);
577
578 nonHwcDisplay->editState().isEnabled = true;
579 nonHwcDisplay->editState().usesClientComposition = false;
580 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
581 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
582
583 CompositionRefreshArgs refreshArgs;
584 refreshArgs.repaintEverything = false;
585
586 nonHwcDisplay->finishFrame(refreshArgs);
587}
588
589TEST_F(DisplayTest, finishFramePerformsCompositionIfDirty) {
590 std::shared_ptr<impl::Display> nonHwcDisplay{
591 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
592
593 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
594 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
595
596 // We expect a single call to queueBuffer when composition is not skipped.
597 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
598
599 nonHwcDisplay->editState().isEnabled = true;
600 nonHwcDisplay->editState().usesClientComposition = false;
601 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
602 nonHwcDisplay->editState().dirtyRegion = Region(Rect(0, 0, 1, 1));
603
604 CompositionRefreshArgs refreshArgs;
605 refreshArgs.repaintEverything = false;
606
607 nonHwcDisplay->finishFrame(refreshArgs);
608}
609
610TEST_F(DisplayTest, finishFramePerformsCompositionIfRepaintEverything) {
611 std::shared_ptr<impl::Display> nonHwcDisplay{
612 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
613
614 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
615 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
616
617 // We expect a single call to queueBuffer when composition is not skipped.
618 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
619
620 nonHwcDisplay->editState().isEnabled = true;
621 nonHwcDisplay->editState().usesClientComposition = false;
622 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
623 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
624
625 CompositionRefreshArgs refreshArgs;
626 refreshArgs.repaintEverything = true;
627
628 nonHwcDisplay->finishFrame(refreshArgs);
629}
630
Lloyd Pique45a165a2018-10-19 11:54:47 -0700631} // namespace
632} // namespace android::compositionengine