blob: 15624167788020dd3b7f98280fa3e1e7b7144759 [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 Pique9755fb72019-03-26 14:44:40 -070019#include <compositionengine/LayerFECompositionState.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 Pique03561a62019-11-19 18:34:52 -080041using testing::ByMove;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080042using testing::InSequence;
43using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070044using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070045using testing::ReturnRef;
46using testing::StrictMock;
47
Lloyd Pique56eba802019-08-28 15:45:25 -070048constexpr auto TR_IDENT = 0u;
49constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
50
Lloyd Pique3eb1b212019-03-07 21:15:40 -080051const mat4 kIdentity;
52const mat4 kNonIdentityHalf = mat4() * 0.5;
53const mat4 kNonIdentityQuarter = mat4() * 0.25;
54
Lloyd Piquefaa3f192019-11-14 14:05:09 -080055struct OutputPartialMockBase : public impl::Output {
56 // compositionengine::Output overrides
57 const OutputCompositionState& getState() const override { return mState; }
58 OutputCompositionState& editState() override { return mState; }
59
60 // Use mocks for all the remaining virtual functions
61 // not implemented by the base implementation class.
62 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
63 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
64 MOCK_METHOD3(ensureOutputLayer,
65 compositionengine::OutputLayer*(std::optional<size_t>,
66 const std::shared_ptr<compositionengine::Layer>&,
67 const sp<LayerFE>&));
68 MOCK_METHOD0(finalizePendingOutputLayers, void());
69 MOCK_METHOD0(clearOutputLayers, void());
70 MOCK_CONST_METHOD1(dumpState, void(std::string&));
71 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
72 MOCK_METHOD2(injectOutputLayerForTest,
73 compositionengine::OutputLayer*(const std::shared_ptr<compositionengine::Layer>&,
74 const sp<LayerFE>&));
75 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
76
77 impl::OutputCompositionState mState;
78};
79
Lloyd Pique66d68602019-02-13 14:23:31 -080080struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -070081 class Output : public impl::Output {
82 public:
83 using impl::Output::injectOutputLayerForTest;
84 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
85 };
86
87 static std::shared_ptr<Output> createOutput(
88 const compositionengine::CompositionEngine& compositionEngine) {
89 return impl::createOutputTemplated<Output>(compositionEngine);
90 }
91
Lloyd Pique31cb2942018-10-19 17:23:03 -070092 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070093 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070094 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070095 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -080096
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070097 mOutput->editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -070098 }
Lloyd Pique32cbe282018-10-19 13:09:22 -070099
Lloyd Piqueef958122019-02-05 18:00:12 -0800100 static const Rect kDefaultDisplaySize;
101
Lloyd Pique32cbe282018-10-19 13:09:22 -0700102 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700103 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700104 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700105 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700106};
107
Lloyd Piqueef958122019-02-05 18:00:12 -0800108const Rect OutputTest::kDefaultDisplaySize{100, 200};
109
Lloyd Pique66d68602019-02-13 14:23:31 -0800110/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700111 * Basic construction
112 */
113
Lloyd Pique31cb2942018-10-19 17:23:03 -0700114TEST_F(OutputTest, canInstantiateOutput) {
115 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700116 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700117 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
118
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700119 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700120
121 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700122 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700123
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700124 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
125
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700126 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700127}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700128
Lloyd Pique66d68602019-02-13 14:23:31 -0800129/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700130 * Output::setCompositionEnabled()
131 */
132
133TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700134 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700135
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700136 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700137
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700138 EXPECT_TRUE(mOutput->getState().isEnabled);
139 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700140}
141
142TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700143 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700144
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700145 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700146
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700147 EXPECT_TRUE(mOutput->getState().isEnabled);
148 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700149}
150
151TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700152 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700153
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700154 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700155
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700156 EXPECT_FALSE(mOutput->getState().isEnabled);
157 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
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::setProjection()
162 */
163
164TEST_F(OutputTest, setProjectionTriviallyWorks) {
165 const ui::Transform transform{ui::Transform::ROT_180};
166 const int32_t orientation = 123;
167 const Rect frame{1, 2, 3, 4};
168 const Rect viewport{5, 6, 7, 8};
169 const Rect scissor{9, 10, 11, 12};
170 const bool needsFiltering = true;
171
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700172 mOutput->setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700173
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700174 EXPECT_THAT(mOutput->getState().transform, TransformEq(transform));
175 EXPECT_EQ(orientation, mOutput->getState().orientation);
176 EXPECT_EQ(frame, mOutput->getState().frame);
177 EXPECT_EQ(viewport, mOutput->getState().viewport);
178 EXPECT_EQ(scissor, mOutput->getState().scissor);
179 EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700180}
181
Lloyd Pique66d68602019-02-13 14:23:31 -0800182/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700183 * Output::setBounds()
184 */
185
186TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800187 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700188
189 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
190 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
191
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700192 mOutput->setBounds(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700193
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700194 EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700195
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700196 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700197}
198
Lloyd Pique66d68602019-02-13 14:23:31 -0800199/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700200 * Output::setLayerStackFilter()
201 */
202
203TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700204 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700205 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700206
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700207 EXPECT_TRUE(mOutput->getState().layerStackInternal);
208 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700209
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700211}
212
Lloyd Pique66d68602019-02-13 14:23:31 -0800213/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214 * Output::setColorTransform
215 */
216
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800217TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800220 // If no colorTransformMatrix is set the update should be skipped.
221 CompositionRefreshArgs refreshArgs;
222 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700225
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800226 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800228
229 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800231}
Lloyd Piqueef958122019-02-05 18:00:12 -0800232
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800233TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800236 // Attempting to set the same colorTransformMatrix that is already set should
237 // also skip the update.
238 CompositionRefreshArgs refreshArgs;
239 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700241 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700242
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800243 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800245
246 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700247 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800248}
249
250TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700251 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800252
253 // Setting a different colorTransformMatrix should perform the update.
254 CompositionRefreshArgs refreshArgs;
255 refreshArgs.colorTransformMatrix = kIdentity;
256
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700257 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800258
259 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700260 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800261
262 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700263 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800264}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700265
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800266TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700267 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700268
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800269 // Setting a different colorTransformMatrix should perform the update.
270 CompositionRefreshArgs refreshArgs;
271 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700272
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700273 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800274
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800275 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700276 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800277
278 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700279 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800280}
281
282TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700283 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800284
285 // Setting a different colorTransformMatrix should perform the update.
286 CompositionRefreshArgs refreshArgs;
287 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
288
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700289 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800290
291 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700292 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800293
294 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700295 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700296}
297
Lloyd Pique66d68602019-02-13 14:23:31 -0800298/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700299 * Output::setColorMode
300 */
301
Lloyd Piqueef958122019-02-05 18:00:12 -0800302TEST_F(OutputTest, setColorModeSetsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800303 using ColorProfile = Output::ColorProfile;
304
Lloyd Piquef5275482019-01-29 18:42:42 -0800305 EXPECT_CALL(*mDisplayColorProfile,
306 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
307 ui::Dataspace::UNKNOWN))
308 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800309 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700310
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700311 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
312 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
313 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700314
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700315 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
316 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
317 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
318 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800319
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700320 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800321}
322
323TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800324 using ColorProfile = Output::ColorProfile;
325
Lloyd Piquef5275482019-01-29 18:42:42 -0800326 EXPECT_CALL(*mDisplayColorProfile,
327 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
328 ui::Dataspace::UNKNOWN))
329 .WillOnce(Return(ui::Dataspace::UNKNOWN));
330
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700331 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
332 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
333 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
334 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800335
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700336 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
337 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
338 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800339
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700340 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700341}
342
Lloyd Pique66d68602019-02-13 14:23:31 -0800343/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700344 * Output::setRenderSurface()
345 */
346
347TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
348 const ui::Size newDisplaySize{640, 480};
349
350 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
351 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
352
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700353 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700354
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700355 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700356}
357
Lloyd Pique66d68602019-02-13 14:23:31 -0800358/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000359 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700360 */
361
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000362TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
363 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700364 mOutput->editState().viewport = viewport;
365 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700366
367 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700368 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700369
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000370 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700371 }
372}
373
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000374TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
375 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700376 mOutput->editState().viewport = viewport;
377 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700378
379 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700380 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700381
382 // The dirtyRegion should be clipped to the display bounds.
383 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
384 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700385}
386
Lloyd Pique66d68602019-02-13 14:23:31 -0800387/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800388 * Output::belongsInOutput()
389 */
390
391TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
392 const uint32_t layerStack1 = 123u;
393 const uint32_t layerStack2 = 456u;
394
395 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700396 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800397
Lloyd Piquec6687342019-03-07 21:34:57 -0800398 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700399 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
400 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800401
Lloyd Piqueef36b002019-01-23 17:52:04 -0800402 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700403 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
404 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
405 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
406 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800407
408 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700409 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800410
411 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700412 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
413 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
414 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
415 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800416}
417
Lloyd Pique66c20c42019-03-07 21:44:02 -0800418TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
419 StrictMock<mock::Layer> layer;
Lloyd Pique9755fb72019-03-26 14:44:40 -0700420 LayerFECompositionState layerFEState;
Lloyd Pique66c20c42019-03-07 21:44:02 -0800421
Lloyd Pique9755fb72019-03-26 14:44:40 -0700422 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800423
424 const uint32_t layerStack1 = 123u;
425 const uint32_t layerStack2 = 456u;
426
427 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700428 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800429
430 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700431 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800432
433 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700434 layerFEState.layerStackId = std::nullopt;
435 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700436 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800437
Lloyd Pique9755fb72019-03-26 14:44:40 -0700438 layerFEState.layerStackId = std::nullopt;
439 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700440 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800441
442 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700443 layerFEState.layerStackId = layerStack1;
444 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700445 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800446
Lloyd Pique9755fb72019-03-26 14:44:40 -0700447 layerFEState.layerStackId = layerStack1;
448 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800450
Lloyd Pique9755fb72019-03-26 14:44:40 -0700451 layerFEState.layerStackId = layerStack2;
452 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800454
Lloyd Pique9755fb72019-03-26 14:44:40 -0700455 layerFEState.layerStackId = layerStack2;
456 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800458
459 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800461
462 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800464
465 // Only non-internal layers with layerStack1 belong to it.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700466 layerFEState.layerStackId = layerStack1;
467 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700468 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800469
Lloyd Pique9755fb72019-03-26 14:44:40 -0700470 layerFEState.layerStackId = layerStack1;
471 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700472 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800473
Lloyd Pique9755fb72019-03-26 14:44:40 -0700474 layerFEState.layerStackId = layerStack2;
475 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800477
Lloyd Pique9755fb72019-03-26 14:44:40 -0700478 layerFEState.layerStackId = layerStack2;
479 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800481}
482
Lloyd Pique66d68602019-02-13 14:23:31 -0800483/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800484 * Output::getOutputLayerForLayer()
485 */
486
487TEST_F(OutputTest, getOutputLayerForLayerWorks) {
488 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
489 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
490
Lloyd Pique01c77c12019-04-17 12:48:32 -0700491 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer1));
492 mOutput->injectOutputLayerForTest(nullptr);
493 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer2));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800494
495 StrictMock<mock::Layer> layer;
496 StrictMock<mock::Layer> otherLayer;
497
498 // If the input layer matches the first OutputLayer, it will be returned.
499 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_EQ(outputLayer1, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800501
502 // If the input layer matches the second OutputLayer, it will be returned.
503 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
504 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700505 EXPECT_EQ(outputLayer2, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800506
507 // If the input layer does not match an output layer, null will be returned.
508 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
509 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700510 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800511}
512
Lloyd Pique66d68602019-02-13 14:23:31 -0800513/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800514 * Output::updateAndWriteCompositionState()
515 */
516
517TEST_F(OutputTest, updateAndWriteCompositionState_takesEarlyOutIfNotEnabled) {
518 mOutput->editState().isEnabled = false;
519
520 CompositionRefreshArgs args;
521 mOutput->updateAndWriteCompositionState(args);
522}
523
524TEST_F(OutputTest, updateAndWriteCompositionState_updatesLayers) {
525 mOutput->editState().isEnabled = true;
526 mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>();
527 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer));
528
529 EXPECT_CALL(*outputLayer, updateCompositionState(true, true)).Times(1);
530 EXPECT_CALL(*outputLayer, writeStateToHWC(true)).Times(1);
531
532 CompositionRefreshArgs args;
533 args.updatingGeometryThisFrame = true;
534 args.devOptForceClientComposition = true;
535 mOutput->updateAndWriteCompositionState(args);
536}
537
538/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800539 * Output::prepareFrame()
540 */
541
542struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800543 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique66d68602019-02-13 14:23:31 -0800544 // Sets up the helper functions called by prepareFrame to use a mock
545 // implementations.
546 MOCK_METHOD0(chooseCompositionStrategy, void());
547 };
548
549 OutputPrepareFrameTest() {
550 mOutput.setDisplayColorProfileForTest(
551 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
552 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
553 }
554
555 StrictMock<mock::CompositionEngine> mCompositionEngine;
556 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
557 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800559};
560
561TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
562 mOutput.editState().isEnabled = false;
563
564 mOutput.prepareFrame();
565}
566
567TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
568 mOutput.editState().isEnabled = true;
569 mOutput.editState().usesClientComposition = false;
570 mOutput.editState().usesDeviceComposition = true;
571
572 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
573 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
574
575 mOutput.prepareFrame();
576}
577
578// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
579// base chooseCompositionStrategy() is invoked.
580TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700581 mOutput->editState().isEnabled = true;
582 mOutput->editState().usesClientComposition = false;
583 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800584
585 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
586
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700587 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800588
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700589 EXPECT_TRUE(mOutput->getState().usesClientComposition);
590 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800591}
592
Lloyd Pique56eba802019-08-28 15:45:25 -0700593/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800594 * Output::present()
595 */
596
597struct OutputPresentTest : public testing::Test {
598 struct OutputPartialMock : public OutputPartialMockBase {
599 // All child helper functions Output::present() are defined as mocks,
600 // and those are tested separately, allowing the present() test to
601 // just cover the high level flow.
602 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
603 MOCK_METHOD1(updateAndWriteCompositionState,
604 void(const compositionengine::CompositionRefreshArgs&));
605 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
606 MOCK_METHOD0(beginFrame, void());
607 MOCK_METHOD0(prepareFrame, void());
608 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
609 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
610 MOCK_METHOD0(postFramebuffer, void());
611 };
612
613 StrictMock<OutputPartialMock> mOutput;
614};
615
616TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
617 CompositionRefreshArgs args;
618
619 InSequence seq;
620 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
621 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
622 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
623 EXPECT_CALL(mOutput, beginFrame());
624 EXPECT_CALL(mOutput, prepareFrame());
625 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
626 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
627 EXPECT_CALL(mOutput, postFramebuffer());
628
629 mOutput.present(args);
630}
631
632/*
633 * Output::updateColorProfile()
634 */
635
636// TODO(b/144060211) - Add coverage
637
638/*
639 * Output::beginFrame()
640 */
641
642/*
643 * Output::devOptRepaintFlash()
644 */
645
Lloyd Piquedb462d82019-11-19 17:58:46 -0800646struct OutputDevOptRepaintFlashTest : public testing::Test {
647 struct OutputPartialMock : public OutputPartialMockBase {
648 // Sets up the helper functions called by composeSurfaces to use a mock
649 // implementations.
650 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
651 MOCK_METHOD1(composeSurfaces, std::optional<base::unique_fd>(const Region&));
652 MOCK_METHOD0(postFramebuffer, void());
653 MOCK_METHOD0(prepareFrame, void());
654 };
655
656 OutputDevOptRepaintFlashTest() {
657 mOutput.setDisplayColorProfileForTest(
658 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
659 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
660 }
661
662 static const Region kEmptyRegion;
663 static const Region kNotEmptyRegion;
664
665 StrictMock<OutputPartialMock> mOutput;
666 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
667 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
668 CompositionRefreshArgs mRefreshArgs;
669};
670
671const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
672const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
673
674TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
675 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
676 mRefreshArgs.repaintEverything = true;
677 mOutput.mState.isEnabled = true;
678
679 mOutput.devOptRepaintFlash(mRefreshArgs);
680}
681
682TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
683 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
684 mRefreshArgs.repaintEverything = true;
685 mOutput.mState.isEnabled = false;
686
687 InSequence seq;
688 EXPECT_CALL(mOutput, postFramebuffer());
689 EXPECT_CALL(mOutput, prepareFrame());
690
691 mOutput.devOptRepaintFlash(mRefreshArgs);
692}
693
694TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
695 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
696 mRefreshArgs.repaintEverything = true;
697 mOutput.mState.isEnabled = true;
698
699 InSequence seq;
700 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
701 EXPECT_CALL(mOutput, postFramebuffer());
702 EXPECT_CALL(mOutput, prepareFrame());
703
704 mOutput.devOptRepaintFlash(mRefreshArgs);
705}
706
707TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
708 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
709 mRefreshArgs.repaintEverything = false;
710 mOutput.mState.isEnabled = true;
711
712 InSequence seq;
713 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
714 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion)));
715 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
716 EXPECT_CALL(mOutput, postFramebuffer());
717 EXPECT_CALL(mOutput, prepareFrame());
718
719 mOutput.devOptRepaintFlash(mRefreshArgs);
720}
721
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800722// TODO(b/144060211) - Add coverage
723
724/*
725 * Output::finishFrame()
726 */
727
Lloyd Pique03561a62019-11-19 18:34:52 -0800728struct OutputFinishFrameTest : public testing::Test {
729 struct OutputPartialMock : public OutputPartialMockBase {
730 // Sets up the helper functions called by composeSurfaces to use a mock
731 // implementations.
732 MOCK_METHOD1(composeSurfaces, std::optional<base::unique_fd>(const Region&));
733 MOCK_METHOD0(postFramebuffer, void());
734 };
735
736 OutputFinishFrameTest() {
737 mOutput.setDisplayColorProfileForTest(
738 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
739 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
740 }
741
742 StrictMock<OutputPartialMock> mOutput;
743 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
744 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
745 CompositionRefreshArgs mRefreshArgs;
746};
747
748TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
749 mOutput.mState.isEnabled = false;
750
751 mOutput.finishFrame(mRefreshArgs);
752}
753
754TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
755 mOutput.mState.isEnabled = true;
756
757 InSequence seq;
758 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION)));
759
760 mOutput.finishFrame(mRefreshArgs);
761}
762
763TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
764 mOutput.mState.isEnabled = true;
765
766 InSequence seq;
767 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION)))
768 .WillOnce(Return(ByMove(base::unique_fd())));
769 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
770
771 mOutput.finishFrame(mRefreshArgs);
772}
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800773
774/*
775 * Output::postFramebuffer()
776 */
777
778// TODO(b/144060211) - Add coverage
779
780/*
Lloyd Pique56eba802019-08-28 15:45:25 -0700781 * Output::composeSurfaces()
782 */
783
784struct OutputComposeSurfacesTest : public testing::Test {
785 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
786 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
787
788 static const Rect kDefaultOutputFrame;
789 static const Rect kDefaultOutputViewport;
790 static const Rect kDefaultOutputScissor;
791 static const mat4 kDefaultColorTransformMat;
792
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800793 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique56eba802019-08-28 15:45:25 -0700794 // Sets up the helper functions called by composeSurfaces to use a mock
795 // implementations.
796 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
797 MOCK_METHOD2(generateClientCompositionRequests,
798 std::vector<renderengine::LayerSettings>(bool, Region&));
799 MOCK_METHOD2(appendRegionFlashRequests,
800 void(const Region&, std::vector<renderengine::LayerSettings>&));
801 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
802 };
803
804 OutputComposeSurfacesTest() {
805 mOutput.setDisplayColorProfileForTest(
806 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
807 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
808
Lloyd Pique56eba802019-08-28 15:45:25 -0700809 mOutput.editState().frame = kDefaultOutputFrame;
810 mOutput.editState().viewport = kDefaultOutputViewport;
811 mOutput.editState().scissor = kDefaultOutputScissor;
812 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
813 mOutput.editState().orientation = kDefaultOutputOrientation;
814 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800815 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700816 mOutput.editState().isSecure = true;
817 mOutput.editState().needsFiltering = false;
818 mOutput.editState().usesClientComposition = true;
819 mOutput.editState().usesDeviceComposition = false;
820
Lloyd Pique01c77c12019-04-17 12:48:32 -0700821 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
822 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
823 .WillRepeatedly(Return(&mOutputLayer1));
824 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
825 .WillRepeatedly(Return(&mOutputLayer2));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700826 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -0700827 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
828 }
829
830 StrictMock<mock::CompositionEngine> mCompositionEngine;
831 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
832 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
833 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700834 StrictMock<mock::OutputLayer> mOutputLayer1;
835 StrictMock<mock::OutputLayer> mOutputLayer2;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700836 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700837 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
838};
839
840const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
841const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
842const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
843const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
844
845// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
846// basic tests.
847
848TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
849 mOutput.editState().usesClientComposition = false;
850
851 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800852 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
853 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700854}
855
856TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
857 const Region kDebugRegion{Rect{100, 101, 102, 103}};
858
859 constexpr float kDefaultMaxLuminance = 1.0f;
860 constexpr float kDefaultAvgLuminance = 0.7f;
861 constexpr float kDefaultMinLuminance = 0.1f;
862 HdrCapabilities HdrCapabilities{{},
863 kDefaultMaxLuminance,
864 kDefaultAvgLuminance,
865 kDefaultMinLuminance};
866
867 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
868 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
869
870 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
871 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
872
873 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
874
875 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
876 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
877 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
878 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
879 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
880
Lloyd Piqued3d69882019-02-28 16:03:46 -0800881 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
882 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700883}
884
885/*
886 * Output::generateClientCompositionRequests()
887 */
888
889struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800890 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700891 // compositionengine::Output overrides
Lloyd Pique56eba802019-08-28 15:45:25 -0700892 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
893 bool supportsProtectedContent, Region& clearRegion) override {
894 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
895 clearRegion);
896 }
897 };
898
899 GenerateClientCompositionRequestsTest() {
900 mOutput.setDisplayColorProfileForTest(
901 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
902 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
903 }
904
Lloyd Pique56eba802019-08-28 15:45:25 -0700905 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
906 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700907 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700908};
909
910// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
911
912TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
913 // In split-screen landscape mode, the screen is rotated 90 degrees, with
914 // one layer on the left covering the left side of the output, and one layer
915 // on the right covering that side of the output.
916
Lloyd Pique01c77c12019-04-17 12:48:32 -0700917 StrictMock<mock::OutputLayer> leftOutputLayer;
918 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700919
920 StrictMock<mock::Layer> leftLayer;
921 StrictMock<mock::LayerFE> leftLayerFE;
922 StrictMock<mock::Layer> rightLayer;
923 StrictMock<mock::LayerFE> rightLayerFE;
924
925 impl::OutputLayerCompositionState leftOutputLayerState;
926 leftOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800927 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700928
Lloyd Pique9755fb72019-03-26 14:44:40 -0700929 LayerFECompositionState leftLayerFEState;
930 leftLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700931
932 const half3 leftLayerColor{1.f, 0.f, 0.f};
933 renderengine::LayerSettings leftLayerRESettings;
934 leftLayerRESettings.source.solidColor = leftLayerColor;
935
936 impl::OutputLayerCompositionState rightOutputLayerState;
937 rightOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800938 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700939
Lloyd Pique9755fb72019-03-26 14:44:40 -0700940 LayerFECompositionState rightLayerFEState;
941 rightLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700942
943 const half3 rightLayerColor{0.f, 1.f, 0.f};
944 renderengine::LayerSettings rightLayerRESettings;
945 rightLayerRESettings.source.solidColor = rightLayerColor;
946
Lloyd Pique01c77c12019-04-17 12:48:32 -0700947 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
948 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
949 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
950 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
951 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700952 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700953 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
954
Lloyd Pique01c77c12019-04-17 12:48:32 -0700955 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
956 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
957 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
958 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
959 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700960 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700961 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
962
Lloyd Pique01c77c12019-04-17 12:48:32 -0700963 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
964 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
965 .WillRepeatedly(Return(&leftOutputLayer));
966 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
967 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -0700968
969 const Rect kPortraitFrame(0, 0, 1000, 2000);
970 const Rect kPortraitViewport(0, 0, 2000, 1000);
971 const Rect kPortraitScissor(0, 0, 1000, 2000);
972 const uint32_t kPortraitOrientation = TR_ROT_90;
973
974 mOutput.editState().frame = kPortraitFrame;
975 mOutput.editState().viewport = kPortraitViewport;
976 mOutput.editState().scissor = kPortraitScissor;
977 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
978 mOutput.editState().orientation = kPortraitOrientation;
979 mOutput.editState().needsFiltering = true;
980 mOutput.editState().isSecure = false;
981
982 constexpr bool supportsProtectedContent = false;
983 Region clearRegion;
984 auto requests =
985 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
986
987 ASSERT_EQ(2u, requests.size());
988 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
989 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
990}
991
992TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
993 // Layers whose visible region does not intersect with the viewport will be
994 // skipped when generating client composition request state.
995
Lloyd Pique01c77c12019-04-17 12:48:32 -0700996 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700997 StrictMock<mock::Layer> layer;
998 StrictMock<mock::LayerFE> layerFE;
999
1000 impl::OutputLayerCompositionState outputLayerState;
1001 outputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -08001002 outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -07001003
Lloyd Pique9755fb72019-03-26 14:44:40 -07001004 LayerFECompositionState layerFEState;
1005 layerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07001006
Lloyd Pique01c77c12019-04-17 12:48:32 -07001007 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1008 EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
1009 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
1010 EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
1011 EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001012 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001013 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
1014
Lloyd Pique01c77c12019-04-17 12:48:32 -07001015 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
1016 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -07001017
1018 const Rect kPortraitFrame(0, 0, 1000, 2000);
1019 const Rect kPortraitViewport(0, 0, 2000, 1000);
1020 const Rect kPortraitScissor(0, 0, 1000, 2000);
1021 const uint32_t kPortraitOrientation = TR_ROT_90;
1022
1023 mOutput.editState().frame = kPortraitFrame;
1024 mOutput.editState().viewport = kPortraitViewport;
1025 mOutput.editState().scissor = kPortraitScissor;
1026 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1027 mOutput.editState().orientation = kPortraitOrientation;
1028 mOutput.editState().needsFiltering = true;
1029 mOutput.editState().isSecure = false;
1030
1031 constexpr bool supportsProtectedContent = false;
1032 Region clearRegion;
1033 auto requests =
1034 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1035
1036 EXPECT_EQ(0u, requests.size());
1037}
1038
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001039TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
1040 // If client composition is performed with some layers set to use device
1041 // composition, device layers after the first layer (device or client) will
1042 // clear the frame buffer if they are opaque and if that layer has a flag
1043 // set to do so. The first layer is skipped as the frame buffer is already
1044 // expected to be clear.
1045
Lloyd Pique01c77c12019-04-17 12:48:32 -07001046 StrictMock<mock::OutputLayer> leftOutputLayer;
1047 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001048
1049 StrictMock<mock::Layer> leftLayer;
1050 StrictMock<mock::LayerFE> leftLayerFE;
1051 StrictMock<mock::Layer> rightLayer;
1052 StrictMock<mock::LayerFE> rightLayerFE;
1053
1054 impl::OutputLayerCompositionState leftOutputLayerState;
1055 leftOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001056 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001057
Lloyd Pique9755fb72019-03-26 14:44:40 -07001058 LayerFECompositionState leftLayerFEState;
1059 leftLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001060
1061 impl::OutputLayerCompositionState rightOutputLayerState;
1062 rightOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001063 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001064
Lloyd Pique9755fb72019-03-26 14:44:40 -07001065 LayerFECompositionState rightLayerFEState;
1066 rightLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001067
1068 const half3 rightLayerColor{0.f, 1.f, 0.f};
1069 renderengine::LayerSettings rightLayerRESettings;
1070 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
1071 rightLayerRESettings.source.solidColor = rightLayerColor;
1072
Lloyd Pique01c77c12019-04-17 12:48:32 -07001073 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
1074 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
1075 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
1076 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1077 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001078 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001079
Lloyd Pique01c77c12019-04-17 12:48:32 -07001080 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
1081 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
1082 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
1083 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1084 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001085 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001086 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
1087
Lloyd Pique01c77c12019-04-17 12:48:32 -07001088 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1089 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1090 .WillRepeatedly(Return(&leftOutputLayer));
1091 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
1092 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001093
1094 const Rect kPortraitFrame(0, 0, 1000, 2000);
1095 const Rect kPortraitViewport(0, 0, 2000, 1000);
1096 const Rect kPortraitScissor(0, 0, 1000, 2000);
1097 const uint32_t kPortraitOrientation = TR_ROT_90;
1098
1099 mOutput.editState().frame = kPortraitFrame;
1100 mOutput.editState().viewport = kPortraitViewport;
1101 mOutput.editState().scissor = kPortraitScissor;
1102 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1103 mOutput.editState().orientation = kPortraitOrientation;
1104 mOutput.editState().needsFiltering = true;
1105 mOutput.editState().isSecure = false;
1106
1107 constexpr bool supportsProtectedContent = false;
1108 Region clearRegion;
1109 auto requests =
1110 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1111
1112 const half3 clearColor{0.f, 0.f, 0.f};
1113
1114 ASSERT_EQ(1u, requests.size());
1115 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
1116 EXPECT_EQ(clearColor, requests[0].source.solidColor);
1117}
1118
Lloyd Pique32cbe282018-10-19 13:09:22 -07001119} // namespace
1120} // namespace android::compositionengine