blob: 008e631debca887467a91bfa1145b73a6bc3cff1 [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) {
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800141 // No change does nothing
142 CompositionRefreshArgs refreshArgs;
143 refreshArgs.colorTransformMatrix = std::nullopt;
144 mDisplay.setColorTransform(refreshArgs);
145
Lloyd Pique32cbe282018-10-19 13:09:22 -0700146 // Identity matrix sets an identity state value
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800147 const mat4 kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700148
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800149 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kIdentity)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700150
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800151 refreshArgs.colorTransformMatrix = kIdentity;
152 mDisplay.setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700153
154 // Non-identity matrix sets a non-identity state value
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800155 const mat4 kNonIdentity = mat4() * 2;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800157 EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kNonIdentity)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700158
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800159 refreshArgs.colorTransformMatrix = kNonIdentity;
160 mDisplay.setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161}
162
Lloyd Pique66d68602019-02-13 14:23:31 -0800163/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700164 * Display::setColorMode()
165 */
166
167TEST_F(DisplayTest, setColorModeSetsModeUnlessNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800168 using ColorProfile = Output::ColorProfile;
169
Lloyd Pique31cb2942018-10-19 17:23:03 -0700170 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
171 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Piquef5275482019-01-29 18:42:42 -0800172 mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
173 mDisplay.setDisplayColorProfileForTest(std::unique_ptr<DisplayColorProfile>(colorProfile));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700174
Lloyd Piquef5275482019-01-29 18:42:42 -0800175 EXPECT_CALL(*colorProfile, getTargetDataspace(_, _, _))
176 .WillRepeatedly(Return(ui::Dataspace::UNKNOWN));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700177
178 // These values are expected to be the initial state.
179 ASSERT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
180 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
181 ASSERT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800182 ASSERT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700183
Lloyd Piquef5275482019-01-29 18:42:42 -0800184 // If the set values are unchanged, nothing happens
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800185 mDisplay.setColorProfile(ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
186 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700187
188 EXPECT_EQ(ui::ColorMode::NATIVE, mDisplay.getState().colorMode);
189 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().dataspace);
190 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800191 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700192
193 // Otherwise if the values are different, updates happen
Lloyd Piqueef958122019-02-05 18:00:12 -0800194 EXPECT_CALL(*renderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700195 EXPECT_CALL(mHwComposer,
Lloyd Piqueef958122019-02-05 18:00:12 -0800196 setActiveColorMode(DEFAULT_DISPLAY_ID, ui::ColorMode::DISPLAY_P3,
Lloyd Pique32cbe282018-10-19 13:09:22 -0700197 ui::RenderIntent::TONE_MAP_COLORIMETRIC))
198 .Times(1);
199
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800200 mDisplay.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
201 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
202 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700203
Lloyd Piqueef958122019-02-05 18:00:12 -0800204 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mDisplay.getState().colorMode);
205 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mDisplay.getState().dataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700206 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800207 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208}
209
210TEST_F(DisplayTest, setColorModeDoesNothingForVirtualDisplay) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800211 using ColorProfile = Output::ColorProfile;
212
Lloyd Pique32cbe282018-10-19 13:09:22 -0700213 impl::Display virtualDisplay{mCompositionEngine,
214 DisplayCreationArgs{false, true, DEFAULT_DISPLAY_ID}};
215
Lloyd Piquef5275482019-01-29 18:42:42 -0800216 mock::DisplayColorProfile* colorProfile = new StrictMock<mock::DisplayColorProfile>();
217 virtualDisplay.setDisplayColorProfileForTest(
218 std::unique_ptr<DisplayColorProfile>(colorProfile));
219
220 EXPECT_CALL(*colorProfile,
221 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
222 ui::Dataspace::UNKNOWN))
223 .WillOnce(Return(ui::Dataspace::UNKNOWN));
224
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800225 virtualDisplay.setColorProfile(
226 ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
227 ui::RenderIntent::TONE_MAP_COLORIMETRIC, ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228
229 EXPECT_EQ(ui::ColorMode::NATIVE, virtualDisplay.getState().colorMode);
230 EXPECT_EQ(ui::Dataspace::UNKNOWN, virtualDisplay.getState().dataspace);
231 EXPECT_EQ(ui::RenderIntent::COLORIMETRIC, virtualDisplay.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800232 EXPECT_EQ(ui::Dataspace::UNKNOWN, mDisplay.getState().targetDataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233}
234
Lloyd Pique66d68602019-02-13 14:23:31 -0800235/*
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700236 * Display::createDisplayColorProfile()
237 */
238
239TEST_F(DisplayTest, createDisplayColorProfileSetsDisplayColorProfile) {
240 EXPECT_TRUE(mDisplay.getDisplayColorProfile() == nullptr);
241 mDisplay.createDisplayColorProfile(
242 DisplayColorProfileCreationArgs{false, HdrCapabilities(), 0,
243 DisplayColorProfileCreationArgs::HwcColorModes()});
244 EXPECT_TRUE(mDisplay.getDisplayColorProfile() != nullptr);
245}
246
Lloyd Pique66d68602019-02-13 14:23:31 -0800247/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700248 * Display::createRenderSurface()
249 */
250
251TEST_F(DisplayTest, createRenderSurfaceSetsRenderSurface) {
chaviw8beb4142019-04-11 13:09:05 -0700252 EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL)).WillRepeatedly(Return(NO_ERROR));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700253 EXPECT_TRUE(mDisplay.getRenderSurface() == nullptr);
chaviw8beb4142019-04-11 13:09:05 -0700254 mDisplay.createRenderSurface(RenderSurfaceCreationArgs{640, 480, mNativeWindow, nullptr});
Lloyd Pique31cb2942018-10-19 17:23:03 -0700255 EXPECT_TRUE(mDisplay.getRenderSurface() != nullptr);
256}
257
Lloyd Pique66d68602019-02-13 14:23:31 -0800258/*
259 * Display::chooseCompositionStrategy()
260 */
261
262struct DisplayChooseCompositionStrategyTest : public testing::Test {
263 struct DisplayPartialMock : public impl::Display {
264 DisplayPartialMock(const compositionengine::CompositionEngine& compositionEngine,
265 compositionengine::DisplayCreationArgs&& args)
266 : impl::Display(compositionEngine, std::move(args)) {}
267
268 // Sets up the helper functions called by chooseCompositionStrategy to
269 // use a mock implementations.
270 MOCK_CONST_METHOD0(anyLayersRequireClientComposition, bool());
271 MOCK_CONST_METHOD0(allLayersRequireClientComposition, bool());
272 MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&));
273 MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&));
274 MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&));
275 };
276
277 DisplayChooseCompositionStrategyTest() {
278 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
279 }
280
281 StrictMock<android::mock::HWComposer> mHwComposer;
282 StrictMock<mock::CompositionEngine> mCompositionEngine;
283 StrictMock<DisplayPartialMock>
284 mDisplay{mCompositionEngine,
285 DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()};
286};
287
288TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) {
289 impl::Display nonHwcDisplay{mCompositionEngine, DisplayCreationArgsBuilder().build()};
290 EXPECT_FALSE(nonHwcDisplay.getId());
291
292 nonHwcDisplay.chooseCompositionStrategy();
293
294 auto& state = nonHwcDisplay.getState();
295 EXPECT_TRUE(state.usesClientComposition);
296 EXPECT_FALSE(state.usesDeviceComposition);
297}
298
299TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
300 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
301 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
302 .WillOnce(Return(INVALID_OPERATION));
303
304 mDisplay.chooseCompositionStrategy();
305
306 auto& state = mDisplay.getState();
307 EXPECT_TRUE(state.usesClientComposition);
308 EXPECT_FALSE(state.usesDeviceComposition);
309}
310
311TEST_F(DisplayChooseCompositionStrategyTest, normalOperation) {
312 // Since two calls are made to anyLayersRequireClientComposition with different return values,
313 // use a Sequence to control the matching so the values are returned in a known order.
314 Sequence s;
315 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
316 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
317 .InSequence(s)
318 .WillOnce(Return(false));
319
320 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
321 .WillOnce(Return(NO_ERROR));
322 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
323
324 mDisplay.chooseCompositionStrategy();
325
326 auto& state = mDisplay.getState();
327 EXPECT_FALSE(state.usesClientComposition);
328 EXPECT_TRUE(state.usesDeviceComposition);
329}
330
331TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) {
332 android::HWComposer::DeviceRequestedChanges changes{
333 {{nullptr, HWC2::Composition::Client}},
334 HWC2::DisplayRequest::FlipClientTarget,
335 {{nullptr, HWC2::LayerRequest::ClearClientTarget}},
336 };
337
338 // Since two calls are made to anyLayersRequireClientComposition with different return values,
339 // use a Sequence to control the matching so the values are returned in a known order.
340 Sequence s;
341 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
342 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
343 .InSequence(s)
344 .WillOnce(Return(false));
345
346 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
347 .WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
348 EXPECT_CALL(mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
349 EXPECT_CALL(mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
350 EXPECT_CALL(mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1);
351 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
352
353 mDisplay.chooseCompositionStrategy();
354
355 auto& state = mDisplay.getState();
356 EXPECT_FALSE(state.usesClientComposition);
357 EXPECT_TRUE(state.usesDeviceComposition);
358}
359
360/*
Lloyd Pique688abd42019-02-15 15:42:24 -0800361 * Display::getSkipColorTransform()
362 */
363
364TEST_F(DisplayTest, getSkipColorTransformDoesNothingIfNonHwcDisplay) {
365 auto nonHwcDisplay{
366 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
367 EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform());
368}
369
370TEST_F(DisplayTest, getSkipColorTransformChecksHwcCapability) {
371 EXPECT_CALL(mHwComposer,
372 hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
373 HWC2::DisplayCapability::SkipClientColorTransform))
374 .WillOnce(Return(true));
375 EXPECT_TRUE(mDisplay.getSkipColorTransform());
376}
377
378/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800379 * Display::anyLayersRequireClientComposition()
380 */
381
382TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) {
383 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
384 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
385 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(false));
386
387 EXPECT_FALSE(mDisplay.anyLayersRequireClientComposition());
388}
389
390TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) {
391 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
392 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
393
394 EXPECT_TRUE(mDisplay.anyLayersRequireClientComposition());
395}
396
397/*
398 * Display::allLayersRequireClientComposition()
399 */
400
401TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) {
402 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
403 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
404 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(true));
405
406 EXPECT_TRUE(mDisplay.allLayersRequireClientComposition());
407}
408
409TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) {
410 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
411 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
412
413 EXPECT_FALSE(mDisplay.allLayersRequireClientComposition());
414}
415
416/*
417 * Display::applyChangedTypesToLayers()
418 */
419
420TEST_F(DisplayTest, applyChangedTypesToLayersTakesEarlyOutIfNoChangedLayers) {
421 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes());
422}
423
424TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) {
425 EXPECT_CALL(*mLayer1,
426 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT))
427 .Times(1);
428 EXPECT_CALL(*mLayer2,
429 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::DEVICE))
430 .Times(1);
431
432 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes{
433 {&mHWC2Layer1, HWC2::Composition::Client},
434 {&mHWC2Layer2, HWC2::Composition::Device},
435 {&mHWC2LayerUnknown, HWC2::Composition::SolidColor},
436 });
437}
438
439/*
440 * Display::applyDisplayRequests()
441 */
442
443TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesNoRequests) {
444 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
445
446 auto& state = mDisplay.getState();
447 EXPECT_FALSE(state.flipClientTarget);
448}
449
450TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesFlipClientTarget) {
451 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
452
453 auto& state = mDisplay.getState();
454 EXPECT_TRUE(state.flipClientTarget);
455}
456
457TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesWriteClientTargetToOutput) {
458 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
459
460 auto& state = mDisplay.getState();
461 EXPECT_FALSE(state.flipClientTarget);
462}
463
464TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) {
465 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
466
467 auto& state = mDisplay.getState();
468 EXPECT_TRUE(state.flipClientTarget);
469}
470
471/*
472 * Display::applyLayerRequestsToLayers()
473 */
474
475TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) {
476 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
477 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
478 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
479
480 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests());
481}
482
483TEST_F(DisplayTest, applyLayerRequestsToLayers2) {
484 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
485 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
486 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
487
488 EXPECT_CALL(*mLayer1,
489 applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET))
490 .Times(1);
491
492 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests{
493 {&mHWC2Layer1, HWC2::LayerRequest::ClearClientTarget},
494 {&mHWC2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
495 });
496}
497
Lloyd Pique35fca9d2019-02-13 14:24:11 -0800498/*
499 * Display::presentAndGetFrameFences()
500 */
501
502TEST_F(DisplayTest, presentAndGetFrameFencesReturnsNoFencesOnNonHwcDisplay) {
503 auto nonHwcDisplay{
504 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
505
506 auto result = nonHwcDisplay->presentAndGetFrameFences();
507
508 ASSERT_TRUE(result.presentFence.get());
509 EXPECT_FALSE(result.presentFence->isValid());
510 EXPECT_EQ(0u, result.layerFences.size());
511}
512
513TEST_F(DisplayTest, presentAndGetFrameFencesReturnsPresentAndLayerFences) {
514 sp<Fence> presentFence = new Fence();
515 sp<Fence> layer1Fence = new Fence();
516 sp<Fence> layer2Fence = new Fence();
517
518 EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
519 EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
520 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer1))
521 .WillOnce(Return(layer1Fence));
522 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer2))
523 .WillOnce(Return(layer2Fence));
524 EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
525
526 auto result = mDisplay.presentAndGetFrameFences();
527
528 EXPECT_EQ(presentFence, result.presentFence);
529
530 EXPECT_EQ(2u, result.layerFences.size());
531 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer1));
532 EXPECT_EQ(layer1Fence, result.layerFences[&mHWC2Layer1]);
533 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer2));
534 EXPECT_EQ(layer2Fence, result.layerFences[&mHWC2Layer2]);
535}
536
Lloyd Pique688abd42019-02-15 15:42:24 -0800537/*
538 * Display::setExpensiveRenderingExpected()
539 */
540
541TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) {
542 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, true)).Times(1);
543 mDisplay.setExpensiveRenderingExpected(true);
544
545 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, false)).Times(1);
546 mDisplay.setExpensiveRenderingExpected(false);
547}
548
Lloyd Piqued3d69882019-02-28 16:03:46 -0800549/*
550 * Display::finishFrame()
551 */
552
553TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) {
554 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
555 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
556
557 // We expect no calls to queueBuffer if composition was skipped.
558 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
559
560 mDisplay.editState().isEnabled = true;
561 mDisplay.editState().usesClientComposition = false;
562 mDisplay.editState().viewport = Rect(0, 0, 1, 1);
563 mDisplay.editState().dirtyRegion = Region::INVALID_REGION;
564
565 CompositionRefreshArgs refreshArgs;
566 refreshArgs.repaintEverything = false;
567
568 mDisplay.finishFrame(refreshArgs);
569}
570
571TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) {
572 std::shared_ptr<impl::Display> nonHwcDisplay{
573 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
574
575 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
576 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
577
578 // We expect no calls to queueBuffer if composition was skipped.
579 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0);
580
581 nonHwcDisplay->editState().isEnabled = true;
582 nonHwcDisplay->editState().usesClientComposition = false;
583 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
584 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
585
586 CompositionRefreshArgs refreshArgs;
587 refreshArgs.repaintEverything = false;
588
589 nonHwcDisplay->finishFrame(refreshArgs);
590}
591
592TEST_F(DisplayTest, finishFramePerformsCompositionIfDirty) {
593 std::shared_ptr<impl::Display> nonHwcDisplay{
594 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
595
596 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
597 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
598
599 // We expect a single call to queueBuffer when composition is not skipped.
600 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
601
602 nonHwcDisplay->editState().isEnabled = true;
603 nonHwcDisplay->editState().usesClientComposition = false;
604 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
605 nonHwcDisplay->editState().dirtyRegion = Region(Rect(0, 0, 1, 1));
606
607 CompositionRefreshArgs refreshArgs;
608 refreshArgs.repaintEverything = false;
609
610 nonHwcDisplay->finishFrame(refreshArgs);
611}
612
613TEST_F(DisplayTest, finishFramePerformsCompositionIfRepaintEverything) {
614 std::shared_ptr<impl::Display> nonHwcDisplay{
615 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
616
617 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
618 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
619
620 // We expect a single call to queueBuffer when composition is not skipped.
621 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
622
623 nonHwcDisplay->editState().isEnabled = true;
624 nonHwcDisplay->editState().usesClientComposition = false;
625 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
626 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
627
628 CompositionRefreshArgs refreshArgs;
629 refreshArgs.repaintEverything = true;
630
631 nonHwcDisplay->finishFrame(refreshArgs);
632}
633
Lloyd Pique45a165a2018-10-19 11:54:47 -0700634} // namespace
635} // namespace android::compositionengine