blob: a904c7df4d786c224f673e5ca298350e3dc5d28c [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
Lloyd Pique17ca7422019-11-14 14:24:10 -080017#include <android-base/stringprintf.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070018#include <compositionengine/LayerFECompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070019#include <compositionengine/impl/Output.h>
Lloyd Pique66d68602019-02-13 14:23:31 -080020#include <compositionengine/impl/OutputCompositionState.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070021#include <compositionengine/impl/OutputLayerCompositionState.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070022#include <compositionengine/mock/CompositionEngine.h>
Lloyd Pique3d0c02e2018-10-19 18:38:12 -070023#include <compositionengine/mock/DisplayColorProfile.h>
Lloyd Piquecc01a452018-12-04 17:24:00 -080024#include <compositionengine/mock/LayerFE.h>
25#include <compositionengine/mock/OutputLayer.h>
Lloyd Pique31cb2942018-10-19 17:23:03 -070026#include <compositionengine/mock/RenderSurface.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070027#include <gtest/gtest.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070028#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070029#include <ui/Rect.h>
30#include <ui/Region.h>
31
Alec Mouria90a5702021-04-16 16:36:21 +000032#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040033#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000034
Lloyd Pique17ca7422019-11-14 14:24:10 -080035#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080036#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070037#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070038#include "TestUtils.h"
Alec Mouria90a5702021-04-16 16:36:21 +000039#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070040
41namespace android::compositionengine {
42namespace {
43
Lloyd Pique56eba802019-08-28 15:45:25 -070044using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080045using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080046using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080047using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080048using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080049using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080050using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080051using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080052using testing::Invoke;
53using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080054using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080055using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080056using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080057using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070058using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070059using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080060using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::StrictMock;
62
Lloyd Pique56eba802019-08-28 15:45:25 -070063constexpr auto TR_IDENT = 0u;
64constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080065constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070066
Lloyd Pique3eb1b212019-03-07 21:15:40 -080067const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080068const mat4 kNonIdentityHalf = mat4() * 0.5f;
69const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080070
Lloyd Pique17ca7422019-11-14 14:24:10 -080071constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
72 static_cast<OutputColorSetting>(0x100);
73
Lloyd Piquefaa3f192019-11-14 14:05:09 -080074struct OutputPartialMockBase : public impl::Output {
75 // compositionengine::Output overrides
76 const OutputCompositionState& getState() const override { return mState; }
77 OutputCompositionState& editState() override { return mState; }
78
79 // Use mocks for all the remaining virtual functions
80 // not implemented by the base implementation class.
81 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
82 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080083 MOCK_METHOD2(ensureOutputLayer,
84 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080085 MOCK_METHOD0(finalizePendingOutputLayers, void());
86 MOCK_METHOD0(clearOutputLayers, void());
87 MOCK_CONST_METHOD1(dumpState, void(std::string&));
88 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080089 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080090 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
91
92 impl::OutputCompositionState mState;
93};
94
Lloyd Piquede196652020-01-22 17:29:58 -080095struct InjectedLayer {
96 InjectedLayer() {
97 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
98 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
99 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
100
101 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800102 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
103 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800104 }
105
106 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
107 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
108 LayerFECompositionState layerFEState;
109 impl::OutputLayerCompositionState outputLayerState;
110};
111
112struct NonInjectedLayer {
113 NonInjectedLayer() {
114 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
115 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
116 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
117
118 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800119 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
120 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800121 }
122
123 mock::OutputLayer outputLayer;
124 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
125 LayerFECompositionState layerFEState;
126 impl::OutputLayerCompositionState outputLayerState;
127};
128
Lloyd Pique66d68602019-02-13 14:23:31 -0800129struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700130 class Output : public impl::Output {
131 public:
132 using impl::Output::injectOutputLayerForTest;
133 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
134 };
135
136 static std::shared_ptr<Output> createOutput(
137 const compositionengine::CompositionEngine& compositionEngine) {
138 return impl::createOutputTemplated<Output>(compositionEngine);
139 }
140
Lloyd Pique31cb2942018-10-19 17:23:03 -0700141 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700142 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700143 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700144 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800145
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200146 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Alec Mouridf6201b2021-06-01 16:20:42 -0700147 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700148 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700149
Lloyd Piquede196652020-01-22 17:29:58 -0800150 void injectOutputLayer(InjectedLayer& layer) {
151 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
152 }
153
154 void injectNullOutputLayer() {
155 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
156 }
157
Lloyd Piqueef958122019-02-05 18:00:12 -0800158 static const Rect kDefaultDisplaySize;
159
Lloyd Pique32cbe282018-10-19 13:09:22 -0700160 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700161 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700162 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700163 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700164 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700165};
166
Lloyd Piqueef958122019-02-05 18:00:12 -0800167const Rect OutputTest::kDefaultDisplaySize{100, 200};
168
Lloyd Pique17ca7422019-11-14 14:24:10 -0800169using ColorProfile = compositionengine::Output::ColorProfile;
170
171void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
172 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
173 toString(profile.mode).c_str(), profile.mode,
174 toString(profile.dataspace).c_str(), profile.dataspace,
175 toString(profile.renderIntent).c_str(), profile.renderIntent,
176 toString(profile.colorSpaceAgnosticDataspace).c_str(),
177 profile.colorSpaceAgnosticDataspace);
178}
179
180// Checks for a ColorProfile match
181MATCHER_P(ColorProfileEq, expected, "") {
182 std::string buf;
183 buf.append("ColorProfiles are not equal\n");
184 dumpColorProfile(expected, buf, "expected value");
185 dumpColorProfile(arg, buf, "actual value");
186 *result_listener << buf;
187
188 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
189 (expected.renderIntent == arg.renderIntent) &&
190 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
191}
192
Lloyd Pique66d68602019-02-13 14:23:31 -0800193/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700194 * Basic construction
195 */
196
Lloyd Pique31cb2942018-10-19 17:23:03 -0700197TEST_F(OutputTest, canInstantiateOutput) {
198 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700199 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700200 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
201
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700202 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203
204 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700205 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700207 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
208
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700209 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700210}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700211
Lloyd Pique66d68602019-02-13 14:23:31 -0800212/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700213 * Output::setCompositionEnabled()
214 */
215
216TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700217 mOutput->editState().isEnabled = true;
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()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223}
224
225TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700226 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700227
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700228 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700229
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700230 EXPECT_TRUE(mOutput->getState().isEnabled);
231 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232}
233
234TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700235 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700236
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700237 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700238
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700239 EXPECT_FALSE(mOutput->getState().isEnabled);
240 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241}
242
Lloyd Pique66d68602019-02-13 14:23:31 -0800243/*
Alec Mouri023c1882021-05-08 16:36:33 -0700244 * Output::setLayerCachingEnabled()
245 */
246
247TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
248 const auto kSize = ui::Size(1, 1);
249 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
250 mOutput->setLayerCachingEnabled(false);
251 mOutput->setLayerCachingEnabled(true);
252
253 EXPECT_TRUE(mOutput->plannerEnabled());
254}
255
256TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
257 const auto kSize = ui::Size(1, 1);
258 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
259 mOutput->setLayerCachingEnabled(true);
260 mOutput->setLayerCachingEnabled(false);
261
262 EXPECT_FALSE(mOutput->plannerEnabled());
263}
264
Alec Mouric773472b2021-05-19 14:29:05 -0700265TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
266 renderengine::mock::RenderEngine renderEngine;
267 const auto kSize = ui::Size(1, 1);
268 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
269 mOutput->setLayerCachingEnabled(true);
270
271 // Inject some layers
272 InjectedLayer layer;
273 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
274 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
275 renderengine::ExternalTexture::Usage::READABLE |
276 renderengine::ExternalTexture::Usage::WRITEABLE);
277 injectOutputLayer(layer);
278 // inject a null layer to check for null exceptions
279 injectNullOutputLayer();
280
281 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
282 mOutput->setLayerCachingEnabled(false);
283 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
284}
285
Alec Mouri023c1882021-05-08 16:36:33 -0700286/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700287 * Output::setProjection()
288 */
289
Marin Shalamanov209ae612020-10-01 00:17:39 +0200290TEST_F(OutputTest, setProjectionWorks) {
291 const Rect displayRect{0, 0, 1000, 2000};
292 mOutput->editState().displaySpace.bounds = displayRect;
293 mOutput->editState().framebufferSpace.bounds = displayRect;
294
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200295 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200296 const Rect frame{50, 60, 100, 100};
297 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700298
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200299 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700300
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200301 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200302 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
303 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200304
305 const auto state = mOutput->getState();
306 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
307 EXPECT_EQ(viewport, state.layerStackSpace.content);
308 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
309
310 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
311 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
312 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
313
314 EXPECT_EQ(displayRect, state.displaySpace.bounds);
315 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
316 EXPECT_EQ(orientation, state.displaySpace.orientation);
317
318 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
319 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
320 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
321
322 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700323
324 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200325}
326
327TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
328 const Rect displayRect{0, 0, 1000, 2000};
329 const Rect framebufferRect{0, 0, 500, 1000};
330 mOutput->editState().displaySpace.bounds = displayRect;
331 mOutput->editState().framebufferSpace.bounds = framebufferRect;
332
333 const ui::Rotation orientation = ui::ROTATION_90;
334 const Rect frame{50, 60, 100, 100};
335 const Rect viewport{10, 20, 30, 40};
336
337 mOutput->setProjection(orientation, viewport, frame);
338
339 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
340 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
341 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
342
343 const auto state = mOutput->getState();
344 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
345 EXPECT_EQ(viewport, state.layerStackSpace.content);
346 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
347
348 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
349 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
350 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
351
352 EXPECT_EQ(displayRect, state.displaySpace.bounds);
353 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
354 EXPECT_EQ(orientation, state.displaySpace.orientation);
355
356 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
357 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
358 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
359
360 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700361}
362
Lloyd Pique66d68602019-02-13 14:23:31 -0800363/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200364 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700365 */
366
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200367TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
368 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
369 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
370 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
371 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
372 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
373 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
374 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
375 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
376 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
377 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700378
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200379 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700380
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200381 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700382
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200383 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700384
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200385 const auto state = mOutput->getState();
386
387 const Rect displayRect(newDisplaySize);
388 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
389 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
390 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200391
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200396 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200397
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200398 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200399 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
400
401 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
402
403 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700404}
405
Lloyd Pique66d68602019-02-13 14:23:31 -0800406/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700407 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700408 */
409
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700410TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
411 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
412 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700413
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700414 const auto& state = mOutput->getState();
415 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
416 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700417
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700418 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700419}
420
Lloyd Pique66d68602019-02-13 14:23:31 -0800421/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700422 * Output::setColorTransform
423 */
424
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800425TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700426 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700427
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800428 // If no colorTransformMatrix is set the update should be skipped.
429 CompositionRefreshArgs refreshArgs;
430 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700431
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700432 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700433
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800434 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700435 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436
437 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700438 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800439}
Lloyd Piqueef958122019-02-05 18:00:12 -0800440
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800441TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700442 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700443
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800444 // Attempting to set the same colorTransformMatrix that is already set should
445 // also skip the update.
446 CompositionRefreshArgs refreshArgs;
447 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700448
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700450
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700452 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800453
454 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700455 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800456}
457
458TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700459 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800460
461 // Setting a different colorTransformMatrix should perform the update.
462 CompositionRefreshArgs refreshArgs;
463 refreshArgs.colorTransformMatrix = kIdentity;
464
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700465 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800466
467 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700468 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800469
470 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700471 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700473
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800474TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700475 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700476
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800477 // Setting a different colorTransformMatrix should perform the update.
478 CompositionRefreshArgs refreshArgs;
479 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700480
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700481 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800482
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700484 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485
486 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700487 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488}
489
490TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700491 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800492
493 // Setting a different colorTransformMatrix should perform the update.
494 CompositionRefreshArgs refreshArgs;
495 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
496
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700497 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800498
499 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700500 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800501
502 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700503 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700504}
505
Lloyd Pique66d68602019-02-13 14:23:31 -0800506/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800507 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700508 */
509
Lloyd Pique17ca7422019-11-14 14:24:10 -0800510using OutputSetColorProfileTest = OutputTest;
511
512TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800513 using ColorProfile = Output::ColorProfile;
514
Lloyd Piquef5275482019-01-29 18:42:42 -0800515 EXPECT_CALL(*mDisplayColorProfile,
516 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
517 ui::Dataspace::UNKNOWN))
518 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800519 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700520
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700521 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
522 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
523 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700524
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700525 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
526 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
527 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
528 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800529
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700530 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800531}
532
Lloyd Pique17ca7422019-11-14 14:24:10 -0800533TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800534 using ColorProfile = Output::ColorProfile;
535
Lloyd Piquef5275482019-01-29 18:42:42 -0800536 EXPECT_CALL(*mDisplayColorProfile,
537 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
538 ui::Dataspace::UNKNOWN))
539 .WillOnce(Return(ui::Dataspace::UNKNOWN));
540
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700541 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
542 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
543 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
544 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800545
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700546 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
547 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
548 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800549
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700550 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700551}
552
Lloyd Pique66d68602019-02-13 14:23:31 -0800553/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700554 * Output::setRenderSurface()
555 */
556
557TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
558 const ui::Size newDisplaySize{640, 480};
559
560 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
561 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
562
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700563 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700564
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200565 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700566}
567
Lloyd Pique66d68602019-02-13 14:23:31 -0800568/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000569 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700570 */
571
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700572TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000573 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200574 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700575 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700576
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700577 // The dirty region should be clipped to the display bounds.
578 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700579}
580
Lloyd Pique66d68602019-02-13 14:23:31 -0800581/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700582 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800583 */
584
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700585TEST_F(OutputTest, layerFiltering) {
586 const ui::LayerStack layerStack1{123u};
587 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800588
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700589 // If the output is associated to layerStack1 and to an internal display...
590 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800591
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700592 // It excludes layers with no layer stack, internal-only or not.
593 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
594 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800595
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700596 // It includes layers on layerStack1, internal-only or not.
597 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
598 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
599 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
600 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800601
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700602 // If the output is associated to layerStack1 but not to an internal display...
603 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800604
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700605 // It includes layers on layerStack1, unless they are internal-only.
606 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
607 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
608 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
609 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800610}
611
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700612TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800613 NonInjectedLayer layer;
614 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800615
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700616 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800617 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700618 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800619}
620
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700621TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800622 NonInjectedLayer layer;
623 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800624
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700625 const ui::LayerStack layerStack1{123u};
626 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800627
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700628 // If the output is associated to layerStack1 and to an internal display...
629 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // It excludes layers with no layer stack, internal-only or not.
632 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
633 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800634
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700635 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
636 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800637
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638 // It includes layers on layerStack1, internal-only or not.
639 layer.layerFEState.outputFilter = {layerStack1, false};
640 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 layer.layerFEState.outputFilter = {layerStack1, true};
643 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800644
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700645 layer.layerFEState.outputFilter = {layerStack2, true};
646 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800647
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700648 layer.layerFEState.outputFilter = {layerStack2, false};
649 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800650
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700651 // If the output is associated to layerStack1 but not to an internal display...
652 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700654 // It includes layers on layerStack1, unless they are internal-only.
655 layer.layerFEState.outputFilter = {layerStack1, false};
656 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800657
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700658 layer.layerFEState.outputFilter = {layerStack1, true};
659 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800660
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 layer.layerFEState.outputFilter = {layerStack2, true};
662 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 layer.layerFEState.outputFilter = {layerStack2, false};
665 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666}
667
Lloyd Pique66d68602019-02-13 14:23:31 -0800668/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800669 * Output::getOutputLayerForLayer()
670 */
671
672TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800673 InjectedLayer layer1;
674 InjectedLayer layer2;
675 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800676
Lloyd Piquede196652020-01-22 17:29:58 -0800677 injectOutputLayer(layer1);
678 injectNullOutputLayer();
679 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800680
681 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800682 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
683 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800684
685 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800686 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
687 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
688 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800689
690 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800691 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
692 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
693 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800694}
695
Lloyd Pique66d68602019-02-13 14:23:31 -0800696/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800697 * Output::setReleasedLayers()
698 */
699
700using OutputSetReleasedLayersTest = OutputTest;
701
702TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
703 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
704 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
705 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
706
707 Output::ReleasedLayers layers;
708 layers.push_back(layer1FE);
709 layers.push_back(layer2FE);
710 layers.push_back(layer3FE);
711
712 mOutput->setReleasedLayers(std::move(layers));
713
714 const auto& setLayers = mOutput->getReleasedLayersForTest();
715 ASSERT_EQ(3u, setLayers.size());
716 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
717 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
718 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
719}
720
721/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800722 * Output::updateLayerStateFromFE()
723 */
724
Lloyd Piquede196652020-01-22 17:29:58 -0800725using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800726
727TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
728 CompositionRefreshArgs refreshArgs;
729
730 mOutput->updateLayerStateFromFE(refreshArgs);
731}
732
Lloyd Piquede196652020-01-22 17:29:58 -0800733TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
734 InjectedLayer layer1;
735 InjectedLayer layer2;
736 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800737
Lloyd Piquede196652020-01-22 17:29:58 -0800738 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
739 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
740 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
741
742 injectOutputLayer(layer1);
743 injectOutputLayer(layer2);
744 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800745
746 CompositionRefreshArgs refreshArgs;
747 refreshArgs.updatingGeometryThisFrame = false;
748
749 mOutput->updateLayerStateFromFE(refreshArgs);
750}
751
Lloyd Piquede196652020-01-22 17:29:58 -0800752TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
753 InjectedLayer layer1;
754 InjectedLayer layer2;
755 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800756
Lloyd Piquede196652020-01-22 17:29:58 -0800757 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
758 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
759 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
760
761 injectOutputLayer(layer1);
762 injectOutputLayer(layer2);
763 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800764
765 CompositionRefreshArgs refreshArgs;
766 refreshArgs.updatingGeometryThisFrame = true;
767
768 mOutput->updateLayerStateFromFE(refreshArgs);
769}
770
771/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800772 * Output::updateAndWriteCompositionState()
773 */
774
Lloyd Piquede196652020-01-22 17:29:58 -0800775using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800776
777TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
778 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800779
780 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800781 mOutput->updateCompositionState(args);
782 mOutput->planComposition();
783 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800784}
785
Lloyd Piqueef63b612019-11-14 13:19:56 -0800786TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800787 InjectedLayer layer1;
788 InjectedLayer layer2;
789 InjectedLayer layer3;
790
Lloyd Piqueef63b612019-11-14 13:19:56 -0800791 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800792
Lloyd Piquede196652020-01-22 17:29:58 -0800793 injectOutputLayer(layer1);
794 injectOutputLayer(layer2);
795 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800796
797 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800798 mOutput->updateCompositionState(args);
799 mOutput->planComposition();
800 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800801}
802
803TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800804 InjectedLayer layer1;
805 InjectedLayer layer2;
806 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800807
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400808 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200809 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800810 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400811 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
812 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200813 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800814 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400815 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
816 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200817 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800818 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400819 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
820 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800821
822 injectOutputLayer(layer1);
823 injectOutputLayer(layer2);
824 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800825
826 mOutput->editState().isEnabled = true;
827
828 CompositionRefreshArgs args;
829 args.updatingGeometryThisFrame = false;
830 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800832 mOutput->updateCompositionState(args);
833 mOutput->planComposition();
834 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800835}
836
837TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800838 InjectedLayer layer1;
839 InjectedLayer layer2;
840 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800841
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400842 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200843 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800844 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400845 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
846 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200847 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800848 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400849 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
850 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200851 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800852 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400853 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
854 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800855
856 injectOutputLayer(layer1);
857 injectOutputLayer(layer2);
858 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800859
860 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800861
862 CompositionRefreshArgs args;
863 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800864 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800865 mOutput->updateCompositionState(args);
866 mOutput->planComposition();
867 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800868}
869
870TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800871 InjectedLayer layer1;
872 InjectedLayer layer2;
873 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800874
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400875 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200876 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800877 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400878 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
879 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200880 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800881 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400882 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
883 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200884 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800885 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400886 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
887 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800888
889 injectOutputLayer(layer1);
890 injectOutputLayer(layer2);
891 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800892
893 mOutput->editState().isEnabled = true;
894
895 CompositionRefreshArgs args;
896 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800897 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800898 mOutput->updateCompositionState(args);
899 mOutput->planComposition();
900 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800901}
902
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400903TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
904 renderengine::mock::RenderEngine renderEngine;
905 InjectedLayer layer0;
906 InjectedLayer layer1;
907 InjectedLayer layer2;
908 InjectedLayer layer3;
909
910 InSequence seq;
911 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
912 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
913 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
914 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
915
916 uint32_t z = 0;
917 EXPECT_CALL(*layer0.outputLayer,
918 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
919 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
920
921 // After calling planComposition (which clears overrideInfo), this test sets
922 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
923 // comes first, setting isPeekingThrough to true and zIsOverridden to true
924 // for it and the following layers.
925 EXPECT_CALL(*layer3.outputLayer,
926 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
927 /*zIsOverridden*/ true, /*isPeekingThrough*/
928 true));
929 EXPECT_CALL(*layer1.outputLayer,
930 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
931 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
932 EXPECT_CALL(*layer2.outputLayer,
933 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
934 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
935
936 injectOutputLayer(layer0);
937 injectOutputLayer(layer1);
938 injectOutputLayer(layer2);
939 injectOutputLayer(layer3);
940
941 mOutput->editState().isEnabled = true;
942
943 CompositionRefreshArgs args;
944 args.updatingGeometryThisFrame = true;
945 args.devOptForceClientComposition = false;
946 mOutput->updateCompositionState(args);
947 mOutput->planComposition();
948
949 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
950 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
951 renderengine::ExternalTexture::Usage::READABLE |
952 renderengine::ExternalTexture::Usage::WRITEABLE);
953 layer1.outputLayerState.overrideInfo.buffer = buffer;
954 layer2.outputLayerState.overrideInfo.buffer = buffer;
955 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
956 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
957
958 mOutput->writeCompositionState(args);
959}
960
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800961/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800962 * Output::prepareFrame()
963 */
964
965struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800966 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800967 // Sets up the helper functions called by the function under test to use
968 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800969 MOCK_METHOD0(chooseCompositionStrategy, void());
970 };
971
972 OutputPrepareFrameTest() {
973 mOutput.setDisplayColorProfileForTest(
974 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
975 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
976 }
977
978 StrictMock<mock::CompositionEngine> mCompositionEngine;
979 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
980 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700981 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800982};
983
984TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
985 mOutput.editState().isEnabled = false;
986
987 mOutput.prepareFrame();
988}
989
990TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
991 mOutput.editState().isEnabled = true;
992 mOutput.editState().usesClientComposition = false;
993 mOutput.editState().usesDeviceComposition = true;
994
995 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700996 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800997 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
998
999 mOutput.prepareFrame();
1000}
1001
1002// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1003// base chooseCompositionStrategy() is invoked.
1004TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001005 mOutput->editState().isEnabled = true;
1006 mOutput->editState().usesClientComposition = false;
1007 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001008
1009 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1010
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001011 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001012
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001013 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1014 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001015}
1016
Lloyd Pique56eba802019-08-28 15:45:25 -07001017/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001018 * Output::prepare()
1019 */
1020
1021struct OutputPrepareTest : public testing::Test {
1022 struct OutputPartialMock : public OutputPartialMockBase {
1023 // Sets up the helper functions called by the function under test to use
1024 // mock implementations.
1025 MOCK_METHOD2(rebuildLayerStacks,
1026 void(const compositionengine::CompositionRefreshArgs&,
1027 compositionengine::LayerFESet&));
1028 };
1029
1030 StrictMock<OutputPartialMock> mOutput;
1031 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001032 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001033};
1034
1035TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1036 InSequence seq;
1037 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1038
1039 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1040}
1041
1042/*
1043 * Output::rebuildLayerStacks()
1044 */
1045
1046struct OutputRebuildLayerStacksTest : public testing::Test {
1047 struct OutputPartialMock : public OutputPartialMockBase {
1048 // Sets up the helper functions called by the function under test to use
1049 // mock implementations.
1050 MOCK_METHOD2(collectVisibleLayers,
1051 void(const compositionengine::CompositionRefreshArgs&,
1052 compositionengine::Output::CoverageState&));
1053 };
1054
1055 OutputRebuildLayerStacksTest() {
1056 mOutput.mState.isEnabled = true;
1057 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001058 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001059
1060 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1061
1062 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1063
1064 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1065 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1066 }
1067
1068 void setTestCoverageValues(const CompositionRefreshArgs&,
1069 compositionengine::Output::CoverageState& state) {
1070 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1071 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1072 state.dirtyRegion = mCoverageDirtyRegionToSet;
1073 }
1074
1075 static const ui::Transform kIdentityTransform;
1076 static const ui::Transform kRotate90Transform;
1077 static const Rect kOutputBounds;
1078
1079 StrictMock<OutputPartialMock> mOutput;
1080 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001081 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001082 Region mCoverageAboveCoveredLayersToSet;
1083 Region mCoverageAboveOpaqueLayersToSet;
1084 Region mCoverageDirtyRegionToSet;
1085};
1086
1087const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1088const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1089const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1090
1091TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1092 mOutput.mState.isEnabled = false;
1093
1094 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1095}
1096
1097TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1098 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1099
1100 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1101}
1102
1103TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1104 mOutput.mState.transform = kIdentityTransform;
1105
1106 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1107
1108 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1109
1110 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1111}
1112
1113TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1114 mOutput.mState.transform = kIdentityTransform;
1115
1116 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1117
1118 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1119
1120 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1121}
1122
1123TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1124 mOutput.mState.transform = kRotate90Transform;
1125
1126 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1127
1128 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1129
1130 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1131}
1132
1133TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1134 mOutput.mState.transform = kRotate90Transform;
1135
1136 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1137
1138 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1139
1140 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1141}
1142
1143TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1144 mOutput.mState.transform = kIdentityTransform;
1145 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1146
1147 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1148
1149 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1150
1151 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1152}
1153
1154TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1155 mOutput.mState.transform = kRotate90Transform;
1156 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1157
1158 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1159
1160 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1161
1162 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1163}
1164
1165/*
1166 * Output::collectVisibleLayers()
1167 */
1168
Lloyd Pique1ef93222019-11-21 16:41:53 -08001169struct OutputCollectVisibleLayersTest : public testing::Test {
1170 struct OutputPartialMock : public OutputPartialMockBase {
1171 // Sets up the helper functions called by the function under test to use
1172 // mock implementations.
1173 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001174 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001175 compositionengine::Output::CoverageState&));
1176 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1177 MOCK_METHOD0(finalizePendingOutputLayers, void());
1178 };
1179
1180 struct Layer {
1181 Layer() {
1182 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1183 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1184 }
1185
1186 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001187 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001188 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001189 };
1190
1191 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001192 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001193 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1194 .WillRepeatedly(Return(&mLayer1.outputLayer));
1195 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1196 .WillRepeatedly(Return(&mLayer2.outputLayer));
1197 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1198 .WillRepeatedly(Return(&mLayer3.outputLayer));
1199
Lloyd Piquede196652020-01-22 17:29:58 -08001200 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1201 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1202 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001203 }
1204
1205 StrictMock<OutputPartialMock> mOutput;
1206 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001207 LayerFESet mGeomSnapshots;
1208 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001209 Layer mLayer1;
1210 Layer mLayer2;
1211 Layer mLayer3;
1212};
1213
1214TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1215 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001216 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001217
1218 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1219 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1220
1221 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1222}
1223
1224TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1225 // Enforce a call order sequence for this test.
1226 InSequence seq;
1227
1228 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001229 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1230 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1231 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001232
1233 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1234 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1235
1236 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001237}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001238
1239/*
1240 * Output::ensureOutputLayerIfVisible()
1241 */
1242
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001243struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1244 struct OutputPartialMock : public OutputPartialMockBase {
1245 // Sets up the helper functions called by the function under test to use
1246 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001247 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1248 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001249 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001250 MOCK_METHOD2(ensureOutputLayer,
1251 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001252 };
1253
1254 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001255 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001256 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001257 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001259 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001260
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001261 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1262 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001263 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1264
Lloyd Piquede196652020-01-22 17:29:58 -08001265 mLayer.layerFEState.isVisible = true;
1266 mLayer.layerFEState.isOpaque = true;
1267 mLayer.layerFEState.contentDirty = true;
1268 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1269 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1270 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001271
Lloyd Piquede196652020-01-22 17:29:58 -08001272 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1273 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001274
Lloyd Piquede196652020-01-22 17:29:58 -08001275 mGeomSnapshots.insert(mLayer.layerFE);
1276 }
1277
1278 void ensureOutputLayerIfVisible() {
1279 sp<LayerFE> layerFE(mLayer.layerFE);
1280 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281 }
1282
1283 static const Region kEmptyRegion;
1284 static const Region kFullBoundsNoRotation;
1285 static const Region kRightHalfBoundsNoRotation;
1286 static const Region kLowerHalfBoundsNoRotation;
1287 static const Region kFullBounds90Rotation;
1288
1289 StrictMock<OutputPartialMock> mOutput;
1290 LayerFESet mGeomSnapshots;
1291 Output::CoverageState mCoverageState{mGeomSnapshots};
1292
Lloyd Piquede196652020-01-22 17:29:58 -08001293 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294};
1295
1296const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1297const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1298 Region(Rect(0, 0, 100, 200));
1299const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1300 Region(Rect(0, 100, 100, 200));
1301const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1302 Region(Rect(50, 0, 100, 200));
1303const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1304 Region(Rect(0, 0, 200, 100));
1305
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001306TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1307 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001308 EXPECT_CALL(*mLayer.layerFE,
1309 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001310
1311 mGeomSnapshots.clear();
1312
Lloyd Piquede196652020-01-22 17:29:58 -08001313 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314}
1315
1316TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001317 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1318 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319
Lloyd Piquede196652020-01-22 17:29:58 -08001320 ensureOutputLayerIfVisible();
1321}
1322
1323TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1324 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1325
1326 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327}
1328
1329TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001330 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001331
Lloyd Piquede196652020-01-22 17:29:58 -08001332 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001333}
1334
1335TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001336 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001337
Lloyd Piquede196652020-01-22 17:29:58 -08001338 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001339}
1340
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001341TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001342 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001343
Lloyd Piquede196652020-01-22 17:29:58 -08001344 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001345}
1346
1347TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1348 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001349 mLayer.layerFEState.isOpaque = true;
1350 mLayer.layerFEState.contentDirty = true;
1351 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
1353 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001354 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1355 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356
Lloyd Piquede196652020-01-22 17:29:58 -08001357 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
1359 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1361 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1362
Lloyd Piquede196652020-01-22 17:29:58 -08001363 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1364 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1365 RegionEq(kFullBoundsNoRotation));
1366 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1367 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368}
1369
1370TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1371 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001372 mLayer.layerFEState.isOpaque = true;
1373 mLayer.layerFEState.contentDirty = true;
1374 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001375
Lloyd Piquede196652020-01-22 17:29:58 -08001376 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1377 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001378
Lloyd Piquede196652020-01-22 17:29:58 -08001379 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001380
1381 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1383 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1384
Lloyd Piquede196652020-01-22 17:29:58 -08001385 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1386 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1387 RegionEq(kFullBoundsNoRotation));
1388 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1389 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390}
1391
1392TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1393 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001394 mLayer.layerFEState.isOpaque = false;
1395 mLayer.layerFEState.contentDirty = true;
1396 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001397
1398 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001399 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1400 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401
Lloyd Piquede196652020-01-22 17:29:58 -08001402 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
1404 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1405 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1406 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1409 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001411 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1412 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001413}
1414
1415TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1416 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001417 mLayer.layerFEState.isOpaque = false;
1418 mLayer.layerFEState.contentDirty = true;
1419 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420
Lloyd Piquede196652020-01-22 17:29:58 -08001421 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1422 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423
Lloyd Piquede196652020-01-22 17:29:58 -08001424 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425
1426 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1427 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1428 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1429
Lloyd Piquede196652020-01-22 17:29:58 -08001430 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1431 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001432 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001433 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1434 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435}
1436
1437TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1438 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001439 mLayer.layerFEState.isOpaque = true;
1440 mLayer.layerFEState.contentDirty = false;
1441 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001442
1443 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001444 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1445 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
Lloyd Piquede196652020-01-22 17:29:58 -08001447 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
1449 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1450 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1451 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1452
Lloyd Piquede196652020-01-22 17:29:58 -08001453 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1454 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1455 RegionEq(kFullBoundsNoRotation));
1456 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1457 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458}
1459
1460TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1461 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001462 mLayer.layerFEState.isOpaque = true;
1463 mLayer.layerFEState.contentDirty = false;
1464 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
Lloyd Piquede196652020-01-22 17:29:58 -08001466 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1467 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001468
Lloyd Piquede196652020-01-22 17:29:58 -08001469 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001470
1471 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1472 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1473 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1474
Lloyd Piquede196652020-01-22 17:29:58 -08001475 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1476 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1477 RegionEq(kFullBoundsNoRotation));
1478 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1479 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480}
1481
1482TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1483 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001484 mLayer.layerFEState.isOpaque = true;
1485 mLayer.layerFEState.contentDirty = true;
1486 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1487 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1488 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1489 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001490
1491 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001492 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1493 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001494
Lloyd Piquede196652020-01-22 17:29:58 -08001495 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001496
1497 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1498 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1499 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1500
Lloyd Piquede196652020-01-22 17:29:58 -08001501 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1502 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1503 RegionEq(kFullBoundsNoRotation));
1504 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1505 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001506}
1507
1508TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1509 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001510 mLayer.layerFEState.isOpaque = true;
1511 mLayer.layerFEState.contentDirty = true;
1512 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1513 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1514 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1515 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001516
Lloyd Piquede196652020-01-22 17:29:58 -08001517 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1518 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
Lloyd Piquede196652020-01-22 17:29:58 -08001520 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
1522 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1524 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1525
Lloyd Piquede196652020-01-22 17:29:58 -08001526 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1527 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1528 RegionEq(kFullBoundsNoRotation));
1529 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1530 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531}
1532
1533TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1534 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001535 mLayer.layerFEState.isOpaque = true;
1536 mLayer.layerFEState.contentDirty = true;
1537 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001538
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001539 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001540 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1541
1542 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001543 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1544 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001545
Lloyd Piquede196652020-01-22 17:29:58 -08001546 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001547
1548 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1551
Lloyd Piquede196652020-01-22 17:29:58 -08001552 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1553 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1554 RegionEq(kFullBoundsNoRotation));
1555 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1556 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001557}
1558
1559TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1560 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001561 mLayer.layerFEState.isOpaque = true;
1562 mLayer.layerFEState.contentDirty = true;
1563 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001564
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001565 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001566 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1567
Lloyd Piquede196652020-01-22 17:29:58 -08001568 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1569 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570
Lloyd Piquede196652020-01-22 17:29:58 -08001571 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572
1573 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1575 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1576
Lloyd Piquede196652020-01-22 17:29:58 -08001577 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1578 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1579 RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1581 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001582}
1583
1584TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1585 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1586 ui::Transform arbitraryTransform;
1587 arbitraryTransform.set(1, 1, -1, 1);
1588 arbitraryTransform.set(0, 100);
1589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 mLayer.layerFEState.isOpaque = true;
1591 mLayer.layerFEState.contentDirty = true;
1592 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1593 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594
1595 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001596 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1597 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001598
Lloyd Piquede196652020-01-22 17:29:58 -08001599 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001600
1601 const Region kRegion = Region(Rect(0, 0, 300, 300));
1602 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1603
1604 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1605 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1606 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1607
Lloyd Piquede196652020-01-22 17:29:58 -08001608 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1609 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1610 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1611 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612}
1613
1614TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001615 mLayer.layerFEState.isOpaque = false;
1616 mLayer.layerFEState.contentDirty = true;
1617 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001618
1619 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1620 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1621 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1624 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625
Lloyd Piquede196652020-01-22 17:29:58 -08001626 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
1628 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1629 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1630 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1631 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1632 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1633 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1634
1635 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1636 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1637 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1640 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001641 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001642 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1643 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1644 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001646
Vishnu Naira483b4a2019-12-12 15:07:52 -08001647TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1648 ui::Transform translate;
1649 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001650 mLayer.layerFEState.geomLayerTransform = translate;
1651 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001652
1653 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1654 // half of the layer including the casting shadow is covered and opaque
1655 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1656 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1657
Lloyd Piquede196652020-01-22 17:29:58 -08001658 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1659 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001660
Lloyd Piquede196652020-01-22 17:29:58 -08001661 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001662
1663 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1664 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1665 // add starting opaque region to the opaque half of the casting layer bounds
1666 const Region kExpectedAboveOpaqueRegion =
1667 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1668 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1669 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1670 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1671 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1672 const Region kExpectedLayerShadowRegion =
1673 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1674
1675 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1676 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1677 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1678
Lloyd Piquede196652020-01-22 17:29:58 -08001679 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1680 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001681 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001682 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1683 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001684 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001685 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001686 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1687}
1688
1689TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1690 ui::Transform translate;
1691 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001692 mLayer.layerFEState.geomLayerTransform = translate;
1693 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001694
1695 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1696 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1697 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1698 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1699
Lloyd Piquede196652020-01-22 17:29:58 -08001700 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1701 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001702
Lloyd Piquede196652020-01-22 17:29:58 -08001703 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001704
1705 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1706 const Region kExpectedLayerShadowRegion =
1707 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1710 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001711 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1712}
1713
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001714TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001715 ui::Transform translate;
1716 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001717 mLayer.layerFEState.geomLayerTransform = translate;
1718 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001719
1720 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1721 // Casting layer and its shadows are covered by an opaque region
1722 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1723 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1724
Lloyd Piquede196652020-01-22 17:29:58 -08001725 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001726}
1727
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001728/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001729 * Output::present()
1730 */
1731
1732struct OutputPresentTest : public testing::Test {
1733 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001734 // Sets up the helper functions called by the function under test to use
1735 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001736 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001737 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001738 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001739 MOCK_METHOD0(planComposition, void());
1740 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001741 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1742 MOCK_METHOD0(beginFrame, void());
1743 MOCK_METHOD0(prepareFrame, void());
1744 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1745 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1746 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001747 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001748 };
1749
1750 StrictMock<OutputPartialMock> mOutput;
1751};
1752
1753TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1754 CompositionRefreshArgs args;
1755
1756 InSequence seq;
1757 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001758 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1759 EXPECT_CALL(mOutput, planComposition());
1760 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001761 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1762 EXPECT_CALL(mOutput, beginFrame());
1763 EXPECT_CALL(mOutput, prepareFrame());
1764 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1765 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1766 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001767 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001768
1769 mOutput.present(args);
1770}
1771
1772/*
1773 * Output::updateColorProfile()
1774 */
1775
Lloyd Pique17ca7422019-11-14 14:24:10 -08001776struct OutputUpdateColorProfileTest : public testing::Test {
1777 using TestType = OutputUpdateColorProfileTest;
1778
1779 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001780 // Sets up the helper functions called by the function under test to use
1781 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001782 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1783 };
1784
1785 struct Layer {
1786 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001787 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1788 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001789 }
1790
1791 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001792 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001793 LayerFECompositionState mLayerFEState;
1794 };
1795
1796 OutputUpdateColorProfileTest() {
1797 mOutput.setDisplayColorProfileForTest(
1798 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1799 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1800
1801 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1802 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1803 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1804 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1805 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1806 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1807 }
1808
1809 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1810 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1811 };
1812
1813 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1814 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1815 StrictMock<OutputPartialMock> mOutput;
1816
1817 Layer mLayer1;
1818 Layer mLayer2;
1819 Layer mLayer3;
1820
1821 CompositionRefreshArgs mRefreshArgs;
1822};
1823
1824// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1825// to make it easier to write unit tests.
1826
1827TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1828 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1829 // a simple default color profile without looking at anything else.
1830
Lloyd Pique0a456232020-01-16 17:51:13 -08001831 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001832 EXPECT_CALL(mOutput,
1833 setColorProfile(ColorProfileEq(
1834 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1835 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1836
1837 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1838 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1839
1840 mOutput.updateColorProfile(mRefreshArgs);
1841}
1842
1843struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1844 : public OutputUpdateColorProfileTest {
1845 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001846 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001847 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1848 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1849 }
1850
1851 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1852 : public CallOrderStateMachineHelper<
1853 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1854 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1855 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1856 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1857 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1858 _))
1859 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1860 SetArgPointee<4>(renderIntent)));
1861 EXPECT_CALL(getInstance()->mOutput,
1862 setColorProfile(
1863 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1864 ui::Dataspace::UNKNOWN})));
1865 return nextState<ExecuteState>();
1866 }
1867 };
1868
1869 // Call this member function to start using the mini-DSL defined above.
1870 [[nodiscard]] auto verify() {
1871 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1872 }
1873};
1874
1875TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1876 Native_Unknown_Colorimetric_Set) {
1877 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1878 ui::Dataspace::UNKNOWN,
1879 ui::RenderIntent::COLORIMETRIC)
1880 .execute();
1881}
1882
1883TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1884 DisplayP3_DisplayP3_Enhance_Set) {
1885 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1886 ui::Dataspace::DISPLAY_P3,
1887 ui::RenderIntent::ENHANCE)
1888 .execute();
1889}
1890
1891struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1892 : public OutputUpdateColorProfileTest {
1893 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001894 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001895 EXPECT_CALL(*mDisplayColorProfile,
1896 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1897 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1898 SetArgPointee<3>(ui::ColorMode::NATIVE),
1899 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1900 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1901 }
1902
1903 struct IfColorSpaceAgnosticDataspaceSetToState
1904 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1905 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1906 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1907 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1908 }
1909 };
1910
1911 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1912 : public CallOrderStateMachineHelper<
1913 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1914 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1915 ui::Dataspace dataspace) {
1916 EXPECT_CALL(getInstance()->mOutput,
1917 setColorProfile(ColorProfileEq(
1918 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1919 ui::RenderIntent::COLORIMETRIC, dataspace})));
1920 return nextState<ExecuteState>();
1921 }
1922 };
1923
1924 // Call this member function to start using the mini-DSL defined above.
1925 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1926};
1927
1928TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1929 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1930 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1931 .execute();
1932}
1933
1934TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1935 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1936 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1937 .execute();
1938}
1939
1940struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1941 : public OutputUpdateColorProfileTest {
1942 // Internally the implementation looks through the dataspaces of all the
1943 // visible layers. The topmost one that also has an actual dataspace
1944 // preference set is used to drive subsequent choices.
1945
1946 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1947 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1948 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1949
Lloyd Pique0a456232020-01-16 17:51:13 -08001950 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001951 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1952 }
1953
1954 struct IfTopLayerDataspaceState
1955 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1956 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1957 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1958 return nextState<AndIfMiddleLayerDataspaceState>();
1959 }
1960 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1961 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1962 }
1963 };
1964
1965 struct AndIfMiddleLayerDataspaceState
1966 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1967 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1968 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1969 return nextState<AndIfBottomLayerDataspaceState>();
1970 }
1971 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1972 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1973 }
1974 };
1975
1976 struct AndIfBottomLayerDataspaceState
1977 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1978 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1979 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1980 return nextState<ThenExpectBestColorModeCallUsesState>();
1981 }
1982 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1983 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1984 }
1985 };
1986
1987 struct ThenExpectBestColorModeCallUsesState
1988 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1989 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1990 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1991 getBestColorMode(dataspace, _, _, _, _));
1992 return nextState<ExecuteState>();
1993 }
1994 };
1995
1996 // Call this member function to start using the mini-DSL defined above.
1997 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1998};
1999
2000TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2001 noStrongLayerPrefenceUses_V0_SRGB) {
2002 // If none of the layers indicate a preference, then V0_SRGB is the
2003 // preferred choice (subject to additional checks).
2004 verify().ifTopLayerHasNoPreference()
2005 .andIfMiddleLayerHasNoPreference()
2006 .andIfBottomLayerHasNoPreference()
2007 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2008 .execute();
2009}
2010
2011TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2012 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2013 // If only the topmost layer has a preference, then that is what is chosen.
2014 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2015 .andIfMiddleLayerHasNoPreference()
2016 .andIfBottomLayerHasNoPreference()
2017 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2018 .execute();
2019}
2020
2021TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2022 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2023 // If only the middle layer has a preference, that that is what is chosen.
2024 verify().ifTopLayerHasNoPreference()
2025 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2026 .andIfBottomLayerHasNoPreference()
2027 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2028 .execute();
2029}
2030
2031TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2032 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2033 // If only the middle layer has a preference, that that is what is chosen.
2034 verify().ifTopLayerHasNoPreference()
2035 .andIfMiddleLayerHasNoPreference()
2036 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2037 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2038 .execute();
2039}
2040
2041TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2042 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2043 // If multiple layers have a preference, the topmost value is what is used.
2044 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2045 .andIfMiddleLayerHasNoPreference()
2046 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2047 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2048 .execute();
2049}
2050
2051TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2052 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2053 // If multiple layers have a preference, the topmost value is what is used.
2054 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2055 .andIfMiddleLayerHasNoPreference()
2056 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2057 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2058 .execute();
2059}
2060
2061struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2062 : public OutputUpdateColorProfileTest {
2063 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2064 // values, it overrides the layer dataspace choice.
2065
2066 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2067 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2068 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2069
2070 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2071
Lloyd Pique0a456232020-01-16 17:51:13 -08002072 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002073 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2074 }
2075
2076 struct IfForceOutputColorModeState
2077 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2078 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2079 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2080 return nextState<ThenExpectBestColorModeCallUsesState>();
2081 }
2082 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2083 };
2084
2085 struct ThenExpectBestColorModeCallUsesState
2086 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2087 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2088 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2089 getBestColorMode(dataspace, _, _, _, _));
2090 return nextState<ExecuteState>();
2091 }
2092 };
2093
2094 // Call this member function to start using the mini-DSL defined above.
2095 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2096};
2097
2098TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2099 // By default the layer state is used to set the preferred dataspace
2100 verify().ifNoOverride()
2101 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2102 .execute();
2103}
2104
2105TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2106 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2107 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2108 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2109 .execute();
2110}
2111
2112TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2113 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2114 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2115 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2116 .execute();
2117}
2118
2119// HDR output requires all layers to be compatible with the chosen HDR
2120// dataspace, along with there being proper support.
2121struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2122 OutputUpdateColorProfileTest_Hdr() {
2123 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2124 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002125 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002126 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2127 }
2128
2129 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2130 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2131 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2132 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2133
2134 struct IfTopLayerDataspaceState
2135 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2136 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2137 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2138 return nextState<AndTopLayerCompositionTypeState>();
2139 }
2140 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2141 };
2142
2143 struct AndTopLayerCompositionTypeState
2144 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2145 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2146 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2147 return nextState<AndIfBottomLayerDataspaceState>();
2148 }
2149 };
2150
2151 struct AndIfBottomLayerDataspaceState
2152 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2153 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2154 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2155 return nextState<AndBottomLayerCompositionTypeState>();
2156 }
2157 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2158 return andIfBottomLayerIs(kNonHdrDataspace);
2159 }
2160 };
2161
2162 struct AndBottomLayerCompositionTypeState
2163 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2164 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2165 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2166 return nextState<AndIfHasLegacySupportState>();
2167 }
2168 };
2169
2170 struct AndIfHasLegacySupportState
2171 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2172 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2173 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2174 .WillOnce(Return(legacySupport));
2175 return nextState<ThenExpectBestColorModeCallUsesState>();
2176 }
2177 };
2178
2179 struct ThenExpectBestColorModeCallUsesState
2180 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2181 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2182 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2183 getBestColorMode(dataspace, _, _, _, _));
2184 return nextState<ExecuteState>();
2185 }
2186 };
2187
2188 // Call this member function to start using the mini-DSL defined above.
2189 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2190};
2191
2192TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2193 // If all layers use BT2020_PQ, and there are no other special conditions,
2194 // BT2020_PQ is used.
2195 verify().ifTopLayerIs(BT2020_PQ)
2196 .andTopLayerIsREComposed(false)
2197 .andIfBottomLayerIs(BT2020_PQ)
2198 .andBottomLayerIsREComposed(false)
2199 .andIfLegacySupportFor(BT2020_PQ, false)
2200 .thenExpectBestColorModeCallUses(BT2020_PQ)
2201 .execute();
2202}
2203
2204TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2205 // BT2020_PQ is not used if there is only legacy support for it.
2206 verify().ifTopLayerIs(BT2020_PQ)
2207 .andTopLayerIsREComposed(false)
2208 .andIfBottomLayerIs(BT2020_PQ)
2209 .andBottomLayerIsREComposed(false)
2210 .andIfLegacySupportFor(BT2020_PQ, true)
2211 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2212 .execute();
2213}
2214
2215TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2216 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2217 verify().ifTopLayerIs(BT2020_PQ)
2218 .andTopLayerIsREComposed(false)
2219 .andIfBottomLayerIs(BT2020_PQ)
2220 .andBottomLayerIsREComposed(true)
2221 .andIfLegacySupportFor(BT2020_PQ, false)
2222 .thenExpectBestColorModeCallUses(BT2020_PQ)
2223 .execute();
2224}
2225
2226TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2227 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2228 verify().ifTopLayerIs(BT2020_PQ)
2229 .andTopLayerIsREComposed(true)
2230 .andIfBottomLayerIs(BT2020_PQ)
2231 .andBottomLayerIsREComposed(false)
2232 .andIfLegacySupportFor(BT2020_PQ, false)
2233 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2234 .execute();
2235}
2236
2237TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2238 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2239 // are no other special conditions.
2240 verify().ifTopLayerIs(BT2020_PQ)
2241 .andTopLayerIsREComposed(false)
2242 .andIfBottomLayerIs(BT2020_HLG)
2243 .andBottomLayerIsREComposed(false)
2244 .andIfLegacySupportFor(BT2020_PQ, false)
2245 .thenExpectBestColorModeCallUses(BT2020_PQ)
2246 .execute();
2247}
2248
2249TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2250 // BT2020_PQ is not used if there is only legacy support for it.
2251 verify().ifTopLayerIs(BT2020_PQ)
2252 .andTopLayerIsREComposed(false)
2253 .andIfBottomLayerIs(BT2020_HLG)
2254 .andBottomLayerIsREComposed(false)
2255 .andIfLegacySupportFor(BT2020_PQ, true)
2256 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2257 .execute();
2258}
2259
2260TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2261 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2262 verify().ifTopLayerIs(BT2020_PQ)
2263 .andTopLayerIsREComposed(false)
2264 .andIfBottomLayerIs(BT2020_HLG)
2265 .andBottomLayerIsREComposed(true)
2266 .andIfLegacySupportFor(BT2020_PQ, false)
2267 .thenExpectBestColorModeCallUses(BT2020_PQ)
2268 .execute();
2269}
2270
2271TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2272 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2273 verify().ifTopLayerIs(BT2020_PQ)
2274 .andTopLayerIsREComposed(true)
2275 .andIfBottomLayerIs(BT2020_HLG)
2276 .andBottomLayerIsREComposed(false)
2277 .andIfLegacySupportFor(BT2020_PQ, false)
2278 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2279 .execute();
2280}
2281
2282TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2283 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2284 // used if there are no other special conditions.
2285 verify().ifTopLayerIs(BT2020_HLG)
2286 .andTopLayerIsREComposed(false)
2287 .andIfBottomLayerIs(BT2020_PQ)
2288 .andBottomLayerIsREComposed(false)
2289 .andIfLegacySupportFor(BT2020_PQ, false)
2290 .thenExpectBestColorModeCallUses(BT2020_PQ)
2291 .execute();
2292}
2293
2294TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2295 // BT2020_PQ is not used if there is only legacy support for it.
2296 verify().ifTopLayerIs(BT2020_HLG)
2297 .andTopLayerIsREComposed(false)
2298 .andIfBottomLayerIs(BT2020_PQ)
2299 .andBottomLayerIsREComposed(false)
2300 .andIfLegacySupportFor(BT2020_PQ, true)
2301 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2306 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2307 verify().ifTopLayerIs(BT2020_HLG)
2308 .andTopLayerIsREComposed(false)
2309 .andIfBottomLayerIs(BT2020_PQ)
2310 .andBottomLayerIsREComposed(true)
2311 .andIfLegacySupportFor(BT2020_PQ, false)
2312 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2313 .execute();
2314}
2315
2316TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2317 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2318 verify().ifTopLayerIs(BT2020_HLG)
2319 .andTopLayerIsREComposed(true)
2320 .andIfBottomLayerIs(BT2020_PQ)
2321 .andBottomLayerIsREComposed(false)
2322 .andIfLegacySupportFor(BT2020_PQ, false)
2323 .thenExpectBestColorModeCallUses(BT2020_PQ)
2324 .execute();
2325}
2326
2327TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2328 // If all layers use HLG then HLG is used if there are no other special
2329 // conditions.
2330 verify().ifTopLayerIs(BT2020_HLG)
2331 .andTopLayerIsREComposed(false)
2332 .andIfBottomLayerIs(BT2020_HLG)
2333 .andBottomLayerIsREComposed(false)
2334 .andIfLegacySupportFor(BT2020_HLG, false)
2335 .thenExpectBestColorModeCallUses(BT2020_HLG)
2336 .execute();
2337}
2338
2339TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2340 // BT2020_HLG is not used if there is legacy support for it.
2341 verify().ifTopLayerIs(BT2020_HLG)
2342 .andTopLayerIsREComposed(false)
2343 .andIfBottomLayerIs(BT2020_HLG)
2344 .andBottomLayerIsREComposed(false)
2345 .andIfLegacySupportFor(BT2020_HLG, true)
2346 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2347 .execute();
2348}
2349
2350TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2351 // BT2020_HLG is used even if the bottom layer is client composed.
2352 verify().ifTopLayerIs(BT2020_HLG)
2353 .andTopLayerIsREComposed(false)
2354 .andIfBottomLayerIs(BT2020_HLG)
2355 .andBottomLayerIsREComposed(true)
2356 .andIfLegacySupportFor(BT2020_HLG, false)
2357 .thenExpectBestColorModeCallUses(BT2020_HLG)
2358 .execute();
2359}
2360
2361TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2362 // BT2020_HLG is used even if the top layer is client composed.
2363 verify().ifTopLayerIs(BT2020_HLG)
2364 .andTopLayerIsREComposed(true)
2365 .andIfBottomLayerIs(BT2020_HLG)
2366 .andBottomLayerIsREComposed(false)
2367 .andIfLegacySupportFor(BT2020_HLG, false)
2368 .thenExpectBestColorModeCallUses(BT2020_HLG)
2369 .execute();
2370}
2371
2372TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2373 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2374 verify().ifTopLayerIs(BT2020_PQ)
2375 .andTopLayerIsREComposed(false)
2376 .andIfBottomLayerIsNotHdr()
2377 .andBottomLayerIsREComposed(false)
2378 .andIfLegacySupportFor(BT2020_PQ, false)
2379 .thenExpectBestColorModeCallUses(BT2020_PQ)
2380 .execute();
2381}
2382
2383TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2384 // If all layers use HLG then HLG is used if there are no other special
2385 // conditions.
2386 verify().ifTopLayerIs(BT2020_HLG)
2387 .andTopLayerIsREComposed(false)
2388 .andIfBottomLayerIsNotHdr()
2389 .andBottomLayerIsREComposed(true)
2390 .andIfLegacySupportFor(BT2020_HLG, false)
2391 .thenExpectBestColorModeCallUses(BT2020_HLG)
2392 .execute();
2393}
2394
2395struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2396 : public OutputUpdateColorProfileTest {
2397 // The various values for CompositionRefreshArgs::outputColorSetting affect
2398 // the chosen renderIntent, along with whether the preferred dataspace is an
2399 // HDR dataspace or not.
2400
2401 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2402 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2403 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2404 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002405 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002406 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2407 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2408 .WillRepeatedly(Return(false));
2409 }
2410
2411 // The tests here involve enough state and GMock setup that using a mini-DSL
2412 // makes the tests much more readable, and allows the test to focus more on
2413 // the intent than on some of the details.
2414
2415 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2416 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2417
2418 struct IfDataspaceChosenState
2419 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2420 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2421 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2422 return nextState<AndOutputColorSettingState>();
2423 }
2424 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2425 return ifDataspaceChosenIs(kNonHdrDataspace);
2426 }
2427 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2428 };
2429
2430 struct AndOutputColorSettingState
2431 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2432 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2433 getInstance()->mRefreshArgs.outputColorSetting = setting;
2434 return nextState<ThenExpectBestColorModeCallUsesState>();
2435 }
2436 };
2437
2438 struct ThenExpectBestColorModeCallUsesState
2439 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2440 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2441 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2442 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2443 _, _));
2444 return nextState<ExecuteState>();
2445 }
2446 };
2447
2448 // Tests call one of these two helper member functions to start using the
2449 // mini-DSL defined above.
2450 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2451};
2452
2453TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2454 Managed_NonHdr_Prefers_Colorimetric) {
2455 verify().ifDataspaceChosenIsNonHdr()
2456 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2457 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2458 .execute();
2459}
2460
2461TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2462 Managed_Hdr_Prefers_ToneMapColorimetric) {
2463 verify().ifDataspaceChosenIsHdr()
2464 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2465 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2466 .execute();
2467}
2468
2469TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2470 verify().ifDataspaceChosenIsNonHdr()
2471 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2472 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2473 .execute();
2474}
2475
2476TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2477 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2478 verify().ifDataspaceChosenIsHdr()
2479 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2480 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2481 .execute();
2482}
2483
2484TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2485 verify().ifDataspaceChosenIsNonHdr()
2486 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2487 .thenExpectBestColorModeCallUses(
2488 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2489 .execute();
2490}
2491
2492TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2493 verify().ifDataspaceChosenIsHdr()
2494 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2495 .thenExpectBestColorModeCallUses(
2496 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2497 .execute();
2498}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002499
2500/*
2501 * Output::beginFrame()
2502 */
2503
Lloyd Piquee5965952019-11-18 16:16:32 -08002504struct OutputBeginFrameTest : public ::testing::Test {
2505 using TestType = OutputBeginFrameTest;
2506
2507 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002508 // Sets up the helper functions called by the function under test to use
2509 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002510 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002511 };
2512
2513 OutputBeginFrameTest() {
2514 mOutput.setDisplayColorProfileForTest(
2515 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2516 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2517 }
2518
2519 struct IfGetDirtyRegionExpectationState
2520 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2521 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002522 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002523 return nextState<AndIfGetOutputLayerCountExpectationState>();
2524 }
2525 };
2526
2527 struct AndIfGetOutputLayerCountExpectationState
2528 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2529 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2530 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2531 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2532 }
2533 };
2534
2535 struct AndIfLastCompositionHadVisibleLayersState
2536 : public CallOrderStateMachineHelper<TestType,
2537 AndIfLastCompositionHadVisibleLayersState> {
2538 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2539 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2540 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2541 }
2542 };
2543
2544 struct ThenExpectRenderSurfaceBeginFrameCallState
2545 : public CallOrderStateMachineHelper<TestType,
2546 ThenExpectRenderSurfaceBeginFrameCallState> {
2547 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2548 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2549 return nextState<ExecuteState>();
2550 }
2551 };
2552
2553 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2554 [[nodiscard]] auto execute() {
2555 getInstance()->mOutput.beginFrame();
2556 return nextState<CheckPostconditionHadVisibleLayersState>();
2557 }
2558 };
2559
2560 struct CheckPostconditionHadVisibleLayersState
2561 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2562 void checkPostconditionHadVisibleLayers(bool expected) {
2563 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2564 }
2565 };
2566
2567 // Tests call one of these two helper member functions to start using the
2568 // mini-DSL defined above.
2569 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2570
2571 static const Region kEmptyRegion;
2572 static const Region kNotEmptyRegion;
2573
2574 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2575 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2576 StrictMock<OutputPartialMock> mOutput;
2577};
2578
2579const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2580const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2581
2582TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2583 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2584 .andIfGetOutputLayerCountReturns(1u)
2585 .andIfLastCompositionHadVisibleLayersIs(true)
2586 .thenExpectRenderSurfaceBeginFrameCall(true)
2587 .execute()
2588 .checkPostconditionHadVisibleLayers(true);
2589}
2590
2591TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2592 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2593 .andIfGetOutputLayerCountReturns(0u)
2594 .andIfLastCompositionHadVisibleLayersIs(true)
2595 .thenExpectRenderSurfaceBeginFrameCall(true)
2596 .execute()
2597 .checkPostconditionHadVisibleLayers(false);
2598}
2599
2600TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2601 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2602 .andIfGetOutputLayerCountReturns(1u)
2603 .andIfLastCompositionHadVisibleLayersIs(false)
2604 .thenExpectRenderSurfaceBeginFrameCall(true)
2605 .execute()
2606 .checkPostconditionHadVisibleLayers(true);
2607}
2608
2609TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2610 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2611 .andIfGetOutputLayerCountReturns(0u)
2612 .andIfLastCompositionHadVisibleLayersIs(false)
2613 .thenExpectRenderSurfaceBeginFrameCall(false)
2614 .execute()
2615 .checkPostconditionHadVisibleLayers(false);
2616}
2617
2618TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2619 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2620 .andIfGetOutputLayerCountReturns(1u)
2621 .andIfLastCompositionHadVisibleLayersIs(true)
2622 .thenExpectRenderSurfaceBeginFrameCall(false)
2623 .execute()
2624 .checkPostconditionHadVisibleLayers(true);
2625}
2626
2627TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2628 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2629 .andIfGetOutputLayerCountReturns(0u)
2630 .andIfLastCompositionHadVisibleLayersIs(true)
2631 .thenExpectRenderSurfaceBeginFrameCall(false)
2632 .execute()
2633 .checkPostconditionHadVisibleLayers(true);
2634}
2635
2636TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2637 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2638 .andIfGetOutputLayerCountReturns(1u)
2639 .andIfLastCompositionHadVisibleLayersIs(false)
2640 .thenExpectRenderSurfaceBeginFrameCall(false)
2641 .execute()
2642 .checkPostconditionHadVisibleLayers(false);
2643}
2644
2645TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2646 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2647 .andIfGetOutputLayerCountReturns(0u)
2648 .andIfLastCompositionHadVisibleLayersIs(false)
2649 .thenExpectRenderSurfaceBeginFrameCall(false)
2650 .execute()
2651 .checkPostconditionHadVisibleLayers(false);
2652}
2653
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002654/*
2655 * Output::devOptRepaintFlash()
2656 */
2657
Lloyd Piquedb462d82019-11-19 17:58:46 -08002658struct OutputDevOptRepaintFlashTest : public testing::Test {
2659 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002660 // Sets up the helper functions called by the function under test to use
2661 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002662 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002663 MOCK_METHOD2(composeSurfaces,
2664 std::optional<base::unique_fd>(
2665 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002666 MOCK_METHOD0(postFramebuffer, void());
2667 MOCK_METHOD0(prepareFrame, void());
2668 };
2669
2670 OutputDevOptRepaintFlashTest() {
2671 mOutput.setDisplayColorProfileForTest(
2672 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2673 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2674 }
2675
2676 static const Region kEmptyRegion;
2677 static const Region kNotEmptyRegion;
2678
2679 StrictMock<OutputPartialMock> mOutput;
2680 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2681 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2682 CompositionRefreshArgs mRefreshArgs;
2683};
2684
2685const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2686const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2687
2688TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2689 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002690 mOutput.mState.isEnabled = true;
2691
2692 mOutput.devOptRepaintFlash(mRefreshArgs);
2693}
2694
2695TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2696 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002697 mOutput.mState.isEnabled = false;
2698
2699 InSequence seq;
2700 EXPECT_CALL(mOutput, postFramebuffer());
2701 EXPECT_CALL(mOutput, prepareFrame());
2702
2703 mOutput.devOptRepaintFlash(mRefreshArgs);
2704}
2705
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002706TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002707 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002708 mOutput.mState.isEnabled = true;
2709
2710 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002711 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002712 EXPECT_CALL(mOutput, postFramebuffer());
2713 EXPECT_CALL(mOutput, prepareFrame());
2714
2715 mOutput.devOptRepaintFlash(mRefreshArgs);
2716}
2717
2718TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2719 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002720 mOutput.mState.isEnabled = true;
2721
2722 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002723 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002724 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002725 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2726 EXPECT_CALL(mOutput, postFramebuffer());
2727 EXPECT_CALL(mOutput, prepareFrame());
2728
2729 mOutput.devOptRepaintFlash(mRefreshArgs);
2730}
2731
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002732/*
2733 * Output::finishFrame()
2734 */
2735
Lloyd Pique03561a62019-11-19 18:34:52 -08002736struct OutputFinishFrameTest : public testing::Test {
2737 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002738 // Sets up the helper functions called by the function under test to use
2739 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002740 MOCK_METHOD2(composeSurfaces,
2741 std::optional<base::unique_fd>(
2742 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002743 MOCK_METHOD0(postFramebuffer, void());
2744 };
2745
2746 OutputFinishFrameTest() {
2747 mOutput.setDisplayColorProfileForTest(
2748 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2749 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2750 }
2751
2752 StrictMock<OutputPartialMock> mOutput;
2753 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2754 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2755 CompositionRefreshArgs mRefreshArgs;
2756};
2757
2758TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2759 mOutput.mState.isEnabled = false;
2760
2761 mOutput.finishFrame(mRefreshArgs);
2762}
2763
2764TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2765 mOutput.mState.isEnabled = true;
2766
2767 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002768 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002769
2770 mOutput.finishFrame(mRefreshArgs);
2771}
2772
2773TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2774 mOutput.mState.isEnabled = true;
2775
2776 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002777 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002778 .WillOnce(Return(ByMove(base::unique_fd())));
2779 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2780
2781 mOutput.finishFrame(mRefreshArgs);
2782}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002783
2784/*
2785 * Output::postFramebuffer()
2786 */
2787
Lloyd Pique07178e32019-11-19 19:15:26 -08002788struct OutputPostFramebufferTest : public testing::Test {
2789 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002790 // Sets up the helper functions called by the function under test to use
2791 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002792 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2793 };
2794
2795 struct Layer {
2796 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002797 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002798 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2799 }
2800
2801 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002802 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002803 StrictMock<HWC2::mock::Layer> hwc2Layer;
2804 };
2805
2806 OutputPostFramebufferTest() {
2807 mOutput.setDisplayColorProfileForTest(
2808 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2809 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2810
2811 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2812 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2813 .WillRepeatedly(Return(&mLayer1.outputLayer));
2814 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2815 .WillRepeatedly(Return(&mLayer2.outputLayer));
2816 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2817 .WillRepeatedly(Return(&mLayer3.outputLayer));
2818 }
2819
2820 StrictMock<OutputPartialMock> mOutput;
2821 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2822 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2823
2824 Layer mLayer1;
2825 Layer mLayer2;
2826 Layer mLayer3;
2827};
2828
2829TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2830 mOutput.mState.isEnabled = false;
2831
2832 mOutput.postFramebuffer();
2833}
2834
2835TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2836 mOutput.mState.isEnabled = true;
2837
2838 compositionengine::Output::FrameFences frameFences;
2839
2840 // This should happen even if there are no output layers.
2841 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2842
2843 // For this test in particular we want to make sure the call expectations
2844 // setup below are satisfied in the specific order.
2845 InSequence seq;
2846
2847 EXPECT_CALL(*mRenderSurface, flip());
2848 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2849 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2850
2851 mOutput.postFramebuffer();
2852}
2853
2854TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2855 // Simulate getting release fences from each layer, and ensure they are passed to the
2856 // front-end layer interface for each layer correctly.
2857
2858 mOutput.mState.isEnabled = true;
2859
2860 // Create three unique fence instances
2861 sp<Fence> layer1Fence = new Fence();
2862 sp<Fence> layer2Fence = new Fence();
2863 sp<Fence> layer3Fence = new Fence();
2864
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002865 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002866 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2867 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2868 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2869
2870 EXPECT_CALL(*mRenderSurface, flip());
2871 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2872 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2873
2874 // Compare the pointers values of each fence to make sure the correct ones
2875 // are passed. This happens to work with the current implementation, but
2876 // would not survive certain calls like Fence::merge() which would return a
2877 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002878 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002879 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002880 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002881 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002882 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002883 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2884
2885 mOutput.postFramebuffer();
2886}
2887
2888TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2889 mOutput.mState.isEnabled = true;
2890 mOutput.mState.usesClientComposition = true;
2891
2892 sp<Fence> clientTargetAcquireFence = new Fence();
2893 sp<Fence> layer1Fence = new Fence();
2894 sp<Fence> layer2Fence = new Fence();
2895 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002896 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002897 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2898 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2899 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2900 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2901
2902 EXPECT_CALL(*mRenderSurface, flip());
2903 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2904 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2905
2906 // Fence::merge is called, and since none of the fences are actually valid,
2907 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2908 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002909 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2910 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2911 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002912
2913 mOutput.postFramebuffer();
2914}
2915
2916TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2917 mOutput.mState.isEnabled = true;
2918 mOutput.mState.usesClientComposition = true;
2919
2920 // This should happen even if there are no (current) output layers.
2921 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2922
2923 // Load up the released layers with some mock instances
2924 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2925 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2926 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2927 Output::ReleasedLayers layers;
2928 layers.push_back(releasedLayer1);
2929 layers.push_back(releasedLayer2);
2930 layers.push_back(releasedLayer3);
2931 mOutput.setReleasedLayers(std::move(layers));
2932
2933 // Set up a fake present fence
2934 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002935 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002936 frameFences.presentFence = presentFence;
2937
2938 EXPECT_CALL(*mRenderSurface, flip());
2939 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2940 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2941
2942 // Each released layer should be given the presentFence.
2943 EXPECT_CALL(*releasedLayer1,
2944 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2945 EXPECT_CALL(*releasedLayer2,
2946 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2947 EXPECT_CALL(*releasedLayer3,
2948 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2949
2950 mOutput.postFramebuffer();
2951
2952 // After the call the list of released layers should have been cleared.
2953 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2954}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002955
2956/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002957 * Output::composeSurfaces()
2958 */
2959
2960struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002961 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002962
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002963 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002964 // Sets up the helper functions called by the function under test to use
2965 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002966 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Sally Qidf3da512021-07-08 17:27:02 +00002967 MOCK_METHOD2(generateClientCompositionRequests,
2968 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002969 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002970 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002971 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2972 };
2973
2974 OutputComposeSurfacesTest() {
2975 mOutput.setDisplayColorProfileForTest(
2976 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2977 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002978 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002979
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002980 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2981 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002982 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002983 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002984 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002985 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002986 mOutput.mState.dataspace = kDefaultOutputDataspace;
2987 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2988 mOutput.mState.isSecure = false;
2989 mOutput.mState.needsFiltering = false;
2990 mOutput.mState.usesClientComposition = true;
2991 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002992 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002993 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002994
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002995 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002996 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002997 EXPECT_CALL(mCompositionEngine, getTimeStats())
2998 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002999 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3000 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003001 }
3002
Lloyd Pique6818fa52019-12-03 12:32:13 -08003003 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3004 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003005 getInstance()->mReadyFence =
3006 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003007 return nextState<FenceCheckState>();
3008 }
3009 };
3010
3011 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3012 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3013
3014 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3015 };
3016
3017 // Call this member function to start using the mini-DSL defined above.
3018 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3019
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003020 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3021 static constexpr uint32_t kDefaultOutputOrientationFlags =
3022 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003023 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3024 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3025 static constexpr float kDefaultMaxLuminance = 0.9f;
3026 static constexpr float kDefaultAvgLuminance = 0.7f;
3027 static constexpr float kDefaultMinLuminance = 0.1f;
3028
3029 static const Rect kDefaultOutputFrame;
3030 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003031 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003032 static const mat4 kDefaultColorTransformMat;
3033
3034 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003035 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003036 static const HdrCapabilities kHdrCapabilities;
3037
Lloyd Pique56eba802019-08-28 15:45:25 -07003038 StrictMock<mock::CompositionEngine> mCompositionEngine;
3039 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003040 // TODO: make this is a proper mock.
3041 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003042 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3043 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003044 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003045 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3046 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3047 renderengine::ExternalTexture::Usage::READABLE |
3048 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003049
3050 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003051};
3052
3053const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3054const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003055const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003056const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003057const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003058const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3059const HdrCapabilities OutputComposeSurfacesTest::
3060 kHdrCapabilities{{},
3061 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3062 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3063 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003064
Lloyd Piquea76ce462020-01-14 13:06:37 -08003065TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003066 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003067
Lloyd Piquee9eff972020-05-05 12:36:44 -07003068 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003069 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003070
Lloyd Piquea76ce462020-01-14 13:06:37 -08003071 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3072
Lloyd Pique6818fa52019-12-03 12:32:13 -08003073 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003074}
3075
Lloyd Piquee9eff972020-05-05 12:36:44 -07003076TEST_F(OutputComposeSurfacesTest,
3077 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3078 mOutput.mState.usesClientComposition = false;
3079 mOutput.mState.flipClientTarget = true;
3080
Lloyd Pique6818fa52019-12-03 12:32:13 -08003081 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003082 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003083
3084 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3085 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3086
3087 verify().execute().expectAFenceWasReturned();
3088}
3089
3090TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3091 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003092 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003093
3094 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3095
3096 verify().execute().expectNoFenceWasReturned();
3097}
3098
3099TEST_F(OutputComposeSurfacesTest,
3100 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3101 mOutput.mState.usesClientComposition = false;
3102 mOutput.mState.flipClientTarget = true;
3103
3104 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003105 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003106
Lloyd Pique6818fa52019-12-03 12:32:13 -08003107 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003108
Lloyd Pique6818fa52019-12-03 12:32:13 -08003109 verify().execute().expectNoFenceWasReturned();
3110}
Lloyd Pique56eba802019-08-28 15:45:25 -07003111
Lloyd Pique6818fa52019-12-03 12:32:13 -08003112TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3113 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3114 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3115 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003116 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003117 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003118 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003119 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3120 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003121
Lloyd Pique6818fa52019-12-03 12:32:13 -08003122 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003123 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3124 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3125 const std::vector<const renderengine::LayerSettings*>&,
3126 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3127 base::unique_fd &&)
3128 -> std::future<renderengine::RenderEngineResult> {
3129 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3130 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003131 verify().execute().expectAFenceWasReturned();
3132}
Lloyd Pique56eba802019-08-28 15:45:25 -07003133
Lloyd Pique6818fa52019-12-03 12:32:13 -08003134TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003135 LayerFE::LayerSettings r1;
3136 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003137
3138 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3139 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3140
3141 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3142 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3143 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003144 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003145 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003146 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003147 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3148 .WillRepeatedly(
3149 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003150 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003151 clientCompositionLayers.emplace_back(r2);
3152 }));
3153
3154 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003155 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3156 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3157 const std::vector<const renderengine::LayerSettings*>&,
3158 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3159 base::unique_fd &&)
3160 -> std::future<renderengine::RenderEngineResult> {
3161 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3162 });
Alec Mouri1684c702021-02-04 12:27:26 -08003163
3164 verify().execute().expectAFenceWasReturned();
3165}
3166
3167TEST_F(OutputComposeSurfacesTest,
3168 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3169 LayerFE::LayerSettings r1;
3170 LayerFE::LayerSettings r2;
3171
3172 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3173 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003174 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003175
3176 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3177 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3178 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3179 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003180 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Alec Mouri1684c702021-02-04 12:27:26 -08003181 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3182 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3183 .WillRepeatedly(
3184 Invoke([&](const Region&,
3185 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3186 clientCompositionLayers.emplace_back(r2);
3187 }));
3188
3189 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003190 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _))
3191 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3192 const std::vector<const renderengine::LayerSettings*>&,
3193 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3194 base::unique_fd &&)
3195 -> std::future<renderengine::RenderEngineResult> {
3196 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3197 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003198
3199 verify().execute().expectAFenceWasReturned();
3200}
3201
Vishnu Nair9b079a22020-01-21 14:36:08 -08003202TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3203 mOutput.cacheClientCompositionRequests(0);
3204 LayerFE::LayerSettings r1;
3205 LayerFE::LayerSettings r2;
3206
3207 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3208 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3209
3210 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3211 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3212 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003213 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003214 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003215 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3216 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3217 .WillRepeatedly(Return());
3218
3219 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003220 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003221 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003222 .WillOnce(Return(ByMove(
3223 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3224 .WillOnce(Return(ByMove(
3225 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003226
3227 verify().execute().expectAFenceWasReturned();
3228 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3229
3230 verify().execute().expectAFenceWasReturned();
3231 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3232}
3233
3234TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3235 mOutput.cacheClientCompositionRequests(3);
3236 LayerFE::LayerSettings r1;
3237 LayerFE::LayerSettings r2;
3238
3239 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3240 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3241
3242 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3243 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3244 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003245 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003246 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003247 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3248 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3249 .WillRepeatedly(Return());
3250
3251 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003252 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3253 .WillOnce(Return(ByMove(
3254 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003255 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3256
3257 verify().execute().expectAFenceWasReturned();
3258 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3259
3260 // We do not expect another call to draw layers.
3261 verify().execute().expectAFenceWasReturned();
3262 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3263}
3264
3265TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3266 LayerFE::LayerSettings r1;
3267 LayerFE::LayerSettings r2;
3268
3269 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3270 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3271
3272 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3273 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3274 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003275 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003276 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003277 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3278 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3279 .WillRepeatedly(Return());
3280
Alec Mouria90a5702021-04-16 16:36:21 +00003281 const auto otherOutputBuffer = std::make_shared<
3282 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3283 renderengine::ExternalTexture::Usage::READABLE |
3284 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003285 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3286 .WillOnce(Return(mOutputBuffer))
3287 .WillOnce(Return(otherOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003288 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3289 .WillRepeatedly([&](const renderengine::DisplaySettings&,
3290 const std::vector<const renderengine::LayerSettings*>&,
3291 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3292 base::unique_fd &&)
3293 -> std::future<renderengine::RenderEngineResult> {
3294 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3295 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003296
3297 verify().execute().expectAFenceWasReturned();
3298 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3299
3300 verify().execute().expectAFenceWasReturned();
3301 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3302}
3303
3304TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3305 LayerFE::LayerSettings r1;
3306 LayerFE::LayerSettings r2;
3307 LayerFE::LayerSettings r3;
3308
3309 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3310 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3311 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3312
3313 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3314 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3315 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003316 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003317 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003318 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3319 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3320 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3321 .WillRepeatedly(Return());
3322
3323 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003324 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _))
3325 .WillOnce(Return(ByMove(
3326 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
3327 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _))
3328 .WillOnce(Return(ByMove(
3329 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003330
3331 verify().execute().expectAFenceWasReturned();
3332 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3333
3334 verify().execute().expectAFenceWasReturned();
3335 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3336}
3337
Lloyd Pique6818fa52019-12-03 12:32:13 -08003338struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3339 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3340 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003341 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003342 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003343 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003344 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3345 .WillRepeatedly(Return());
3346 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3347 }
3348
3349 struct MixedCompositionState
3350 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3351 auto ifMixedCompositionIs(bool used) {
3352 getInstance()->mOutput.mState.usesDeviceComposition = used;
3353 return nextState<OutputUsesHdrState>();
3354 }
3355 };
3356
3357 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3358 auto andIfUsesHdr(bool used) {
3359 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3360 .WillOnce(Return(used));
3361 return nextState<SkipColorTransformState>();
3362 }
3363 };
3364
3365 struct SkipColorTransformState
3366 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3367 auto andIfSkipColorTransform(bool skip) {
3368 // May be called zero or one times.
3369 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3370 .WillRepeatedly(Return(skip));
3371 return nextState<ExpectDisplaySettingsState>();
3372 }
3373 };
3374
3375 struct ExpectDisplaySettingsState
3376 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3377 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003378 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3379 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3380 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003381 return nextState<ExecuteState>();
3382 }
3383 };
3384
3385 // Call this member function to start using the mini-DSL defined above.
3386 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3387};
3388
3389TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3390 verify().ifMixedCompositionIs(true)
3391 .andIfUsesHdr(true)
3392 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003393 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003394 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003395 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003396 .execute()
3397 .expectAFenceWasReturned();
3398}
3399
3400TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3401 verify().ifMixedCompositionIs(true)
3402 .andIfUsesHdr(false)
3403 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003404 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003405 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003406 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003407 .execute()
3408 .expectAFenceWasReturned();
3409}
3410
3411TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3412 verify().ifMixedCompositionIs(false)
3413 .andIfUsesHdr(true)
3414 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003415 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003416 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003417 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003418 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003419 .execute()
3420 .expectAFenceWasReturned();
3421}
3422
3423TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3424 verify().ifMixedCompositionIs(false)
3425 .andIfUsesHdr(false)
3426 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003427 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003428 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003429 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003430 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003431 .execute()
3432 .expectAFenceWasReturned();
3433}
3434
3435TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3436 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3437 verify().ifMixedCompositionIs(false)
3438 .andIfUsesHdr(true)
3439 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003440 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003441 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003442 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003443 .execute()
3444 .expectAFenceWasReturned();
3445}
3446
3447struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3448 struct Layer {
3449 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003450 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3451 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003452 }
3453
3454 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003455 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003456 LayerFECompositionState mLayerFEState;
3457 };
3458
3459 OutputComposeSurfacesTest_HandlesProtectedContent() {
3460 mLayer1.mLayerFEState.hasProtectedContent = false;
3461 mLayer2.mLayerFEState.hasProtectedContent = false;
3462
3463 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3464 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3465 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3466 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3467 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3468
3469 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3470
3471 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3472
Sally Qidf3da512021-07-08 17:27:02 +00003473 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003474 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003475 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3476 .WillRepeatedly(Return());
3477 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003478 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3479 .WillRepeatedly(
3480 [&](const renderengine::DisplaySettings&,
3481 const std::vector<const renderengine::LayerSettings*>&,
3482 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
3483 base::unique_fd &&) -> std::future<renderengine::RenderEngineResult> {
3484 return futureOf<renderengine::RenderEngineResult>(
3485 {NO_ERROR, base::unique_fd()});
3486 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003487 }
3488
3489 Layer mLayer1;
3490 Layer mLayer2;
3491};
3492
3493TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3494 mOutput.mState.isSecure = false;
3495 mLayer2.mLayerFEState.hasProtectedContent = true;
3496 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003497 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003498 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003499
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003500 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003501}
3502
3503TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3504 mOutput.mState.isSecure = true;
3505 mLayer2.mLayerFEState.hasProtectedContent = true;
3506 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3507
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003508 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003509}
3510
3511TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3512 mOutput.mState.isSecure = true;
3513 mLayer2.mLayerFEState.hasProtectedContent = false;
3514 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3515 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3516 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3517 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3518 EXPECT_CALL(*mRenderSurface, setProtected(false));
3519
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003520 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003521}
3522
3523TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3524 mOutput.mState.isSecure = true;
3525 mLayer2.mLayerFEState.hasProtectedContent = true;
3526 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3527
3528 // For this test, we also check the call order of key functions.
3529 InSequence seq;
3530
3531 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3532 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3533 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3534 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3535 EXPECT_CALL(*mRenderSurface, setProtected(true));
3536 // Must happen after setting the protected content state.
3537 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003538 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3539 .WillOnce(Return(ByMove(
3540 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003541
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003542 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003543}
3544
3545TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3546 mOutput.mState.isSecure = true;
3547 mLayer2.mLayerFEState.hasProtectedContent = true;
3548 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3549 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3550 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3551
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003552 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003553}
3554
3555TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3556 mOutput.mState.isSecure = true;
3557 mLayer2.mLayerFEState.hasProtectedContent = true;
3558 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3559 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3560 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3561 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3562
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003563 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003564}
3565
3566TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3567 mOutput.mState.isSecure = true;
3568 mLayer2.mLayerFEState.hasProtectedContent = true;
3569 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3570 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3571 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3572 EXPECT_CALL(*mRenderSurface, setProtected(true));
3573
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003574 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003575}
3576
3577TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3578 mOutput.mState.isSecure = true;
3579 mLayer2.mLayerFEState.hasProtectedContent = true;
3580 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3581 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3582 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3583 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3584
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003585 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003586}
3587
3588struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3589 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3590 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3591 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3592 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003593 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003594 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3595 .WillRepeatedly(Return());
3596 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3597 }
3598};
3599
3600TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3601 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3602
Sally Qidf3da512021-07-08 17:27:02 +00003603 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003604 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003605
3606 // For this test, we also check the call order of key functions.
3607 InSequence seq;
3608
3609 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003610 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3611 .WillOnce(Return(ByMove(
3612 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003613
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003614 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3615}
3616
3617struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3618 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3619 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3620 mLayer.layerFEState.backgroundBlurRadius = 10;
3621 mOutput.editState().isEnabled = true;
3622
Snild Dolkow9e217d62020-04-22 15:53:42 +02003623 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003624 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003625 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3626 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Sally Qidf3da512021-07-08 17:27:02 +00003627 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003628 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003629 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3630 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3631 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003632 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3633 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3634 .WillRepeatedly(Return(&mLayer.outputLayer));
3635 }
3636
3637 NonInjectedLayer mLayer;
3638 compositionengine::CompositionRefreshArgs mRefreshArgs;
3639};
3640
3641TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3642 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003643 mOutput.updateCompositionState(mRefreshArgs);
3644 mOutput.planComposition();
3645 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003646
3647 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3648 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3649}
3650
3651TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3652 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003653 mOutput.updateCompositionState(mRefreshArgs);
3654 mOutput.planComposition();
3655 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003656
3657 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3658 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003659}
3660
3661/*
3662 * Output::generateClientCompositionRequests()
3663 */
3664
3665struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003666 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003667 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003668 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Sally Qidf3da512021-07-08 17:27:02 +00003669 bool supportsProtectedContent, ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003670 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Sally Qidf3da512021-07-08 17:27:02 +00003671 dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003672 }
3673 };
3674
Lloyd Piquea4863342019-12-04 18:45:02 -08003675 struct Layer {
3676 Layer() {
3677 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3678 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003679 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3680 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003681 }
3682
3683 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003684 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003685 LayerFECompositionState mLayerFEState;
3686 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003687 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003688 };
3689
Lloyd Pique56eba802019-08-28 15:45:25 -07003690 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003691 mOutput.mState.needsFiltering = false;
3692
Lloyd Pique56eba802019-08-28 15:45:25 -07003693 mOutput.setDisplayColorProfileForTest(
3694 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3695 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3696 }
3697
Lloyd Pique56eba802019-08-28 15:45:25 -07003698 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3699 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003700 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003701};
3702
Lloyd Piquea4863342019-12-04 18:45:02 -08003703struct GenerateClientCompositionRequestsTest_ThreeLayers
3704 : public GenerateClientCompositionRequestsTest {
3705 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003706 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3707 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3708 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003709 mOutput.mState.transform =
3710 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3711 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003712 mOutput.mState.needsFiltering = false;
3713 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003714
Lloyd Piquea4863342019-12-04 18:45:02 -08003715 for (size_t i = 0; i < mLayers.size(); i++) {
3716 mLayers[i].mOutputLayerState.clearClientTarget = false;
3717 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3718 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003719 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003720 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003721 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3722 mLayers[i].mLayerSettings.alpha = 1.0f;
3723 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003724
Lloyd Piquea4863342019-12-04 18:45:02 -08003725 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3726 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3727 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3728 .WillRepeatedly(Return(true));
3729 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3730 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003731
Lloyd Piquea4863342019-12-04 18:45:02 -08003732 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3733 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003734
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003735 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003736 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003737
Lloyd Piquea4863342019-12-04 18:45:02 -08003738 static const Rect kDisplayFrame;
3739 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003740 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003741
Lloyd Piquea4863342019-12-04 18:45:02 -08003742 std::array<Layer, 3> mLayers;
3743};
Lloyd Pique56eba802019-08-28 15:45:25 -07003744
Lloyd Piquea4863342019-12-04 18:45:02 -08003745const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3746const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003747const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3748 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003749
Lloyd Piquea4863342019-12-04 18:45:02 -08003750TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3751 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3752 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3753 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003754
Lloyd Piquea4863342019-12-04 18:45:02 -08003755 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003756 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003757 EXPECT_EQ(0u, requests.size());
3758}
3759
Lloyd Piquea4863342019-12-04 18:45:02 -08003760TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3761 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3762 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3763 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3764
Lloyd Piquea4863342019-12-04 18:45:02 -08003765 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003766 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003767 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003768}
3769
3770TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003771 LayerFE::LayerSettings mShadowSettings;
3772 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003773
Ady Abrahameca9d752021-03-03 12:20:00 -08003774 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003775 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003776 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003777 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003778 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003779 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3780 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003781
Lloyd Piquea4863342019-12-04 18:45:02 -08003782 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003783 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003784 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003785 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3786 EXPECT_EQ(mShadowSettings, requests[1]);
3787 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003788
Lloyd Piquea4863342019-12-04 18:45:02 -08003789 // Check that a timestamp was set for the layers that generated requests
3790 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3791 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3792 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3793}
3794
Alec Mourif54453c2021-05-13 16:28:28 -07003795MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3796 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3797 *result_listener << "expected " << expectedBlurSetting << "\n";
3798 *result_listener << "actual " << arg.blurSetting << "\n";
3799
3800 return expectedBlurSetting == arg.blurSetting;
3801}
3802
3803TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3804 LayerFE::LayerSettings mShadowSettings;
3805 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3806
3807 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3808
3809 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3810 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3811 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3812 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3813 EXPECT_CALL(*mLayers[2].mLayerFE,
3814 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3815 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3816 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3817 {mShadowSettings, mLayers[2].mLayerSettings})));
3818
Alec Mourif54453c2021-05-13 16:28:28 -07003819 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003820 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003821 ASSERT_EQ(3u, requests.size());
3822 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3823 EXPECT_EQ(mShadowSettings, requests[1]);
3824 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3825
Alec Mourif54453c2021-05-13 16:28:28 -07003826 // Check that a timestamp was set for the layers that generated requests
3827 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3828 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3829 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3830}
3831
Lloyd Piquea4863342019-12-04 18:45:02 -08003832TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3833 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3834 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3835 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3836 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3837
3838 mLayers[0].mOutputLayerState.clearClientTarget = false;
3839 mLayers[1].mOutputLayerState.clearClientTarget = false;
3840 mLayers[2].mOutputLayerState.clearClientTarget = false;
3841
3842 mLayers[0].mLayerFEState.isOpaque = true;
3843 mLayers[1].mLayerFEState.isOpaque = true;
3844 mLayers[2].mLayerFEState.isOpaque = true;
3845
Ady Abrahameca9d752021-03-03 12:20:00 -08003846 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003847 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003848
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003850 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003851 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003852 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003853}
3854
3855TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3856 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3857 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3858 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3859 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3860
3861 mLayers[0].mOutputLayerState.clearClientTarget = true;
3862 mLayers[1].mOutputLayerState.clearClientTarget = true;
3863 mLayers[2].mOutputLayerState.clearClientTarget = true;
3864
3865 mLayers[0].mLayerFEState.isOpaque = false;
3866 mLayers[1].mLayerFEState.isOpaque = false;
3867 mLayers[2].mLayerFEState.isOpaque = false;
3868
Ady Abrahameca9d752021-03-03 12:20:00 -08003869 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003870 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003871
Lloyd Piquea4863342019-12-04 18:45:02 -08003872 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003873 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003874 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003875 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003876}
3877
3878TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003879 // If client composition is performed with some layers set to use device
3880 // composition, device layers after the first layer (device or client) will
3881 // clear the frame buffer if they are opaque and if that layer has a flag
3882 // set to do so. The first layer is skipped as the frame buffer is already
3883 // expected to be clear.
3884
Lloyd Piquea4863342019-12-04 18:45:02 -08003885 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3886 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3887 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003888
Lloyd Piquea4863342019-12-04 18:45:02 -08003889 mLayers[0].mOutputLayerState.clearClientTarget = true;
3890 mLayers[1].mOutputLayerState.clearClientTarget = true;
3891 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003892
Lloyd Piquea4863342019-12-04 18:45:02 -08003893 mLayers[0].mLayerFEState.isOpaque = true;
3894 mLayers[1].mLayerFEState.isOpaque = true;
3895 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003896
3897 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3898 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003899 false, /* needs filtering */
3900 false, /* secure */
3901 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003902 kDisplayViewport,
3903 kDisplayDataspace,
3904 false /* realContentIsVisible */,
3905 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003906 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003907 };
3908 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3909 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003910 false, /* needs filtering */
3911 false, /* secure */
3912 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003913 kDisplayViewport,
3914 kDisplayDataspace,
3915 true /* realContentIsVisible */,
3916 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003917 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003918 };
3919
3920 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3921 mBlackoutSettings.source.buffer.buffer = nullptr;
3922 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3923 mBlackoutSettings.alpha = 0.f;
3924 mBlackoutSettings.disableBlending = true;
3925
Ady Abrahameca9d752021-03-03 12:20:00 -08003926 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003927 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003928 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003929 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3930
Lloyd Piquea4863342019-12-04 18:45:02 -08003931 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003932 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003933 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003934
Lloyd Piquea4863342019-12-04 18:45:02 -08003935 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003936 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003937
Vishnu Nair9b079a22020-01-21 14:36:08 -08003938 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003939}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003940
Lloyd Piquea4863342019-12-04 18:45:02 -08003941TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3942 clippedVisibleRegionUsedToGenerateRequest) {
3943 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3944 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3945 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003946
Lloyd Piquea4863342019-12-04 18:45:02 -08003947 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3948 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003949 false, /* needs filtering */
3950 false, /* secure */
3951 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003952 kDisplayViewport,
3953 kDisplayDataspace,
3954 true /* realContentIsVisible */,
3955 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003956 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003957 };
3958 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3959 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003960 false, /* needs filtering */
3961 false, /* secure */
3962 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003963 kDisplayViewport,
3964 kDisplayDataspace,
3965 true /* realContentIsVisible */,
3966 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003967 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003968 };
3969 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3970 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003971 false, /* needs filtering */
3972 false, /* secure */
3973 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003974 kDisplayViewport,
3975 kDisplayDataspace,
3976 true /* realContentIsVisible */,
3977 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003978 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003979 };
3980
Ady Abrahameca9d752021-03-03 12:20:00 -08003981 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003982 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003983 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003984 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003985 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003986 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003987
3988 static_cast<void>(
3989 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003990 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08003991}
3992
3993TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3994 perLayerNeedsFilteringUsedToGenerateRequests) {
3995 mOutput.mState.needsFiltering = false;
3996 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3997
Lloyd Piquea4863342019-12-04 18:45:02 -08003998 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3999 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004000 true, /* needs filtering */
4001 false, /* secure */
4002 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004003 kDisplayViewport,
4004 kDisplayDataspace,
4005 true /* realContentIsVisible */,
4006 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004007 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004008 };
4009 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4010 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004011 false, /* needs filtering */
4012 false, /* secure */
4013 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004014 kDisplayViewport,
4015 kDisplayDataspace,
4016 true /* realContentIsVisible */,
4017 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004018 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004019 };
4020 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4021 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004022 false, /* needs filtering */
4023 false, /* secure */
4024 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004025 kDisplayViewport,
4026 kDisplayDataspace,
4027 true /* realContentIsVisible */,
4028 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004029 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 };
4031
Ady Abrahameca9d752021-03-03 12:20:00 -08004032 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004033 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004034 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004035 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004036 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004037 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004038
4039 static_cast<void>(
4040 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004041 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004042}
4043
4044TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4045 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4046 mOutput.mState.needsFiltering = true;
4047 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4048
Lloyd Piquea4863342019-12-04 18:45:02 -08004049 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4050 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004051 true, /* needs filtering */
4052 false, /* secure */
4053 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004054 kDisplayViewport,
4055 kDisplayDataspace,
4056 true /* realContentIsVisible */,
4057 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004058 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004059
Lloyd Piquea4863342019-12-04 18:45:02 -08004060 };
4061 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4062 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004063 true, /* needs filtering */
4064 false, /* secure */
4065 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004066 kDisplayViewport,
4067 kDisplayDataspace,
4068 true /* realContentIsVisible */,
4069 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004070 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004071 };
4072 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4073 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004074 true, /* needs filtering */
4075 false, /* secure */
4076 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004077 kDisplayViewport,
4078 kDisplayDataspace,
4079 true /* realContentIsVisible */,
4080 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004081 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004082 };
4083
Ady Abrahameca9d752021-03-03 12:20:00 -08004084 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004085 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004086 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004087 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004088 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004089 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004090
4091 static_cast<void>(
4092 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004093 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004094}
4095
4096TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4097 wholeOutputSecurityUsedToGenerateRequests) {
4098 mOutput.mState.isSecure = true;
4099
Lloyd Piquea4863342019-12-04 18:45:02 -08004100 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4101 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004102 false, /* needs filtering */
4103 true, /* secure */
4104 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004105 kDisplayViewport,
4106 kDisplayDataspace,
4107 true /* realContentIsVisible */,
4108 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004109 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004110 };
4111 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4112 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004113 false, /* needs filtering */
4114 true, /* secure */
4115 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004116 kDisplayViewport,
4117 kDisplayDataspace,
4118 true /* realContentIsVisible */,
4119 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004120 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004121 };
4122 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4123 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004124 false, /* needs filtering */
4125 true, /* secure */
4126 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004127 kDisplayViewport,
4128 kDisplayDataspace,
4129 true /* realContentIsVisible */,
4130 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004131 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004132 };
4133
Ady Abrahameca9d752021-03-03 12:20:00 -08004134 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004135 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004136 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004137 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004138 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004139 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004140
4141 static_cast<void>(
4142 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004143 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004144}
4145
4146TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4147 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004148
4149 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4150 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004151 false, /* needs filtering */
4152 false, /* secure */
4153 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004154 kDisplayViewport,
4155 kDisplayDataspace,
4156 true /* realContentIsVisible */,
4157 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004158 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004159 };
4160 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4161 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004162 false, /* needs filtering */
4163 false, /* secure */
4164 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004165 kDisplayViewport,
4166 kDisplayDataspace,
4167 true /* realContentIsVisible */,
4168 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004169 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004170 };
4171 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4172 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004173 false, /* needs filtering */
4174 false, /* secure */
4175 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004176 kDisplayViewport,
4177 kDisplayDataspace,
4178 true /* realContentIsVisible */,
4179 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004180 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004181 };
4182
Ady Abrahameca9d752021-03-03 12:20:00 -08004183 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004184 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004185 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004186 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004187 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004188 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004189
4190 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004191 kDisplayDataspace));
4192}
4193
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004194TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004195 InjectedLayer layer1;
4196 InjectedLayer layer2;
4197 InjectedLayer layer3;
4198
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004199 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004200 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004201 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004202 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004203 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4204 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004205 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004206 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004207 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4208 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004209 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004210 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004211 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4212 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004213
Lloyd Piquede196652020-01-22 17:29:58 -08004214 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004215
Lloyd Piquede196652020-01-22 17:29:58 -08004216 injectOutputLayer(layer1);
4217 injectOutputLayer(layer2);
4218 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004219
4220 mOutput->editState().isEnabled = true;
4221
4222 CompositionRefreshArgs args;
4223 args.updatingGeometryThisFrame = false;
4224 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004225 mOutput->updateCompositionState(args);
4226 mOutput->planComposition();
4227 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004228}
4229
Lucas Dupinc3800b82020-10-02 16:24:48 -07004230TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4231 InjectedLayer layer1;
4232 InjectedLayer layer2;
4233 InjectedLayer layer3;
4234
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004235 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004236 // Layer requesting blur, or below, should request client composition.
4237 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004238 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004239 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4240 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004241 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004242 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004243 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4244 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004245 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004246 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004247 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4248 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004249
4250 BlurRegion region;
4251 layer2.layerFEState.blurRegions.push_back(region);
4252
4253 injectOutputLayer(layer1);
4254 injectOutputLayer(layer2);
4255 injectOutputLayer(layer3);
4256
4257 mOutput->editState().isEnabled = true;
4258
4259 CompositionRefreshArgs args;
4260 args.updatingGeometryThisFrame = false;
4261 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004262 mOutput->updateCompositionState(args);
4263 mOutput->planComposition();
4264 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004265}
4266
Lloyd Piquea4863342019-12-04 18:45:02 -08004267TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4268 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4269 // one layer on the left covering the left side of the output, and one layer
4270 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004271
4272 const Rect kPortraitFrame(0, 0, 1000, 2000);
4273 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004274 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004275 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004276 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004277
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004278 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4279 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4280 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004281 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4282 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004283 mOutput.mState.needsFiltering = false;
4284 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004285
Lloyd Piquea4863342019-12-04 18:45:02 -08004286 Layer leftLayer;
4287 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004288
Lloyd Piquea4863342019-12-04 18:45:02 -08004289 leftLayer.mOutputLayerState.clearClientTarget = false;
4290 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4291 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004292 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004293
Lloyd Piquea4863342019-12-04 18:45:02 -08004294 rightLayer.mOutputLayerState.clearClientTarget = false;
4295 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4296 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004297 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004298
4299 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4300 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4301 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4302 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4303 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4304
Lloyd Piquea4863342019-12-04 18:45:02 -08004305 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4306 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004307 false, /* needs filtering */
4308 true, /* secure */
4309 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004310 kPortraitViewport,
4311 kOutputDataspace,
4312 true /* realContentIsVisible */,
4313 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004314 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004315 };
4316
4317 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4318 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004319 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004320 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004321
4322 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4323 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004324 false, /* needs filtering */
4325 true, /* secure */
4326 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004327 kPortraitViewport,
4328 kOutputDataspace,
4329 true /* realContentIsVisible */,
4330 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004331 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004332 };
4333
4334 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4335 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004336 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004337 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004338
4339 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004340 auto requests =
4341 mOutput.generateClientCompositionRequests(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004342 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004343 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4344 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004345}
4346
Vishnu Naira483b4a2019-12-12 15:07:52 -08004347TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4348 shadowRegionOnlyVisibleSkipsContentComposition) {
4349 const Rect kContentWithShadow(40, 40, 70, 90);
4350 const Rect kContent(50, 50, 60, 80);
4351 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4352 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4353
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004354 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4355 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004356 false, /* needs filtering */
4357 false, /* secure */
4358 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004359 kDisplayViewport,
4360 kDisplayDataspace,
4361 false /* realContentIsVisible */,
4362 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004363 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004364 };
4365
Vishnu Nair9b079a22020-01-21 14:36:08 -08004366 LayerFE::LayerSettings mShadowSettings;
4367 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004368
4369 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4370 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4371
4372 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4373 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004374 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004375 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004376
Vishnu Naira483b4a2019-12-12 15:07:52 -08004377 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004378 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004379 ASSERT_EQ(1u, requests.size());
4380
Vishnu Nair9b079a22020-01-21 14:36:08 -08004381 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004382}
4383
4384TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4385 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4386 const Rect kContentWithShadow(40, 40, 70, 90);
4387 const Rect kContent(50, 50, 60, 80);
4388 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4389 const Region kPartialContentWithPartialShadowRegion =
4390 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4391
Vishnu Nair9b079a22020-01-21 14:36:08 -08004392 LayerFE::LayerSettings mShadowSettings;
4393 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004394
4395 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4396 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4397
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004398 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4399 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004400 false, /* needs filtering */
4401 false, /* secure */
4402 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004403 kDisplayViewport,
4404 kDisplayDataspace,
4405 true /* realContentIsVisible */,
4406 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004407 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004408 };
4409
Vishnu Naira483b4a2019-12-12 15:07:52 -08004410 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4411 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004412 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004413 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4414 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004415
Vishnu Naira483b4a2019-12-12 15:07:52 -08004416 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004417 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004418 ASSERT_EQ(2u, requests.size());
4419
Vishnu Nair9b079a22020-01-21 14:36:08 -08004420 EXPECT_EQ(mShadowSettings, requests[0]);
4421 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004422}
4423
Lloyd Pique32cbe282018-10-19 13:09:22 -07004424} // namespace
4425} // namespace android::compositionengine