blob: 3b1f07c3ba2425a72ead00cdb7a2582c76e0c5b0 [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
632TEST_F(OutputTest, updateAndWriteCompositionState_takesEarlyOutIfNotEnabled) {
633 mOutput->editState().isEnabled = false;
634
635 CompositionRefreshArgs args;
636 mOutput->updateAndWriteCompositionState(args);
637}
638
639TEST_F(OutputTest, updateAndWriteCompositionState_updatesLayers) {
640 mOutput->editState().isEnabled = true;
641 mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>();
642 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer));
643
644 EXPECT_CALL(*outputLayer, updateCompositionState(true, true)).Times(1);
645 EXPECT_CALL(*outputLayer, writeStateToHWC(true)).Times(1);
646
647 CompositionRefreshArgs args;
648 args.updatingGeometryThisFrame = true;
649 args.devOptForceClientComposition = true;
650 mOutput->updateAndWriteCompositionState(args);
651}
652
653/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800654 * Output::prepareFrame()
655 */
656
657struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800658 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique66d68602019-02-13 14:23:31 -0800659 // Sets up the helper functions called by prepareFrame to use a mock
660 // implementations.
661 MOCK_METHOD0(chooseCompositionStrategy, void());
662 };
663
664 OutputPrepareFrameTest() {
665 mOutput.setDisplayColorProfileForTest(
666 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
667 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
668 }
669
670 StrictMock<mock::CompositionEngine> mCompositionEngine;
671 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
672 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700673 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800674};
675
676TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
677 mOutput.editState().isEnabled = false;
678
679 mOutput.prepareFrame();
680}
681
682TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
683 mOutput.editState().isEnabled = true;
684 mOutput.editState().usesClientComposition = false;
685 mOutput.editState().usesDeviceComposition = true;
686
687 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
688 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
689
690 mOutput.prepareFrame();
691}
692
693// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
694// base chooseCompositionStrategy() is invoked.
695TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700696 mOutput->editState().isEnabled = true;
697 mOutput->editState().usesClientComposition = false;
698 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800699
700 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
701
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700702 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800703
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700704 EXPECT_TRUE(mOutput->getState().usesClientComposition);
705 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800706}
707
Lloyd Pique56eba802019-08-28 15:45:25 -0700708/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800709 * Output::present()
710 */
711
712struct OutputPresentTest : public testing::Test {
713 struct OutputPartialMock : public OutputPartialMockBase {
714 // All child helper functions Output::present() are defined as mocks,
715 // and those are tested separately, allowing the present() test to
716 // just cover the high level flow.
717 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
718 MOCK_METHOD1(updateAndWriteCompositionState,
719 void(const compositionengine::CompositionRefreshArgs&));
720 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
721 MOCK_METHOD0(beginFrame, void());
722 MOCK_METHOD0(prepareFrame, void());
723 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
724 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
725 MOCK_METHOD0(postFramebuffer, void());
726 };
727
728 StrictMock<OutputPartialMock> mOutput;
729};
730
731TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
732 CompositionRefreshArgs args;
733
734 InSequence seq;
735 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
736 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
737 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
738 EXPECT_CALL(mOutput, beginFrame());
739 EXPECT_CALL(mOutput, prepareFrame());
740 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
741 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
742 EXPECT_CALL(mOutput, postFramebuffer());
743
744 mOutput.present(args);
745}
746
747/*
748 * Output::updateColorProfile()
749 */
750
751// TODO(b/144060211) - Add coverage
752
753/*
754 * Output::beginFrame()
755 */
756
757/*
758 * Output::devOptRepaintFlash()
759 */
760
761// TODO(b/144060211) - Add coverage
762
763/*
764 * Output::finishFrame()
765 */
766
767// TODO(b/144060211) - Add coverage
768
769/*
770 * Output::postFramebuffer()
771 */
772
773// TODO(b/144060211) - Add coverage
774
775/*
Lloyd Pique56eba802019-08-28 15:45:25 -0700776 * Output::composeSurfaces()
777 */
778
779struct OutputComposeSurfacesTest : public testing::Test {
780 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
781 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
782
783 static const Rect kDefaultOutputFrame;
784 static const Rect kDefaultOutputViewport;
785 static const Rect kDefaultOutputScissor;
786 static const mat4 kDefaultColorTransformMat;
787
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800788 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique56eba802019-08-28 15:45:25 -0700789 // Sets up the helper functions called by composeSurfaces to use a mock
790 // implementations.
791 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
792 MOCK_METHOD2(generateClientCompositionRequests,
793 std::vector<renderengine::LayerSettings>(bool, Region&));
794 MOCK_METHOD2(appendRegionFlashRequests,
795 void(const Region&, std::vector<renderengine::LayerSettings>&));
796 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
797 };
798
799 OutputComposeSurfacesTest() {
800 mOutput.setDisplayColorProfileForTest(
801 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
802 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
803
Lloyd Pique56eba802019-08-28 15:45:25 -0700804 mOutput.editState().frame = kDefaultOutputFrame;
805 mOutput.editState().viewport = kDefaultOutputViewport;
806 mOutput.editState().scissor = kDefaultOutputScissor;
807 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
808 mOutput.editState().orientation = kDefaultOutputOrientation;
809 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800810 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700811 mOutput.editState().isSecure = true;
812 mOutput.editState().needsFiltering = false;
813 mOutput.editState().usesClientComposition = true;
814 mOutput.editState().usesDeviceComposition = false;
815
Lloyd Pique01c77c12019-04-17 12:48:32 -0700816 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
817 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
818 .WillRepeatedly(Return(&mOutputLayer1));
819 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
820 .WillRepeatedly(Return(&mOutputLayer2));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700821 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -0700822 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
823 }
824
825 StrictMock<mock::CompositionEngine> mCompositionEngine;
826 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
827 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
828 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700829 StrictMock<mock::OutputLayer> mOutputLayer1;
830 StrictMock<mock::OutputLayer> mOutputLayer2;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700831 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700832 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
833};
834
835const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
836const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
837const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
838const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
839
840// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
841// basic tests.
842
843TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
844 mOutput.editState().usesClientComposition = false;
845
846 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800847 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
848 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700849}
850
851TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
852 const Region kDebugRegion{Rect{100, 101, 102, 103}};
853
854 constexpr float kDefaultMaxLuminance = 1.0f;
855 constexpr float kDefaultAvgLuminance = 0.7f;
856 constexpr float kDefaultMinLuminance = 0.1f;
857 HdrCapabilities HdrCapabilities{{},
858 kDefaultMaxLuminance,
859 kDefaultAvgLuminance,
860 kDefaultMinLuminance};
861
862 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
863 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
864
865 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
866 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
867
868 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
869
870 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
871 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
872 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
873 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
874 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
875
Lloyd Piqued3d69882019-02-28 16:03:46 -0800876 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
877 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700878}
879
880/*
881 * Output::generateClientCompositionRequests()
882 */
883
884struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800885 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700886 // compositionengine::Output overrides
Lloyd Pique56eba802019-08-28 15:45:25 -0700887 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
888 bool supportsProtectedContent, Region& clearRegion) override {
889 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
890 clearRegion);
891 }
892 };
893
894 GenerateClientCompositionRequestsTest() {
895 mOutput.setDisplayColorProfileForTest(
896 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
897 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
898 }
899
Lloyd Pique56eba802019-08-28 15:45:25 -0700900 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
901 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700902 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700903};
904
905// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
906
907TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
908 // In split-screen landscape mode, the screen is rotated 90 degrees, with
909 // one layer on the left covering the left side of the output, and one layer
910 // on the right covering that side of the output.
911
Lloyd Pique01c77c12019-04-17 12:48:32 -0700912 StrictMock<mock::OutputLayer> leftOutputLayer;
913 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700914
915 StrictMock<mock::Layer> leftLayer;
916 StrictMock<mock::LayerFE> leftLayerFE;
917 StrictMock<mock::Layer> rightLayer;
918 StrictMock<mock::LayerFE> rightLayerFE;
919
920 impl::OutputLayerCompositionState leftOutputLayerState;
921 leftOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800922 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700923
Lloyd Pique9755fb72019-03-26 14:44:40 -0700924 LayerFECompositionState leftLayerFEState;
925 leftLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700926
927 const half3 leftLayerColor{1.f, 0.f, 0.f};
928 renderengine::LayerSettings leftLayerRESettings;
929 leftLayerRESettings.source.solidColor = leftLayerColor;
930
931 impl::OutputLayerCompositionState rightOutputLayerState;
932 rightOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800933 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700934
Lloyd Pique9755fb72019-03-26 14:44:40 -0700935 LayerFECompositionState rightLayerFEState;
936 rightLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700937
938 const half3 rightLayerColor{0.f, 1.f, 0.f};
939 renderengine::LayerSettings rightLayerRESettings;
940 rightLayerRESettings.source.solidColor = rightLayerColor;
941
Lloyd Pique01c77c12019-04-17 12:48:32 -0700942 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
943 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
944 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
945 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
946 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700947 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700948 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800949 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700950
Lloyd Pique01c77c12019-04-17 12:48:32 -0700951 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
952 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
953 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
954 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
955 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700956 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700957 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800958 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700959
Lloyd Pique01c77c12019-04-17 12:48:32 -0700960 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
961 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
962 .WillRepeatedly(Return(&leftOutputLayer));
963 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
964 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -0700965
966 const Rect kPortraitFrame(0, 0, 1000, 2000);
967 const Rect kPortraitViewport(0, 0, 2000, 1000);
968 const Rect kPortraitScissor(0, 0, 1000, 2000);
969 const uint32_t kPortraitOrientation = TR_ROT_90;
970
971 mOutput.editState().frame = kPortraitFrame;
972 mOutput.editState().viewport = kPortraitViewport;
973 mOutput.editState().scissor = kPortraitScissor;
974 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
975 mOutput.editState().orientation = kPortraitOrientation;
976 mOutput.editState().needsFiltering = true;
977 mOutput.editState().isSecure = false;
978
979 constexpr bool supportsProtectedContent = false;
980 Region clearRegion;
981 auto requests =
982 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
983
984 ASSERT_EQ(2u, requests.size());
985 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
986 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
987}
988
989TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
990 // Layers whose visible region does not intersect with the viewport will be
991 // skipped when generating client composition request state.
992
Lloyd Pique01c77c12019-04-17 12:48:32 -0700993 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700994 StrictMock<mock::Layer> layer;
995 StrictMock<mock::LayerFE> layerFE;
996
997 impl::OutputLayerCompositionState outputLayerState;
998 outputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800999 outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -07001000
Lloyd Pique9755fb72019-03-26 14:44:40 -07001001 LayerFECompositionState layerFEState;
1002 layerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -07001003
Lloyd Pique01c77c12019-04-17 12:48:32 -07001004 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1005 EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
1006 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
1007 EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
1008 EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001009 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001010 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001011 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -07001012
Lloyd Pique01c77c12019-04-17 12:48:32 -07001013 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
1014 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -07001015
1016 const Rect kPortraitFrame(0, 0, 1000, 2000);
1017 const Rect kPortraitViewport(0, 0, 2000, 1000);
1018 const Rect kPortraitScissor(0, 0, 1000, 2000);
1019 const uint32_t kPortraitOrientation = TR_ROT_90;
1020
1021 mOutput.editState().frame = kPortraitFrame;
1022 mOutput.editState().viewport = kPortraitViewport;
1023 mOutput.editState().scissor = kPortraitScissor;
1024 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1025 mOutput.editState().orientation = kPortraitOrientation;
1026 mOutput.editState().needsFiltering = true;
1027 mOutput.editState().isSecure = false;
1028
1029 constexpr bool supportsProtectedContent = false;
1030 Region clearRegion;
1031 auto requests =
1032 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1033
1034 EXPECT_EQ(0u, requests.size());
1035}
1036
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001037TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
1038 // If client composition is performed with some layers set to use device
1039 // composition, device layers after the first layer (device or client) will
1040 // clear the frame buffer if they are opaque and if that layer has a flag
1041 // set to do so. The first layer is skipped as the frame buffer is already
1042 // expected to be clear.
1043
Lloyd Pique01c77c12019-04-17 12:48:32 -07001044 StrictMock<mock::OutputLayer> leftOutputLayer;
1045 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001046
1047 StrictMock<mock::Layer> leftLayer;
1048 StrictMock<mock::LayerFE> leftLayerFE;
1049 StrictMock<mock::Layer> rightLayer;
1050 StrictMock<mock::LayerFE> rightLayerFE;
1051
1052 impl::OutputLayerCompositionState leftOutputLayerState;
1053 leftOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001054 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001055
Lloyd Pique9755fb72019-03-26 14:44:40 -07001056 LayerFECompositionState leftLayerFEState;
1057 leftLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001058
1059 impl::OutputLayerCompositionState rightOutputLayerState;
1060 rightOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -08001061 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001062
Lloyd Pique9755fb72019-03-26 14:44:40 -07001063 LayerFECompositionState rightLayerFEState;
1064 rightLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001065
1066 const half3 rightLayerColor{0.f, 1.f, 0.f};
1067 renderengine::LayerSettings rightLayerRESettings;
1068 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
1069 rightLayerRESettings.source.solidColor = rightLayerColor;
1070
Lloyd Pique01c77c12019-04-17 12:48:32 -07001071 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
1072 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
1073 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
1074 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1075 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001076 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001077 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001078
Lloyd Pique01c77c12019-04-17 12:48:32 -07001079 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
1080 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
1081 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
1082 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
1083 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -07001084 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001085 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -08001086 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001087
Lloyd Pique01c77c12019-04-17 12:48:32 -07001088 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
1089 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1090 .WillRepeatedly(Return(&leftOutputLayer));
1091 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
1092 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001093
1094 const Rect kPortraitFrame(0, 0, 1000, 2000);
1095 const Rect kPortraitViewport(0, 0, 2000, 1000);
1096 const Rect kPortraitScissor(0, 0, 1000, 2000);
1097 const uint32_t kPortraitOrientation = TR_ROT_90;
1098
1099 mOutput.editState().frame = kPortraitFrame;
1100 mOutput.editState().viewport = kPortraitViewport;
1101 mOutput.editState().scissor = kPortraitScissor;
1102 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1103 mOutput.editState().orientation = kPortraitOrientation;
1104 mOutput.editState().needsFiltering = true;
1105 mOutput.editState().isSecure = false;
1106
1107 constexpr bool supportsProtectedContent = false;
1108 Region clearRegion;
1109 auto requests =
1110 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1111
1112 const half3 clearColor{0.f, 0.f, 0.f};
1113
1114 ASSERT_EQ(1u, requests.size());
1115 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
1116 EXPECT_EQ(clearColor, requests[0].source.solidColor);
1117}
1118
Lloyd Pique32cbe282018-10-19 13:09:22 -07001119} // namespace
1120} // namespace android::compositionengine