blob: 65aed785f6dfbb9fd36e1bf3c15149912696108b [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 Piquefaa3f192019-11-14 14:05:09 -080041using testing::InSequence;
42using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070043using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070044using testing::ReturnRef;
45using testing::StrictMock;
46
Lloyd Pique56eba802019-08-28 15:45:25 -070047constexpr auto TR_IDENT = 0u;
48constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
49
Lloyd Pique3eb1b212019-03-07 21:15:40 -080050const mat4 kIdentity;
51const mat4 kNonIdentityHalf = mat4() * 0.5;
52const mat4 kNonIdentityQuarter = mat4() * 0.25;
53
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054struct OutputPartialMockBase : public impl::Output {
55 // compositionengine::Output overrides
56 const OutputCompositionState& getState() const override { return mState; }
57 OutputCompositionState& editState() override { return mState; }
58
59 // Use mocks for all the remaining virtual functions
60 // not implemented by the base implementation class.
61 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
62 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
63 MOCK_METHOD3(ensureOutputLayer,
64 compositionengine::OutputLayer*(std::optional<size_t>,
65 const std::shared_ptr<compositionengine::Layer>&,
66 const sp<LayerFE>&));
67 MOCK_METHOD0(finalizePendingOutputLayers, void());
68 MOCK_METHOD0(clearOutputLayers, void());
69 MOCK_CONST_METHOD1(dumpState, void(std::string&));
70 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
71 MOCK_METHOD2(injectOutputLayerForTest,
72 compositionengine::OutputLayer*(const std::shared_ptr<compositionengine::Layer>&,
73 const sp<LayerFE>&));
74 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
75
76 impl::OutputCompositionState mState;
77};
78
Lloyd Pique66d68602019-02-13 14:23:31 -080079struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -070080 class Output : public impl::Output {
81 public:
82 using impl::Output::injectOutputLayerForTest;
83 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
84 };
85
86 static std::shared_ptr<Output> createOutput(
87 const compositionengine::CompositionEngine& compositionEngine) {
88 return impl::createOutputTemplated<Output>(compositionEngine);
89 }
90
Lloyd Pique31cb2942018-10-19 17:23:03 -070091 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070092 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070093 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070094 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -080095
Lloyd Piquea38ea7e2019-04-16 18:10:26 -070096 mOutput->editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -070097 }
Lloyd Pique32cbe282018-10-19 13:09:22 -070098
Lloyd Piqueef958122019-02-05 18:00:12 -080099 static const Rect kDefaultDisplaySize;
100
Lloyd Pique32cbe282018-10-19 13:09:22 -0700101 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700102 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700103 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700104 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700105};
106
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800107// Extension of the base test useful for checking interactions with the LayerFE
108// functions to latch composition state.
109struct OutputLatchFEStateTest : public OutputTest {
110 OutputLatchFEStateTest() {
111 EXPECT_CALL(*mOutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mLayer1));
112 EXPECT_CALL(*mOutputLayer2, getLayer()).WillRepeatedly(ReturnRef(mLayer2));
113 EXPECT_CALL(*mOutputLayer3, getLayer()).WillRepeatedly(ReturnRef(mLayer3));
114
115 EXPECT_CALL(*mOutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mLayer1FE));
116 EXPECT_CALL(*mOutputLayer2, getLayerFE()).WillRepeatedly(ReturnRef(mLayer2FE));
117 EXPECT_CALL(*mOutputLayer3, getLayerFE()).WillRepeatedly(ReturnRef(mLayer3FE));
118
119 EXPECT_CALL(mLayer1, editFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
120 EXPECT_CALL(mLayer2, editFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
121 EXPECT_CALL(mLayer3, editFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
122 }
123
124 void injectLayer(std::unique_ptr<mock::OutputLayer> layer) {
125 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.release()));
126 }
127
128 std::unique_ptr<mock::OutputLayer> mOutputLayer1{new StrictMock<mock::OutputLayer>};
129 std::unique_ptr<mock::OutputLayer> mOutputLayer2{new StrictMock<mock::OutputLayer>};
130 std::unique_ptr<mock::OutputLayer> mOutputLayer3{new StrictMock<mock::OutputLayer>};
131
132 StrictMock<mock::Layer> mLayer1;
133 StrictMock<mock::Layer> mLayer2;
134 StrictMock<mock::Layer> mLayer3;
135
136 StrictMock<mock::LayerFE> mLayer1FE;
137 StrictMock<mock::LayerFE> mLayer2FE;
138 StrictMock<mock::LayerFE> mLayer3FE;
139
140 LayerFECompositionState mLayer1FEState;
141 LayerFECompositionState mLayer2FEState;
142 LayerFECompositionState mLayer3FEState;
143};
144
Lloyd Piqueef958122019-02-05 18:00:12 -0800145const Rect OutputTest::kDefaultDisplaySize{100, 200};
146
Lloyd Pique66d68602019-02-13 14:23:31 -0800147/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700148 * Basic construction
149 */
150
Lloyd Pique31cb2942018-10-19 17:23:03 -0700151TEST_F(OutputTest, canInstantiateOutput) {
152 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700153 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
155
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700156 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700157
158 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700159 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700160
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700161 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
162
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700163 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700164}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700165
Lloyd Pique66d68602019-02-13 14:23:31 -0800166/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700167 * Output::setCompositionEnabled()
168 */
169
170TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700171 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700173 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700174
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700175 EXPECT_TRUE(mOutput->getState().isEnabled);
176 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700177}
178
179TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700180 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700181
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700182 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700183
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700184 EXPECT_TRUE(mOutput->getState().isEnabled);
185 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700186}
187
188TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700189 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700190
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700191 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700192
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700193 EXPECT_FALSE(mOutput->getState().isEnabled);
194 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700195}
196
Lloyd Pique66d68602019-02-13 14:23:31 -0800197/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700198 * Output::setProjection()
199 */
200
201TEST_F(OutputTest, setProjectionTriviallyWorks) {
202 const ui::Transform transform{ui::Transform::ROT_180};
203 const int32_t orientation = 123;
204 const Rect frame{1, 2, 3, 4};
205 const Rect viewport{5, 6, 7, 8};
206 const Rect scissor{9, 10, 11, 12};
207 const bool needsFiltering = true;
208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 mOutput->setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700211 EXPECT_THAT(mOutput->getState().transform, TransformEq(transform));
212 EXPECT_EQ(orientation, mOutput->getState().orientation);
213 EXPECT_EQ(frame, mOutput->getState().frame);
214 EXPECT_EQ(viewport, mOutput->getState().viewport);
215 EXPECT_EQ(scissor, mOutput->getState().scissor);
216 EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217}
218
Lloyd Pique66d68602019-02-13 14:23:31 -0800219/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220 * Output::setBounds()
221 */
222
223TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800224 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700225
226 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
227 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
228
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->setBounds(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234}
235
Lloyd Pique66d68602019-02-13 14:23:31 -0800236/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237 * Output::setLayerStackFilter()
238 */
239
240TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700243
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700244 EXPECT_TRUE(mOutput->getState().layerStackInternal);
245 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700246
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700247 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700251 * Output::setColorTransform
252 */
253
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800254TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700255 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700256
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800257 // If no colorTransformMatrix is set the update should be skipped.
258 CompositionRefreshArgs refreshArgs;
259 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700260
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700261 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700262
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800263 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700264 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800265
266 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700267 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800268}
Lloyd Piqueef958122019-02-05 18:00:12 -0800269
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800270TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700271 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700272
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800273 // Attempting to set the same colorTransformMatrix that is already set should
274 // also skip the update.
275 CompositionRefreshArgs refreshArgs;
276 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700277
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700278 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700279
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800280 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700281 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800282
283 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700284 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800285}
286
287TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700288 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800289
290 // Setting a different colorTransformMatrix should perform the update.
291 CompositionRefreshArgs refreshArgs;
292 refreshArgs.colorTransformMatrix = kIdentity;
293
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700294 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800295
296 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700297 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800298
299 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700300 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800301}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700302
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800303TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700304 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700305
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800306 // Setting a different colorTransformMatrix should perform the update.
307 CompositionRefreshArgs refreshArgs;
308 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700309
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700310 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800311
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800312 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700313 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800314
315 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700316 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800317}
318
319TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700320 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800321
322 // Setting a different colorTransformMatrix should perform the update.
323 CompositionRefreshArgs refreshArgs;
324 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
325
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700326 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800327
328 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700329 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800330
331 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700332 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700333}
334
Lloyd Pique66d68602019-02-13 14:23:31 -0800335/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700336 * Output::setColorMode
337 */
338
Lloyd Piqueef958122019-02-05 18:00:12 -0800339TEST_F(OutputTest, setColorModeSetsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800340 using ColorProfile = Output::ColorProfile;
341
Lloyd Piquef5275482019-01-29 18:42:42 -0800342 EXPECT_CALL(*mDisplayColorProfile,
343 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
344 ui::Dataspace::UNKNOWN))
345 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800346 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700347
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700348 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
349 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
350 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700351
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700352 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
353 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
354 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
355 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800356
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700357 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800358}
359
360TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800361 using ColorProfile = Output::ColorProfile;
362
Lloyd Piquef5275482019-01-29 18:42:42 -0800363 EXPECT_CALL(*mDisplayColorProfile,
364 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
365 ui::Dataspace::UNKNOWN))
366 .WillOnce(Return(ui::Dataspace::UNKNOWN));
367
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700368 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
369 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
370 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
371 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800372
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700373 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
374 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
375 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800376
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700377 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700378}
379
Lloyd Pique66d68602019-02-13 14:23:31 -0800380/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700381 * Output::setRenderSurface()
382 */
383
384TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
385 const ui::Size newDisplaySize{640, 480};
386
387 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
388 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
389
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700390 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700391
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700392 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700393}
394
Lloyd Pique66d68602019-02-13 14:23:31 -0800395/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000396 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700397 */
398
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000399TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
400 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700401 mOutput->editState().viewport = viewport;
402 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700403
404 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700405 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700406
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000407 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700408 }
409}
410
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000411TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
412 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700413 mOutput->editState().viewport = viewport;
414 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415
416 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700417 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700418
419 // The dirtyRegion should be clipped to the display bounds.
420 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
421 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700422}
423
Lloyd Pique66d68602019-02-13 14:23:31 -0800424/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800425 * Output::belongsInOutput()
426 */
427
428TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
429 const uint32_t layerStack1 = 123u;
430 const uint32_t layerStack2 = 456u;
431
432 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700433 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800434
Lloyd Piquec6687342019-03-07 21:34:57 -0800435 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700436 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
437 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800438
Lloyd Piqueef36b002019-01-23 17:52:04 -0800439 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700440 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
441 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
442 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
443 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800444
445 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700446 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800447
448 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
450 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
451 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
452 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800453}
454
Lloyd Pique66c20c42019-03-07 21:44:02 -0800455TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
456 StrictMock<mock::Layer> layer;
Lloyd Pique9755fb72019-03-26 14:44:40 -0700457 LayerFECompositionState layerFEState;
Lloyd Pique66c20c42019-03-07 21:44:02 -0800458
Lloyd Pique9755fb72019-03-26 14:44:40 -0700459 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800460
461 const uint32_t layerStack1 = 123u;
462 const uint32_t layerStack2 = 456u;
463
464 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700465 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800466
467 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700468 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800469
470 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700471 layerFEState.layerStackId = std::nullopt;
472 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800474
Lloyd Pique9755fb72019-03-26 14:44:40 -0700475 layerFEState.layerStackId = std::nullopt;
476 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700477 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800478
479 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700480 layerFEState.layerStackId = layerStack1;
481 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800483
Lloyd Pique9755fb72019-03-26 14:44:40 -0700484 layerFEState.layerStackId = layerStack1;
485 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800487
Lloyd Pique9755fb72019-03-26 14:44:40 -0700488 layerFEState.layerStackId = layerStack2;
489 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800491
Lloyd Pique9755fb72019-03-26 14:44:40 -0700492 layerFEState.layerStackId = layerStack2;
493 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700494 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800495
496 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800498
499 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800501
502 // Only non-internal layers with layerStack1 belong to it.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700503 layerFEState.layerStackId = layerStack1;
504 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700505 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800506
Lloyd Pique9755fb72019-03-26 14:44:40 -0700507 layerFEState.layerStackId = layerStack1;
508 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800510
Lloyd Pique9755fb72019-03-26 14:44:40 -0700511 layerFEState.layerStackId = layerStack2;
512 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700513 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800514
Lloyd Pique9755fb72019-03-26 14:44:40 -0700515 layerFEState.layerStackId = layerStack2;
516 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700517 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800518}
519
Lloyd Pique66d68602019-02-13 14:23:31 -0800520/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800521 * Output::getOutputLayerForLayer()
522 */
523
524TEST_F(OutputTest, getOutputLayerForLayerWorks) {
525 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
526 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
527
Lloyd Pique01c77c12019-04-17 12:48:32 -0700528 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer1));
529 mOutput->injectOutputLayerForTest(nullptr);
530 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer2));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800531
532 StrictMock<mock::Layer> layer;
533 StrictMock<mock::Layer> otherLayer;
534
535 // If the input layer matches the first OutputLayer, it will be returned.
536 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700537 EXPECT_EQ(outputLayer1, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800538
539 // If the input layer matches the second OutputLayer, it will be returned.
540 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
541 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700542 EXPECT_EQ(outputLayer2, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800543
544 // If the input layer does not match an output layer, null will be returned.
545 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
546 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700547 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800548}
549
Lloyd Pique66d68602019-02-13 14:23:31 -0800550/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800551 * Output::setReleasedLayers()
552 */
553
554using OutputSetReleasedLayersTest = OutputTest;
555
556TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
557 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
558 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
559 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
560
561 Output::ReleasedLayers layers;
562 layers.push_back(layer1FE);
563 layers.push_back(layer2FE);
564 layers.push_back(layer3FE);
565
566 mOutput->setReleasedLayers(std::move(layers));
567
568 const auto& setLayers = mOutput->getReleasedLayersForTest();
569 ASSERT_EQ(3u, setLayers.size());
570 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
571 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
572 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
573}
574
575/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800576 * Output::updateLayerStateFromFE()
577 */
578
579using OutputUpdateLayerStateFromFETest = OutputLatchFEStateTest;
580
581TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
582 CompositionRefreshArgs refreshArgs;
583
584 mOutput->updateLayerStateFromFE(refreshArgs);
585}
586
587TEST_F(OutputUpdateLayerStateFromFETest, latchesContentStateForAllContainedLayers) {
588 EXPECT_CALL(mLayer1FE,
589 latchCompositionState(Ref(mLayer1FEState), LayerFE::StateSubset::Content));
590 EXPECT_CALL(mLayer2FE,
591 latchCompositionState(Ref(mLayer2FEState), LayerFE::StateSubset::Content));
592 EXPECT_CALL(mLayer3FE,
593 latchCompositionState(Ref(mLayer3FEState), LayerFE::StateSubset::Content));
594
595 // Note: Must be performed after any expectations on these mocks
596 injectLayer(std::move(mOutputLayer1));
597 injectLayer(std::move(mOutputLayer2));
598 injectLayer(std::move(mOutputLayer3));
599
600 CompositionRefreshArgs refreshArgs;
601 refreshArgs.updatingGeometryThisFrame = false;
602
603 mOutput->updateLayerStateFromFE(refreshArgs);
604}
605
606TEST_F(OutputUpdateLayerStateFromFETest, latchesGeometryAndContentStateForAllContainedLayers) {
607 EXPECT_CALL(mLayer1FE,
608 latchCompositionState(Ref(mLayer1FEState),
609 LayerFE::StateSubset::GeometryAndContent));
610 EXPECT_CALL(mLayer2FE,
611 latchCompositionState(Ref(mLayer2FEState),
612 LayerFE::StateSubset::GeometryAndContent));
613 EXPECT_CALL(mLayer3FE,
614 latchCompositionState(Ref(mLayer3FEState),
615 LayerFE::StateSubset::GeometryAndContent));
616
617 // Note: Must be performed after any expectations on these mocks
618 injectLayer(std::move(mOutputLayer1));
619 injectLayer(std::move(mOutputLayer2));
620 injectLayer(std::move(mOutputLayer3));
621
622 CompositionRefreshArgs refreshArgs;
623 refreshArgs.updatingGeometryThisFrame = true;
624
625 mOutput->updateLayerStateFromFE(refreshArgs);
626}
627
628/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800629 * Output::updateAndWriteCompositionState()
630 */
631
Lloyd Piqueef63b612019-11-14 13:19:56 -0800632using OutputUpdateAndWriteCompositionStateTest = OutputLatchFEStateTest;
633
634TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
635 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800636
637 CompositionRefreshArgs args;
638 mOutput->updateAndWriteCompositionState(args);
639}
640
Lloyd Piqueef63b612019-11-14 13:19:56 -0800641TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
642 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800643
Lloyd Piqueef63b612019-11-14 13:19:56 -0800644 injectLayer(std::move(mOutputLayer1));
645 injectLayer(std::move(mOutputLayer2));
646 injectLayer(std::move(mOutputLayer3));
647
648 CompositionRefreshArgs args;
649 mOutput->updateAndWriteCompositionState(args);
650}
651
652TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
653 EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, false));
654 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
655 EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, false));
656 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
657 EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, false));
658 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
659
660 injectLayer(std::move(mOutputLayer1));
661 injectLayer(std::move(mOutputLayer2));
662 injectLayer(std::move(mOutputLayer3));
663
664 mOutput->editState().isEnabled = true;
665
666 CompositionRefreshArgs args;
667 args.updatingGeometryThisFrame = false;
668 args.devOptForceClientComposition = false;
669 mOutput->updateAndWriteCompositionState(args);
670}
671
672TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
673 EXPECT_CALL(*mOutputLayer1, updateCompositionState(true, false));
674 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(true));
675 EXPECT_CALL(*mOutputLayer2, updateCompositionState(true, false));
676 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(true));
677 EXPECT_CALL(*mOutputLayer3, updateCompositionState(true, false));
678 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(true));
679
680 injectLayer(std::move(mOutputLayer1));
681 injectLayer(std::move(mOutputLayer2));
682 injectLayer(std::move(mOutputLayer3));
683
684 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800685
686 CompositionRefreshArgs args;
687 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800688 args.devOptForceClientComposition = false;
689 mOutput->updateAndWriteCompositionState(args);
690}
691
692TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
693 EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, true));
694 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
695 EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, true));
696 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
697 EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, true));
698 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
699
700 injectLayer(std::move(mOutputLayer1));
701 injectLayer(std::move(mOutputLayer2));
702 injectLayer(std::move(mOutputLayer3));
703
704 mOutput->editState().isEnabled = true;
705
706 CompositionRefreshArgs args;
707 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800708 args.devOptForceClientComposition = true;
709 mOutput->updateAndWriteCompositionState(args);
710}
711
712/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800713 * Output::prepareFrame()
714 */
715
716struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800717 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique66d68602019-02-13 14:23:31 -0800718 // Sets up the helper functions called by prepareFrame to use a mock
719 // implementations.
720 MOCK_METHOD0(chooseCompositionStrategy, void());
721 };
722
723 OutputPrepareFrameTest() {
724 mOutput.setDisplayColorProfileForTest(
725 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
726 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
727 }
728
729 StrictMock<mock::CompositionEngine> mCompositionEngine;
730 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
731 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700732 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800733};
734
735TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
736 mOutput.editState().isEnabled = false;
737
738 mOutput.prepareFrame();
739}
740
741TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
742 mOutput.editState().isEnabled = true;
743 mOutput.editState().usesClientComposition = false;
744 mOutput.editState().usesDeviceComposition = true;
745
746 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
747 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
748
749 mOutput.prepareFrame();
750}
751
752// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
753// base chooseCompositionStrategy() is invoked.
754TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700755 mOutput->editState().isEnabled = true;
756 mOutput->editState().usesClientComposition = false;
757 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800758
759 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
760
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700761 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800762
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700763 EXPECT_TRUE(mOutput->getState().usesClientComposition);
764 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800765}
766
Lloyd Pique56eba802019-08-28 15:45:25 -0700767/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800768 * Output::present()
769 */
770
771struct OutputPresentTest : public testing::Test {
772 struct OutputPartialMock : public OutputPartialMockBase {
773 // All child helper functions Output::present() are defined as mocks,
774 // and those are tested separately, allowing the present() test to
775 // just cover the high level flow.
776 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
777 MOCK_METHOD1(updateAndWriteCompositionState,
778 void(const compositionengine::CompositionRefreshArgs&));
779 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
780 MOCK_METHOD0(beginFrame, void());
781 MOCK_METHOD0(prepareFrame, void());
782 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
783 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
784 MOCK_METHOD0(postFramebuffer, void());
785 };
786
787 StrictMock<OutputPartialMock> mOutput;
788};
789
790TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
791 CompositionRefreshArgs args;
792
793 InSequence seq;
794 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
795 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
796 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
797 EXPECT_CALL(mOutput, beginFrame());
798 EXPECT_CALL(mOutput, prepareFrame());
799 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
800 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
801 EXPECT_CALL(mOutput, postFramebuffer());
802
803 mOutput.present(args);
804}
805
806/*
807 * Output::updateColorProfile()
808 */
809
810// TODO(b/144060211) - Add coverage
811
812/*
813 * Output::beginFrame()
814 */
815
816/*
817 * Output::devOptRepaintFlash()
818 */
819
820// TODO(b/144060211) - Add coverage
821
822/*
823 * Output::finishFrame()
824 */
825
826// TODO(b/144060211) - Add coverage
827
828/*
829 * Output::postFramebuffer()
830 */
831
832// TODO(b/144060211) - Add coverage
833
834/*
Lloyd Pique56eba802019-08-28 15:45:25 -0700835 * Output::composeSurfaces()
836 */
837
838struct OutputComposeSurfacesTest : public testing::Test {
839 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
840 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
841
842 static const Rect kDefaultOutputFrame;
843 static const Rect kDefaultOutputViewport;
844 static const Rect kDefaultOutputScissor;
845 static const mat4 kDefaultColorTransformMat;
846
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800847 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique56eba802019-08-28 15:45:25 -0700848 // Sets up the helper functions called by composeSurfaces to use a mock
849 // implementations.
850 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
851 MOCK_METHOD2(generateClientCompositionRequests,
852 std::vector<renderengine::LayerSettings>(bool, Region&));
853 MOCK_METHOD2(appendRegionFlashRequests,
854 void(const Region&, std::vector<renderengine::LayerSettings>&));
855 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
856 };
857
858 OutputComposeSurfacesTest() {
859 mOutput.setDisplayColorProfileForTest(
860 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
861 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
862
Lloyd Pique56eba802019-08-28 15:45:25 -0700863 mOutput.editState().frame = kDefaultOutputFrame;
864 mOutput.editState().viewport = kDefaultOutputViewport;
865 mOutput.editState().scissor = kDefaultOutputScissor;
866 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
867 mOutput.editState().orientation = kDefaultOutputOrientation;
868 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800869 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700870 mOutput.editState().isSecure = true;
871 mOutput.editState().needsFiltering = false;
872 mOutput.editState().usesClientComposition = true;
873 mOutput.editState().usesDeviceComposition = false;
874
Lloyd Pique01c77c12019-04-17 12:48:32 -0700875 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
876 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
877 .WillRepeatedly(Return(&mOutputLayer1));
878 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
879 .WillRepeatedly(Return(&mOutputLayer2));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700880 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -0700881 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
882 }
883
884 StrictMock<mock::CompositionEngine> mCompositionEngine;
885 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
886 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
887 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700888 StrictMock<mock::OutputLayer> mOutputLayer1;
889 StrictMock<mock::OutputLayer> mOutputLayer2;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700890 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700891 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
892};
893
894const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
895const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
896const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
897const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
898
899// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
900// basic tests.
901
902TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
903 mOutput.editState().usesClientComposition = false;
904
905 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800906 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
907 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700908}
909
910TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
911 const Region kDebugRegion{Rect{100, 101, 102, 103}};
912
913 constexpr float kDefaultMaxLuminance = 1.0f;
914 constexpr float kDefaultAvgLuminance = 0.7f;
915 constexpr float kDefaultMinLuminance = 0.1f;
916 HdrCapabilities HdrCapabilities{{},
917 kDefaultMaxLuminance,
918 kDefaultAvgLuminance,
919 kDefaultMinLuminance};
920
921 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
922 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
923
924 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
925 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
926
927 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
928
929 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
930 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
931 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
932 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
933 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
934
Lloyd Piqued3d69882019-02-28 16:03:46 -0800935 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
936 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700937}
938
939/*
940 * Output::generateClientCompositionRequests()
941 */
942
943struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800944 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700945 // compositionengine::Output overrides
Lloyd Pique56eba802019-08-28 15:45:25 -0700946 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
947 bool supportsProtectedContent, Region& clearRegion) override {
948 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
949 clearRegion);
950 }
951 };
952
953 GenerateClientCompositionRequestsTest() {
954 mOutput.setDisplayColorProfileForTest(
955 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
956 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
957 }
958
Lloyd Pique56eba802019-08-28 15:45:25 -0700959 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
960 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700961 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700962};
963
964// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
965
966TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
967 // In split-screen landscape mode, the screen is rotated 90 degrees, with
968 // one layer on the left covering the left side of the output, and one layer
969 // on the right covering that side of the output.
970
Lloyd Pique01c77c12019-04-17 12:48:32 -0700971 StrictMock<mock::OutputLayer> leftOutputLayer;
972 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700973
974 StrictMock<mock::Layer> leftLayer;
975 StrictMock<mock::LayerFE> leftLayerFE;
976 StrictMock<mock::Layer> rightLayer;
977 StrictMock<mock::LayerFE> rightLayerFE;
978
979 impl::OutputLayerCompositionState leftOutputLayerState;
980 leftOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800981 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700982
Lloyd Pique9755fb72019-03-26 14:44:40 -0700983 LayerFECompositionState leftLayerFEState;
984 leftLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700985
986 const half3 leftLayerColor{1.f, 0.f, 0.f};
987 renderengine::LayerSettings leftLayerRESettings;
988 leftLayerRESettings.source.solidColor = leftLayerColor;
989
990 impl::OutputLayerCompositionState rightOutputLayerState;
991 rightOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800992 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700993
Lloyd Pique9755fb72019-03-26 14:44:40 -0700994 LayerFECompositionState rightLayerFEState;
995 rightLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700996
997 const half3 rightLayerColor{0.f, 1.f, 0.f};
998 renderengine::LayerSettings rightLayerRESettings;
999 rightLayerRESettings.source.solidColor = rightLayerColor;
1000
Lloyd Pique01c77c12019-04-17 12:48:32 -07001001 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
1002 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
1003 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
1004 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
1005 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001006 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001007 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001008 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001009
Lloyd Pique01c77c12019-04-17 12:48:32 -07001010 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
1011 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
1012 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
1013 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
1014 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001015 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001016 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001017 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001018
Lloyd Pique01c77c12019-04-17 12:48:32 -07001019 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1020 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1021 .WillRepeatedly(Return(&leftOutputLayer));
1022 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
1023 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -07001024
1025 const Rect kPortraitFrame(0, 0, 1000, 2000);
1026 const Rect kPortraitViewport(0, 0, 2000, 1000);
1027 const Rect kPortraitScissor(0, 0, 1000, 2000);
1028 const uint32_t kPortraitOrientation = TR_ROT_90;
1029
1030 mOutput.editState().frame = kPortraitFrame;
1031 mOutput.editState().viewport = kPortraitViewport;
1032 mOutput.editState().scissor = kPortraitScissor;
1033 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1034 mOutput.editState().orientation = kPortraitOrientation;
1035 mOutput.editState().needsFiltering = true;
1036 mOutput.editState().isSecure = false;
1037
1038 constexpr bool supportsProtectedContent = false;
1039 Region clearRegion;
1040 auto requests =
1041 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1042
1043 ASSERT_EQ(2u, requests.size());
1044 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
1045 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
1046}
1047
1048TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
1049 // Layers whose visible region does not intersect with the viewport will be
1050 // skipped when generating client composition request state.
1051
Lloyd Pique01c77c12019-04-17 12:48:32 -07001052 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -07001053 StrictMock<mock::Layer> layer;
1054 StrictMock<mock::LayerFE> layerFE;
1055
1056 impl::OutputLayerCompositionState outputLayerState;
1057 outputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -08001058 outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -07001059
Lloyd Pique9755fb72019-03-26 14:44:40 -07001060 LayerFECompositionState layerFEState;
1061 layerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07001062
Lloyd Pique01c77c12019-04-17 12:48:32 -07001063 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1064 EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
1065 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
1066 EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
1067 EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001068 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001069 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001070 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001071
Lloyd Pique01c77c12019-04-17 12:48:32 -07001072 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
1073 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -07001074
1075 const Rect kPortraitFrame(0, 0, 1000, 2000);
1076 const Rect kPortraitViewport(0, 0, 2000, 1000);
1077 const Rect kPortraitScissor(0, 0, 1000, 2000);
1078 const uint32_t kPortraitOrientation = TR_ROT_90;
1079
1080 mOutput.editState().frame = kPortraitFrame;
1081 mOutput.editState().viewport = kPortraitViewport;
1082 mOutput.editState().scissor = kPortraitScissor;
1083 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1084 mOutput.editState().orientation = kPortraitOrientation;
1085 mOutput.editState().needsFiltering = true;
1086 mOutput.editState().isSecure = false;
1087
1088 constexpr bool supportsProtectedContent = false;
1089 Region clearRegion;
1090 auto requests =
1091 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1092
1093 EXPECT_EQ(0u, requests.size());
1094}
1095
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001096TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
1097 // If client composition is performed with some layers set to use device
1098 // composition, device layers after the first layer (device or client) will
1099 // clear the frame buffer if they are opaque and if that layer has a flag
1100 // set to do so. The first layer is skipped as the frame buffer is already
1101 // expected to be clear.
1102
Lloyd Pique01c77c12019-04-17 12:48:32 -07001103 StrictMock<mock::OutputLayer> leftOutputLayer;
1104 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001105
1106 StrictMock<mock::Layer> leftLayer;
1107 StrictMock<mock::LayerFE> leftLayerFE;
1108 StrictMock<mock::Layer> rightLayer;
1109 StrictMock<mock::LayerFE> rightLayerFE;
1110
1111 impl::OutputLayerCompositionState leftOutputLayerState;
1112 leftOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001113 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001114
Lloyd Pique9755fb72019-03-26 14:44:40 -07001115 LayerFECompositionState leftLayerFEState;
1116 leftLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001117
1118 impl::OutputLayerCompositionState rightOutputLayerState;
1119 rightOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001120 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001121
Lloyd Pique9755fb72019-03-26 14:44:40 -07001122 LayerFECompositionState rightLayerFEState;
1123 rightLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001124
1125 const half3 rightLayerColor{0.f, 1.f, 0.f};
1126 renderengine::LayerSettings rightLayerRESettings;
1127 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
1128 rightLayerRESettings.source.solidColor = rightLayerColor;
1129
Lloyd Pique01c77c12019-04-17 12:48:32 -07001130 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
1131 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
1132 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
1133 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1134 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001135 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001136 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001137
Lloyd Pique01c77c12019-04-17 12:48:32 -07001138 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
1139 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
1140 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
1141 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1142 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001143 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001144 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001145 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001146
Lloyd Pique01c77c12019-04-17 12:48:32 -07001147 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1148 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1149 .WillRepeatedly(Return(&leftOutputLayer));
1150 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
1151 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001152
1153 const Rect kPortraitFrame(0, 0, 1000, 2000);
1154 const Rect kPortraitViewport(0, 0, 2000, 1000);
1155 const Rect kPortraitScissor(0, 0, 1000, 2000);
1156 const uint32_t kPortraitOrientation = TR_ROT_90;
1157
1158 mOutput.editState().frame = kPortraitFrame;
1159 mOutput.editState().viewport = kPortraitViewport;
1160 mOutput.editState().scissor = kPortraitScissor;
1161 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1162 mOutput.editState().orientation = kPortraitOrientation;
1163 mOutput.editState().needsFiltering = true;
1164 mOutput.editState().isSecure = false;
1165
1166 constexpr bool supportsProtectedContent = false;
1167 Region clearRegion;
1168 auto requests =
1169 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1170
1171 const half3 clearColor{0.f, 0.f, 0.f};
1172
1173 ASSERT_EQ(1u, requests.size());
1174 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
1175 EXPECT_EQ(clearColor, requests[0].source.solidColor);
1176}
1177
Lloyd Pique32cbe282018-10-19 13:09:22 -07001178} // namespace
1179} // namespace android::compositionengine