blob: 6821ec130177cf8a4b5cab514a39b82ffa353d2a [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 Pique66d68602019-02-13 14:23:31 -0800280 * Display::chooseCompositionStrategy()
281 */
282
283struct DisplayChooseCompositionStrategyTest : public testing::Test {
284 struct DisplayPartialMock : public impl::Display {
285 DisplayPartialMock(const compositionengine::CompositionEngine& compositionEngine,
286 compositionengine::DisplayCreationArgs&& args)
287 : impl::Display(compositionEngine, std::move(args)) {}
288
289 // Sets up the helper functions called by chooseCompositionStrategy to
290 // use a mock implementations.
291 MOCK_CONST_METHOD0(anyLayersRequireClientComposition, bool());
292 MOCK_CONST_METHOD0(allLayersRequireClientComposition, bool());
293 MOCK_METHOD1(applyChangedTypesToLayers, void(const impl::Display::ChangedTypes&));
294 MOCK_METHOD1(applyDisplayRequests, void(const impl::Display::DisplayRequests&));
295 MOCK_METHOD1(applyLayerRequestsToLayers, void(const impl::Display::LayerRequests&));
296 };
297
298 DisplayChooseCompositionStrategyTest() {
299 EXPECT_CALL(mCompositionEngine, getHwComposer()).WillRepeatedly(ReturnRef(mHwComposer));
300 }
301
302 StrictMock<android::mock::HWComposer> mHwComposer;
303 StrictMock<mock::CompositionEngine> mCompositionEngine;
304 StrictMock<DisplayPartialMock>
305 mDisplay{mCompositionEngine,
306 DisplayCreationArgsBuilder().setDisplayId(DEFAULT_DISPLAY_ID).build()};
307};
308
309TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutIfNotAHwcDisplay) {
310 impl::Display nonHwcDisplay{mCompositionEngine, DisplayCreationArgsBuilder().build()};
311 EXPECT_FALSE(nonHwcDisplay.getId());
312
313 nonHwcDisplay.chooseCompositionStrategy();
314
315 auto& state = nonHwcDisplay.getState();
316 EXPECT_TRUE(state.usesClientComposition);
317 EXPECT_FALSE(state.usesDeviceComposition);
318}
319
320TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
321 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
322 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
323 .WillOnce(Return(INVALID_OPERATION));
324
325 mDisplay.chooseCompositionStrategy();
326
327 auto& state = mDisplay.getState();
328 EXPECT_TRUE(state.usesClientComposition);
329 EXPECT_FALSE(state.usesDeviceComposition);
330}
331
332TEST_F(DisplayChooseCompositionStrategyTest, normalOperation) {
333 // Since two calls are made to anyLayersRequireClientComposition with different return values,
334 // use a Sequence to control the matching so the values are returned in a known order.
335 Sequence s;
336 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
337 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
338 .InSequence(s)
339 .WillOnce(Return(false));
340
341 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
342 .WillOnce(Return(NO_ERROR));
343 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
344
345 mDisplay.chooseCompositionStrategy();
346
347 auto& state = mDisplay.getState();
348 EXPECT_FALSE(state.usesClientComposition);
349 EXPECT_TRUE(state.usesDeviceComposition);
350}
351
352TEST_F(DisplayChooseCompositionStrategyTest, normalOperationWithChanges) {
353 android::HWComposer::DeviceRequestedChanges changes{
354 {{nullptr, HWC2::Composition::Client}},
355 HWC2::DisplayRequest::FlipClientTarget,
356 {{nullptr, HWC2::LayerRequest::ClearClientTarget}},
357 };
358
359 // Since two calls are made to anyLayersRequireClientComposition with different return values,
360 // use a Sequence to control the matching so the values are returned in a known order.
361 Sequence s;
362 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition()).InSequence(s).WillOnce(Return(true));
363 EXPECT_CALL(mDisplay, anyLayersRequireClientComposition())
364 .InSequence(s)
365 .WillOnce(Return(false));
366
367 EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
368 .WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
369 EXPECT_CALL(mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
370 EXPECT_CALL(mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
371 EXPECT_CALL(mDisplay, applyLayerRequestsToLayers(changes.layerRequests)).Times(1);
372 EXPECT_CALL(mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
373
374 mDisplay.chooseCompositionStrategy();
375
376 auto& state = mDisplay.getState();
377 EXPECT_FALSE(state.usesClientComposition);
378 EXPECT_TRUE(state.usesDeviceComposition);
379}
380
381/*
Lloyd Pique688abd42019-02-15 15:42:24 -0800382 * Display::getSkipColorTransform()
383 */
384
385TEST_F(DisplayTest, getSkipColorTransformDoesNothingIfNonHwcDisplay) {
386 auto nonHwcDisplay{
387 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
388 EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform());
389}
390
391TEST_F(DisplayTest, getSkipColorTransformChecksHwcCapability) {
392 EXPECT_CALL(mHwComposer,
393 hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
394 HWC2::DisplayCapability::SkipClientColorTransform))
395 .WillOnce(Return(true));
396 EXPECT_TRUE(mDisplay.getSkipColorTransform());
397}
398
399/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800400 * Display::anyLayersRequireClientComposition()
401 */
402
403TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsFalse) {
404 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
405 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
406 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(false));
407
408 EXPECT_FALSE(mDisplay.anyLayersRequireClientComposition());
409}
410
411TEST_F(DisplayTest, anyLayersRequireClientCompositionReturnsTrue) {
412 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(false));
413 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
414
415 EXPECT_TRUE(mDisplay.anyLayersRequireClientComposition());
416}
417
418/*
419 * Display::allLayersRequireClientComposition()
420 */
421
422TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsTrue) {
423 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
424 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(true));
425 EXPECT_CALL(*mLayer3, requiresClientComposition()).WillOnce(Return(true));
426
427 EXPECT_TRUE(mDisplay.allLayersRequireClientComposition());
428}
429
430TEST_F(DisplayTest, allLayersRequireClientCompositionReturnsFalse) {
431 EXPECT_CALL(*mLayer1, requiresClientComposition()).WillOnce(Return(true));
432 EXPECT_CALL(*mLayer2, requiresClientComposition()).WillOnce(Return(false));
433
434 EXPECT_FALSE(mDisplay.allLayersRequireClientComposition());
435}
436
437/*
438 * Display::applyChangedTypesToLayers()
439 */
440
441TEST_F(DisplayTest, applyChangedTypesToLayersTakesEarlyOutIfNoChangedLayers) {
442 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes());
443}
444
445TEST_F(DisplayTest, applyChangedTypesToLayersAppliesChanges) {
446 EXPECT_CALL(*mLayer1,
447 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::CLIENT))
448 .Times(1);
449 EXPECT_CALL(*mLayer2,
450 applyDeviceCompositionTypeChange(Hwc2::IComposerClient::Composition::DEVICE))
451 .Times(1);
452
453 mDisplay.applyChangedTypesToLayers(impl::Display::ChangedTypes{
454 {&mHWC2Layer1, HWC2::Composition::Client},
455 {&mHWC2Layer2, HWC2::Composition::Device},
456 {&mHWC2LayerUnknown, HWC2::Composition::SolidColor},
457 });
458}
459
460/*
461 * Display::applyDisplayRequests()
462 */
463
464TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesNoRequests) {
465 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(0));
466
467 auto& state = mDisplay.getState();
468 EXPECT_FALSE(state.flipClientTarget);
469}
470
471TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesFlipClientTarget) {
472 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::FlipClientTarget);
473
474 auto& state = mDisplay.getState();
475 EXPECT_TRUE(state.flipClientTarget);
476}
477
478TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesWriteClientTargetToOutput) {
479 mDisplay.applyDisplayRequests(HWC2::DisplayRequest::WriteClientTargetToOutput);
480
481 auto& state = mDisplay.getState();
482 EXPECT_FALSE(state.flipClientTarget);
483}
484
485TEST_F(DisplayTest, applyDisplayRequestsToLayersHandlesAllRequestFlagsSet) {
486 mDisplay.applyDisplayRequests(static_cast<HWC2::DisplayRequest>(~0));
487
488 auto& state = mDisplay.getState();
489 EXPECT_TRUE(state.flipClientTarget);
490}
491
492/*
493 * Display::applyLayerRequestsToLayers()
494 */
495
496TEST_F(DisplayTest, applyLayerRequestsToLayersPreparesAllLayers) {
497 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
498 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
499 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
500
501 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests());
502}
503
504TEST_F(DisplayTest, applyLayerRequestsToLayers2) {
505 EXPECT_CALL(*mLayer1, prepareForDeviceLayerRequests()).Times(1);
506 EXPECT_CALL(*mLayer2, prepareForDeviceLayerRequests()).Times(1);
507 EXPECT_CALL(*mLayer3, prepareForDeviceLayerRequests()).Times(1);
508
509 EXPECT_CALL(*mLayer1,
510 applyDeviceLayerRequest(Hwc2::IComposerClient::LayerRequest::CLEAR_CLIENT_TARGET))
511 .Times(1);
512
513 mDisplay.applyLayerRequestsToLayers(impl::Display::LayerRequests{
514 {&mHWC2Layer1, HWC2::LayerRequest::ClearClientTarget},
515 {&mHWC2LayerUnknown, HWC2::LayerRequest::ClearClientTarget},
516 });
517}
518
Lloyd Pique35fca9d2019-02-13 14:24:11 -0800519/*
520 * Display::presentAndGetFrameFences()
521 */
522
523TEST_F(DisplayTest, presentAndGetFrameFencesReturnsNoFencesOnNonHwcDisplay) {
524 auto nonHwcDisplay{
525 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
526
527 auto result = nonHwcDisplay->presentAndGetFrameFences();
528
529 ASSERT_TRUE(result.presentFence.get());
530 EXPECT_FALSE(result.presentFence->isValid());
531 EXPECT_EQ(0u, result.layerFences.size());
532}
533
534TEST_F(DisplayTest, presentAndGetFrameFencesReturnsPresentAndLayerFences) {
535 sp<Fence> presentFence = new Fence();
536 sp<Fence> layer1Fence = new Fence();
537 sp<Fence> layer2Fence = new Fence();
538
539 EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
540 EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
541 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer1))
542 .WillOnce(Return(layer1Fence));
543 EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mHWC2Layer2))
544 .WillOnce(Return(layer2Fence));
545 EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
546
547 auto result = mDisplay.presentAndGetFrameFences();
548
549 EXPECT_EQ(presentFence, result.presentFence);
550
551 EXPECT_EQ(2u, result.layerFences.size());
552 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer1));
553 EXPECT_EQ(layer1Fence, result.layerFences[&mHWC2Layer1]);
554 ASSERT_EQ(1, result.layerFences.count(&mHWC2Layer2));
555 EXPECT_EQ(layer2Fence, result.layerFences[&mHWC2Layer2]);
556}
557
Lloyd Pique688abd42019-02-15 15:42:24 -0800558/*
559 * Display::setExpensiveRenderingExpected()
560 */
561
562TEST_F(DisplayTest, setExpensiveRenderingExpectedForwardsToPowerAdvisor) {
563 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, true)).Times(1);
564 mDisplay.setExpensiveRenderingExpected(true);
565
566 EXPECT_CALL(mPowerAdvisor, setExpensiveRenderingExpected(DEFAULT_DISPLAY_ID, false)).Times(1);
567 mDisplay.setExpensiveRenderingExpected(false);
568}
569
Lloyd Piqued3d69882019-02-28 16:03:46 -0800570/*
571 * Display::finishFrame()
572 */
573
574TEST_F(DisplayTest, finishFrameDoesNotSkipCompositionIfNotDirtyOnHwcDisplay) {
575 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
576 mDisplay.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
577
578 // We expect no calls to queueBuffer if composition was skipped.
579 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
580
581 mDisplay.editState().isEnabled = true;
582 mDisplay.editState().usesClientComposition = false;
583 mDisplay.editState().viewport = Rect(0, 0, 1, 1);
584 mDisplay.editState().dirtyRegion = Region::INVALID_REGION;
585
586 CompositionRefreshArgs refreshArgs;
587 refreshArgs.repaintEverything = false;
588
589 mDisplay.finishFrame(refreshArgs);
590}
591
592TEST_F(DisplayTest, finishFrameSkipsCompositionIfNotDirty) {
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 no calls to queueBuffer if composition was skipped.
600 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(0);
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::INVALID_REGION;
606
607 CompositionRefreshArgs refreshArgs;
608 refreshArgs.repaintEverything = false;
609
610 nonHwcDisplay->finishFrame(refreshArgs);
611}
612
613TEST_F(DisplayTest, finishFramePerformsCompositionIfDirty) {
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(Rect(0, 0, 1, 1));
627
628 CompositionRefreshArgs refreshArgs;
629 refreshArgs.repaintEverything = false;
630
631 nonHwcDisplay->finishFrame(refreshArgs);
632}
633
634TEST_F(DisplayTest, finishFramePerformsCompositionIfRepaintEverything) {
635 std::shared_ptr<impl::Display> nonHwcDisplay{
636 impl::createDisplay(mCompositionEngine, DisplayCreationArgsBuilder().build())};
637
638 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
639 nonHwcDisplay->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(renderSurface));
640
641 // We expect a single call to queueBuffer when composition is not skipped.
642 EXPECT_CALL(*renderSurface, queueBuffer(_)).Times(1);
643
644 nonHwcDisplay->editState().isEnabled = true;
645 nonHwcDisplay->editState().usesClientComposition = false;
646 nonHwcDisplay->editState().viewport = Rect(0, 0, 1, 1);
647 nonHwcDisplay->editState().dirtyRegion = Region::INVALID_REGION;
648
649 CompositionRefreshArgs refreshArgs;
650 refreshArgs.repaintEverything = true;
651
652 nonHwcDisplay->finishFrame(refreshArgs);
653}
654
Lloyd Pique45a165a2018-10-19 11:54:47 -0700655} // namespace
656} // namespace android::compositionengine