blob: 6ba06a632cf003557db4bea9ce88ab7aea8c3c8e [file] [log] [blame]
Lloyd Pique32cbe282018-10-19 13:09:22 -07001/*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cmath>
18
Lloyd Pique17ca7422019-11-14 14:24:10 -080019#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070020#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070021#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080022#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070023#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070024#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070025#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080026#include <compositionengine/mock/LayerFE.h>
27#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070028#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070030#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070031#include <ui/Rect.h>
32#include <ui/Region.h>
33
Lloyd Pique17ca7422019-11-14 14:24:10 -080034#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080035#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070036#include "RegionMatcher.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037
38namespace android::compositionengine {
39namespace {
40
Lloyd Pique56eba802019-08-28 15:45:25 -070041using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080042using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080043using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080044using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080045using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080046using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080047using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080048using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080049using testing::Invoke;
50using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080051using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080052using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080053using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080054using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070055using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070056using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080057using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070058using testing::StrictMock;
59
Lloyd Pique56eba802019-08-28 15:45:25 -070060constexpr auto TR_IDENT = 0u;
61constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080062constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070063
Lloyd Pique3eb1b212019-03-07 21:15:40 -080064const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080065const mat4 kNonIdentityHalf = mat4() * 0.5f;
66const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080067
Lloyd Pique17ca7422019-11-14 14:24:10 -080068constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
69 static_cast<OutputColorSetting>(0x100);
70
Lloyd Piquefaa3f192019-11-14 14:05:09 -080071struct OutputPartialMockBase : public impl::Output {
72 // compositionengine::Output overrides
73 const OutputCompositionState& getState() const override { return mState; }
74 OutputCompositionState& editState() override { return mState; }
75
76 // Use mocks for all the remaining virtual functions
77 // not implemented by the base implementation class.
78 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
79 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080080 MOCK_METHOD2(ensureOutputLayer,
81 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080082 MOCK_METHOD0(finalizePendingOutputLayers, void());
83 MOCK_METHOD0(clearOutputLayers, void());
84 MOCK_CONST_METHOD1(dumpState, void(std::string&));
85 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080086 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080087 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
88
89 impl::OutputCompositionState mState;
90};
91
Lloyd Piquede196652020-01-22 17:29:58 -080092struct InjectedLayer {
93 InjectedLayer() {
94 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
95 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
96 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
97
98 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
99 }
100
101 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
102 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
103 LayerFECompositionState layerFEState;
104 impl::OutputLayerCompositionState outputLayerState;
105};
106
107struct NonInjectedLayer {
108 NonInjectedLayer() {
109 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
110 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
111 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
112
113 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
114 }
115
116 mock::OutputLayer outputLayer;
117 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
118 LayerFECompositionState layerFEState;
119 impl::OutputLayerCompositionState outputLayerState;
120};
121
Lloyd Pique66d68602019-02-13 14:23:31 -0800122struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700123 class Output : public impl::Output {
124 public:
125 using impl::Output::injectOutputLayerForTest;
126 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
127 };
128
129 static std::shared_ptr<Output> createOutput(
130 const compositionengine::CompositionEngine& compositionEngine) {
131 return impl::createOutputTemplated<Output>(compositionEngine);
132 }
133
Lloyd Pique31cb2942018-10-19 17:23:03 -0700134 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700135 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700136 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700137 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800138
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700139 mOutput->editState().bounds = kDefaultDisplaySize;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700140 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700141
Lloyd Piquede196652020-01-22 17:29:58 -0800142 void injectOutputLayer(InjectedLayer& layer) {
143 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
144 }
145
146 void injectNullOutputLayer() {
147 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
148 }
149
Lloyd Piqueef958122019-02-05 18:00:12 -0800150 static const Rect kDefaultDisplaySize;
151
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152 StrictMock<mock::CompositionEngine> mCompositionEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700153 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700154 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700155 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700156};
157
Lloyd Piqueef958122019-02-05 18:00:12 -0800158const Rect OutputTest::kDefaultDisplaySize{100, 200};
159
Lloyd Pique17ca7422019-11-14 14:24:10 -0800160using ColorProfile = compositionengine::Output::ColorProfile;
161
162void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
163 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
164 toString(profile.mode).c_str(), profile.mode,
165 toString(profile.dataspace).c_str(), profile.dataspace,
166 toString(profile.renderIntent).c_str(), profile.renderIntent,
167 toString(profile.colorSpaceAgnosticDataspace).c_str(),
168 profile.colorSpaceAgnosticDataspace);
169}
170
171// Checks for a ColorProfile match
172MATCHER_P(ColorProfileEq, expected, "") {
173 std::string buf;
174 buf.append("ColorProfiles are not equal\n");
175 dumpColorProfile(expected, buf, "expected value");
176 dumpColorProfile(arg, buf, "actual value");
177 *result_listener << buf;
178
179 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
180 (expected.renderIntent == arg.renderIntent) &&
181 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
182}
183
Lloyd Pique66d68602019-02-13 14:23:31 -0800184/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700185 * Basic construction
186 */
187
Lloyd Pique31cb2942018-10-19 17:23:03 -0700188TEST_F(OutputTest, canInstantiateOutput) {
189 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700190 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700191 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
192
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700193 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700194
195 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700196 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700197
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700198 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
199
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700200 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700201}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700202
Lloyd Pique66d68602019-02-13 14:23:31 -0800203/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700204 * Output::setCompositionEnabled()
205 */
206
207TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700209
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700210 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_TRUE(mOutput->getState().isEnabled);
213 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214}
215
216TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700217 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700218
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700219 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700220
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700221 EXPECT_TRUE(mOutput->getState().isEnabled);
222 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223}
224
225TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 EXPECT_FALSE(mOutput->getState().isEnabled);
231 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232}
233
Lloyd Pique66d68602019-02-13 14:23:31 -0800234/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235 * Output::setProjection()
236 */
237
238TEST_F(OutputTest, setProjectionTriviallyWorks) {
239 const ui::Transform transform{ui::Transform::ROT_180};
240 const int32_t orientation = 123;
241 const Rect frame{1, 2, 3, 4};
242 const Rect viewport{5, 6, 7, 8};
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800243 const Rect destinationClip{13, 14, 15, 16};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244 const bool needsFiltering = true;
245
Marin Shalamanov06ca1632020-07-28 12:32:01 +0200246 mOutput->setProjection(transform, orientation, frame, viewport, destinationClip,
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800247 needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248
Lloyd Piqueea629282019-12-03 15:57:10 -0800249 EXPECT_THAT(mOutput->getState().transform, transform);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700250 EXPECT_EQ(orientation, mOutput->getState().orientation);
251 EXPECT_EQ(frame, mOutput->getState().frame);
252 EXPECT_EQ(viewport, mOutput->getState().viewport);
Lloyd Piquee8fe4742020-01-21 15:26:18 -0800253 EXPECT_EQ(destinationClip, mOutput->getState().destinationClip);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700254 EXPECT_EQ(needsFiltering, mOutput->getState().needsFiltering);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700255}
256
Lloyd Pique66d68602019-02-13 14:23:31 -0800257/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700258 * Output::setBounds()
259 */
260
261TEST_F(OutputTest, setBoundsSetsSizeAndDirtiesEntireOutput) {
Lloyd Piqueef958122019-02-05 18:00:12 -0800262 const ui::Size displaySize{200, 400};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700263
264 EXPECT_CALL(*mRenderSurface, setDisplaySize(displaySize)).Times(1);
265 EXPECT_CALL(*mRenderSurface, getSize()).WillOnce(ReturnRef(displaySize));
266
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700267 mOutput->setBounds(displaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700268
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700269 EXPECT_EQ(Rect(displaySize), mOutput->getState().bounds);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700270
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700271 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(Rect(displaySize))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700272}
273
Lloyd Pique66d68602019-02-13 14:23:31 -0800274/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700275 * Output::setLayerStackFilter()
276 */
277
278TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700279 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700280 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700281
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700282 EXPECT_TRUE(mOutput->getState().layerStackInternal);
283 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700284
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700285 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700286}
287
Lloyd Pique66d68602019-02-13 14:23:31 -0800288/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700289 * Output::setColorTransform
290 */
291
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800292TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700293 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700294
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800295 // If no colorTransformMatrix is set the update should be skipped.
296 CompositionRefreshArgs refreshArgs;
297 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700298
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700299 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700300
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800301 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700302 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800303
304 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700305 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800306}
Lloyd Piqueef958122019-02-05 18:00:12 -0800307
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800308TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700309 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700310
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800311 // Attempting to set the same colorTransformMatrix that is already set should
312 // also skip the update.
313 CompositionRefreshArgs refreshArgs;
314 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700315
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700316 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700317
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800318 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700319 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800320
321 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700322 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800323}
324
325TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700326 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800327
328 // Setting a different colorTransformMatrix should perform the update.
329 CompositionRefreshArgs refreshArgs;
330 refreshArgs.colorTransformMatrix = kIdentity;
331
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700332 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800333
334 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700335 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800336
337 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700338 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800339}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700340
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800341TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700342 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700343
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800344 // Setting a different colorTransformMatrix should perform the update.
345 CompositionRefreshArgs refreshArgs;
346 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700347
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700348 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800349
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800350 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700351 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800352
353 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700354 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800355}
356
357TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700358 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800359
360 // Setting a different colorTransformMatrix should perform the update.
361 CompositionRefreshArgs refreshArgs;
362 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
363
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700364 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800365
366 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700367 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800368
369 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700370 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700371}
372
Lloyd Pique66d68602019-02-13 14:23:31 -0800373/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800374 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375 */
376
Lloyd Pique17ca7422019-11-14 14:24:10 -0800377using OutputSetColorProfileTest = OutputTest;
378
379TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800380 using ColorProfile = Output::ColorProfile;
381
Lloyd Piquef5275482019-01-29 18:42:42 -0800382 EXPECT_CALL(*mDisplayColorProfile,
383 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
384 ui::Dataspace::UNKNOWN))
385 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800386 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700387
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700388 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
389 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
390 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700391
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700392 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
393 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
394 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
395 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800396
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700397 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800398}
399
Lloyd Pique17ca7422019-11-14 14:24:10 -0800400TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800401 using ColorProfile = Output::ColorProfile;
402
Lloyd Piquef5275482019-01-29 18:42:42 -0800403 EXPECT_CALL(*mDisplayColorProfile,
404 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
405 ui::Dataspace::UNKNOWN))
406 .WillOnce(Return(ui::Dataspace::UNKNOWN));
407
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700408 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
409 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
410 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
411 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800412
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700413 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
414 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
415 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800416
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700417 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700418}
419
Lloyd Pique66d68602019-02-13 14:23:31 -0800420/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700421 * Output::setRenderSurface()
422 */
423
424TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
425 const ui::Size newDisplaySize{640, 480};
426
427 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
428 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
429
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700430 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700431
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700432 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700433}
434
Lloyd Pique66d68602019-02-13 14:23:31 -0800435/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000436 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700437 */
438
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000439TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
440 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 mOutput->editState().viewport = viewport;
442 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700443
444 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700445 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000447 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448 }
449}
450
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000451TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
452 const Rect viewport{100, 200};
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 mOutput->editState().viewport = viewport;
454 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700455
456 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700458
459 // The dirtyRegion should be clipped to the display bounds.
460 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
461 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700462}
463
Lloyd Pique66d68602019-02-13 14:23:31 -0800464/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800465 * Output::belongsInOutput()
466 */
467
468TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
469 const uint32_t layerStack1 = 123u;
470 const uint32_t layerStack2 = 456u;
471
472 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800474
Lloyd Piquec6687342019-03-07 21:34:57 -0800475 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
477 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800478
Lloyd Piqueef36b002019-01-23 17:52:04 -0800479 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
481 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
482 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
483 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800484
485 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800487
488 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700489 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
490 EXPECT_FALSE(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
Lloyd Piquede196652020-01-22 17:29:58 -0800495TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
496 NonInjectedLayer layer;
497 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800498
Lloyd Piquede196652020-01-22 17:29:58 -0800499 // If the layer has no composition state, it does not belong to any output.
500 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
501 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
502}
503
504TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
505 NonInjectedLayer layer;
506 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800507
508 const uint32_t layerStack1 = 123u;
509 const uint32_t layerStack2 = 456u;
510
511 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700512 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800513
Lloyd Pique66c20c42019-03-07 21:44:02 -0800514 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800515 layer.layerFEState.layerStackId = std::nullopt;
516 layer.layerFEState.internalOnly = false;
517 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800518
Lloyd Piquede196652020-01-22 17:29:58 -0800519 layer.layerFEState.layerStackId = std::nullopt;
520 layer.layerFEState.internalOnly = true;
521 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800522
523 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800524 layer.layerFEState.layerStackId = layerStack1;
525 layer.layerFEState.internalOnly = false;
526 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800527
Lloyd Piquede196652020-01-22 17:29:58 -0800528 layer.layerFEState.layerStackId = layerStack1;
529 layer.layerFEState.internalOnly = true;
530 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800531
Lloyd Piquede196652020-01-22 17:29:58 -0800532 layer.layerFEState.layerStackId = layerStack2;
533 layer.layerFEState.internalOnly = true;
534 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800535
Lloyd Piquede196652020-01-22 17:29:58 -0800536 layer.layerFEState.layerStackId = layerStack2;
537 layer.layerFEState.internalOnly = false;
538 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800539
540 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700541 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800542
Lloyd Pique66c20c42019-03-07 21:44:02 -0800543 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800544 layer.layerFEState.layerStackId = layerStack1;
545 layer.layerFEState.internalOnly = false;
546 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800547
Lloyd Piquede196652020-01-22 17:29:58 -0800548 layer.layerFEState.layerStackId = layerStack1;
549 layer.layerFEState.internalOnly = true;
550 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800551
Lloyd Piquede196652020-01-22 17:29:58 -0800552 layer.layerFEState.layerStackId = layerStack2;
553 layer.layerFEState.internalOnly = true;
554 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800555
Lloyd Piquede196652020-01-22 17:29:58 -0800556 layer.layerFEState.layerStackId = layerStack2;
557 layer.layerFEState.internalOnly = false;
558 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800559}
560
Lloyd Pique66d68602019-02-13 14:23:31 -0800561/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800562 * Output::getOutputLayerForLayer()
563 */
564
565TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800566 InjectedLayer layer1;
567 InjectedLayer layer2;
568 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800569
Lloyd Piquede196652020-01-22 17:29:58 -0800570 injectOutputLayer(layer1);
571 injectNullOutputLayer();
572 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800573
574 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800575 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
576 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800577
578 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800579 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
580 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
581 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800582
583 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800584 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
585 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
586 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800587}
588
Lloyd Pique66d68602019-02-13 14:23:31 -0800589/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800590 * Output::setReleasedLayers()
591 */
592
593using OutputSetReleasedLayersTest = OutputTest;
594
595TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
596 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
597 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
598 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
599
600 Output::ReleasedLayers layers;
601 layers.push_back(layer1FE);
602 layers.push_back(layer2FE);
603 layers.push_back(layer3FE);
604
605 mOutput->setReleasedLayers(std::move(layers));
606
607 const auto& setLayers = mOutput->getReleasedLayersForTest();
608 ASSERT_EQ(3u, setLayers.size());
609 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
610 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
611 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
612}
613
614/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800615 * Output::updateLayerStateFromFE()
616 */
617
Lloyd Piquede196652020-01-22 17:29:58 -0800618using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800619
620TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
621 CompositionRefreshArgs refreshArgs;
622
623 mOutput->updateLayerStateFromFE(refreshArgs);
624}
625
Lloyd Piquede196652020-01-22 17:29:58 -0800626TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
627 InjectedLayer layer1;
628 InjectedLayer layer2;
629 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800630
Lloyd Piquede196652020-01-22 17:29:58 -0800631 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
632 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
633 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
634
635 injectOutputLayer(layer1);
636 injectOutputLayer(layer2);
637 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800638
639 CompositionRefreshArgs refreshArgs;
640 refreshArgs.updatingGeometryThisFrame = false;
641
642 mOutput->updateLayerStateFromFE(refreshArgs);
643}
644
Lloyd Piquede196652020-01-22 17:29:58 -0800645TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
646 InjectedLayer layer1;
647 InjectedLayer layer2;
648 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800649
Lloyd Piquede196652020-01-22 17:29:58 -0800650 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
651 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
652 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
653
654 injectOutputLayer(layer1);
655 injectOutputLayer(layer2);
656 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800657
658 CompositionRefreshArgs refreshArgs;
659 refreshArgs.updatingGeometryThisFrame = true;
660
661 mOutput->updateLayerStateFromFE(refreshArgs);
662}
663
664/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800665 * Output::updateAndWriteCompositionState()
666 */
667
Lloyd Piquede196652020-01-22 17:29:58 -0800668using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800669
670TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
671 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800672
673 CompositionRefreshArgs args;
674 mOutput->updateAndWriteCompositionState(args);
675}
676
Lloyd Piqueef63b612019-11-14 13:19:56 -0800677TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800678 InjectedLayer layer1;
679 InjectedLayer layer2;
680 InjectedLayer layer3;
681
Lloyd Piqueef63b612019-11-14 13:19:56 -0800682 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800683
Lloyd Piquede196652020-01-22 17:29:58 -0800684 injectOutputLayer(layer1);
685 injectOutputLayer(layer2);
686 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800687
688 CompositionRefreshArgs args;
689 mOutput->updateAndWriteCompositionState(args);
690}
691
692TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800693 InjectedLayer layer1;
694 InjectedLayer layer2;
695 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800696
Snild Dolkow9e217d62020-04-22 15:53:42 +0200697 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800698 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200699 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800700 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200701 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800702 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
703
704 injectOutputLayer(layer1);
705 injectOutputLayer(layer2);
706 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800707
708 mOutput->editState().isEnabled = true;
709
710 CompositionRefreshArgs args;
711 args.updatingGeometryThisFrame = false;
712 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200713 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800714 mOutput->updateAndWriteCompositionState(args);
715}
716
717TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800718 InjectedLayer layer1;
719 InjectedLayer layer2;
720 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800721
Snild Dolkow9e217d62020-04-22 15:53:42 +0200722 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800723 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200724 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800725 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200726 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800727 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
728
729 injectOutputLayer(layer1);
730 injectOutputLayer(layer2);
731 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800732
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) {
Lloyd Piquede196652020-01-22 17:29:58 -0800742 InjectedLayer layer1;
743 InjectedLayer layer2;
744 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800745
Snild Dolkow9e217d62020-04-22 15:53:42 +0200746 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800747 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200748 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800749 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200750 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800751 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
752
753 injectOutputLayer(layer1);
754 injectOutputLayer(layer2);
755 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800756
757 mOutput->editState().isEnabled = true;
758
759 CompositionRefreshArgs args;
760 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800761 args.devOptForceClientComposition = true;
762 mOutput->updateAndWriteCompositionState(args);
763}
764
765/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800766 * Output::prepareFrame()
767 */
768
769struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800770 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800771 // Sets up the helper functions called by the function under test to use
772 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800773 MOCK_METHOD0(chooseCompositionStrategy, void());
774 };
775
776 OutputPrepareFrameTest() {
777 mOutput.setDisplayColorProfileForTest(
778 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
779 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
780 }
781
782 StrictMock<mock::CompositionEngine> mCompositionEngine;
783 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
784 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700785 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800786};
787
788TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
789 mOutput.editState().isEnabled = false;
790
791 mOutput.prepareFrame();
792}
793
794TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
795 mOutput.editState().isEnabled = true;
796 mOutput.editState().usesClientComposition = false;
797 mOutput.editState().usesDeviceComposition = true;
798
799 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
800 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
801
802 mOutput.prepareFrame();
803}
804
805// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
806// base chooseCompositionStrategy() is invoked.
807TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700808 mOutput->editState().isEnabled = true;
809 mOutput->editState().usesClientComposition = false;
810 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800811
812 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
813
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700814 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800815
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700816 EXPECT_TRUE(mOutput->getState().usesClientComposition);
817 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800818}
819
Lloyd Pique56eba802019-08-28 15:45:25 -0700820/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800821 * Output::prepare()
822 */
823
824struct OutputPrepareTest : public testing::Test {
825 struct OutputPartialMock : public OutputPartialMockBase {
826 // Sets up the helper functions called by the function under test to use
827 // mock implementations.
828 MOCK_METHOD2(rebuildLayerStacks,
829 void(const compositionengine::CompositionRefreshArgs&,
830 compositionengine::LayerFESet&));
831 };
832
833 StrictMock<OutputPartialMock> mOutput;
834 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800835 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800836};
837
838TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
839 InSequence seq;
840 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
841
842 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
843}
844
845/*
846 * Output::rebuildLayerStacks()
847 */
848
849struct OutputRebuildLayerStacksTest : public testing::Test {
850 struct OutputPartialMock : public OutputPartialMockBase {
851 // Sets up the helper functions called by the function under test to use
852 // mock implementations.
853 MOCK_METHOD2(collectVisibleLayers,
854 void(const compositionengine::CompositionRefreshArgs&,
855 compositionengine::Output::CoverageState&));
856 };
857
858 OutputRebuildLayerStacksTest() {
859 mOutput.mState.isEnabled = true;
860 mOutput.mState.transform = kIdentityTransform;
861 mOutput.mState.bounds = kOutputBounds;
862
863 mRefreshArgs.updatingOutputGeometryThisFrame = true;
864
865 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
866
867 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
868 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
869 }
870
871 void setTestCoverageValues(const CompositionRefreshArgs&,
872 compositionengine::Output::CoverageState& state) {
873 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
874 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
875 state.dirtyRegion = mCoverageDirtyRegionToSet;
876 }
877
878 static const ui::Transform kIdentityTransform;
879 static const ui::Transform kRotate90Transform;
880 static const Rect kOutputBounds;
881
882 StrictMock<OutputPartialMock> mOutput;
883 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800884 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800885 Region mCoverageAboveCoveredLayersToSet;
886 Region mCoverageAboveOpaqueLayersToSet;
887 Region mCoverageDirtyRegionToSet;
888};
889
890const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
891const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
892const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
893
894TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
895 mOutput.mState.isEnabled = false;
896
897 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
898}
899
900TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
901 mRefreshArgs.updatingOutputGeometryThisFrame = false;
902
903 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
904}
905
906TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
907 mOutput.mState.transform = kIdentityTransform;
908
909 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
910
911 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
912
913 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
914}
915
916TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
917 mOutput.mState.transform = kIdentityTransform;
918
919 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
920
921 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
922
923 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
924}
925
926TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
927 mOutput.mState.transform = kRotate90Transform;
928
929 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
930
931 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
932
933 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
934}
935
936TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
937 mOutput.mState.transform = kRotate90Transform;
938
939 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
940
941 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
942
943 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
944}
945
946TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
947 mOutput.mState.transform = kIdentityTransform;
948 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
949
950 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
951
952 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
953
954 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
955}
956
957TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
958 mOutput.mState.transform = kRotate90Transform;
959 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
960
961 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
962
963 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
964
965 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
966}
967
968/*
969 * Output::collectVisibleLayers()
970 */
971
Lloyd Pique1ef93222019-11-21 16:41:53 -0800972struct OutputCollectVisibleLayersTest : public testing::Test {
973 struct OutputPartialMock : public OutputPartialMockBase {
974 // Sets up the helper functions called by the function under test to use
975 // mock implementations.
976 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -0800977 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -0800978 compositionengine::Output::CoverageState&));
979 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
980 MOCK_METHOD0(finalizePendingOutputLayers, void());
981 };
982
983 struct Layer {
984 Layer() {
985 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
986 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
987 }
988
989 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -0800990 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -0800991 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -0800992 };
993
994 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -0800995 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -0800996 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
997 .WillRepeatedly(Return(&mLayer1.outputLayer));
998 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
999 .WillRepeatedly(Return(&mLayer2.outputLayer));
1000 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1001 .WillRepeatedly(Return(&mLayer3.outputLayer));
1002
Lloyd Piquede196652020-01-22 17:29:58 -08001003 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1004 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1005 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001006 }
1007
1008 StrictMock<OutputPartialMock> mOutput;
1009 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001010 LayerFESet mGeomSnapshots;
1011 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001012 Layer mLayer1;
1013 Layer mLayer2;
1014 Layer mLayer3;
1015};
1016
1017TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1018 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001019 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001020
1021 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1022 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1023
1024 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1025}
1026
1027TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1028 // Enforce a call order sequence for this test.
1029 InSequence seq;
1030
1031 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001032 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1033 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1034 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001035
1036 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1037 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1038
1039 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1040
1041 // Ensure all output layers have been assigned a simple/flattened z-order.
1042 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1043 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1044 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1045}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001046
1047/*
1048 * Output::ensureOutputLayerIfVisible()
1049 */
1050
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001051struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1052 struct OutputPartialMock : public OutputPartialMockBase {
1053 // Sets up the helper functions called by the function under test to use
1054 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001055 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001056 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001057 MOCK_METHOD2(ensureOutputLayer,
1058 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001059 };
1060
1061 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001062 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1063 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001064 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001065 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001066 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001067
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001068 mOutput.mState.bounds = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001069 mOutput.mState.viewport = Rect(0, 0, 200, 300);
1070 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1071
Lloyd Piquede196652020-01-22 17:29:58 -08001072 mLayer.layerFEState.isVisible = true;
1073 mLayer.layerFEState.isOpaque = true;
1074 mLayer.layerFEState.contentDirty = true;
1075 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1076 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1077 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001078
Lloyd Piquede196652020-01-22 17:29:58 -08001079 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1080 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001081
Lloyd Piquede196652020-01-22 17:29:58 -08001082 mGeomSnapshots.insert(mLayer.layerFE);
1083 }
1084
1085 void ensureOutputLayerIfVisible() {
1086 sp<LayerFE> layerFE(mLayer.layerFE);
1087 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001088 }
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
Lloyd Piquede196652020-01-22 17:29:58 -08001100 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001101};
1102
1103const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1104const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1105 Region(Rect(0, 0, 100, 200));
1106const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1107 Region(Rect(0, 100, 100, 200));
1108const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1109 Region(Rect(50, 0, 100, 200));
1110const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1111 Region(Rect(0, 0, 200, 100));
1112
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001113TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001114 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1115 EXPECT_CALL(*mLayer.layerFE,
1116 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001117
1118 mGeomSnapshots.clear();
1119
Lloyd Piquede196652020-01-22 17:29:58 -08001120 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001121}
1122
1123TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1124 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001125 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001126
Lloyd Piquede196652020-01-22 17:29:58 -08001127 ensureOutputLayerIfVisible();
1128}
1129
1130TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1131 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1132
1133 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001134}
1135
1136TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001137 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001138
Lloyd Piquede196652020-01-22 17:29:58 -08001139 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001140}
1141
1142TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001143 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001144
Lloyd Piquede196652020-01-22 17:29:58 -08001145 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001146}
1147
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001148TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
1149 mOutput.mState.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001150
Lloyd Piquede196652020-01-22 17:29:58 -08001151 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001152}
1153
1154TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1155 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001156 mLayer.layerFEState.isOpaque = true;
1157 mLayer.layerFEState.contentDirty = true;
1158 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001159
1160 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001161 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1162 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001163
Lloyd Piquede196652020-01-22 17:29:58 -08001164 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001165
1166 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1167 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1168 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1169
Lloyd Piquede196652020-01-22 17:29:58 -08001170 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1171 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1172 RegionEq(kFullBoundsNoRotation));
1173 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1174 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001175}
1176
1177TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1178 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001179 mLayer.layerFEState.isOpaque = true;
1180 mLayer.layerFEState.contentDirty = true;
1181 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182
Lloyd Piquede196652020-01-22 17:29:58 -08001183 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1184 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001185
Lloyd Piquede196652020-01-22 17:29:58 -08001186 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001187
1188 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1189 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1190 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1191
Lloyd Piquede196652020-01-22 17:29:58 -08001192 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1193 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1194 RegionEq(kFullBoundsNoRotation));
1195 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1196 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001197}
1198
1199TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1200 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001201 mLayer.layerFEState.isOpaque = false;
1202 mLayer.layerFEState.contentDirty = true;
1203 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001204
1205 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001206 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1207 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001208
Lloyd Piquede196652020-01-22 17:29:58 -08001209 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001210
1211 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1212 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1213 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1214
Lloyd Piquede196652020-01-22 17:29:58 -08001215 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1216 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001217 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001218 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1219 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001220}
1221
1222TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1223 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001224 mLayer.layerFEState.isOpaque = false;
1225 mLayer.layerFEState.contentDirty = true;
1226 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001227
Lloyd Piquede196652020-01-22 17:29:58 -08001228 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1229 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001230
Lloyd Piquede196652020-01-22 17:29:58 -08001231 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001232
1233 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1234 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1235 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1236
Lloyd Piquede196652020-01-22 17:29:58 -08001237 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1238 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001239 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001240 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1241 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001242}
1243
1244TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1245 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001246 mLayer.layerFEState.isOpaque = true;
1247 mLayer.layerFEState.contentDirty = false;
1248 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001249
1250 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001251 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1252 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001253
Lloyd Piquede196652020-01-22 17:29:58 -08001254 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001255
1256 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1257 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1258 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1259
Lloyd Piquede196652020-01-22 17:29:58 -08001260 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1261 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1262 RegionEq(kFullBoundsNoRotation));
1263 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1264 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265}
1266
1267TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1268 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001269 mLayer.layerFEState.isOpaque = true;
1270 mLayer.layerFEState.contentDirty = false;
1271 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272
Lloyd Piquede196652020-01-22 17:29:58 -08001273 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1274 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001275
Lloyd Piquede196652020-01-22 17:29:58 -08001276 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001277
1278 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1279 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1280 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1281
Lloyd Piquede196652020-01-22 17:29:58 -08001282 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1283 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1284 RegionEq(kFullBoundsNoRotation));
1285 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1286 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001287}
1288
1289TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1290 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001291 mLayer.layerFEState.isOpaque = true;
1292 mLayer.layerFEState.contentDirty = true;
1293 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1294 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1295 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1296 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001297
1298 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001299 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1300 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001301
Lloyd Piquede196652020-01-22 17:29:58 -08001302 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001303
1304 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1305 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1306 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1307
Lloyd Piquede196652020-01-22 17:29:58 -08001308 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1309 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1310 RegionEq(kFullBoundsNoRotation));
1311 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1312 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001313}
1314
1315TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1316 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001317 mLayer.layerFEState.isOpaque = true;
1318 mLayer.layerFEState.contentDirty = true;
1319 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1320 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1321 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1322 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323
Lloyd Piquede196652020-01-22 17:29:58 -08001324 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1325 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001326
Lloyd Piquede196652020-01-22 17:29:58 -08001327 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001328
1329 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1330 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1331 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1332
Lloyd Piquede196652020-01-22 17:29:58 -08001333 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1334 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1335 RegionEq(kFullBoundsNoRotation));
1336 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1337 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338}
1339
1340TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1341 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001342 mLayer.layerFEState.isOpaque = true;
1343 mLayer.layerFEState.contentDirty = true;
1344 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345
1346 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1347 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1348
1349 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001350 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1351 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
Lloyd Piquede196652020-01-22 17:29:58 -08001353 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354
1355 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1356 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1357 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1361 RegionEq(kFullBoundsNoRotation));
1362 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1363 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364}
1365
1366TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1367 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001368 mLayer.layerFEState.isOpaque = true;
1369 mLayer.layerFEState.contentDirty = true;
1370 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001371
1372 mOutput.mState.viewport = Rect(0, 0, 300, 200);
1373 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1374
Lloyd Piquede196652020-01-22 17:29:58 -08001375 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1376 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377
Lloyd Piquede196652020-01-22 17:29:58 -08001378 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
1380 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1381 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1383
Lloyd Piquede196652020-01-22 17:29:58 -08001384 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1386 RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1388 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001389}
1390
1391TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1392 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1393 ui::Transform arbitraryTransform;
1394 arbitraryTransform.set(1, 1, -1, 1);
1395 arbitraryTransform.set(0, 100);
1396
Lloyd Piquede196652020-01-22 17:29:58 -08001397 mLayer.layerFEState.isOpaque = true;
1398 mLayer.layerFEState.contentDirty = true;
1399 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1400 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401
1402 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001403 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1404 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001405
Lloyd Piquede196652020-01-22 17:29:58 -08001406 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407
1408 const Region kRegion = Region(Rect(0, 0, 300, 300));
1409 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1410
1411 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1412 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1413 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1414
Lloyd Piquede196652020-01-22 17:29:58 -08001415 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1416 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1417 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1418 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419}
1420
1421TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001422 mLayer.layerFEState.isOpaque = false;
1423 mLayer.layerFEState.contentDirty = true;
1424 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
1426 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1427 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1428 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1431 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432
Lloyd Piquede196652020-01-22 17:29:58 -08001433 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434
1435 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1436 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1437 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1438 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1439 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1440 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1441
1442 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1443 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1444 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1445
Lloyd Piquede196652020-01-22 17:29:58 -08001446 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1447 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001449 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1450 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1451 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001453
Vishnu Naira483b4a2019-12-12 15:07:52 -08001454TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1455 ui::Transform translate;
1456 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001457 mLayer.layerFEState.geomLayerTransform = translate;
1458 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001459
1460 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1461 // half of the layer including the casting shadow is covered and opaque
1462 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1463 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1466 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001469
1470 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1471 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1472 // add starting opaque region to the opaque half of the casting layer bounds
1473 const Region kExpectedAboveOpaqueRegion =
1474 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1475 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1476 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1477 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1478 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1479 const Region kExpectedLayerShadowRegion =
1480 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1481
1482 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1483 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1484 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1485
Lloyd Piquede196652020-01-22 17:29:58 -08001486 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1487 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001488 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001489 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1490 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001491 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001492 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001493 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1494}
1495
1496TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1497 ui::Transform translate;
1498 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001499 mLayer.layerFEState.geomLayerTransform = translate;
1500 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001501
1502 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1503 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1504 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1505 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1506
Lloyd Piquede196652020-01-22 17:29:58 -08001507 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1508 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001509
Lloyd Piquede196652020-01-22 17:29:58 -08001510 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001511
1512 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1513 const Region kExpectedLayerShadowRegion =
1514 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1517 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001518 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1519}
1520
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001521TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001522 ui::Transform translate;
1523 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001524 mLayer.layerFEState.geomLayerTransform = translate;
1525 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001526
1527 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1528 // Casting layer and its shadows are covered by an opaque region
1529 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1530 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1531
Lloyd Piquede196652020-01-22 17:29:58 -08001532 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001533}
1534
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001535/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001536 * Output::present()
1537 */
1538
1539struct OutputPresentTest : public testing::Test {
1540 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001541 // Sets up the helper functions called by the function under test to use
1542 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001543 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1544 MOCK_METHOD1(updateAndWriteCompositionState,
1545 void(const compositionengine::CompositionRefreshArgs&));
1546 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1547 MOCK_METHOD0(beginFrame, void());
1548 MOCK_METHOD0(prepareFrame, void());
1549 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1550 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1551 MOCK_METHOD0(postFramebuffer, void());
1552 };
1553
1554 StrictMock<OutputPartialMock> mOutput;
1555};
1556
1557TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1558 CompositionRefreshArgs args;
1559
1560 InSequence seq;
1561 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1562 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1563 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1564 EXPECT_CALL(mOutput, beginFrame());
1565 EXPECT_CALL(mOutput, prepareFrame());
1566 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1567 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1568 EXPECT_CALL(mOutput, postFramebuffer());
1569
1570 mOutput.present(args);
1571}
1572
1573/*
1574 * Output::updateColorProfile()
1575 */
1576
Lloyd Pique17ca7422019-11-14 14:24:10 -08001577struct OutputUpdateColorProfileTest : public testing::Test {
1578 using TestType = OutputUpdateColorProfileTest;
1579
1580 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001581 // Sets up the helper functions called by the function under test to use
1582 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001583 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1584 };
1585
1586 struct Layer {
1587 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001588 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001589 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001590 }
1591
1592 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001593 StrictMock<mock::LayerFE> mLayerFE;
1594 LayerFECompositionState mLayerFEState;
1595 };
1596
1597 OutputUpdateColorProfileTest() {
1598 mOutput.setDisplayColorProfileForTest(
1599 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1600 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1601
1602 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1603 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1604 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1605 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1606 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1607 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1608 }
1609
1610 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1611 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1612 };
1613
1614 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1615 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1616 StrictMock<OutputPartialMock> mOutput;
1617
1618 Layer mLayer1;
1619 Layer mLayer2;
1620 Layer mLayer3;
1621
1622 CompositionRefreshArgs mRefreshArgs;
1623};
1624
1625// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1626// to make it easier to write unit tests.
1627
1628TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1629 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1630 // a simple default color profile without looking at anything else.
1631
Lloyd Pique0a456232020-01-16 17:51:13 -08001632 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001633 EXPECT_CALL(mOutput,
1634 setColorProfile(ColorProfileEq(
1635 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1636 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1637
1638 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1639 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1640
1641 mOutput.updateColorProfile(mRefreshArgs);
1642}
1643
1644struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1645 : public OutputUpdateColorProfileTest {
1646 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001647 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001648 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1649 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1650 }
1651
1652 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1653 : public CallOrderStateMachineHelper<
1654 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1655 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1656 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1657 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1658 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1659 _))
1660 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1661 SetArgPointee<4>(renderIntent)));
1662 EXPECT_CALL(getInstance()->mOutput,
1663 setColorProfile(
1664 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1665 ui::Dataspace::UNKNOWN})));
1666 return nextState<ExecuteState>();
1667 }
1668 };
1669
1670 // Call this member function to start using the mini-DSL defined above.
1671 [[nodiscard]] auto verify() {
1672 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1673 }
1674};
1675
1676TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1677 Native_Unknown_Colorimetric_Set) {
1678 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1679 ui::Dataspace::UNKNOWN,
1680 ui::RenderIntent::COLORIMETRIC)
1681 .execute();
1682}
1683
1684TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1685 DisplayP3_DisplayP3_Enhance_Set) {
1686 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1687 ui::Dataspace::DISPLAY_P3,
1688 ui::RenderIntent::ENHANCE)
1689 .execute();
1690}
1691
1692struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1693 : public OutputUpdateColorProfileTest {
1694 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001695 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001696 EXPECT_CALL(*mDisplayColorProfile,
1697 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1698 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1699 SetArgPointee<3>(ui::ColorMode::NATIVE),
1700 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1701 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1702 }
1703
1704 struct IfColorSpaceAgnosticDataspaceSetToState
1705 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1706 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1707 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1708 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1709 }
1710 };
1711
1712 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1713 : public CallOrderStateMachineHelper<
1714 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1715 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1716 ui::Dataspace dataspace) {
1717 EXPECT_CALL(getInstance()->mOutput,
1718 setColorProfile(ColorProfileEq(
1719 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1720 ui::RenderIntent::COLORIMETRIC, dataspace})));
1721 return nextState<ExecuteState>();
1722 }
1723 };
1724
1725 // Call this member function to start using the mini-DSL defined above.
1726 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1727};
1728
1729TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1730 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1731 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1732 .execute();
1733}
1734
1735TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1736 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1737 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1738 .execute();
1739}
1740
1741struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1742 : public OutputUpdateColorProfileTest {
1743 // Internally the implementation looks through the dataspaces of all the
1744 // visible layers. The topmost one that also has an actual dataspace
1745 // preference set is used to drive subsequent choices.
1746
1747 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1748 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1749 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1750
Lloyd Pique0a456232020-01-16 17:51:13 -08001751 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001752 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1753 }
1754
1755 struct IfTopLayerDataspaceState
1756 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1757 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1758 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1759 return nextState<AndIfMiddleLayerDataspaceState>();
1760 }
1761 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1762 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1763 }
1764 };
1765
1766 struct AndIfMiddleLayerDataspaceState
1767 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1768 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1769 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1770 return nextState<AndIfBottomLayerDataspaceState>();
1771 }
1772 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1773 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1774 }
1775 };
1776
1777 struct AndIfBottomLayerDataspaceState
1778 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1779 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1780 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1781 return nextState<ThenExpectBestColorModeCallUsesState>();
1782 }
1783 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1784 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1785 }
1786 };
1787
1788 struct ThenExpectBestColorModeCallUsesState
1789 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1790 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1791 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1792 getBestColorMode(dataspace, _, _, _, _));
1793 return nextState<ExecuteState>();
1794 }
1795 };
1796
1797 // Call this member function to start using the mini-DSL defined above.
1798 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1799};
1800
1801TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1802 noStrongLayerPrefenceUses_V0_SRGB) {
1803 // If none of the layers indicate a preference, then V0_SRGB is the
1804 // preferred choice (subject to additional checks).
1805 verify().ifTopLayerHasNoPreference()
1806 .andIfMiddleLayerHasNoPreference()
1807 .andIfBottomLayerHasNoPreference()
1808 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1809 .execute();
1810}
1811
1812TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1813 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1814 // If only the topmost layer has a preference, then that is what is chosen.
1815 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1816 .andIfMiddleLayerHasNoPreference()
1817 .andIfBottomLayerHasNoPreference()
1818 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1819 .execute();
1820}
1821
1822TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1823 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1824 // If only the middle layer has a preference, that that is what is chosen.
1825 verify().ifTopLayerHasNoPreference()
1826 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1827 .andIfBottomLayerHasNoPreference()
1828 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1829 .execute();
1830}
1831
1832TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1833 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1834 // If only the middle layer has a preference, that that is what is chosen.
1835 verify().ifTopLayerHasNoPreference()
1836 .andIfMiddleLayerHasNoPreference()
1837 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1838 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1839 .execute();
1840}
1841
1842TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1843 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1844 // If multiple layers have a preference, the topmost value is what is used.
1845 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1846 .andIfMiddleLayerHasNoPreference()
1847 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1848 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1849 .execute();
1850}
1851
1852TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1853 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1854 // If multiple layers have a preference, the topmost value is what is used.
1855 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1856 .andIfMiddleLayerHasNoPreference()
1857 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1858 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1859 .execute();
1860}
1861
1862struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1863 : public OutputUpdateColorProfileTest {
1864 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1865 // values, it overrides the layer dataspace choice.
1866
1867 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1868 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1869 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1870
1871 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1872
Lloyd Pique0a456232020-01-16 17:51:13 -08001873 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001874 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1875 }
1876
1877 struct IfForceOutputColorModeState
1878 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1879 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1880 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1881 return nextState<ThenExpectBestColorModeCallUsesState>();
1882 }
1883 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1884 };
1885
1886 struct ThenExpectBestColorModeCallUsesState
1887 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1888 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1889 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1890 getBestColorMode(dataspace, _, _, _, _));
1891 return nextState<ExecuteState>();
1892 }
1893 };
1894
1895 // Call this member function to start using the mini-DSL defined above.
1896 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1897};
1898
1899TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1900 // By default the layer state is used to set the preferred dataspace
1901 verify().ifNoOverride()
1902 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1903 .execute();
1904}
1905
1906TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1907 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1908 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1909 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1910 .execute();
1911}
1912
1913TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1914 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1915 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1916 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1917 .execute();
1918}
1919
1920// HDR output requires all layers to be compatible with the chosen HDR
1921// dataspace, along with there being proper support.
1922struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1923 OutputUpdateColorProfileTest_Hdr() {
1924 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1925 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001926 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001927 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1928 }
1929
1930 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1931 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1932 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1933 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1934
1935 struct IfTopLayerDataspaceState
1936 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1937 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1938 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1939 return nextState<AndTopLayerCompositionTypeState>();
1940 }
1941 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1942 };
1943
1944 struct AndTopLayerCompositionTypeState
1945 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1946 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1947 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1948 return nextState<AndIfBottomLayerDataspaceState>();
1949 }
1950 };
1951
1952 struct AndIfBottomLayerDataspaceState
1953 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1954 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1955 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1956 return nextState<AndBottomLayerCompositionTypeState>();
1957 }
1958 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1959 return andIfBottomLayerIs(kNonHdrDataspace);
1960 }
1961 };
1962
1963 struct AndBottomLayerCompositionTypeState
1964 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1965 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1966 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1967 return nextState<AndIfHasLegacySupportState>();
1968 }
1969 };
1970
1971 struct AndIfHasLegacySupportState
1972 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1973 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1974 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1975 .WillOnce(Return(legacySupport));
1976 return nextState<ThenExpectBestColorModeCallUsesState>();
1977 }
1978 };
1979
1980 struct ThenExpectBestColorModeCallUsesState
1981 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1982 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1983 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1984 getBestColorMode(dataspace, _, _, _, _));
1985 return nextState<ExecuteState>();
1986 }
1987 };
1988
1989 // Call this member function to start using the mini-DSL defined above.
1990 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1991};
1992
1993TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
1994 // If all layers use BT2020_PQ, and there are no other special conditions,
1995 // BT2020_PQ is used.
1996 verify().ifTopLayerIs(BT2020_PQ)
1997 .andTopLayerIsREComposed(false)
1998 .andIfBottomLayerIs(BT2020_PQ)
1999 .andBottomLayerIsREComposed(false)
2000 .andIfLegacySupportFor(BT2020_PQ, false)
2001 .thenExpectBestColorModeCallUses(BT2020_PQ)
2002 .execute();
2003}
2004
2005TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2006 // BT2020_PQ is not used if there is only legacy support for it.
2007 verify().ifTopLayerIs(BT2020_PQ)
2008 .andTopLayerIsREComposed(false)
2009 .andIfBottomLayerIs(BT2020_PQ)
2010 .andBottomLayerIsREComposed(false)
2011 .andIfLegacySupportFor(BT2020_PQ, true)
2012 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2013 .execute();
2014}
2015
2016TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2017 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2018 verify().ifTopLayerIs(BT2020_PQ)
2019 .andTopLayerIsREComposed(false)
2020 .andIfBottomLayerIs(BT2020_PQ)
2021 .andBottomLayerIsREComposed(true)
2022 .andIfLegacySupportFor(BT2020_PQ, false)
2023 .thenExpectBestColorModeCallUses(BT2020_PQ)
2024 .execute();
2025}
2026
2027TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2028 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2029 verify().ifTopLayerIs(BT2020_PQ)
2030 .andTopLayerIsREComposed(true)
2031 .andIfBottomLayerIs(BT2020_PQ)
2032 .andBottomLayerIsREComposed(false)
2033 .andIfLegacySupportFor(BT2020_PQ, false)
2034 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2035 .execute();
2036}
2037
2038TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2039 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2040 // are no other special conditions.
2041 verify().ifTopLayerIs(BT2020_PQ)
2042 .andTopLayerIsREComposed(false)
2043 .andIfBottomLayerIs(BT2020_HLG)
2044 .andBottomLayerIsREComposed(false)
2045 .andIfLegacySupportFor(BT2020_PQ, false)
2046 .thenExpectBestColorModeCallUses(BT2020_PQ)
2047 .execute();
2048}
2049
2050TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2051 // BT2020_PQ is not used if there is only legacy support for it.
2052 verify().ifTopLayerIs(BT2020_PQ)
2053 .andTopLayerIsREComposed(false)
2054 .andIfBottomLayerIs(BT2020_HLG)
2055 .andBottomLayerIsREComposed(false)
2056 .andIfLegacySupportFor(BT2020_PQ, true)
2057 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2058 .execute();
2059}
2060
2061TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2062 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2063 verify().ifTopLayerIs(BT2020_PQ)
2064 .andTopLayerIsREComposed(false)
2065 .andIfBottomLayerIs(BT2020_HLG)
2066 .andBottomLayerIsREComposed(true)
2067 .andIfLegacySupportFor(BT2020_PQ, false)
2068 .thenExpectBestColorModeCallUses(BT2020_PQ)
2069 .execute();
2070}
2071
2072TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2073 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2074 verify().ifTopLayerIs(BT2020_PQ)
2075 .andTopLayerIsREComposed(true)
2076 .andIfBottomLayerIs(BT2020_HLG)
2077 .andBottomLayerIsREComposed(false)
2078 .andIfLegacySupportFor(BT2020_PQ, false)
2079 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2080 .execute();
2081}
2082
2083TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2084 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2085 // used if there are no other special conditions.
2086 verify().ifTopLayerIs(BT2020_HLG)
2087 .andTopLayerIsREComposed(false)
2088 .andIfBottomLayerIs(BT2020_PQ)
2089 .andBottomLayerIsREComposed(false)
2090 .andIfLegacySupportFor(BT2020_PQ, false)
2091 .thenExpectBestColorModeCallUses(BT2020_PQ)
2092 .execute();
2093}
2094
2095TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2096 // BT2020_PQ is not used if there is only legacy support for it.
2097 verify().ifTopLayerIs(BT2020_HLG)
2098 .andTopLayerIsREComposed(false)
2099 .andIfBottomLayerIs(BT2020_PQ)
2100 .andBottomLayerIsREComposed(false)
2101 .andIfLegacySupportFor(BT2020_PQ, true)
2102 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2103 .execute();
2104}
2105
2106TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2107 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2108 verify().ifTopLayerIs(BT2020_HLG)
2109 .andTopLayerIsREComposed(false)
2110 .andIfBottomLayerIs(BT2020_PQ)
2111 .andBottomLayerIsREComposed(true)
2112 .andIfLegacySupportFor(BT2020_PQ, false)
2113 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2114 .execute();
2115}
2116
2117TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2118 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2119 verify().ifTopLayerIs(BT2020_HLG)
2120 .andTopLayerIsREComposed(true)
2121 .andIfBottomLayerIs(BT2020_PQ)
2122 .andBottomLayerIsREComposed(false)
2123 .andIfLegacySupportFor(BT2020_PQ, false)
2124 .thenExpectBestColorModeCallUses(BT2020_PQ)
2125 .execute();
2126}
2127
2128TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2129 // If all layers use HLG then HLG is used if there are no other special
2130 // conditions.
2131 verify().ifTopLayerIs(BT2020_HLG)
2132 .andTopLayerIsREComposed(false)
2133 .andIfBottomLayerIs(BT2020_HLG)
2134 .andBottomLayerIsREComposed(false)
2135 .andIfLegacySupportFor(BT2020_HLG, false)
2136 .thenExpectBestColorModeCallUses(BT2020_HLG)
2137 .execute();
2138}
2139
2140TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2141 // BT2020_HLG is not used if there is legacy support for it.
2142 verify().ifTopLayerIs(BT2020_HLG)
2143 .andTopLayerIsREComposed(false)
2144 .andIfBottomLayerIs(BT2020_HLG)
2145 .andBottomLayerIsREComposed(false)
2146 .andIfLegacySupportFor(BT2020_HLG, true)
2147 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2148 .execute();
2149}
2150
2151TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2152 // BT2020_HLG is used even if the bottom layer is client composed.
2153 verify().ifTopLayerIs(BT2020_HLG)
2154 .andTopLayerIsREComposed(false)
2155 .andIfBottomLayerIs(BT2020_HLG)
2156 .andBottomLayerIsREComposed(true)
2157 .andIfLegacySupportFor(BT2020_HLG, false)
2158 .thenExpectBestColorModeCallUses(BT2020_HLG)
2159 .execute();
2160}
2161
2162TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2163 // BT2020_HLG is used even if the top layer is client composed.
2164 verify().ifTopLayerIs(BT2020_HLG)
2165 .andTopLayerIsREComposed(true)
2166 .andIfBottomLayerIs(BT2020_HLG)
2167 .andBottomLayerIsREComposed(false)
2168 .andIfLegacySupportFor(BT2020_HLG, false)
2169 .thenExpectBestColorModeCallUses(BT2020_HLG)
2170 .execute();
2171}
2172
2173TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2174 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2175 verify().ifTopLayerIs(BT2020_PQ)
2176 .andTopLayerIsREComposed(false)
2177 .andIfBottomLayerIsNotHdr()
2178 .andBottomLayerIsREComposed(false)
2179 .andIfLegacySupportFor(BT2020_PQ, false)
2180 .thenExpectBestColorModeCallUses(BT2020_PQ)
2181 .execute();
2182}
2183
2184TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2185 // If all layers use HLG then HLG is used if there are no other special
2186 // conditions.
2187 verify().ifTopLayerIs(BT2020_HLG)
2188 .andTopLayerIsREComposed(false)
2189 .andIfBottomLayerIsNotHdr()
2190 .andBottomLayerIsREComposed(true)
2191 .andIfLegacySupportFor(BT2020_HLG, false)
2192 .thenExpectBestColorModeCallUses(BT2020_HLG)
2193 .execute();
2194}
2195
2196struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2197 : public OutputUpdateColorProfileTest {
2198 // The various values for CompositionRefreshArgs::outputColorSetting affect
2199 // the chosen renderIntent, along with whether the preferred dataspace is an
2200 // HDR dataspace or not.
2201
2202 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2203 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2204 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2205 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002206 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002207 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2208 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2209 .WillRepeatedly(Return(false));
2210 }
2211
2212 // The tests here involve enough state and GMock setup that using a mini-DSL
2213 // makes the tests much more readable, and allows the test to focus more on
2214 // the intent than on some of the details.
2215
2216 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2217 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2218
2219 struct IfDataspaceChosenState
2220 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2221 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2222 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2223 return nextState<AndOutputColorSettingState>();
2224 }
2225 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2226 return ifDataspaceChosenIs(kNonHdrDataspace);
2227 }
2228 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2229 };
2230
2231 struct AndOutputColorSettingState
2232 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2233 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2234 getInstance()->mRefreshArgs.outputColorSetting = setting;
2235 return nextState<ThenExpectBestColorModeCallUsesState>();
2236 }
2237 };
2238
2239 struct ThenExpectBestColorModeCallUsesState
2240 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2241 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2242 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2243 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2244 _, _));
2245 return nextState<ExecuteState>();
2246 }
2247 };
2248
2249 // Tests call one of these two helper member functions to start using the
2250 // mini-DSL defined above.
2251 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2252};
2253
2254TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2255 Managed_NonHdr_Prefers_Colorimetric) {
2256 verify().ifDataspaceChosenIsNonHdr()
2257 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2258 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2259 .execute();
2260}
2261
2262TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2263 Managed_Hdr_Prefers_ToneMapColorimetric) {
2264 verify().ifDataspaceChosenIsHdr()
2265 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2266 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2271 verify().ifDataspaceChosenIsNonHdr()
2272 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2273 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2274 .execute();
2275}
2276
2277TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2278 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2279 verify().ifDataspaceChosenIsHdr()
2280 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2281 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2282 .execute();
2283}
2284
2285TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2286 verify().ifDataspaceChosenIsNonHdr()
2287 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2288 .thenExpectBestColorModeCallUses(
2289 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2290 .execute();
2291}
2292
2293TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2294 verify().ifDataspaceChosenIsHdr()
2295 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2296 .thenExpectBestColorModeCallUses(
2297 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2298 .execute();
2299}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002300
2301/*
2302 * Output::beginFrame()
2303 */
2304
Lloyd Piquee5965952019-11-18 16:16:32 -08002305struct OutputBeginFrameTest : public ::testing::Test {
2306 using TestType = OutputBeginFrameTest;
2307
2308 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002309 // Sets up the helper functions called by the function under test to use
2310 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002311 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2312 };
2313
2314 OutputBeginFrameTest() {
2315 mOutput.setDisplayColorProfileForTest(
2316 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2317 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2318 }
2319
2320 struct IfGetDirtyRegionExpectationState
2321 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2322 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2323 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2324 .WillOnce(Return(dirtyRegion));
2325 return nextState<AndIfGetOutputLayerCountExpectationState>();
2326 }
2327 };
2328
2329 struct AndIfGetOutputLayerCountExpectationState
2330 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2331 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2332 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2333 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2334 }
2335 };
2336
2337 struct AndIfLastCompositionHadVisibleLayersState
2338 : public CallOrderStateMachineHelper<TestType,
2339 AndIfLastCompositionHadVisibleLayersState> {
2340 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2341 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2342 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2343 }
2344 };
2345
2346 struct ThenExpectRenderSurfaceBeginFrameCallState
2347 : public CallOrderStateMachineHelper<TestType,
2348 ThenExpectRenderSurfaceBeginFrameCallState> {
2349 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2350 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2351 return nextState<ExecuteState>();
2352 }
2353 };
2354
2355 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2356 [[nodiscard]] auto execute() {
2357 getInstance()->mOutput.beginFrame();
2358 return nextState<CheckPostconditionHadVisibleLayersState>();
2359 }
2360 };
2361
2362 struct CheckPostconditionHadVisibleLayersState
2363 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2364 void checkPostconditionHadVisibleLayers(bool expected) {
2365 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2366 }
2367 };
2368
2369 // Tests call one of these two helper member functions to start using the
2370 // mini-DSL defined above.
2371 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2372
2373 static const Region kEmptyRegion;
2374 static const Region kNotEmptyRegion;
2375
2376 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2377 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2378 StrictMock<OutputPartialMock> mOutput;
2379};
2380
2381const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2382const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2383
2384TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2385 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2386 .andIfGetOutputLayerCountReturns(1u)
2387 .andIfLastCompositionHadVisibleLayersIs(true)
2388 .thenExpectRenderSurfaceBeginFrameCall(true)
2389 .execute()
2390 .checkPostconditionHadVisibleLayers(true);
2391}
2392
2393TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2394 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2395 .andIfGetOutputLayerCountReturns(0u)
2396 .andIfLastCompositionHadVisibleLayersIs(true)
2397 .thenExpectRenderSurfaceBeginFrameCall(true)
2398 .execute()
2399 .checkPostconditionHadVisibleLayers(false);
2400}
2401
2402TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2403 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2404 .andIfGetOutputLayerCountReturns(1u)
2405 .andIfLastCompositionHadVisibleLayersIs(false)
2406 .thenExpectRenderSurfaceBeginFrameCall(true)
2407 .execute()
2408 .checkPostconditionHadVisibleLayers(true);
2409}
2410
2411TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2412 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2413 .andIfGetOutputLayerCountReturns(0u)
2414 .andIfLastCompositionHadVisibleLayersIs(false)
2415 .thenExpectRenderSurfaceBeginFrameCall(false)
2416 .execute()
2417 .checkPostconditionHadVisibleLayers(false);
2418}
2419
2420TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2421 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2422 .andIfGetOutputLayerCountReturns(1u)
2423 .andIfLastCompositionHadVisibleLayersIs(true)
2424 .thenExpectRenderSurfaceBeginFrameCall(false)
2425 .execute()
2426 .checkPostconditionHadVisibleLayers(true);
2427}
2428
2429TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2430 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2431 .andIfGetOutputLayerCountReturns(0u)
2432 .andIfLastCompositionHadVisibleLayersIs(true)
2433 .thenExpectRenderSurfaceBeginFrameCall(false)
2434 .execute()
2435 .checkPostconditionHadVisibleLayers(true);
2436}
2437
2438TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2439 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2440 .andIfGetOutputLayerCountReturns(1u)
2441 .andIfLastCompositionHadVisibleLayersIs(false)
2442 .thenExpectRenderSurfaceBeginFrameCall(false)
2443 .execute()
2444 .checkPostconditionHadVisibleLayers(false);
2445}
2446
2447TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2448 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2449 .andIfGetOutputLayerCountReturns(0u)
2450 .andIfLastCompositionHadVisibleLayersIs(false)
2451 .thenExpectRenderSurfaceBeginFrameCall(false)
2452 .execute()
2453 .checkPostconditionHadVisibleLayers(false);
2454}
2455
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002456/*
2457 * Output::devOptRepaintFlash()
2458 */
2459
Lloyd Piquedb462d82019-11-19 17:58:46 -08002460struct OutputDevOptRepaintFlashTest : public testing::Test {
2461 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002462 // Sets up the helper functions called by the function under test to use
2463 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002464 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002465 MOCK_METHOD2(composeSurfaces,
2466 std::optional<base::unique_fd>(
2467 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002468 MOCK_METHOD0(postFramebuffer, void());
2469 MOCK_METHOD0(prepareFrame, void());
2470 };
2471
2472 OutputDevOptRepaintFlashTest() {
2473 mOutput.setDisplayColorProfileForTest(
2474 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2475 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2476 }
2477
2478 static const Region kEmptyRegion;
2479 static const Region kNotEmptyRegion;
2480
2481 StrictMock<OutputPartialMock> mOutput;
2482 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2483 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2484 CompositionRefreshArgs mRefreshArgs;
2485};
2486
2487const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2488const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2489
2490TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2491 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2492 mRefreshArgs.repaintEverything = true;
2493 mOutput.mState.isEnabled = true;
2494
2495 mOutput.devOptRepaintFlash(mRefreshArgs);
2496}
2497
2498TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2499 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2500 mRefreshArgs.repaintEverything = true;
2501 mOutput.mState.isEnabled = false;
2502
2503 InSequence seq;
2504 EXPECT_CALL(mOutput, postFramebuffer());
2505 EXPECT_CALL(mOutput, prepareFrame());
2506
2507 mOutput.devOptRepaintFlash(mRefreshArgs);
2508}
2509
2510TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2511 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2512 mRefreshArgs.repaintEverything = true;
2513 mOutput.mState.isEnabled = true;
2514
2515 InSequence seq;
2516 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2517 EXPECT_CALL(mOutput, postFramebuffer());
2518 EXPECT_CALL(mOutput, prepareFrame());
2519
2520 mOutput.devOptRepaintFlash(mRefreshArgs);
2521}
2522
2523TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2524 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2525 mRefreshArgs.repaintEverything = false;
2526 mOutput.mState.isEnabled = true;
2527
2528 InSequence seq;
2529 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002530 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002531 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2532 EXPECT_CALL(mOutput, postFramebuffer());
2533 EXPECT_CALL(mOutput, prepareFrame());
2534
2535 mOutput.devOptRepaintFlash(mRefreshArgs);
2536}
2537
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002538/*
2539 * Output::finishFrame()
2540 */
2541
Lloyd Pique03561a62019-11-19 18:34:52 -08002542struct OutputFinishFrameTest : public testing::Test {
2543 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002544 // Sets up the helper functions called by the function under test to use
2545 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002546 MOCK_METHOD2(composeSurfaces,
2547 std::optional<base::unique_fd>(
2548 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002549 MOCK_METHOD0(postFramebuffer, void());
2550 };
2551
2552 OutputFinishFrameTest() {
2553 mOutput.setDisplayColorProfileForTest(
2554 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2555 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2556 }
2557
2558 StrictMock<OutputPartialMock> mOutput;
2559 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2560 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2561 CompositionRefreshArgs mRefreshArgs;
2562};
2563
2564TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2565 mOutput.mState.isEnabled = false;
2566
2567 mOutput.finishFrame(mRefreshArgs);
2568}
2569
2570TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2571 mOutput.mState.isEnabled = true;
2572
2573 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002574 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002575
2576 mOutput.finishFrame(mRefreshArgs);
2577}
2578
2579TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2580 mOutput.mState.isEnabled = true;
2581
2582 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002583 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002584 .WillOnce(Return(ByMove(base::unique_fd())));
2585 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2586
2587 mOutput.finishFrame(mRefreshArgs);
2588}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002589
2590/*
2591 * Output::postFramebuffer()
2592 */
2593
Lloyd Pique07178e32019-11-19 19:15:26 -08002594struct OutputPostFramebufferTest : public testing::Test {
2595 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002596 // Sets up the helper functions called by the function under test to use
2597 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002598 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2599 };
2600
2601 struct Layer {
2602 Layer() {
2603 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2604 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2605 }
2606
2607 StrictMock<mock::OutputLayer> outputLayer;
2608 StrictMock<mock::LayerFE> layerFE;
2609 StrictMock<HWC2::mock::Layer> hwc2Layer;
2610 };
2611
2612 OutputPostFramebufferTest() {
2613 mOutput.setDisplayColorProfileForTest(
2614 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2615 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2616
2617 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2618 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2619 .WillRepeatedly(Return(&mLayer1.outputLayer));
2620 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2621 .WillRepeatedly(Return(&mLayer2.outputLayer));
2622 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2623 .WillRepeatedly(Return(&mLayer3.outputLayer));
2624 }
2625
2626 StrictMock<OutputPartialMock> mOutput;
2627 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2628 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2629
2630 Layer mLayer1;
2631 Layer mLayer2;
2632 Layer mLayer3;
2633};
2634
2635TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2636 mOutput.mState.isEnabled = false;
2637
2638 mOutput.postFramebuffer();
2639}
2640
2641TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2642 mOutput.mState.isEnabled = true;
2643
2644 compositionengine::Output::FrameFences frameFences;
2645
2646 // This should happen even if there are no output layers.
2647 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2648
2649 // For this test in particular we want to make sure the call expectations
2650 // setup below are satisfied in the specific order.
2651 InSequence seq;
2652
2653 EXPECT_CALL(*mRenderSurface, flip());
2654 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2655 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2656
2657 mOutput.postFramebuffer();
2658}
2659
2660TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2661 // Simulate getting release fences from each layer, and ensure they are passed to the
2662 // front-end layer interface for each layer correctly.
2663
2664 mOutput.mState.isEnabled = true;
2665
2666 // Create three unique fence instances
2667 sp<Fence> layer1Fence = new Fence();
2668 sp<Fence> layer2Fence = new Fence();
2669 sp<Fence> layer3Fence = new Fence();
2670
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002671 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002672 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2673 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2674 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2675
2676 EXPECT_CALL(*mRenderSurface, flip());
2677 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2678 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2679
2680 // Compare the pointers values of each fence to make sure the correct ones
2681 // are passed. This happens to work with the current implementation, but
2682 // would not survive certain calls like Fence::merge() which would return a
2683 // new instance.
2684 EXPECT_CALL(mLayer1.layerFE,
2685 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2686 EXPECT_CALL(mLayer2.layerFE,
2687 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2688 EXPECT_CALL(mLayer3.layerFE,
2689 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2690
2691 mOutput.postFramebuffer();
2692}
2693
2694TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2695 mOutput.mState.isEnabled = true;
2696 mOutput.mState.usesClientComposition = true;
2697
2698 sp<Fence> clientTargetAcquireFence = new Fence();
2699 sp<Fence> layer1Fence = new Fence();
2700 sp<Fence> layer2Fence = new Fence();
2701 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002702 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002703 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2704 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2705 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2706 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2707
2708 EXPECT_CALL(*mRenderSurface, flip());
2709 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2710 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2711
2712 // Fence::merge is called, and since none of the fences are actually valid,
2713 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2714 // This is the best we can do without creating a real kernel fence object.
2715 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2716 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2717 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2718
2719 mOutput.postFramebuffer();
2720}
2721
2722TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2723 mOutput.mState.isEnabled = true;
2724 mOutput.mState.usesClientComposition = true;
2725
2726 // This should happen even if there are no (current) output layers.
2727 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2728
2729 // Load up the released layers with some mock instances
2730 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2731 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2732 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2733 Output::ReleasedLayers layers;
2734 layers.push_back(releasedLayer1);
2735 layers.push_back(releasedLayer2);
2736 layers.push_back(releasedLayer3);
2737 mOutput.setReleasedLayers(std::move(layers));
2738
2739 // Set up a fake present fence
2740 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002741 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002742 frameFences.presentFence = presentFence;
2743
2744 EXPECT_CALL(*mRenderSurface, flip());
2745 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2746 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2747
2748 // Each released layer should be given the presentFence.
2749 EXPECT_CALL(*releasedLayer1,
2750 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2751 EXPECT_CALL(*releasedLayer2,
2752 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2753 EXPECT_CALL(*releasedLayer3,
2754 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2755
2756 mOutput.postFramebuffer();
2757
2758 // After the call the list of released layers should have been cleared.
2759 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2760}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002761
2762/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002763 * Output::composeSurfaces()
2764 */
2765
2766struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002767 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002768
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002769 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002770 // Sets up the helper functions called by the function under test to use
2771 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002772 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002773 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002774 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002775 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002776 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002777 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2778 };
2779
2780 OutputComposeSurfacesTest() {
2781 mOutput.setDisplayColorProfileForTest(
2782 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2783 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002784 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002785
Lloyd Pique6818fa52019-12-03 12:32:13 -08002786 mOutput.mState.frame = kDefaultOutputFrame;
2787 mOutput.mState.viewport = kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002788 mOutput.mState.destinationClip = kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002789 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientation};
2790 mOutput.mState.orientation = kDefaultOutputOrientation;
2791 mOutput.mState.dataspace = kDefaultOutputDataspace;
2792 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2793 mOutput.mState.isSecure = false;
2794 mOutput.mState.needsFiltering = false;
2795 mOutput.mState.usesClientComposition = true;
2796 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002797 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002798 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002799
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002800 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002801 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002802 EXPECT_CALL(mCompositionEngine, getTimeStats())
2803 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002804 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2805 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002806 }
2807
Lloyd Pique6818fa52019-12-03 12:32:13 -08002808 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2809 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002810 getInstance()->mReadyFence =
2811 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002812 return nextState<FenceCheckState>();
2813 }
2814 };
2815
2816 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2817 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2818
2819 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2820 };
2821
2822 // Call this member function to start using the mini-DSL defined above.
2823 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2824
2825 static constexpr uint32_t kDefaultOutputOrientation = TR_IDENT;
2826 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2827 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2828 static constexpr float kDefaultMaxLuminance = 0.9f;
2829 static constexpr float kDefaultAvgLuminance = 0.7f;
2830 static constexpr float kDefaultMinLuminance = 0.1f;
2831
2832 static const Rect kDefaultOutputFrame;
2833 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002834 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002835 static const mat4 kDefaultColorTransformMat;
2836
2837 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002838 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002839 static const HdrCapabilities kHdrCapabilities;
2840
Lloyd Pique56eba802019-08-28 15:45:25 -07002841 StrictMock<mock::CompositionEngine> mCompositionEngine;
2842 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002843 // TODO: make this is a proper mock.
2844 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002845 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2846 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002847 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002848 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002849
2850 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002851};
2852
2853const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2854const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002855const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002856const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002857const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002858const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2859const HdrCapabilities OutputComposeSurfacesTest::
2860 kHdrCapabilities{{},
2861 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2862 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2863 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002864
Lloyd Piquea76ce462020-01-14 13:06:37 -08002865TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002866 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002867
Lloyd Piquee9eff972020-05-05 12:36:44 -07002868 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2869
Lloyd Piquea76ce462020-01-14 13:06:37 -08002870 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2871
Lloyd Pique6818fa52019-12-03 12:32:13 -08002872 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002873}
2874
Lloyd Piquee9eff972020-05-05 12:36:44 -07002875TEST_F(OutputComposeSurfacesTest,
2876 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2877 mOutput.mState.usesClientComposition = false;
2878 mOutput.mState.flipClientTarget = true;
2879
Lloyd Pique6818fa52019-12-03 12:32:13 -08002880 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002881
2882 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2883 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2884
2885 verify().execute().expectAFenceWasReturned();
2886}
2887
2888TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2889 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2890
2891 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2892
2893 verify().execute().expectNoFenceWasReturned();
2894}
2895
2896TEST_F(OutputComposeSurfacesTest,
2897 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2898 mOutput.mState.usesClientComposition = false;
2899 mOutput.mState.flipClientTarget = true;
2900
2901 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002902
Lloyd Pique6818fa52019-12-03 12:32:13 -08002903 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002904
Lloyd Pique6818fa52019-12-03 12:32:13 -08002905 verify().execute().expectNoFenceWasReturned();
2906}
Lloyd Pique56eba802019-08-28 15:45:25 -07002907
Lloyd Pique6818fa52019-12-03 12:32:13 -08002908TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
2909 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2910 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2911 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2912 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002913 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002914 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2915 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002916
Lloyd Pique6818fa52019-12-03 12:32:13 -08002917 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2918 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2919 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002920
Lloyd Pique6818fa52019-12-03 12:32:13 -08002921 verify().execute().expectAFenceWasReturned();
2922}
Lloyd Pique56eba802019-08-28 15:45:25 -07002923
Lloyd Pique6818fa52019-12-03 12:32:13 -08002924TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002925 LayerFE::LayerSettings r1;
2926 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002927
2928 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2929 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2930
2931 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2932 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2933 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2934 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002935 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002936 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2937 .WillRepeatedly(
2938 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002939 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002940 clientCompositionLayers.emplace_back(r2);
2941 }));
2942
2943 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002944 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002945 .WillRepeatedly(Return(NO_ERROR));
2946
2947 verify().execute().expectAFenceWasReturned();
2948}
2949
Vishnu Nair9b079a22020-01-21 14:36:08 -08002950TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2951 mOutput.cacheClientCompositionRequests(0);
2952 LayerFE::LayerSettings r1;
2953 LayerFE::LayerSettings r2;
2954
2955 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2956 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2957
2958 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2959 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2960 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2961 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2962 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2963 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2964 .WillRepeatedly(Return());
2965
2966 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2967 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2968 .Times(2)
2969 .WillOnce(Return(NO_ERROR));
2970
2971 verify().execute().expectAFenceWasReturned();
2972 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2973
2974 verify().execute().expectAFenceWasReturned();
2975 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2976}
2977
2978TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
2979 mOutput.cacheClientCompositionRequests(3);
2980 LayerFE::LayerSettings r1;
2981 LayerFE::LayerSettings r2;
2982
2983 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2984 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2985
2986 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2987 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2988 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2989 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2990 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2991 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2992 .WillRepeatedly(Return());
2993
2994 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2995 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2996 .WillOnce(Return(NO_ERROR));
2997 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2998
2999 verify().execute().expectAFenceWasReturned();
3000 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3001
3002 // We do not expect another call to draw layers.
3003 verify().execute().expectAFenceWasReturned();
3004 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3005}
3006
3007TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3008 LayerFE::LayerSettings r1;
3009 LayerFE::LayerSettings r2;
3010
3011 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3012 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3013
3014 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3015 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3016 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3017 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3018 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3019 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3020 .WillRepeatedly(Return());
3021
3022 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3023 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3024 .WillOnce(Return(mOutputBuffer))
3025 .WillOnce(Return(otherOutputBuffer));
3026 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3027 .WillRepeatedly(Return(NO_ERROR));
3028
3029 verify().execute().expectAFenceWasReturned();
3030 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3031
3032 verify().execute().expectAFenceWasReturned();
3033 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3034}
3035
3036TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3037 LayerFE::LayerSettings r1;
3038 LayerFE::LayerSettings r2;
3039 LayerFE::LayerSettings r3;
3040
3041 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3042 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3043 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3044
3045 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3046 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3047 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3048 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3049 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3050 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3051 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3052 .WillRepeatedly(Return());
3053
3054 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3055 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3056 .WillOnce(Return(NO_ERROR));
3057 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3058 .WillOnce(Return(NO_ERROR));
3059
3060 verify().execute().expectAFenceWasReturned();
3061 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3062
3063 verify().execute().expectAFenceWasReturned();
3064 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3065}
3066
Lloyd Pique6818fa52019-12-03 12:32:13 -08003067struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3068 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3069 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3070 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003071 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003072 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3073 .WillRepeatedly(Return());
3074 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3075 }
3076
3077 struct MixedCompositionState
3078 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3079 auto ifMixedCompositionIs(bool used) {
3080 getInstance()->mOutput.mState.usesDeviceComposition = used;
3081 return nextState<OutputUsesHdrState>();
3082 }
3083 };
3084
3085 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3086 auto andIfUsesHdr(bool used) {
3087 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3088 .WillOnce(Return(used));
3089 return nextState<SkipColorTransformState>();
3090 }
3091 };
3092
3093 struct SkipColorTransformState
3094 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3095 auto andIfSkipColorTransform(bool skip) {
3096 // May be called zero or one times.
3097 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3098 .WillRepeatedly(Return(skip));
3099 return nextState<ExpectDisplaySettingsState>();
3100 }
3101 };
3102
3103 struct ExpectDisplaySettingsState
3104 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3105 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3106 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3107 .WillOnce(Return(NO_ERROR));
3108 return nextState<ExecuteState>();
3109 }
3110 };
3111
3112 // Call this member function to start using the mini-DSL defined above.
3113 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3114};
3115
3116TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3117 verify().ifMixedCompositionIs(true)
3118 .andIfUsesHdr(true)
3119 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003120 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003121 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3122 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003123 .execute()
3124 .expectAFenceWasReturned();
3125}
3126
3127TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3128 verify().ifMixedCompositionIs(true)
3129 .andIfUsesHdr(false)
3130 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003131 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003132 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3133 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003134 .execute()
3135 .expectAFenceWasReturned();
3136}
3137
3138TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3139 verify().ifMixedCompositionIs(false)
3140 .andIfUsesHdr(true)
3141 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003142 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003143 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003144 kDefaultColorTransformMat, Region::INVALID_REGION,
3145 kDefaultOutputOrientation})
3146 .execute()
3147 .expectAFenceWasReturned();
3148}
3149
3150TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3151 verify().ifMixedCompositionIs(false)
3152 .andIfUsesHdr(false)
3153 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003154 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003155 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156 kDefaultColorTransformMat, Region::INVALID_REGION,
3157 kDefaultOutputOrientation})
3158 .execute()
3159 .expectAFenceWasReturned();
3160}
3161
3162TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3163 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3164 verify().ifMixedCompositionIs(false)
3165 .andIfUsesHdr(true)
3166 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003167 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003168 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
3169 Region::INVALID_REGION, kDefaultOutputOrientation})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003170 .execute()
3171 .expectAFenceWasReturned();
3172}
3173
3174struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3175 struct Layer {
3176 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003177 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3178 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003179 }
3180
3181 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003182 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003183 LayerFECompositionState mLayerFEState;
3184 };
3185
3186 OutputComposeSurfacesTest_HandlesProtectedContent() {
3187 mLayer1.mLayerFEState.hasProtectedContent = false;
3188 mLayer2.mLayerFEState.hasProtectedContent = false;
3189
3190 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3191 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3192 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3193 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3194 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3195
3196 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3197
3198 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3199
3200 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003201 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003202 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3203 .WillRepeatedly(Return());
3204 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3205 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3206 .WillRepeatedly(Return(NO_ERROR));
3207 }
3208
3209 Layer mLayer1;
3210 Layer mLayer2;
3211};
3212
3213TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3214 mOutput.mState.isSecure = false;
3215 mLayer2.mLayerFEState.hasProtectedContent = true;
3216 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3217
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003218 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003219}
3220
3221TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3222 mOutput.mState.isSecure = true;
3223 mLayer2.mLayerFEState.hasProtectedContent = true;
3224 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3225
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003226 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003227}
3228
3229TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3230 mOutput.mState.isSecure = true;
3231 mLayer2.mLayerFEState.hasProtectedContent = false;
3232 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3233 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3234 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3235 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3236 EXPECT_CALL(*mRenderSurface, setProtected(false));
3237
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003238 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003239}
3240
3241TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3242 mOutput.mState.isSecure = true;
3243 mLayer2.mLayerFEState.hasProtectedContent = true;
3244 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3245
3246 // For this test, we also check the call order of key functions.
3247 InSequence seq;
3248
3249 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3250 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3251 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3252 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3253 EXPECT_CALL(*mRenderSurface, setProtected(true));
3254 // Must happen after setting the protected content state.
3255 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3256 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3257
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003258 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003259}
3260
3261TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3262 mOutput.mState.isSecure = true;
3263 mLayer2.mLayerFEState.hasProtectedContent = true;
3264 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3265 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3266 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3267
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003268 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003269}
3270
3271TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3272 mOutput.mState.isSecure = true;
3273 mLayer2.mLayerFEState.hasProtectedContent = true;
3274 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3275 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3276 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3277 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3278
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003279 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003280}
3281
3282TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3283 mOutput.mState.isSecure = true;
3284 mLayer2.mLayerFEState.hasProtectedContent = true;
3285 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3286 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3287 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3288 EXPECT_CALL(*mRenderSurface, setProtected(true));
3289
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003290 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003291}
3292
3293TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3294 mOutput.mState.isSecure = true;
3295 mLayer2.mLayerFEState.hasProtectedContent = true;
3296 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3297 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3298 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3299 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3300
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003301 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003302}
3303
3304struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3305 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3306 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3307 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3308 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3309 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3310 .WillRepeatedly(Return());
3311 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3312 }
3313};
3314
3315TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3316 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3317
3318 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003319 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003320
3321 // For this test, we also check the call order of key functions.
3322 InSequence seq;
3323
3324 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3325 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003326
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003327 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3328}
3329
3330struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3331 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3332 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3333 mLayer.layerFEState.backgroundBlurRadius = 10;
3334 mOutput.editState().isEnabled = true;
3335
Snild Dolkow9e217d62020-04-22 15:53:42 +02003336 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003337 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3338 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3339 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3340 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3341 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3342 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3343 .WillRepeatedly(Return(&mLayer.outputLayer));
3344 }
3345
3346 NonInjectedLayer mLayer;
3347 compositionengine::CompositionRefreshArgs mRefreshArgs;
3348};
3349
3350TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3351 mRefreshArgs.blursAreExpensive = true;
3352 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3353
3354 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3355 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3356}
3357
3358TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3359 mRefreshArgs.blursAreExpensive = false;
3360 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3361
3362 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3363 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003364}
3365
3366/*
3367 * Output::generateClientCompositionRequests()
3368 */
3369
3370struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003371 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003372 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003373 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003374 bool supportsProtectedContent, Region& clearRegion,
3375 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003376 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003377 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003378 }
3379 };
3380
Lloyd Piquea4863342019-12-04 18:45:02 -08003381 struct Layer {
3382 Layer() {
3383 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3384 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003385 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003386 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003387 }
3388
3389 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003390 StrictMock<mock::LayerFE> mLayerFE;
3391 LayerFECompositionState mLayerFEState;
3392 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003393 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003394 };
3395
Lloyd Pique56eba802019-08-28 15:45:25 -07003396 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003397 mOutput.mState.needsFiltering = false;
3398
Lloyd Pique56eba802019-08-28 15:45:25 -07003399 mOutput.setDisplayColorProfileForTest(
3400 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3401 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3402 }
3403
Lloyd Pique56eba802019-08-28 15:45:25 -07003404 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3405 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003406 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003407};
3408
Lloyd Piquea4863342019-12-04 18:45:02 -08003409struct GenerateClientCompositionRequestsTest_ThreeLayers
3410 : public GenerateClientCompositionRequestsTest {
3411 GenerateClientCompositionRequestsTest_ThreeLayers() {
3412 mOutput.mState.frame = kDisplayFrame;
3413 mOutput.mState.viewport = kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003414 mOutput.mState.destinationClip = kDisplayDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003415 mOutput.mState.transform = ui::Transform{kDisplayOrientation};
3416 mOutput.mState.orientation = kDisplayOrientation;
3417 mOutput.mState.needsFiltering = false;
3418 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003419
Lloyd Piquea4863342019-12-04 18:45:02 -08003420 for (size_t i = 0; i < mLayers.size(); i++) {
3421 mLayers[i].mOutputLayerState.clearClientTarget = false;
3422 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3423 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003424 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003425 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003426 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3427 mLayers[i].mLayerSettings.alpha = 1.0f;
3428 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003429
Lloyd Piquea4863342019-12-04 18:45:02 -08003430 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3431 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3432 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3433 .WillRepeatedly(Return(true));
3434 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3435 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003436
Lloyd Piquea4863342019-12-04 18:45:02 -08003437 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3438 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003439
Lloyd Piquea4863342019-12-04 18:45:02 -08003440 static constexpr uint32_t kDisplayOrientation = TR_IDENT;
3441 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003442
Lloyd Piquea4863342019-12-04 18:45:02 -08003443 static const Rect kDisplayFrame;
3444 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003445 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003446
Lloyd Piquea4863342019-12-04 18:45:02 -08003447 std::array<Layer, 3> mLayers;
3448};
Lloyd Pique56eba802019-08-28 15:45:25 -07003449
Lloyd Piquea4863342019-12-04 18:45:02 -08003450const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3451const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003452const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3453 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003454
Lloyd Piquea4863342019-12-04 18:45:02 -08003455TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3456 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3457 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3458 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003459
Lloyd Piquea4863342019-12-04 18:45:02 -08003460 Region accumClearRegion(Rect(10, 11, 12, 13));
3461 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3462 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003463 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003464 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003465}
3466
Lloyd Piquea4863342019-12-04 18:45:02 -08003467TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3468 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3469 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3470 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3471
3472 Region accumClearRegion(Rect(10, 11, 12, 13));
3473 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3474 accumClearRegion, kDisplayDataspace);
3475 EXPECT_EQ(0u, requests.size());
3476 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3477}
3478
3479TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003480 LayerFE::LayerSettings mShadowSettings;
3481 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003482
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003483 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3484 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3485 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3486 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3487 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3488 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3489 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003490
3491 Region accumClearRegion(Rect(10, 11, 12, 13));
3492 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3493 accumClearRegion, kDisplayDataspace);
3494 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003495 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3496 EXPECT_EQ(mShadowSettings, requests[1]);
3497 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003498
3499 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3500
3501 // Check that a timestamp was set for the layers that generated requests
3502 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3503 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3504 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3505}
3506
3507TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3508 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3509 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3510 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3511 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3512
3513 mLayers[0].mOutputLayerState.clearClientTarget = false;
3514 mLayers[1].mOutputLayerState.clearClientTarget = false;
3515 mLayers[2].mOutputLayerState.clearClientTarget = false;
3516
3517 mLayers[0].mLayerFEState.isOpaque = true;
3518 mLayers[1].mLayerFEState.isOpaque = true;
3519 mLayers[2].mLayerFEState.isOpaque = true;
3520
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003521 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3522 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003523
3524 Region accumClearRegion(Rect(10, 11, 12, 13));
3525 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3526 accumClearRegion, kDisplayDataspace);
3527 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003528 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003529
3530 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3531}
3532
3533TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3534 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3535 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3536 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3537 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3538
3539 mLayers[0].mOutputLayerState.clearClientTarget = true;
3540 mLayers[1].mOutputLayerState.clearClientTarget = true;
3541 mLayers[2].mOutputLayerState.clearClientTarget = true;
3542
3543 mLayers[0].mLayerFEState.isOpaque = false;
3544 mLayers[1].mLayerFEState.isOpaque = false;
3545 mLayers[2].mLayerFEState.isOpaque = false;
3546
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003547 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3548 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003549
3550 Region accumClearRegion(Rect(10, 11, 12, 13));
3551 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3552 accumClearRegion, kDisplayDataspace);
3553 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003554 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003555
3556 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3557}
3558
3559TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003560 // If client composition is performed with some layers set to use device
3561 // composition, device layers after the first layer (device or client) will
3562 // clear the frame buffer if they are opaque and if that layer has a flag
3563 // set to do so. The first layer is skipped as the frame buffer is already
3564 // expected to be clear.
3565
Lloyd Piquea4863342019-12-04 18:45:02 -08003566 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3567 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3568 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003569
Lloyd Piquea4863342019-12-04 18:45:02 -08003570 mLayers[0].mOutputLayerState.clearClientTarget = true;
3571 mLayers[1].mOutputLayerState.clearClientTarget = true;
3572 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003573
Lloyd Piquea4863342019-12-04 18:45:02 -08003574 mLayers[0].mLayerFEState.isOpaque = true;
3575 mLayers[1].mLayerFEState.isOpaque = true;
3576 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003577 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003578 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003579
3580 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3581 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003582 false, /* identity transform */
3583 false, /* needs filtering */
3584 false, /* secure */
3585 false, /* supports protected content */
3586 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003587 kDisplayViewport,
3588 kDisplayDataspace,
3589 false /* realContentIsVisible */,
3590 true /* clearContent */,
3591 };
3592 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3593 Region(kDisplayFrame),
3594 false, /* identity transform */
3595 false, /* needs filtering */
3596 false, /* secure */
3597 false, /* supports protected content */
3598 accumClearRegion,
3599 kDisplayViewport,
3600 kDisplayDataspace,
3601 true /* realContentIsVisible */,
3602 false /* clearContent */,
3603 };
3604
3605 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3606 mBlackoutSettings.source.buffer.buffer = nullptr;
3607 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3608 mBlackoutSettings.alpha = 0.f;
3609 mBlackoutSettings.disableBlending = true;
3610
3611 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3612 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3613 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3614 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3615
Lloyd Piquea4863342019-12-04 18:45:02 -08003616 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3617 accumClearRegion, kDisplayDataspace);
3618 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003619
Lloyd Piquea4863342019-12-04 18:45:02 -08003620 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003621 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003622
Vishnu Nair9b079a22020-01-21 14:36:08 -08003623 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003624
Lloyd Piquea4863342019-12-04 18:45:02 -08003625 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3626}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003627
Lloyd Piquea4863342019-12-04 18:45:02 -08003628TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3629 clippedVisibleRegionUsedToGenerateRequest) {
3630 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3631 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3632 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003633
Lloyd Piquea4863342019-12-04 18:45:02 -08003634 Region accumClearRegion(Rect(10, 11, 12, 13));
3635
3636 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3637 Region(Rect(10, 10, 20, 20)),
3638 false, /* identity transform */
3639 false, /* needs filtering */
3640 false, /* secure */
3641 false, /* supports protected content */
3642 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003643 kDisplayViewport,
3644 kDisplayDataspace,
3645 true /* realContentIsVisible */,
3646 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003647 };
3648 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3649 Region(Rect(0, 0, 30, 30)),
3650 false, /* identity transform */
3651 false, /* needs filtering */
3652 false, /* secure */
3653 false, /* supports protected content */
3654 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003655 kDisplayViewport,
3656 kDisplayDataspace,
3657 true /* realContentIsVisible */,
3658 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003659 };
3660 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3661 Region(Rect(0, 0, 40, 201)),
3662 false, /* identity transform */
3663 false, /* needs filtering */
3664 false, /* secure */
3665 false, /* supports protected content */
3666 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003667 kDisplayViewport,
3668 kDisplayDataspace,
3669 true /* realContentIsVisible */,
3670 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003671 };
3672
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003673 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3674 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3675 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3676 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3677 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3678 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003679
3680 static_cast<void>(
3681 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3682 accumClearRegion, kDisplayDataspace));
3683}
3684
3685TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3686 perLayerNeedsFilteringUsedToGenerateRequests) {
3687 mOutput.mState.needsFiltering = false;
3688 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3689
3690 Region accumClearRegion(Rect(10, 11, 12, 13));
3691
3692 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3693 Region(kDisplayFrame),
3694 false, /* identity transform */
3695 true, /* needs filtering */
3696 false, /* secure */
3697 false, /* supports protected content */
3698 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003699 kDisplayViewport,
3700 kDisplayDataspace,
3701 true /* realContentIsVisible */,
3702 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003703 };
3704 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3705 Region(kDisplayFrame),
3706 false, /* identity transform */
3707 false, /* needs filtering */
3708 false, /* secure */
3709 false, /* supports protected content */
3710 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003711 kDisplayViewport,
3712 kDisplayDataspace,
3713 true /* realContentIsVisible */,
3714 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003715 };
3716 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3717 Region(kDisplayFrame),
3718 false, /* identity transform */
3719 false, /* needs filtering */
3720 false, /* secure */
3721 false, /* supports protected content */
3722 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003723 kDisplayViewport,
3724 kDisplayDataspace,
3725 true /* realContentIsVisible */,
3726 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003727 };
3728
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003729 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3730 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3731 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3732 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3733 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3734 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003735
3736 static_cast<void>(
3737 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3738 accumClearRegion, kDisplayDataspace));
3739}
3740
3741TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3742 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3743 mOutput.mState.needsFiltering = true;
3744 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3745
3746 Region accumClearRegion(Rect(10, 11, 12, 13));
3747
3748 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3749 Region(kDisplayFrame),
3750 false, /* identity transform */
3751 true, /* needs filtering */
3752 false, /* secure */
3753 false, /* supports protected content */
3754 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003755 kDisplayViewport,
3756 kDisplayDataspace,
3757 true /* realContentIsVisible */,
3758 false /* clearContent */,
3759
Lloyd Piquea4863342019-12-04 18:45:02 -08003760 };
3761 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3762 Region(kDisplayFrame),
3763 false, /* identity transform */
3764 true, /* needs filtering */
3765 false, /* secure */
3766 false, /* supports protected content */
3767 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003768 kDisplayViewport,
3769 kDisplayDataspace,
3770 true /* realContentIsVisible */,
3771 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003772 };
3773 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3774 Region(kDisplayFrame),
3775 false, /* identity transform */
3776 true, /* needs filtering */
3777 false, /* secure */
3778 false, /* supports protected content */
3779 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003780 kDisplayViewport,
3781 kDisplayDataspace,
3782 true /* realContentIsVisible */,
3783 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003784 };
3785
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003786 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3787 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3788 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3789 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3790 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3791 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003792
3793 static_cast<void>(
3794 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3795 accumClearRegion, kDisplayDataspace));
3796}
3797
3798TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3799 wholeOutputSecurityUsedToGenerateRequests) {
3800 mOutput.mState.isSecure = true;
3801
3802 Region accumClearRegion(Rect(10, 11, 12, 13));
3803
3804 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3805 Region(kDisplayFrame),
3806 false, /* identity transform */
3807 false, /* needs filtering */
3808 true, /* secure */
3809 false, /* supports protected content */
3810 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003811 kDisplayViewport,
3812 kDisplayDataspace,
3813 true /* realContentIsVisible */,
3814 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003815 };
3816 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3817 Region(kDisplayFrame),
3818 false, /* identity transform */
3819 false, /* needs filtering */
3820 true, /* secure */
3821 false, /* supports protected content */
3822 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003823 kDisplayViewport,
3824 kDisplayDataspace,
3825 true /* realContentIsVisible */,
3826 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003827 };
3828 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3829 Region(kDisplayFrame),
3830 false, /* identity transform */
3831 false, /* needs filtering */
3832 true, /* secure */
3833 false, /* supports protected content */
3834 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003835 kDisplayViewport,
3836 kDisplayDataspace,
3837 true /* realContentIsVisible */,
3838 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003839 };
3840
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003841 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3842 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3843 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3844 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3845 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3846 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003847
3848 static_cast<void>(
3849 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3850 accumClearRegion, kDisplayDataspace));
3851}
3852
3853TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3854 protectedContentSupportUsedToGenerateRequests) {
3855 Region accumClearRegion(Rect(10, 11, 12, 13));
3856
3857 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3858 Region(kDisplayFrame),
3859 false, /* identity transform */
3860 false, /* needs filtering */
3861 false, /* secure */
3862 true, /* supports protected content */
3863 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003864 kDisplayViewport,
3865 kDisplayDataspace,
3866 true /* realContentIsVisible */,
3867 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003868 };
3869 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3870 Region(kDisplayFrame),
3871 false, /* identity transform */
3872 false, /* needs filtering */
3873 false, /* secure */
3874 true, /* supports protected content */
3875 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003876 kDisplayViewport,
3877 kDisplayDataspace,
3878 true /* realContentIsVisible */,
3879 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003880 };
3881 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3882 Region(kDisplayFrame),
3883 false, /* identity transform */
3884 false, /* needs filtering */
3885 false, /* secure */
3886 true, /* supports protected content */
3887 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003888 kDisplayViewport,
3889 kDisplayDataspace,
3890 true /* realContentIsVisible */,
3891 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003892 };
3893
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003894 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3895 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3896 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3897 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3898 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3899 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003900
3901 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3902 accumClearRegion,
3903 kDisplayDataspace));
3904}
3905
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003906TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003907 InjectedLayer layer1;
3908 InjectedLayer layer2;
3909 InjectedLayer layer3;
3910
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003911 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003912 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003913 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003914 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003915 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003916 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003917 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003918
Lloyd Piquede196652020-01-22 17:29:58 -08003919 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003920
Lloyd Piquede196652020-01-22 17:29:58 -08003921 injectOutputLayer(layer1);
3922 injectOutputLayer(layer2);
3923 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003924
3925 mOutput->editState().isEnabled = true;
3926
3927 CompositionRefreshArgs args;
3928 args.updatingGeometryThisFrame = false;
3929 args.devOptForceClientComposition = false;
3930 mOutput->updateAndWriteCompositionState(args);
3931}
3932
Lloyd Piquea4863342019-12-04 18:45:02 -08003933TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3934 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3935 // one layer on the left covering the left side of the output, and one layer
3936 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003937
3938 const Rect kPortraitFrame(0, 0, 1000, 2000);
3939 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003940 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003941 const uint32_t kPortraitOrientation = TR_ROT_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003942 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003943
Lloyd Piquea4863342019-12-04 18:45:02 -08003944 mOutput.mState.frame = kPortraitFrame;
3945 mOutput.mState.viewport = kPortraitViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003946 mOutput.mState.destinationClip = kPortraitDestinationClip;
Lloyd Piquea4863342019-12-04 18:45:02 -08003947 mOutput.mState.transform = ui::Transform{kPortraitOrientation};
3948 mOutput.mState.orientation = kPortraitOrientation;
3949 mOutput.mState.needsFiltering = false;
3950 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003951
Lloyd Piquea4863342019-12-04 18:45:02 -08003952 Layer leftLayer;
3953 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003954
Lloyd Piquea4863342019-12-04 18:45:02 -08003955 leftLayer.mOutputLayerState.clearClientTarget = false;
3956 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3957 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003958 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003959
Lloyd Piquea4863342019-12-04 18:45:02 -08003960 rightLayer.mOutputLayerState.clearClientTarget = false;
3961 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3962 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003963 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003964
3965 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3966 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3967 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3968 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3969 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3970
3971 Region accumClearRegion(Rect(10, 11, 12, 13));
3972
3973 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3974 Region(Rect(0, 0, 1000, 1000)),
3975 false, /* identity transform */
3976 false, /* needs filtering */
3977 true, /* secure */
3978 true, /* supports protected content */
3979 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003980 kPortraitViewport,
3981 kOutputDataspace,
3982 true /* realContentIsVisible */,
3983 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003984 };
3985
3986 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3987 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003988 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
3989 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003990
3991 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
3992 Region(Rect(1000, 0, 2000, 1000)),
3993 false, /* identity transform */
3994 false, /* needs filtering */
3995 true, /* secure */
3996 true, /* supports protected content */
3997 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003998 kPortraitViewport,
3999 kOutputDataspace,
4000 true /* realContentIsVisible */,
4001 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004002 };
4003
4004 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4005 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004006 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4007 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004008
4009 constexpr bool supportsProtectedContent = true;
4010 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4011 accumClearRegion, kOutputDataspace);
4012 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004013 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4014 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004015}
4016
Vishnu Naira483b4a2019-12-12 15:07:52 -08004017TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4018 shadowRegionOnlyVisibleSkipsContentComposition) {
4019 const Rect kContentWithShadow(40, 40, 70, 90);
4020 const Rect kContent(50, 50, 60, 80);
4021 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4022 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4023
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004024 Region accumClearRegion(Rect(10, 11, 12, 13));
4025 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4026 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4027 false, /* identity transform */
4028 false, /* needs filtering */
4029 false, /* secure */
4030 false, /* supports protected content */
4031 accumClearRegion,
4032 kDisplayViewport,
4033 kDisplayDataspace,
4034 false /* realContentIsVisible */,
4035 false /* clearContent */,
4036 };
4037
Vishnu Nair9b079a22020-01-21 14:36:08 -08004038 LayerFE::LayerSettings mShadowSettings;
4039 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004040
4041 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4042 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4043
4044 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4045 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004046 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4047 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004048
Vishnu Naira483b4a2019-12-12 15:07:52 -08004049 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4050 accumClearRegion, kDisplayDataspace);
4051 ASSERT_EQ(1u, requests.size());
4052
Vishnu Nair9b079a22020-01-21 14:36:08 -08004053 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004054}
4055
4056TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4057 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4058 const Rect kContentWithShadow(40, 40, 70, 90);
4059 const Rect kContent(50, 50, 60, 80);
4060 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4061 const Region kPartialContentWithPartialShadowRegion =
4062 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4063
Vishnu Nair9b079a22020-01-21 14:36:08 -08004064 LayerFE::LayerSettings mShadowSettings;
4065 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004066
4067 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4068 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4069
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004070 Region accumClearRegion(Rect(10, 11, 12, 13));
4071 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4072 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
4073 false, /* identity transform */
4074 false, /* needs filtering */
4075 false, /* secure */
4076 false, /* supports protected content */
4077 accumClearRegion,
4078 kDisplayViewport,
4079 kDisplayDataspace,
4080 true /* realContentIsVisible */,
4081 false /* clearContent */,
4082 };
4083
Vishnu Naira483b4a2019-12-12 15:07:52 -08004084 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4085 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004086 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4087 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4088 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004089
Vishnu Naira483b4a2019-12-12 15:07:52 -08004090 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4091 accumClearRegion, kDisplayDataspace);
4092 ASSERT_EQ(2u, requests.size());
4093
Vishnu Nair9b079a22020-01-21 14:36:08 -08004094 EXPECT_EQ(mShadowSettings, requests[0]);
4095 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004096}
4097
Lloyd Pique32cbe282018-10-19 13:09:22 -07004098} // namespace
4099} // namespace android::compositionengine