blob: 6761b866c4dc6ecad52b29e5a7f2dd1888bee11c [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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Lloyd Pique32cbe282018-10-19 13:09:22 -070021#include <cmath>
22
Lloyd Pique17ca7422019-11-14 14:24:10 -080023#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070024#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070025#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080026#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070027#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070029#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080030#include <compositionengine/mock/Layer.h>
31#include <compositionengine/mock/LayerFE.h>
32#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070033#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070034#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070035#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070036#include <ui/Rect.h>
37#include <ui/Region.h>
38
Lloyd Pique17ca7422019-11-14 14:24:10 -080039#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080040#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070041#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042
43namespace android::compositionengine {
44namespace {
45
Lloyd Pique56eba802019-08-28 15:45:25 -070046using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080047using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080048using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080049using testing::DoAll;
Lloyd Pique6818fa52019-12-03 12:32:13 -080050using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080051using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080052using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080053using testing::Invoke;
54using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080055using testing::Mock;
Lloyd Pique07178e32019-11-19 19:15:26 -080056using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080057using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070058using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070059using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080060using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::StrictMock;
62
Lloyd Pique56eba802019-08-28 15:45:25 -070063constexpr auto TR_IDENT = 0u;
64constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
65
Lloyd Pique3eb1b212019-03-07 21:15:40 -080066const mat4 kIdentity;
67const mat4 kNonIdentityHalf = mat4() * 0.5;
68const mat4 kNonIdentityQuarter = mat4() * 0.25;
69
Lloyd Pique17ca7422019-11-14 14:24:10 -080070constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
71 static_cast<OutputColorSetting>(0x100);
72
Lloyd Piquefaa3f192019-11-14 14:05:09 -080073struct OutputPartialMockBase : public impl::Output {
74 // compositionengine::Output overrides
75 const OutputCompositionState& getState() const override { return mState; }
76 OutputCompositionState& editState() override { return mState; }
77
78 // Use mocks for all the remaining virtual functions
79 // not implemented by the base implementation class.
80 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
81 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
82 MOCK_METHOD3(ensureOutputLayer,
83 compositionengine::OutputLayer*(std::optional<size_t>,
84 const std::shared_ptr<compositionengine::Layer>&,
85 const sp<LayerFE>&));
86 MOCK_METHOD0(finalizePendingOutputLayers, void());
87 MOCK_METHOD0(clearOutputLayers, void());
88 MOCK_CONST_METHOD1(dumpState, void(std::string&));
89 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
90 MOCK_METHOD2(injectOutputLayerForTest,
91 compositionengine::OutputLayer*(const std::shared_ptr<compositionengine::Layer>&,
92 const sp<LayerFE>&));
93 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
94
95 impl::OutputCompositionState mState;
96};
97
Lloyd Pique66d68602019-02-13 14:23:31 -080098struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -070099 class Output : public impl::Output {
100 public:
101 using impl::Output::injectOutputLayerForTest;
102 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
103 };
104
105 static std::shared_ptr<Output> createOutput(
106 const compositionengine::CompositionEngine& compositionEngine) {
107 return impl::createOutputTemplated<Output>(compositionEngine);
108 }
109
Lloyd Pique31cb2942018-10-19 17:23:03 -0700110 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700111 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700112 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700113 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800114
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700115 mOutput->editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700116 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700117
Lloyd Piqueef958122019-02-05 18:00:12 -0800118 static const Rect kDefaultDisplaySize;
119
Lloyd Pique32cbe282018-10-19 13:09:22 -0700120 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700121 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700122 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700123 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700124};
125
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800126// Extension of the base test useful for checking interactions with the LayerFE
127// functions to latch composition state.
128struct OutputLatchFEStateTest : public OutputTest {
129 OutputLatchFEStateTest() {
130 EXPECT_CALL(*mOutputLayer1, getLayer()).WillRepeatedly(ReturnRef(mLayer1));
131 EXPECT_CALL(*mOutputLayer2, getLayer()).WillRepeatedly(ReturnRef(mLayer2));
132 EXPECT_CALL(*mOutputLayer3, getLayer()).WillRepeatedly(ReturnRef(mLayer3));
133
134 EXPECT_CALL(*mOutputLayer1, getLayerFE()).WillRepeatedly(ReturnRef(mLayer1FE));
135 EXPECT_CALL(*mOutputLayer2, getLayerFE()).WillRepeatedly(ReturnRef(mLayer2FE));
136 EXPECT_CALL(*mOutputLayer3, getLayerFE()).WillRepeatedly(ReturnRef(mLayer3FE));
137
138 EXPECT_CALL(mLayer1, editFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
139 EXPECT_CALL(mLayer2, editFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
140 EXPECT_CALL(mLayer3, editFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -0800141
142 EXPECT_CALL(mLayer1, getFEState()).WillRepeatedly(ReturnRef(mLayer1FEState));
143 EXPECT_CALL(mLayer2, getFEState()).WillRepeatedly(ReturnRef(mLayer2FEState));
144 EXPECT_CALL(mLayer3, getFEState()).WillRepeatedly(ReturnRef(mLayer3FEState));
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800145 }
146
147 void injectLayer(std::unique_ptr<mock::OutputLayer> layer) {
148 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.release()));
149 }
150
151 std::unique_ptr<mock::OutputLayer> mOutputLayer1{new StrictMock<mock::OutputLayer>};
152 std::unique_ptr<mock::OutputLayer> mOutputLayer2{new StrictMock<mock::OutputLayer>};
153 std::unique_ptr<mock::OutputLayer> mOutputLayer3{new StrictMock<mock::OutputLayer>};
154
155 StrictMock<mock::Layer> mLayer1;
156 StrictMock<mock::Layer> mLayer2;
157 StrictMock<mock::Layer> mLayer3;
158
159 StrictMock<mock::LayerFE> mLayer1FE;
160 StrictMock<mock::LayerFE> mLayer2FE;
161 StrictMock<mock::LayerFE> mLayer3FE;
162
163 LayerFECompositionState mLayer1FEState;
164 LayerFECompositionState mLayer2FEState;
165 LayerFECompositionState mLayer3FEState;
166};
167
Lloyd Piqueef958122019-02-05 18:00:12 -0800168const Rect OutputTest::kDefaultDisplaySize{100, 200};
169
Lloyd Pique17ca7422019-11-14 14:24:10 -0800170using ColorProfile = compositionengine::Output::ColorProfile;
171
172void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
173 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
174 toString(profile.mode).c_str(), profile.mode,
175 toString(profile.dataspace).c_str(), profile.dataspace,
176 toString(profile.renderIntent).c_str(), profile.renderIntent,
177 toString(profile.colorSpaceAgnosticDataspace).c_str(),
178 profile.colorSpaceAgnosticDataspace);
179}
180
181// Checks for a ColorProfile match
182MATCHER_P(ColorProfileEq, expected, "") {
183 std::string buf;
184 buf.append("ColorProfiles are not equal\n");
185 dumpColorProfile(expected, buf, "expected value");
186 dumpColorProfile(arg, buf, "actual value");
187 *result_listener << buf;
188
189 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
190 (expected.renderIntent == arg.renderIntent) &&
191 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
192}
193
Lloyd Pique66d68602019-02-13 14:23:31 -0800194/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700195 * Basic construction
196 */
197
Lloyd Pique31cb2942018-10-19 17:23:03 -0700198TEST_F(OutputTest, canInstantiateOutput) {
199 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700200 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
202
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700203 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700204
205 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700206 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700207
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700208 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
209
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700211}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700212
Lloyd Pique66d68602019-02-13 14:23:31 -0800213/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214 * Output::setCompositionEnabled()
215 */
216
217TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700220 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700221
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 EXPECT_TRUE(mOutput->getState().isEnabled);
223 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700224}
225
226TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 EXPECT_TRUE(mOutput->getState().isEnabled);
232 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700233}
234
235TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 EXPECT_FALSE(mOutput->getState().isEnabled);
241 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242}
243
Lloyd Pique66d68602019-02-13 14:23:31 -0800244/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700245 * Output::setProjection()
246 */
247
248TEST_F(OutputTest, setProjectionTriviallyWorks) {
249 const ui::Transform transform{ui::Transform::ROT_180};
250 const int32_t orientation = 123;
251 const Rect frame{1, 2, 3, 4};
252 const Rect viewport{5, 6, 7, 8};
253 const Rect scissor{9, 10, 11, 12};
254 const bool needsFiltering = true;
255
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700256 mOutput->setProjection(transform, orientation, frame, viewport, scissor, needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700257
Lloyd Piqueea629282019-12-03 15:57:10 -0800258 EXPECT_THAT(mOutput->getState().transform, transform);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700259 EXPECT_EQ(orientation, mOutput->getState().orientation);
260 EXPECT_EQ(frame, mOutput->getState().frame);
261 EXPECT_EQ(viewport, mOutput->getState().viewport);
262 EXPECT_EQ(scissor, mOutput->getState().scissor);
263 EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700264}
265
Lloyd Pique66d68602019-02-13 14:23:31 -0800266/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700267 * Output::setBounds()
268 */
269
270TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800271 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700272
273 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
274 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
275
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700276 mOutput->setBounds(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700277
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700278 EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700279
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700280 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700281}
282
Lloyd Pique66d68602019-02-13 14:23:31 -0800283/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700284 * Output::setLayerStackFilter()
285 */
286
287TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700288 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700289 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700290
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700291 EXPECT_TRUE(mOutput->getState().layerStackInternal);
292 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700293
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::setColorTransform
299 */
300
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800301TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700302 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700303
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800304 // If no colorTransformMatrix is set the update should be skipped.
305 CompositionRefreshArgs refreshArgs;
306 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700307
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700308 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700309
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800310 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700311 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800312
313 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700314 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800315}
Lloyd Piqueef958122019-02-05 18:00:12 -0800316
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800317TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700318 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700319
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800320 // Attempting to set the same colorTransformMatrix that is already set should
321 // also skip the update.
322 CompositionRefreshArgs refreshArgs;
323 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700324
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700325 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700326
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800327 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700328 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800329
330 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700331 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800332}
333
334TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700335 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800336
337 // Setting a different colorTransformMatrix should perform the update.
338 CompositionRefreshArgs refreshArgs;
339 refreshArgs.colorTransformMatrix = kIdentity;
340
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700341 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800342
343 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700344 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800345
346 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700347 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800348}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700349
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800350TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700351 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700352
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800353 // Setting a different colorTransformMatrix should perform the update.
354 CompositionRefreshArgs refreshArgs;
355 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700356
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700357 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800358
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800359 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700360 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800361
362 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700363 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800364}
365
366TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700367 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800368
369 // Setting a different colorTransformMatrix should perform the update.
370 CompositionRefreshArgs refreshArgs;
371 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
372
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700373 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800374
375 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700376 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800377
378 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700379 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700380}
381
Lloyd Pique66d68602019-02-13 14:23:31 -0800382/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800383 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700384 */
385
Lloyd Pique17ca7422019-11-14 14:24:10 -0800386using OutputSetColorProfileTest = OutputTest;
387
388TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800389 using ColorProfile = Output::ColorProfile;
390
Lloyd Piquef5275482019-01-29 18:42:42 -0800391 EXPECT_CALL(*mDisplayColorProfile,
392 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
393 ui::Dataspace::UNKNOWN))
394 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800395 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700396
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700397 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
398 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
399 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700400
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700401 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
402 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
403 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
404 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800405
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700406 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800407}
408
Lloyd Pique17ca7422019-11-14 14:24:10 -0800409TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800410 using ColorProfile = Output::ColorProfile;
411
Lloyd Piquef5275482019-01-29 18:42:42 -0800412 EXPECT_CALL(*mDisplayColorProfile,
413 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
414 ui::Dataspace::UNKNOWN))
415 .WillOnce(Return(ui::Dataspace::UNKNOWN));
416
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700417 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
418 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
419 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
420 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800421
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700422 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
423 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
424 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800425
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700426 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700427}
428
Lloyd Pique66d68602019-02-13 14:23:31 -0800429/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700430 * Output::setRenderSurface()
431 */
432
433TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
434 const ui::Size newDisplaySize{640, 480};
435
436 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
437 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
438
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700439 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700440
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700442}
443
Lloyd Pique66d68602019-02-13 14:23:31 -0800444/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000445 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446 */
447
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000448TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
449 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 mOutput->editState().viewport = viewport;
451 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700452
453 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000456 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700457 }
458}
459
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000460TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
461 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700462 mOutput->editState().viewport = viewport;
463 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700464
465 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700467
468 // The dirtyRegion should be clipped to the display bounds.
469 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
470 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700471}
472
Lloyd Pique66d68602019-02-13 14:23:31 -0800473/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800474 * Output::belongsInOutput()
475 */
476
477TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
478 const uint32_t layerStack1 = 123u;
479 const uint32_t layerStack2 = 456u;
480
481 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800483
Lloyd Piquec6687342019-03-07 21:34:57 -0800484 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700485 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
486 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800487
Lloyd Piqueef36b002019-01-23 17:52:04 -0800488 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700489 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
490 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
491 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
492 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800493
494 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800496
497 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
499 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
500 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
501 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800502}
503
Lloyd Pique66c20c42019-03-07 21:44:02 -0800504TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
505 StrictMock<mock::Layer> layer;
Lloyd Pique9755fb72019-03-26 14:44:40 -0700506 LayerFECompositionState layerFEState;
Lloyd Pique66c20c42019-03-07 21:44:02 -0800507
Lloyd Pique9755fb72019-03-26 14:44:40 -0700508 EXPECT_CALL(layer, getFEState()).WillRepeatedly(ReturnRef(layerFEState));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800509
510 const uint32_t layerStack1 = 123u;
511 const uint32_t layerStack2 = 456u;
512
513 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800515
516 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700517 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800518
519 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700520 layerFEState.layerStackId = std::nullopt;
521 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700522 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800523
Lloyd Pique9755fb72019-03-26 14:44:40 -0700524 layerFEState.layerStackId = std::nullopt;
525 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700526 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800527
528 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700529 layerFEState.layerStackId = layerStack1;
530 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700531 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800532
Lloyd Pique9755fb72019-03-26 14:44:40 -0700533 layerFEState.layerStackId = layerStack1;
534 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700535 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800536
Lloyd Pique9755fb72019-03-26 14:44:40 -0700537 layerFEState.layerStackId = layerStack2;
538 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700539 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800540
Lloyd Pique9755fb72019-03-26 14:44:40 -0700541 layerFEState.layerStackId = layerStack2;
542 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700543 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800544
545 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700546 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800547
548 // A null layer pointer does not belong to the output
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 EXPECT_FALSE(mOutput->belongsInOutput(nullptr));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800550
551 // Only non-internal layers with layerStack1 belong to it.
Lloyd Pique9755fb72019-03-26 14:44:40 -0700552 layerFEState.layerStackId = layerStack1;
553 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700554 EXPECT_TRUE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800555
Lloyd Pique9755fb72019-03-26 14:44:40 -0700556 layerFEState.layerStackId = layerStack1;
557 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700558 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800559
Lloyd Pique9755fb72019-03-26 14:44:40 -0700560 layerFEState.layerStackId = layerStack2;
561 layerFEState.internalOnly = true;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800563
Lloyd Pique9755fb72019-03-26 14:44:40 -0700564 layerFEState.layerStackId = layerStack2;
565 layerFEState.internalOnly = false;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700566 EXPECT_FALSE(mOutput->belongsInOutput(&layer));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800567}
568
Lloyd Pique66d68602019-02-13 14:23:31 -0800569/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800570 * Output::getOutputLayerForLayer()
571 */
572
573TEST_F(OutputTest, getOutputLayerForLayerWorks) {
574 mock::OutputLayer* outputLayer1 = new StrictMock<mock::OutputLayer>();
575 mock::OutputLayer* outputLayer2 = new StrictMock<mock::OutputLayer>();
576
Lloyd Pique01c77c12019-04-17 12:48:32 -0700577 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer1));
578 mOutput->injectOutputLayerForTest(nullptr);
579 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(outputLayer2));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800580
581 StrictMock<mock::Layer> layer;
582 StrictMock<mock::Layer> otherLayer;
583
584 // If the input layer matches the first OutputLayer, it will be returned.
585 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700586 EXPECT_EQ(outputLayer1, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800587
588 // If the input layer matches the second OutputLayer, it will be returned.
589 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
590 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(layer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700591 EXPECT_EQ(outputLayer2, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800592
593 // If the input layer does not match an output layer, null will be returned.
594 EXPECT_CALL(*outputLayer1, getLayer()).WillOnce(ReturnRef(otherLayer));
595 EXPECT_CALL(*outputLayer2, getLayer()).WillOnce(ReturnRef(otherLayer));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700596 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(&layer));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800597}
598
Lloyd Pique66d68602019-02-13 14:23:31 -0800599/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800600 * Output::setReleasedLayers()
601 */
602
603using OutputSetReleasedLayersTest = OutputTest;
604
605TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
606 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
607 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
608 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
609
610 Output::ReleasedLayers layers;
611 layers.push_back(layer1FE);
612 layers.push_back(layer2FE);
613 layers.push_back(layer3FE);
614
615 mOutput->setReleasedLayers(std::move(layers));
616
617 const auto& setLayers = mOutput->getReleasedLayersForTest();
618 ASSERT_EQ(3u, setLayers.size());
619 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
620 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
621 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
622}
623
624/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800625 * Output::updateLayerStateFromFE()
626 */
627
628using OutputUpdateLayerStateFromFETest = OutputLatchFEStateTest;
629
630TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
631 CompositionRefreshArgs refreshArgs;
632
633 mOutput->updateLayerStateFromFE(refreshArgs);
634}
635
636TEST_F(OutputUpdateLayerStateFromFETest, latchesContentStateForAllContainedLayers) {
637 EXPECT_CALL(mLayer1FE,
638 latchCompositionState(Ref(mLayer1FEState), LayerFE::StateSubset::Content));
639 EXPECT_CALL(mLayer2FE,
640 latchCompositionState(Ref(mLayer2FEState), LayerFE::StateSubset::Content));
641 EXPECT_CALL(mLayer3FE,
642 latchCompositionState(Ref(mLayer3FEState), LayerFE::StateSubset::Content));
643
644 // Note: Must be performed after any expectations on these mocks
645 injectLayer(std::move(mOutputLayer1));
646 injectLayer(std::move(mOutputLayer2));
647 injectLayer(std::move(mOutputLayer3));
648
649 CompositionRefreshArgs refreshArgs;
650 refreshArgs.updatingGeometryThisFrame = false;
651
652 mOutput->updateLayerStateFromFE(refreshArgs);
653}
654
655TEST_F(OutputUpdateLayerStateFromFETest, latchesGeometryAndContentStateForAllContainedLayers) {
656 EXPECT_CALL(mLayer1FE,
657 latchCompositionState(Ref(mLayer1FEState),
658 LayerFE::StateSubset::GeometryAndContent));
659 EXPECT_CALL(mLayer2FE,
660 latchCompositionState(Ref(mLayer2FEState),
661 LayerFE::StateSubset::GeometryAndContent));
662 EXPECT_CALL(mLayer3FE,
663 latchCompositionState(Ref(mLayer3FEState),
664 LayerFE::StateSubset::GeometryAndContent));
665
666 // Note: Must be performed after any expectations on these mocks
667 injectLayer(std::move(mOutputLayer1));
668 injectLayer(std::move(mOutputLayer2));
669 injectLayer(std::move(mOutputLayer3));
670
671 CompositionRefreshArgs refreshArgs;
672 refreshArgs.updatingGeometryThisFrame = true;
673
674 mOutput->updateLayerStateFromFE(refreshArgs);
675}
676
677/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800678 * Output::updateAndWriteCompositionState()
679 */
680
Lloyd Piqueef63b612019-11-14 13:19:56 -0800681using OutputUpdateAndWriteCompositionStateTest = OutputLatchFEStateTest;
682
683TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
684 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800685
686 CompositionRefreshArgs args;
687 mOutput->updateAndWriteCompositionState(args);
688}
689
Lloyd Piqueef63b612019-11-14 13:19:56 -0800690TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
691 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800692
Lloyd Piqueef63b612019-11-14 13:19:56 -0800693 injectLayer(std::move(mOutputLayer1));
694 injectLayer(std::move(mOutputLayer2));
695 injectLayer(std::move(mOutputLayer3));
696
697 CompositionRefreshArgs args;
698 mOutput->updateAndWriteCompositionState(args);
699}
700
701TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
702 EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, false));
703 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
704 EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, false));
705 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
706 EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, false));
707 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
708
709 injectLayer(std::move(mOutputLayer1));
710 injectLayer(std::move(mOutputLayer2));
711 injectLayer(std::move(mOutputLayer3));
712
713 mOutput->editState().isEnabled = true;
714
715 CompositionRefreshArgs args;
716 args.updatingGeometryThisFrame = false;
717 args.devOptForceClientComposition = false;
718 mOutput->updateAndWriteCompositionState(args);
719}
720
721TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
722 EXPECT_CALL(*mOutputLayer1, updateCompositionState(true, false));
723 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(true));
724 EXPECT_CALL(*mOutputLayer2, updateCompositionState(true, false));
725 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(true));
726 EXPECT_CALL(*mOutputLayer3, updateCompositionState(true, false));
727 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(true));
728
729 injectLayer(std::move(mOutputLayer1));
730 injectLayer(std::move(mOutputLayer2));
731 injectLayer(std::move(mOutputLayer3));
732
733 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800734
735 CompositionRefreshArgs args;
736 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800737 args.devOptForceClientComposition = false;
738 mOutput->updateAndWriteCompositionState(args);
739}
740
741TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
742 EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, true));
743 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
744 EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, true));
745 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
746 EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, true));
747 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
748
749 injectLayer(std::move(mOutputLayer1));
750 injectLayer(std::move(mOutputLayer2));
751 injectLayer(std::move(mOutputLayer3));
752
753 mOutput->editState().isEnabled = true;
754
755 CompositionRefreshArgs args;
756 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800757 args.devOptForceClientComposition = true;
758 mOutput->updateAndWriteCompositionState(args);
759}
760
761/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800762 * Output::prepareFrame()
763 */
764
765struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800766 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800767 // Sets up the helper functions called by the function under test to use
768 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800769 MOCK_METHOD0(chooseCompositionStrategy, void());
770 };
771
772 OutputPrepareFrameTest() {
773 mOutput.setDisplayColorProfileForTest(
774 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
775 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
776 }
777
778 StrictMock<mock::CompositionEngine> mCompositionEngine;
779 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
780 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700781 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800782};
783
784TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
785 mOutput.editState().isEnabled = false;
786
787 mOutput.prepareFrame();
788}
789
790TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
791 mOutput.editState().isEnabled = true;
792 mOutput.editState().usesClientComposition = false;
793 mOutput.editState().usesDeviceComposition = true;
794
795 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
796 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
797
798 mOutput.prepareFrame();
799}
800
801// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
802// base chooseCompositionStrategy() is invoked.
803TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700804 mOutput->editState().isEnabled = true;
805 mOutput->editState().usesClientComposition = false;
806 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800807
808 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
809
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700810 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800811
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700812 EXPECT_TRUE(mOutput->getState().usesClientComposition);
813 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800814}
815
Lloyd Pique56eba802019-08-28 15:45:25 -0700816/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800817 * Output::prepare()
818 */
819
820struct OutputPrepareTest : public testing::Test {
821 struct OutputPartialMock : public OutputPartialMockBase {
822 // Sets up the helper functions called by the function under test to use
823 // mock implementations.
824 MOCK_METHOD2(rebuildLayerStacks,
825 void(const compositionengine::CompositionRefreshArgs&,
826 compositionengine::LayerFESet&));
827 };
828
829 StrictMock<OutputPartialMock> mOutput;
830 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800831 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800832};
833
834TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
835 InSequence seq;
836 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
837
838 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
839}
840
841/*
842 * Output::rebuildLayerStacks()
843 */
844
845struct OutputRebuildLayerStacksTest : public testing::Test {
846 struct OutputPartialMock : public OutputPartialMockBase {
847 // Sets up the helper functions called by the function under test to use
848 // mock implementations.
849 MOCK_METHOD2(collectVisibleLayers,
850 void(const compositionengine::CompositionRefreshArgs&,
851 compositionengine::Output::CoverageState&));
852 };
853
854 OutputRebuildLayerStacksTest() {
855 mOutput.mState.isEnabled = true;
856 mOutput.mState.transform = kIdentityTransform;
857 mOutput.mState.bounds = kOutputBounds;
858
859 mRefreshArgs.updatingOutputGeometryThisFrame = true;
860
861 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
862
863 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
864 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
865 }
866
867 void setTestCoverageValues(const CompositionRefreshArgs&,
868 compositionengine::Output::CoverageState& state) {
869 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
870 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
871 state.dirtyRegion = mCoverageDirtyRegionToSet;
872 }
873
874 static const ui::Transform kIdentityTransform;
875 static const ui::Transform kRotate90Transform;
876 static const Rect kOutputBounds;
877
878 StrictMock<OutputPartialMock> mOutput;
879 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800880 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800881 Region mCoverageAboveCoveredLayersToSet;
882 Region mCoverageAboveOpaqueLayersToSet;
883 Region mCoverageDirtyRegionToSet;
884};
885
886const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
887const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
888const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
889
890TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
891 mOutput.mState.isEnabled = false;
892
893 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
894}
895
896TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
897 mRefreshArgs.updatingOutputGeometryThisFrame = false;
898
899 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
900}
901
902TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
903 mOutput.mState.transform = kIdentityTransform;
904
905 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
906
907 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
908
909 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
910}
911
912TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
913 mOutput.mState.transform = kIdentityTransform;
914
915 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
916
917 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
918
919 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
920}
921
922TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
923 mOutput.mState.transform = kRotate90Transform;
924
925 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
926
927 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
928
929 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
930}
931
932TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
933 mOutput.mState.transform = kRotate90Transform;
934
935 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
936
937 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
938
939 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
940}
941
942TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
943 mOutput.mState.transform = kIdentityTransform;
944 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
945
946 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
947
948 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
949
950 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
951}
952
953TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
954 mOutput.mState.transform = kRotate90Transform;
955 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
956
957 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
958
959 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
960
961 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
962}
963
964/*
965 * Output::collectVisibleLayers()
966 */
967
Lloyd Pique1ef93222019-11-21 16:41:53 -0800968struct OutputCollectVisibleLayersTest : public testing::Test {
969 struct OutputPartialMock : public OutputPartialMockBase {
970 // Sets up the helper functions called by the function under test to use
971 // mock implementations.
972 MOCK_METHOD2(ensureOutputLayerIfVisible,
973 void(std::shared_ptr<compositionengine::Layer>,
974 compositionengine::Output::CoverageState&));
975 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
976 MOCK_METHOD0(finalizePendingOutputLayers, void());
977 };
978
979 struct Layer {
980 Layer() {
981 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
982 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
983 }
984
985 StrictMock<mock::OutputLayer> outputLayer;
986 std::shared_ptr<StrictMock<mock::Layer>> layer{new StrictMock<mock::Layer>()};
987 impl::OutputLayerCompositionState outputLayerState;
988 };
989
990 OutputCollectVisibleLayersTest() {
991 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3));
992 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
993 .WillRepeatedly(Return(&mLayer1.outputLayer));
994 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
995 .WillRepeatedly(Return(&mLayer2.outputLayer));
996 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
997 .WillRepeatedly(Return(&mLayer3.outputLayer));
998
999 mRefreshArgs.layers.push_back(mLayer1.layer);
1000 mRefreshArgs.layers.push_back(mLayer2.layer);
1001 mRefreshArgs.layers.push_back(mLayer3.layer);
1002 }
1003
1004 StrictMock<OutputPartialMock> mOutput;
1005 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001006 LayerFESet mGeomSnapshots;
1007 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001008 Layer mLayer1;
1009 Layer mLayer2;
1010 Layer mLayer3;
1011};
1012
1013TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1014 mRefreshArgs.layers.clear();
1015 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0));
1016
1017 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1018 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1019
1020 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1021}
1022
1023TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1024 // Enforce a call order sequence for this test.
1025 InSequence seq;
1026
1027 // Layer coverage is evaluated from front to back!
1028 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layer), Ref(mCoverageState)));
1029 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layer), Ref(mCoverageState)));
1030 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layer), Ref(mCoverageState)));
1031
1032 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1033 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1034
1035 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1036
1037 // Ensure all output layers have been assigned a simple/flattened z-order.
1038 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1039 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1040 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1041}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001042
1043/*
1044 * Output::ensureOutputLayerIfVisible()
1045 */
1046
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001047struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1048 struct OutputPartialMock : public OutputPartialMockBase {
1049 // Sets up the helper functions called by the function under test to use
1050 // mock implementations.
1051 MOCK_CONST_METHOD1(belongsInOutput, bool(const compositionengine::Layer*));
1052 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
1053 MOCK_METHOD3(ensureOutputLayer,
1054 compositionengine::OutputLayer*(
1055 std::optional<size_t>,
1056 const std::shared_ptr<compositionengine::Layer>&, const sp<LayerFE>&));
1057 };
1058
1059 OutputEnsureOutputLayerIfVisibleTest() {
1060 EXPECT_CALL(*mLayer, getLayerFE()).WillRepeatedly(Return(mLayerFE));
1061 EXPECT_CALL(*mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
1062 EXPECT_CALL(*mLayer, editFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
1063
1064 EXPECT_CALL(mOutput, belongsInOutput(mLayer.get())).WillRepeatedly(Return(true));
1065 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1));
1066 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
1067 .WillRepeatedly(Return(&mOutputLayer));
1068
1069 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
1070 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
1071 EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(*mLayer.get()));
1072
1073 mOutput.mState.bounds = Rect(0, 0, 200, 300);
1074 mOutput.mState.viewport = Rect(0, 0, 200, 300);
1075 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1076
1077 mLayerFEState.isVisible = true;
1078 mLayerFEState.isOpaque = true;
1079 mLayerFEState.contentDirty = true;
1080 mLayerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1081 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1082 mLayerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
1083
1084 mOutputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1085 mOutputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
1086
1087 mGeomSnapshots.insert(mLayerFE);
1088 }
1089
1090 static const Region kEmptyRegion;
1091 static const Region kFullBoundsNoRotation;
1092 static const Region kRightHalfBoundsNoRotation;
1093 static const Region kLowerHalfBoundsNoRotation;
1094 static const Region kFullBounds90Rotation;
1095
1096 StrictMock<OutputPartialMock> mOutput;
1097 LayerFESet mGeomSnapshots;
1098 Output::CoverageState mCoverageState{mGeomSnapshots};
1099
1100 std::shared_ptr<mock::Layer> mLayer{new StrictMock<mock::Layer>()};
1101 sp<StrictMock<mock::LayerFE>> mLayerFE{new StrictMock<mock::LayerFE>()};
1102 LayerFECompositionState mLayerFEState;
1103 mock::OutputLayer mOutputLayer;
1104 impl::OutputLayerCompositionState mOutputLayerState;
1105};
1106
1107const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1108const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1109 Region(Rect(0, 0, 100, 200));
1110const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1111 Region(Rect(0, 100, 100, 200));
1112const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1113 Region(Rect(50, 0, 100, 200));
1114const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1115 Region(Rect(0, 0, 200, 100));
1116
1117TEST_F(OutputEnsureOutputLayerIfVisibleTest, doesNothingIfNoLayerFE) {
1118 EXPECT_CALL(*mLayer, getLayerFE).WillOnce(Return(sp<LayerFE>()));
1119
1120 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1121}
1122
1123TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
1124 EXPECT_CALL(mOutput, belongsInOutput(mLayer.get())).WillOnce(Return(false));
1125 EXPECT_CALL(*mLayerFE.get(),
1126 latchCompositionState(Ref(mLayerFEState),
1127 compositionengine::LayerFE::StateSubset::BasicGeometry));
1128
1129 mGeomSnapshots.clear();
1130
1131 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1132}
1133
1134TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1135 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
1136 EXPECT_CALL(mOutput, belongsInOutput(mLayer.get())).WillOnce(Return(false));
1137
1138 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1139}
1140
1141TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
1142 mLayerFEState.isVisible = false;
1143
1144 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1145}
1146
1147TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
1148 mLayerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
1149
1150 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1151}
1152
1153TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
1154 mOutput.mState.bounds = Rect(0, 0, 0, 0);
1155
1156 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1157}
1158
1159TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1160 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
1161 mLayerFEState.isOpaque = true;
1162 mLayerFEState.contentDirty = true;
1163 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1164
1165 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1166 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
1167 .WillOnce(Return(&mOutputLayer));
1168
1169 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1170
1171 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1172 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1173 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1174
1175 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1176 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1177 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1178 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1179}
1180
1181TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1182 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
1183 mLayerFEState.isOpaque = true;
1184 mLayerFEState.contentDirty = true;
1185 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1186
1187 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1188 .WillOnce(Return(&mOutputLayer));
1189
1190 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1191
1192 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1193 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1194 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1195
1196 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1197 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1198 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1199 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1200}
1201
1202TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1203 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
1204 mLayerFEState.isOpaque = false;
1205 mLayerFEState.contentDirty = true;
1206 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1207
1208 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1209 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
1210 .WillOnce(Return(&mOutputLayer));
1211
1212 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1213
1214 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1215 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1216 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1217
1218 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1219 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
1220 RegionEq(kRightHalfBoundsNoRotation));
1221 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1222 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1223}
1224
1225TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1226 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
1227 mLayerFEState.isOpaque = false;
1228 mLayerFEState.contentDirty = true;
1229 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1230
1231 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1232 .WillOnce(Return(&mOutputLayer));
1233
1234 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1235
1236 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1237 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1238 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1239
1240 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1241 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
1242 RegionEq(kRightHalfBoundsNoRotation));
1243 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1244 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1245}
1246
1247TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1248 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
1249 mLayerFEState.isOpaque = true;
1250 mLayerFEState.contentDirty = false;
1251 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1252
1253 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1254 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
1255 .WillOnce(Return(&mOutputLayer));
1256
1257 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1258
1259 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1260 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1261 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1262
1263 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1264 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1265 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1266 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1267}
1268
1269TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1270 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
1271 mLayerFEState.isOpaque = true;
1272 mLayerFEState.contentDirty = false;
1273 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1274
1275 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1276 .WillOnce(Return(&mOutputLayer));
1277
1278 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1279
1280 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1281 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1282 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1283
1284 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1285 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1286 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1287 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1288}
1289
1290TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1291 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
1292 mLayerFEState.isOpaque = true;
1293 mLayerFEState.contentDirty = true;
1294 mLayerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1295 mLayerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1296 mOutputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1297 mOutputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
1298
1299 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1300 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
1301 .WillOnce(Return(&mOutputLayer));
1302
1303 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1304
1305 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1306 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1307 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1308
1309 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1310 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1311 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1312 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1313}
1314
1315TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1316 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
1317 mLayerFEState.isOpaque = true;
1318 mLayerFEState.contentDirty = true;
1319 mLayerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1320 mLayerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1321 mOutputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1322 mOutputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
1323
1324 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1325 .WillOnce(Return(&mOutputLayer));
1326
1327 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1328
1329 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1330 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1331 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1332
1333 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1334 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1335 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1336 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
1337}
1338
1339TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1340 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
1341 mLayerFEState.isOpaque = true;
1342 mLayerFEState.contentDirty = true;
1343 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1344
1345 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1346 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1347
1348 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1349 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
1350 .WillOnce(Return(&mOutputLayer));
1351
1352 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1353
1354 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1355 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1356 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1357
1358 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1359 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1361 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
1362}
1363
1364TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1365 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
1366 mLayerFEState.isOpaque = true;
1367 mLayerFEState.contentDirty = true;
1368 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1369
1370 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1371 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1372
1373 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1374 .WillOnce(Return(&mOutputLayer));
1375
1376 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1377
1378 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1379 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1380 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1381
1382 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1383 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kFullBoundsNoRotation));
1384 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1385 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
1386}
1387
1388TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1389 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1390 ui::Transform arbitraryTransform;
1391 arbitraryTransform.set(1, 1, -1, 1);
1392 arbitraryTransform.set(0, 100);
1393
1394 mLayerFEState.isOpaque = true;
1395 mLayerFEState.contentDirty = true;
1396 mLayerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1397 mLayerFEState.geomLayerTransform = arbitraryTransform;
1398
1399 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1400 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer), Eq(mLayerFE)))
1401 .WillOnce(Return(&mOutputLayer));
1402
1403 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1404
1405 const Region kRegion = Region(Rect(0, 0, 300, 300));
1406 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1407
1408 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1409 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1410 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1411
1412 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kRegion));
1413 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1414 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1415 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
1416}
1417
1418TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
1419 mLayerFEState.isOpaque = false;
1420 mLayerFEState.contentDirty = true;
1421 mLayerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1422
1423 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1424 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1425 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1426
1427 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1428 .WillOnce(Return(&mOutputLayer));
1429
1430 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1431
1432 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1433 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1434 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1435 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1436 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1437 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1438
1439 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1440 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1441 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1442
1443 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1444 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
1445 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
1446 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1447 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1448}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001449
Vishnu Naira483b4a2019-12-12 15:07:52 -08001450TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1451 ui::Transform translate;
1452 translate.set(50, 50);
1453 mLayerFEState.geomLayerTransform = translate;
1454 mLayerFEState.shadowRadius = 10.0f;
1455
1456 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1457 // half of the layer including the casting shadow is covered and opaque
1458 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1459 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1460
1461 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1462 .WillOnce(Return(&mOutputLayer));
1463
1464 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1465
1466 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1467 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1468 // add starting opaque region to the opaque half of the casting layer bounds
1469 const Region kExpectedAboveOpaqueRegion =
1470 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1471 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1472 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1473 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1474 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1475 const Region kExpectedLayerShadowRegion =
1476 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1477
1478 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1479 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1480 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1481
1482 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1483 EXPECT_THAT(mOutputLayerState.visibleNonTransparentRegion,
1484 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
1485 EXPECT_THAT(mOutputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1486 EXPECT_THAT(mOutputLayerState.outputSpaceVisibleRegion,
1487 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
1488 EXPECT_THAT(mOutputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
1489 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1490}
1491
1492TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1493 ui::Transform translate;
1494 translate.set(50, 50);
1495 mLayerFEState.geomLayerTransform = translate;
1496 mLayerFEState.shadowRadius = 10.0f;
1497
1498 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1499 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1500 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1501 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1502
1503 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer), Eq(mLayerFE)))
1504 .WillOnce(Return(&mOutputLayer));
1505
1506 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1507
1508 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1509 const Region kExpectedLayerShadowRegion =
1510 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1511
1512 EXPECT_THAT(mOutputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1513 EXPECT_THAT(mOutputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
1514 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1515}
1516
1517TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
1518 ui::Transform translate;
1519 translate.set(50, 50);
1520 mLayerFEState.geomLayerTransform = translate;
1521 mLayerFEState.shadowRadius = 10.0f;
1522
1523 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1524 // Casting layer and its shadows are covered by an opaque region
1525 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1526 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1527
1528 mOutput.ensureOutputLayerIfVisible(mLayer, mCoverageState);
1529}
1530
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001531/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001532 * Output::present()
1533 */
1534
1535struct OutputPresentTest : public testing::Test {
1536 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001537 // Sets up the helper functions called by the function under test to use
1538 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001539 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1540 MOCK_METHOD1(updateAndWriteCompositionState,
1541 void(const compositionengine::CompositionRefreshArgs&));
1542 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1543 MOCK_METHOD0(beginFrame, void());
1544 MOCK_METHOD0(prepareFrame, void());
1545 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1546 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1547 MOCK_METHOD0(postFramebuffer, void());
1548 };
1549
1550 StrictMock<OutputPartialMock> mOutput;
1551};
1552
1553TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1554 CompositionRefreshArgs args;
1555
1556 InSequence seq;
1557 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1558 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1559 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1560 EXPECT_CALL(mOutput, beginFrame());
1561 EXPECT_CALL(mOutput, prepareFrame());
1562 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1563 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1564 EXPECT_CALL(mOutput, postFramebuffer());
1565
1566 mOutput.present(args);
1567}
1568
1569/*
1570 * Output::updateColorProfile()
1571 */
1572
Lloyd Pique17ca7422019-11-14 14:24:10 -08001573struct OutputUpdateColorProfileTest : public testing::Test {
1574 using TestType = OutputUpdateColorProfileTest;
1575
1576 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001577 // Sets up the helper functions called by the function under test to use
1578 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001579 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1580 };
1581
1582 struct Layer {
1583 Layer() {
1584 EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
1585 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
1586 EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
1587 }
1588
1589 StrictMock<mock::OutputLayer> mOutputLayer;
1590 StrictMock<mock::Layer> mLayer;
1591 StrictMock<mock::LayerFE> mLayerFE;
1592 LayerFECompositionState mLayerFEState;
1593 };
1594
1595 OutputUpdateColorProfileTest() {
1596 mOutput.setDisplayColorProfileForTest(
1597 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1598 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1599
1600 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1601 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1602 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1603 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1604 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1605 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1606 }
1607
1608 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1609 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1610 };
1611
1612 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1613 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1614 StrictMock<OutputPartialMock> mOutput;
1615
1616 Layer mLayer1;
1617 Layer mLayer2;
1618 Layer mLayer3;
1619
1620 CompositionRefreshArgs mRefreshArgs;
1621};
1622
1623// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1624// to make it easier to write unit tests.
1625
1626TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1627 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1628 // a simple default color profile without looking at anything else.
1629
1630 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3));
1631 EXPECT_CALL(mOutput,
1632 setColorProfile(ColorProfileEq(
1633 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1634 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1635
1636 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1637 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1638
1639 mOutput.updateColorProfile(mRefreshArgs);
1640}
1641
1642struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1643 : public OutputUpdateColorProfileTest {
1644 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
1645 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0));
1646 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1647 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1648 }
1649
1650 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1651 : public CallOrderStateMachineHelper<
1652 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1653 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1654 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1655 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1656 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1657 _))
1658 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1659 SetArgPointee<4>(renderIntent)));
1660 EXPECT_CALL(getInstance()->mOutput,
1661 setColorProfile(
1662 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1663 ui::Dataspace::UNKNOWN})));
1664 return nextState<ExecuteState>();
1665 }
1666 };
1667
1668 // Call this member function to start using the mini-DSL defined above.
1669 [[nodiscard]] auto verify() {
1670 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1671 }
1672};
1673
1674TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1675 Native_Unknown_Colorimetric_Set) {
1676 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1677 ui::Dataspace::UNKNOWN,
1678 ui::RenderIntent::COLORIMETRIC)
1679 .execute();
1680}
1681
1682TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1683 DisplayP3_DisplayP3_Enhance_Set) {
1684 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1685 ui::Dataspace::DISPLAY_P3,
1686 ui::RenderIntent::ENHANCE)
1687 .execute();
1688}
1689
1690struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1691 : public OutputUpdateColorProfileTest {
1692 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
1693 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0));
1694 EXPECT_CALL(*mDisplayColorProfile,
1695 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1696 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1697 SetArgPointee<3>(ui::ColorMode::NATIVE),
1698 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1699 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1700 }
1701
1702 struct IfColorSpaceAgnosticDataspaceSetToState
1703 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1704 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1705 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1706 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1707 }
1708 };
1709
1710 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1711 : public CallOrderStateMachineHelper<
1712 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1713 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1714 ui::Dataspace dataspace) {
1715 EXPECT_CALL(getInstance()->mOutput,
1716 setColorProfile(ColorProfileEq(
1717 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1718 ui::RenderIntent::COLORIMETRIC, dataspace})));
1719 return nextState<ExecuteState>();
1720 }
1721 };
1722
1723 // Call this member function to start using the mini-DSL defined above.
1724 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1725};
1726
1727TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1728 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1729 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1730 .execute();
1731}
1732
1733TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1734 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1735 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1736 .execute();
1737}
1738
1739struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1740 : public OutputUpdateColorProfileTest {
1741 // Internally the implementation looks through the dataspaces of all the
1742 // visible layers. The topmost one that also has an actual dataspace
1743 // preference set is used to drive subsequent choices.
1744
1745 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1746 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1747 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1748
1749 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3));
1750 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1751 }
1752
1753 struct IfTopLayerDataspaceState
1754 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1755 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1756 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1757 return nextState<AndIfMiddleLayerDataspaceState>();
1758 }
1759 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1760 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1761 }
1762 };
1763
1764 struct AndIfMiddleLayerDataspaceState
1765 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1766 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1767 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1768 return nextState<AndIfBottomLayerDataspaceState>();
1769 }
1770 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1771 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1772 }
1773 };
1774
1775 struct AndIfBottomLayerDataspaceState
1776 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1777 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1778 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1779 return nextState<ThenExpectBestColorModeCallUsesState>();
1780 }
1781 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1782 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1783 }
1784 };
1785
1786 struct ThenExpectBestColorModeCallUsesState
1787 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1788 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1789 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1790 getBestColorMode(dataspace, _, _, _, _));
1791 return nextState<ExecuteState>();
1792 }
1793 };
1794
1795 // Call this member function to start using the mini-DSL defined above.
1796 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1797};
1798
1799TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1800 noStrongLayerPrefenceUses_V0_SRGB) {
1801 // If none of the layers indicate a preference, then V0_SRGB is the
1802 // preferred choice (subject to additional checks).
1803 verify().ifTopLayerHasNoPreference()
1804 .andIfMiddleLayerHasNoPreference()
1805 .andIfBottomLayerHasNoPreference()
1806 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1807 .execute();
1808}
1809
1810TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1811 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1812 // If only the topmost layer has a preference, then that is what is chosen.
1813 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1814 .andIfMiddleLayerHasNoPreference()
1815 .andIfBottomLayerHasNoPreference()
1816 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1817 .execute();
1818}
1819
1820TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1821 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1822 // If only the middle layer has a preference, that that is what is chosen.
1823 verify().ifTopLayerHasNoPreference()
1824 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1825 .andIfBottomLayerHasNoPreference()
1826 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1827 .execute();
1828}
1829
1830TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1831 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1832 // If only the middle layer has a preference, that that is what is chosen.
1833 verify().ifTopLayerHasNoPreference()
1834 .andIfMiddleLayerHasNoPreference()
1835 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1836 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1837 .execute();
1838}
1839
1840TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1841 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1842 // If multiple layers have a preference, the topmost value is what is used.
1843 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1844 .andIfMiddleLayerHasNoPreference()
1845 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1846 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1847 .execute();
1848}
1849
1850TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1851 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1852 // If multiple layers have a preference, the topmost value is what is used.
1853 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1854 .andIfMiddleLayerHasNoPreference()
1855 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1856 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1857 .execute();
1858}
1859
1860struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1861 : public OutputUpdateColorProfileTest {
1862 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1863 // values, it overrides the layer dataspace choice.
1864
1865 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1866 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1867 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1868
1869 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1870
1871 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1));
1872 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1873 }
1874
1875 struct IfForceOutputColorModeState
1876 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1877 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1878 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1879 return nextState<ThenExpectBestColorModeCallUsesState>();
1880 }
1881 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1882 };
1883
1884 struct ThenExpectBestColorModeCallUsesState
1885 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1886 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1887 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1888 getBestColorMode(dataspace, _, _, _, _));
1889 return nextState<ExecuteState>();
1890 }
1891 };
1892
1893 // Call this member function to start using the mini-DSL defined above.
1894 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1895};
1896
1897TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1898 // By default the layer state is used to set the preferred dataspace
1899 verify().ifNoOverride()
1900 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1901 .execute();
1902}
1903
1904TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1905 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1906 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1907 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1908 .execute();
1909}
1910
1911TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1912 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1913 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1914 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1915 .execute();
1916}
1917
1918// HDR output requires all layers to be compatible with the chosen HDR
1919// dataspace, along with there being proper support.
1920struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1921 OutputUpdateColorProfileTest_Hdr() {
1922 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1923 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1924 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2));
1925 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1926 }
1927
1928 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1929 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1930 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1931 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1932
1933 struct IfTopLayerDataspaceState
1934 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1935 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1936 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1937 return nextState<AndTopLayerCompositionTypeState>();
1938 }
1939 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1940 };
1941
1942 struct AndTopLayerCompositionTypeState
1943 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1944 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1945 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1946 return nextState<AndIfBottomLayerDataspaceState>();
1947 }
1948 };
1949
1950 struct AndIfBottomLayerDataspaceState
1951 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1952 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1953 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1954 return nextState<AndBottomLayerCompositionTypeState>();
1955 }
1956 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1957 return andIfBottomLayerIs(kNonHdrDataspace);
1958 }
1959 };
1960
1961 struct AndBottomLayerCompositionTypeState
1962 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1963 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1964 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1965 return nextState<AndIfHasLegacySupportState>();
1966 }
1967 };
1968
1969 struct AndIfHasLegacySupportState
1970 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1971 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1972 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1973 .WillOnce(Return(legacySupport));
1974 return nextState<ThenExpectBestColorModeCallUsesState>();
1975 }
1976 };
1977
1978 struct ThenExpectBestColorModeCallUsesState
1979 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1980 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1981 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1982 getBestColorMode(dataspace, _, _, _, _));
1983 return nextState<ExecuteState>();
1984 }
1985 };
1986
1987 // Call this member function to start using the mini-DSL defined above.
1988 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1989};
1990
1991TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
1992 // If all layers use BT2020_PQ, and there are no other special conditions,
1993 // BT2020_PQ is used.
1994 verify().ifTopLayerIs(BT2020_PQ)
1995 .andTopLayerIsREComposed(false)
1996 .andIfBottomLayerIs(BT2020_PQ)
1997 .andBottomLayerIsREComposed(false)
1998 .andIfLegacySupportFor(BT2020_PQ, false)
1999 .thenExpectBestColorModeCallUses(BT2020_PQ)
2000 .execute();
2001}
2002
2003TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2004 // BT2020_PQ is not used if there is only legacy support for it.
2005 verify().ifTopLayerIs(BT2020_PQ)
2006 .andTopLayerIsREComposed(false)
2007 .andIfBottomLayerIs(BT2020_PQ)
2008 .andBottomLayerIsREComposed(false)
2009 .andIfLegacySupportFor(BT2020_PQ, true)
2010 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2011 .execute();
2012}
2013
2014TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2015 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2016 verify().ifTopLayerIs(BT2020_PQ)
2017 .andTopLayerIsREComposed(false)
2018 .andIfBottomLayerIs(BT2020_PQ)
2019 .andBottomLayerIsREComposed(true)
2020 .andIfLegacySupportFor(BT2020_PQ, false)
2021 .thenExpectBestColorModeCallUses(BT2020_PQ)
2022 .execute();
2023}
2024
2025TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2026 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2027 verify().ifTopLayerIs(BT2020_PQ)
2028 .andTopLayerIsREComposed(true)
2029 .andIfBottomLayerIs(BT2020_PQ)
2030 .andBottomLayerIsREComposed(false)
2031 .andIfLegacySupportFor(BT2020_PQ, false)
2032 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2033 .execute();
2034}
2035
2036TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2037 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2038 // are no other special conditions.
2039 verify().ifTopLayerIs(BT2020_PQ)
2040 .andTopLayerIsREComposed(false)
2041 .andIfBottomLayerIs(BT2020_HLG)
2042 .andBottomLayerIsREComposed(false)
2043 .andIfLegacySupportFor(BT2020_PQ, false)
2044 .thenExpectBestColorModeCallUses(BT2020_PQ)
2045 .execute();
2046}
2047
2048TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2049 // BT2020_PQ is not used if there is only legacy support for it.
2050 verify().ifTopLayerIs(BT2020_PQ)
2051 .andTopLayerIsREComposed(false)
2052 .andIfBottomLayerIs(BT2020_HLG)
2053 .andBottomLayerIsREComposed(false)
2054 .andIfLegacySupportFor(BT2020_PQ, true)
2055 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2056 .execute();
2057}
2058
2059TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2060 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2061 verify().ifTopLayerIs(BT2020_PQ)
2062 .andTopLayerIsREComposed(false)
2063 .andIfBottomLayerIs(BT2020_HLG)
2064 .andBottomLayerIsREComposed(true)
2065 .andIfLegacySupportFor(BT2020_PQ, false)
2066 .thenExpectBestColorModeCallUses(BT2020_PQ)
2067 .execute();
2068}
2069
2070TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2071 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2072 verify().ifTopLayerIs(BT2020_PQ)
2073 .andTopLayerIsREComposed(true)
2074 .andIfBottomLayerIs(BT2020_HLG)
2075 .andBottomLayerIsREComposed(false)
2076 .andIfLegacySupportFor(BT2020_PQ, false)
2077 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2078 .execute();
2079}
2080
2081TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2082 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2083 // used if there are no other special conditions.
2084 verify().ifTopLayerIs(BT2020_HLG)
2085 .andTopLayerIsREComposed(false)
2086 .andIfBottomLayerIs(BT2020_PQ)
2087 .andBottomLayerIsREComposed(false)
2088 .andIfLegacySupportFor(BT2020_PQ, false)
2089 .thenExpectBestColorModeCallUses(BT2020_PQ)
2090 .execute();
2091}
2092
2093TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2094 // BT2020_PQ is not used if there is only legacy support for it.
2095 verify().ifTopLayerIs(BT2020_HLG)
2096 .andTopLayerIsREComposed(false)
2097 .andIfBottomLayerIs(BT2020_PQ)
2098 .andBottomLayerIsREComposed(false)
2099 .andIfLegacySupportFor(BT2020_PQ, true)
2100 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2101 .execute();
2102}
2103
2104TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2105 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2106 verify().ifTopLayerIs(BT2020_HLG)
2107 .andTopLayerIsREComposed(false)
2108 .andIfBottomLayerIs(BT2020_PQ)
2109 .andBottomLayerIsREComposed(true)
2110 .andIfLegacySupportFor(BT2020_PQ, false)
2111 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2112 .execute();
2113}
2114
2115TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2116 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2117 verify().ifTopLayerIs(BT2020_HLG)
2118 .andTopLayerIsREComposed(true)
2119 .andIfBottomLayerIs(BT2020_PQ)
2120 .andBottomLayerIsREComposed(false)
2121 .andIfLegacySupportFor(BT2020_PQ, false)
2122 .thenExpectBestColorModeCallUses(BT2020_PQ)
2123 .execute();
2124}
2125
2126TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2127 // If all layers use HLG then HLG is used if there are no other special
2128 // conditions.
2129 verify().ifTopLayerIs(BT2020_HLG)
2130 .andTopLayerIsREComposed(false)
2131 .andIfBottomLayerIs(BT2020_HLG)
2132 .andBottomLayerIsREComposed(false)
2133 .andIfLegacySupportFor(BT2020_HLG, false)
2134 .thenExpectBestColorModeCallUses(BT2020_HLG)
2135 .execute();
2136}
2137
2138TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2139 // BT2020_HLG is not used if there is legacy support for it.
2140 verify().ifTopLayerIs(BT2020_HLG)
2141 .andTopLayerIsREComposed(false)
2142 .andIfBottomLayerIs(BT2020_HLG)
2143 .andBottomLayerIsREComposed(false)
2144 .andIfLegacySupportFor(BT2020_HLG, true)
2145 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2146 .execute();
2147}
2148
2149TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2150 // BT2020_HLG is used even if the bottom layer is client composed.
2151 verify().ifTopLayerIs(BT2020_HLG)
2152 .andTopLayerIsREComposed(false)
2153 .andIfBottomLayerIs(BT2020_HLG)
2154 .andBottomLayerIsREComposed(true)
2155 .andIfLegacySupportFor(BT2020_HLG, false)
2156 .thenExpectBestColorModeCallUses(BT2020_HLG)
2157 .execute();
2158}
2159
2160TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2161 // BT2020_HLG is used even if the top layer is client composed.
2162 verify().ifTopLayerIs(BT2020_HLG)
2163 .andTopLayerIsREComposed(true)
2164 .andIfBottomLayerIs(BT2020_HLG)
2165 .andBottomLayerIsREComposed(false)
2166 .andIfLegacySupportFor(BT2020_HLG, false)
2167 .thenExpectBestColorModeCallUses(BT2020_HLG)
2168 .execute();
2169}
2170
2171TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2172 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2173 verify().ifTopLayerIs(BT2020_PQ)
2174 .andTopLayerIsREComposed(false)
2175 .andIfBottomLayerIsNotHdr()
2176 .andBottomLayerIsREComposed(false)
2177 .andIfLegacySupportFor(BT2020_PQ, false)
2178 .thenExpectBestColorModeCallUses(BT2020_PQ)
2179 .execute();
2180}
2181
2182TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2183 // If all layers use HLG then HLG is used if there are no other special
2184 // conditions.
2185 verify().ifTopLayerIs(BT2020_HLG)
2186 .andTopLayerIsREComposed(false)
2187 .andIfBottomLayerIsNotHdr()
2188 .andBottomLayerIsREComposed(true)
2189 .andIfLegacySupportFor(BT2020_HLG, false)
2190 .thenExpectBestColorModeCallUses(BT2020_HLG)
2191 .execute();
2192}
2193
2194struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2195 : public OutputUpdateColorProfileTest {
2196 // The various values for CompositionRefreshArgs::outputColorSetting affect
2197 // the chosen renderIntent, along with whether the preferred dataspace is an
2198 // HDR dataspace or not.
2199
2200 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2201 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2202 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2203 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
2204 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1));
2205 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2206 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2207 .WillRepeatedly(Return(false));
2208 }
2209
2210 // The tests here involve enough state and GMock setup that using a mini-DSL
2211 // makes the tests much more readable, and allows the test to focus more on
2212 // the intent than on some of the details.
2213
2214 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2215 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2216
2217 struct IfDataspaceChosenState
2218 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2219 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2220 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2221 return nextState<AndOutputColorSettingState>();
2222 }
2223 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2224 return ifDataspaceChosenIs(kNonHdrDataspace);
2225 }
2226 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2227 };
2228
2229 struct AndOutputColorSettingState
2230 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2231 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2232 getInstance()->mRefreshArgs.outputColorSetting = setting;
2233 return nextState<ThenExpectBestColorModeCallUsesState>();
2234 }
2235 };
2236
2237 struct ThenExpectBestColorModeCallUsesState
2238 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2239 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2240 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2241 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2242 _, _));
2243 return nextState<ExecuteState>();
2244 }
2245 };
2246
2247 // Tests call one of these two helper member functions to start using the
2248 // mini-DSL defined above.
2249 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2250};
2251
2252TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2253 Managed_NonHdr_Prefers_Colorimetric) {
2254 verify().ifDataspaceChosenIsNonHdr()
2255 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2256 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2257 .execute();
2258}
2259
2260TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2261 Managed_Hdr_Prefers_ToneMapColorimetric) {
2262 verify().ifDataspaceChosenIsHdr()
2263 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2264 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2265 .execute();
2266}
2267
2268TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2269 verify().ifDataspaceChosenIsNonHdr()
2270 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2271 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2272 .execute();
2273}
2274
2275TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2276 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2277 verify().ifDataspaceChosenIsHdr()
2278 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2279 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2280 .execute();
2281}
2282
2283TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2284 verify().ifDataspaceChosenIsNonHdr()
2285 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2286 .thenExpectBestColorModeCallUses(
2287 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2288 .execute();
2289}
2290
2291TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2292 verify().ifDataspaceChosenIsHdr()
2293 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2294 .thenExpectBestColorModeCallUses(
2295 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2296 .execute();
2297}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002298
2299/*
2300 * Output::beginFrame()
2301 */
2302
Lloyd Piquee5965952019-11-18 16:16:32 -08002303struct OutputBeginFrameTest : public ::testing::Test {
2304 using TestType = OutputBeginFrameTest;
2305
2306 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002307 // Sets up the helper functions called by the function under test to use
2308 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002309 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2310 };
2311
2312 OutputBeginFrameTest() {
2313 mOutput.setDisplayColorProfileForTest(
2314 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2315 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2316 }
2317
2318 struct IfGetDirtyRegionExpectationState
2319 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2320 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2321 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2322 .WillOnce(Return(dirtyRegion));
2323 return nextState<AndIfGetOutputLayerCountExpectationState>();
2324 }
2325 };
2326
2327 struct AndIfGetOutputLayerCountExpectationState
2328 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2329 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2330 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2331 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2332 }
2333 };
2334
2335 struct AndIfLastCompositionHadVisibleLayersState
2336 : public CallOrderStateMachineHelper<TestType,
2337 AndIfLastCompositionHadVisibleLayersState> {
2338 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2339 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2340 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2341 }
2342 };
2343
2344 struct ThenExpectRenderSurfaceBeginFrameCallState
2345 : public CallOrderStateMachineHelper<TestType,
2346 ThenExpectRenderSurfaceBeginFrameCallState> {
2347 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2348 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2349 return nextState<ExecuteState>();
2350 }
2351 };
2352
2353 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2354 [[nodiscard]] auto execute() {
2355 getInstance()->mOutput.beginFrame();
2356 return nextState<CheckPostconditionHadVisibleLayersState>();
2357 }
2358 };
2359
2360 struct CheckPostconditionHadVisibleLayersState
2361 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2362 void checkPostconditionHadVisibleLayers(bool expected) {
2363 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2364 }
2365 };
2366
2367 // Tests call one of these two helper member functions to start using the
2368 // mini-DSL defined above.
2369 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2370
2371 static const Region kEmptyRegion;
2372 static const Region kNotEmptyRegion;
2373
2374 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2375 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2376 StrictMock<OutputPartialMock> mOutput;
2377};
2378
2379const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2380const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2381
2382TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2383 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2384 .andIfGetOutputLayerCountReturns(1u)
2385 .andIfLastCompositionHadVisibleLayersIs(true)
2386 .thenExpectRenderSurfaceBeginFrameCall(true)
2387 .execute()
2388 .checkPostconditionHadVisibleLayers(true);
2389}
2390
2391TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2392 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2393 .andIfGetOutputLayerCountReturns(0u)
2394 .andIfLastCompositionHadVisibleLayersIs(true)
2395 .thenExpectRenderSurfaceBeginFrameCall(true)
2396 .execute()
2397 .checkPostconditionHadVisibleLayers(false);
2398}
2399
2400TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2401 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2402 .andIfGetOutputLayerCountReturns(1u)
2403 .andIfLastCompositionHadVisibleLayersIs(false)
2404 .thenExpectRenderSurfaceBeginFrameCall(true)
2405 .execute()
2406 .checkPostconditionHadVisibleLayers(true);
2407}
2408
2409TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2410 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2411 .andIfGetOutputLayerCountReturns(0u)
2412 .andIfLastCompositionHadVisibleLayersIs(false)
2413 .thenExpectRenderSurfaceBeginFrameCall(false)
2414 .execute()
2415 .checkPostconditionHadVisibleLayers(false);
2416}
2417
2418TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2419 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2420 .andIfGetOutputLayerCountReturns(1u)
2421 .andIfLastCompositionHadVisibleLayersIs(true)
2422 .thenExpectRenderSurfaceBeginFrameCall(false)
2423 .execute()
2424 .checkPostconditionHadVisibleLayers(true);
2425}
2426
2427TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2428 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2429 .andIfGetOutputLayerCountReturns(0u)
2430 .andIfLastCompositionHadVisibleLayersIs(true)
2431 .thenExpectRenderSurfaceBeginFrameCall(false)
2432 .execute()
2433 .checkPostconditionHadVisibleLayers(true);
2434}
2435
2436TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2437 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2438 .andIfGetOutputLayerCountReturns(1u)
2439 .andIfLastCompositionHadVisibleLayersIs(false)
2440 .thenExpectRenderSurfaceBeginFrameCall(false)
2441 .execute()
2442 .checkPostconditionHadVisibleLayers(false);
2443}
2444
2445TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2446 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2447 .andIfGetOutputLayerCountReturns(0u)
2448 .andIfLastCompositionHadVisibleLayersIs(false)
2449 .thenExpectRenderSurfaceBeginFrameCall(false)
2450 .execute()
2451 .checkPostconditionHadVisibleLayers(false);
2452}
2453
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002454/*
2455 * Output::devOptRepaintFlash()
2456 */
2457
Lloyd Piquedb462d82019-11-19 17:58:46 -08002458struct OutputDevOptRepaintFlashTest : public testing::Test {
2459 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002460 // Sets up the helper functions called by the function under test to use
2461 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002462 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2463 MOCK_METHOD1(composeSurfaces, std::optional<base::unique_fd>(const Region&));
2464 MOCK_METHOD0(postFramebuffer, void());
2465 MOCK_METHOD0(prepareFrame, void());
2466 };
2467
2468 OutputDevOptRepaintFlashTest() {
2469 mOutput.setDisplayColorProfileForTest(
2470 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2471 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2472 }
2473
2474 static const Region kEmptyRegion;
2475 static const Region kNotEmptyRegion;
2476
2477 StrictMock<OutputPartialMock> mOutput;
2478 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2479 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2480 CompositionRefreshArgs mRefreshArgs;
2481};
2482
2483const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2484const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2485
2486TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2487 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2488 mRefreshArgs.repaintEverything = true;
2489 mOutput.mState.isEnabled = true;
2490
2491 mOutput.devOptRepaintFlash(mRefreshArgs);
2492}
2493
2494TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2495 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2496 mRefreshArgs.repaintEverything = true;
2497 mOutput.mState.isEnabled = false;
2498
2499 InSequence seq;
2500 EXPECT_CALL(mOutput, postFramebuffer());
2501 EXPECT_CALL(mOutput, prepareFrame());
2502
2503 mOutput.devOptRepaintFlash(mRefreshArgs);
2504}
2505
2506TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2507 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2508 mRefreshArgs.repaintEverything = true;
2509 mOutput.mState.isEnabled = true;
2510
2511 InSequence seq;
2512 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2513 EXPECT_CALL(mOutput, postFramebuffer());
2514 EXPECT_CALL(mOutput, prepareFrame());
2515
2516 mOutput.devOptRepaintFlash(mRefreshArgs);
2517}
2518
2519TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2520 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2521 mRefreshArgs.repaintEverything = false;
2522 mOutput.mState.isEnabled = true;
2523
2524 InSequence seq;
2525 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
2526 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion)));
2527 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2528 EXPECT_CALL(mOutput, postFramebuffer());
2529 EXPECT_CALL(mOutput, prepareFrame());
2530
2531 mOutput.devOptRepaintFlash(mRefreshArgs);
2532}
2533
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002534/*
2535 * Output::finishFrame()
2536 */
2537
Lloyd Pique03561a62019-11-19 18:34:52 -08002538struct OutputFinishFrameTest : public testing::Test {
2539 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002540 // Sets up the helper functions called by the function under test to use
2541 // mock implementations.
Lloyd Pique03561a62019-11-19 18:34:52 -08002542 MOCK_METHOD1(composeSurfaces, std::optional<base::unique_fd>(const Region&));
2543 MOCK_METHOD0(postFramebuffer, void());
2544 };
2545
2546 OutputFinishFrameTest() {
2547 mOutput.setDisplayColorProfileForTest(
2548 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2549 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2550 }
2551
2552 StrictMock<OutputPartialMock> mOutput;
2553 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2554 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2555 CompositionRefreshArgs mRefreshArgs;
2556};
2557
2558TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2559 mOutput.mState.isEnabled = false;
2560
2561 mOutput.finishFrame(mRefreshArgs);
2562}
2563
2564TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2565 mOutput.mState.isEnabled = true;
2566
2567 InSequence seq;
2568 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION)));
2569
2570 mOutput.finishFrame(mRefreshArgs);
2571}
2572
2573TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2574 mOutput.mState.isEnabled = true;
2575
2576 InSequence seq;
2577 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION)))
2578 .WillOnce(Return(ByMove(base::unique_fd())));
2579 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2580
2581 mOutput.finishFrame(mRefreshArgs);
2582}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002583
2584/*
2585 * Output::postFramebuffer()
2586 */
2587
Lloyd Pique07178e32019-11-19 19:15:26 -08002588struct OutputPostFramebufferTest : public testing::Test {
2589 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002590 // Sets up the helper functions called by the function under test to use
2591 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002592 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2593 };
2594
2595 struct Layer {
2596 Layer() {
2597 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2598 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2599 }
2600
2601 StrictMock<mock::OutputLayer> outputLayer;
2602 StrictMock<mock::LayerFE> layerFE;
2603 StrictMock<HWC2::mock::Layer> hwc2Layer;
2604 };
2605
2606 OutputPostFramebufferTest() {
2607 mOutput.setDisplayColorProfileForTest(
2608 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2609 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2610
2611 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2612 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2613 .WillRepeatedly(Return(&mLayer1.outputLayer));
2614 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2615 .WillRepeatedly(Return(&mLayer2.outputLayer));
2616 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2617 .WillRepeatedly(Return(&mLayer3.outputLayer));
2618 }
2619
2620 StrictMock<OutputPartialMock> mOutput;
2621 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2622 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2623
2624 Layer mLayer1;
2625 Layer mLayer2;
2626 Layer mLayer3;
2627};
2628
2629TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2630 mOutput.mState.isEnabled = false;
2631
2632 mOutput.postFramebuffer();
2633}
2634
2635TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2636 mOutput.mState.isEnabled = true;
2637
2638 compositionengine::Output::FrameFences frameFences;
2639
2640 // This should happen even if there are no output layers.
2641 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2642
2643 // For this test in particular we want to make sure the call expectations
2644 // setup below are satisfied in the specific order.
2645 InSequence seq;
2646
2647 EXPECT_CALL(*mRenderSurface, flip());
2648 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2649 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2650
2651 mOutput.postFramebuffer();
2652}
2653
2654TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2655 // Simulate getting release fences from each layer, and ensure they are passed to the
2656 // front-end layer interface for each layer correctly.
2657
2658 mOutput.mState.isEnabled = true;
2659
2660 // Create three unique fence instances
2661 sp<Fence> layer1Fence = new Fence();
2662 sp<Fence> layer2Fence = new Fence();
2663 sp<Fence> layer3Fence = new Fence();
2664
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002665 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002666 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2667 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2668 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2669
2670 EXPECT_CALL(*mRenderSurface, flip());
2671 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2672 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2673
2674 // Compare the pointers values of each fence to make sure the correct ones
2675 // are passed. This happens to work with the current implementation, but
2676 // would not survive certain calls like Fence::merge() which would return a
2677 // new instance.
2678 EXPECT_CALL(mLayer1.layerFE,
2679 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2680 EXPECT_CALL(mLayer2.layerFE,
2681 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2682 EXPECT_CALL(mLayer3.layerFE,
2683 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2684
2685 mOutput.postFramebuffer();
2686}
2687
2688TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2689 mOutput.mState.isEnabled = true;
2690 mOutput.mState.usesClientComposition = true;
2691
2692 sp<Fence> clientTargetAcquireFence = new Fence();
2693 sp<Fence> layer1Fence = new Fence();
2694 sp<Fence> layer2Fence = new Fence();
2695 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002696 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002697 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2698 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2699 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2700 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2701
2702 EXPECT_CALL(*mRenderSurface, flip());
2703 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2704 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2705
2706 // Fence::merge is called, and since none of the fences are actually valid,
2707 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2708 // This is the best we can do without creating a real kernel fence object.
2709 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2710 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2711 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2712
2713 mOutput.postFramebuffer();
2714}
2715
2716TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2717 mOutput.mState.isEnabled = true;
2718 mOutput.mState.usesClientComposition = true;
2719
2720 // This should happen even if there are no (current) output layers.
2721 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2722
2723 // Load up the released layers with some mock instances
2724 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2725 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2726 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2727 Output::ReleasedLayers layers;
2728 layers.push_back(releasedLayer1);
2729 layers.push_back(releasedLayer2);
2730 layers.push_back(releasedLayer3);
2731 mOutput.setReleasedLayers(std::move(layers));
2732
2733 // Set up a fake present fence
2734 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002735 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002736 frameFences.presentFence = presentFence;
2737
2738 EXPECT_CALL(*mRenderSurface, flip());
2739 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2740 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2741
2742 // Each released layer should be given the presentFence.
2743 EXPECT_CALL(*releasedLayer1,
2744 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2745 EXPECT_CALL(*releasedLayer2,
2746 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2747 EXPECT_CALL(*releasedLayer3,
2748 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2749
2750 mOutput.postFramebuffer();
2751
2752 // After the call the list of released layers should have been cleared.
2753 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2754}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002755
2756/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002757 * Output::composeSurfaces()
2758 */
2759
2760struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002761 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002762
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002763 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002764 // Sets up the helper functions called by the function under test to use
2765 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002766 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002767 MOCK_METHOD3(generateClientCompositionRequests,
2768 std::vector<renderengine::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002769 MOCK_METHOD2(appendRegionFlashRequests,
2770 void(const Region&, std::vector<renderengine::LayerSettings>&));
2771 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2772 };
2773
2774 OutputComposeSurfacesTest() {
2775 mOutput.setDisplayColorProfileForTest(
2776 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2777 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2778
Lloyd Pique6818fa52019-12-03 12:32:13 -08002779 mOutput.mState.frame = kDefaultOutputFrame;
2780 mOutput.mState.viewport = kDefaultOutputViewport;
2781 mOutput.mState.scissor = kDefaultOutputScissor;
2782 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
2783 mOutput.mState.orientation = kDefaultOutputOrientation;
2784 mOutput.mState.dataspace = kDefaultOutputDataspace;
2785 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2786 mOutput.mState.isSecure = false;
2787 mOutput.mState.needsFiltering = false;
2788 mOutput.mState.usesClientComposition = true;
2789 mOutput.mState.usesDeviceComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002790
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002791 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002792 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002793 EXPECT_CALL(mCompositionEngine, getTimeStats())
2794 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002795 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2796 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002797 }
2798
Lloyd Pique6818fa52019-12-03 12:32:13 -08002799 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2800 auto execute() {
2801 getInstance()->mReadyFence = getInstance()->mOutput.composeSurfaces(kDebugRegion);
2802 return nextState<FenceCheckState>();
2803 }
2804 };
2805
2806 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2807 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2808
2809 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2810 };
2811
2812 // Call this member function to start using the mini-DSL defined above.
2813 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2814
2815 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
2816 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2817 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2818 static constexpr float kDefaultMaxLuminance = 0.9f;
2819 static constexpr float kDefaultAvgLuminance = 0.7f;
2820 static constexpr float kDefaultMinLuminance = 0.1f;
2821
2822 static const Rect kDefaultOutputFrame;
2823 static const Rect kDefaultOutputViewport;
2824 static const Rect kDefaultOutputScissor;
2825 static const mat4 kDefaultColorTransformMat;
2826
2827 static const Region kDebugRegion;
2828 static const HdrCapabilities kHdrCapabilities;
2829
Lloyd Pique56eba802019-08-28 15:45:25 -07002830 StrictMock<mock::CompositionEngine> mCompositionEngine;
2831 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002832 // TODO: make this is a proper mock.
2833 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002834 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2835 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002836 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002837 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002838
2839 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002840};
2841
2842const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2843const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
2844const Rect OutputComposeSurfacesTest::kDefaultOutputScissor{1009, 1010, 1011, 1012};
2845const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002846const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2847const HdrCapabilities OutputComposeSurfacesTest::
2848 kHdrCapabilities{{},
2849 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2850 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2851 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002852
Lloyd Piquea76ce462020-01-14 13:06:37 -08002853TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002854 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002855
Lloyd Piquea76ce462020-01-14 13:06:37 -08002856 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2857
Lloyd Pique6818fa52019-12-03 12:32:13 -08002858 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002859}
2860
Lloyd Pique6818fa52019-12-03 12:32:13 -08002861TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFails) {
2862 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2863 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2864 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2865 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2866 .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
2867 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2868 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002869
Lloyd Pique6818fa52019-12-03 12:32:13 -08002870 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002871
Lloyd Pique6818fa52019-12-03 12:32:13 -08002872 verify().execute().expectNoFenceWasReturned();
2873}
Lloyd Pique56eba802019-08-28 15:45:25 -07002874
Lloyd Pique6818fa52019-12-03 12:32:13 -08002875TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2876 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2877 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2878 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2879 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2880 .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
2881 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2882 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002883
Lloyd Pique6818fa52019-12-03 12:32:13 -08002884 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2885 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2886 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002887
Lloyd Pique6818fa52019-12-03 12:32:13 -08002888 verify().execute().expectAFenceWasReturned();
2889}
Lloyd Pique56eba802019-08-28 15:45:25 -07002890
Lloyd Pique6818fa52019-12-03 12:32:13 -08002891TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
2892 renderengine::LayerSettings r1;
2893 renderengine::LayerSettings r2;
2894
2895 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2896 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2897
2898 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2899 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2900 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2901 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2902 .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{r1}));
2903 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2904 .WillRepeatedly(
2905 Invoke([&](const Region&,
2906 std::vector<renderengine::LayerSettings>& clientCompositionLayers) {
2907 clientCompositionLayers.emplace_back(r2);
2908 }));
2909
2910 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2911 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAreArray({r1, r2}), _, true, _, _))
2912 .WillRepeatedly(Return(NO_ERROR));
2913
2914 verify().execute().expectAFenceWasReturned();
2915}
2916
2917struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
2918 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
2919 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2920 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2921 .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
2922 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2923 .WillRepeatedly(Return());
2924 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2925 }
2926
2927 struct MixedCompositionState
2928 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
2929 auto ifMixedCompositionIs(bool used) {
2930 getInstance()->mOutput.mState.usesDeviceComposition = used;
2931 return nextState<OutputUsesHdrState>();
2932 }
2933 };
2934
2935 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
2936 auto andIfUsesHdr(bool used) {
2937 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
2938 .WillOnce(Return(used));
2939 return nextState<SkipColorTransformState>();
2940 }
2941 };
2942
2943 struct SkipColorTransformState
2944 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
2945 auto andIfSkipColorTransform(bool skip) {
2946 // May be called zero or one times.
2947 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
2948 .WillRepeatedly(Return(skip));
2949 return nextState<ExpectDisplaySettingsState>();
2950 }
2951 };
2952
2953 struct ExpectDisplaySettingsState
2954 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
2955 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
2956 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
2957 .WillOnce(Return(NO_ERROR));
2958 return nextState<ExecuteState>();
2959 }
2960 };
2961
2962 // Call this member function to start using the mini-DSL defined above.
2963 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
2964};
2965
2966TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
2967 verify().ifMixedCompositionIs(true)
2968 .andIfUsesHdr(true)
2969 .andIfSkipColorTransform(false)
2970 .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
2971 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
2972 Region::INVALID_REGION, kDefaultOutputOrientation})
2973 .execute()
2974 .expectAFenceWasReturned();
2975}
2976
2977TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
2978 verify().ifMixedCompositionIs(true)
2979 .andIfUsesHdr(false)
2980 .andIfSkipColorTransform(false)
2981 .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
2982 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
2983 Region::INVALID_REGION, kDefaultOutputOrientation})
2984 .execute()
2985 .expectAFenceWasReturned();
2986}
2987
2988TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
2989 verify().ifMixedCompositionIs(false)
2990 .andIfUsesHdr(true)
2991 .andIfSkipColorTransform(false)
2992 .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
2993 kDefaultMaxLuminance, kDefaultOutputDataspace,
2994 kDefaultColorTransformMat, Region::INVALID_REGION,
2995 kDefaultOutputOrientation})
2996 .execute()
2997 .expectAFenceWasReturned();
2998}
2999
3000TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3001 verify().ifMixedCompositionIs(false)
3002 .andIfUsesHdr(false)
3003 .andIfSkipColorTransform(false)
3004 .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
3005 kDefaultMaxLuminance, kDefaultOutputDataspace,
3006 kDefaultColorTransformMat, Region::INVALID_REGION,
3007 kDefaultOutputOrientation})
3008 .execute()
3009 .expectAFenceWasReturned();
3010}
3011
3012TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3013 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3014 verify().ifMixedCompositionIs(false)
3015 .andIfUsesHdr(true)
3016 .andIfSkipColorTransform(true)
3017 .thenExpectDisplaySettingsUsed({kDefaultOutputScissor, kDefaultOutputScissor, mat4(),
3018 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3019 Region::INVALID_REGION, kDefaultOutputOrientation})
3020 .execute()
3021 .expectAFenceWasReturned();
3022}
3023
3024struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3025 struct Layer {
3026 Layer() {
3027 EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
3028 EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
3029 }
3030
3031 StrictMock<mock::OutputLayer> mOutputLayer;
3032 StrictMock<mock::Layer> mLayer;
3033 LayerFECompositionState mLayerFEState;
3034 };
3035
3036 OutputComposeSurfacesTest_HandlesProtectedContent() {
3037 mLayer1.mLayerFEState.hasProtectedContent = false;
3038 mLayer2.mLayerFEState.hasProtectedContent = false;
3039
3040 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3041 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3042 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3043 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3044 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3045
3046 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3047
3048 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3049
3050 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
3051 .WillRepeatedly(Return(std::vector<renderengine::LayerSettings>{}));
3052 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3053 .WillRepeatedly(Return());
3054 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3055 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3056 .WillRepeatedly(Return(NO_ERROR));
3057 }
3058
3059 Layer mLayer1;
3060 Layer mLayer2;
3061};
3062
3063TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3064 mOutput.mState.isSecure = false;
3065 mLayer2.mLayerFEState.hasProtectedContent = true;
3066 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3067
3068 mOutput.composeSurfaces(kDebugRegion);
3069}
3070
3071TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3072 mOutput.mState.isSecure = true;
3073 mLayer2.mLayerFEState.hasProtectedContent = true;
3074 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3075
3076 mOutput.composeSurfaces(kDebugRegion);
3077}
3078
3079TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3080 mOutput.mState.isSecure = true;
3081 mLayer2.mLayerFEState.hasProtectedContent = false;
3082 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3083 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3084 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3085 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3086 EXPECT_CALL(*mRenderSurface, setProtected(false));
3087
3088 mOutput.composeSurfaces(kDebugRegion);
3089}
3090
3091TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3092 mOutput.mState.isSecure = true;
3093 mLayer2.mLayerFEState.hasProtectedContent = true;
3094 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3095
3096 // For this test, we also check the call order of key functions.
3097 InSequence seq;
3098
3099 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3100 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3101 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3102 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3103 EXPECT_CALL(*mRenderSurface, setProtected(true));
3104 // Must happen after setting the protected content state.
3105 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3106 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3107
3108 mOutput.composeSurfaces(kDebugRegion);
3109}
3110
3111TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3112 mOutput.mState.isSecure = true;
3113 mLayer2.mLayerFEState.hasProtectedContent = true;
3114 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3115 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3116 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3117
3118 mOutput.composeSurfaces(kDebugRegion);
3119}
3120
3121TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3122 mOutput.mState.isSecure = true;
3123 mLayer2.mLayerFEState.hasProtectedContent = true;
3124 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3125 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3126 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3127 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3128
3129 mOutput.composeSurfaces(kDebugRegion);
3130}
3131
3132TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3133 mOutput.mState.isSecure = true;
3134 mLayer2.mLayerFEState.hasProtectedContent = true;
3135 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3136 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3137 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3138 EXPECT_CALL(*mRenderSurface, setProtected(true));
3139
3140 mOutput.composeSurfaces(kDebugRegion);
3141}
3142
3143TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3144 mOutput.mState.isSecure = true;
3145 mLayer2.mLayerFEState.hasProtectedContent = true;
3146 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3147 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3148 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3149 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3150
3151 mOutput.composeSurfaces(kDebugRegion);
3152}
3153
3154struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3155 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3156 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3157 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3158 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3159 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3160 .WillRepeatedly(Return());
3161 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3162 }
3163};
3164
3165TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3166 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3167
3168 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
3169 .WillOnce(Return(std::vector<renderengine::LayerSettings>{}));
3170
3171 // For this test, we also check the call order of key functions.
3172 InSequence seq;
3173
3174 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3175 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003176
3177 mOutput.composeSurfaces(kDebugRegion);
Lloyd Pique56eba802019-08-28 15:45:25 -07003178}
3179
3180/*
3181 * Output::generateClientCompositionRequests()
3182 */
3183
3184struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003185 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003186 // compositionengine::Output overrides
Lloyd Pique56eba802019-08-28 15:45:25 -07003187 std::vector<renderengine::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003188 bool supportsProtectedContent, Region& clearRegion,
3189 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003190 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003191 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003192 }
3193 };
3194
Lloyd Piquea4863342019-12-04 18:45:02 -08003195 struct Layer {
3196 Layer() {
3197 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3198 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3199 EXPECT_CALL(mOutputLayer, getLayer()).WillRepeatedly(ReturnRef(mLayer));
3200 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
3201 EXPECT_CALL(mLayer, getFEState()).WillRepeatedly(ReturnRef(mLayerFEState));
3202 }
3203
3204 StrictMock<mock::OutputLayer> mOutputLayer;
3205 StrictMock<mock::Layer> mLayer;
3206 StrictMock<mock::LayerFE> mLayerFE;
3207 LayerFECompositionState mLayerFEState;
3208 impl::OutputLayerCompositionState mOutputLayerState;
3209 renderengine::LayerSettings mRELayerSettings;
3210 };
3211
Lloyd Pique56eba802019-08-28 15:45:25 -07003212 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003213 mOutput.mState.needsFiltering = false;
3214
Lloyd Pique56eba802019-08-28 15:45:25 -07003215 mOutput.setDisplayColorProfileForTest(
3216 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3217 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3218 }
3219
Lloyd Pique56eba802019-08-28 15:45:25 -07003220 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3221 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003222 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003223};
3224
Lloyd Piquea4863342019-12-04 18:45:02 -08003225struct GenerateClientCompositionRequestsTest_ThreeLayers
3226 : public GenerateClientCompositionRequestsTest {
3227 GenerateClientCompositionRequestsTest_ThreeLayers() {
3228 mOutput.mState.frame = kDisplayFrame;
3229 mOutput.mState.viewport = kDisplayViewport;
3230 mOutput.mState.scissor = kDisplayScissor;
3231 mOutput.mState.transform = ui::Transform{kDisplayOrientation};
3232 mOutput.mState.orientation = kDisplayOrientation;
3233 mOutput.mState.needsFiltering = false;
3234 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003235
Lloyd Piquea4863342019-12-04 18:45:02 -08003236 for (size_t i = 0; i < mLayers.size(); i++) {
3237 mLayers[i].mOutputLayerState.clearClientTarget = false;
3238 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3239 mLayers[i].mLayerFEState.isOpaque = true;
3240 mLayers[i].mRELayerSettings.geometry.boundaries =
3241 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
3242 mLayers[i].mRELayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3243 mLayers[i].mRELayerSettings.alpha = 1.0f;
3244 mLayers[i].mRELayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003245
Lloyd Piquea4863342019-12-04 18:45:02 -08003246 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3247 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3248 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3249 .WillRepeatedly(Return(true));
3250 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3251 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003252
Lloyd Piquea4863342019-12-04 18:45:02 -08003253 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3254 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003255
Lloyd Piquea4863342019-12-04 18:45:02 -08003256 static constexpr uint32_t kDisplayOrientation = TR_IDENT;
3257 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003258
Lloyd Piquea4863342019-12-04 18:45:02 -08003259 static const Rect kDisplayFrame;
3260 static const Rect kDisplayViewport;
3261 static const Rect kDisplayScissor;
Lloyd Pique56eba802019-08-28 15:45:25 -07003262
Lloyd Piquea4863342019-12-04 18:45:02 -08003263 std::array<Layer, 3> mLayers;
3264};
Lloyd Pique56eba802019-08-28 15:45:25 -07003265
Lloyd Piquea4863342019-12-04 18:45:02 -08003266const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3267const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
3268const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayScissor(0, 0, 102, 202);
Lloyd Pique56eba802019-08-28 15:45:25 -07003269
Lloyd Piquea4863342019-12-04 18:45:02 -08003270TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3271 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3272 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3273 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003274
Lloyd Piquea4863342019-12-04 18:45:02 -08003275 Region accumClearRegion(Rect(10, 11, 12, 13));
3276 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3277 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003278 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003279 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003280}
3281
Lloyd Piquea4863342019-12-04 18:45:02 -08003282TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3283 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3284 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3285 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3286
3287 Region accumClearRegion(Rect(10, 11, 12, 13));
3288 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3289 accumClearRegion, kDisplayDataspace);
3290 EXPECT_EQ(0u, requests.size());
3291 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3292}
3293
3294TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
3295 renderengine::LayerSettings mREShadowSettings;
3296 mREShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3297
3298 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(_)).WillOnce(Return(std::nullopt));
3299 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(_))
3300 .WillOnce(Return(mLayers[1].mRELayerSettings));
3301 EXPECT_CALL(mLayers[1].mLayerFE,
3302 prepareShadowClientComposition(mLayers[1].mRELayerSettings, kDisplayViewport,
3303 kDisplayDataspace))
3304 .WillOnce(Return(std::nullopt));
3305 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
3306 .WillOnce(Return(mLayers[2].mRELayerSettings));
3307 EXPECT_CALL(mLayers[2].mLayerFE,
3308 prepareShadowClientComposition(mLayers[2].mRELayerSettings, kDisplayViewport,
3309 kDisplayDataspace))
3310 .WillOnce(Return(mREShadowSettings));
3311
3312 Region accumClearRegion(Rect(10, 11, 12, 13));
3313 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3314 accumClearRegion, kDisplayDataspace);
3315 ASSERT_EQ(3u, requests.size());
3316 EXPECT_EQ(mLayers[1].mRELayerSettings, requests[0]);
3317 EXPECT_EQ(mREShadowSettings, requests[1]);
3318 EXPECT_EQ(mLayers[2].mRELayerSettings, requests[2]);
3319
3320 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3321
3322 // Check that a timestamp was set for the layers that generated requests
3323 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3324 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3325 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3326}
3327
3328TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3329 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3330 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3331 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3332 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3333
3334 mLayers[0].mOutputLayerState.clearClientTarget = false;
3335 mLayers[1].mOutputLayerState.clearClientTarget = false;
3336 mLayers[2].mOutputLayerState.clearClientTarget = false;
3337
3338 mLayers[0].mLayerFEState.isOpaque = true;
3339 mLayers[1].mLayerFEState.isOpaque = true;
3340 mLayers[2].mLayerFEState.isOpaque = true;
3341
3342 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
3343 .WillOnce(Return(mLayers[2].mRELayerSettings));
3344 EXPECT_CALL(mLayers[2].mLayerFE, prepareShadowClientComposition(_, _, _))
3345 .WillOnce(Return(std::nullopt));
3346
3347 Region accumClearRegion(Rect(10, 11, 12, 13));
3348 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3349 accumClearRegion, kDisplayDataspace);
3350 ASSERT_EQ(1u, requests.size());
3351 EXPECT_EQ(mLayers[2].mRELayerSettings, requests[0]);
3352
3353 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3354}
3355
3356TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3357 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3358 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3359 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3360 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3361
3362 mLayers[0].mOutputLayerState.clearClientTarget = true;
3363 mLayers[1].mOutputLayerState.clearClientTarget = true;
3364 mLayers[2].mOutputLayerState.clearClientTarget = true;
3365
3366 mLayers[0].mLayerFEState.isOpaque = false;
3367 mLayers[1].mLayerFEState.isOpaque = false;
3368 mLayers[2].mLayerFEState.isOpaque = false;
3369
3370 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
3371 .WillOnce(Return(mLayers[2].mRELayerSettings));
3372 EXPECT_CALL(mLayers[2].mLayerFE, prepareShadowClientComposition(_, _, _))
3373 .WillOnce(Return(std::nullopt));
3374
3375 Region accumClearRegion(Rect(10, 11, 12, 13));
3376 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3377 accumClearRegion, kDisplayDataspace);
3378 ASSERT_EQ(1u, requests.size());
3379 EXPECT_EQ(mLayers[2].mRELayerSettings, requests[0]);
3380
3381 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3382}
3383
3384TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003385 // If client composition is performed with some layers set to use device
3386 // composition, device layers after the first layer (device or client) will
3387 // clear the frame buffer if they are opaque and if that layer has a flag
3388 // set to do so. The first layer is skipped as the frame buffer is already
3389 // expected to be clear.
3390
Lloyd Piquea4863342019-12-04 18:45:02 -08003391 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3392 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3393 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003394
Lloyd Piquea4863342019-12-04 18:45:02 -08003395 mLayers[0].mOutputLayerState.clearClientTarget = true;
3396 mLayers[1].mOutputLayerState.clearClientTarget = true;
3397 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003398
Lloyd Piquea4863342019-12-04 18:45:02 -08003399 mLayers[0].mLayerFEState.isOpaque = true;
3400 mLayers[1].mLayerFEState.isOpaque = true;
3401 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003402
Lloyd Piquea4863342019-12-04 18:45:02 -08003403 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(_))
3404 .WillOnce(Return(mLayers[1].mRELayerSettings));
3405 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
3406 .WillOnce(Return(mLayers[2].mRELayerSettings));
3407 EXPECT_CALL(mLayers[2].mLayerFE, prepareShadowClientComposition(_, _, _))
3408 .WillOnce(Return(std::nullopt));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003409
Lloyd Piquea4863342019-12-04 18:45:02 -08003410 Region accumClearRegion(Rect(10, 11, 12, 13));
3411 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3412 accumClearRegion, kDisplayDataspace);
3413 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003414
Lloyd Piquea4863342019-12-04 18:45:02 -08003415 // The second layer is expected to be rendered as alpha=0 black with no blending
3416 EXPECT_EQ(mLayers[1].mRELayerSettings.geometry.boundaries, requests[0].geometry.boundaries);
3417 EXPECT_FALSE(requests[0].source.buffer.buffer);
3418 EXPECT_EQ((half3{0.f, 0.f, 0.f}), requests[0].source.solidColor);
3419 EXPECT_EQ(half{0.f}, requests[0].alpha);
3420 EXPECT_EQ(true, requests[0].disableBlending);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003421
Lloyd Piquea4863342019-12-04 18:45:02 -08003422 EXPECT_EQ(mLayers[2].mRELayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003423
Lloyd Piquea4863342019-12-04 18:45:02 -08003424 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3425}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003426
Lloyd Piquea4863342019-12-04 18:45:02 -08003427TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3428 clippedVisibleRegionUsedToGenerateRequest) {
3429 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3430 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3431 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003432
Lloyd Piquea4863342019-12-04 18:45:02 -08003433 Region accumClearRegion(Rect(10, 11, 12, 13));
3434
3435 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3436 Region(Rect(10, 10, 20, 20)),
3437 false, /* identity transform */
3438 false, /* needs filtering */
3439 false, /* secure */
3440 false, /* supports protected content */
3441 accumClearRegion,
3442 };
3443 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3444 Region(Rect(0, 0, 30, 30)),
3445 false, /* identity transform */
3446 false, /* needs filtering */
3447 false, /* secure */
3448 false, /* supports protected content */
3449 accumClearRegion,
3450 };
3451 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3452 Region(Rect(0, 0, 40, 201)),
3453 false, /* identity transform */
3454 false, /* needs filtering */
3455 false, /* secure */
3456 false, /* supports protected content */
3457 accumClearRegion,
3458 };
3459
3460 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
3461 .WillOnce(Return(std::nullopt));
3462 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
3463 .WillOnce(Return(std::nullopt));
3464 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
3465 .WillOnce(Return(std::nullopt));
3466
3467 static_cast<void>(
3468 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3469 accumClearRegion, kDisplayDataspace));
3470}
3471
3472TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3473 perLayerNeedsFilteringUsedToGenerateRequests) {
3474 mOutput.mState.needsFiltering = false;
3475 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3476
3477 Region accumClearRegion(Rect(10, 11, 12, 13));
3478
3479 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3480 Region(kDisplayFrame),
3481 false, /* identity transform */
3482 true, /* needs filtering */
3483 false, /* secure */
3484 false, /* supports protected content */
3485 accumClearRegion,
3486 };
3487 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3488 Region(kDisplayFrame),
3489 false, /* identity transform */
3490 false, /* needs filtering */
3491 false, /* secure */
3492 false, /* supports protected content */
3493 accumClearRegion,
3494 };
3495 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3496 Region(kDisplayFrame),
3497 false, /* identity transform */
3498 false, /* needs filtering */
3499 false, /* secure */
3500 false, /* supports protected content */
3501 accumClearRegion,
3502 };
3503
3504 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
3505 .WillOnce(Return(std::nullopt));
3506 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
3507 .WillOnce(Return(std::nullopt));
3508 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
3509 .WillOnce(Return(std::nullopt));
3510
3511 static_cast<void>(
3512 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3513 accumClearRegion, kDisplayDataspace));
3514}
3515
3516TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3517 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3518 mOutput.mState.needsFiltering = true;
3519 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3520
3521 Region accumClearRegion(Rect(10, 11, 12, 13));
3522
3523 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3524 Region(kDisplayFrame),
3525 false, /* identity transform */
3526 true, /* needs filtering */
3527 false, /* secure */
3528 false, /* supports protected content */
3529 accumClearRegion,
3530 };
3531 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3532 Region(kDisplayFrame),
3533 false, /* identity transform */
3534 true, /* needs filtering */
3535 false, /* secure */
3536 false, /* supports protected content */
3537 accumClearRegion,
3538 };
3539 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3540 Region(kDisplayFrame),
3541 false, /* identity transform */
3542 true, /* needs filtering */
3543 false, /* secure */
3544 false, /* supports protected content */
3545 accumClearRegion,
3546 };
3547
3548 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
3549 .WillOnce(Return(std::nullopt));
3550 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
3551 .WillOnce(Return(std::nullopt));
3552 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
3553 .WillOnce(Return(std::nullopt));
3554
3555 static_cast<void>(
3556 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3557 accumClearRegion, kDisplayDataspace));
3558}
3559
3560TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3561 wholeOutputSecurityUsedToGenerateRequests) {
3562 mOutput.mState.isSecure = true;
3563
3564 Region accumClearRegion(Rect(10, 11, 12, 13));
3565
3566 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3567 Region(kDisplayFrame),
3568 false, /* identity transform */
3569 false, /* needs filtering */
3570 true, /* secure */
3571 false, /* supports protected content */
3572 accumClearRegion,
3573 };
3574 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3575 Region(kDisplayFrame),
3576 false, /* identity transform */
3577 false, /* needs filtering */
3578 true, /* secure */
3579 false, /* supports protected content */
3580 accumClearRegion,
3581 };
3582 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3583 Region(kDisplayFrame),
3584 false, /* identity transform */
3585 false, /* needs filtering */
3586 true, /* secure */
3587 false, /* supports protected content */
3588 accumClearRegion,
3589 };
3590
3591 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
3592 .WillOnce(Return(std::nullopt));
3593 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
3594 .WillOnce(Return(std::nullopt));
3595 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
3596 .WillOnce(Return(std::nullopt));
3597
3598 static_cast<void>(
3599 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3600 accumClearRegion, kDisplayDataspace));
3601}
3602
3603TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3604 protectedContentSupportUsedToGenerateRequests) {
3605 Region accumClearRegion(Rect(10, 11, 12, 13));
3606
3607 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3608 Region(kDisplayFrame),
3609 false, /* identity transform */
3610 false, /* needs filtering */
3611 false, /* secure */
3612 true, /* supports protected content */
3613 accumClearRegion,
3614 };
3615 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3616 Region(kDisplayFrame),
3617 false, /* identity transform */
3618 false, /* needs filtering */
3619 false, /* secure */
3620 true, /* supports protected content */
3621 accumClearRegion,
3622 };
3623 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3624 Region(kDisplayFrame),
3625 false, /* identity transform */
3626 false, /* needs filtering */
3627 false, /* secure */
3628 true, /* supports protected content */
3629 accumClearRegion,
3630 };
3631
3632 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientComposition(Eq(ByRef(layer0TargetSettings))))
3633 .WillOnce(Return(std::nullopt));
3634 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientComposition(Eq(ByRef(layer1TargetSettings))))
3635 .WillOnce(Return(std::nullopt));
3636 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(Eq(ByRef(layer2TargetSettings))))
3637 .WillOnce(Return(std::nullopt));
3638
3639 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3640 accumClearRegion,
3641 kDisplayDataspace));
3642}
3643
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003644TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
3645 // Layer requesting blur, or below, should request client composition.
3646 EXPECT_CALL(*mOutputLayer1, updateCompositionState(false, true));
3647 EXPECT_CALL(*mOutputLayer1, writeStateToHWC(false));
3648 EXPECT_CALL(*mOutputLayer2, updateCompositionState(false, true));
3649 EXPECT_CALL(*mOutputLayer2, writeStateToHWC(false));
3650 EXPECT_CALL(*mOutputLayer3, updateCompositionState(false, false));
3651 EXPECT_CALL(*mOutputLayer3, writeStateToHWC(false));
3652
3653 mLayer2FEState.backgroundBlurRadius = 10;
3654
3655 injectLayer(std::move(mOutputLayer1));
3656 injectLayer(std::move(mOutputLayer2));
3657 injectLayer(std::move(mOutputLayer3));
3658
3659 mOutput->editState().isEnabled = true;
3660
3661 CompositionRefreshArgs args;
3662 args.updatingGeometryThisFrame = false;
3663 args.devOptForceClientComposition = false;
3664 mOutput->updateAndWriteCompositionState(args);
3665}
3666
Lloyd Piquea4863342019-12-04 18:45:02 -08003667TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3668 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3669 // one layer on the left covering the left side of the output, and one layer
3670 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003671
3672 const Rect kPortraitFrame(0, 0, 1000, 2000);
3673 const Rect kPortraitViewport(0, 0, 2000, 1000);
3674 const Rect kPortraitScissor(0, 0, 1000, 2000);
3675 const uint32_t kPortraitOrientation = TR_ROT_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003676 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003677
Lloyd Piquea4863342019-12-04 18:45:02 -08003678 mOutput.mState.frame = kPortraitFrame;
3679 mOutput.mState.viewport = kPortraitViewport;
3680 mOutput.mState.scissor = kPortraitScissor;
3681 mOutput.mState.transform = ui::Transform{kPortraitOrientation};
3682 mOutput.mState.orientation = kPortraitOrientation;
3683 mOutput.mState.needsFiltering = false;
3684 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003685
Lloyd Piquea4863342019-12-04 18:45:02 -08003686 Layer leftLayer;
3687 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003688
Lloyd Piquea4863342019-12-04 18:45:02 -08003689 leftLayer.mOutputLayerState.clearClientTarget = false;
3690 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3691 leftLayer.mLayerFEState.isOpaque = true;
3692 leftLayer.mRELayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003693
Lloyd Piquea4863342019-12-04 18:45:02 -08003694 rightLayer.mOutputLayerState.clearClientTarget = false;
3695 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3696 rightLayer.mLayerFEState.isOpaque = true;
3697 rightLayer.mRELayerSettings.source.solidColor = {0.f, 1.f, 0.f};
3698
3699 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3700 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3701 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3702 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3703 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3704
3705 Region accumClearRegion(Rect(10, 11, 12, 13));
3706
3707 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3708 Region(Rect(0, 0, 1000, 1000)),
3709 false, /* identity transform */
3710 false, /* needs filtering */
3711 true, /* secure */
3712 true, /* supports protected content */
3713 accumClearRegion,
3714 };
3715
3716 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3717 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3718 EXPECT_CALL(leftLayer.mLayerFE, prepareClientComposition(Eq(ByRef(leftLayerSettings))))
3719 .WillOnce(Return(leftLayer.mRELayerSettings));
3720 EXPECT_CALL(leftLayer.mLayerFE,
3721 prepareShadowClientComposition(leftLayer.mRELayerSettings, kPortraitViewport,
3722 kOutputDataspace))
3723 .WillOnce(Return(std::nullopt));
3724
3725 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
3726 Region(Rect(1000, 0, 2000, 1000)),
3727 false, /* identity transform */
3728 false, /* needs filtering */
3729 true, /* secure */
3730 true, /* supports protected content */
3731 accumClearRegion,
3732 };
3733
3734 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3735 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3736 EXPECT_CALL(rightLayer.mLayerFE, prepareClientComposition(Eq(ByRef(rightLayerSettings))))
3737 .WillOnce(Return(rightLayer.mRELayerSettings));
3738 EXPECT_CALL(rightLayer.mLayerFE,
3739 prepareShadowClientComposition(rightLayer.mRELayerSettings, kPortraitViewport,
3740 kOutputDataspace))
3741 .WillOnce(Return(std::nullopt));
3742
3743 constexpr bool supportsProtectedContent = true;
3744 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
3745 accumClearRegion, kOutputDataspace);
3746 ASSERT_EQ(2u, requests.size());
3747 EXPECT_EQ(leftLayer.mRELayerSettings, requests[0]);
3748 EXPECT_EQ(rightLayer.mRELayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003749}
3750
Vishnu Naira483b4a2019-12-12 15:07:52 -08003751TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3752 shadowRegionOnlyVisibleSkipsContentComposition) {
3753 const Rect kContentWithShadow(40, 40, 70, 90);
3754 const Rect kContent(50, 50, 60, 80);
3755 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
3756 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
3757
3758 renderengine::LayerSettings mREShadowSettings;
3759 mREShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3760
3761 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
3762 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
3763
3764 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3765 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3766 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
3767 .WillOnce(Return(mLayers[2].mRELayerSettings));
3768 EXPECT_CALL(mLayers[2].mLayerFE,
3769 prepareShadowClientComposition(mLayers[2].mRELayerSettings, kDisplayViewport,
3770 kDisplayDataspace))
3771 .WillOnce(Return(mREShadowSettings));
3772
3773 Region accumClearRegion(Rect(10, 11, 12, 13));
3774 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3775 accumClearRegion, kDisplayDataspace);
3776 ASSERT_EQ(1u, requests.size());
3777
3778 EXPECT_EQ(mREShadowSettings, requests[0]);
3779}
3780
3781TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3782 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
3783 const Rect kContentWithShadow(40, 40, 70, 90);
3784 const Rect kContent(50, 50, 60, 80);
3785 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
3786 const Region kPartialContentWithPartialShadowRegion =
3787 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
3788
3789 renderengine::LayerSettings mREShadowSettings;
3790 mREShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3791
3792 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
3793 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
3794
3795 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3796 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3797 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientComposition(_))
3798 .WillOnce(Return(mLayers[2].mRELayerSettings));
3799 EXPECT_CALL(mLayers[2].mLayerFE,
3800 prepareShadowClientComposition(mLayers[2].mRELayerSettings, kDisplayViewport,
3801 kDisplayDataspace))
3802 .WillOnce(Return(mREShadowSettings));
3803
3804 Region accumClearRegion(Rect(10, 11, 12, 13));
3805 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3806 accumClearRegion, kDisplayDataspace);
3807 ASSERT_EQ(2u, requests.size());
3808
3809 EXPECT_EQ(mREShadowSettings, requests[0]);
3810 EXPECT_EQ(mLayers[2].mRELayerSettings, requests[1]);
3811}
3812
Lloyd Pique32cbe282018-10-19 13:09:22 -07003813} // namespace
3814} // namespace android::compositionengine
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08003815
3816// TODO(b/129481165): remove the #pragma below and fix conversion issues
3817#pragma clang diagnostic pop // ignored "-Wconversion"