blob: 57b399a9282fb5a7603a372d55c3474e201379d2 [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
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200139 mOutput->editState().displaySpace.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) {
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200239 const ui::Rotation orientation = ui::ROTATION_90;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240 const Rect frame{1, 2, 3, 4};
241 const Rect viewport{5, 6, 7, 8};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700242
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200243 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200245 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200246 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
247 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700248}
249
Lloyd Pique66d68602019-02-13 14:23:31 -0800250/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200251 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700252 */
253
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200254TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
255 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
256 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
257 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
258 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
259 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
260 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
261 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
262 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
263 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
264 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700265
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200266 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700267
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200268 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700269
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200270 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700271
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200272 const auto state = mOutput->getState();
273
274 const Rect displayRect(newDisplaySize);
275 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
276 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
277 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
278 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
279 EXPECT_EQ(Rect(0, 0, 900, 450), state.orientedDisplaySpace.content);
280 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
281 EXPECT_EQ(displayRect, state.displaySpace.bounds);
282 EXPECT_EQ(Rect(0, 0, 450, 900), state.displaySpace.content);
283 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
284 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
285 EXPECT_EQ(Rect(0, 0, 450, 900), state.framebufferSpace.content);
286 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
287
288 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
289
290 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700291}
292
Lloyd Pique66d68602019-02-13 14:23:31 -0800293/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700294 * Output::setLayerStackFilter()
295 */
296
297TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700298 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700299 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700300
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700301 EXPECT_TRUE(mOutput->getState().layerStackInternal);
302 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700303
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700304 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700305}
306
Lloyd Pique66d68602019-02-13 14:23:31 -0800307/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700308 * Output::setColorTransform
309 */
310
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800311TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700312 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700313
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800314 // If no colorTransformMatrix is set the update should be skipped.
315 CompositionRefreshArgs refreshArgs;
316 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700317
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700318 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700319
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800320 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700321 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800322
323 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700324 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800325}
Lloyd Piqueef958122019-02-05 18:00:12 -0800326
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800327TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700328 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700329
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800330 // Attempting to set the same colorTransformMatrix that is already set should
331 // also skip the update.
332 CompositionRefreshArgs refreshArgs;
333 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700334
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700335 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700336
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800337 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700338 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800339
340 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700341 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800342}
343
344TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700345 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800346
347 // Setting a different colorTransformMatrix should perform the update.
348 CompositionRefreshArgs refreshArgs;
349 refreshArgs.colorTransformMatrix = kIdentity;
350
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700351 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800352
353 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700354 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800355
356 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700357 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800358}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700359
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800360TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700361 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700362
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800363 // Setting a different colorTransformMatrix should perform the update.
364 CompositionRefreshArgs refreshArgs;
365 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700366
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700367 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800368
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800369 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700370 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800371
372 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700373 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800374}
375
376TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700377 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800378
379 // Setting a different colorTransformMatrix should perform the update.
380 CompositionRefreshArgs refreshArgs;
381 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
382
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700383 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800384
385 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700386 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800387
388 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700389 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700390}
391
Lloyd Pique66d68602019-02-13 14:23:31 -0800392/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800393 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700394 */
395
Lloyd Pique17ca7422019-11-14 14:24:10 -0800396using OutputSetColorProfileTest = OutputTest;
397
398TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800399 using ColorProfile = Output::ColorProfile;
400
Lloyd Piquef5275482019-01-29 18:42:42 -0800401 EXPECT_CALL(*mDisplayColorProfile,
402 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
403 ui::Dataspace::UNKNOWN))
404 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800405 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700406
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700407 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
408 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
409 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700410
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700411 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
412 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
413 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
414 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800415
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700416 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800417}
418
Lloyd Pique17ca7422019-11-14 14:24:10 -0800419TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800420 using ColorProfile = Output::ColorProfile;
421
Lloyd Piquef5275482019-01-29 18:42:42 -0800422 EXPECT_CALL(*mDisplayColorProfile,
423 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
424 ui::Dataspace::UNKNOWN))
425 .WillOnce(Return(ui::Dataspace::UNKNOWN));
426
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700427 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
428 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
429 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
430 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800431
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700432 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
433 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
434 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800435
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700436 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700437}
438
Lloyd Pique66d68602019-02-13 14:23:31 -0800439/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700440 * Output::setRenderSurface()
441 */
442
443TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
444 const ui::Size newDisplaySize{640, 480};
445
446 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
447 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
448
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700450
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200451 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700452}
453
Lloyd Pique66d68602019-02-13 14:23:31 -0800454/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000455 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700456 */
457
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000458TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
459 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200460 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700461 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700462
463 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700465
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000466 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700467 }
468}
469
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000470TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
471 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200472 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700474
475 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700477
478 // The dirtyRegion should be clipped to the display bounds.
479 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
480 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700481}
482
Lloyd Pique66d68602019-02-13 14:23:31 -0800483/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800484 * Output::belongsInOutput()
485 */
486
487TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
488 const uint32_t layerStack1 = 123u;
489 const uint32_t layerStack2 = 456u;
490
491 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700492 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800493
Lloyd Piquec6687342019-03-07 21:34:57 -0800494 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
496 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800497
Lloyd Piqueef36b002019-01-23 17:52:04 -0800498 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
500 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
501 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
502 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800503
504 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700505 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800506
507 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700508 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
509 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
510 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
511 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800512}
513
Lloyd Piquede196652020-01-22 17:29:58 -0800514TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
515 NonInjectedLayer layer;
516 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800517
Lloyd Piquede196652020-01-22 17:29:58 -0800518 // If the layer has no composition state, it does not belong to any output.
519 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
520 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
521}
522
523TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
524 NonInjectedLayer layer;
525 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800526
527 const uint32_t layerStack1 = 123u;
528 const uint32_t layerStack2 = 456u;
529
530 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700531 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800532
Lloyd Pique66c20c42019-03-07 21:44:02 -0800533 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800534 layer.layerFEState.layerStackId = std::nullopt;
535 layer.layerFEState.internalOnly = false;
536 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800537
Lloyd Piquede196652020-01-22 17:29:58 -0800538 layer.layerFEState.layerStackId = std::nullopt;
539 layer.layerFEState.internalOnly = true;
540 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800541
542 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800543 layer.layerFEState.layerStackId = layerStack1;
544 layer.layerFEState.internalOnly = false;
545 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800546
Lloyd Piquede196652020-01-22 17:29:58 -0800547 layer.layerFEState.layerStackId = layerStack1;
548 layer.layerFEState.internalOnly = true;
549 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800550
Lloyd Piquede196652020-01-22 17:29:58 -0800551 layer.layerFEState.layerStackId = layerStack2;
552 layer.layerFEState.internalOnly = true;
553 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800554
Lloyd Piquede196652020-01-22 17:29:58 -0800555 layer.layerFEState.layerStackId = layerStack2;
556 layer.layerFEState.internalOnly = false;
557 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800558
559 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700560 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800561
Lloyd Pique66c20c42019-03-07 21:44:02 -0800562 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800563 layer.layerFEState.layerStackId = layerStack1;
564 layer.layerFEState.internalOnly = false;
565 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800566
Lloyd Piquede196652020-01-22 17:29:58 -0800567 layer.layerFEState.layerStackId = layerStack1;
568 layer.layerFEState.internalOnly = true;
569 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800570
Lloyd Piquede196652020-01-22 17:29:58 -0800571 layer.layerFEState.layerStackId = layerStack2;
572 layer.layerFEState.internalOnly = true;
573 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800574
Lloyd Piquede196652020-01-22 17:29:58 -0800575 layer.layerFEState.layerStackId = layerStack2;
576 layer.layerFEState.internalOnly = false;
577 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800578}
579
Lloyd Pique66d68602019-02-13 14:23:31 -0800580/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800581 * Output::getOutputLayerForLayer()
582 */
583
584TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800585 InjectedLayer layer1;
586 InjectedLayer layer2;
587 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800588
Lloyd Piquede196652020-01-22 17:29:58 -0800589 injectOutputLayer(layer1);
590 injectNullOutputLayer();
591 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800592
593 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800594 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
595 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800596
597 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800598 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
599 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
600 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800601
602 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800603 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
604 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
605 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800606}
607
Lloyd Pique66d68602019-02-13 14:23:31 -0800608/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800609 * Output::setReleasedLayers()
610 */
611
612using OutputSetReleasedLayersTest = OutputTest;
613
614TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
615 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
616 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
617 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
618
619 Output::ReleasedLayers layers;
620 layers.push_back(layer1FE);
621 layers.push_back(layer2FE);
622 layers.push_back(layer3FE);
623
624 mOutput->setReleasedLayers(std::move(layers));
625
626 const auto& setLayers = mOutput->getReleasedLayersForTest();
627 ASSERT_EQ(3u, setLayers.size());
628 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
629 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
630 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
631}
632
633/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800634 * Output::updateLayerStateFromFE()
635 */
636
Lloyd Piquede196652020-01-22 17:29:58 -0800637using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800638
639TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
640 CompositionRefreshArgs refreshArgs;
641
642 mOutput->updateLayerStateFromFE(refreshArgs);
643}
644
Lloyd Piquede196652020-01-22 17:29:58 -0800645TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
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.get(), prepareCompositionState(LayerFE::StateSubset::Content));
651 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
652 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
653
654 injectOutputLayer(layer1);
655 injectOutputLayer(layer2);
656 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800657
658 CompositionRefreshArgs refreshArgs;
659 refreshArgs.updatingGeometryThisFrame = false;
660
661 mOutput->updateLayerStateFromFE(refreshArgs);
662}
663
Lloyd Piquede196652020-01-22 17:29:58 -0800664TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
665 InjectedLayer layer1;
666 InjectedLayer layer2;
667 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800668
Lloyd Piquede196652020-01-22 17:29:58 -0800669 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
670 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
671 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
672
673 injectOutputLayer(layer1);
674 injectOutputLayer(layer2);
675 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800676
677 CompositionRefreshArgs refreshArgs;
678 refreshArgs.updatingGeometryThisFrame = true;
679
680 mOutput->updateLayerStateFromFE(refreshArgs);
681}
682
683/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800684 * Output::updateAndWriteCompositionState()
685 */
686
Lloyd Piquede196652020-01-22 17:29:58 -0800687using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800688
689TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
690 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800691
692 CompositionRefreshArgs args;
693 mOutput->updateAndWriteCompositionState(args);
694}
695
Lloyd Piqueef63b612019-11-14 13:19:56 -0800696TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800697 InjectedLayer layer1;
698 InjectedLayer layer2;
699 InjectedLayer layer3;
700
Lloyd Piqueef63b612019-11-14 13:19:56 -0800701 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800702
Lloyd Piquede196652020-01-22 17:29:58 -0800703 injectOutputLayer(layer1);
704 injectOutputLayer(layer2);
705 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800706
707 CompositionRefreshArgs args;
708 mOutput->updateAndWriteCompositionState(args);
709}
710
711TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800712 InjectedLayer layer1;
713 InjectedLayer layer2;
714 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800715
Snild Dolkow9e217d62020-04-22 15:53:42 +0200716 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800717 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200718 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800719 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200720 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Lloyd Piquede196652020-01-22 17:29:58 -0800721 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
722
723 injectOutputLayer(layer1);
724 injectOutputLayer(layer2);
725 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800726
727 mOutput->editState().isEnabled = true;
728
729 CompositionRefreshArgs args;
730 args.updatingGeometryThisFrame = false;
731 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200732 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800733 mOutput->updateAndWriteCompositionState(args);
734}
735
736TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800737 InjectedLayer layer1;
738 InjectedLayer layer2;
739 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800740
Snild Dolkow9e217d62020-04-22 15:53:42 +0200741 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800742 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200743 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800744 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(true));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200745 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800746 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(true));
747
748 injectOutputLayer(layer1);
749 injectOutputLayer(layer2);
750 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800751
752 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800753
754 CompositionRefreshArgs args;
755 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800756 args.devOptForceClientComposition = false;
757 mOutput->updateAndWriteCompositionState(args);
758}
759
760TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800761 InjectedLayer layer1;
762 InjectedLayer layer2;
763 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800764
Snild Dolkow9e217d62020-04-22 15:53:42 +0200765 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800766 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200767 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800768 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200769 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -0800770 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
771
772 injectOutputLayer(layer1);
773 injectOutputLayer(layer2);
774 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800775
776 mOutput->editState().isEnabled = true;
777
778 CompositionRefreshArgs args;
779 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800780 args.devOptForceClientComposition = true;
781 mOutput->updateAndWriteCompositionState(args);
782}
783
784/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800785 * Output::prepareFrame()
786 */
787
788struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800789 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800790 // Sets up the helper functions called by the function under test to use
791 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800792 MOCK_METHOD0(chooseCompositionStrategy, void());
793 };
794
795 OutputPrepareFrameTest() {
796 mOutput.setDisplayColorProfileForTest(
797 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
798 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
799 }
800
801 StrictMock<mock::CompositionEngine> mCompositionEngine;
802 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
803 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700804 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800805};
806
807TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
808 mOutput.editState().isEnabled = false;
809
810 mOutput.prepareFrame();
811}
812
813TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
814 mOutput.editState().isEnabled = true;
815 mOutput.editState().usesClientComposition = false;
816 mOutput.editState().usesDeviceComposition = true;
817
818 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
819 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
820
821 mOutput.prepareFrame();
822}
823
824// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
825// base chooseCompositionStrategy() is invoked.
826TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700827 mOutput->editState().isEnabled = true;
828 mOutput->editState().usesClientComposition = false;
829 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -0800830
831 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
832
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700833 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -0800834
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700835 EXPECT_TRUE(mOutput->getState().usesClientComposition);
836 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -0800837}
838
Lloyd Pique56eba802019-08-28 15:45:25 -0700839/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800840 * Output::prepare()
841 */
842
843struct OutputPrepareTest : public testing::Test {
844 struct OutputPartialMock : public OutputPartialMockBase {
845 // Sets up the helper functions called by the function under test to use
846 // mock implementations.
847 MOCK_METHOD2(rebuildLayerStacks,
848 void(const compositionengine::CompositionRefreshArgs&,
849 compositionengine::LayerFESet&));
850 };
851
852 StrictMock<OutputPartialMock> mOutput;
853 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800854 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800855};
856
857TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
858 InSequence seq;
859 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
860
861 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
862}
863
864/*
865 * Output::rebuildLayerStacks()
866 */
867
868struct OutputRebuildLayerStacksTest : public testing::Test {
869 struct OutputPartialMock : public OutputPartialMockBase {
870 // Sets up the helper functions called by the function under test to use
871 // mock implementations.
872 MOCK_METHOD2(collectVisibleLayers,
873 void(const compositionengine::CompositionRefreshArgs&,
874 compositionengine::Output::CoverageState&));
875 };
876
877 OutputRebuildLayerStacksTest() {
878 mOutput.mState.isEnabled = true;
879 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200880 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800881
882 mRefreshArgs.updatingOutputGeometryThisFrame = true;
883
884 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
885
886 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
887 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
888 }
889
890 void setTestCoverageValues(const CompositionRefreshArgs&,
891 compositionengine::Output::CoverageState& state) {
892 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
893 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
894 state.dirtyRegion = mCoverageDirtyRegionToSet;
895 }
896
897 static const ui::Transform kIdentityTransform;
898 static const ui::Transform kRotate90Transform;
899 static const Rect kOutputBounds;
900
901 StrictMock<OutputPartialMock> mOutput;
902 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -0800903 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -0800904 Region mCoverageAboveCoveredLayersToSet;
905 Region mCoverageAboveOpaqueLayersToSet;
906 Region mCoverageDirtyRegionToSet;
907};
908
909const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
910const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
911const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
912
913TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
914 mOutput.mState.isEnabled = false;
915
916 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
917}
918
919TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
920 mRefreshArgs.updatingOutputGeometryThisFrame = false;
921
922 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
923}
924
925TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
926 mOutput.mState.transform = kIdentityTransform;
927
928 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
929
930 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
931
932 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
933}
934
935TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
936 mOutput.mState.transform = kIdentityTransform;
937
938 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
939
940 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
941
942 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
943}
944
945TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
946 mOutput.mState.transform = kRotate90Transform;
947
948 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
949
950 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
951
952 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
953}
954
955TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
956 mOutput.mState.transform = kRotate90Transform;
957
958 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
959
960 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
961
962 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
963}
964
965TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
966 mOutput.mState.transform = kIdentityTransform;
967 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
968
969 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
970
971 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
972
973 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
974}
975
976TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
977 mOutput.mState.transform = kRotate90Transform;
978 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
979
980 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
981
982 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
983
984 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
985}
986
987/*
988 * Output::collectVisibleLayers()
989 */
990
Lloyd Pique1ef93222019-11-21 16:41:53 -0800991struct OutputCollectVisibleLayersTest : public testing::Test {
992 struct OutputPartialMock : public OutputPartialMockBase {
993 // Sets up the helper functions called by the function under test to use
994 // mock implementations.
995 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -0800996 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -0800997 compositionengine::Output::CoverageState&));
998 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
999 MOCK_METHOD0(finalizePendingOutputLayers, void());
1000 };
1001
1002 struct Layer {
1003 Layer() {
1004 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1005 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1006 }
1007
1008 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001009 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001010 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001011 };
1012
1013 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001014 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001015 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1016 .WillRepeatedly(Return(&mLayer1.outputLayer));
1017 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1018 .WillRepeatedly(Return(&mLayer2.outputLayer));
1019 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1020 .WillRepeatedly(Return(&mLayer3.outputLayer));
1021
Lloyd Piquede196652020-01-22 17:29:58 -08001022 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1023 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1024 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001025 }
1026
1027 StrictMock<OutputPartialMock> mOutput;
1028 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001029 LayerFESet mGeomSnapshots;
1030 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001031 Layer mLayer1;
1032 Layer mLayer2;
1033 Layer mLayer3;
1034};
1035
1036TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1037 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001038 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001039
1040 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1041 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1042
1043 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1044}
1045
1046TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1047 // Enforce a call order sequence for this test.
1048 InSequence seq;
1049
1050 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001051 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1052 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1053 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001054
1055 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1056 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1057
1058 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1059
1060 // Ensure all output layers have been assigned a simple/flattened z-order.
1061 EXPECT_EQ(0u, mLayer1.outputLayerState.z);
1062 EXPECT_EQ(1u, mLayer2.outputLayerState.z);
1063 EXPECT_EQ(2u, mLayer3.outputLayerState.z);
1064}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001065
1066/*
1067 * Output::ensureOutputLayerIfVisible()
1068 */
1069
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001070struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1071 struct OutputPartialMock : public OutputPartialMockBase {
1072 // Sets up the helper functions called by the function under test to use
1073 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001074 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001075 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001076 MOCK_METHOD2(ensureOutputLayer,
1077 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001078 };
1079
1080 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001081 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1082 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001083 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001084 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001085 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001086
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001087 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1088 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001089 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1090
Lloyd Piquede196652020-01-22 17:29:58 -08001091 mLayer.layerFEState.isVisible = true;
1092 mLayer.layerFEState.isOpaque = true;
1093 mLayer.layerFEState.contentDirty = true;
1094 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1095 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1096 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001097
Lloyd Piquede196652020-01-22 17:29:58 -08001098 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1099 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001100
Lloyd Piquede196652020-01-22 17:29:58 -08001101 mGeomSnapshots.insert(mLayer.layerFE);
1102 }
1103
1104 void ensureOutputLayerIfVisible() {
1105 sp<LayerFE> layerFE(mLayer.layerFE);
1106 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001107 }
1108
1109 static const Region kEmptyRegion;
1110 static const Region kFullBoundsNoRotation;
1111 static const Region kRightHalfBoundsNoRotation;
1112 static const Region kLowerHalfBoundsNoRotation;
1113 static const Region kFullBounds90Rotation;
1114
1115 StrictMock<OutputPartialMock> mOutput;
1116 LayerFESet mGeomSnapshots;
1117 Output::CoverageState mCoverageState{mGeomSnapshots};
1118
Lloyd Piquede196652020-01-22 17:29:58 -08001119 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001120};
1121
1122const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1123const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1124 Region(Rect(0, 0, 100, 200));
1125const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1126 Region(Rect(0, 100, 100, 200));
1127const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1128 Region(Rect(50, 0, 100, 200));
1129const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1130 Region(Rect(0, 0, 200, 100));
1131
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001132TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001133 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1134 EXPECT_CALL(*mLayer.layerFE,
1135 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001136
1137 mGeomSnapshots.clear();
1138
Lloyd Piquede196652020-01-22 17:29:58 -08001139 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001140}
1141
1142TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1143 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001144 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001145
Lloyd Piquede196652020-01-22 17:29:58 -08001146 ensureOutputLayerIfVisible();
1147}
1148
1149TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1150 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1151
1152 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001153}
1154
1155TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001156 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001157
Lloyd Piquede196652020-01-22 17:29:58 -08001158 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001159}
1160
1161TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001162 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
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
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001167TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001168 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001169
Lloyd Piquede196652020-01-22 17:29:58 -08001170 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001171}
1172
1173TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1174 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001175 mLayer.layerFEState.isOpaque = true;
1176 mLayer.layerFEState.contentDirty = true;
1177 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001178
1179 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001180 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1181 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001182
Lloyd Piquede196652020-01-22 17:29:58 -08001183 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001184
1185 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1186 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1187 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1188
Lloyd Piquede196652020-01-22 17:29:58 -08001189 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1190 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1191 RegionEq(kFullBoundsNoRotation));
1192 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1193 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001194}
1195
1196TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1197 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001198 mLayer.layerFEState.isOpaque = true;
1199 mLayer.layerFEState.contentDirty = true;
1200 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001201
Lloyd Piquede196652020-01-22 17:29:58 -08001202 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1203 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001204
Lloyd Piquede196652020-01-22 17:29:58 -08001205 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001206
1207 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1208 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1209 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1210
Lloyd Piquede196652020-01-22 17:29:58 -08001211 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1212 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1213 RegionEq(kFullBoundsNoRotation));
1214 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1215 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001216}
1217
1218TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1219 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001220 mLayer.layerFEState.isOpaque = false;
1221 mLayer.layerFEState.contentDirty = true;
1222 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001223
1224 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001225 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1226 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001227
Lloyd Piquede196652020-01-22 17:29:58 -08001228 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001229
1230 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1231 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1232 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1233
Lloyd Piquede196652020-01-22 17:29:58 -08001234 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1235 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001236 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001237 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1238 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001239}
1240
1241TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1242 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001243 mLayer.layerFEState.isOpaque = false;
1244 mLayer.layerFEState.contentDirty = true;
1245 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001246
Lloyd Piquede196652020-01-22 17:29:58 -08001247 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1248 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001249
Lloyd Piquede196652020-01-22 17:29:58 -08001250 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001251
1252 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1253 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1254 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1255
Lloyd Piquede196652020-01-22 17:29:58 -08001256 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1257 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001259 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1260 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001261}
1262
1263TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1264 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001265 mLayer.layerFEState.isOpaque = true;
1266 mLayer.layerFEState.contentDirty = false;
1267 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001268
1269 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001270 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1271 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272
Lloyd Piquede196652020-01-22 17:29:58 -08001273 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274
1275 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1276 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1277 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1278
Lloyd Piquede196652020-01-22 17:29:58 -08001279 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1280 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1281 RegionEq(kFullBoundsNoRotation));
1282 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1283 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284}
1285
1286TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1287 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001288 mLayer.layerFEState.isOpaque = true;
1289 mLayer.layerFEState.contentDirty = false;
1290 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001291
Lloyd Piquede196652020-01-22 17:29:58 -08001292 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1293 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294
Lloyd Piquede196652020-01-22 17:29:58 -08001295 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001296
1297 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1298 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1299 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1300
Lloyd Piquede196652020-01-22 17:29:58 -08001301 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1302 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1303 RegionEq(kFullBoundsNoRotation));
1304 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1305 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001306}
1307
1308TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1309 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001310 mLayer.layerFEState.isOpaque = true;
1311 mLayer.layerFEState.contentDirty = true;
1312 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1313 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1314 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1315 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001316
1317 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001318 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1319 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001320
Lloyd Piquede196652020-01-22 17:29:58 -08001321 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001322
1323 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1324 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1325 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1326
Lloyd Piquede196652020-01-22 17:29:58 -08001327 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1328 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1329 RegionEq(kFullBoundsNoRotation));
1330 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1331 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332}
1333
1334TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1335 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001336 mLayer.layerFEState.isOpaque = true;
1337 mLayer.layerFEState.contentDirty = true;
1338 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1339 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1340 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1341 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1344 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345
Lloyd Piquede196652020-01-22 17:29:58 -08001346 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001347
1348 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1349 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1350 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1351
Lloyd Piquede196652020-01-22 17:29:58 -08001352 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1353 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1354 RegionEq(kFullBoundsNoRotation));
1355 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1356 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357}
1358
1359TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1360 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001361 mLayer.layerFEState.isOpaque = true;
1362 mLayer.layerFEState.contentDirty = true;
1363 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001365 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1367
1368 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001369 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1370 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001371
Lloyd Piquede196652020-01-22 17:29:58 -08001372 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373
1374 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1375 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1376 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1377
Lloyd Piquede196652020-01-22 17:29:58 -08001378 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1379 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1380 RegionEq(kFullBoundsNoRotation));
1381 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1382 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383}
1384
1385TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1386 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001387 mLayer.layerFEState.isOpaque = true;
1388 mLayer.layerFEState.contentDirty = true;
1389 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001391 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001392 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1393
Lloyd Piquede196652020-01-22 17:29:58 -08001394 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1395 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001396
Lloyd Piquede196652020-01-22 17:29:58 -08001397 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001398
1399 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1400 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1401 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1402
Lloyd Piquede196652020-01-22 17:29:58 -08001403 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1404 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1405 RegionEq(kFullBoundsNoRotation));
1406 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1407 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408}
1409
1410TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1411 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1412 ui::Transform arbitraryTransform;
1413 arbitraryTransform.set(1, 1, -1, 1);
1414 arbitraryTransform.set(0, 100);
1415
Lloyd Piquede196652020-01-22 17:29:58 -08001416 mLayer.layerFEState.isOpaque = true;
1417 mLayer.layerFEState.contentDirty = true;
1418 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1419 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420
1421 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001422 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1423 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424
Lloyd Piquede196652020-01-22 17:29:58 -08001425 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
1427 const Region kRegion = Region(Rect(0, 0, 300, 300));
1428 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1429
1430 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1431 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1432 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1435 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1436 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1437 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438}
1439
1440TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001441 mLayer.layerFEState.isOpaque = false;
1442 mLayer.layerFEState.contentDirty = true;
1443 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001444
1445 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1446 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1447 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1448
Lloyd Piquede196652020-01-22 17:29:58 -08001449 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1450 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001451
Lloyd Piquede196652020-01-22 17:29:58 -08001452 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453
1454 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1455 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1456 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1457 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1458 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1459 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1460
1461 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1462 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1463 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1466 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001468 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1469 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1470 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001472
Vishnu Naira483b4a2019-12-12 15:07:52 -08001473TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1474 ui::Transform translate;
1475 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001476 mLayer.layerFEState.geomLayerTransform = translate;
1477 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001478
1479 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1480 // half of the layer including the casting shadow is covered and opaque
1481 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1482 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1483
Lloyd Piquede196652020-01-22 17:29:58 -08001484 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1485 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001486
Lloyd Piquede196652020-01-22 17:29:58 -08001487 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001488
1489 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1490 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1491 // add starting opaque region to the opaque half of the casting layer bounds
1492 const Region kExpectedAboveOpaqueRegion =
1493 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1494 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1495 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1496 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1497 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1498 const Region kExpectedLayerShadowRegion =
1499 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1500
1501 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1502 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1503 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1504
Lloyd Piquede196652020-01-22 17:29:58 -08001505 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1506 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001507 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001508 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1509 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001510 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001511 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001512 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1513}
1514
1515TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1516 ui::Transform translate;
1517 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001518 mLayer.layerFEState.geomLayerTransform = translate;
1519 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001520
1521 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1522 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1523 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1524 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1527 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001528
Lloyd Piquede196652020-01-22 17:29:58 -08001529 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001530
1531 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1532 const Region kExpectedLayerShadowRegion =
1533 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1536 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001537 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1538}
1539
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001540TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001541 ui::Transform translate;
1542 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001543 mLayer.layerFEState.geomLayerTransform = translate;
1544 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001545
1546 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1547 // Casting layer and its shadows are covered by an opaque region
1548 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1549 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001552}
1553
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001554/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001555 * Output::present()
1556 */
1557
1558struct OutputPresentTest : public testing::Test {
1559 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001560 // Sets up the helper functions called by the function under test to use
1561 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001562 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
1563 MOCK_METHOD1(updateAndWriteCompositionState,
1564 void(const compositionengine::CompositionRefreshArgs&));
1565 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1566 MOCK_METHOD0(beginFrame, void());
1567 MOCK_METHOD0(prepareFrame, void());
1568 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1569 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1570 MOCK_METHOD0(postFramebuffer, void());
1571 };
1572
1573 StrictMock<OutputPartialMock> mOutput;
1574};
1575
1576TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1577 CompositionRefreshArgs args;
1578
1579 InSequence seq;
1580 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
1581 EXPECT_CALL(mOutput, updateAndWriteCompositionState(Ref(args)));
1582 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1583 EXPECT_CALL(mOutput, beginFrame());
1584 EXPECT_CALL(mOutput, prepareFrame());
1585 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1586 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1587 EXPECT_CALL(mOutput, postFramebuffer());
1588
1589 mOutput.present(args);
1590}
1591
1592/*
1593 * Output::updateColorProfile()
1594 */
1595
Lloyd Pique17ca7422019-11-14 14:24:10 -08001596struct OutputUpdateColorProfileTest : public testing::Test {
1597 using TestType = OutputUpdateColorProfileTest;
1598
1599 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001600 // Sets up the helper functions called by the function under test to use
1601 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001602 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1603 };
1604
1605 struct Layer {
1606 Layer() {
Lloyd Pique17ca7422019-11-14 14:24:10 -08001607 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001609 }
1610
1611 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Pique17ca7422019-11-14 14:24:10 -08001612 StrictMock<mock::LayerFE> mLayerFE;
1613 LayerFECompositionState mLayerFEState;
1614 };
1615
1616 OutputUpdateColorProfileTest() {
1617 mOutput.setDisplayColorProfileForTest(
1618 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1619 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1620
1621 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1622 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1623 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1624 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1625 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1626 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1627 }
1628
1629 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1630 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1631 };
1632
1633 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1634 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1635 StrictMock<OutputPartialMock> mOutput;
1636
1637 Layer mLayer1;
1638 Layer mLayer2;
1639 Layer mLayer3;
1640
1641 CompositionRefreshArgs mRefreshArgs;
1642};
1643
1644// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1645// to make it easier to write unit tests.
1646
1647TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1648 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1649 // a simple default color profile without looking at anything else.
1650
Lloyd Pique0a456232020-01-16 17:51:13 -08001651 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001652 EXPECT_CALL(mOutput,
1653 setColorProfile(ColorProfileEq(
1654 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1655 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1656
1657 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1658 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1659
1660 mOutput.updateColorProfile(mRefreshArgs);
1661}
1662
1663struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1664 : public OutputUpdateColorProfileTest {
1665 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001666 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001667 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1668 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1669 }
1670
1671 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1672 : public CallOrderStateMachineHelper<
1673 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1674 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1675 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1676 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1677 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1678 _))
1679 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1680 SetArgPointee<4>(renderIntent)));
1681 EXPECT_CALL(getInstance()->mOutput,
1682 setColorProfile(
1683 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1684 ui::Dataspace::UNKNOWN})));
1685 return nextState<ExecuteState>();
1686 }
1687 };
1688
1689 // Call this member function to start using the mini-DSL defined above.
1690 [[nodiscard]] auto verify() {
1691 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1692 }
1693};
1694
1695TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1696 Native_Unknown_Colorimetric_Set) {
1697 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1698 ui::Dataspace::UNKNOWN,
1699 ui::RenderIntent::COLORIMETRIC)
1700 .execute();
1701}
1702
1703TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1704 DisplayP3_DisplayP3_Enhance_Set) {
1705 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1706 ui::Dataspace::DISPLAY_P3,
1707 ui::RenderIntent::ENHANCE)
1708 .execute();
1709}
1710
1711struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1712 : public OutputUpdateColorProfileTest {
1713 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001714 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001715 EXPECT_CALL(*mDisplayColorProfile,
1716 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1717 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1718 SetArgPointee<3>(ui::ColorMode::NATIVE),
1719 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1720 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1721 }
1722
1723 struct IfColorSpaceAgnosticDataspaceSetToState
1724 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1725 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1726 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1727 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1728 }
1729 };
1730
1731 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1732 : public CallOrderStateMachineHelper<
1733 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1734 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1735 ui::Dataspace dataspace) {
1736 EXPECT_CALL(getInstance()->mOutput,
1737 setColorProfile(ColorProfileEq(
1738 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1739 ui::RenderIntent::COLORIMETRIC, dataspace})));
1740 return nextState<ExecuteState>();
1741 }
1742 };
1743
1744 // Call this member function to start using the mini-DSL defined above.
1745 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1746};
1747
1748TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1749 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1750 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1751 .execute();
1752}
1753
1754TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1755 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1756 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1757 .execute();
1758}
1759
1760struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1761 : public OutputUpdateColorProfileTest {
1762 // Internally the implementation looks through the dataspaces of all the
1763 // visible layers. The topmost one that also has an actual dataspace
1764 // preference set is used to drive subsequent choices.
1765
1766 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1767 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1768 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1769
Lloyd Pique0a456232020-01-16 17:51:13 -08001770 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001771 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1772 }
1773
1774 struct IfTopLayerDataspaceState
1775 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1776 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1777 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1778 return nextState<AndIfMiddleLayerDataspaceState>();
1779 }
1780 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1781 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1782 }
1783 };
1784
1785 struct AndIfMiddleLayerDataspaceState
1786 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1787 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1788 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1789 return nextState<AndIfBottomLayerDataspaceState>();
1790 }
1791 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1792 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1793 }
1794 };
1795
1796 struct AndIfBottomLayerDataspaceState
1797 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1798 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1799 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1800 return nextState<ThenExpectBestColorModeCallUsesState>();
1801 }
1802 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1803 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1804 }
1805 };
1806
1807 struct ThenExpectBestColorModeCallUsesState
1808 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1809 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1810 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1811 getBestColorMode(dataspace, _, _, _, _));
1812 return nextState<ExecuteState>();
1813 }
1814 };
1815
1816 // Call this member function to start using the mini-DSL defined above.
1817 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1818};
1819
1820TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1821 noStrongLayerPrefenceUses_V0_SRGB) {
1822 // If none of the layers indicate a preference, then V0_SRGB is the
1823 // preferred choice (subject to additional checks).
1824 verify().ifTopLayerHasNoPreference()
1825 .andIfMiddleLayerHasNoPreference()
1826 .andIfBottomLayerHasNoPreference()
1827 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1828 .execute();
1829}
1830
1831TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1832 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
1833 // If only the topmost layer has a preference, then that is what is chosen.
1834 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1835 .andIfMiddleLayerHasNoPreference()
1836 .andIfBottomLayerHasNoPreference()
1837 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1838 .execute();
1839}
1840
1841TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1842 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
1843 // If only the middle layer has a preference, that that is what is chosen.
1844 verify().ifTopLayerHasNoPreference()
1845 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
1846 .andIfBottomLayerHasNoPreference()
1847 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1848 .execute();
1849}
1850
1851TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1852 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
1853 // If only the middle layer has a preference, that that is what is chosen.
1854 verify().ifTopLayerHasNoPreference()
1855 .andIfMiddleLayerHasNoPreference()
1856 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1857 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1858 .execute();
1859}
1860
1861TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1862 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
1863 // If multiple layers have a preference, the topmost value is what is used.
1864 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
1865 .andIfMiddleLayerHasNoPreference()
1866 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
1867 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1868 .execute();
1869}
1870
1871TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
1872 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
1873 // If multiple layers have a preference, the topmost value is what is used.
1874 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
1875 .andIfMiddleLayerHasNoPreference()
1876 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
1877 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1878 .execute();
1879}
1880
1881struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
1882 : public OutputUpdateColorProfileTest {
1883 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
1884 // values, it overrides the layer dataspace choice.
1885
1886 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
1887 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1888 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1889
1890 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
1891
Lloyd Pique0a456232020-01-16 17:51:13 -08001892 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001893 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1894 }
1895
1896 struct IfForceOutputColorModeState
1897 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
1898 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
1899 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
1900 return nextState<ThenExpectBestColorModeCallUsesState>();
1901 }
1902 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
1903 };
1904
1905 struct ThenExpectBestColorModeCallUsesState
1906 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1907 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1908 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1909 getBestColorMode(dataspace, _, _, _, _));
1910 return nextState<ExecuteState>();
1911 }
1912 };
1913
1914 // Call this member function to start using the mini-DSL defined above.
1915 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
1916};
1917
1918TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
1919 // By default the layer state is used to set the preferred dataspace
1920 verify().ifNoOverride()
1921 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
1922 .execute();
1923}
1924
1925TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
1926 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
1927 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
1928 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
1929 .execute();
1930}
1931
1932TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
1933 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
1934 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
1935 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
1936 .execute();
1937}
1938
1939// HDR output requires all layers to be compatible with the chosen HDR
1940// dataspace, along with there being proper support.
1941struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
1942 OutputUpdateColorProfileTest_Hdr() {
1943 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1944 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08001945 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001946 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1947 }
1948
1949 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
1950 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
1951 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
1952 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
1953
1954 struct IfTopLayerDataspaceState
1955 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1956 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1957 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1958 return nextState<AndTopLayerCompositionTypeState>();
1959 }
1960 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
1961 };
1962
1963 struct AndTopLayerCompositionTypeState
1964 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
1965 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
1966 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
1967 return nextState<AndIfBottomLayerDataspaceState>();
1968 }
1969 };
1970
1971 struct AndIfBottomLayerDataspaceState
1972 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1973 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1974 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1975 return nextState<AndBottomLayerCompositionTypeState>();
1976 }
1977 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
1978 return andIfBottomLayerIs(kNonHdrDataspace);
1979 }
1980 };
1981
1982 struct AndBottomLayerCompositionTypeState
1983 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
1984 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
1985 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
1986 return nextState<AndIfHasLegacySupportState>();
1987 }
1988 };
1989
1990 struct AndIfHasLegacySupportState
1991 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
1992 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
1993 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
1994 .WillOnce(Return(legacySupport));
1995 return nextState<ThenExpectBestColorModeCallUsesState>();
1996 }
1997 };
1998
1999 struct ThenExpectBestColorModeCallUsesState
2000 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2001 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2002 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2003 getBestColorMode(dataspace, _, _, _, _));
2004 return nextState<ExecuteState>();
2005 }
2006 };
2007
2008 // Call this member function to start using the mini-DSL defined above.
2009 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2010};
2011
2012TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2013 // If all layers use BT2020_PQ, and there are no other special conditions,
2014 // BT2020_PQ is used.
2015 verify().ifTopLayerIs(BT2020_PQ)
2016 .andTopLayerIsREComposed(false)
2017 .andIfBottomLayerIs(BT2020_PQ)
2018 .andBottomLayerIsREComposed(false)
2019 .andIfLegacySupportFor(BT2020_PQ, false)
2020 .thenExpectBestColorModeCallUses(BT2020_PQ)
2021 .execute();
2022}
2023
2024TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2025 // BT2020_PQ is not used if there is only legacy support for it.
2026 verify().ifTopLayerIs(BT2020_PQ)
2027 .andTopLayerIsREComposed(false)
2028 .andIfBottomLayerIs(BT2020_PQ)
2029 .andBottomLayerIsREComposed(false)
2030 .andIfLegacySupportFor(BT2020_PQ, true)
2031 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2032 .execute();
2033}
2034
2035TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2036 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2037 verify().ifTopLayerIs(BT2020_PQ)
2038 .andTopLayerIsREComposed(false)
2039 .andIfBottomLayerIs(BT2020_PQ)
2040 .andBottomLayerIsREComposed(true)
2041 .andIfLegacySupportFor(BT2020_PQ, false)
2042 .thenExpectBestColorModeCallUses(BT2020_PQ)
2043 .execute();
2044}
2045
2046TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2047 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2048 verify().ifTopLayerIs(BT2020_PQ)
2049 .andTopLayerIsREComposed(true)
2050 .andIfBottomLayerIs(BT2020_PQ)
2051 .andBottomLayerIsREComposed(false)
2052 .andIfLegacySupportFor(BT2020_PQ, false)
2053 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2054 .execute();
2055}
2056
2057TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2058 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2059 // are no other special conditions.
2060 verify().ifTopLayerIs(BT2020_PQ)
2061 .andTopLayerIsREComposed(false)
2062 .andIfBottomLayerIs(BT2020_HLG)
2063 .andBottomLayerIsREComposed(false)
2064 .andIfLegacySupportFor(BT2020_PQ, false)
2065 .thenExpectBestColorModeCallUses(BT2020_PQ)
2066 .execute();
2067}
2068
2069TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2070 // BT2020_PQ is not used if there is only legacy support for it.
2071 verify().ifTopLayerIs(BT2020_PQ)
2072 .andTopLayerIsREComposed(false)
2073 .andIfBottomLayerIs(BT2020_HLG)
2074 .andBottomLayerIsREComposed(false)
2075 .andIfLegacySupportFor(BT2020_PQ, true)
2076 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2077 .execute();
2078}
2079
2080TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2081 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2082 verify().ifTopLayerIs(BT2020_PQ)
2083 .andTopLayerIsREComposed(false)
2084 .andIfBottomLayerIs(BT2020_HLG)
2085 .andBottomLayerIsREComposed(true)
2086 .andIfLegacySupportFor(BT2020_PQ, false)
2087 .thenExpectBestColorModeCallUses(BT2020_PQ)
2088 .execute();
2089}
2090
2091TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2092 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2093 verify().ifTopLayerIs(BT2020_PQ)
2094 .andTopLayerIsREComposed(true)
2095 .andIfBottomLayerIs(BT2020_HLG)
2096 .andBottomLayerIsREComposed(false)
2097 .andIfLegacySupportFor(BT2020_PQ, false)
2098 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2099 .execute();
2100}
2101
2102TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2103 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2104 // used if there are no other special conditions.
2105 verify().ifTopLayerIs(BT2020_HLG)
2106 .andTopLayerIsREComposed(false)
2107 .andIfBottomLayerIs(BT2020_PQ)
2108 .andBottomLayerIsREComposed(false)
2109 .andIfLegacySupportFor(BT2020_PQ, false)
2110 .thenExpectBestColorModeCallUses(BT2020_PQ)
2111 .execute();
2112}
2113
2114TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2115 // BT2020_PQ is not used if there is only legacy support for it.
2116 verify().ifTopLayerIs(BT2020_HLG)
2117 .andTopLayerIsREComposed(false)
2118 .andIfBottomLayerIs(BT2020_PQ)
2119 .andBottomLayerIsREComposed(false)
2120 .andIfLegacySupportFor(BT2020_PQ, true)
2121 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2122 .execute();
2123}
2124
2125TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2126 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2127 verify().ifTopLayerIs(BT2020_HLG)
2128 .andTopLayerIsREComposed(false)
2129 .andIfBottomLayerIs(BT2020_PQ)
2130 .andBottomLayerIsREComposed(true)
2131 .andIfLegacySupportFor(BT2020_PQ, false)
2132 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2133 .execute();
2134}
2135
2136TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2137 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2138 verify().ifTopLayerIs(BT2020_HLG)
2139 .andTopLayerIsREComposed(true)
2140 .andIfBottomLayerIs(BT2020_PQ)
2141 .andBottomLayerIsREComposed(false)
2142 .andIfLegacySupportFor(BT2020_PQ, false)
2143 .thenExpectBestColorModeCallUses(BT2020_PQ)
2144 .execute();
2145}
2146
2147TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2148 // If all layers use HLG then HLG is used if there are no other special
2149 // conditions.
2150 verify().ifTopLayerIs(BT2020_HLG)
2151 .andTopLayerIsREComposed(false)
2152 .andIfBottomLayerIs(BT2020_HLG)
2153 .andBottomLayerIsREComposed(false)
2154 .andIfLegacySupportFor(BT2020_HLG, false)
2155 .thenExpectBestColorModeCallUses(BT2020_HLG)
2156 .execute();
2157}
2158
2159TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2160 // BT2020_HLG is not used if there is legacy support for it.
2161 verify().ifTopLayerIs(BT2020_HLG)
2162 .andTopLayerIsREComposed(false)
2163 .andIfBottomLayerIs(BT2020_HLG)
2164 .andBottomLayerIsREComposed(false)
2165 .andIfLegacySupportFor(BT2020_HLG, true)
2166 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2167 .execute();
2168}
2169
2170TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2171 // BT2020_HLG is used even if the bottom layer is client composed.
2172 verify().ifTopLayerIs(BT2020_HLG)
2173 .andTopLayerIsREComposed(false)
2174 .andIfBottomLayerIs(BT2020_HLG)
2175 .andBottomLayerIsREComposed(true)
2176 .andIfLegacySupportFor(BT2020_HLG, false)
2177 .thenExpectBestColorModeCallUses(BT2020_HLG)
2178 .execute();
2179}
2180
2181TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2182 // BT2020_HLG is used even if the top layer is client composed.
2183 verify().ifTopLayerIs(BT2020_HLG)
2184 .andTopLayerIsREComposed(true)
2185 .andIfBottomLayerIs(BT2020_HLG)
2186 .andBottomLayerIsREComposed(false)
2187 .andIfLegacySupportFor(BT2020_HLG, false)
2188 .thenExpectBestColorModeCallUses(BT2020_HLG)
2189 .execute();
2190}
2191
2192TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2193 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2194 verify().ifTopLayerIs(BT2020_PQ)
2195 .andTopLayerIsREComposed(false)
2196 .andIfBottomLayerIsNotHdr()
2197 .andBottomLayerIsREComposed(false)
2198 .andIfLegacySupportFor(BT2020_PQ, false)
2199 .thenExpectBestColorModeCallUses(BT2020_PQ)
2200 .execute();
2201}
2202
2203TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2204 // If all layers use HLG then HLG is used if there are no other special
2205 // conditions.
2206 verify().ifTopLayerIs(BT2020_HLG)
2207 .andTopLayerIsREComposed(false)
2208 .andIfBottomLayerIsNotHdr()
2209 .andBottomLayerIsREComposed(true)
2210 .andIfLegacySupportFor(BT2020_HLG, false)
2211 .thenExpectBestColorModeCallUses(BT2020_HLG)
2212 .execute();
2213}
2214
2215struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2216 : public OutputUpdateColorProfileTest {
2217 // The various values for CompositionRefreshArgs::outputColorSetting affect
2218 // the chosen renderIntent, along with whether the preferred dataspace is an
2219 // HDR dataspace or not.
2220
2221 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2222 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2223 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2224 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002225 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002226 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2227 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2228 .WillRepeatedly(Return(false));
2229 }
2230
2231 // The tests here involve enough state and GMock setup that using a mini-DSL
2232 // makes the tests much more readable, and allows the test to focus more on
2233 // the intent than on some of the details.
2234
2235 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2236 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2237
2238 struct IfDataspaceChosenState
2239 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2240 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2241 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2242 return nextState<AndOutputColorSettingState>();
2243 }
2244 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2245 return ifDataspaceChosenIs(kNonHdrDataspace);
2246 }
2247 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2248 };
2249
2250 struct AndOutputColorSettingState
2251 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2252 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2253 getInstance()->mRefreshArgs.outputColorSetting = setting;
2254 return nextState<ThenExpectBestColorModeCallUsesState>();
2255 }
2256 };
2257
2258 struct ThenExpectBestColorModeCallUsesState
2259 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2260 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2261 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2262 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2263 _, _));
2264 return nextState<ExecuteState>();
2265 }
2266 };
2267
2268 // Tests call one of these two helper member functions to start using the
2269 // mini-DSL defined above.
2270 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2271};
2272
2273TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2274 Managed_NonHdr_Prefers_Colorimetric) {
2275 verify().ifDataspaceChosenIsNonHdr()
2276 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2277 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2278 .execute();
2279}
2280
2281TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2282 Managed_Hdr_Prefers_ToneMapColorimetric) {
2283 verify().ifDataspaceChosenIsHdr()
2284 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2285 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2286 .execute();
2287}
2288
2289TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2290 verify().ifDataspaceChosenIsNonHdr()
2291 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2292 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2293 .execute();
2294}
2295
2296TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2297 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2298 verify().ifDataspaceChosenIsHdr()
2299 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2300 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2301 .execute();
2302}
2303
2304TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2305 verify().ifDataspaceChosenIsNonHdr()
2306 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2307 .thenExpectBestColorModeCallUses(
2308 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2309 .execute();
2310}
2311
2312TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2313 verify().ifDataspaceChosenIsHdr()
2314 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2315 .thenExpectBestColorModeCallUses(
2316 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2317 .execute();
2318}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002319
2320/*
2321 * Output::beginFrame()
2322 */
2323
Lloyd Piquee5965952019-11-18 16:16:32 -08002324struct OutputBeginFrameTest : public ::testing::Test {
2325 using TestType = OutputBeginFrameTest;
2326
2327 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002328 // Sets up the helper functions called by the function under test to use
2329 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002330 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2331 };
2332
2333 OutputBeginFrameTest() {
2334 mOutput.setDisplayColorProfileForTest(
2335 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2336 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2337 }
2338
2339 struct IfGetDirtyRegionExpectationState
2340 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2341 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2342 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2343 .WillOnce(Return(dirtyRegion));
2344 return nextState<AndIfGetOutputLayerCountExpectationState>();
2345 }
2346 };
2347
2348 struct AndIfGetOutputLayerCountExpectationState
2349 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2350 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2351 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2352 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2353 }
2354 };
2355
2356 struct AndIfLastCompositionHadVisibleLayersState
2357 : public CallOrderStateMachineHelper<TestType,
2358 AndIfLastCompositionHadVisibleLayersState> {
2359 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2360 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2361 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2362 }
2363 };
2364
2365 struct ThenExpectRenderSurfaceBeginFrameCallState
2366 : public CallOrderStateMachineHelper<TestType,
2367 ThenExpectRenderSurfaceBeginFrameCallState> {
2368 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2369 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2370 return nextState<ExecuteState>();
2371 }
2372 };
2373
2374 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2375 [[nodiscard]] auto execute() {
2376 getInstance()->mOutput.beginFrame();
2377 return nextState<CheckPostconditionHadVisibleLayersState>();
2378 }
2379 };
2380
2381 struct CheckPostconditionHadVisibleLayersState
2382 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2383 void checkPostconditionHadVisibleLayers(bool expected) {
2384 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2385 }
2386 };
2387
2388 // Tests call one of these two helper member functions to start using the
2389 // mini-DSL defined above.
2390 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2391
2392 static const Region kEmptyRegion;
2393 static const Region kNotEmptyRegion;
2394
2395 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2396 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2397 StrictMock<OutputPartialMock> mOutput;
2398};
2399
2400const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2401const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2402
2403TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2404 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2405 .andIfGetOutputLayerCountReturns(1u)
2406 .andIfLastCompositionHadVisibleLayersIs(true)
2407 .thenExpectRenderSurfaceBeginFrameCall(true)
2408 .execute()
2409 .checkPostconditionHadVisibleLayers(true);
2410}
2411
2412TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2413 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2414 .andIfGetOutputLayerCountReturns(0u)
2415 .andIfLastCompositionHadVisibleLayersIs(true)
2416 .thenExpectRenderSurfaceBeginFrameCall(true)
2417 .execute()
2418 .checkPostconditionHadVisibleLayers(false);
2419}
2420
2421TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2422 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2423 .andIfGetOutputLayerCountReturns(1u)
2424 .andIfLastCompositionHadVisibleLayersIs(false)
2425 .thenExpectRenderSurfaceBeginFrameCall(true)
2426 .execute()
2427 .checkPostconditionHadVisibleLayers(true);
2428}
2429
2430TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2431 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2432 .andIfGetOutputLayerCountReturns(0u)
2433 .andIfLastCompositionHadVisibleLayersIs(false)
2434 .thenExpectRenderSurfaceBeginFrameCall(false)
2435 .execute()
2436 .checkPostconditionHadVisibleLayers(false);
2437}
2438
2439TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2440 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2441 .andIfGetOutputLayerCountReturns(1u)
2442 .andIfLastCompositionHadVisibleLayersIs(true)
2443 .thenExpectRenderSurfaceBeginFrameCall(false)
2444 .execute()
2445 .checkPostconditionHadVisibleLayers(true);
2446}
2447
2448TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2449 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2450 .andIfGetOutputLayerCountReturns(0u)
2451 .andIfLastCompositionHadVisibleLayersIs(true)
2452 .thenExpectRenderSurfaceBeginFrameCall(false)
2453 .execute()
2454 .checkPostconditionHadVisibleLayers(true);
2455}
2456
2457TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2458 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2459 .andIfGetOutputLayerCountReturns(1u)
2460 .andIfLastCompositionHadVisibleLayersIs(false)
2461 .thenExpectRenderSurfaceBeginFrameCall(false)
2462 .execute()
2463 .checkPostconditionHadVisibleLayers(false);
2464}
2465
2466TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2467 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2468 .andIfGetOutputLayerCountReturns(0u)
2469 .andIfLastCompositionHadVisibleLayersIs(false)
2470 .thenExpectRenderSurfaceBeginFrameCall(false)
2471 .execute()
2472 .checkPostconditionHadVisibleLayers(false);
2473}
2474
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002475/*
2476 * Output::devOptRepaintFlash()
2477 */
2478
Lloyd Piquedb462d82019-11-19 17:58:46 -08002479struct OutputDevOptRepaintFlashTest : public testing::Test {
2480 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002481 // Sets up the helper functions called by the function under test to use
2482 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002483 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002484 MOCK_METHOD2(composeSurfaces,
2485 std::optional<base::unique_fd>(
2486 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002487 MOCK_METHOD0(postFramebuffer, void());
2488 MOCK_METHOD0(prepareFrame, void());
2489 };
2490
2491 OutputDevOptRepaintFlashTest() {
2492 mOutput.setDisplayColorProfileForTest(
2493 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2494 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2495 }
2496
2497 static const Region kEmptyRegion;
2498 static const Region kNotEmptyRegion;
2499
2500 StrictMock<OutputPartialMock> mOutput;
2501 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2502 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2503 CompositionRefreshArgs mRefreshArgs;
2504};
2505
2506const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2507const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2508
2509TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2510 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2511 mRefreshArgs.repaintEverything = true;
2512 mOutput.mState.isEnabled = true;
2513
2514 mOutput.devOptRepaintFlash(mRefreshArgs);
2515}
2516
2517TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2518 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2519 mRefreshArgs.repaintEverything = true;
2520 mOutput.mState.isEnabled = false;
2521
2522 InSequence seq;
2523 EXPECT_CALL(mOutput, postFramebuffer());
2524 EXPECT_CALL(mOutput, prepareFrame());
2525
2526 mOutput.devOptRepaintFlash(mRefreshArgs);
2527}
2528
2529TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2530 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2531 mRefreshArgs.repaintEverything = true;
2532 mOutput.mState.isEnabled = true;
2533
2534 InSequence seq;
2535 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2536 EXPECT_CALL(mOutput, postFramebuffer());
2537 EXPECT_CALL(mOutput, prepareFrame());
2538
2539 mOutput.devOptRepaintFlash(mRefreshArgs);
2540}
2541
2542TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2543 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2544 mRefreshArgs.repaintEverything = false;
2545 mOutput.mState.isEnabled = true;
2546
2547 InSequence seq;
2548 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002549 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002550 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2551 EXPECT_CALL(mOutput, postFramebuffer());
2552 EXPECT_CALL(mOutput, prepareFrame());
2553
2554 mOutput.devOptRepaintFlash(mRefreshArgs);
2555}
2556
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002557/*
2558 * Output::finishFrame()
2559 */
2560
Lloyd Pique03561a62019-11-19 18:34:52 -08002561struct OutputFinishFrameTest : public testing::Test {
2562 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002563 // Sets up the helper functions called by the function under test to use
2564 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002565 MOCK_METHOD2(composeSurfaces,
2566 std::optional<base::unique_fd>(
2567 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002568 MOCK_METHOD0(postFramebuffer, void());
2569 };
2570
2571 OutputFinishFrameTest() {
2572 mOutput.setDisplayColorProfileForTest(
2573 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2574 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2575 }
2576
2577 StrictMock<OutputPartialMock> mOutput;
2578 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2579 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2580 CompositionRefreshArgs mRefreshArgs;
2581};
2582
2583TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2584 mOutput.mState.isEnabled = false;
2585
2586 mOutput.finishFrame(mRefreshArgs);
2587}
2588
2589TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2590 mOutput.mState.isEnabled = true;
2591
2592 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002593 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002594
2595 mOutput.finishFrame(mRefreshArgs);
2596}
2597
2598TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2599 mOutput.mState.isEnabled = true;
2600
2601 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002602 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002603 .WillOnce(Return(ByMove(base::unique_fd())));
2604 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2605
2606 mOutput.finishFrame(mRefreshArgs);
2607}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002608
2609/*
2610 * Output::postFramebuffer()
2611 */
2612
Lloyd Pique07178e32019-11-19 19:15:26 -08002613struct OutputPostFramebufferTest : public testing::Test {
2614 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002615 // Sets up the helper functions called by the function under test to use
2616 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002617 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2618 };
2619
2620 struct Layer {
2621 Layer() {
2622 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(layerFE));
2623 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2624 }
2625
2626 StrictMock<mock::OutputLayer> outputLayer;
2627 StrictMock<mock::LayerFE> layerFE;
2628 StrictMock<HWC2::mock::Layer> hwc2Layer;
2629 };
2630
2631 OutputPostFramebufferTest() {
2632 mOutput.setDisplayColorProfileForTest(
2633 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2634 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2635
2636 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2637 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2638 .WillRepeatedly(Return(&mLayer1.outputLayer));
2639 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2640 .WillRepeatedly(Return(&mLayer2.outputLayer));
2641 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2642 .WillRepeatedly(Return(&mLayer3.outputLayer));
2643 }
2644
2645 StrictMock<OutputPartialMock> mOutput;
2646 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2647 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2648
2649 Layer mLayer1;
2650 Layer mLayer2;
2651 Layer mLayer3;
2652};
2653
2654TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2655 mOutput.mState.isEnabled = false;
2656
2657 mOutput.postFramebuffer();
2658}
2659
2660TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2661 mOutput.mState.isEnabled = true;
2662
2663 compositionengine::Output::FrameFences frameFences;
2664
2665 // This should happen even if there are no output layers.
2666 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2667
2668 // For this test in particular we want to make sure the call expectations
2669 // setup below are satisfied in the specific order.
2670 InSequence seq;
2671
2672 EXPECT_CALL(*mRenderSurface, flip());
2673 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2674 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2675
2676 mOutput.postFramebuffer();
2677}
2678
2679TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2680 // Simulate getting release fences from each layer, and ensure they are passed to the
2681 // front-end layer interface for each layer correctly.
2682
2683 mOutput.mState.isEnabled = true;
2684
2685 // Create three unique fence instances
2686 sp<Fence> layer1Fence = new Fence();
2687 sp<Fence> layer2Fence = new Fence();
2688 sp<Fence> layer3Fence = new Fence();
2689
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002690 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002691 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2692 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2693 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2694
2695 EXPECT_CALL(*mRenderSurface, flip());
2696 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2697 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2698
2699 // Compare the pointers values of each fence to make sure the correct ones
2700 // are passed. This happens to work with the current implementation, but
2701 // would not survive certain calls like Fence::merge() which would return a
2702 // new instance.
2703 EXPECT_CALL(mLayer1.layerFE,
2704 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
2705 EXPECT_CALL(mLayer2.layerFE,
2706 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
2707 EXPECT_CALL(mLayer3.layerFE,
2708 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2709
2710 mOutput.postFramebuffer();
2711}
2712
2713TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2714 mOutput.mState.isEnabled = true;
2715 mOutput.mState.usesClientComposition = true;
2716
2717 sp<Fence> clientTargetAcquireFence = new Fence();
2718 sp<Fence> layer1Fence = new Fence();
2719 sp<Fence> layer2Fence = new Fence();
2720 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002721 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002722 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2723 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2724 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2725 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2726
2727 EXPECT_CALL(*mRenderSurface, flip());
2728 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2729 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2730
2731 // Fence::merge is called, and since none of the fences are actually valid,
2732 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2733 // This is the best we can do without creating a real kernel fence object.
2734 EXPECT_CALL(mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2735 EXPECT_CALL(mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2736 EXPECT_CALL(mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2737
2738 mOutput.postFramebuffer();
2739}
2740
2741TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2742 mOutput.mState.isEnabled = true;
2743 mOutput.mState.usesClientComposition = true;
2744
2745 // This should happen even if there are no (current) output layers.
2746 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2747
2748 // Load up the released layers with some mock instances
2749 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2750 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2751 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2752 Output::ReleasedLayers layers;
2753 layers.push_back(releasedLayer1);
2754 layers.push_back(releasedLayer2);
2755 layers.push_back(releasedLayer3);
2756 mOutput.setReleasedLayers(std::move(layers));
2757
2758 // Set up a fake present fence
2759 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002760 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002761 frameFences.presentFence = presentFence;
2762
2763 EXPECT_CALL(*mRenderSurface, flip());
2764 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2765 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2766
2767 // Each released layer should be given the presentFence.
2768 EXPECT_CALL(*releasedLayer1,
2769 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2770 EXPECT_CALL(*releasedLayer2,
2771 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2772 EXPECT_CALL(*releasedLayer3,
2773 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2774
2775 mOutput.postFramebuffer();
2776
2777 // After the call the list of released layers should have been cleared.
2778 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2779}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002780
2781/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002782 * Output::composeSurfaces()
2783 */
2784
2785struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002786 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002787
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002788 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002789 // Sets up the helper functions called by the function under test to use
2790 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002791 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002792 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002793 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002794 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002795 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002796 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2797 };
2798
2799 OutputComposeSurfacesTest() {
2800 mOutput.setDisplayColorProfileForTest(
2801 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2802 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002803 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002804
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002805 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2806 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002807 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002808 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002809 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002810 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002811 mOutput.mState.dataspace = kDefaultOutputDataspace;
2812 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2813 mOutput.mState.isSecure = false;
2814 mOutput.mState.needsFiltering = false;
2815 mOutput.mState.usesClientComposition = true;
2816 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002817 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002818 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002819
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002820 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002821 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002822 EXPECT_CALL(mCompositionEngine, getTimeStats())
2823 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002824 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2825 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07002826 }
2827
Lloyd Pique6818fa52019-12-03 12:32:13 -08002828 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2829 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002830 getInstance()->mReadyFence =
2831 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002832 return nextState<FenceCheckState>();
2833 }
2834 };
2835
2836 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
2837 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
2838
2839 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
2840 };
2841
2842 // Call this member function to start using the mini-DSL defined above.
2843 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
2844
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002845 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
2846 static constexpr uint32_t kDefaultOutputOrientationFlags =
2847 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08002848 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
2849 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
2850 static constexpr float kDefaultMaxLuminance = 0.9f;
2851 static constexpr float kDefaultAvgLuminance = 0.7f;
2852 static constexpr float kDefaultMinLuminance = 0.1f;
2853
2854 static const Rect kDefaultOutputFrame;
2855 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002856 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002857 static const mat4 kDefaultColorTransformMat;
2858
2859 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002860 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002861 static const HdrCapabilities kHdrCapabilities;
2862
Lloyd Pique56eba802019-08-28 15:45:25 -07002863 StrictMock<mock::CompositionEngine> mCompositionEngine;
2864 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08002865 // TODO: make this is a proper mock.
2866 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07002867 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2868 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002869 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07002870 sp<GraphicBuffer> mOutputBuffer = new GraphicBuffer();
Lloyd Pique6818fa52019-12-03 12:32:13 -08002871
2872 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07002873};
2874
2875const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
2876const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08002877const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08002878const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002879const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002880const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
2881const HdrCapabilities OutputComposeSurfacesTest::
2882 kHdrCapabilities{{},
2883 OutputComposeSurfacesTest::kDefaultMaxLuminance,
2884 OutputComposeSurfacesTest::kDefaultAvgLuminance,
2885 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07002886
Lloyd Piquea76ce462020-01-14 13:06:37 -08002887TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002888 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002889
Lloyd Piquee9eff972020-05-05 12:36:44 -07002890 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2891
Lloyd Piquea76ce462020-01-14 13:06:37 -08002892 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2893
Lloyd Pique6818fa52019-12-03 12:32:13 -08002894 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07002895}
2896
Lloyd Piquee9eff972020-05-05 12:36:44 -07002897TEST_F(OutputComposeSurfacesTest,
2898 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
2899 mOutput.mState.usesClientComposition = false;
2900 mOutput.mState.flipClientTarget = true;
2901
Lloyd Pique6818fa52019-12-03 12:32:13 -08002902 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07002903
2904 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
2905 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
2906
2907 verify().execute().expectAFenceWasReturned();
2908}
2909
2910TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
2911 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2912
2913 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
2914
2915 verify().execute().expectNoFenceWasReturned();
2916}
2917
2918TEST_F(OutputComposeSurfacesTest,
2919 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
2920 mOutput.mState.usesClientComposition = false;
2921 mOutput.mState.flipClientTarget = true;
2922
2923 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07002924
Lloyd Pique6818fa52019-12-03 12:32:13 -08002925 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07002926
Lloyd Pique6818fa52019-12-03 12:32:13 -08002927 verify().execute().expectNoFenceWasReturned();
2928}
Lloyd Pique56eba802019-08-28 15:45:25 -07002929
Lloyd Pique6818fa52019-12-03 12:32:13 -08002930TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
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>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002936 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2937 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07002938
Lloyd Pique6818fa52019-12-03 12:32:13 -08002939 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2940 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, true, _, _))
2941 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07002942
Lloyd Pique6818fa52019-12-03 12:32:13 -08002943 verify().execute().expectAFenceWasReturned();
2944}
Lloyd Pique56eba802019-08-28 15:45:25 -07002945
Lloyd Pique6818fa52019-12-03 12:32:13 -08002946TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08002947 LayerFE::LayerSettings r1;
2948 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08002949
2950 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2951 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2952
2953 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2954 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2955 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2956 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08002957 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002958 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2959 .WillRepeatedly(
2960 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002961 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002962 clientCompositionLayers.emplace_back(r2);
2963 }));
2964
2965 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002966 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08002967 .WillRepeatedly(Return(NO_ERROR));
2968
2969 verify().execute().expectAFenceWasReturned();
2970}
2971
Vishnu Nair9b079a22020-01-21 14:36:08 -08002972TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
2973 mOutput.cacheClientCompositionRequests(0);
2974 LayerFE::LayerSettings r1;
2975 LayerFE::LayerSettings r2;
2976
2977 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
2978 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
2979
2980 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
2981 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
2982 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
2983 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
2984 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
2985 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
2986 .WillRepeatedly(Return());
2987
2988 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
2989 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
2990 .Times(2)
2991 .WillOnce(Return(NO_ERROR));
2992
2993 verify().execute().expectAFenceWasReturned();
2994 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2995
2996 verify().execute().expectAFenceWasReturned();
2997 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
2998}
2999
3000TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3001 mOutput.cacheClientCompositionRequests(3);
3002 LayerFE::LayerSettings r1;
3003 LayerFE::LayerSettings r2;
3004
3005 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3006 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3007
3008 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3009 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3010 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3011 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3012 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3013 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3014 .WillRepeatedly(Return());
3015
3016 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3017 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3018 .WillOnce(Return(NO_ERROR));
3019 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3020
3021 verify().execute().expectAFenceWasReturned();
3022 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3023
3024 // We do not expect another call to draw layers.
3025 verify().execute().expectAFenceWasReturned();
3026 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3027}
3028
3029TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3030 LayerFE::LayerSettings r1;
3031 LayerFE::LayerSettings r2;
3032
3033 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3034 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3035
3036 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3037 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3038 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3039 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3040 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3041 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3042 .WillRepeatedly(Return());
3043
3044 sp<GraphicBuffer> otherOutputBuffer = new GraphicBuffer();
3045 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3046 .WillOnce(Return(mOutputBuffer))
3047 .WillOnce(Return(otherOutputBuffer));
3048 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3049 .WillRepeatedly(Return(NO_ERROR));
3050
3051 verify().execute().expectAFenceWasReturned();
3052 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3053
3054 verify().execute().expectAFenceWasReturned();
3055 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3056}
3057
3058TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3059 LayerFE::LayerSettings r1;
3060 LayerFE::LayerSettings r2;
3061 LayerFE::LayerSettings r3;
3062
3063 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3064 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3065 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3066
3067 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3068 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3069 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3070 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3071 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3072 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3073 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3074 .WillRepeatedly(Return());
3075
3076 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3077 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
3078 .WillOnce(Return(NO_ERROR));
3079 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, true, _, _))
3080 .WillOnce(Return(NO_ERROR));
3081
3082 verify().execute().expectAFenceWasReturned();
3083 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3084
3085 verify().execute().expectAFenceWasReturned();
3086 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3087}
3088
Lloyd Pique6818fa52019-12-03 12:32:13 -08003089struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3090 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3091 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3092 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003093 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003094 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3095 .WillRepeatedly(Return());
3096 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3097 }
3098
3099 struct MixedCompositionState
3100 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3101 auto ifMixedCompositionIs(bool used) {
3102 getInstance()->mOutput.mState.usesDeviceComposition = used;
3103 return nextState<OutputUsesHdrState>();
3104 }
3105 };
3106
3107 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3108 auto andIfUsesHdr(bool used) {
3109 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3110 .WillOnce(Return(used));
3111 return nextState<SkipColorTransformState>();
3112 }
3113 };
3114
3115 struct SkipColorTransformState
3116 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3117 auto andIfSkipColorTransform(bool skip) {
3118 // May be called zero or one times.
3119 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3120 .WillRepeatedly(Return(skip));
3121 return nextState<ExpectDisplaySettingsState>();
3122 }
3123 };
3124
3125 struct ExpectDisplaySettingsState
3126 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3127 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
3128 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, true, _, _))
3129 .WillOnce(Return(NO_ERROR));
3130 return nextState<ExecuteState>();
3131 }
3132 };
3133
3134 // Call this member function to start using the mini-DSL defined above.
3135 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3136};
3137
3138TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3139 verify().ifMixedCompositionIs(true)
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, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003144 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003145 .execute()
3146 .expectAFenceWasReturned();
3147}
3148
3149TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3150 verify().ifMixedCompositionIs(true)
3151 .andIfUsesHdr(false)
3152 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003153 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003154 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003155 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003156 .execute()
3157 .expectAFenceWasReturned();
3158}
3159
3160TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3161 verify().ifMixedCompositionIs(false)
3162 .andIfUsesHdr(true)
3163 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003164 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003165 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003166 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003167 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003168 .execute()
3169 .expectAFenceWasReturned();
3170}
3171
3172TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3173 verify().ifMixedCompositionIs(false)
3174 .andIfUsesHdr(false)
3175 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003176 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003177 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003178 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003179 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003180 .execute()
3181 .expectAFenceWasReturned();
3182}
3183
3184TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3185 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3186 verify().ifMixedCompositionIs(false)
3187 .andIfUsesHdr(true)
3188 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003189 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003190 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003191 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003192 .execute()
3193 .expectAFenceWasReturned();
3194}
3195
3196struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3197 struct Layer {
3198 Layer() {
Lloyd Piquede196652020-01-22 17:29:58 -08003199 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3200 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003201 }
3202
3203 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquede196652020-01-22 17:29:58 -08003204 StrictMock<mock::LayerFE> mLayerFE;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003205 LayerFECompositionState mLayerFEState;
3206 };
3207
3208 OutputComposeSurfacesTest_HandlesProtectedContent() {
3209 mLayer1.mLayerFEState.hasProtectedContent = false;
3210 mLayer2.mLayerFEState.hasProtectedContent = false;
3211
3212 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3213 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3214 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3215 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3216 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3217
3218 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3219
3220 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3221
3222 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003223 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003224 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3225 .WillRepeatedly(Return());
3226 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3227 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _))
3228 .WillRepeatedly(Return(NO_ERROR));
3229 }
3230
3231 Layer mLayer1;
3232 Layer mLayer2;
3233};
3234
3235TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3236 mOutput.mState.isSecure = false;
3237 mLayer2.mLayerFEState.hasProtectedContent = true;
3238 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3239
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003240 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003241}
3242
3243TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3244 mOutput.mState.isSecure = true;
3245 mLayer2.mLayerFEState.hasProtectedContent = true;
3246 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3247
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003248 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003249}
3250
3251TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3252 mOutput.mState.isSecure = true;
3253 mLayer2.mLayerFEState.hasProtectedContent = false;
3254 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3255 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3256 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3257 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3258 EXPECT_CALL(*mRenderSurface, setProtected(false));
3259
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003260 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003261}
3262
3263TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3264 mOutput.mState.isSecure = true;
3265 mLayer2.mLayerFEState.hasProtectedContent = true;
3266 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3267
3268 // For this test, we also check the call order of key functions.
3269 InSequence seq;
3270
3271 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3272 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3273 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3274 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3275 EXPECT_CALL(*mRenderSurface, setProtected(true));
3276 // Must happen after setting the protected content state.
3277 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3278 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3279
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003280 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003281}
3282
3283TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3284 mOutput.mState.isSecure = true;
3285 mLayer2.mLayerFEState.hasProtectedContent = true;
3286 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3287 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3288 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(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, ifFailsToEnableInRenderEngine) {
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)).WillOnce(Return(false));
3298 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
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
3304TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3305 mOutput.mState.isSecure = true;
3306 mLayer2.mLayerFEState.hasProtectedContent = true;
3307 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3308 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3309 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3310 EXPECT_CALL(*mRenderSurface, setProtected(true));
3311
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003312 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003313}
3314
3315TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3316 mOutput.mState.isSecure = true;
3317 mLayer2.mLayerFEState.hasProtectedContent = true;
3318 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3319 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3320 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3321 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3322
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003323 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003324}
3325
3326struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3327 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3328 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3329 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3330 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3331 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3332 .WillRepeatedly(Return());
3333 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3334 }
3335};
3336
3337TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3338 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3339
3340 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003341 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003342
3343 // For this test, we also check the call order of key functions.
3344 InSequence seq;
3345
3346 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3347 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003348
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003349 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3350}
3351
3352struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3353 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3354 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3355 mLayer.layerFEState.backgroundBlurRadius = 10;
3356 mOutput.editState().isEnabled = true;
3357
Snild Dolkow9e217d62020-04-22 15:53:42 +02003358 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003359 EXPECT_CALL(mLayer.outputLayer, writeStateToHWC(false));
3360 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3361 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
3362 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, true, _, _)).WillOnce(Return(NO_ERROR));
3363 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3364 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3365 .WillRepeatedly(Return(&mLayer.outputLayer));
3366 }
3367
3368 NonInjectedLayer mLayer;
3369 compositionengine::CompositionRefreshArgs mRefreshArgs;
3370};
3371
3372TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3373 mRefreshArgs.blursAreExpensive = true;
3374 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3375
3376 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3377 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3378}
3379
3380TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3381 mRefreshArgs.blursAreExpensive = false;
3382 mOutput.updateAndWriteCompositionState(mRefreshArgs);
3383
3384 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3385 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003386}
3387
3388/*
3389 * Output::generateClientCompositionRequests()
3390 */
3391
3392struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003393 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003394 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003395 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003396 bool supportsProtectedContent, Region& clearRegion,
3397 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003398 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003399 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003400 }
3401 };
3402
Lloyd Piquea4863342019-12-04 18:45:02 -08003403 struct Layer {
3404 Layer() {
3405 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3406 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003407 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(mLayerFE));
Lloyd Piquede196652020-01-22 17:29:58 -08003408 EXPECT_CALL(mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003409 }
3410
3411 StrictMock<mock::OutputLayer> mOutputLayer;
Lloyd Piquea4863342019-12-04 18:45:02 -08003412 StrictMock<mock::LayerFE> mLayerFE;
3413 LayerFECompositionState mLayerFEState;
3414 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003415 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003416 };
3417
Lloyd Pique56eba802019-08-28 15:45:25 -07003418 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003419 mOutput.mState.needsFiltering = false;
3420
Lloyd Pique56eba802019-08-28 15:45:25 -07003421 mOutput.setDisplayColorProfileForTest(
3422 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3423 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3424 }
3425
Lloyd Pique56eba802019-08-28 15:45:25 -07003426 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3427 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003428 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003429};
3430
Lloyd Piquea4863342019-12-04 18:45:02 -08003431struct GenerateClientCompositionRequestsTest_ThreeLayers
3432 : public GenerateClientCompositionRequestsTest {
3433 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003434 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3435 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3436 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003437 mOutput.mState.transform =
3438 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3439 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003440 mOutput.mState.needsFiltering = false;
3441 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003442
Lloyd Piquea4863342019-12-04 18:45:02 -08003443 for (size_t i = 0; i < mLayers.size(); i++) {
3444 mLayers[i].mOutputLayerState.clearClientTarget = false;
3445 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3446 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003447 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003448 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003449 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3450 mLayers[i].mLayerSettings.alpha = 1.0f;
3451 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003452
Lloyd Piquea4863342019-12-04 18:45:02 -08003453 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3454 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3455 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3456 .WillRepeatedly(Return(true));
3457 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3458 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003459
Lloyd Piquea4863342019-12-04 18:45:02 -08003460 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3461 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003462
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003463 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003464 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003465
Lloyd Piquea4863342019-12-04 18:45:02 -08003466 static const Rect kDisplayFrame;
3467 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003468 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003469
Lloyd Piquea4863342019-12-04 18:45:02 -08003470 std::array<Layer, 3> mLayers;
3471};
Lloyd Pique56eba802019-08-28 15:45:25 -07003472
Lloyd Piquea4863342019-12-04 18:45:02 -08003473const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3474const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003475const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3476 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003477
Lloyd Piquea4863342019-12-04 18:45:02 -08003478TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3479 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3480 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3481 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003482
Lloyd Piquea4863342019-12-04 18:45:02 -08003483 Region accumClearRegion(Rect(10, 11, 12, 13));
3484 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3485 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003486 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003487 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003488}
3489
Lloyd Piquea4863342019-12-04 18:45:02 -08003490TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3491 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3492 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3493 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3494
3495 Region accumClearRegion(Rect(10, 11, 12, 13));
3496 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3497 accumClearRegion, kDisplayDataspace);
3498 EXPECT_EQ(0u, requests.size());
3499 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3500}
3501
3502TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003503 LayerFE::LayerSettings mShadowSettings;
3504 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003505
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003506 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(_))
3507 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3508 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(_))
3509 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3510 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3511 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3512 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003513
3514 Region accumClearRegion(Rect(10, 11, 12, 13));
3515 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3516 accumClearRegion, kDisplayDataspace);
3517 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003518 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3519 EXPECT_EQ(mShadowSettings, requests[1]);
3520 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003521
3522 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3523
3524 // Check that a timestamp was set for the layers that generated requests
3525 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3526 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3527 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3528}
3529
3530TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3531 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3532 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3533 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3534 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3535
3536 mLayers[0].mOutputLayerState.clearClientTarget = false;
3537 mLayers[1].mOutputLayerState.clearClientTarget = false;
3538 mLayers[2].mOutputLayerState.clearClientTarget = false;
3539
3540 mLayers[0].mLayerFEState.isOpaque = true;
3541 mLayers[1].mLayerFEState.isOpaque = true;
3542 mLayers[2].mLayerFEState.isOpaque = true;
3543
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003544 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3545 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003546
3547 Region accumClearRegion(Rect(10, 11, 12, 13));
3548 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3549 accumClearRegion, kDisplayDataspace);
3550 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003551 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003552
3553 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3554}
3555
3556TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3557 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3558 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3559 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3560 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3561
3562 mLayers[0].mOutputLayerState.clearClientTarget = true;
3563 mLayers[1].mOutputLayerState.clearClientTarget = true;
3564 mLayers[2].mOutputLayerState.clearClientTarget = true;
3565
3566 mLayers[0].mLayerFEState.isOpaque = false;
3567 mLayers[1].mLayerFEState.isOpaque = false;
3568 mLayers[2].mLayerFEState.isOpaque = false;
3569
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003570 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(_))
3571 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003572
3573 Region accumClearRegion(Rect(10, 11, 12, 13));
3574 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3575 accumClearRegion, kDisplayDataspace);
3576 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003577 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003578
3579 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3580}
3581
3582TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003583 // If client composition is performed with some layers set to use device
3584 // composition, device layers after the first layer (device or client) will
3585 // clear the frame buffer if they are opaque and if that layer has a flag
3586 // set to do so. The first layer is skipped as the frame buffer is already
3587 // expected to be clear.
3588
Lloyd Piquea4863342019-12-04 18:45:02 -08003589 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3590 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3591 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003592
Lloyd Piquea4863342019-12-04 18:45:02 -08003593 mLayers[0].mOutputLayerState.clearClientTarget = true;
3594 mLayers[1].mOutputLayerState.clearClientTarget = true;
3595 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003596
Lloyd Piquea4863342019-12-04 18:45:02 -08003597 mLayers[0].mLayerFEState.isOpaque = true;
3598 mLayers[1].mLayerFEState.isOpaque = true;
3599 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003600 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003601 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003602
3603 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3604 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003605 false, /* needs filtering */
3606 false, /* secure */
3607 false, /* supports protected content */
3608 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003609 kDisplayViewport,
3610 kDisplayDataspace,
3611 false /* realContentIsVisible */,
3612 true /* clearContent */,
3613 };
3614 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3615 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003616 false, /* needs filtering */
3617 false, /* secure */
3618 false, /* supports protected content */
3619 accumClearRegion,
3620 kDisplayViewport,
3621 kDisplayDataspace,
3622 true /* realContentIsVisible */,
3623 false /* clearContent */,
3624 };
3625
3626 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3627 mBlackoutSettings.source.buffer.buffer = nullptr;
3628 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3629 mBlackoutSettings.alpha = 0.f;
3630 mBlackoutSettings.disableBlending = true;
3631
3632 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3633 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
3634 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3635 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3636
Lloyd Piquea4863342019-12-04 18:45:02 -08003637 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3638 accumClearRegion, kDisplayDataspace);
3639 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003640
Lloyd Piquea4863342019-12-04 18:45:02 -08003641 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003642 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003643
Vishnu Nair9b079a22020-01-21 14:36:08 -08003644 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003645
Lloyd Piquea4863342019-12-04 18:45:02 -08003646 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3647}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003648
Lloyd Piquea4863342019-12-04 18:45:02 -08003649TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3650 clippedVisibleRegionUsedToGenerateRequest) {
3651 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3652 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3653 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003654
Lloyd Piquea4863342019-12-04 18:45:02 -08003655 Region accumClearRegion(Rect(10, 11, 12, 13));
3656
3657 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3658 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003659 false, /* needs filtering */
3660 false, /* secure */
3661 false, /* supports protected content */
3662 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003663 kDisplayViewport,
3664 kDisplayDataspace,
3665 true /* realContentIsVisible */,
3666 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003667 };
3668 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3669 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003670 false, /* needs filtering */
3671 false, /* secure */
3672 false, /* supports protected content */
3673 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003674 kDisplayViewport,
3675 kDisplayDataspace,
3676 true /* realContentIsVisible */,
3677 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003678 };
3679 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3680 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003681 false, /* needs filtering */
3682 false, /* secure */
3683 false, /* supports protected content */
3684 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003685 kDisplayViewport,
3686 kDisplayDataspace,
3687 true /* realContentIsVisible */,
3688 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003689 };
3690
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003691 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3692 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3693 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3694 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3695 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3696 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003697
3698 static_cast<void>(
3699 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3700 accumClearRegion, kDisplayDataspace));
3701}
3702
3703TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3704 perLayerNeedsFilteringUsedToGenerateRequests) {
3705 mOutput.mState.needsFiltering = false;
3706 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3707
3708 Region accumClearRegion(Rect(10, 11, 12, 13));
3709
3710 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3711 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003712 true, /* needs filtering */
3713 false, /* secure */
3714 false, /* supports protected content */
3715 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003716 kDisplayViewport,
3717 kDisplayDataspace,
3718 true /* realContentIsVisible */,
3719 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003720 };
3721 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3722 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 false, /* needs filtering */
3724 false, /* secure */
3725 false, /* supports protected content */
3726 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003727 kDisplayViewport,
3728 kDisplayDataspace,
3729 true /* realContentIsVisible */,
3730 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003731 };
3732 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3733 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003734 false, /* needs filtering */
3735 false, /* secure */
3736 false, /* supports protected content */
3737 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003738 kDisplayViewport,
3739 kDisplayDataspace,
3740 true /* realContentIsVisible */,
3741 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003742 };
3743
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003744 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3745 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3746 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3747 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3748 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3749 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003750
3751 static_cast<void>(
3752 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3753 accumClearRegion, kDisplayDataspace));
3754}
3755
3756TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3757 wholeOutputNeedsFilteringUsedToGenerateRequests) {
3758 mOutput.mState.needsFiltering = true;
3759 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3760
3761 Region accumClearRegion(Rect(10, 11, 12, 13));
3762
3763 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3764 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003765 true, /* needs filtering */
3766 false, /* secure */
3767 false, /* supports protected content */
3768 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003769 kDisplayViewport,
3770 kDisplayDataspace,
3771 true /* realContentIsVisible */,
3772 false /* clearContent */,
3773
Lloyd Piquea4863342019-12-04 18:45:02 -08003774 };
3775 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3776 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003777 true, /* needs filtering */
3778 false, /* secure */
3779 false, /* supports protected content */
3780 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003781 kDisplayViewport,
3782 kDisplayDataspace,
3783 true /* realContentIsVisible */,
3784 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003785 };
3786 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3787 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003788 true, /* needs filtering */
3789 false, /* secure */
3790 false, /* supports protected content */
3791 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003792 kDisplayViewport,
3793 kDisplayDataspace,
3794 true /* realContentIsVisible */,
3795 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003796 };
3797
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003798 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3799 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3800 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3801 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3802 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3803 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003804
3805 static_cast<void>(
3806 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3807 accumClearRegion, kDisplayDataspace));
3808}
3809
3810TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3811 wholeOutputSecurityUsedToGenerateRequests) {
3812 mOutput.mState.isSecure = true;
3813
3814 Region accumClearRegion(Rect(10, 11, 12, 13));
3815
3816 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3817 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003818 false, /* needs filtering */
3819 true, /* secure */
3820 false, /* supports protected content */
3821 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003822 kDisplayViewport,
3823 kDisplayDataspace,
3824 true /* realContentIsVisible */,
3825 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003826 };
3827 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3828 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003829 false, /* needs filtering */
3830 true, /* secure */
3831 false, /* supports protected content */
3832 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003833 kDisplayViewport,
3834 kDisplayDataspace,
3835 true /* realContentIsVisible */,
3836 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003837 };
3838 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3839 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003840 false, /* needs filtering */
3841 true, /* secure */
3842 false, /* supports protected content */
3843 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003844 kDisplayViewport,
3845 kDisplayDataspace,
3846 true /* realContentIsVisible */,
3847 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003848 };
3849
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003850 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3851 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3852 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3853 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3854 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3855 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003856
3857 static_cast<void>(
3858 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3859 accumClearRegion, kDisplayDataspace));
3860}
3861
3862TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3863 protectedContentSupportUsedToGenerateRequests) {
3864 Region accumClearRegion(Rect(10, 11, 12, 13));
3865
3866 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3867 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003868 false, /* needs filtering */
3869 false, /* secure */
3870 true, /* supports protected content */
3871 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003872 kDisplayViewport,
3873 kDisplayDataspace,
3874 true /* realContentIsVisible */,
3875 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003876 };
3877 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3878 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003879 false, /* needs filtering */
3880 false, /* secure */
3881 true, /* supports protected content */
3882 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003883 kDisplayViewport,
3884 kDisplayDataspace,
3885 true /* realContentIsVisible */,
3886 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003887 };
3888 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3889 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003890 false, /* needs filtering */
3891 false, /* secure */
3892 true, /* supports protected content */
3893 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003894 kDisplayViewport,
3895 kDisplayDataspace,
3896 true /* realContentIsVisible */,
3897 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003898 };
3899
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003900 EXPECT_CALL(mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
3901 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3902 EXPECT_CALL(mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
3903 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3904 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
3905 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003906
3907 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
3908 accumClearRegion,
3909 kDisplayDataspace));
3910}
3911
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003912TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08003913 InjectedLayer layer1;
3914 InjectedLayer layer2;
3915 InjectedLayer layer3;
3916
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003917 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02003918 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003919 EXPECT_CALL(*layer1.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003920 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003921 EXPECT_CALL(*layer2.outputLayer, writeStateToHWC(false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02003922 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Lloyd Piquede196652020-01-22 17:29:58 -08003923 EXPECT_CALL(*layer3.outputLayer, writeStateToHWC(false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003924
Lloyd Piquede196652020-01-22 17:29:58 -08003925 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003926
Lloyd Piquede196652020-01-22 17:29:58 -08003927 injectOutputLayer(layer1);
3928 injectOutputLayer(layer2);
3929 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08003930
3931 mOutput->editState().isEnabled = true;
3932
3933 CompositionRefreshArgs args;
3934 args.updatingGeometryThisFrame = false;
3935 args.devOptForceClientComposition = false;
3936 mOutput->updateAndWriteCompositionState(args);
3937}
3938
Lloyd Piquea4863342019-12-04 18:45:02 -08003939TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
3940 // In split-screen landscape mode, the screen is rotated 90 degrees, with
3941 // one layer on the left covering the left side of the output, and one layer
3942 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003943
3944 const Rect kPortraitFrame(0, 0, 1000, 2000);
3945 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003946 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003947 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08003948 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003949
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003950 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
3951 mOutput.mState.layerStackSpace.content = kPortraitViewport;
3952 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003953 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
3954 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003955 mOutput.mState.needsFiltering = false;
3956 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003957
Lloyd Piquea4863342019-12-04 18:45:02 -08003958 Layer leftLayer;
3959 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003960
Lloyd Piquea4863342019-12-04 18:45:02 -08003961 leftLayer.mOutputLayerState.clearClientTarget = false;
3962 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
3963 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003964 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003965
Lloyd Piquea4863342019-12-04 18:45:02 -08003966 rightLayer.mOutputLayerState.clearClientTarget = false;
3967 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
3968 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003969 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003970
3971 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3972 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3973 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
3974 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3975 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
3976
3977 Region accumClearRegion(Rect(10, 11, 12, 13));
3978
3979 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
3980 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003981 false, /* needs filtering */
3982 true, /* secure */
3983 true, /* supports protected content */
3984 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003985 kPortraitViewport,
3986 kOutputDataspace,
3987 true /* realContentIsVisible */,
3988 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08003989 };
3990
3991 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
3992 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003993 EXPECT_CALL(leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
3994 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003995
3996 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
3997 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003998 false, /* needs filtering */
3999 true, /* secure */
4000 true, /* supports protected content */
4001 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004002 kPortraitViewport,
4003 kOutputDataspace,
4004 true /* realContentIsVisible */,
4005 false /* clearContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004006 };
4007
4008 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4009 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004010 EXPECT_CALL(rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
4011 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004012
4013 constexpr bool supportsProtectedContent = true;
4014 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4015 accumClearRegion, kOutputDataspace);
4016 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004017 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4018 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004019}
4020
Vishnu Naira483b4a2019-12-12 15:07:52 -08004021TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4022 shadowRegionOnlyVisibleSkipsContentComposition) {
4023 const Rect kContentWithShadow(40, 40, 70, 90);
4024 const Rect kContent(50, 50, 60, 80);
4025 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4026 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4027
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004028 Region accumClearRegion(Rect(10, 11, 12, 13));
4029 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4030 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004031 false, /* needs filtering */
4032 false, /* secure */
4033 false, /* supports protected content */
4034 accumClearRegion,
4035 kDisplayViewport,
4036 kDisplayDataspace,
4037 false /* realContentIsVisible */,
4038 false /* clearContent */,
4039 };
4040
Vishnu Nair9b079a22020-01-21 14:36:08 -08004041 LayerFE::LayerSettings mShadowSettings;
4042 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004043
4044 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4045 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4046
4047 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4048 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004049 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4050 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004051
Vishnu Naira483b4a2019-12-12 15:07:52 -08004052 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4053 accumClearRegion, kDisplayDataspace);
4054 ASSERT_EQ(1u, requests.size());
4055
Vishnu Nair9b079a22020-01-21 14:36:08 -08004056 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004057}
4058
4059TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4060 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4061 const Rect kContentWithShadow(40, 40, 70, 90);
4062 const Rect kContent(50, 50, 60, 80);
4063 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4064 const Region kPartialContentWithPartialShadowRegion =
4065 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4066
Vishnu Nair9b079a22020-01-21 14:36:08 -08004067 LayerFE::LayerSettings mShadowSettings;
4068 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004069
4070 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4071 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4072
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004073 Region accumClearRegion(Rect(10, 11, 12, 13));
4074 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4075 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004076 false, /* needs filtering */
4077 false, /* secure */
4078 false, /* supports protected content */
4079 accumClearRegion,
4080 kDisplayViewport,
4081 kDisplayDataspace,
4082 true /* realContentIsVisible */,
4083 false /* clearContent */,
4084 };
4085
Vishnu Naira483b4a2019-12-12 15:07:52 -08004086 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4087 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004088 EXPECT_CALL(mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
4089 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4090 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004091
Vishnu Naira483b4a2019-12-12 15:07:52 -08004092 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4093 accumClearRegion, kDisplayDataspace);
4094 ASSERT_EQ(2u, requests.size());
4095
Vishnu Nair9b079a22020-01-21 14:36:08 -08004096 EXPECT_EQ(mShadowSettings, requests[0]);
4097 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004098}
4099
Lloyd Pique32cbe282018-10-19 13:09:22 -07004100} // namespace
4101} // namespace android::compositionengine