blob: 6c510eb99afd29930b2e25c67b3f898914489240 [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"
Alec Mouria90a5702021-04-16 16:36:21 +000038#include "renderengine/ExternalTexture.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070039
40namespace android::compositionengine {
41namespace {
42
Lloyd Pique56eba802019-08-28 15:45:25 -070043using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080044using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080045using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080046using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080047using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080048using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080049using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080050using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::Invoke;
52using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080053using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080054using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080055using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080056using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070057using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070058using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080059using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070060using testing::StrictMock;
61
Lloyd Pique56eba802019-08-28 15:45:25 -070062constexpr auto TR_IDENT = 0u;
63constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080064constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070065
Lloyd Pique3eb1b212019-03-07 21:15:40 -080066const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080067const mat4 kNonIdentityHalf = mat4() * 0.5f;
68const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069
Lloyd Pique17ca7422019-11-14 14:24:10 -080070constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
71 static_cast<OutputColorSetting>(0x100);
72
Lloyd Piquefaa3f192019-11-14 14:05:09 -080073struct OutputPartialMockBase : public impl::Output {
74 // compositionengine::Output overrides
75 const OutputCompositionState& getState() const override { return mState; }
76 OutputCompositionState& editState() override { return mState; }
77
78 // Use mocks for all the remaining virtual functions
79 // not implemented by the base implementation class.
80 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
81 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080082 MOCK_METHOD2(ensureOutputLayer,
83 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080084 MOCK_METHOD0(finalizePendingOutputLayers, void());
85 MOCK_METHOD0(clearOutputLayers, void());
86 MOCK_CONST_METHOD1(dumpState, void(std::string&));
87 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080088 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080089 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
90
91 impl::OutputCompositionState mState;
92};
93
Lloyd Piquede196652020-01-22 17:29:58 -080094struct InjectedLayer {
95 InjectedLayer() {
96 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
97 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
98 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
99
100 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800101 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
102 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800103 }
104
105 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
106 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
107 LayerFECompositionState layerFEState;
108 impl::OutputLayerCompositionState outputLayerState;
109};
110
111struct NonInjectedLayer {
112 NonInjectedLayer() {
113 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
114 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
115 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
116
117 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800118 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
119 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800120 }
121
122 mock::OutputLayer outputLayer;
123 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
124 LayerFECompositionState layerFEState;
125 impl::OutputLayerCompositionState outputLayerState;
126};
127
Lloyd Pique66d68602019-02-13 14:23:31 -0800128struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700129 class Output : public impl::Output {
130 public:
131 using impl::Output::injectOutputLayerForTest;
132 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
133 };
134
135 static std::shared_ptr<Output> createOutput(
136 const compositionengine::CompositionEngine& compositionEngine) {
137 return impl::createOutputTemplated<Output>(compositionEngine);
138 }
139
Lloyd Pique31cb2942018-10-19 17:23:03 -0700140 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700141 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700142 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700143 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800144
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200145 mOutput->editState().displaySpace.bounds = kDefaultDisplaySize;
Alec Mouridf6201b2021-06-01 16:20:42 -0700146 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700147 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700148
Lloyd Piquede196652020-01-22 17:29:58 -0800149 void injectOutputLayer(InjectedLayer& layer) {
150 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
151 }
152
153 void injectNullOutputLayer() {
154 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
155 }
156
Lloyd Piqueef958122019-02-05 18:00:12 -0800157 static const Rect kDefaultDisplaySize;
158
Lloyd Pique32cbe282018-10-19 13:09:22 -0700159 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700160 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700161 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700162 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700163 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700164};
165
Lloyd Piqueef958122019-02-05 18:00:12 -0800166const Rect OutputTest::kDefaultDisplaySize{100, 200};
167
Lloyd Pique17ca7422019-11-14 14:24:10 -0800168using ColorProfile = compositionengine::Output::ColorProfile;
169
170void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
171 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
172 toString(profile.mode).c_str(), profile.mode,
173 toString(profile.dataspace).c_str(), profile.dataspace,
174 toString(profile.renderIntent).c_str(), profile.renderIntent,
175 toString(profile.colorSpaceAgnosticDataspace).c_str(),
176 profile.colorSpaceAgnosticDataspace);
177}
178
179// Checks for a ColorProfile match
180MATCHER_P(ColorProfileEq, expected, "") {
181 std::string buf;
182 buf.append("ColorProfiles are not equal\n");
183 dumpColorProfile(expected, buf, "expected value");
184 dumpColorProfile(arg, buf, "actual value");
185 *result_listener << buf;
186
187 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
188 (expected.renderIntent == arg.renderIntent) &&
189 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
190}
191
Lloyd Pique66d68602019-02-13 14:23:31 -0800192/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700193 * Basic construction
194 */
195
Lloyd Pique31cb2942018-10-19 17:23:03 -0700196TEST_F(OutputTest, canInstantiateOutput) {
197 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700198 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700199 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
200
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700201 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700202
203 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700204 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700205
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700206 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
207
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700210
Lloyd Pique66d68602019-02-13 14:23:31 -0800211/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700212 * Output::setCompositionEnabled()
213 */
214
215TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700216 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700217
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700218 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700219
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700220 EXPECT_TRUE(mOutput->getState().isEnabled);
221 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700222}
223
224TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700225 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700227 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700228
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 EXPECT_TRUE(mOutput->getState().isEnabled);
230 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700231}
232
233TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700234 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700236 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700237
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 EXPECT_FALSE(mOutput->getState().isEnabled);
239 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700240}
241
Lloyd Pique66d68602019-02-13 14:23:31 -0800242/*
Alec Mouri023c1882021-05-08 16:36:33 -0700243 * Output::setLayerCachingEnabled()
244 */
245
246TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
247 const auto kSize = ui::Size(1, 1);
248 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
249 mOutput->setLayerCachingEnabled(false);
250 mOutput->setLayerCachingEnabled(true);
251
252 EXPECT_TRUE(mOutput->plannerEnabled());
253}
254
255TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
256 const auto kSize = ui::Size(1, 1);
257 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
258 mOutput->setLayerCachingEnabled(true);
259 mOutput->setLayerCachingEnabled(false);
260
261 EXPECT_FALSE(mOutput->plannerEnabled());
262}
263
Alec Mouric773472b2021-05-19 14:29:05 -0700264TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
265 renderengine::mock::RenderEngine renderEngine;
266 const auto kSize = ui::Size(1, 1);
267 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
268 mOutput->setLayerCachingEnabled(true);
269
270 // Inject some layers
271 InjectedLayer layer;
272 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
273 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
274 renderengine::ExternalTexture::Usage::READABLE |
275 renderengine::ExternalTexture::Usage::WRITEABLE);
276 injectOutputLayer(layer);
277 // inject a null layer to check for null exceptions
278 injectNullOutputLayer();
279
280 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
281 mOutput->setLayerCachingEnabled(false);
282 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
283}
284
Alec Mouri023c1882021-05-08 16:36:33 -0700285/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700286 * Output::setProjection()
287 */
288
Marin Shalamanov209ae612020-10-01 00:17:39 +0200289TEST_F(OutputTest, setProjectionWorks) {
290 const Rect displayRect{0, 0, 1000, 2000};
291 mOutput->editState().displaySpace.bounds = displayRect;
292 mOutput->editState().framebufferSpace.bounds = displayRect;
293
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200294 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200295 const Rect frame{50, 60, 100, 100};
296 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700297
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200298 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700299
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200300 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200301 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
302 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200303
304 const auto state = mOutput->getState();
305 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
306 EXPECT_EQ(viewport, state.layerStackSpace.content);
307 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
308
309 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
310 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
311 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
312
313 EXPECT_EQ(displayRect, state.displaySpace.bounds);
314 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
315 EXPECT_EQ(orientation, state.displaySpace.orientation);
316
317 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
318 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.content);
319 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
320
321 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Garfield Tan54edd912020-10-21 16:31:41 -0700322
323 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200324}
325
326TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
327 const Rect displayRect{0, 0, 1000, 2000};
328 const Rect framebufferRect{0, 0, 500, 1000};
329 mOutput->editState().displaySpace.bounds = displayRect;
330 mOutput->editState().framebufferSpace.bounds = framebufferRect;
331
332 const ui::Rotation orientation = ui::ROTATION_90;
333 const Rect frame{50, 60, 100, 100};
334 const Rect viewport{10, 20, 30, 40};
335
336 mOutput->setProjection(orientation, viewport, frame);
337
338 EXPECT_EQ(orientation, mOutput->getState().displaySpace.orientation);
339 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.content);
340 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.content);
341
342 const auto state = mOutput->getState();
343 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
344 EXPECT_EQ(viewport, state.layerStackSpace.content);
345 EXPECT_EQ(viewport, state.layerStackSpace.bounds);
346
347 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
348 EXPECT_EQ(frame, state.orientedDisplaySpace.content);
349 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.bounds);
350
351 EXPECT_EQ(displayRect, state.displaySpace.bounds);
352 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.content);
353 EXPECT_EQ(orientation, state.displaySpace.orientation);
354
355 EXPECT_EQ(framebufferRect, state.framebufferSpace.bounds);
356 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.content);
357 EXPECT_EQ(orientation, state.framebufferSpace.orientation);
358
359 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700360}
361
Lloyd Pique66d68602019-02-13 14:23:31 -0800362/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200363 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700364 */
365
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200366TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
367 mOutput->editState().layerStackSpace.content = Rect(0, 0, 2000, 1000);
368 mOutput->editState().layerStackSpace.bounds = Rect(0, 0, 2000, 1000);
369 mOutput->editState().orientedDisplaySpace.content = Rect(0, 0, 1800, 900);
370 mOutput->editState().orientedDisplaySpace.bounds = Rect(0, 0, 2000, 1000);
371 mOutput->editState().framebufferSpace.content = Rect(0, 0, 900, 1800);
372 mOutput->editState().framebufferSpace.bounds = Rect(0, 0, 1000, 2000);
373 mOutput->editState().framebufferSpace.orientation = ui::ROTATION_90;
374 mOutput->editState().displaySpace.content = Rect(0, 0, 900, 1800);
375 mOutput->editState().displaySpace.bounds = Rect(0, 0, 1000, 2000);
376 mOutput->editState().displaySpace.orientation = ui::ROTATION_90;
Lloyd Pique31cb2942018-10-19 17:23:03 -0700377
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200378 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700379
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200380 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700381
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200382 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700383
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200384 const auto state = mOutput->getState();
385
386 const Rect displayRect(newDisplaySize);
387 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.orientation);
388 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.content);
389 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200390
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.orientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200392 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.bounds);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200393
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200394 EXPECT_EQ(displayRect, state.displaySpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.orientation);
Marin Shalamanov209ae612020-10-01 00:17:39 +0200396
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200397 EXPECT_EQ(displayRect, state.framebufferSpace.bounds);
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200398 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.orientation);
399
400 EXPECT_EQ(state.displaySpace.content, state.transform.transform(state.layerStackSpace.content));
401
402 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700403}
404
Lloyd Pique66d68602019-02-13 14:23:31 -0800405/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700406 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700407 */
408
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700409TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
410 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
411 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700412
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700413 const auto& state = mOutput->getState();
414 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
415 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700416
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700417 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700418}
419
Lloyd Pique66d68602019-02-13 14:23:31 -0800420/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700421 * Output::setColorTransform
422 */
423
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800424TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700425 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700426
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800427 // If no colorTransformMatrix is set the update should be skipped.
428 CompositionRefreshArgs refreshArgs;
429 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700430
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700431 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700432
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800433 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700434 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800435
436 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700437 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800438}
Lloyd Piqueef958122019-02-05 18:00:12 -0800439
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800440TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700441 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800443 // Attempting to set the same colorTransformMatrix that is already set should
444 // also skip the update.
445 CompositionRefreshArgs refreshArgs;
446 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700447
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700448 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700449
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800450 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700451 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452
453 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700454 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800455}
456
457TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700458 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800459
460 // Setting a different colorTransformMatrix should perform the update.
461 CompositionRefreshArgs refreshArgs;
462 refreshArgs.colorTransformMatrix = kIdentity;
463
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700464 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800465
466 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700467 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800468
469 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700472
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800473TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700474 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700475
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800476 // Setting a different colorTransformMatrix should perform the update.
477 CompositionRefreshArgs refreshArgs;
478 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700479
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700480 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800481
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800482 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700483 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800484
485 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800487}
488
489TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700490 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800491
492 // Setting a different colorTransformMatrix should perform the update.
493 CompositionRefreshArgs refreshArgs;
494 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
495
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700496 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800497
498 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700499 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800500
501 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700503}
504
Lloyd Pique66d68602019-02-13 14:23:31 -0800505/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800506 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700507 */
508
Lloyd Pique17ca7422019-11-14 14:24:10 -0800509using OutputSetColorProfileTest = OutputTest;
510
511TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800512 using ColorProfile = Output::ColorProfile;
513
Lloyd Piquef5275482019-01-29 18:42:42 -0800514 EXPECT_CALL(*mDisplayColorProfile,
515 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
516 ui::Dataspace::UNKNOWN))
517 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800518 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700519
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700520 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
521 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
522 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700523
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700524 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
525 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
526 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
527 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800528
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700529 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800530}
531
Lloyd Pique17ca7422019-11-14 14:24:10 -0800532TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800533 using ColorProfile = Output::ColorProfile;
534
Lloyd Piquef5275482019-01-29 18:42:42 -0800535 EXPECT_CALL(*mDisplayColorProfile,
536 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
537 ui::Dataspace::UNKNOWN))
538 .WillOnce(Return(ui::Dataspace::UNKNOWN));
539
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700540 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
541 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
542 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
543 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800544
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700545 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
546 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
547 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800548
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700549 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700550}
551
Lloyd Pique66d68602019-02-13 14:23:31 -0800552/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700553 * Output::setRenderSurface()
554 */
555
556TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
557 const ui::Size newDisplaySize{640, 480};
558
559 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
560 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
561
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700562 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700563
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200564 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700565}
566
Lloyd Pique66d68602019-02-13 14:23:31 -0800567/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000568 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700569 */
570
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700571TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000572 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200573 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700575
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700576 // The dirty region should be clipped to the display bounds.
577 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700578}
579
Lloyd Pique66d68602019-02-13 14:23:31 -0800580/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700581 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800582 */
583
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700584TEST_F(OutputTest, layerFiltering) {
585 const ui::LayerStack layerStack1{123u};
586 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800587
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700588 // If the output is associated to layerStack1 and to an internal display...
589 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800590
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700591 // It excludes layers with no layer stack, internal-only or not.
592 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
593 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800594
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700595 // It includes layers on layerStack1, internal-only or not.
596 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
597 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
598 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
599 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800600
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700601 // If the output is associated to layerStack1 but not to an internal display...
602 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800603
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700604 // It includes layers on layerStack1, unless they are internal-only.
605 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
606 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
607 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
608 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800609}
610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800612 NonInjectedLayer layer;
613 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800614
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700615 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800616 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700617 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800618}
619
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700620TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800621 NonInjectedLayer layer;
622 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800623
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700624 const ui::LayerStack layerStack1{123u};
625 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800626
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627 // If the output is associated to layerStack1 and to an internal display...
628 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800629
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700630 // It excludes layers with no layer stack, internal-only or not.
631 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
632 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800633
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700634 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
635 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800636
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700637 // It includes layers on layerStack1, internal-only or not.
638 layer.layerFEState.outputFilter = {layerStack1, false};
639 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800640
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700641 layer.layerFEState.outputFilter = {layerStack1, true};
642 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800643
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700644 layer.layerFEState.outputFilter = {layerStack2, true};
645 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800646
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647 layer.layerFEState.outputFilter = {layerStack2, false};
648 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650 // If the output is associated to layerStack1 but not to an internal display...
651 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 // It includes layers on layerStack1, unless they are internal-only.
654 layer.layerFEState.outputFilter = {layerStack1, false};
655 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 layer.layerFEState.outputFilter = {layerStack1, true};
658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660 layer.layerFEState.outputFilter = {layerStack2, true};
661 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800662
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700663 layer.layerFEState.outputFilter = {layerStack2, false};
664 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800665}
666
Lloyd Pique66d68602019-02-13 14:23:31 -0800667/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800668 * Output::getOutputLayerForLayer()
669 */
670
671TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800672 InjectedLayer layer1;
673 InjectedLayer layer2;
674 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800675
Lloyd Piquede196652020-01-22 17:29:58 -0800676 injectOutputLayer(layer1);
677 injectNullOutputLayer();
678 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800679
680 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800681 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
682 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800683
684 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800685 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
686 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
687 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800688
689 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800690 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
691 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
692 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800693}
694
Lloyd Pique66d68602019-02-13 14:23:31 -0800695/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800696 * Output::setReleasedLayers()
697 */
698
699using OutputSetReleasedLayersTest = OutputTest;
700
701TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
702 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
703 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
704 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
705
706 Output::ReleasedLayers layers;
707 layers.push_back(layer1FE);
708 layers.push_back(layer2FE);
709 layers.push_back(layer3FE);
710
711 mOutput->setReleasedLayers(std::move(layers));
712
713 const auto& setLayers = mOutput->getReleasedLayersForTest();
714 ASSERT_EQ(3u, setLayers.size());
715 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
716 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
717 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
718}
719
720/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800721 * Output::updateLayerStateFromFE()
722 */
723
Lloyd Piquede196652020-01-22 17:29:58 -0800724using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800725
726TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
727 CompositionRefreshArgs refreshArgs;
728
729 mOutput->updateLayerStateFromFE(refreshArgs);
730}
731
Lloyd Piquede196652020-01-22 17:29:58 -0800732TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
733 InjectedLayer layer1;
734 InjectedLayer layer2;
735 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800736
Lloyd Piquede196652020-01-22 17:29:58 -0800737 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
738 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
739 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
740
741 injectOutputLayer(layer1);
742 injectOutputLayer(layer2);
743 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800744
745 CompositionRefreshArgs refreshArgs;
746 refreshArgs.updatingGeometryThisFrame = false;
747
748 mOutput->updateLayerStateFromFE(refreshArgs);
749}
750
Lloyd Piquede196652020-01-22 17:29:58 -0800751TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
752 InjectedLayer layer1;
753 InjectedLayer layer2;
754 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800755
Lloyd Piquede196652020-01-22 17:29:58 -0800756 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
757 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
758 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
759
760 injectOutputLayer(layer1);
761 injectOutputLayer(layer2);
762 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800763
764 CompositionRefreshArgs refreshArgs;
765 refreshArgs.updatingGeometryThisFrame = true;
766
767 mOutput->updateLayerStateFromFE(refreshArgs);
768}
769
770/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800771 * Output::updateAndWriteCompositionState()
772 */
773
Lloyd Piquede196652020-01-22 17:29:58 -0800774using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800775
776TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
777 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800778
779 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800780 mOutput->updateCompositionState(args);
781 mOutput->planComposition();
782 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800783}
784
Lloyd Piqueef63b612019-11-14 13:19:56 -0800785TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800786 InjectedLayer layer1;
787 InjectedLayer layer2;
788 InjectedLayer layer3;
789
Lloyd Piqueef63b612019-11-14 13:19:56 -0800790 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800791
Lloyd Piquede196652020-01-22 17:29:58 -0800792 injectOutputLayer(layer1);
793 injectOutputLayer(layer2);
794 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800795
796 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800797 mOutput->updateCompositionState(args);
798 mOutput->planComposition();
799 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800800}
801
802TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800803 InjectedLayer layer1;
804 InjectedLayer layer2;
805 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800806
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400807 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200808 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800809 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400810 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
811 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200812 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800813 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400814 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
815 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200816 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800817 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400818 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
819 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800820
821 injectOutputLayer(layer1);
822 injectOutputLayer(layer2);
823 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800824
825 mOutput->editState().isEnabled = true;
826
827 CompositionRefreshArgs args;
828 args.updatingGeometryThisFrame = false;
829 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200830 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800831 mOutput->updateCompositionState(args);
832 mOutput->planComposition();
833 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800834}
835
836TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800837 InjectedLayer layer1;
838 InjectedLayer layer2;
839 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800840
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400841 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200842 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800843 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400844 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
845 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200846 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800847 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400848 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
849 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200850 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800851 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400852 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
853 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800854
855 injectOutputLayer(layer1);
856 injectOutputLayer(layer2);
857 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800858
859 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800860
861 CompositionRefreshArgs args;
862 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800863 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800864 mOutput->updateCompositionState(args);
865 mOutput->planComposition();
866 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800867}
868
869TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800870 InjectedLayer layer1;
871 InjectedLayer layer2;
872 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800873
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400874 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200875 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800876 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400877 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
878 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200879 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800880 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400881 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
882 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200883 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800884 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400885 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
886 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800887
888 injectOutputLayer(layer1);
889 injectOutputLayer(layer2);
890 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800891
892 mOutput->editState().isEnabled = true;
893
894 CompositionRefreshArgs args;
895 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800896 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800897 mOutput->updateCompositionState(args);
898 mOutput->planComposition();
899 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800900}
901
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400902TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
903 renderengine::mock::RenderEngine renderEngine;
904 InjectedLayer layer0;
905 InjectedLayer layer1;
906 InjectedLayer layer2;
907 InjectedLayer layer3;
908
909 InSequence seq;
910 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
911 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
912 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
913 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
914
915 uint32_t z = 0;
916 EXPECT_CALL(*layer0.outputLayer,
917 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
918 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
919
920 // After calling planComposition (which clears overrideInfo), this test sets
921 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
922 // comes first, setting isPeekingThrough to true and zIsOverridden to true
923 // for it and the following layers.
924 EXPECT_CALL(*layer3.outputLayer,
925 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
926 /*zIsOverridden*/ true, /*isPeekingThrough*/
927 true));
928 EXPECT_CALL(*layer1.outputLayer,
929 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
930 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
931 EXPECT_CALL(*layer2.outputLayer,
932 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
933 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
934
935 injectOutputLayer(layer0);
936 injectOutputLayer(layer1);
937 injectOutputLayer(layer2);
938 injectOutputLayer(layer3);
939
940 mOutput->editState().isEnabled = true;
941
942 CompositionRefreshArgs args;
943 args.updatingGeometryThisFrame = true;
944 args.devOptForceClientComposition = false;
945 mOutput->updateCompositionState(args);
946 mOutput->planComposition();
947
948 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
949 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
950 renderengine::ExternalTexture::Usage::READABLE |
951 renderengine::ExternalTexture::Usage::WRITEABLE);
952 layer1.outputLayerState.overrideInfo.buffer = buffer;
953 layer2.outputLayerState.overrideInfo.buffer = buffer;
954 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
955 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
956
957 mOutput->writeCompositionState(args);
958}
959
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800960/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800961 * Output::prepareFrame()
962 */
963
964struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800965 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800966 // Sets up the helper functions called by the function under test to use
967 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800968 MOCK_METHOD0(chooseCompositionStrategy, void());
969 };
970
971 OutputPrepareFrameTest() {
972 mOutput.setDisplayColorProfileForTest(
973 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
974 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
975 }
976
977 StrictMock<mock::CompositionEngine> mCompositionEngine;
978 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
979 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700980 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800981};
982
983TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
984 mOutput.editState().isEnabled = false;
985
986 mOutput.prepareFrame();
987}
988
989TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
990 mOutput.editState().isEnabled = true;
991 mOutput.editState().usesClientComposition = false;
992 mOutput.editState().usesDeviceComposition = true;
993
994 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -0700995 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -0800996 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
997
998 mOutput.prepareFrame();
999}
1000
1001// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1002// base chooseCompositionStrategy() is invoked.
1003TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001004 mOutput->editState().isEnabled = true;
1005 mOutput->editState().usesClientComposition = false;
1006 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001007
1008 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1009
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001010 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001011
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001012 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1013 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001014}
1015
Lloyd Pique56eba802019-08-28 15:45:25 -07001016/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001017 * Output::prepare()
1018 */
1019
1020struct OutputPrepareTest : public testing::Test {
1021 struct OutputPartialMock : public OutputPartialMockBase {
1022 // Sets up the helper functions called by the function under test to use
1023 // mock implementations.
1024 MOCK_METHOD2(rebuildLayerStacks,
1025 void(const compositionengine::CompositionRefreshArgs&,
1026 compositionengine::LayerFESet&));
1027 };
1028
1029 StrictMock<OutputPartialMock> mOutput;
1030 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001031 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001032};
1033
1034TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1035 InSequence seq;
1036 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1037
1038 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1039}
1040
1041/*
1042 * Output::rebuildLayerStacks()
1043 */
1044
1045struct OutputRebuildLayerStacksTest : public testing::Test {
1046 struct OutputPartialMock : public OutputPartialMockBase {
1047 // Sets up the helper functions called by the function under test to use
1048 // mock implementations.
1049 MOCK_METHOD2(collectVisibleLayers,
1050 void(const compositionengine::CompositionRefreshArgs&,
1051 compositionengine::Output::CoverageState&));
1052 };
1053
1054 OutputRebuildLayerStacksTest() {
1055 mOutput.mState.isEnabled = true;
1056 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001057 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001058
1059 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1060
1061 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1062
1063 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1064 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1065 }
1066
1067 void setTestCoverageValues(const CompositionRefreshArgs&,
1068 compositionengine::Output::CoverageState& state) {
1069 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1070 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1071 state.dirtyRegion = mCoverageDirtyRegionToSet;
1072 }
1073
1074 static const ui::Transform kIdentityTransform;
1075 static const ui::Transform kRotate90Transform;
1076 static const Rect kOutputBounds;
1077
1078 StrictMock<OutputPartialMock> mOutput;
1079 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001080 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001081 Region mCoverageAboveCoveredLayersToSet;
1082 Region mCoverageAboveOpaqueLayersToSet;
1083 Region mCoverageDirtyRegionToSet;
1084};
1085
1086const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1087const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1088const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1089
1090TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1091 mOutput.mState.isEnabled = false;
1092
1093 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1094}
1095
1096TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1097 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1098
1099 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1100}
1101
1102TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1103 mOutput.mState.transform = kIdentityTransform;
1104
1105 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1106
1107 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1108
1109 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1110}
1111
1112TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1113 mOutput.mState.transform = kIdentityTransform;
1114
1115 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1116
1117 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1118
1119 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1120}
1121
1122TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1123 mOutput.mState.transform = kRotate90Transform;
1124
1125 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1126
1127 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1128
1129 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1130}
1131
1132TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1133 mOutput.mState.transform = kRotate90Transform;
1134
1135 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1136
1137 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1138
1139 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1140}
1141
1142TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1143 mOutput.mState.transform = kIdentityTransform;
1144 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1145
1146 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1147
1148 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1149
1150 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1151}
1152
1153TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1154 mOutput.mState.transform = kRotate90Transform;
1155 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1156
1157 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1158
1159 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1160
1161 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1162}
1163
1164/*
1165 * Output::collectVisibleLayers()
1166 */
1167
Lloyd Pique1ef93222019-11-21 16:41:53 -08001168struct OutputCollectVisibleLayersTest : public testing::Test {
1169 struct OutputPartialMock : public OutputPartialMockBase {
1170 // Sets up the helper functions called by the function under test to use
1171 // mock implementations.
1172 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001173 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001174 compositionengine::Output::CoverageState&));
1175 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1176 MOCK_METHOD0(finalizePendingOutputLayers, void());
1177 };
1178
1179 struct Layer {
1180 Layer() {
1181 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1182 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1183 }
1184
1185 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001186 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001187 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001188 };
1189
1190 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001191 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001192 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1193 .WillRepeatedly(Return(&mLayer1.outputLayer));
1194 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1195 .WillRepeatedly(Return(&mLayer2.outputLayer));
1196 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1197 .WillRepeatedly(Return(&mLayer3.outputLayer));
1198
Lloyd Piquede196652020-01-22 17:29:58 -08001199 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1200 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1201 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001202 }
1203
1204 StrictMock<OutputPartialMock> mOutput;
1205 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001206 LayerFESet mGeomSnapshots;
1207 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001208 Layer mLayer1;
1209 Layer mLayer2;
1210 Layer mLayer3;
1211};
1212
1213TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1214 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001215 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001216
1217 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1218 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1219
1220 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1221}
1222
1223TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1224 // Enforce a call order sequence for this test.
1225 InSequence seq;
1226
1227 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001228 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1229 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1230 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001231
1232 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1233 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1234
1235 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001236}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001237
1238/*
1239 * Output::ensureOutputLayerIfVisible()
1240 */
1241
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001242struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1243 struct OutputPartialMock : public OutputPartialMockBase {
1244 // Sets up the helper functions called by the function under test to use
1245 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001246 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1247 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001248 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001249 MOCK_METHOD2(ensureOutputLayer,
1250 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001251 };
1252
1253 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001254 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001255 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001256 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001257 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001258 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001259
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001260 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1261 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001262 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1263
Lloyd Piquede196652020-01-22 17:29:58 -08001264 mLayer.layerFEState.isVisible = true;
1265 mLayer.layerFEState.isOpaque = true;
1266 mLayer.layerFEState.contentDirty = true;
1267 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1268 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1269 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001270
Lloyd Piquede196652020-01-22 17:29:58 -08001271 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1272 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273
Lloyd Piquede196652020-01-22 17:29:58 -08001274 mGeomSnapshots.insert(mLayer.layerFE);
1275 }
1276
1277 void ensureOutputLayerIfVisible() {
1278 sp<LayerFE> layerFE(mLayer.layerFE);
1279 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001280 }
1281
1282 static const Region kEmptyRegion;
1283 static const Region kFullBoundsNoRotation;
1284 static const Region kRightHalfBoundsNoRotation;
1285 static const Region kLowerHalfBoundsNoRotation;
1286 static const Region kFullBounds90Rotation;
1287
1288 StrictMock<OutputPartialMock> mOutput;
1289 LayerFESet mGeomSnapshots;
1290 Output::CoverageState mCoverageState{mGeomSnapshots};
1291
Lloyd Piquede196652020-01-22 17:29:58 -08001292 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001293};
1294
1295const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1296const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1297 Region(Rect(0, 0, 100, 200));
1298const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1299 Region(Rect(0, 100, 100, 200));
1300const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1301 Region(Rect(50, 0, 100, 200));
1302const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1303 Region(Rect(0, 0, 200, 100));
1304
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001305TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1306 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001307 EXPECT_CALL(*mLayer.layerFE,
1308 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001309
1310 mGeomSnapshots.clear();
1311
Lloyd Piquede196652020-01-22 17:29:58 -08001312 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001313}
1314
1315TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001316 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1317 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001318
Lloyd Piquede196652020-01-22 17:29:58 -08001319 ensureOutputLayerIfVisible();
1320}
1321
1322TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1323 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1324
1325 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001326}
1327
1328TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001329 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001330
Lloyd Piquede196652020-01-22 17:29:58 -08001331 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332}
1333
1334TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001335 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001336
Lloyd Piquede196652020-01-22 17:29:58 -08001337 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001338}
1339
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001340TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001341 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001344}
1345
1346TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1347 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001348 mLayer.layerFEState.isOpaque = true;
1349 mLayer.layerFEState.contentDirty = true;
1350 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001351
1352 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001353 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1354 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001355
Lloyd Piquede196652020-01-22 17:29:58 -08001356 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357
1358 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1359 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1360 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1361
Lloyd Piquede196652020-01-22 17:29:58 -08001362 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1363 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1364 RegionEq(kFullBoundsNoRotation));
1365 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1366 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001367}
1368
1369TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1370 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001371 mLayer.layerFEState.isOpaque = true;
1372 mLayer.layerFEState.contentDirty = true;
1373 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001374
Lloyd Piquede196652020-01-22 17:29:58 -08001375 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1376 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001377
Lloyd Piquede196652020-01-22 17:29:58 -08001378 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
1380 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1381 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1382 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1383
Lloyd Piquede196652020-01-22 17:29:58 -08001384 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1385 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1386 RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1388 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001389}
1390
1391TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1392 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001393 mLayer.layerFEState.isOpaque = false;
1394 mLayer.layerFEState.contentDirty = true;
1395 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001396
1397 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001398 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1399 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001400
Lloyd Piquede196652020-01-22 17:29:58 -08001401 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001402
1403 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1404 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1405 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1406
Lloyd Piquede196652020-01-22 17:29:58 -08001407 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1408 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001409 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001410 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1411 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412}
1413
1414TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1415 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001416 mLayer.layerFEState.isOpaque = false;
1417 mLayer.layerFEState.contentDirty = true;
1418 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001419
Lloyd Piquede196652020-01-22 17:29:58 -08001420 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1421 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424
1425 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1426 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1427 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1428
Lloyd Piquede196652020-01-22 17:29:58 -08001429 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1430 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001432 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1433 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001434}
1435
1436TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1437 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001438 mLayer.layerFEState.isOpaque = true;
1439 mLayer.layerFEState.contentDirty = false;
1440 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001441
1442 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001443 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1444 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445
Lloyd Piquede196652020-01-22 17:29:58 -08001446 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447
1448 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1449 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1450 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1451
Lloyd Piquede196652020-01-22 17:29:58 -08001452 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1453 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1454 RegionEq(kFullBoundsNoRotation));
1455 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1456 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001457}
1458
1459TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1460 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001461 mLayer.layerFEState.isOpaque = true;
1462 mLayer.layerFEState.contentDirty = false;
1463 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001464
Lloyd Piquede196652020-01-22 17:29:58 -08001465 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1466 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
1470 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1471 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1472 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1473
Lloyd Piquede196652020-01-22 17:29:58 -08001474 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1475 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1476 RegionEq(kFullBoundsNoRotation));
1477 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1478 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001479}
1480
1481TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1482 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001483 mLayer.layerFEState.isOpaque = true;
1484 mLayer.layerFEState.contentDirty = true;
1485 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1486 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1487 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1488 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001489
1490 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001491 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1492 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001493
Lloyd Piquede196652020-01-22 17:29:58 -08001494 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495
1496 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1497 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1498 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1499
Lloyd Piquede196652020-01-22 17:29:58 -08001500 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1501 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1502 RegionEq(kFullBoundsNoRotation));
1503 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1504 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505}
1506
1507TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1508 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001509 mLayer.layerFEState.isOpaque = true;
1510 mLayer.layerFEState.contentDirty = true;
1511 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1512 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1513 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1514 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1517 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001518
Lloyd Piquede196652020-01-22 17:29:58 -08001519 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520
1521 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1522 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1523 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1524
Lloyd Piquede196652020-01-22 17:29:58 -08001525 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1526 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1527 RegionEq(kFullBoundsNoRotation));
1528 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1529 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001530}
1531
1532TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1533 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001534 mLayer.layerFEState.isOpaque = true;
1535 mLayer.layerFEState.contentDirty = true;
1536 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001537
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001538 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001539 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1540
1541 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001542 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1543 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544
Lloyd Piquede196652020-01-22 17:29:58 -08001545 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546
1547 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1548 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1549 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1550
Lloyd Piquede196652020-01-22 17:29:58 -08001551 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1552 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1553 RegionEq(kFullBoundsNoRotation));
1554 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1555 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001556}
1557
1558TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1559 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001560 mLayer.layerFEState.isOpaque = true;
1561 mLayer.layerFEState.contentDirty = true;
1562 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001564 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1568 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001569
Lloyd Piquede196652020-01-22 17:29:58 -08001570 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001571
1572 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1573 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1574 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1577 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1578 RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1580 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581}
1582
1583TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1584 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1585 ui::Transform arbitraryTransform;
1586 arbitraryTransform.set(1, 1, -1, 1);
1587 arbitraryTransform.set(0, 100);
1588
Lloyd Piquede196652020-01-22 17:29:58 -08001589 mLayer.layerFEState.isOpaque = true;
1590 mLayer.layerFEState.contentDirty = true;
1591 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1592 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
1594 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001595 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1596 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001597
Lloyd Piquede196652020-01-22 17:29:58 -08001598 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001599
1600 const Region kRegion = Region(Rect(0, 0, 300, 300));
1601 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1602
1603 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1604 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1605 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1606
Lloyd Piquede196652020-01-22 17:29:58 -08001607 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1608 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1609 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1610 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001611}
1612
1613TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001614 mLayer.layerFEState.isOpaque = false;
1615 mLayer.layerFEState.contentDirty = true;
1616 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001617
1618 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1619 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1620 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1621
Lloyd Piquede196652020-01-22 17:29:58 -08001622 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1623 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624
Lloyd Piquede196652020-01-22 17:29:58 -08001625 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001626
1627 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1628 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1629 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1630 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1631 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1632 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1633
1634 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1635 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1636 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1639 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001641 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1642 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1643 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001644}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001645
Vishnu Naira483b4a2019-12-12 15:07:52 -08001646TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1647 ui::Transform translate;
1648 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001649 mLayer.layerFEState.geomLayerTransform = translate;
1650 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001651
1652 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1653 // half of the layer including the casting shadow is covered and opaque
1654 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1655 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1656
Lloyd Piquede196652020-01-22 17:29:58 -08001657 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1658 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001659
Lloyd Piquede196652020-01-22 17:29:58 -08001660 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001661
1662 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1663 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1664 // add starting opaque region to the opaque half of the casting layer bounds
1665 const Region kExpectedAboveOpaqueRegion =
1666 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1667 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1668 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1669 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1670 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1671 const Region kExpectedLayerShadowRegion =
1672 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1673
1674 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1675 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1676 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1677
Lloyd Piquede196652020-01-22 17:29:58 -08001678 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1679 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001680 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001681 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1682 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001683 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001684 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001685 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1686}
1687
1688TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1689 ui::Transform translate;
1690 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001691 mLayer.layerFEState.geomLayerTransform = translate;
1692 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001693
1694 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1695 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1696 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1697 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1698
Lloyd Piquede196652020-01-22 17:29:58 -08001699 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1700 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001701
Lloyd Piquede196652020-01-22 17:29:58 -08001702 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001703
1704 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1705 const Region kExpectedLayerShadowRegion =
1706 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1707
Lloyd Piquede196652020-01-22 17:29:58 -08001708 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1709 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001710 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1711}
1712
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001713TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001714 ui::Transform translate;
1715 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001716 mLayer.layerFEState.geomLayerTransform = translate;
1717 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001718
1719 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1720 // Casting layer and its shadows are covered by an opaque region
1721 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1722 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001725}
1726
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001727/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001728 * Output::present()
1729 */
1730
1731struct OutputPresentTest : public testing::Test {
1732 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001733 // Sets up the helper functions called by the function under test to use
1734 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001735 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001736 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001737 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001738 MOCK_METHOD0(planComposition, void());
1739 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001740 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1741 MOCK_METHOD0(beginFrame, void());
1742 MOCK_METHOD0(prepareFrame, void());
1743 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1744 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1745 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001746 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001747 };
1748
1749 StrictMock<OutputPartialMock> mOutput;
1750};
1751
1752TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1753 CompositionRefreshArgs args;
1754
1755 InSequence seq;
1756 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001757 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1758 EXPECT_CALL(mOutput, planComposition());
1759 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001760 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1761 EXPECT_CALL(mOutput, beginFrame());
1762 EXPECT_CALL(mOutput, prepareFrame());
1763 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1764 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1765 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001766 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001767
1768 mOutput.present(args);
1769}
1770
1771/*
1772 * Output::updateColorProfile()
1773 */
1774
Lloyd Pique17ca7422019-11-14 14:24:10 -08001775struct OutputUpdateColorProfileTest : public testing::Test {
1776 using TestType = OutputUpdateColorProfileTest;
1777
1778 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001779 // Sets up the helper functions called by the function under test to use
1780 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001781 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1782 };
1783
1784 struct Layer {
1785 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001786 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1787 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001788 }
1789
1790 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001791 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001792 LayerFECompositionState mLayerFEState;
1793 };
1794
1795 OutputUpdateColorProfileTest() {
1796 mOutput.setDisplayColorProfileForTest(
1797 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1798 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1799
1800 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1801 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1802 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1803 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1804 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1805 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1806 }
1807
1808 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1809 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1810 };
1811
1812 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1813 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1814 StrictMock<OutputPartialMock> mOutput;
1815
1816 Layer mLayer1;
1817 Layer mLayer2;
1818 Layer mLayer3;
1819
1820 CompositionRefreshArgs mRefreshArgs;
1821};
1822
1823// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1824// to make it easier to write unit tests.
1825
1826TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1827 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1828 // a simple default color profile without looking at anything else.
1829
Lloyd Pique0a456232020-01-16 17:51:13 -08001830 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001831 EXPECT_CALL(mOutput,
1832 setColorProfile(ColorProfileEq(
1833 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1834 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1835
1836 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1837 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1838
1839 mOutput.updateColorProfile(mRefreshArgs);
1840}
1841
1842struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1843 : public OutputUpdateColorProfileTest {
1844 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001845 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001846 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1847 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1848 }
1849
1850 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1851 : public CallOrderStateMachineHelper<
1852 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1853 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1854 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1855 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1856 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1857 _))
1858 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1859 SetArgPointee<4>(renderIntent)));
1860 EXPECT_CALL(getInstance()->mOutput,
1861 setColorProfile(
1862 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1863 ui::Dataspace::UNKNOWN})));
1864 return nextState<ExecuteState>();
1865 }
1866 };
1867
1868 // Call this member function to start using the mini-DSL defined above.
1869 [[nodiscard]] auto verify() {
1870 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1871 }
1872};
1873
1874TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1875 Native_Unknown_Colorimetric_Set) {
1876 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1877 ui::Dataspace::UNKNOWN,
1878 ui::RenderIntent::COLORIMETRIC)
1879 .execute();
1880}
1881
1882TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1883 DisplayP3_DisplayP3_Enhance_Set) {
1884 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1885 ui::Dataspace::DISPLAY_P3,
1886 ui::RenderIntent::ENHANCE)
1887 .execute();
1888}
1889
1890struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1891 : public OutputUpdateColorProfileTest {
1892 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001893 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001894 EXPECT_CALL(*mDisplayColorProfile,
1895 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1896 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1897 SetArgPointee<3>(ui::ColorMode::NATIVE),
1898 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1899 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1900 }
1901
1902 struct IfColorSpaceAgnosticDataspaceSetToState
1903 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1904 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1905 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1906 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1907 }
1908 };
1909
1910 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1911 : public CallOrderStateMachineHelper<
1912 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1913 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1914 ui::Dataspace dataspace) {
1915 EXPECT_CALL(getInstance()->mOutput,
1916 setColorProfile(ColorProfileEq(
1917 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1918 ui::RenderIntent::COLORIMETRIC, dataspace})));
1919 return nextState<ExecuteState>();
1920 }
1921 };
1922
1923 // Call this member function to start using the mini-DSL defined above.
1924 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1925};
1926
1927TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1928 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1929 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1930 .execute();
1931}
1932
1933TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1934 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1935 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1936 .execute();
1937}
1938
1939struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1940 : public OutputUpdateColorProfileTest {
1941 // Internally the implementation looks through the dataspaces of all the
1942 // visible layers. The topmost one that also has an actual dataspace
1943 // preference set is used to drive subsequent choices.
1944
1945 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1946 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1947 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1948
Lloyd Pique0a456232020-01-16 17:51:13 -08001949 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001950 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1951 }
1952
1953 struct IfTopLayerDataspaceState
1954 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1955 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1956 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1957 return nextState<AndIfMiddleLayerDataspaceState>();
1958 }
1959 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1960 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1961 }
1962 };
1963
1964 struct AndIfMiddleLayerDataspaceState
1965 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1966 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1967 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1968 return nextState<AndIfBottomLayerDataspaceState>();
1969 }
1970 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1971 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1972 }
1973 };
1974
1975 struct AndIfBottomLayerDataspaceState
1976 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1977 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1978 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1979 return nextState<ThenExpectBestColorModeCallUsesState>();
1980 }
1981 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1982 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1983 }
1984 };
1985
1986 struct ThenExpectBestColorModeCallUsesState
1987 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
1988 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
1989 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1990 getBestColorMode(dataspace, _, _, _, _));
1991 return nextState<ExecuteState>();
1992 }
1993 };
1994
1995 // Call this member function to start using the mini-DSL defined above.
1996 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
1997};
1998
1999TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2000 noStrongLayerPrefenceUses_V0_SRGB) {
2001 // If none of the layers indicate a preference, then V0_SRGB is the
2002 // preferred choice (subject to additional checks).
2003 verify().ifTopLayerHasNoPreference()
2004 .andIfMiddleLayerHasNoPreference()
2005 .andIfBottomLayerHasNoPreference()
2006 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2007 .execute();
2008}
2009
2010TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2011 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2012 // If only the topmost layer has a preference, then that is what is chosen.
2013 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2014 .andIfMiddleLayerHasNoPreference()
2015 .andIfBottomLayerHasNoPreference()
2016 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2017 .execute();
2018}
2019
2020TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2021 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2022 // If only the middle layer has a preference, that that is what is chosen.
2023 verify().ifTopLayerHasNoPreference()
2024 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2025 .andIfBottomLayerHasNoPreference()
2026 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2027 .execute();
2028}
2029
2030TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2031 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2032 // If only the middle layer has a preference, that that is what is chosen.
2033 verify().ifTopLayerHasNoPreference()
2034 .andIfMiddleLayerHasNoPreference()
2035 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2036 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2037 .execute();
2038}
2039
2040TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2041 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2042 // If multiple layers have a preference, the topmost value is what is used.
2043 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2044 .andIfMiddleLayerHasNoPreference()
2045 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2046 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2047 .execute();
2048}
2049
2050TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2051 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2052 // If multiple layers have a preference, the topmost value is what is used.
2053 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2054 .andIfMiddleLayerHasNoPreference()
2055 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2056 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2057 .execute();
2058}
2059
2060struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2061 : public OutputUpdateColorProfileTest {
2062 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2063 // values, it overrides the layer dataspace choice.
2064
2065 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2066 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2067 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2068
2069 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2070
Lloyd Pique0a456232020-01-16 17:51:13 -08002071 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002072 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2073 }
2074
2075 struct IfForceOutputColorModeState
2076 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2077 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2078 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2079 return nextState<ThenExpectBestColorModeCallUsesState>();
2080 }
2081 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2082 };
2083
2084 struct ThenExpectBestColorModeCallUsesState
2085 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2086 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2087 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2088 getBestColorMode(dataspace, _, _, _, _));
2089 return nextState<ExecuteState>();
2090 }
2091 };
2092
2093 // Call this member function to start using the mini-DSL defined above.
2094 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2095};
2096
2097TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2098 // By default the layer state is used to set the preferred dataspace
2099 verify().ifNoOverride()
2100 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2101 .execute();
2102}
2103
2104TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2105 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2106 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2107 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2108 .execute();
2109}
2110
2111TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2112 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2113 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2114 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2115 .execute();
2116}
2117
2118// HDR output requires all layers to be compatible with the chosen HDR
2119// dataspace, along with there being proper support.
2120struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2121 OutputUpdateColorProfileTest_Hdr() {
2122 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2123 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002124 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002125 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2126 }
2127
2128 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2129 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2130 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2131 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2132
2133 struct IfTopLayerDataspaceState
2134 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2135 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2136 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2137 return nextState<AndTopLayerCompositionTypeState>();
2138 }
2139 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2140 };
2141
2142 struct AndTopLayerCompositionTypeState
2143 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2144 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2145 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2146 return nextState<AndIfBottomLayerDataspaceState>();
2147 }
2148 };
2149
2150 struct AndIfBottomLayerDataspaceState
2151 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2152 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2153 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2154 return nextState<AndBottomLayerCompositionTypeState>();
2155 }
2156 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2157 return andIfBottomLayerIs(kNonHdrDataspace);
2158 }
2159 };
2160
2161 struct AndBottomLayerCompositionTypeState
2162 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2163 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2164 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2165 return nextState<AndIfHasLegacySupportState>();
2166 }
2167 };
2168
2169 struct AndIfHasLegacySupportState
2170 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2171 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2172 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2173 .WillOnce(Return(legacySupport));
2174 return nextState<ThenExpectBestColorModeCallUsesState>();
2175 }
2176 };
2177
2178 struct ThenExpectBestColorModeCallUsesState
2179 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2180 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2181 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2182 getBestColorMode(dataspace, _, _, _, _));
2183 return nextState<ExecuteState>();
2184 }
2185 };
2186
2187 // Call this member function to start using the mini-DSL defined above.
2188 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2189};
2190
2191TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2192 // If all layers use BT2020_PQ, and there are no other special conditions,
2193 // BT2020_PQ is used.
2194 verify().ifTopLayerIs(BT2020_PQ)
2195 .andTopLayerIsREComposed(false)
2196 .andIfBottomLayerIs(BT2020_PQ)
2197 .andBottomLayerIsREComposed(false)
2198 .andIfLegacySupportFor(BT2020_PQ, false)
2199 .thenExpectBestColorModeCallUses(BT2020_PQ)
2200 .execute();
2201}
2202
2203TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2204 // BT2020_PQ is not used if there is only legacy support for it.
2205 verify().ifTopLayerIs(BT2020_PQ)
2206 .andTopLayerIsREComposed(false)
2207 .andIfBottomLayerIs(BT2020_PQ)
2208 .andBottomLayerIsREComposed(false)
2209 .andIfLegacySupportFor(BT2020_PQ, true)
2210 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2211 .execute();
2212}
2213
2214TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2215 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2216 verify().ifTopLayerIs(BT2020_PQ)
2217 .andTopLayerIsREComposed(false)
2218 .andIfBottomLayerIs(BT2020_PQ)
2219 .andBottomLayerIsREComposed(true)
2220 .andIfLegacySupportFor(BT2020_PQ, false)
2221 .thenExpectBestColorModeCallUses(BT2020_PQ)
2222 .execute();
2223}
2224
2225TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2226 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2227 verify().ifTopLayerIs(BT2020_PQ)
2228 .andTopLayerIsREComposed(true)
2229 .andIfBottomLayerIs(BT2020_PQ)
2230 .andBottomLayerIsREComposed(false)
2231 .andIfLegacySupportFor(BT2020_PQ, false)
2232 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2233 .execute();
2234}
2235
2236TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2237 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2238 // are no other special conditions.
2239 verify().ifTopLayerIs(BT2020_PQ)
2240 .andTopLayerIsREComposed(false)
2241 .andIfBottomLayerIs(BT2020_HLG)
2242 .andBottomLayerIsREComposed(false)
2243 .andIfLegacySupportFor(BT2020_PQ, false)
2244 .thenExpectBestColorModeCallUses(BT2020_PQ)
2245 .execute();
2246}
2247
2248TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2249 // BT2020_PQ is not used if there is only legacy support for it.
2250 verify().ifTopLayerIs(BT2020_PQ)
2251 .andTopLayerIsREComposed(false)
2252 .andIfBottomLayerIs(BT2020_HLG)
2253 .andBottomLayerIsREComposed(false)
2254 .andIfLegacySupportFor(BT2020_PQ, true)
2255 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2256 .execute();
2257}
2258
2259TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2260 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2261 verify().ifTopLayerIs(BT2020_PQ)
2262 .andTopLayerIsREComposed(false)
2263 .andIfBottomLayerIs(BT2020_HLG)
2264 .andBottomLayerIsREComposed(true)
2265 .andIfLegacySupportFor(BT2020_PQ, false)
2266 .thenExpectBestColorModeCallUses(BT2020_PQ)
2267 .execute();
2268}
2269
2270TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2271 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2272 verify().ifTopLayerIs(BT2020_PQ)
2273 .andTopLayerIsREComposed(true)
2274 .andIfBottomLayerIs(BT2020_HLG)
2275 .andBottomLayerIsREComposed(false)
2276 .andIfLegacySupportFor(BT2020_PQ, false)
2277 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2278 .execute();
2279}
2280
2281TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2282 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2283 // used if there are no other special conditions.
2284 verify().ifTopLayerIs(BT2020_HLG)
2285 .andTopLayerIsREComposed(false)
2286 .andIfBottomLayerIs(BT2020_PQ)
2287 .andBottomLayerIsREComposed(false)
2288 .andIfLegacySupportFor(BT2020_PQ, false)
2289 .thenExpectBestColorModeCallUses(BT2020_PQ)
2290 .execute();
2291}
2292
2293TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2294 // BT2020_PQ is not used if there is only legacy support for it.
2295 verify().ifTopLayerIs(BT2020_HLG)
2296 .andTopLayerIsREComposed(false)
2297 .andIfBottomLayerIs(BT2020_PQ)
2298 .andBottomLayerIsREComposed(false)
2299 .andIfLegacySupportFor(BT2020_PQ, true)
2300 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2301 .execute();
2302}
2303
2304TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2305 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2306 verify().ifTopLayerIs(BT2020_HLG)
2307 .andTopLayerIsREComposed(false)
2308 .andIfBottomLayerIs(BT2020_PQ)
2309 .andBottomLayerIsREComposed(true)
2310 .andIfLegacySupportFor(BT2020_PQ, false)
2311 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2312 .execute();
2313}
2314
2315TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2316 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2317 verify().ifTopLayerIs(BT2020_HLG)
2318 .andTopLayerIsREComposed(true)
2319 .andIfBottomLayerIs(BT2020_PQ)
2320 .andBottomLayerIsREComposed(false)
2321 .andIfLegacySupportFor(BT2020_PQ, false)
2322 .thenExpectBestColorModeCallUses(BT2020_PQ)
2323 .execute();
2324}
2325
2326TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2327 // If all layers use HLG then HLG is used if there are no other special
2328 // conditions.
2329 verify().ifTopLayerIs(BT2020_HLG)
2330 .andTopLayerIsREComposed(false)
2331 .andIfBottomLayerIs(BT2020_HLG)
2332 .andBottomLayerIsREComposed(false)
2333 .andIfLegacySupportFor(BT2020_HLG, false)
2334 .thenExpectBestColorModeCallUses(BT2020_HLG)
2335 .execute();
2336}
2337
2338TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2339 // BT2020_HLG is not used if there is legacy support for it.
2340 verify().ifTopLayerIs(BT2020_HLG)
2341 .andTopLayerIsREComposed(false)
2342 .andIfBottomLayerIs(BT2020_HLG)
2343 .andBottomLayerIsREComposed(false)
2344 .andIfLegacySupportFor(BT2020_HLG, true)
2345 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2346 .execute();
2347}
2348
2349TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2350 // BT2020_HLG is used even if the bottom layer is client composed.
2351 verify().ifTopLayerIs(BT2020_HLG)
2352 .andTopLayerIsREComposed(false)
2353 .andIfBottomLayerIs(BT2020_HLG)
2354 .andBottomLayerIsREComposed(true)
2355 .andIfLegacySupportFor(BT2020_HLG, false)
2356 .thenExpectBestColorModeCallUses(BT2020_HLG)
2357 .execute();
2358}
2359
2360TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2361 // BT2020_HLG is used even if the top layer is client composed.
2362 verify().ifTopLayerIs(BT2020_HLG)
2363 .andTopLayerIsREComposed(true)
2364 .andIfBottomLayerIs(BT2020_HLG)
2365 .andBottomLayerIsREComposed(false)
2366 .andIfLegacySupportFor(BT2020_HLG, false)
2367 .thenExpectBestColorModeCallUses(BT2020_HLG)
2368 .execute();
2369}
2370
2371TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2372 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2373 verify().ifTopLayerIs(BT2020_PQ)
2374 .andTopLayerIsREComposed(false)
2375 .andIfBottomLayerIsNotHdr()
2376 .andBottomLayerIsREComposed(false)
2377 .andIfLegacySupportFor(BT2020_PQ, false)
2378 .thenExpectBestColorModeCallUses(BT2020_PQ)
2379 .execute();
2380}
2381
2382TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2383 // If all layers use HLG then HLG is used if there are no other special
2384 // conditions.
2385 verify().ifTopLayerIs(BT2020_HLG)
2386 .andTopLayerIsREComposed(false)
2387 .andIfBottomLayerIsNotHdr()
2388 .andBottomLayerIsREComposed(true)
2389 .andIfLegacySupportFor(BT2020_HLG, false)
2390 .thenExpectBestColorModeCallUses(BT2020_HLG)
2391 .execute();
2392}
2393
2394struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2395 : public OutputUpdateColorProfileTest {
2396 // The various values for CompositionRefreshArgs::outputColorSetting affect
2397 // the chosen renderIntent, along with whether the preferred dataspace is an
2398 // HDR dataspace or not.
2399
2400 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2401 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2402 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2403 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002404 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002405 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2406 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2407 .WillRepeatedly(Return(false));
2408 }
2409
2410 // The tests here involve enough state and GMock setup that using a mini-DSL
2411 // makes the tests much more readable, and allows the test to focus more on
2412 // the intent than on some of the details.
2413
2414 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2415 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2416
2417 struct IfDataspaceChosenState
2418 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2419 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2420 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2421 return nextState<AndOutputColorSettingState>();
2422 }
2423 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2424 return ifDataspaceChosenIs(kNonHdrDataspace);
2425 }
2426 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2427 };
2428
2429 struct AndOutputColorSettingState
2430 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2431 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2432 getInstance()->mRefreshArgs.outputColorSetting = setting;
2433 return nextState<ThenExpectBestColorModeCallUsesState>();
2434 }
2435 };
2436
2437 struct ThenExpectBestColorModeCallUsesState
2438 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2439 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2440 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2441 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2442 _, _));
2443 return nextState<ExecuteState>();
2444 }
2445 };
2446
2447 // Tests call one of these two helper member functions to start using the
2448 // mini-DSL defined above.
2449 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2450};
2451
2452TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2453 Managed_NonHdr_Prefers_Colorimetric) {
2454 verify().ifDataspaceChosenIsNonHdr()
2455 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2456 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2457 .execute();
2458}
2459
2460TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2461 Managed_Hdr_Prefers_ToneMapColorimetric) {
2462 verify().ifDataspaceChosenIsHdr()
2463 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2464 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2465 .execute();
2466}
2467
2468TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2469 verify().ifDataspaceChosenIsNonHdr()
2470 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2471 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2472 .execute();
2473}
2474
2475TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2476 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2477 verify().ifDataspaceChosenIsHdr()
2478 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2479 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2480 .execute();
2481}
2482
2483TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2484 verify().ifDataspaceChosenIsNonHdr()
2485 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2486 .thenExpectBestColorModeCallUses(
2487 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2488 .execute();
2489}
2490
2491TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2492 verify().ifDataspaceChosenIsHdr()
2493 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2494 .thenExpectBestColorModeCallUses(
2495 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2496 .execute();
2497}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002498
2499/*
2500 * Output::beginFrame()
2501 */
2502
Lloyd Piquee5965952019-11-18 16:16:32 -08002503struct OutputBeginFrameTest : public ::testing::Test {
2504 using TestType = OutputBeginFrameTest;
2505
2506 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002507 // Sets up the helper functions called by the function under test to use
2508 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002509 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002510 };
2511
2512 OutputBeginFrameTest() {
2513 mOutput.setDisplayColorProfileForTest(
2514 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2515 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2516 }
2517
2518 struct IfGetDirtyRegionExpectationState
2519 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2520 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002521 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002522 return nextState<AndIfGetOutputLayerCountExpectationState>();
2523 }
2524 };
2525
2526 struct AndIfGetOutputLayerCountExpectationState
2527 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2528 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2529 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2530 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2531 }
2532 };
2533
2534 struct AndIfLastCompositionHadVisibleLayersState
2535 : public CallOrderStateMachineHelper<TestType,
2536 AndIfLastCompositionHadVisibleLayersState> {
2537 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2538 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2539 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2540 }
2541 };
2542
2543 struct ThenExpectRenderSurfaceBeginFrameCallState
2544 : public CallOrderStateMachineHelper<TestType,
2545 ThenExpectRenderSurfaceBeginFrameCallState> {
2546 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2547 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2548 return nextState<ExecuteState>();
2549 }
2550 };
2551
2552 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2553 [[nodiscard]] auto execute() {
2554 getInstance()->mOutput.beginFrame();
2555 return nextState<CheckPostconditionHadVisibleLayersState>();
2556 }
2557 };
2558
2559 struct CheckPostconditionHadVisibleLayersState
2560 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2561 void checkPostconditionHadVisibleLayers(bool expected) {
2562 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2563 }
2564 };
2565
2566 // Tests call one of these two helper member functions to start using the
2567 // mini-DSL defined above.
2568 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2569
2570 static const Region kEmptyRegion;
2571 static const Region kNotEmptyRegion;
2572
2573 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2574 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2575 StrictMock<OutputPartialMock> mOutput;
2576};
2577
2578const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2579const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2580
2581TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2582 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2583 .andIfGetOutputLayerCountReturns(1u)
2584 .andIfLastCompositionHadVisibleLayersIs(true)
2585 .thenExpectRenderSurfaceBeginFrameCall(true)
2586 .execute()
2587 .checkPostconditionHadVisibleLayers(true);
2588}
2589
2590TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2591 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2592 .andIfGetOutputLayerCountReturns(0u)
2593 .andIfLastCompositionHadVisibleLayersIs(true)
2594 .thenExpectRenderSurfaceBeginFrameCall(true)
2595 .execute()
2596 .checkPostconditionHadVisibleLayers(false);
2597}
2598
2599TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2600 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2601 .andIfGetOutputLayerCountReturns(1u)
2602 .andIfLastCompositionHadVisibleLayersIs(false)
2603 .thenExpectRenderSurfaceBeginFrameCall(true)
2604 .execute()
2605 .checkPostconditionHadVisibleLayers(true);
2606}
2607
2608TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2609 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2610 .andIfGetOutputLayerCountReturns(0u)
2611 .andIfLastCompositionHadVisibleLayersIs(false)
2612 .thenExpectRenderSurfaceBeginFrameCall(false)
2613 .execute()
2614 .checkPostconditionHadVisibleLayers(false);
2615}
2616
2617TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2618 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2619 .andIfGetOutputLayerCountReturns(1u)
2620 .andIfLastCompositionHadVisibleLayersIs(true)
2621 .thenExpectRenderSurfaceBeginFrameCall(false)
2622 .execute()
2623 .checkPostconditionHadVisibleLayers(true);
2624}
2625
2626TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2627 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2628 .andIfGetOutputLayerCountReturns(0u)
2629 .andIfLastCompositionHadVisibleLayersIs(true)
2630 .thenExpectRenderSurfaceBeginFrameCall(false)
2631 .execute()
2632 .checkPostconditionHadVisibleLayers(true);
2633}
2634
2635TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2636 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2637 .andIfGetOutputLayerCountReturns(1u)
2638 .andIfLastCompositionHadVisibleLayersIs(false)
2639 .thenExpectRenderSurfaceBeginFrameCall(false)
2640 .execute()
2641 .checkPostconditionHadVisibleLayers(false);
2642}
2643
2644TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2645 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2646 .andIfGetOutputLayerCountReturns(0u)
2647 .andIfLastCompositionHadVisibleLayersIs(false)
2648 .thenExpectRenderSurfaceBeginFrameCall(false)
2649 .execute()
2650 .checkPostconditionHadVisibleLayers(false);
2651}
2652
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002653/*
2654 * Output::devOptRepaintFlash()
2655 */
2656
Lloyd Piquedb462d82019-11-19 17:58:46 -08002657struct OutputDevOptRepaintFlashTest : public testing::Test {
2658 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002659 // Sets up the helper functions called by the function under test to use
2660 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002661 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002662 MOCK_METHOD2(composeSurfaces,
2663 std::optional<base::unique_fd>(
2664 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002665 MOCK_METHOD0(postFramebuffer, void());
2666 MOCK_METHOD0(prepareFrame, void());
2667 };
2668
2669 OutputDevOptRepaintFlashTest() {
2670 mOutput.setDisplayColorProfileForTest(
2671 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2672 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2673 }
2674
2675 static const Region kEmptyRegion;
2676 static const Region kNotEmptyRegion;
2677
2678 StrictMock<OutputPartialMock> mOutput;
2679 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2680 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2681 CompositionRefreshArgs mRefreshArgs;
2682};
2683
2684const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2685const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2686
2687TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2688 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002689 mOutput.mState.isEnabled = true;
2690
2691 mOutput.devOptRepaintFlash(mRefreshArgs);
2692}
2693
2694TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2695 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002696 mOutput.mState.isEnabled = false;
2697
2698 InSequence seq;
2699 EXPECT_CALL(mOutput, postFramebuffer());
2700 EXPECT_CALL(mOutput, prepareFrame());
2701
2702 mOutput.devOptRepaintFlash(mRefreshArgs);
2703}
2704
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002705TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002706 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002707 mOutput.mState.isEnabled = true;
2708
2709 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002710 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002711 EXPECT_CALL(mOutput, postFramebuffer());
2712 EXPECT_CALL(mOutput, prepareFrame());
2713
2714 mOutput.devOptRepaintFlash(mRefreshArgs);
2715}
2716
2717TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2718 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002719 mOutput.mState.isEnabled = true;
2720
2721 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002722 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002723 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002724 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2725 EXPECT_CALL(mOutput, postFramebuffer());
2726 EXPECT_CALL(mOutput, prepareFrame());
2727
2728 mOutput.devOptRepaintFlash(mRefreshArgs);
2729}
2730
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002731/*
2732 * Output::finishFrame()
2733 */
2734
Lloyd Pique03561a62019-11-19 18:34:52 -08002735struct OutputFinishFrameTest : public testing::Test {
2736 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002737 // Sets up the helper functions called by the function under test to use
2738 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002739 MOCK_METHOD2(composeSurfaces,
2740 std::optional<base::unique_fd>(
2741 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002742 MOCK_METHOD0(postFramebuffer, void());
2743 };
2744
2745 OutputFinishFrameTest() {
2746 mOutput.setDisplayColorProfileForTest(
2747 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2748 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2749 }
2750
2751 StrictMock<OutputPartialMock> mOutput;
2752 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2753 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2754 CompositionRefreshArgs mRefreshArgs;
2755};
2756
2757TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2758 mOutput.mState.isEnabled = false;
2759
2760 mOutput.finishFrame(mRefreshArgs);
2761}
2762
2763TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2764 mOutput.mState.isEnabled = true;
2765
2766 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002767 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002768
2769 mOutput.finishFrame(mRefreshArgs);
2770}
2771
2772TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2773 mOutput.mState.isEnabled = true;
2774
2775 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002776 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002777 .WillOnce(Return(ByMove(base::unique_fd())));
2778 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2779
2780 mOutput.finishFrame(mRefreshArgs);
2781}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002782
2783/*
2784 * Output::postFramebuffer()
2785 */
2786
Lloyd Pique07178e32019-11-19 19:15:26 -08002787struct OutputPostFramebufferTest : public testing::Test {
2788 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002789 // Sets up the helper functions called by the function under test to use
2790 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002791 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2792 };
2793
2794 struct Layer {
2795 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002796 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002797 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2798 }
2799
2800 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002801 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002802 StrictMock<HWC2::mock::Layer> hwc2Layer;
2803 };
2804
2805 OutputPostFramebufferTest() {
2806 mOutput.setDisplayColorProfileForTest(
2807 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2808 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2809
2810 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2811 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2812 .WillRepeatedly(Return(&mLayer1.outputLayer));
2813 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2814 .WillRepeatedly(Return(&mLayer2.outputLayer));
2815 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2816 .WillRepeatedly(Return(&mLayer3.outputLayer));
2817 }
2818
2819 StrictMock<OutputPartialMock> mOutput;
2820 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2821 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2822
2823 Layer mLayer1;
2824 Layer mLayer2;
2825 Layer mLayer3;
2826};
2827
2828TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2829 mOutput.mState.isEnabled = false;
2830
2831 mOutput.postFramebuffer();
2832}
2833
2834TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2835 mOutput.mState.isEnabled = true;
2836
2837 compositionengine::Output::FrameFences frameFences;
2838
2839 // This should happen even if there are no output layers.
2840 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2841
2842 // For this test in particular we want to make sure the call expectations
2843 // setup below are satisfied in the specific order.
2844 InSequence seq;
2845
2846 EXPECT_CALL(*mRenderSurface, flip());
2847 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2848 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2849
2850 mOutput.postFramebuffer();
2851}
2852
2853TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2854 // Simulate getting release fences from each layer, and ensure they are passed to the
2855 // front-end layer interface for each layer correctly.
2856
2857 mOutput.mState.isEnabled = true;
2858
2859 // Create three unique fence instances
2860 sp<Fence> layer1Fence = new Fence();
2861 sp<Fence> layer2Fence = new Fence();
2862 sp<Fence> layer3Fence = new Fence();
2863
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002864 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002865 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2866 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2867 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2868
2869 EXPECT_CALL(*mRenderSurface, flip());
2870 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2871 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2872
2873 // Compare the pointers values of each fence to make sure the correct ones
2874 // are passed. This happens to work with the current implementation, but
2875 // would not survive certain calls like Fence::merge() which would return a
2876 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002877 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002878 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002879 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002880 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002881 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002882 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2883
2884 mOutput.postFramebuffer();
2885}
2886
2887TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2888 mOutput.mState.isEnabled = true;
2889 mOutput.mState.usesClientComposition = true;
2890
2891 sp<Fence> clientTargetAcquireFence = new Fence();
2892 sp<Fence> layer1Fence = new Fence();
2893 sp<Fence> layer2Fence = new Fence();
2894 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002895 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002896 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2897 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2898 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2899 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2900
2901 EXPECT_CALL(*mRenderSurface, flip());
2902 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2903 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2904
2905 // Fence::merge is called, and since none of the fences are actually valid,
2906 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2907 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002908 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2909 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2910 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002911
2912 mOutput.postFramebuffer();
2913}
2914
2915TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2916 mOutput.mState.isEnabled = true;
2917 mOutput.mState.usesClientComposition = true;
2918
2919 // This should happen even if there are no (current) output layers.
2920 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2921
2922 // Load up the released layers with some mock instances
2923 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2924 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2925 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2926 Output::ReleasedLayers layers;
2927 layers.push_back(releasedLayer1);
2928 layers.push_back(releasedLayer2);
2929 layers.push_back(releasedLayer3);
2930 mOutput.setReleasedLayers(std::move(layers));
2931
2932 // Set up a fake present fence
2933 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002934 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002935 frameFences.presentFence = presentFence;
2936
2937 EXPECT_CALL(*mRenderSurface, flip());
2938 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2939 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2940
2941 // Each released layer should be given the presentFence.
2942 EXPECT_CALL(*releasedLayer1,
2943 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2944 EXPECT_CALL(*releasedLayer2,
2945 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2946 EXPECT_CALL(*releasedLayer3,
2947 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2948
2949 mOutput.postFramebuffer();
2950
2951 // After the call the list of released layers should have been cleared.
2952 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2953}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002954
2955/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002956 * Output::composeSurfaces()
2957 */
2958
2959struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002960 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002961
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002962 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002963 // Sets up the helper functions called by the function under test to use
2964 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002965 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Sally Qidf3da512021-07-08 17:27:02 +00002966 MOCK_METHOD2(generateClientCompositionRequests,
2967 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002968 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002969 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002970 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2971 };
2972
2973 OutputComposeSurfacesTest() {
2974 mOutput.setDisplayColorProfileForTest(
2975 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2976 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002977 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002978
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002979 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
2980 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002981 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02002982 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02002983 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02002984 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08002985 mOutput.mState.dataspace = kDefaultOutputDataspace;
2986 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
2987 mOutput.mState.isSecure = false;
2988 mOutput.mState.needsFiltering = false;
2989 mOutput.mState.usesClientComposition = true;
2990 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08002991 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07002992 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07002993
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07002994 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07002995 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08002996 EXPECT_CALL(mCompositionEngine, getTimeStats())
2997 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08002998 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
2999 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003000 }
3001
Lloyd Pique6818fa52019-12-03 12:32:13 -08003002 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3003 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003004 getInstance()->mReadyFence =
3005 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003006 return nextState<FenceCheckState>();
3007 }
3008 };
3009
3010 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3011 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3012
3013 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3014 };
3015
3016 // Call this member function to start using the mini-DSL defined above.
3017 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3018
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003019 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3020 static constexpr uint32_t kDefaultOutputOrientationFlags =
3021 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003022 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3023 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3024 static constexpr float kDefaultMaxLuminance = 0.9f;
3025 static constexpr float kDefaultAvgLuminance = 0.7f;
3026 static constexpr float kDefaultMinLuminance = 0.1f;
3027
3028 static const Rect kDefaultOutputFrame;
3029 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003030 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003031 static const mat4 kDefaultColorTransformMat;
3032
3033 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003034 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003035 static const HdrCapabilities kHdrCapabilities;
3036
Lloyd Pique56eba802019-08-28 15:45:25 -07003037 StrictMock<mock::CompositionEngine> mCompositionEngine;
3038 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003039 // TODO: make this is a proper mock.
3040 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003041 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3042 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003043 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003044 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3045 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3046 renderengine::ExternalTexture::Usage::READABLE |
3047 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003048
3049 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003050};
3051
3052const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3053const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003054const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003055const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003056const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003057const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3058const HdrCapabilities OutputComposeSurfacesTest::
3059 kHdrCapabilities{{},
3060 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3061 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3062 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003063
Lloyd Piquea76ce462020-01-14 13:06:37 -08003064TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003065 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003066
Lloyd Piquee9eff972020-05-05 12:36:44 -07003067 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003068 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003069
Lloyd Piquea76ce462020-01-14 13:06:37 -08003070 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3071
Lloyd Pique6818fa52019-12-03 12:32:13 -08003072 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003073}
3074
Lloyd Piquee9eff972020-05-05 12:36:44 -07003075TEST_F(OutputComposeSurfacesTest,
3076 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3077 mOutput.mState.usesClientComposition = false;
3078 mOutput.mState.flipClientTarget = true;
3079
Lloyd Pique6818fa52019-12-03 12:32:13 -08003080 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003081 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003082
3083 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3084 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3085
3086 verify().execute().expectAFenceWasReturned();
3087}
3088
3089TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3090 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003091 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003092
3093 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3094
3095 verify().execute().expectNoFenceWasReturned();
3096}
3097
3098TEST_F(OutputComposeSurfacesTest,
3099 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3100 mOutput.mState.usesClientComposition = false;
3101 mOutput.mState.flipClientTarget = true;
3102
3103 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003104 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003105
Lloyd Pique6818fa52019-12-03 12:32:13 -08003106 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003107
Lloyd Pique6818fa52019-12-03 12:32:13 -08003108 verify().execute().expectNoFenceWasReturned();
3109}
Lloyd Pique56eba802019-08-28 15:45:25 -07003110
Lloyd Pique6818fa52019-12-03 12:32:13 -08003111TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3112 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3113 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3114 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003115 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003116 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003117 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003118 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3119 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003120
Lloyd Pique6818fa52019-12-03 12:32:13 -08003121 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003122 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003123 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003124
Lloyd Pique6818fa52019-12-03 12:32:13 -08003125 verify().execute().expectAFenceWasReturned();
3126}
Lloyd Pique56eba802019-08-28 15:45:25 -07003127
Lloyd Pique6818fa52019-12-03 12:32:13 -08003128TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003129 LayerFE::LayerSettings r1;
3130 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003131
3132 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3133 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3134
3135 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3136 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3137 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003138 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003139 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003140 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003141 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3142 .WillRepeatedly(
3143 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003144 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003145 clientCompositionLayers.emplace_back(r2);
3146 }));
3147
3148 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003149 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3150 .WillRepeatedly(Return(NO_ERROR));
3151
3152 verify().execute().expectAFenceWasReturned();
3153}
3154
3155TEST_F(OutputComposeSurfacesTest,
3156 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3157 LayerFE::LayerSettings r1;
3158 LayerFE::LayerSettings r2;
3159
3160 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3161 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003162 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003163
3164 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3165 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3166 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3167 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003168 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Alec Mouri1684c702021-02-04 12:27:26 -08003169 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3170 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3171 .WillRepeatedly(
3172 Invoke([&](const Region&,
3173 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3174 clientCompositionLayers.emplace_back(r2);
3175 }));
3176
3177 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003178 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003179 .WillRepeatedly(Return(NO_ERROR));
3180
3181 verify().execute().expectAFenceWasReturned();
3182}
3183
Vishnu Nair9b079a22020-01-21 14:36:08 -08003184TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3185 mOutput.cacheClientCompositionRequests(0);
3186 LayerFE::LayerSettings r1;
3187 LayerFE::LayerSettings r2;
3188
3189 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3190 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3191
3192 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3193 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3194 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003195 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003196 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003197 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3198 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3199 .WillRepeatedly(Return());
3200
3201 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003202 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003203 .Times(2)
3204 .WillOnce(Return(NO_ERROR));
3205
3206 verify().execute().expectAFenceWasReturned();
3207 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3208
3209 verify().execute().expectAFenceWasReturned();
3210 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3211}
3212
3213TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3214 mOutput.cacheClientCompositionRequests(3);
3215 LayerFE::LayerSettings r1;
3216 LayerFE::LayerSettings r2;
3217
3218 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3219 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3220
3221 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3222 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3223 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003224 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003225 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003226 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3227 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3228 .WillRepeatedly(Return());
3229
3230 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003231 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003232 .WillOnce(Return(NO_ERROR));
3233 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3234
3235 verify().execute().expectAFenceWasReturned();
3236 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3237
3238 // We do not expect another call to draw layers.
3239 verify().execute().expectAFenceWasReturned();
3240 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3241}
3242
3243TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3244 LayerFE::LayerSettings r1;
3245 LayerFE::LayerSettings r2;
3246
3247 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3248 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3249
3250 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3251 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3252 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003253 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003254 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003255 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3256 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3257 .WillRepeatedly(Return());
3258
Alec Mouria90a5702021-04-16 16:36:21 +00003259 const auto otherOutputBuffer = std::make_shared<
3260 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3261 renderengine::ExternalTexture::Usage::READABLE |
3262 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003263 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3264 .WillOnce(Return(mOutputBuffer))
3265 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003266 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003267 .WillRepeatedly(Return(NO_ERROR));
3268
3269 verify().execute().expectAFenceWasReturned();
3270 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3271
3272 verify().execute().expectAFenceWasReturned();
3273 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3274}
3275
3276TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3277 LayerFE::LayerSettings r1;
3278 LayerFE::LayerSettings r2;
3279 LayerFE::LayerSettings r3;
3280
3281 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3282 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3283 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3284
3285 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3286 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3287 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003288 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003289 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003290 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3291 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3292 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3293 .WillRepeatedly(Return());
3294
3295 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003296 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003297 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003298 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003299 .WillOnce(Return(NO_ERROR));
3300
3301 verify().execute().expectAFenceWasReturned();
3302 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3303
3304 verify().execute().expectAFenceWasReturned();
3305 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3306}
3307
Lloyd Pique6818fa52019-12-03 12:32:13 -08003308struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3309 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3310 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003311 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003312 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003313 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003314 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3315 .WillRepeatedly(Return());
3316 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3317 }
3318
3319 struct MixedCompositionState
3320 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3321 auto ifMixedCompositionIs(bool used) {
3322 getInstance()->mOutput.mState.usesDeviceComposition = used;
3323 return nextState<OutputUsesHdrState>();
3324 }
3325 };
3326
3327 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3328 auto andIfUsesHdr(bool used) {
3329 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3330 .WillOnce(Return(used));
3331 return nextState<SkipColorTransformState>();
3332 }
3333 };
3334
3335 struct SkipColorTransformState
3336 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3337 auto andIfSkipColorTransform(bool skip) {
3338 // May be called zero or one times.
3339 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3340 .WillRepeatedly(Return(skip));
3341 return nextState<ExpectDisplaySettingsState>();
3342 }
3343 };
3344
3345 struct ExpectDisplaySettingsState
3346 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3347 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003348 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003349 .WillOnce(Return(NO_ERROR));
3350 return nextState<ExecuteState>();
3351 }
3352 };
3353
3354 // Call this member function to start using the mini-DSL defined above.
3355 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3356};
3357
3358TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3359 verify().ifMixedCompositionIs(true)
3360 .andIfUsesHdr(true)
3361 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003362 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003363 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003364 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003365 .execute()
3366 .expectAFenceWasReturned();
3367}
3368
3369TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3370 verify().ifMixedCompositionIs(true)
3371 .andIfUsesHdr(false)
3372 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003373 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003374 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003375 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003376 .execute()
3377 .expectAFenceWasReturned();
3378}
3379
3380TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3381 verify().ifMixedCompositionIs(false)
3382 .andIfUsesHdr(true)
3383 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003384 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003385 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003386 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003387 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003388 .execute()
3389 .expectAFenceWasReturned();
3390}
3391
3392TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3393 verify().ifMixedCompositionIs(false)
3394 .andIfUsesHdr(false)
3395 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003396 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003397 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003398 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003399 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003400 .execute()
3401 .expectAFenceWasReturned();
3402}
3403
3404TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3405 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3406 verify().ifMixedCompositionIs(false)
3407 .andIfUsesHdr(true)
3408 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003409 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003410 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003411 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003412 .execute()
3413 .expectAFenceWasReturned();
3414}
3415
3416struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3417 struct Layer {
3418 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003419 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3420 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003421 }
3422
3423 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003424 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003425 LayerFECompositionState mLayerFEState;
3426 };
3427
3428 OutputComposeSurfacesTest_HandlesProtectedContent() {
3429 mLayer1.mLayerFEState.hasProtectedContent = false;
3430 mLayer2.mLayerFEState.hasProtectedContent = false;
3431
3432 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3433 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3434 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3435 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3436 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3437
3438 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3439
3440 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3441
Sally Qidf3da512021-07-08 17:27:02 +00003442 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003443 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003444 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3445 .WillRepeatedly(Return());
3446 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003447 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003448 .WillRepeatedly(Return(NO_ERROR));
3449 }
3450
3451 Layer mLayer1;
3452 Layer mLayer2;
3453};
3454
3455TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3456 mOutput.mState.isSecure = false;
3457 mLayer2.mLayerFEState.hasProtectedContent = true;
3458 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003459 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003460 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003461
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003462 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003463}
3464
3465TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3466 mOutput.mState.isSecure = true;
3467 mLayer2.mLayerFEState.hasProtectedContent = true;
3468 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3469
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003470 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003471}
3472
3473TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3474 mOutput.mState.isSecure = true;
3475 mLayer2.mLayerFEState.hasProtectedContent = false;
3476 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3477 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3478 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3479 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3480 EXPECT_CALL(*mRenderSurface, setProtected(false));
3481
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003482 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003483}
3484
3485TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3486 mOutput.mState.isSecure = true;
3487 mLayer2.mLayerFEState.hasProtectedContent = true;
3488 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3489
3490 // For this test, we also check the call order of key functions.
3491 InSequence seq;
3492
3493 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3494 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3495 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3496 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3497 EXPECT_CALL(*mRenderSurface, setProtected(true));
3498 // Must happen after setting the protected content state.
3499 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003500 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003501
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003502 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003503}
3504
3505TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3506 mOutput.mState.isSecure = true;
3507 mLayer2.mLayerFEState.hasProtectedContent = true;
3508 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3509 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3510 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3511
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003512 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513}
3514
3515TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3516 mOutput.mState.isSecure = true;
3517 mLayer2.mLayerFEState.hasProtectedContent = true;
3518 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3519 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3520 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3521 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3522
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003523 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003524}
3525
3526TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3527 mOutput.mState.isSecure = true;
3528 mLayer2.mLayerFEState.hasProtectedContent = true;
3529 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3530 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3531 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3532 EXPECT_CALL(*mRenderSurface, setProtected(true));
3533
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003534 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003535}
3536
3537TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3538 mOutput.mState.isSecure = true;
3539 mLayer2.mLayerFEState.hasProtectedContent = true;
3540 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3541 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3542 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3543 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3544
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003545 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003546}
3547
3548struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3549 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3550 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3551 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3552 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003553 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003554 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3555 .WillRepeatedly(Return());
3556 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3557 }
3558};
3559
3560TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3561 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3562
Sally Qidf3da512021-07-08 17:27:02 +00003563 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003564 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003565
3566 // For this test, we also check the call order of key functions.
3567 InSequence seq;
3568
3569 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003570 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003571
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003572 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3573}
3574
3575struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3576 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3577 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3578 mLayer.layerFEState.backgroundBlurRadius = 10;
3579 mOutput.editState().isEnabled = true;
3580
Snild Dolkow9e217d62020-04-22 15:53:42 +02003581 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003582 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003583 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3584 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Sally Qidf3da512021-07-08 17:27:02 +00003585 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003586 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003587 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003588 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3589 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3590 .WillRepeatedly(Return(&mLayer.outputLayer));
3591 }
3592
3593 NonInjectedLayer mLayer;
3594 compositionengine::CompositionRefreshArgs mRefreshArgs;
3595};
3596
3597TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3598 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003599 mOutput.updateCompositionState(mRefreshArgs);
3600 mOutput.planComposition();
3601 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003602
3603 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3604 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3605}
3606
3607TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3608 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003609 mOutput.updateCompositionState(mRefreshArgs);
3610 mOutput.planComposition();
3611 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003612
3613 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3614 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003615}
3616
3617/*
3618 * Output::generateClientCompositionRequests()
3619 */
3620
3621struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003622 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003623 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003624 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Sally Qidf3da512021-07-08 17:27:02 +00003625 bool supportsProtectedContent, ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003626 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Sally Qidf3da512021-07-08 17:27:02 +00003627 dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003628 }
3629 };
3630
Lloyd Piquea4863342019-12-04 18:45:02 -08003631 struct Layer {
3632 Layer() {
3633 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3634 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003635 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3636 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003637 }
3638
3639 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003640 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003641 LayerFECompositionState mLayerFEState;
3642 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003643 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003644 };
3645
Lloyd Pique56eba802019-08-28 15:45:25 -07003646 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003647 mOutput.mState.needsFiltering = false;
3648
Lloyd Pique56eba802019-08-28 15:45:25 -07003649 mOutput.setDisplayColorProfileForTest(
3650 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3651 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3652 }
3653
Lloyd Pique56eba802019-08-28 15:45:25 -07003654 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3655 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003656 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003657};
3658
Lloyd Piquea4863342019-12-04 18:45:02 -08003659struct GenerateClientCompositionRequestsTest_ThreeLayers
3660 : public GenerateClientCompositionRequestsTest {
3661 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003662 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3663 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3664 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003665 mOutput.mState.transform =
3666 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3667 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003668 mOutput.mState.needsFiltering = false;
3669 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003670
Lloyd Piquea4863342019-12-04 18:45:02 -08003671 for (size_t i = 0; i < mLayers.size(); i++) {
3672 mLayers[i].mOutputLayerState.clearClientTarget = false;
3673 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3674 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003675 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003676 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003677 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3678 mLayers[i].mLayerSettings.alpha = 1.0f;
3679 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003680
Lloyd Piquea4863342019-12-04 18:45:02 -08003681 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3682 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3683 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3684 .WillRepeatedly(Return(true));
3685 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3686 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003687
Lloyd Piquea4863342019-12-04 18:45:02 -08003688 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3689 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003690
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003691 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003692 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003693
Lloyd Piquea4863342019-12-04 18:45:02 -08003694 static const Rect kDisplayFrame;
3695 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003696 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003697
Lloyd Piquea4863342019-12-04 18:45:02 -08003698 std::array<Layer, 3> mLayers;
3699};
Lloyd Pique56eba802019-08-28 15:45:25 -07003700
Lloyd Piquea4863342019-12-04 18:45:02 -08003701const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3702const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003703const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3704 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003705
Lloyd Piquea4863342019-12-04 18:45:02 -08003706TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3707 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3708 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3709 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003710
Lloyd Piquea4863342019-12-04 18:45:02 -08003711 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003712 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003713 EXPECT_EQ(0u, requests.size());
3714}
3715
Lloyd Piquea4863342019-12-04 18:45:02 -08003716TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3717 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3718 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3719 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3720
Lloyd Piquea4863342019-12-04 18:45:02 -08003721 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003722 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003724}
3725
3726TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003727 LayerFE::LayerSettings mShadowSettings;
3728 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003729
Ady Abrahameca9d752021-03-03 12:20:00 -08003730 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003731 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003732 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003733 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003734 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003735 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3736 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003737
Lloyd Piquea4863342019-12-04 18:45:02 -08003738 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003739 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003740 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003741 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3742 EXPECT_EQ(mShadowSettings, requests[1]);
3743 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003744
Lloyd Piquea4863342019-12-04 18:45:02 -08003745 // Check that a timestamp was set for the layers that generated requests
3746 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3747 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3748 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3749}
3750
Alec Mourif54453c2021-05-13 16:28:28 -07003751MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3752 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3753 *result_listener << "expected " << expectedBlurSetting << "\n";
3754 *result_listener << "actual " << arg.blurSetting << "\n";
3755
3756 return expectedBlurSetting == arg.blurSetting;
3757}
3758
3759TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3760 LayerFE::LayerSettings mShadowSettings;
3761 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3762
3763 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3764
3765 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3766 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3767 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3768 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3769 EXPECT_CALL(*mLayers[2].mLayerFE,
3770 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3771 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3772 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3773 {mShadowSettings, mLayers[2].mLayerSettings})));
3774
Alec Mourif54453c2021-05-13 16:28:28 -07003775 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003776 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003777 ASSERT_EQ(3u, requests.size());
3778 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3779 EXPECT_EQ(mShadowSettings, requests[1]);
3780 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3781
Alec Mourif54453c2021-05-13 16:28:28 -07003782 // Check that a timestamp was set for the layers that generated requests
3783 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3784 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3785 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3786}
3787
Lloyd Piquea4863342019-12-04 18:45:02 -08003788TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3789 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3790 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3791 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3792 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3793
3794 mLayers[0].mOutputLayerState.clearClientTarget = false;
3795 mLayers[1].mOutputLayerState.clearClientTarget = false;
3796 mLayers[2].mOutputLayerState.clearClientTarget = false;
3797
3798 mLayers[0].mLayerFEState.isOpaque = true;
3799 mLayers[1].mLayerFEState.isOpaque = true;
3800 mLayers[2].mLayerFEState.isOpaque = true;
3801
Ady Abrahameca9d752021-03-03 12:20:00 -08003802 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003803 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003804
Lloyd Piquea4863342019-12-04 18:45:02 -08003805 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003806 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003807 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003808 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003809}
3810
3811TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3812 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3813 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3814 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3815 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3816
3817 mLayers[0].mOutputLayerState.clearClientTarget = true;
3818 mLayers[1].mOutputLayerState.clearClientTarget = true;
3819 mLayers[2].mOutputLayerState.clearClientTarget = true;
3820
3821 mLayers[0].mLayerFEState.isOpaque = false;
3822 mLayers[1].mLayerFEState.isOpaque = false;
3823 mLayers[2].mLayerFEState.isOpaque = false;
3824
Ady Abrahameca9d752021-03-03 12:20:00 -08003825 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003826 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003827
Lloyd Piquea4863342019-12-04 18:45:02 -08003828 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003829 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003830 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003831 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003832}
3833
3834TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003835 // If client composition is performed with some layers set to use device
3836 // composition, device layers after the first layer (device or client) will
3837 // clear the frame buffer if they are opaque and if that layer has a flag
3838 // set to do so. The first layer is skipped as the frame buffer is already
3839 // expected to be clear.
3840
Lloyd Piquea4863342019-12-04 18:45:02 -08003841 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3842 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3843 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003844
Lloyd Piquea4863342019-12-04 18:45:02 -08003845 mLayers[0].mOutputLayerState.clearClientTarget = true;
3846 mLayers[1].mOutputLayerState.clearClientTarget = true;
3847 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003848
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 mLayers[0].mLayerFEState.isOpaque = true;
3850 mLayers[1].mLayerFEState.isOpaque = true;
3851 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003852
3853 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3854 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003855 false, /* needs filtering */
3856 false, /* secure */
3857 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003858 kDisplayViewport,
3859 kDisplayDataspace,
3860 false /* realContentIsVisible */,
3861 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003862 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003863 };
3864 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3865 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003866 false, /* needs filtering */
3867 false, /* secure */
3868 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003869 kDisplayViewport,
3870 kDisplayDataspace,
3871 true /* realContentIsVisible */,
3872 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003873 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003874 };
3875
3876 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3877 mBlackoutSettings.source.buffer.buffer = nullptr;
3878 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3879 mBlackoutSettings.alpha = 0.f;
3880 mBlackoutSettings.disableBlending = true;
3881
Ady Abrahameca9d752021-03-03 12:20:00 -08003882 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003883 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003884 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003885 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3886
Lloyd Piquea4863342019-12-04 18:45:02 -08003887 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003888 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003889 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003890
Lloyd Piquea4863342019-12-04 18:45:02 -08003891 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003892 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003893
Vishnu Nair9b079a22020-01-21 14:36:08 -08003894 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003895}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003896
Lloyd Piquea4863342019-12-04 18:45:02 -08003897TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3898 clippedVisibleRegionUsedToGenerateRequest) {
3899 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3900 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3901 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003902
Lloyd Piquea4863342019-12-04 18:45:02 -08003903 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3904 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003905 false, /* needs filtering */
3906 false, /* secure */
3907 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003908 kDisplayViewport,
3909 kDisplayDataspace,
3910 true /* realContentIsVisible */,
3911 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003912 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003913 };
3914 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3915 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003916 false, /* needs filtering */
3917 false, /* secure */
3918 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003919 kDisplayViewport,
3920 kDisplayDataspace,
3921 true /* realContentIsVisible */,
3922 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003923 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003924 };
3925 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3926 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003927 false, /* needs filtering */
3928 false, /* secure */
3929 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003930 kDisplayViewport,
3931 kDisplayDataspace,
3932 true /* realContentIsVisible */,
3933 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003934 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003935 };
3936
Ady Abrahameca9d752021-03-03 12:20:00 -08003937 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003938 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003939 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003940 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003941 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003942 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003943
3944 static_cast<void>(
3945 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003946 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08003947}
3948
3949TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3950 perLayerNeedsFilteringUsedToGenerateRequests) {
3951 mOutput.mState.needsFiltering = false;
3952 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3953
Lloyd Piquea4863342019-12-04 18:45:02 -08003954 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3955 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 true, /* needs filtering */
3957 false, /* secure */
3958 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003959 kDisplayViewport,
3960 kDisplayDataspace,
3961 true /* realContentIsVisible */,
3962 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003963 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003964 };
3965 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3966 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003967 false, /* needs filtering */
3968 false, /* secure */
3969 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003970 kDisplayViewport,
3971 kDisplayDataspace,
3972 true /* realContentIsVisible */,
3973 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003974 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003975 };
3976 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3977 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003978 false, /* needs filtering */
3979 false, /* secure */
3980 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003981 kDisplayViewport,
3982 kDisplayDataspace,
3983 true /* realContentIsVisible */,
3984 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003985 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003986 };
3987
Ady Abrahameca9d752021-03-03 12:20:00 -08003988 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003989 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003990 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003992 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003993 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003994
3995 static_cast<void>(
3996 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003997 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08003998}
3999
4000TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4001 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4002 mOutput.mState.needsFiltering = true;
4003 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4004
Lloyd Piquea4863342019-12-04 18:45:02 -08004005 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4006 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004007 true, /* needs filtering */
4008 false, /* secure */
4009 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004010 kDisplayViewport,
4011 kDisplayDataspace,
4012 true /* realContentIsVisible */,
4013 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004014 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004015
Lloyd Piquea4863342019-12-04 18:45:02 -08004016 };
4017 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4018 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004019 true, /* needs filtering */
4020 false, /* secure */
4021 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004022 kDisplayViewport,
4023 kDisplayDataspace,
4024 true /* realContentIsVisible */,
4025 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004026 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004027 };
4028 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4029 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004030 true, /* needs filtering */
4031 false, /* secure */
4032 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004033 kDisplayViewport,
4034 kDisplayDataspace,
4035 true /* realContentIsVisible */,
4036 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004037 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004038 };
4039
Ady Abrahameca9d752021-03-03 12:20:00 -08004040 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004041 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004042 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004043 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004044 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004045 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004046
4047 static_cast<void>(
4048 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004049 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004050}
4051
4052TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4053 wholeOutputSecurityUsedToGenerateRequests) {
4054 mOutput.mState.isSecure = true;
4055
Lloyd Piquea4863342019-12-04 18:45:02 -08004056 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4057 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004058 false, /* needs filtering */
4059 true, /* secure */
4060 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004061 kDisplayViewport,
4062 kDisplayDataspace,
4063 true /* realContentIsVisible */,
4064 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004065 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004066 };
4067 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4068 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004069 false, /* needs filtering */
4070 true, /* secure */
4071 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004072 kDisplayViewport,
4073 kDisplayDataspace,
4074 true /* realContentIsVisible */,
4075 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004076 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004077 };
4078 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4079 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004080 false, /* needs filtering */
4081 true, /* secure */
4082 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004083 kDisplayViewport,
4084 kDisplayDataspace,
4085 true /* realContentIsVisible */,
4086 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004087 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004088 };
4089
Ady Abrahameca9d752021-03-03 12:20:00 -08004090 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004091 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004092 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004093 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004094 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004095 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004096
4097 static_cast<void>(
4098 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004099 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004100}
4101
4102TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4103 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004104
4105 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4106 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004107 false, /* needs filtering */
4108 false, /* secure */
4109 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004110 kDisplayViewport,
4111 kDisplayDataspace,
4112 true /* realContentIsVisible */,
4113 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004114 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004115 };
4116 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4117 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004118 false, /* needs filtering */
4119 false, /* secure */
4120 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004121 kDisplayViewport,
4122 kDisplayDataspace,
4123 true /* realContentIsVisible */,
4124 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004125 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004126 };
4127 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4128 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004129 false, /* needs filtering */
4130 false, /* secure */
4131 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004132 kDisplayViewport,
4133 kDisplayDataspace,
4134 true /* realContentIsVisible */,
4135 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004136 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004137 };
4138
Ady Abrahameca9d752021-03-03 12:20:00 -08004139 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004140 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004141 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004142 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004143 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004144 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004145
4146 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004147 kDisplayDataspace));
4148}
4149
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004150TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004151 InjectedLayer layer1;
4152 InjectedLayer layer2;
4153 InjectedLayer layer3;
4154
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004155 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004156 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004157 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004158 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004159 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4160 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004161 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004162 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004163 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4164 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004165 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004166 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004167 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4168 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004169
Lloyd Piquede196652020-01-22 17:29:58 -08004170 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004171
Lloyd Piquede196652020-01-22 17:29:58 -08004172 injectOutputLayer(layer1);
4173 injectOutputLayer(layer2);
4174 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004175
4176 mOutput->editState().isEnabled = true;
4177
4178 CompositionRefreshArgs args;
4179 args.updatingGeometryThisFrame = false;
4180 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004181 mOutput->updateCompositionState(args);
4182 mOutput->planComposition();
4183 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004184}
4185
Lucas Dupinc3800b82020-10-02 16:24:48 -07004186TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4187 InjectedLayer layer1;
4188 InjectedLayer layer2;
4189 InjectedLayer layer3;
4190
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004191 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004192 // Layer requesting blur, or below, should request client composition.
4193 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004194 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004195 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4196 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004197 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004198 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004199 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4200 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004201 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004202 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004203 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4204 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004205
4206 BlurRegion region;
4207 layer2.layerFEState.blurRegions.push_back(region);
4208
4209 injectOutputLayer(layer1);
4210 injectOutputLayer(layer2);
4211 injectOutputLayer(layer3);
4212
4213 mOutput->editState().isEnabled = true;
4214
4215 CompositionRefreshArgs args;
4216 args.updatingGeometryThisFrame = false;
4217 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004218 mOutput->updateCompositionState(args);
4219 mOutput->planComposition();
4220 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004221}
4222
Lloyd Piquea4863342019-12-04 18:45:02 -08004223TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4224 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4225 // one layer on the left covering the left side of the output, and one layer
4226 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004227
4228 const Rect kPortraitFrame(0, 0, 1000, 2000);
4229 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004230 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004231 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004232 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004233
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004234 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4235 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4236 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004237 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4238 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004239 mOutput.mState.needsFiltering = false;
4240 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004241
Lloyd Piquea4863342019-12-04 18:45:02 -08004242 Layer leftLayer;
4243 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004244
Lloyd Piquea4863342019-12-04 18:45:02 -08004245 leftLayer.mOutputLayerState.clearClientTarget = false;
4246 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4247 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004248 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004249
Lloyd Piquea4863342019-12-04 18:45:02 -08004250 rightLayer.mOutputLayerState.clearClientTarget = false;
4251 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4252 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004253 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004254
4255 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4256 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4257 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4258 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4259 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4260
Lloyd Piquea4863342019-12-04 18:45:02 -08004261 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4262 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004263 false, /* needs filtering */
4264 true, /* secure */
4265 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004266 kPortraitViewport,
4267 kOutputDataspace,
4268 true /* realContentIsVisible */,
4269 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004270 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004271 };
4272
4273 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4274 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004275 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004276 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004277
4278 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4279 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004280 false, /* needs filtering */
4281 true, /* secure */
4282 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004283 kPortraitViewport,
4284 kOutputDataspace,
4285 true /* realContentIsVisible */,
4286 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004287 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004288 };
4289
4290 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4291 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004292 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004293 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004294
4295 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004296 auto requests =
4297 mOutput.generateClientCompositionRequests(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004298 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004299 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4300 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004301}
4302
Vishnu Naira483b4a2019-12-12 15:07:52 -08004303TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4304 shadowRegionOnlyVisibleSkipsContentComposition) {
4305 const Rect kContentWithShadow(40, 40, 70, 90);
4306 const Rect kContent(50, 50, 60, 80);
4307 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4308 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4309
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004310 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4311 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004312 false, /* needs filtering */
4313 false, /* secure */
4314 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004315 kDisplayViewport,
4316 kDisplayDataspace,
4317 false /* realContentIsVisible */,
4318 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004319 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004320 };
4321
Vishnu Nair9b079a22020-01-21 14:36:08 -08004322 LayerFE::LayerSettings mShadowSettings;
4323 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004324
4325 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4326 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4327
4328 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4329 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004330 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004331 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004332
Vishnu Naira483b4a2019-12-12 15:07:52 -08004333 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004334 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004335 ASSERT_EQ(1u, requests.size());
4336
Vishnu Nair9b079a22020-01-21 14:36:08 -08004337 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004338}
4339
4340TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4341 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4342 const Rect kContentWithShadow(40, 40, 70, 90);
4343 const Rect kContent(50, 50, 60, 80);
4344 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4345 const Region kPartialContentWithPartialShadowRegion =
4346 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4347
Vishnu Nair9b079a22020-01-21 14:36:08 -08004348 LayerFE::LayerSettings mShadowSettings;
4349 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004350
4351 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4352 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4353
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004354 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4355 Region(Rect(50, 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 true /* 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 Naira483b4a2019-12-12 15:07:52 -08004366 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4367 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004368 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004369 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4370 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004371
Vishnu Naira483b4a2019-12-12 15:07:52 -08004372 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004373 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004374 ASSERT_EQ(2u, requests.size());
4375
Vishnu Nair9b079a22020-01-21 14:36:08 -08004376 EXPECT_EQ(mShadowSettings, requests[0]);
4377 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004378}
4379
Lloyd Pique32cbe282018-10-19 13:09:22 -07004380} // namespace
4381} // namespace android::compositionengine