blob: 242ccd57c2678dbdbae32c04ad7247202e90b8d9 [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/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800514 * Output::setReleasedLayers()
515 */
516
517using OutputSetReleasedLayersTest = OutputTest;
518
519TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
520 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
521 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
522 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
523
524 Output::ReleasedLayers layers;
525 layers.push_back(layer1FE);
526 layers.push_back(layer2FE);
527 layers.push_back(layer3FE);
528
529 mOutput->setReleasedLayers(std::move(layers));
530
531 const auto& setLayers = mOutput->getReleasedLayersForTest();
532 ASSERT_EQ(3u, setLayers.size());
533 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
534 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
535 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
536}
537
538/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800539 * Output::updateAndWriteCompositionState()
540 */
541
542TEST_F(OutputTest, updateAndWriteCompositionState_takesEarlyOutIfNotEnabled) {
543 mOutput->editState().isEnabled = false;
544
545 CompositionRefreshArgs args;
546 mOutput->updateAndWriteCompositionState(args);
547}
548
549TEST_F(OutputTest, updateAndWriteCompositionState_updatesLayers) {
550 mOutput->editState().isEnabled = true;
551 mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>();
552 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer));
553
554 EXPECT_CALL(*outputLayer, updateCompositionState(true, true)).Times(1);
555 EXPECT_CALL(*outputLayer, writeStateToHWC(true)).Times(1);
556
557 CompositionRefreshArgs args;
558 args.updatingGeometryThisFrame = true;
559 args.devOptForceClientComposition = true;
560 mOutput->updateAndWriteCompositionState(args);
561}
562
563/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800564 * Output::prepareFrame()
565 */
566
567struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800568 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique66d68602019-02-13 14:23:31 -0800569 // Sets up the helper functions called by prepareFrame to use a mock
570 // implementations.
571 MOCK_METHOD0(chooseCompositionStrategy, void());
572 };
573
574 OutputPrepareFrameTest() {
575 mOutput.setDisplayColorProfileForTest(
576 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
577 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
578 }
579
580 StrictMock<mock::CompositionEngine> mCompositionEngine;
581 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
582 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700583 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800584};
585
586TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
587 mOutput.editState().isEnabled = false;
588
589 mOutput.prepareFrame();
590}
591
592TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
593 mOutput.editState().isEnabled = true;
594 mOutput.editState().usesClientComposition = false;
595 mOutput.editState().usesDeviceComposition = true;
596
597 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
598 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
599
600 mOutput.prepareFrame();
601}
602
603// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
604// base chooseCompositionStrategy() is invoked.
605TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700606 mOutput->editState().isEnabled = true;
607 mOutput->editState().usesClientComposition = false;
608 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800609
610 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
611
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700612 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800613
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700614 EXPECT_TRUE(mOutput->getState().usesClientComposition);
615 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800616}
617
Lloyd Pique56eba802019-08-28 15:45:25 -0700618/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800619 * Output::present()
620 */
621
622struct OutputPresentTest : public testing::Test {
623 struct OutputPartialMock : public OutputPartialMockBase {
624 // All child helper functions Output::present() are defined as mocks,
625 // and those are tested separately, allowing the present() test to
626 // just cover the high level flow.
627 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
628 MOCK_METHOD1(updateAndWriteCompositionState,
629 void(const compositionengine::CompositionRefreshArgs&));
630 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
631 MOCK_METHOD0(beginFrame, void());
632 MOCK_METHOD0(prepareFrame, void());
633 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
634 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
635 MOCK_METHOD0(postFramebuffer, void());
636 };
637
638 StrictMock<OutputPartialMock> mOutput;
639};
640
641TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
642 CompositionRefreshArgs args;
643
644 InSequence seq;
645 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
646 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
647 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
648 EXPECT_CALL(mOutput, beginFrame());
649 EXPECT_CALL(mOutput, prepareFrame());
650 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
651 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
652 EXPECT_CALL(mOutput, postFramebuffer());
653
654 mOutput.present(args);
655}
656
657/*
658 * Output::updateColorProfile()
659 */
660
661// TODO(b/144060211) - Add coverage
662
663/*
664 * Output::beginFrame()
665 */
666
667/*
668 * Output::devOptRepaintFlash()
669 */
670
Lloyd Piquedb462d82019-11-19 17:58:46 -0800671struct OutputDevOptRepaintFlashTest : public testing::Test {
672 struct OutputPartialMock : public OutputPartialMockBase {
673 // Sets up the helper functions called by composeSurfaces to use a mock
674 // implementations.
675 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
676 MOCK_METHOD1(composeSurfaces, std::optional<base::unique_fd>(const Region&));
677 MOCK_METHOD0(postFramebuffer, void());
678 MOCK_METHOD0(prepareFrame, void());
679 };
680
681 OutputDevOptRepaintFlashTest() {
682 mOutput.setDisplayColorProfileForTest(
683 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
684 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
685 }
686
687 static const Region kEmptyRegion;
688 static const Region kNotEmptyRegion;
689
690 StrictMock<OutputPartialMock> mOutput;
691 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
692 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
693 CompositionRefreshArgs mRefreshArgs;
694};
695
696const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
697const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
698
699TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
700 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
701 mRefreshArgs.repaintEverything = true;
702 mOutput.mState.isEnabled = true;
703
704 mOutput.devOptRepaintFlash(mRefreshArgs);
705}
706
707TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
708 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
709 mRefreshArgs.repaintEverything = true;
710 mOutput.mState.isEnabled = false;
711
712 InSequence seq;
713 EXPECT_CALL(mOutput, postFramebuffer());
714 EXPECT_CALL(mOutput, prepareFrame());
715
716 mOutput.devOptRepaintFlash(mRefreshArgs);
717}
718
719TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
720 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
721 mRefreshArgs.repaintEverything = true;
722 mOutput.mState.isEnabled = true;
723
724 InSequence seq;
725 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
726 EXPECT_CALL(mOutput, postFramebuffer());
727 EXPECT_CALL(mOutput, prepareFrame());
728
729 mOutput.devOptRepaintFlash(mRefreshArgs);
730}
731
732TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
733 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
734 mRefreshArgs.repaintEverything = false;
735 mOutput.mState.isEnabled = true;
736
737 InSequence seq;
738 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
739 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion)));
740 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
741 EXPECT_CALL(mOutput, postFramebuffer());
742 EXPECT_CALL(mOutput, prepareFrame());
743
744 mOutput.devOptRepaintFlash(mRefreshArgs);
745}
746
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800747// TODO(b/144060211) - Add coverage
748
749/*
750 * Output::finishFrame()
751 */
752
Lloyd Pique03561a62019-11-19 18:34:52 -0800753struct OutputFinishFrameTest : public testing::Test {
754 struct OutputPartialMock : public OutputPartialMockBase {
755 // Sets up the helper functions called by composeSurfaces to use a mock
756 // implementations.
757 MOCK_METHOD1(composeSurfaces, std::optional<base::unique_fd>(const Region&));
758 MOCK_METHOD0(postFramebuffer, void());
759 };
760
761 OutputFinishFrameTest() {
762 mOutput.setDisplayColorProfileForTest(
763 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
764 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
765 }
766
767 StrictMock<OutputPartialMock> mOutput;
768 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
769 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
770 CompositionRefreshArgs mRefreshArgs;
771};
772
773TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
774 mOutput.mState.isEnabled = false;
775
776 mOutput.finishFrame(mRefreshArgs);
777}
778
779TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
780 mOutput.mState.isEnabled = true;
781
782 InSequence seq;
783 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION)));
784
785 mOutput.finishFrame(mRefreshArgs);
786}
787
788TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
789 mOutput.mState.isEnabled = true;
790
791 InSequence seq;
792 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION)))
793 .WillOnce(Return(ByMove(base::unique_fd())));
794 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
795
796 mOutput.finishFrame(mRefreshArgs);
797}
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800798
799/*
800 * Output::postFramebuffer()
801 */
802
803// TODO(b/144060211) - Add coverage
804
805/*
Lloyd Pique56eba802019-08-28 15:45:25 -0700806 * Output::composeSurfaces()
807 */
808
809struct OutputComposeSurfacesTest : public testing::Test {
810 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
811 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
812
813 static const Rect kDefaultOutputFrame;
814 static const Rect kDefaultOutputViewport;
815 static const Rect kDefaultOutputScissor;
816 static const mat4 kDefaultColorTransformMat;
817
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800818 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique56eba802019-08-28 15:45:25 -0700819 // Sets up the helper functions called by composeSurfaces to use a mock
820 // implementations.
821 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
822 MOCK_METHOD2(generateClientCompositionRequests,
823 std::vector<renderengine::LayerSettings>(bool, Region&));
824 MOCK_METHOD2(appendRegionFlashRequests,
825 void(const Region&, std::vector<renderengine::LayerSettings>&));
826 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
827 };
828
829 OutputComposeSurfacesTest() {
830 mOutput.setDisplayColorProfileForTest(
831 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
832 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
833
Lloyd Pique56eba802019-08-28 15:45:25 -0700834 mOutput.editState().frame = kDefaultOutputFrame;
835 mOutput.editState().viewport = kDefaultOutputViewport;
836 mOutput.editState().scissor = kDefaultOutputScissor;
837 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
838 mOutput.editState().orientation = kDefaultOutputOrientation;
839 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800840 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700841 mOutput.editState().isSecure = true;
842 mOutput.editState().needsFiltering = false;
843 mOutput.editState().usesClientComposition = true;
844 mOutput.editState().usesDeviceComposition = false;
845
Lloyd Pique01c77c12019-04-17 12:48:32 -0700846 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
847 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
848 .WillRepeatedly(Return(&mOutputLayer1));
849 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
850 .WillRepeatedly(Return(&mOutputLayer2));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700851 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -0700852 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
853 }
854
855 StrictMock<mock::CompositionEngine> mCompositionEngine;
856 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
857 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
858 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700859 StrictMock<mock::OutputLayer> mOutputLayer1;
860 StrictMock<mock::OutputLayer> mOutputLayer2;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700861 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700862 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
863};
864
865const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
866const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
867const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
868const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
869
870// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
871// basic tests.
872
873TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
874 mOutput.editState().usesClientComposition = false;
875
876 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800877 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
878 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700879}
880
881TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
882 const Region kDebugRegion{Rect{100, 101, 102, 103}};
883
884 constexpr float kDefaultMaxLuminance = 1.0f;
885 constexpr float kDefaultAvgLuminance = 0.7f;
886 constexpr float kDefaultMinLuminance = 0.1f;
887 HdrCapabilities HdrCapabilities{{},
888 kDefaultMaxLuminance,
889 kDefaultAvgLuminance,
890 kDefaultMinLuminance};
891
892 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
893 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
894
895 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
896 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
897
898 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
899
900 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
901 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
902 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
903 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
904 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
905
Lloyd Piqued3d69882019-02-28 16:03:46 -0800906 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
907 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700908}
909
910/*
911 * Output::generateClientCompositionRequests()
912 */
913
914struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800915 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700916 // compositionengine::Output overrides
Lloyd Pique56eba802019-08-28 15:45:25 -0700917 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
918 bool supportsProtectedContent, Region& clearRegion) override {
919 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
920 clearRegion);
921 }
922 };
923
924 GenerateClientCompositionRequestsTest() {
925 mOutput.setDisplayColorProfileForTest(
926 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
927 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
928 }
929
Lloyd Pique56eba802019-08-28 15:45:25 -0700930 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
931 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700932 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700933};
934
935// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
936
937TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
938 // In split-screen landscape mode, the screen is rotated 90 degrees, with
939 // one layer on the left covering the left side of the output, and one layer
940 // on the right covering that side of the output.
941
Lloyd Pique01c77c12019-04-17 12:48:32 -0700942 StrictMock<mock::OutputLayer> leftOutputLayer;
943 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700944
945 StrictMock<mock::Layer> leftLayer;
946 StrictMock<mock::LayerFE> leftLayerFE;
947 StrictMock<mock::Layer> rightLayer;
948 StrictMock<mock::LayerFE> rightLayerFE;
949
950 impl::OutputLayerCompositionState leftOutputLayerState;
951 leftOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800952 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700953
Lloyd Pique9755fb72019-03-26 14:44:40 -0700954 LayerFECompositionState leftLayerFEState;
955 leftLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700956
957 const half3 leftLayerColor{1.f, 0.f, 0.f};
958 renderengine::LayerSettings leftLayerRESettings;
959 leftLayerRESettings.source.solidColor = leftLayerColor;
960
961 impl::OutputLayerCompositionState rightOutputLayerState;
962 rightOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800963 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700964
Lloyd Pique9755fb72019-03-26 14:44:40 -0700965 LayerFECompositionState rightLayerFEState;
966 rightLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700967
968 const half3 rightLayerColor{0.f, 1.f, 0.f};
969 renderengine::LayerSettings rightLayerRESettings;
970 rightLayerRESettings.source.solidColor = rightLayerColor;
971
Lloyd Pique01c77c12019-04-17 12:48:32 -0700972 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
973 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
974 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
975 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
976 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700977 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700978 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800979 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700980
Lloyd Pique01c77c12019-04-17 12:48:32 -0700981 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
982 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
983 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
984 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
985 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700986 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700987 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800988 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700989
Lloyd Pique01c77c12019-04-17 12:48:32 -0700990 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
991 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
992 .WillRepeatedly(Return(&leftOutputLayer));
993 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
994 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -0700995
996 const Rect kPortraitFrame(0, 0, 1000, 2000);
997 const Rect kPortraitViewport(0, 0, 2000, 1000);
998 const Rect kPortraitScissor(0, 0, 1000, 2000);
999 const uint32_t kPortraitOrientation = TR_ROT_90;
1000
1001 mOutput.editState().frame = kPortraitFrame;
1002 mOutput.editState().viewport = kPortraitViewport;
1003 mOutput.editState().scissor = kPortraitScissor;
1004 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1005 mOutput.editState().orientation = kPortraitOrientation;
1006 mOutput.editState().needsFiltering = true;
1007 mOutput.editState().isSecure = false;
1008
1009 constexpr bool supportsProtectedContent = false;
1010 Region clearRegion;
1011 auto requests =
1012 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1013
1014 ASSERT_EQ(2u, requests.size());
1015 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
1016 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
1017}
1018
1019TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
1020 // Layers whose visible region does not intersect with the viewport will be
1021 // skipped when generating client composition request state.
1022
Lloyd Pique01c77c12019-04-17 12:48:32 -07001023 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -07001024 StrictMock<mock::Layer> layer;
1025 StrictMock<mock::LayerFE> layerFE;
1026
1027 impl::OutputLayerCompositionState outputLayerState;
1028 outputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -08001029 outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -07001030
Lloyd Pique9755fb72019-03-26 14:44:40 -07001031 LayerFECompositionState layerFEState;
1032 layerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07001033
Lloyd Pique01c77c12019-04-17 12:48:32 -07001034 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1035 EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
1036 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
1037 EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
1038 EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001039 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001040 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001041 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001042
Lloyd Pique01c77c12019-04-17 12:48:32 -07001043 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
1044 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -07001045
1046 const Rect kPortraitFrame(0, 0, 1000, 2000);
1047 const Rect kPortraitViewport(0, 0, 2000, 1000);
1048 const Rect kPortraitScissor(0, 0, 1000, 2000);
1049 const uint32_t kPortraitOrientation = TR_ROT_90;
1050
1051 mOutput.editState().frame = kPortraitFrame;
1052 mOutput.editState().viewport = kPortraitViewport;
1053 mOutput.editState().scissor = kPortraitScissor;
1054 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1055 mOutput.editState().orientation = kPortraitOrientation;
1056 mOutput.editState().needsFiltering = true;
1057 mOutput.editState().isSecure = false;
1058
1059 constexpr bool supportsProtectedContent = false;
1060 Region clearRegion;
1061 auto requests =
1062 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1063
1064 EXPECT_EQ(0u, requests.size());
1065}
1066
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001067TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
1068 // If client composition is performed with some layers set to use device
1069 // composition, device layers after the first layer (device or client) will
1070 // clear the frame buffer if they are opaque and if that layer has a flag
1071 // set to do so. The first layer is skipped as the frame buffer is already
1072 // expected to be clear.
1073
Lloyd Pique01c77c12019-04-17 12:48:32 -07001074 StrictMock<mock::OutputLayer> leftOutputLayer;
1075 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001076
1077 StrictMock<mock::Layer> leftLayer;
1078 StrictMock<mock::LayerFE> leftLayerFE;
1079 StrictMock<mock::Layer> rightLayer;
1080 StrictMock<mock::LayerFE> rightLayerFE;
1081
1082 impl::OutputLayerCompositionState leftOutputLayerState;
1083 leftOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001084 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001085
Lloyd Pique9755fb72019-03-26 14:44:40 -07001086 LayerFECompositionState leftLayerFEState;
1087 leftLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001088
1089 impl::OutputLayerCompositionState rightOutputLayerState;
1090 rightOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001091 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001092
Lloyd Pique9755fb72019-03-26 14:44:40 -07001093 LayerFECompositionState rightLayerFEState;
1094 rightLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001095
1096 const half3 rightLayerColor{0.f, 1.f, 0.f};
1097 renderengine::LayerSettings rightLayerRESettings;
1098 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
1099 rightLayerRESettings.source.solidColor = rightLayerColor;
1100
Lloyd Pique01c77c12019-04-17 12:48:32 -07001101 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
1102 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
1103 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
1104 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1105 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001106 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001107 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001108
Lloyd Pique01c77c12019-04-17 12:48:32 -07001109 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
1110 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
1111 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
1112 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1113 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001114 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001115 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001116 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001117
Lloyd Pique01c77c12019-04-17 12:48:32 -07001118 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1119 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1120 .WillRepeatedly(Return(&leftOutputLayer));
1121 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
1122 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001123
1124 const Rect kPortraitFrame(0, 0, 1000, 2000);
1125 const Rect kPortraitViewport(0, 0, 2000, 1000);
1126 const Rect kPortraitScissor(0, 0, 1000, 2000);
1127 const uint32_t kPortraitOrientation = TR_ROT_90;
1128
1129 mOutput.editState().frame = kPortraitFrame;
1130 mOutput.editState().viewport = kPortraitViewport;
1131 mOutput.editState().scissor = kPortraitScissor;
1132 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1133 mOutput.editState().orientation = kPortraitOrientation;
1134 mOutput.editState().needsFiltering = true;
1135 mOutput.editState().isSecure = false;
1136
1137 constexpr bool supportsProtectedContent = false;
1138 Region clearRegion;
1139 auto requests =
1140 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1141
1142 const half3 clearColor{0.f, 0.f, 0.f};
1143
1144 ASSERT_EQ(1u, requests.size());
1145 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
1146 EXPECT_EQ(clearColor, requests[0].source.solidColor);
1147}
1148
Lloyd Pique32cbe282018-10-19 13:09:22 -07001149} // namespace
1150} // namespace android::compositionengine