blob: 70d98717ae9b69449d30edc5c36eb3d654df3c03 [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -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
17#include <cmath>
18
Lloyd Pique56eba802019-08-28 15:45:25 -070019#include <compositionengine/impl/LayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070020#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080021#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070022#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070023#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070024#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080025#include <compositionengine/mock/Layer.h>
26#include <compositionengine/mock/LayerFE.h>
27#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 Pique56eba802019-08-28 15:45:25 -070030#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070031#include <ui/Rect.h>
32#include <ui/Region.h>
33
34#include "RegionMatcher.h"
35#include "TransformMatcher.h"
36
37namespace android::compositionengine {
38namespace {
39
Lloyd Pique56eba802019-08-28 15:45:25 -070040using testing::_;
Lloyd Pique31cb2942018-10-19 17:23:03 -070041using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070042using testing::ReturnRef;
43using testing::StrictMock;
44
Lloyd Pique56eba802019-08-28 15:45:25 -070045constexpr auto TR_IDENT = 0u;
46constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
47
Lloyd Pique3eb1b212019-03-07 21:15:40 -080048const mat4 kIdentity;
49const mat4 kNonIdentityHalf = mat4() * 0.5;
50const mat4 kNonIdentityQuarter = mat4() * 0.25;
51
Lloyd Pique66d68602019-02-13 14:23:31 -080052struct OutputTest : public testing::Test {
Lloyd Pique31cb2942018-10-19 17:23:03 -070053 OutputTest() {
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070054 mOutput.setDisplayColorProfileForTest(
55 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Pique31cb2942018-10-19 17:23:03 -070056 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -080057
58 mOutput.editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -070059 }
Lloyd Pique32cbe282018-10-19 13:09:22 -070060
Lloyd Piqueef958122019-02-05 18:00:12 -080061 static const Rect kDefaultDisplaySize;
62
Lloyd Pique32cbe282018-10-19 13:09:22 -070063 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070064 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -070065 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique32cbe282018-10-19 13:09:22 -070066 impl::Output mOutput{mCompositionEngine};
67};
68
Lloyd Piqueef958122019-02-05 18:00:12 -080069const Rect OutputTest::kDefaultDisplaySize{100, 200};
70
Lloyd Pique66d68602019-02-13 14:23:31 -080071/*
Lloyd Pique32cbe282018-10-19 13:09:22 -070072 * Basic construction
73 */
74
Lloyd Pique31cb2942018-10-19 17:23:03 -070075TEST_F(OutputTest, canInstantiateOutput) {
76 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070077 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -070078 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
79
80 EXPECT_TRUE(mOutput.isValid());
81
82 // If we take away the required components, it is no longer valid.
83 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
84
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070085 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
86
Lloyd Pique31cb2942018-10-19 17:23:03 -070087 EXPECT_FALSE(mOutput.isValid());
88}
Lloyd Pique32cbe282018-10-19 13:09:22 -070089
Lloyd Pique66d68602019-02-13 14:23:31 -080090/*
Lloyd Pique32cbe282018-10-19 13:09:22 -070091 * Output::setCompositionEnabled()
92 */
93
94TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Pique32cbe282018-10-19 13:09:22 -070095 mOutput.editState().isEnabled = true;
96
97 mOutput.setCompositionEnabled(true);
98
99 EXPECT_TRUE(mOutput.getState().isEnabled);
100 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
101}
102
103TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700104 mOutput.editState().isEnabled = false;
105
106 mOutput.setCompositionEnabled(true);
107
108 EXPECT_TRUE(mOutput.getState().isEnabled);
Lloyd Piqueef958122019-02-05 18:00:12 -0800109 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700110}
111
112TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700113 mOutput.editState().isEnabled = true;
114
115 mOutput.setCompositionEnabled(false);
116
117 EXPECT_FALSE(mOutput.getState().isEnabled);
Lloyd Piqueef958122019-02-05 18:00:12 -0800118 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700119}
120
Lloyd Pique66d68602019-02-13 14:23:31 -0800121/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700122 * Output::setProjection()
123 */
124
125TEST_F(OutputTest, setProjectionTriviallyWorks) {
126 const ui::Transform transform{ui::Transform::ROT_180};
127 const int32_t orientation = 123;
128 const Rect frame{1, 2, 3, 4};
129 const Rect viewport{5, 6, 7, 8};
130 const Rect scissor{9, 10, 11, 12};
131 const bool needsFiltering = true;
132
133 mOutput.setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
134
135 EXPECT_THAT(mOutput.getState().transform, TransformEq(transform));
136 EXPECT_EQ(orientation, mOutput.getState().orientation);
137 EXPECT_EQ(frame, mOutput.getState().frame);
138 EXPECT_EQ(viewport, mOutput.getState().viewport);
139 EXPECT_EQ(scissor, mOutput.getState().scissor);
140 EXPECT_EQ(needsFiltering, mOutput.getState().needsFiltering);
141}
142
Lloyd Pique66d68602019-02-13 14:23:31 -0800143/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700144 * Output::setBounds()
145 */
146
147TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800148 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700149
150 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
151 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
152
Lloyd Pique32cbe282018-10-19 13:09:22 -0700153 mOutput.setBounds(displaySize);
154
Lloyd Pique31cb2942018-10-19 17:23:03 -0700155 EXPECT_EQ(Rect(displaySize), mOutput.getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156
Lloyd Pique31cb2942018-10-19 17:23:03 -0700157 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700158}
159
Lloyd Pique66d68602019-02-13 14:23:31 -0800160/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700161 * Output::setLayerStackFilter()
162 */
163
164TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700165 const uint32_t layerStack = 123u;
Lloyd Piqueef36b002019-01-23 17:52:04 -0800166 mOutput.setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167
Lloyd Piqueef36b002019-01-23 17:52:04 -0800168 EXPECT_TRUE(mOutput.getState().layerStackInternal);
169 EXPECT_EQ(layerStack, mOutput.getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700170
Lloyd Piqueef958122019-02-05 18:00:12 -0800171 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172}
173
Lloyd Pique66d68602019-02-13 14:23:31 -0800174/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700175 * Output::setColorTransform
176 */
177
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800178TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
179 mOutput.editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700180
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800181 // If no colorTransformMatrix is set the update should be skipped.
182 CompositionRefreshArgs refreshArgs;
183 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700184
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800185 mOutput.setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700186
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800187 // The internal state should be unchanged
188 EXPECT_EQ(kIdentity, mOutput.getState().colorTransformMatrix);
189
190 // No dirty region should be set
Lloyd Piqueef958122019-02-05 18:00:12 -0800191 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800192}
Lloyd Piqueef958122019-02-05 18:00:12 -0800193
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800194TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
195 mOutput.editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700196
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800197 // Attempting to set the same colorTransformMatrix that is already set should
198 // also skip the update.
199 CompositionRefreshArgs refreshArgs;
200 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700201
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800202 mOutput.setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700203
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800204 // The internal state should be unchanged
205 EXPECT_EQ(kIdentity, mOutput.getState().colorTransformMatrix);
206
207 // No dirty region should be set
208 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
209}
210
211TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
212 mOutput.editState().colorTransformMatrix = kNonIdentityHalf;
213
214 // Setting a different colorTransformMatrix should perform the update.
215 CompositionRefreshArgs refreshArgs;
216 refreshArgs.colorTransformMatrix = kIdentity;
217
218 mOutput.setColorTransform(refreshArgs);
219
220 // The internal state should have been updated
221 EXPECT_EQ(kIdentity, mOutput.getState().colorTransformMatrix);
222
223 // The dirtyRegion should be set to the full display size
Lloyd Pique77f79a22019-04-29 15:55:40 -0700224 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800225}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700226
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800227TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
228 mOutput.editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700229
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800230 // Setting a different colorTransformMatrix should perform the update.
231 CompositionRefreshArgs refreshArgs;
232 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700233
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800234 mOutput.setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800235
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800236 // The internal state should have been updated
237 EXPECT_EQ(kNonIdentityHalf, mOutput.getState().colorTransformMatrix);
238
239 // The dirtyRegion should be set to the full display size
240 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
241}
242
243TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
244 mOutput.editState().colorTransformMatrix = kNonIdentityHalf;
245
246 // Setting a different colorTransformMatrix should perform the update.
247 CompositionRefreshArgs refreshArgs;
248 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
249
250 mOutput.setColorTransform(refreshArgs);
251
252 // The internal state should have been updated
253 EXPECT_EQ(kNonIdentityQuarter, mOutput.getState().colorTransformMatrix);
254
255 // The dirtyRegion should be set to the full display size
Lloyd Piqueef958122019-02-05 18:00:12 -0800256 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700257}
258
Lloyd Pique66d68602019-02-13 14:23:31 -0800259/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700260 * Output::setColorMode
261 */
262
Lloyd Piqueef958122019-02-05 18:00:12 -0800263TEST_F(OutputTest, setColorModeSetsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800264 using ColorProfile = Output::ColorProfile;
265
Lloyd Piquef5275482019-01-29 18:42:42 -0800266 EXPECT_CALL(*mDisplayColorProfile,
267 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
268 ui::Dataspace::UNKNOWN))
269 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800270 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700271
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800272 mOutput.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
273 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
274 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700275
Lloyd Piqueef958122019-02-05 18:00:12 -0800276 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput.getState().colorMode);
277 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput.getState().dataspace);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700278 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput.getState().renderIntent);
Lloyd Piquef5275482019-01-29 18:42:42 -0800279 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput.getState().targetDataspace);
280
Lloyd Piqueef958122019-02-05 18:00:12 -0800281 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
282}
283
284TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800285 using ColorProfile = Output::ColorProfile;
286
Lloyd Piquef5275482019-01-29 18:42:42 -0800287 EXPECT_CALL(*mDisplayColorProfile,
288 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
289 ui::Dataspace::UNKNOWN))
290 .WillOnce(Return(ui::Dataspace::UNKNOWN));
291
Lloyd Piqueef958122019-02-05 18:00:12 -0800292 mOutput.editState().colorMode = ui::ColorMode::DISPLAY_P3;
293 mOutput.editState().dataspace = ui::Dataspace::DISPLAY_P3;
294 mOutput.editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
Lloyd Piquef5275482019-01-29 18:42:42 -0800295 mOutput.editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800296
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800297 mOutput.setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
298 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
299 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800300
301 EXPECT_THAT(mOutput.getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700302}
303
Lloyd Pique66d68602019-02-13 14:23:31 -0800304/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700305 * Output::setRenderSurface()
306 */
307
308TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
309 const ui::Size newDisplaySize{640, 480};
310
311 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
312 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
313
314 mOutput.setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
315
316 EXPECT_EQ(Rect(newDisplaySize), mOutput.getState().bounds);
317}
318
Lloyd Pique66d68602019-02-13 14:23:31 -0800319/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000320 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700321 */
322
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000323TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
324 const Rect viewport{100, 200};
325 mOutput.editState().viewport = viewport;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700326 mOutput.editState().dirtyRegion.set(50, 300);
327
328 {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000329 Region result = mOutput.getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700330
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000331 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700332 }
333}
334
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000335TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
336 const Rect viewport{100, 200};
337 mOutput.editState().viewport = viewport;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700338 mOutput.editState().dirtyRegion.set(50, 300);
339
340 {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000341 Region result = mOutput.getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700342
343 // The dirtyRegion should be clipped to the display bounds.
344 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
345 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700346}
347
Lloyd Pique66d68602019-02-13 14:23:31 -0800348/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800349 * Output::belongsInOutput()
350 */
351
352TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
353 const uint32_t layerStack1 = 123u;
354 const uint32_t layerStack2 = 456u;
355
356 // If the output accepts layerStack1 and internal-only layers....
357 mOutput.setLayerStackFilter(layerStack1, true);
358
Lloyd Piquec6687342019-03-07 21:34:57 -0800359 // A layer with no layerStack does not belong to it, internal-only or not.
360 EXPECT_FALSE(mOutput.belongsInOutput(std::nullopt, false));
361 EXPECT_FALSE(mOutput.belongsInOutput(std::nullopt, true));
362
Lloyd Piqueef36b002019-01-23 17:52:04 -0800363 // Any layer with layerStack1 belongs to it, internal-only or not.
364 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
365 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, true));
366 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
367 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
368
369 // If the output accepts layerStack21 but not internal-only layers...
370 mOutput.setLayerStackFilter(layerStack1, false);
371
372 // Only non-internal layers with layerStack1 belong to it.
373 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
374 EXPECT_FALSE(mOutput.belongsInOutput(layerStack1, true));
375 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
376 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
377}
378
Lloyd Pique66d68602019-02-13 14:23:31 -0800379/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800380 * Output::getOutputLayerForLayer()
381 */
382
383TEST_F(OutputTest, getOutputLayerForLayerWorks) {
384 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
385 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
386
387 Output::OutputLayers outputLayers;
388 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer1));
389 outputLayers.emplace_back(nullptr);
390 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer2));
391 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
392
393 StrictMock<mock::Layer> layer;
394 StrictMock<mock::Layer> otherLayer;
395
396 // If the input layer matches the first OutputLayer, it will be returned.
397 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
398 EXPECT_EQ(outputLayer1, mOutput.getOutputLayerForLayer(&layer));
399
400 // If the input layer matches the second OutputLayer, it will be returned.
401 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
402 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
403 EXPECT_EQ(outputLayer2, mOutput.getOutputLayerForLayer(&layer));
404
405 // If the input layer does not match an output layer, null will be returned.
406 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
407 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
408 EXPECT_EQ(nullptr, mOutput.getOutputLayerForLayer(&layer));
409}
410
Lloyd Pique66d68602019-02-13 14:23:31 -0800411/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800412 * Output::getOrCreateOutputLayer()
413 */
414
415TEST_F(OutputTest, getOrCreateOutputLayerWorks) {
416 mock::OutputLayer* existingOutputLayer = new StrictMock<mock::OutputLayer>();
417
418 Output::OutputLayers outputLayers;
419 outputLayers.emplace_back(nullptr);
420 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(existingOutputLayer));
421 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
422
423 std::shared_ptr<mock::Layer> layer{new StrictMock<mock::Layer>()};
424 sp<LayerFE> layerFE{new StrictMock<mock::LayerFE>()};
425
426 StrictMock<mock::Layer> otherLayer;
427
428 {
429 // If there is no OutputLayer corresponding to the input layer, a
430 // new OutputLayer is constructed and returned.
431 EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Pique07e33212018-12-18 16:33:37 -0800432 auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800433 EXPECT_NE(existingOutputLayer, result.get());
434 EXPECT_TRUE(result.get() != nullptr);
435 EXPECT_EQ(layer.get(), &result->getLayer());
436 EXPECT_EQ(layerFE.get(), &result->getLayerFE());
437
438 // The entries in the ordered array should be unchanged.
439 auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
440 EXPECT_EQ(nullptr, outputLayers[0].get());
441 EXPECT_EQ(existingOutputLayer, outputLayers[1].get());
442 }
443
444 {
445 // If there is an existing OutputLayer for the requested layer, an owned
446 // pointer is returned
447 EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(*layer));
Lloyd Pique07e33212018-12-18 16:33:37 -0800448 auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800449 EXPECT_EQ(existingOutputLayer, result.get());
450
451 // The corresponding entry in the ordered array should be cleared.
452 auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
453 EXPECT_EQ(nullptr, outputLayers[0].get());
454 EXPECT_EQ(nullptr, outputLayers[1].get());
455 }
456}
457
Lloyd Pique66d68602019-02-13 14:23:31 -0800458/*
459 * Output::prepareFrame()
460 */
461
462struct OutputPrepareFrameTest : public testing::Test {
463 struct OutputPartialMock : public impl::Output {
464 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
465 : impl::Output(compositionEngine) {}
466
467 // Sets up the helper functions called by prepareFrame to use a mock
468 // implementations.
469 MOCK_METHOD0(chooseCompositionStrategy, void());
470 };
471
472 OutputPrepareFrameTest() {
473 mOutput.setDisplayColorProfileForTest(
474 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
475 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
476 }
477
478 StrictMock<mock::CompositionEngine> mCompositionEngine;
479 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
480 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
481 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
482};
483
484TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
485 mOutput.editState().isEnabled = false;
486
487 mOutput.prepareFrame();
488}
489
490TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
491 mOutput.editState().isEnabled = true;
492 mOutput.editState().usesClientComposition = false;
493 mOutput.editState().usesDeviceComposition = true;
494
495 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
496 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
497
498 mOutput.prepareFrame();
499}
500
501// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
502// base chooseCompositionStrategy() is invoked.
503TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
504 mOutput.editState().isEnabled = true;
505 mOutput.editState().usesClientComposition = false;
506 mOutput.editState().usesDeviceComposition = true;
507
508 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
509
510 mOutput.prepareFrame();
511
512 EXPECT_TRUE(mOutput.getState().usesClientComposition);
513 EXPECT_FALSE(mOutput.getState().usesDeviceComposition);
514}
515
Lloyd Pique56eba802019-08-28 15:45:25 -0700516/*
517 * Output::composeSurfaces()
518 */
519
520struct OutputComposeSurfacesTest : public testing::Test {
521 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
522 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
523
524 static const Rect kDefaultOutputFrame;
525 static const Rect kDefaultOutputViewport;
526 static const Rect kDefaultOutputScissor;
527 static const mat4 kDefaultColorTransformMat;
528
529 struct OutputPartialMock : public impl::Output {
530 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
531 : impl::Output(compositionEngine) {}
532
533 // Sets up the helper functions called by composeSurfaces to use a mock
534 // implementations.
535 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
536 MOCK_METHOD2(generateClientCompositionRequests,
537 std::vector<renderengine::LayerSettings>(bool, Region&));
538 MOCK_METHOD2(appendRegionFlashRequests,
539 void(const Region&, std::vector<renderengine::LayerSettings>&));
540 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
541 };
542
543 OutputComposeSurfacesTest() {
544 mOutput.setDisplayColorProfileForTest(
545 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
546 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
547
548 Output::OutputLayers outputLayers;
549 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(mOutputLayer1));
550 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(mOutputLayer2));
551 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
552
553 mOutput.editState().frame = kDefaultOutputFrame;
554 mOutput.editState().viewport = kDefaultOutputViewport;
555 mOutput.editState().scissor = kDefaultOutputScissor;
556 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
557 mOutput.editState().orientation = kDefaultOutputOrientation;
558 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800559 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700560 mOutput.editState().isSecure = true;
561 mOutput.editState().needsFiltering = false;
562 mOutput.editState().usesClientComposition = true;
563 mOutput.editState().usesDeviceComposition = false;
564
565 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
566 }
567
568 StrictMock<mock::CompositionEngine> mCompositionEngine;
569 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
570 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
571 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
572 mock::OutputLayer* mOutputLayer1 = new StrictMock<mock::OutputLayer>();
573 mock::OutputLayer* mOutputLayer2 = new StrictMock<mock::OutputLayer>();
574 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
575 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
576};
577
578const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
579const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
580const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
581const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
582
583// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
584// basic tests.
585
586TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
587 mOutput.editState().usesClientComposition = false;
588
589 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800590 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
591 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700592}
593
594TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
595 const Region kDebugRegion{Rect{100, 101, 102, 103}};
596
597 constexpr float kDefaultMaxLuminance = 1.0f;
598 constexpr float kDefaultAvgLuminance = 0.7f;
599 constexpr float kDefaultMinLuminance = 0.1f;
600 HdrCapabilities HdrCapabilities{{},
601 kDefaultMaxLuminance,
602 kDefaultAvgLuminance,
603 kDefaultMinLuminance};
604
605 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
606 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
607
608 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
609 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
610
611 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
612
613 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
614 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
615 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
616 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
617 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
618
Lloyd Piqued3d69882019-02-28 16:03:46 -0800619 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
620 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700621}
622
623/*
624 * Output::generateClientCompositionRequests()
625 */
626
627struct GenerateClientCompositionRequestsTest : public testing::Test {
628 struct OutputPartialMock : public impl::Output {
629 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
630 : impl::Output(compositionEngine) {}
631
632 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
633 bool supportsProtectedContent, Region& clearRegion) override {
634 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
635 clearRegion);
636 }
637 };
638
639 GenerateClientCompositionRequestsTest() {
640 mOutput.setDisplayColorProfileForTest(
641 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
642 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
643 }
644
645 StrictMock<mock::CompositionEngine> mCompositionEngine;
646 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
647 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
648 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
649};
650
651// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
652
653TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
654 // In split-screen landscape mode, the screen is rotated 90 degrees, with
655 // one layer on the left covering the left side of the output, and one layer
656 // on the right covering that side of the output.
657
658 mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>();
659 mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>();
660
661 StrictMock<mock::Layer> leftLayer;
662 StrictMock<mock::LayerFE> leftLayerFE;
663 StrictMock<mock::Layer> rightLayer;
664 StrictMock<mock::LayerFE> rightLayerFE;
665
666 impl::OutputLayerCompositionState leftOutputLayerState;
667 leftOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800668 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700669
670 impl::LayerCompositionState leftLayerState;
Lloyd Pique56eba802019-08-28 15:45:25 -0700671 leftLayerState.frontEnd.isOpaque = true;
672
673 const half3 leftLayerColor{1.f, 0.f, 0.f};
674 renderengine::LayerSettings leftLayerRESettings;
675 leftLayerRESettings.source.solidColor = leftLayerColor;
676
677 impl::OutputLayerCompositionState rightOutputLayerState;
678 rightOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800679 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700680
681 impl::LayerCompositionState rightLayerState;
Lloyd Pique56eba802019-08-28 15:45:25 -0700682 rightLayerState.frontEnd.isOpaque = true;
683
684 const half3 rightLayerColor{0.f, 1.f, 0.f};
685 renderengine::LayerSettings rightLayerRESettings;
686 rightLayerRESettings.source.solidColor = rightLayerColor;
687
688 EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
689 EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
690 EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
691 EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
692 EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
693 EXPECT_CALL(leftLayer, getState()).WillRepeatedly(ReturnRef(leftLayerState));
694 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
695
696 EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
697 EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
698 EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
699 EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
700 EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
701 EXPECT_CALL(rightLayer, getState()).WillRepeatedly(ReturnRef(rightLayerState));
702 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
703
704 Output::OutputLayers outputLayers;
705 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer));
706 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer));
707 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
708
709 const Rect kPortraitFrame(0, 0, 1000, 2000);
710 const Rect kPortraitViewport(0, 0, 2000, 1000);
711 const Rect kPortraitScissor(0, 0, 1000, 2000);
712 const uint32_t kPortraitOrientation = TR_ROT_90;
713
714 mOutput.editState().frame = kPortraitFrame;
715 mOutput.editState().viewport = kPortraitViewport;
716 mOutput.editState().scissor = kPortraitScissor;
717 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
718 mOutput.editState().orientation = kPortraitOrientation;
719 mOutput.editState().needsFiltering = true;
720 mOutput.editState().isSecure = false;
721
722 constexpr bool supportsProtectedContent = false;
723 Region clearRegion;
724 auto requests =
725 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
726
727 ASSERT_EQ(2u, requests.size());
728 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
729 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
730}
731
732TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
733 // Layers whose visible region does not intersect with the viewport will be
734 // skipped when generating client composition request state.
735
736 mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>();
737 StrictMock<mock::Layer> layer;
738 StrictMock<mock::LayerFE> layerFE;
739
740 impl::OutputLayerCompositionState outputLayerState;
741 outputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800742 outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700743
744 impl::LayerCompositionState layerState;
Lloyd Pique56eba802019-08-28 15:45:25 -0700745 layerState.frontEnd.isOpaque = true;
746
747 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
748 EXPECT_CALL(*outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
749 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
750 EXPECT_CALL(*outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
751 EXPECT_CALL(*outputLayer, needsFiltering()).WillRepeatedly(Return(false));
752 EXPECT_CALL(layer, getState()).WillRepeatedly(ReturnRef(layerState));
753 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
754
755 Output::OutputLayers outputLayers;
756 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer));
757 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
758
759 const Rect kPortraitFrame(0, 0, 1000, 2000);
760 const Rect kPortraitViewport(0, 0, 2000, 1000);
761 const Rect kPortraitScissor(0, 0, 1000, 2000);
762 const uint32_t kPortraitOrientation = TR_ROT_90;
763
764 mOutput.editState().frame = kPortraitFrame;
765 mOutput.editState().viewport = kPortraitViewport;
766 mOutput.editState().scissor = kPortraitScissor;
767 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
768 mOutput.editState().orientation = kPortraitOrientation;
769 mOutput.editState().needsFiltering = true;
770 mOutput.editState().isSecure = false;
771
772 constexpr bool supportsProtectedContent = false;
773 Region clearRegion;
774 auto requests =
775 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
776
777 EXPECT_EQ(0u, requests.size());
778}
779
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700780TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
781 // If client composition is performed with some layers set to use device
782 // composition, device layers after the first layer (device or client) will
783 // clear the frame buffer if they are opaque and if that layer has a flag
784 // set to do so. The first layer is skipped as the frame buffer is already
785 // expected to be clear.
786
787 mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>();
788 mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>();
789
790 StrictMock<mock::Layer> leftLayer;
791 StrictMock<mock::LayerFE> leftLayerFE;
792 StrictMock<mock::Layer> rightLayer;
793 StrictMock<mock::LayerFE> rightLayerFE;
794
795 impl::OutputLayerCompositionState leftOutputLayerState;
796 leftOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -0800797 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700798
799 impl::LayerCompositionState leftLayerState;
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700800 leftLayerState.frontEnd.isOpaque = true;
801
802 impl::OutputLayerCompositionState rightOutputLayerState;
803 rightOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -0800804 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700805
806 impl::LayerCompositionState rightLayerState;
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700807 rightLayerState.frontEnd.isOpaque = true;
808
809 const half3 rightLayerColor{0.f, 1.f, 0.f};
810 renderengine::LayerSettings rightLayerRESettings;
811 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
812 rightLayerRESettings.source.solidColor = rightLayerColor;
813
814 EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
815 EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
816 EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
817 EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
818 EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
819 EXPECT_CALL(leftLayer, getState()).WillRepeatedly(ReturnRef(leftLayerState));
820
821 EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
822 EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
823 EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
824 EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
825 EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
826 EXPECT_CALL(rightLayer, getState()).WillRepeatedly(ReturnRef(rightLayerState));
827 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
828
829 Output::OutputLayers outputLayers;
830 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer));
831 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer));
832 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
833
834 const Rect kPortraitFrame(0, 0, 1000, 2000);
835 const Rect kPortraitViewport(0, 0, 2000, 1000);
836 const Rect kPortraitScissor(0, 0, 1000, 2000);
837 const uint32_t kPortraitOrientation = TR_ROT_90;
838
839 mOutput.editState().frame = kPortraitFrame;
840 mOutput.editState().viewport = kPortraitViewport;
841 mOutput.editState().scissor = kPortraitScissor;
842 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
843 mOutput.editState().orientation = kPortraitOrientation;
844 mOutput.editState().needsFiltering = true;
845 mOutput.editState().isSecure = false;
846
847 constexpr bool supportsProtectedContent = false;
848 Region clearRegion;
849 auto requests =
850 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
851
852 const half3 clearColor{0.f, 0.f, 0.f};
853
854 ASSERT_EQ(1u, requests.size());
855 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
856 EXPECT_EQ(clearColor, requests[0].source.solidColor);
857}
858
Lloyd Pique32cbe282018-10-19 13:09:22 -0700859} // namespace
860} // namespace android::compositionengine