blob: 09ddc601ec70510ea6d088dc91cb2df807c35607 [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 Piqueef958122019-02-05 18:00:12 -0800107const Rect OutputTest::kDefaultDisplaySize{100, 200};
108
Lloyd Pique66d68602019-02-13 14:23:31 -0800109/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700110 * Basic construction
111 */
112
Lloyd Pique31cb2942018-10-19 17:23:03 -0700113TEST_F(OutputTest, canInstantiateOutput) {
114 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700115 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700116 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
117
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700118 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700119
120 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700121 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700122
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700123 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
124
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700125 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700126}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700127
Lloyd Pique66d68602019-02-13 14:23:31 -0800128/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700129 * Output::setCompositionEnabled()
130 */
131
132TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700133 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700134
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700135 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700136
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700137 EXPECT_TRUE(mOutput->getState().isEnabled);
138 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700139}
140
141TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700142 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700143
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700144 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700145
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700146 EXPECT_TRUE(mOutput->getState().isEnabled);
147 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700148}
149
150TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700151 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700153 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700154
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700155 EXPECT_FALSE(mOutput->getState().isEnabled);
156 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700157}
158
Lloyd Pique66d68602019-02-13 14:23:31 -0800159/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700160 * Output::setProjection()
161 */
162
163TEST_F(OutputTest, setProjectionTriviallyWorks) {
164 const ui::Transform transform{ui::Transform::ROT_180};
165 const int32_t orientation = 123;
166 const Rect frame{1, 2, 3, 4};
167 const Rect viewport{5, 6, 7, 8};
168 const Rect scissor{9, 10, 11, 12};
169 const bool needsFiltering = true;
170
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700171 mOutput->setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700172
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700173 EXPECT_THAT(mOutput->getState().transform, TransformEq(transform));
174 EXPECT_EQ(orientation, mOutput->getState().orientation);
175 EXPECT_EQ(frame, mOutput->getState().frame);
176 EXPECT_EQ(viewport, mOutput->getState().viewport);
177 EXPECT_EQ(scissor, mOutput->getState().scissor);
178 EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700179}
180
Lloyd Pique66d68602019-02-13 14:23:31 -0800181/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700182 * Output::setBounds()
183 */
184
185TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800186 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700187
188 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
189 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
190
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700191 mOutput->setBounds(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700192
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700193 EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700194
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700195 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700196}
197
Lloyd Pique66d68602019-02-13 14:23:31 -0800198/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700199 * Output::setLayerStackFilter()
200 */
201
202TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700203 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700204 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700205
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 EXPECT_TRUE(mOutput->getState().layerStackInternal);
207 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210}
211
Lloyd Pique66d68602019-02-13 14:23:31 -0800212/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700213 * Output::setColorTransform
214 */
215
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800216TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700217 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800219 // If no colorTransformMatrix is set the update should be skipped.
220 CompositionRefreshArgs refreshArgs;
221 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700223 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800225 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800227
228 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800230}
Lloyd Piqueef958122019-02-05 18:00:12 -0800231
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800232TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700234
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800235 // Attempting to set the same colorTransformMatrix that is already set should
236 // also skip the update.
237 CompositionRefreshArgs refreshArgs;
238 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700241
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800242 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700243 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800244
245 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700246 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800247}
248
249TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700250 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800251
252 // Setting a different colorTransformMatrix should perform the update.
253 CompositionRefreshArgs refreshArgs;
254 refreshArgs.colorTransformMatrix = kIdentity;
255
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700256 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800257
258 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700259 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800260
261 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700262 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800263}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700264
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800265TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700266 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700267
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800268 // Setting a different colorTransformMatrix should perform the update.
269 CompositionRefreshArgs refreshArgs;
270 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700271
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700272 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800273
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800274 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700275 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800276
277 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700278 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800279}
280
281TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700282 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800283
284 // Setting a different colorTransformMatrix should perform the update.
285 CompositionRefreshArgs refreshArgs;
286 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
287
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700288 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800289
290 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700291 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800292
293 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700294 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700295}
296
Lloyd Pique66d68602019-02-13 14:23:31 -0800297/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700298 * Output::setColorMode
299 */
300
Lloyd Piqueef958122019-02-05 18:00:12 -0800301TEST_F(OutputTest, setColorModeSetsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800302 using ColorProfile = Output::ColorProfile;
303
Lloyd Piquef5275482019-01-29 18:42:42 -0800304 EXPECT_CALL(*mDisplayColorProfile,
305 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
306 ui::Dataspace::UNKNOWN))
307 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800308 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700309
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700310 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
311 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
312 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700313
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700314 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
315 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
316 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
317 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800318
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700319 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800320}
321
322TEST_F(OutputTest, setColorModeDoesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800323 using ColorProfile = Output::ColorProfile;
324
Lloyd Piquef5275482019-01-29 18:42:42 -0800325 EXPECT_CALL(*mDisplayColorProfile,
326 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
327 ui::Dataspace::UNKNOWN))
328 .WillOnce(Return(ui::Dataspace::UNKNOWN));
329
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700330 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
331 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
332 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
333 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800334
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700335 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
336 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
337 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800338
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700339 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700340}
341
Lloyd Pique66d68602019-02-13 14:23:31 -0800342/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700343 * Output::setRenderSurface()
344 */
345
346TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
347 const ui::Size newDisplaySize{640, 480};
348
349 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
350 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
351
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700352 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700353
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700354 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700355}
356
Lloyd Pique66d68602019-02-13 14:23:31 -0800357/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000358 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700359 */
360
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000361TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
362 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700363 mOutput->editState().viewport = viewport;
364 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700365
366 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700367 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700368
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000369 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700370 }
371}
372
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000373TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
374 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700375 mOutput->editState().viewport = viewport;
376 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700377
378 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700379 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700380
381 // The dirtyRegion should be clipped to the display bounds.
382 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
383 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700384}
385
Lloyd Pique66d68602019-02-13 14:23:31 -0800386/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800387 * Output::belongsInOutput()
388 */
389
390TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
391 const uint32_t layerStack1 = 123u;
392 const uint32_t layerStack2 = 456u;
393
394 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700395 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800396
Lloyd Piquec6687342019-03-07 21:34:57 -0800397 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700398 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
399 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800400
Lloyd Piqueef36b002019-01-23 17:52:04 -0800401 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700402 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
403 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
404 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
405 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800406
407 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700408 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800409
410 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700411 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
412 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
413 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
414 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800415}
416
Lloyd Pique66c20c42019-03-07 21:44:02 -0800417TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
418 StrictMock<mock::Layer> layer;
Lloyd Pique9755fb72019-03-26 14:44:40 -0700419 LayerFECompositionState layerFEState;
Lloyd Pique66c20c42019-03-07 21:44:02 -0800420
Lloyd Pique9755fb72019-03-26 14:44:40 -0700421 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800422
423 const uint32_t layerStack1 = 123u;
424 const uint32_t layerStack2 = 456u;
425
426 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700427 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800428
429 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700430 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800431
432 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700433 layerFEState.layerStackId = std::nullopt;
434 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700435 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800436
Lloyd Pique9755fb72019-03-26 14:44:40 -0700437 layerFEState.layerStackId = std::nullopt;
438 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700439 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800440
441 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700442 layerFEState.layerStackId = layerStack1;
443 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700444 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800445
Lloyd Pique9755fb72019-03-26 14:44:40 -0700446 layerFEState.layerStackId = layerStack1;
447 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700448 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800449
Lloyd Pique9755fb72019-03-26 14:44:40 -0700450 layerFEState.layerStackId = layerStack2;
451 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700452 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800453
Lloyd Pique9755fb72019-03-26 14:44:40 -0700454 layerFEState.layerStackId = layerStack2;
455 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700456 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800457
458 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700459 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800460
461 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700462 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800463
464 // Only non-internal layers with layerStack1 belong to it.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700465 layerFEState.layerStackId = layerStack1;
466 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800468
Lloyd Pique9755fb72019-03-26 14:44:40 -0700469 layerFEState.layerStackId = layerStack1;
470 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800472
Lloyd Pique9755fb72019-03-26 14:44:40 -0700473 layerFEState.layerStackId = layerStack2;
474 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700475 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800476
Lloyd Pique9755fb72019-03-26 14:44:40 -0700477 layerFEState.layerStackId = layerStack2;
478 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800480}
481
Lloyd Pique66d68602019-02-13 14:23:31 -0800482/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800483 * Output::getOutputLayerForLayer()
484 */
485
486TEST_F(OutputTest, getOutputLayerForLayerWorks) {
487 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
488 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
489
Lloyd Pique01c77c12019-04-17 12:48:32 -0700490 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer1));
491 mOutput->injectOutputLayerForTest(nullptr);
492 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer2));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800493
494 StrictMock<mock::Layer> layer;
495 StrictMock<mock::Layer> otherLayer;
496
497 // If the input layer matches the first OutputLayer, it will be returned.
498 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_EQ(outputLayer1, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800500
501 // If the input layer matches the second OutputLayer, it will be returned.
502 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
503 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700504 EXPECT_EQ(outputLayer2, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800505
506 // If the input layer does not match an output layer, null will be returned.
507 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
508 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700509 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800510}
511
Lloyd Pique66d68602019-02-13 14:23:31 -0800512/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800513 * Output::setReleasedLayers()
514 */
515
516using OutputSetReleasedLayersTest = OutputTest;
517
518TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
519 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
520 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
521 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
522
523 Output::ReleasedLayers layers;
524 layers.push_back(layer1FE);
525 layers.push_back(layer2FE);
526 layers.push_back(layer3FE);
527
528 mOutput->setReleasedLayers(std::move(layers));
529
530 const auto& setLayers = mOutput->getReleasedLayersForTest();
531 ASSERT_EQ(3u, setLayers.size());
532 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
533 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
534 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
535}
536
537/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800538 * Output::updateAndWriteCompositionState()
539 */
540
541TEST_F(OutputTest, updateAndWriteCompositionState_takesEarlyOutIfNotEnabled) {
542 mOutput->editState().isEnabled = false;
543
544 CompositionRefreshArgs args;
545 mOutput->updateAndWriteCompositionState(args);
546}
547
548TEST_F(OutputTest, updateAndWriteCompositionState_updatesLayers) {
549 mOutput->editState().isEnabled = true;
550 mock::OutputLayer* outputLayer = new StrictMock<mock::OutputLayer>();
551 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer));
552
553 EXPECT_CALL(*outputLayer, updateCompositionState(true, true)).Times(1);
554 EXPECT_CALL(*outputLayer, writeStateToHWC(true)).Times(1);
555
556 CompositionRefreshArgs args;
557 args.updatingGeometryThisFrame = true;
558 args.devOptForceClientComposition = true;
559 mOutput->updateAndWriteCompositionState(args);
560}
561
562/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800563 * Output::prepareFrame()
564 */
565
566struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800567 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique66d68602019-02-13 14:23:31 -0800568 // Sets up the helper functions called by prepareFrame to use a mock
569 // implementations.
570 MOCK_METHOD0(chooseCompositionStrategy, void());
571 };
572
573 OutputPrepareFrameTest() {
574 mOutput.setDisplayColorProfileForTest(
575 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
576 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
577 }
578
579 StrictMock<mock::CompositionEngine> mCompositionEngine;
580 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
581 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700582 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800583};
584
585TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
586 mOutput.editState().isEnabled = false;
587
588 mOutput.prepareFrame();
589}
590
591TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
592 mOutput.editState().isEnabled = true;
593 mOutput.editState().usesClientComposition = false;
594 mOutput.editState().usesDeviceComposition = true;
595
596 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
597 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
598
599 mOutput.prepareFrame();
600}
601
602// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
603// base chooseCompositionStrategy() is invoked.
604TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700605 mOutput->editState().isEnabled = true;
606 mOutput->editState().usesClientComposition = false;
607 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800608
609 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
610
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700611 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800612
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700613 EXPECT_TRUE(mOutput->getState().usesClientComposition);
614 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800615}
616
Lloyd Pique56eba802019-08-28 15:45:25 -0700617/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800618 * Output::present()
619 */
620
621struct OutputPresentTest : public testing::Test {
622 struct OutputPartialMock : public OutputPartialMockBase {
623 // All child helper functions Output::present() are defined as mocks,
624 // and those are tested separately, allowing the present() test to
625 // just cover the high level flow.
626 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
627 MOCK_METHOD1(updateAndWriteCompositionState,
628 void(const compositionengine::CompositionRefreshArgs&));
629 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
630 MOCK_METHOD0(beginFrame, void());
631 MOCK_METHOD0(prepareFrame, void());
632 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
633 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
634 MOCK_METHOD0(postFramebuffer, void());
635 };
636
637 StrictMock<OutputPartialMock> mOutput;
638};
639
640TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
641 CompositionRefreshArgs args;
642
643 InSequence seq;
644 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
645 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
646 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
647 EXPECT_CALL(mOutput, beginFrame());
648 EXPECT_CALL(mOutput, prepareFrame());
649 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
650 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
651 EXPECT_CALL(mOutput, postFramebuffer());
652
653 mOutput.present(args);
654}
655
656/*
657 * Output::updateColorProfile()
658 */
659
660// TODO(b/144060211) - Add coverage
661
662/*
663 * Output::beginFrame()
664 */
665
666/*
667 * Output::devOptRepaintFlash()
668 */
669
670// TODO(b/144060211) - Add coverage
671
672/*
673 * Output::finishFrame()
674 */
675
676// TODO(b/144060211) - Add coverage
677
678/*
679 * Output::postFramebuffer()
680 */
681
682// TODO(b/144060211) - Add coverage
683
684/*
Lloyd Pique56eba802019-08-28 15:45:25 -0700685 * Output::composeSurfaces()
686 */
687
688struct OutputComposeSurfacesTest : public testing::Test {
689 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
690 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::DISPLAY_P3;
691
692 static const Rect kDefaultOutputFrame;
693 static const Rect kDefaultOutputViewport;
694 static const Rect kDefaultOutputScissor;
695 static const mat4 kDefaultColorTransformMat;
696
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800697 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique56eba802019-08-28 15:45:25 -0700698 // Sets up the helper functions called by composeSurfaces to use a mock
699 // implementations.
700 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
701 MOCK_METHOD2(generateClientCompositionRequests,
702 std::vector<renderengine::LayerSettings>(bool, Region&));
703 MOCK_METHOD2(appendRegionFlashRequests,
704 void(const Region&, std::vector<renderengine::LayerSettings>&));
705 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
706 };
707
708 OutputComposeSurfacesTest() {
709 mOutput.setDisplayColorProfileForTest(
710 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
711 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
712
Lloyd Pique56eba802019-08-28 15:45:25 -0700713 mOutput.editState().frame = kDefaultOutputFrame;
714 mOutput.editState().viewport = kDefaultOutputViewport;
715 mOutput.editState().scissor = kDefaultOutputScissor;
716 mOutput.editState().transform = ui::Transform{kDefaultOutputOrientation};
717 mOutput.editState().orientation = kDefaultOutputOrientation;
718 mOutput.editState().dataspace = kDefaultOutputDataspace;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800719 mOutput.editState().colorTransformMatrix = kDefaultColorTransformMat;
Lloyd Pique56eba802019-08-28 15:45:25 -0700720 mOutput.editState().isSecure = true;
721 mOutput.editState().needsFiltering = false;
722 mOutput.editState().usesClientComposition = true;
723 mOutput.editState().usesDeviceComposition = false;
724
Lloyd Pique01c77c12019-04-17 12:48:32 -0700725 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
726 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
727 .WillRepeatedly(Return(&mOutputLayer1));
728 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
729 .WillRepeatedly(Return(&mOutputLayer2));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700730 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -0700731 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
732 }
733
734 StrictMock<mock::CompositionEngine> mCompositionEngine;
735 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
736 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
737 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700738 StrictMock<mock::OutputLayer> mOutputLayer1;
739 StrictMock<mock::OutputLayer> mOutputLayer2;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700740 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700741 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
742};
743
744const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
745const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
746const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
747const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
748
749// TODO(b/121291683): Expand unit test coverage for composeSurfaces beyond these
750// basic tests.
751
752TEST_F(OutputComposeSurfacesTest, doesNothingIfNoClientComposition) {
753 mOutput.editState().usesClientComposition = false;
754
755 Region debugRegion;
Lloyd Piqued3d69882019-02-28 16:03:46 -0800756 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(debugRegion);
757 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700758}
759
760TEST_F(OutputComposeSurfacesTest, worksIfNoClientLayersQueued) {
761 const Region kDebugRegion{Rect{100, 101, 102, 103}};
762
763 constexpr float kDefaultMaxLuminance = 1.0f;
764 constexpr float kDefaultAvgLuminance = 0.7f;
765 constexpr float kDefaultMinLuminance = 0.1f;
766 HdrCapabilities HdrCapabilities{{},
767 kDefaultMaxLuminance,
768 kDefaultAvgLuminance,
769 kDefaultMinLuminance};
770
771 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillOnce(Return(false));
772 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).Times(1);
773
774 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillOnce(Return(true));
775 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities()).WillOnce(ReturnRef(HdrCapabilities));
776
777 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
778
779 EXPECT_CALL(mOutput, getSkipColorTransform()).WillOnce(Return(false));
780 EXPECT_CALL(mOutput, generateClientCompositionRequests(false, _)).Times(1);
781 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _)).Times(1);
782 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(1);
783 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false)).Times(1);
784
Lloyd Piqued3d69882019-02-28 16:03:46 -0800785 std::optional<base::unique_fd> readyFence = mOutput.composeSurfaces(kDebugRegion);
786 EXPECT_TRUE(readyFence);
Lloyd Pique56eba802019-08-28 15:45:25 -0700787}
788
789/*
790 * Output::generateClientCompositionRequests()
791 */
792
793struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800794 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700795 // compositionengine::Output overrides
Lloyd Pique56eba802019-08-28 15:45:25 -0700796 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
797 bool supportsProtectedContent, Region& clearRegion) override {
798 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
799 clearRegion);
800 }
801 };
802
803 GenerateClientCompositionRequestsTest() {
804 mOutput.setDisplayColorProfileForTest(
805 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
806 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
807 }
808
Lloyd Pique56eba802019-08-28 15:45:25 -0700809 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
810 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700811 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -0700812};
813
814// TODO(b/121291683): Add more unit test coverage for generateClientCompositionRequests
815
816TEST_F(GenerateClientCompositionRequestsTest, worksForLandscapeModeSplitScreen) {
817 // In split-screen landscape mode, the screen is rotated 90 degrees, with
818 // one layer on the left covering the left side of the output, and one layer
819 // on the right covering that side of the output.
820
Lloyd Pique01c77c12019-04-17 12:48:32 -0700821 StrictMock<mock::OutputLayer> leftOutputLayer;
822 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700823
824 StrictMock<mock::Layer> leftLayer;
825 StrictMock<mock::LayerFE> leftLayerFE;
826 StrictMock<mock::Layer> rightLayer;
827 StrictMock<mock::LayerFE> rightLayerFE;
828
829 impl::OutputLayerCompositionState leftOutputLayerState;
830 leftOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800831 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700832
Lloyd Pique9755fb72019-03-26 14:44:40 -0700833 LayerFECompositionState leftLayerFEState;
834 leftLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700835
836 const half3 leftLayerColor{1.f, 0.f, 0.f};
837 renderengine::LayerSettings leftLayerRESettings;
838 leftLayerRESettings.source.solidColor = leftLayerColor;
839
840 impl::OutputLayerCompositionState rightOutputLayerState;
841 rightOutputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800842 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700843
Lloyd Pique9755fb72019-03-26 14:44:40 -0700844 LayerFECompositionState rightLayerFEState;
845 rightLayerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700846
847 const half3 rightLayerColor{0.f, 1.f, 0.f};
848 renderengine::LayerSettings rightLayerRESettings;
849 rightLayerRESettings.source.solidColor = rightLayerColor;
850
Lloyd Pique01c77c12019-04-17 12:48:32 -0700851 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
852 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
853 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
854 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
855 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700856 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700857 EXPECT_CALL(leftLayerFE, prepareClientComposition(_)).WillOnce(Return(leftLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800858 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700859
Lloyd Pique01c77c12019-04-17 12:48:32 -0700860 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
861 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
862 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
863 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
864 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700865 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700866 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800867 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700868
Lloyd Pique01c77c12019-04-17 12:48:32 -0700869 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
870 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
871 .WillRepeatedly(Return(&leftOutputLayer));
872 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
873 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -0700874
875 const Rect kPortraitFrame(0, 0, 1000, 2000);
876 const Rect kPortraitViewport(0, 0, 2000, 1000);
877 const Rect kPortraitScissor(0, 0, 1000, 2000);
878 const uint32_t kPortraitOrientation = TR_ROT_90;
879
880 mOutput.editState().frame = kPortraitFrame;
881 mOutput.editState().viewport = kPortraitViewport;
882 mOutput.editState().scissor = kPortraitScissor;
883 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
884 mOutput.editState().orientation = kPortraitOrientation;
885 mOutput.editState().needsFiltering = true;
886 mOutput.editState().isSecure = false;
887
888 constexpr bool supportsProtectedContent = false;
889 Region clearRegion;
890 auto requests =
891 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
892
893 ASSERT_EQ(2u, requests.size());
894 EXPECT_EQ(leftLayerColor, requests[0].source.solidColor);
895 EXPECT_EQ(rightLayerColor, requests[1].source.solidColor);
896}
897
898TEST_F(GenerateClientCompositionRequestsTest, ignoresLayersThatDoNotIntersectWithViewport) {
899 // Layers whose visible region does not intersect with the viewport will be
900 // skipped when generating client composition request state.
901
Lloyd Pique01c77c12019-04-17 12:48:32 -0700902 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique56eba802019-08-28 15:45:25 -0700903 StrictMock<mock::Layer> layer;
904 StrictMock<mock::LayerFE> layerFE;
905
906 impl::OutputLayerCompositionState outputLayerState;
907 outputLayerState.clearClientTarget = false;
Lloyd Piquea2468662019-03-07 21:31:06 -0800908 outputLayerState.visibleRegion = Region{Rect{3000, 0, 4000, 1000}};
Lloyd Pique56eba802019-08-28 15:45:25 -0700909
Lloyd Pique9755fb72019-03-26 14:44:40 -0700910 LayerFECompositionState layerFEState;
911 layerFEState.isOpaque = true;
Lloyd Pique56eba802019-08-28 15:45:25 -0700912
Lloyd Pique01c77c12019-04-17 12:48:32 -0700913 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
914 EXPECT_CALL(outputLayer, getLayer()).WillRepeatedly(ReturnRef(layer));
915 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
916 EXPECT_CALL(outputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
917 EXPECT_CALL(outputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700918 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700919 EXPECT_CALL(layerFE, prepareClientComposition(_)).Times(0);
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800920 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
Lloyd Pique56eba802019-08-28 15:45:25 -0700921
Lloyd Pique01c77c12019-04-17 12:48:32 -0700922 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
923 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u)).WillRepeatedly(Return(&outputLayer));
Lloyd Pique56eba802019-08-28 15:45:25 -0700924
925 const Rect kPortraitFrame(0, 0, 1000, 2000);
926 const Rect kPortraitViewport(0, 0, 2000, 1000);
927 const Rect kPortraitScissor(0, 0, 1000, 2000);
928 const uint32_t kPortraitOrientation = TR_ROT_90;
929
930 mOutput.editState().frame = kPortraitFrame;
931 mOutput.editState().viewport = kPortraitViewport;
932 mOutput.editState().scissor = kPortraitScissor;
933 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
934 mOutput.editState().orientation = kPortraitOrientation;
935 mOutput.editState().needsFiltering = true;
936 mOutput.editState().isSecure = false;
937
938 constexpr bool supportsProtectedContent = false;
939 Region clearRegion;
940 auto requests =
941 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
942
943 EXPECT_EQ(0u, requests.size());
944}
945
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700946TEST_F(GenerateClientCompositionRequestsTest, clearsDeviceLayesAfterFirst) {
947 // If client composition is performed with some layers set to use device
948 // composition, device layers after the first layer (device or client) will
949 // clear the frame buffer if they are opaque and if that layer has a flag
950 // set to do so. The first layer is skipped as the frame buffer is already
951 // expected to be clear.
952
Lloyd Pique01c77c12019-04-17 12:48:32 -0700953 StrictMock<mock::OutputLayer> leftOutputLayer;
954 StrictMock<mock::OutputLayer> rightOutputLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700955
956 StrictMock<mock::Layer> leftLayer;
957 StrictMock<mock::LayerFE> leftLayerFE;
958 StrictMock<mock::Layer> rightLayer;
959 StrictMock<mock::LayerFE> rightLayerFE;
960
961 impl::OutputLayerCompositionState leftOutputLayerState;
962 leftOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -0800963 leftOutputLayerState.visibleRegion = Region{Rect{0, 0, 1000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700964
Lloyd Pique9755fb72019-03-26 14:44:40 -0700965 LayerFECompositionState leftLayerFEState;
966 leftLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700967
968 impl::OutputLayerCompositionState rightOutputLayerState;
969 rightOutputLayerState.clearClientTarget = true;
Lloyd Piquea2468662019-03-07 21:31:06 -0800970 rightOutputLayerState.visibleRegion = Region{Rect{1000, 0, 2000, 1000}};
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700971
Lloyd Pique9755fb72019-03-26 14:44:40 -0700972 LayerFECompositionState rightLayerFEState;
973 rightLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700974
975 const half3 rightLayerColor{0.f, 1.f, 0.f};
976 renderengine::LayerSettings rightLayerRESettings;
977 rightLayerRESettings.geometry.boundaries = FloatRect{456, 0, 0, 0};
978 rightLayerRESettings.source.solidColor = rightLayerColor;
979
Lloyd Pique01c77c12019-04-17 12:48:32 -0700980 EXPECT_CALL(leftOutputLayer, getState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
981 EXPECT_CALL(leftOutputLayer, getLayer()).WillRepeatedly(ReturnRef(leftLayer));
982 EXPECT_CALL(leftOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(leftLayerFE));
983 EXPECT_CALL(leftOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
984 EXPECT_CALL(leftOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700985 EXPECT_CALL(leftLayer, getFEState()).WillRepeatedly(ReturnRef(leftLayerFEState));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800986 EXPECT_CALL(leftOutputLayer, editState()).WillRepeatedly(ReturnRef(leftOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700987
Lloyd Pique01c77c12019-04-17 12:48:32 -0700988 EXPECT_CALL(rightOutputLayer, getState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
989 EXPECT_CALL(rightOutputLayer, getLayer()).WillRepeatedly(ReturnRef(rightLayer));
990 EXPECT_CALL(rightOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(rightLayerFE));
991 EXPECT_CALL(rightOutputLayer, requiresClientComposition()).WillRepeatedly(Return(false));
992 EXPECT_CALL(rightOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Lloyd Pique9755fb72019-03-26 14:44:40 -0700993 EXPECT_CALL(rightLayer, getFEState()).WillRepeatedly(ReturnRef(rightLayerFEState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700994 EXPECT_CALL(rightLayerFE, prepareClientComposition(_)).WillOnce(Return(rightLayerRESettings));
Adithya Srinivasanb69e0762019-11-11 18:39:53 -0800995 EXPECT_CALL(rightOutputLayer, editState()).WillRepeatedly(ReturnRef(rightOutputLayerState));
Lloyd Piquec2d54d42019-08-28 18:04:21 -0700996
Lloyd Pique01c77c12019-04-17 12:48:32 -0700997 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
998 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
999 .WillRepeatedly(Return(&leftOutputLayer));
1000 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
1001 .WillRepeatedly(Return(&rightOutputLayer));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07001002
1003 const Rect kPortraitFrame(0, 0, 1000, 2000);
1004 const Rect kPortraitViewport(0, 0, 2000, 1000);
1005 const Rect kPortraitScissor(0, 0, 1000, 2000);
1006 const uint32_t kPortraitOrientation = TR_ROT_90;
1007
1008 mOutput.editState().frame = kPortraitFrame;
1009 mOutput.editState().viewport = kPortraitViewport;
1010 mOutput.editState().scissor = kPortraitScissor;
1011 mOutput.editState().transform = ui::Transform{kPortraitOrientation};
1012 mOutput.editState().orientation = kPortraitOrientation;
1013 mOutput.editState().needsFiltering = true;
1014 mOutput.editState().isSecure = false;
1015
1016 constexpr bool supportsProtectedContent = false;
1017 Region clearRegion;
1018 auto requests =
1019 mOutput.generateClientCompositionRequests(supportsProtectedContent, clearRegion);
1020
1021 const half3 clearColor{0.f, 0.f, 0.f};
1022
1023 ASSERT_EQ(1u, requests.size());
1024 EXPECT_EQ(456.f, requests[0].geometry.boundaries.left);
1025 EXPECT_EQ(clearColor, requests[0].source.solidColor);
1026}
1027
Lloyd Pique32cbe282018-10-19 13:09:22 -07001028} // namespace
1029} // namespace android::compositionengine