blob: 1d5f2f0d54f89211d385851faa1b97fca484fad7 [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
359 // Any layer with layerStack1 belongs to it, internal-only or not.
360 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
361 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, true));
362 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
363 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
364
365 // If the output accepts layerStack21 but not internal-only layers...
366 mOutput.setLayerStackFilter(layerStack1, false);
367
368 // Only non-internal layers with layerStack1 belong to it.
369 EXPECT_TRUE(mOutput.belongsInOutput(layerStack1, false));
370 EXPECT_FALSE(mOutput.belongsInOutput(layerStack1, true));
371 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, true));
372 EXPECT_FALSE(mOutput.belongsInOutput(layerStack2, false));
373}
374
Lloyd Pique66d68602019-02-13 14:23:31 -0800375/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800376 * Output::getOutputLayerForLayer()
377 */
378
379TEST_F(OutputTest, getOutputLayerForLayerWorks) {
380 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
381 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
382
383 Output::OutputLayers outputLayers;
384 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer1));
385 outputLayers.emplace_back(nullptr);
386 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer2));
387 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
388
389 StrictMock<mock::Layer> layer;
390 StrictMock<mock::Layer> otherLayer;
391
392 // If the input layer matches the first OutputLayer, it will be returned.
393 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
394 EXPECT_EQ(outputLayer1, mOutput.getOutputLayerForLayer(&layer));
395
396 // If the input layer matches the second OutputLayer, it will be returned.
397 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
398 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
399 EXPECT_EQ(outputLayer2, mOutput.getOutputLayerForLayer(&layer));
400
401 // If the input layer does not match an output layer, null will be returned.
402 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
403 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
404 EXPECT_EQ(nullptr, mOutput.getOutputLayerForLayer(&layer));
405}
406
Lloyd Pique66d68602019-02-13 14:23:31 -0800407/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800408 * Output::getOrCreateOutputLayer()
409 */
410
411TEST_F(OutputTest, getOrCreateOutputLayerWorks) {
412 mock::OutputLayer* existingOutputLayer = new StrictMock<mock::OutputLayer>();
413
414 Output::OutputLayers outputLayers;
415 outputLayers.emplace_back(nullptr);
416 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(existingOutputLayer));
417 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
418
419 std::shared_ptr<mock::Layer> layer{new StrictMock<mock::Layer>()};
420 sp<LayerFE> layerFE{new StrictMock<mock::LayerFE>()};
421
422 StrictMock<mock::Layer> otherLayer;
423
424 {
425 // If there is no OutputLayer corresponding to the input layer, a
426 // new OutputLayer is constructed and returned.
427 EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Pique07e33212018-12-18 16:33:37 -0800428 auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800429 EXPECT_NE(existingOutputLayer, result.get());
430 EXPECT_TRUE(result.get() != nullptr);
431 EXPECT_EQ(layer.get(), &result->getLayer());
432 EXPECT_EQ(layerFE.get(), &result->getLayerFE());
433
434 // The entries in the ordered array should be unchanged.
435 auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
436 EXPECT_EQ(nullptr, outputLayers[0].get());
437 EXPECT_EQ(existingOutputLayer, outputLayers[1].get());
438 }
439
440 {
441 // If there is an existing OutputLayer for the requested layer, an owned
442 // pointer is returned
443 EXPECT_CALL(*existingOutputLayer, getLayer()).WillOnce(ReturnRef(*layer));
Lloyd Pique07e33212018-12-18 16:33:37 -0800444 auto result = mOutput.getOrCreateOutputLayer(std::nullopt, layer, layerFE);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800445 EXPECT_EQ(existingOutputLayer, result.get());
446
447 // The corresponding entry in the ordered array should be cleared.
448 auto& outputLayers = mOutput.getOutputLayersOrderedByZ();
449 EXPECT_EQ(nullptr, outputLayers[0].get());
450 EXPECT_EQ(nullptr, outputLayers[1].get());
451 }
452}
453
Lloyd Pique66d68602019-02-13 14:23:31 -0800454/*
455 * Output::prepareFrame()
456 */
457
458struct OutputPrepareFrameTest : public testing::Test {
459 struct OutputPartialMock : public impl::Output {
460 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
461 : impl::Output(compositionEngine) {}
462
463 // Sets up the helper functions called by prepareFrame to use a mock
464 // implementations.
465 MOCK_METHOD0(chooseCompositionStrategy, void());
466 };
467
468 OutputPrepareFrameTest() {
469 mOutput.setDisplayColorProfileForTest(
470 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
471 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
472 }
473
474 StrictMock<mock::CompositionEngine> mCompositionEngine;
475 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
476 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
477 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
478};
479
480TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
481 mOutput.editState().isEnabled = false;
482
483 mOutput.prepareFrame();
484}
485
486TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
487 mOutput.editState().isEnabled = true;
488 mOutput.editState().usesClientComposition = false;
489 mOutput.editState().usesDeviceComposition = true;
490
491 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
492 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
493
494 mOutput.prepareFrame();
495}
496
497// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
498// base chooseCompositionStrategy() is invoked.
499TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
500 mOutput.editState().isEnabled = true;
501 mOutput.editState().usesClientComposition = false;
502 mOutput.editState().usesDeviceComposition = true;
503
504 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
505
506 mOutput.prepareFrame();
507
508 EXPECT_TRUE(mOutput.getState().usesClientComposition);
509 EXPECT_FALSE(mOutput.getState().usesDeviceComposition);
510}
511
Lloyd Pique56eba802019-08-28 15:45:25 -0700512/*
513 * Output::composeSurfaces()
514 */
515
516struct OutputComposeSurfacesTest : public testing::Test {
517 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
518 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
519
520 static const Rect kDefaultOutputFrame;
521 static const Rect kDefaultOutputViewport;
522 static const Rect kDefaultOutputScissor;
523 static const mat4 kDefaultColorTransformMat;
524
525 struct OutputPartialMock : public impl::Output {
526 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
527 : impl::Output(compositionEngine) {}
528
529 // Sets up the helper functions called by composeSurfaces to use a mock
530 // implementations.
531 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
532 MOCK_METHOD2(generateClientCompositionRequests,
533 std::vector<renderengine::LayerSettings>(bool, Region&));
534 MOCK_METHOD2(appendRegionFlashRequests,
535 void(const Region&, std::vector<renderengine::LayerSettings>&));
536 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
537 };
538
539 OutputComposeSurfacesTest() {
540 mOutput.setDisplayColorProfileForTest(
541 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
542 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
543
544 Output::OutputLayers outputLayers;
545 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(mOutputLayer1));
546 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(mOutputLayer2));
547 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
548
549 mOutput.editState().frame = kDefaultOutputFrame;
550 mOutput.editState().viewport = kDefaultOutputViewport;
551 mOutput.editState().scissor = kDefaultOutputScissor;
552 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
553 mOutput.editState().orientation = kDefaultOutputOrientation;
554 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800555 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700556 mOutput.editState().isSecure = true;
557 mOutput.editState().needsFiltering = false;
558 mOutput.editState().usesClientComposition = true;
559 mOutput.editState().usesDeviceComposition = false;
560
561 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
562 }
563
564 StrictMock<mock::CompositionEngine> mCompositionEngine;
565 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
566 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
567 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
568 mock::OutputLayer* mOutputLayer1 = new StrictMock<mock::OutputLayer>();
569 mock::OutputLayer* mOutputLayer2 = new StrictMock<mock::OutputLayer>();
570 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
571 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
572};
573
574const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
575const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
576const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
577const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
578
579// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
580// basic tests.
581
582TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
583 mOutput.editState().usesClientComposition = false;
584
585 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800586 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
587 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700588}
589
590TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
591 const Region kDebugRegion{Rect{100, 101, 102, 103}};
592
593 constexpr float kDefaultMaxLuminance = 1.0f;
594 constexpr float kDefaultAvgLuminance = 0.7f;
595 constexpr float kDefaultMinLuminance = 0.1f;
596 HdrCapabilities HdrCapabilities{{},
597 kDefaultMaxLuminance,
598 kDefaultAvgLuminance,
599 kDefaultMinLuminance};
600
601 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
602 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
603
604 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
605 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
606
607 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
608
609 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
610 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
611 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
612 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
613 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
614
Lloyd Piqued3d69882019-02-28 16:03:46 -0800615 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
616 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700617}
618
619/*
620 * Output::generateClientCompositionRequests()
621 */
622
623struct GenerateClientCompositionRequestsTest : public testing::Test {
624 struct OutputPartialMock : public impl::Output {
625 OutputPartialMock(const compositionengine::CompositionEngine& compositionEngine)
626 : impl::Output(compositionEngine) {}
627
628 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
629 bool supportsProtectedContent, Region& clearRegion) override {
630 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
631 clearRegion);
632 }
633 };
634
635 GenerateClientCompositionRequestsTest() {
636 mOutput.setDisplayColorProfileForTest(
637 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
638 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
639 }
640
641 StrictMock<mock::CompositionEngine> mCompositionEngine;
642 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
643 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
644 StrictMock<OutputPartialMock> mOutput{mCompositionEngine};
645};
646
647// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
648
649TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
650 // In split-screen landscape mode, the screen is rotated 90 degrees, with
651 // one layer on the left covering the left side of the output, and one layer
652 // on the right covering that side of the output.
653
654 mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>();
655 mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>();
656
657 StrictMock<mock::Layer> leftLayer;
658 StrictMock<mock::LayerFE> leftLayerFE;
659 StrictMock<mock::Layer> rightLayer;
660 StrictMock<mock::LayerFE> rightLayerFE;
661
662 impl::OutputLayerCompositionState leftOutputLayerState;
663 leftOutputLayerState.clearClientTarget = false;
664
665 impl::LayerCompositionState leftLayerState;
666 leftLayerState.frontEnd.geomVisibleRegion = Region{Rect{0, 0, 1000, 1000}};
667 leftLayerState.frontEnd.isOpaque = true;
668
669 const half3 leftLayerColor{1.f, 0.f, 0.f};
670 renderengine::LayerSettings leftLayerRESettings;
671 leftLayerRESettings.source.solidColor = leftLayerColor;
672
673 impl::OutputLayerCompositionState rightOutputLayerState;
674 rightOutputLayerState.clearClientTarget = false;
675
676 impl::LayerCompositionState rightLayerState;
677 rightLayerState.frontEnd.geomVisibleRegion = Region{Rect{1000, 0, 2000, 1000}};
678 rightLayerState.frontEnd.isOpaque = true;
679
680 const half3 rightLayerColor{0.f, 1.f, 0.f};
681 renderengine::LayerSettings rightLayerRESettings;
682 rightLayerRESettings.source.solidColor = rightLayerColor;
683
684 EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
685 EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
686 EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
687 EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
688 EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
689 EXPECT_CALL(leftLayer, getState()).WillRepeatedly(ReturnRef(leftLayerState));
690 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
691
692 EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
693 EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
694 EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
695 EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
696 EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
697 EXPECT_CALL(rightLayer, getState()).WillRepeatedly(ReturnRef(rightLayerState));
698 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
699
700 Output::OutputLayers outputLayers;
701 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer));
702 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer));
703 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
704
705 const Rect kPortraitFrame(0, 0, 1000, 2000);
706 const Rect kPortraitViewport(0, 0, 2000, 1000);
707 const Rect kPortraitScissor(0, 0, 1000, 2000);
708 const uint32_t kPortraitOrientation = TR_ROT_90;
709
710 mOutput.editState().frame = kPortraitFrame;
711 mOutput.editState().viewport = kPortraitViewport;
712 mOutput.editState().scissor = kPortraitScissor;
713 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
714 mOutput.editState().orientation = kPortraitOrientation;
715 mOutput.editState().needsFiltering = true;
716 mOutput.editState().isSecure = false;
717
718 constexpr bool supportsProtectedContent = false;
719 Region clearRegion;
720 auto requests =
721 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
722
723 ASSERT_EQ(2u, requests.size());
724 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
725 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
726}
727
728TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
729 // Layers whose visible region does not intersect with the viewport will be
730 // skipped when generating client composition request state.
731
732 mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>();
733 StrictMock<mock::Layer> layer;
734 StrictMock<mock::LayerFE> layerFE;
735
736 impl::OutputLayerCompositionState outputLayerState;
737 outputLayerState.clearClientTarget = false;
738
739 impl::LayerCompositionState layerState;
740 layerState.frontEnd.geomVisibleRegion = Region{Rect{3000, 0, 4000, 1000}};
741 layerState.frontEnd.isOpaque = true;
742
743 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
744 EXPECT_CALL(*outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
745 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
746 EXPECT_CALL(*outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
747 EXPECT_CALL(*outputLayer, needsFiltering()).WillRepeatedly(Return(false));
748 EXPECT_CALL(layer, getState()).WillRepeatedly(ReturnRef(layerState));
749 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
750
751 Output::OutputLayers outputLayers;
752 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(outputLayer));
753 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
754
755 const Rect kPortraitFrame(0, 0, 1000, 2000);
756 const Rect kPortraitViewport(0, 0, 2000, 1000);
757 const Rect kPortraitScissor(0, 0, 1000, 2000);
758 const uint32_t kPortraitOrientation = TR_ROT_90;
759
760 mOutput.editState().frame = kPortraitFrame;
761 mOutput.editState().viewport = kPortraitViewport;
762 mOutput.editState().scissor = kPortraitScissor;
763 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
764 mOutput.editState().orientation = kPortraitOrientation;
765 mOutput.editState().needsFiltering = true;
766 mOutput.editState().isSecure = false;
767
768 constexpr bool supportsProtectedContent = false;
769 Region clearRegion;
770 auto requests =
771 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
772
773 EXPECT_EQ(0u, requests.size());
774}
775
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700776TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
777 // If client composition is performed with some layers set to use device
778 // composition, device layers after the first layer (device or client) will
779 // clear the frame buffer if they are opaque and if that layer has a flag
780 // set to do so. The first layer is skipped as the frame buffer is already
781 // expected to be clear.
782
783 mock::OutputLayer* leftOutputLayer = new StrictMock<mock::OutputLayer>();
784 mock::OutputLayer* rightOutputLayer = new StrictMock<mock::OutputLayer>();
785
786 StrictMock<mock::Layer> leftLayer;
787 StrictMock<mock::LayerFE> leftLayerFE;
788 StrictMock<mock::Layer> rightLayer;
789 StrictMock<mock::LayerFE> rightLayerFE;
790
791 impl::OutputLayerCompositionState leftOutputLayerState;
792 leftOutputLayerState.clearClientTarget = true;
793
794 impl::LayerCompositionState leftLayerState;
795 leftLayerState.frontEnd.geomVisibleRegion = Region{Rect{0, 0, 1000, 1000}};
796 leftLayerState.frontEnd.isOpaque = true;
797
798 impl::OutputLayerCompositionState rightOutputLayerState;
799 rightOutputLayerState.clearClientTarget = true;
800
801 impl::LayerCompositionState rightLayerState;
802 rightLayerState.frontEnd.geomVisibleRegion = Region{Rect{1000, 0, 2000, 1000}};
803 rightLayerState.frontEnd.isOpaque = true;
804
805 const half3 rightLayerColor{0.f, 1.f, 0.f};
806 renderengine::LayerSettings rightLayerRESettings;
807 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
808 rightLayerRESettings.source.solidColor = rightLayerColor;
809
810 EXPECT_CALL(*leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
811 EXPECT_CALL(*leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
812 EXPECT_CALL(*leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
813 EXPECT_CALL(*leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
814 EXPECT_CALL(*leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
815 EXPECT_CALL(leftLayer, getState()).WillRepeatedly(ReturnRef(leftLayerState));
816
817 EXPECT_CALL(*rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
818 EXPECT_CALL(*rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
819 EXPECT_CALL(*rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
820 EXPECT_CALL(*rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
821 EXPECT_CALL(*rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
822 EXPECT_CALL(rightLayer, getState()).WillRepeatedly(ReturnRef(rightLayerState));
823 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
824
825 Output::OutputLayers outputLayers;
826 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(leftOutputLayer));
827 outputLayers.emplace_back(std::unique_ptr<OutputLayer>(rightOutputLayer));
828 mOutput.setOutputLayersOrderedByZ(std::move(outputLayers));
829
830 const Rect kPortraitFrame(0, 0, 1000, 2000);
831 const Rect kPortraitViewport(0, 0, 2000, 1000);
832 const Rect kPortraitScissor(0, 0, 1000, 2000);
833 const uint32_t kPortraitOrientation = TR_ROT_90;
834
835 mOutput.editState().frame = kPortraitFrame;
836 mOutput.editState().viewport = kPortraitViewport;
837 mOutput.editState().scissor = kPortraitScissor;
838 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
839 mOutput.editState().orientation = kPortraitOrientation;
840 mOutput.editState().needsFiltering = true;
841 mOutput.editState().isSecure = false;
842
843 constexpr bool supportsProtectedContent = false;
844 Region clearRegion;
845 auto requests =
846 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
847
848 const half3 clearColor{0.f, 0.f, 0.f};
849
850 ASSERT_EQ(1u, requests.size());
851 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
852 EXPECT_EQ(clearColor, requests[0].source.solidColor);
853}
854
Lloyd Pique32cbe282018-10-19 13:09:22 -0700855} // namespace
856} // namespace android::compositionengine