blob: e7fad594a6ed931aa2ba54b788467aefeaf66b3f [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
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000571TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
572 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
576 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700577 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700578
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000579 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700580 }
581}
582
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000583TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
584 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200585 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700586 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700587
588 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700589 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700590
591 // The dirtyRegion should be clipped to the display bounds.
592 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
593 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700594}
595
Lloyd Pique66d68602019-02-13 14:23:31 -0800596/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700597 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800598 */
599
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700600TEST_F(OutputTest, layerFiltering) {
601 const ui::LayerStack layerStack1{123u};
602 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800603
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700604 // If the output is associated to layerStack1 and to an internal display...
605 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800606
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700607 // It excludes layers with no layer stack, internal-only or not.
608 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
609 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611 // It includes layers on layerStack1, internal-only or not.
612 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
613 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
614 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
615 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800616
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700617 // If the output is associated to layerStack1 but not to an internal display...
618 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800619
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700620 // It includes layers on layerStack1, unless they are internal-only.
621 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
622 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
623 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
624 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800625}
626
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800628 NonInjectedLayer layer;
629 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800630
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700631 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800632 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700633 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800634}
635
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700636TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800637 NonInjectedLayer layer;
638 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800639
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700640 const ui::LayerStack layerStack1{123u};
641 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800642
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700643 // If the output is associated to layerStack1 and to an internal display...
644 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800645
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700646 // It excludes layers with no layer stack, internal-only or not.
647 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
648 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
651 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 // It includes layers on layerStack1, internal-only or not.
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_TRUE(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
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700666 // If the output is associated to layerStack1 but not to an internal display...
667 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800668
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700669 // It includes layers on layerStack1, unless they are internal-only.
670 layer.layerFEState.outputFilter = {layerStack1, false};
671 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800672
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700673 layer.layerFEState.outputFilter = {layerStack1, true};
674 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800675
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700676 layer.layerFEState.outputFilter = {layerStack2, true};
677 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800678
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700679 layer.layerFEState.outputFilter = {layerStack2, false};
680 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800681}
682
Lloyd Pique66d68602019-02-13 14:23:31 -0800683/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800684 * Output::getOutputLayerForLayer()
685 */
686
687TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800688 InjectedLayer layer1;
689 InjectedLayer layer2;
690 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800691
Lloyd Piquede196652020-01-22 17:29:58 -0800692 injectOutputLayer(layer1);
693 injectNullOutputLayer();
694 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800695
696 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800697 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
698 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800699
700 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800701 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
702 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
703 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800704
705 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800706 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
707 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
708 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800709}
710
Lloyd Pique66d68602019-02-13 14:23:31 -0800711/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800712 * Output::setReleasedLayers()
713 */
714
715using OutputSetReleasedLayersTest = OutputTest;
716
717TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
718 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
719 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
720 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
721
722 Output::ReleasedLayers layers;
723 layers.push_back(layer1FE);
724 layers.push_back(layer2FE);
725 layers.push_back(layer3FE);
726
727 mOutput->setReleasedLayers(std::move(layers));
728
729 const auto& setLayers = mOutput->getReleasedLayersForTest();
730 ASSERT_EQ(3u, setLayers.size());
731 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
732 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
733 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
734}
735
736/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800737 * Output::updateLayerStateFromFE()
738 */
739
Lloyd Piquede196652020-01-22 17:29:58 -0800740using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800741
742TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
743 CompositionRefreshArgs refreshArgs;
744
745 mOutput->updateLayerStateFromFE(refreshArgs);
746}
747
Lloyd Piquede196652020-01-22 17:29:58 -0800748TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
749 InjectedLayer layer1;
750 InjectedLayer layer2;
751 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800752
Lloyd Piquede196652020-01-22 17:29:58 -0800753 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
754 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
755 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
756
757 injectOutputLayer(layer1);
758 injectOutputLayer(layer2);
759 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800760
761 CompositionRefreshArgs refreshArgs;
762 refreshArgs.updatingGeometryThisFrame = false;
763
764 mOutput->updateLayerStateFromFE(refreshArgs);
765}
766
Lloyd Piquede196652020-01-22 17:29:58 -0800767TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
768 InjectedLayer layer1;
769 InjectedLayer layer2;
770 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800771
Lloyd Piquede196652020-01-22 17:29:58 -0800772 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
773 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
774 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
775
776 injectOutputLayer(layer1);
777 injectOutputLayer(layer2);
778 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800779
780 CompositionRefreshArgs refreshArgs;
781 refreshArgs.updatingGeometryThisFrame = true;
782
783 mOutput->updateLayerStateFromFE(refreshArgs);
784}
785
786/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800787 * Output::updateAndWriteCompositionState()
788 */
789
Lloyd Piquede196652020-01-22 17:29:58 -0800790using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800791
792TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
793 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800794
795 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800796 mOutput->updateCompositionState(args);
797 mOutput->planComposition();
798 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800799}
800
Lloyd Piqueef63b612019-11-14 13:19:56 -0800801TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800802 InjectedLayer layer1;
803 InjectedLayer layer2;
804 InjectedLayer layer3;
805
Lloyd Piqueef63b612019-11-14 13:19:56 -0800806 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800807
Lloyd Piquede196652020-01-22 17:29:58 -0800808 injectOutputLayer(layer1);
809 injectOutputLayer(layer2);
810 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800811
812 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800813 mOutput->updateCompositionState(args);
814 mOutput->planComposition();
815 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800816}
817
818TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800819 InjectedLayer layer1;
820 InjectedLayer layer2;
821 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800822
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400823 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200824 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800825 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400826 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
827 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200828 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800829 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400830 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
831 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200832 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800833 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400834 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
835 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800836
837 injectOutputLayer(layer1);
838 injectOutputLayer(layer2);
839 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800840
841 mOutput->editState().isEnabled = true;
842
843 CompositionRefreshArgs args;
844 args.updatingGeometryThisFrame = false;
845 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200846 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800847 mOutput->updateCompositionState(args);
848 mOutput->planComposition();
849 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800850}
851
852TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800853 InjectedLayer layer1;
854 InjectedLayer layer2;
855 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800856
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400857 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200858 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800859 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400860 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
861 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200862 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800863 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400864 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
865 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200866 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800867 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400868 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
869 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800870
871 injectOutputLayer(layer1);
872 injectOutputLayer(layer2);
873 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800874
875 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800876
877 CompositionRefreshArgs args;
878 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800879 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800880 mOutput->updateCompositionState(args);
881 mOutput->planComposition();
882 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800883}
884
885TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800886 InjectedLayer layer1;
887 InjectedLayer layer2;
888 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800889
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400890 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200891 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800892 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400893 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
894 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200895 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800896 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400897 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
898 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200899 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800900 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400901 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
902 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800903
904 injectOutputLayer(layer1);
905 injectOutputLayer(layer2);
906 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800907
908 mOutput->editState().isEnabled = true;
909
910 CompositionRefreshArgs args;
911 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800912 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800913 mOutput->updateCompositionState(args);
914 mOutput->planComposition();
915 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800916}
917
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400918TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
919 renderengine::mock::RenderEngine renderEngine;
920 InjectedLayer layer0;
921 InjectedLayer layer1;
922 InjectedLayer layer2;
923 InjectedLayer layer3;
924
925 InSequence seq;
926 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
927 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
928 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
929 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
930
931 uint32_t z = 0;
932 EXPECT_CALL(*layer0.outputLayer,
933 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
934 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
935
936 // After calling planComposition (which clears overrideInfo), this test sets
937 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
938 // comes first, setting isPeekingThrough to true and zIsOverridden to true
939 // for it and the following layers.
940 EXPECT_CALL(*layer3.outputLayer,
941 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
942 /*zIsOverridden*/ true, /*isPeekingThrough*/
943 true));
944 EXPECT_CALL(*layer1.outputLayer,
945 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
946 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
947 EXPECT_CALL(*layer2.outputLayer,
948 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
949 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
950
951 injectOutputLayer(layer0);
952 injectOutputLayer(layer1);
953 injectOutputLayer(layer2);
954 injectOutputLayer(layer3);
955
956 mOutput->editState().isEnabled = true;
957
958 CompositionRefreshArgs args;
959 args.updatingGeometryThisFrame = true;
960 args.devOptForceClientComposition = false;
961 mOutput->updateCompositionState(args);
962 mOutput->planComposition();
963
964 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
965 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
966 renderengine::ExternalTexture::Usage::READABLE |
967 renderengine::ExternalTexture::Usage::WRITEABLE);
968 layer1.outputLayerState.overrideInfo.buffer = buffer;
969 layer2.outputLayerState.overrideInfo.buffer = buffer;
970 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
971 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
972
973 mOutput->writeCompositionState(args);
974}
975
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800976/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800977 * Output::prepareFrame()
978 */
979
980struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800981 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800982 // Sets up the helper functions called by the function under test to use
983 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800984 MOCK_METHOD0(chooseCompositionStrategy, void());
985 };
986
987 OutputPrepareFrameTest() {
988 mOutput.setDisplayColorProfileForTest(
989 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
990 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
991 }
992
993 StrictMock<mock::CompositionEngine> mCompositionEngine;
994 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
995 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700996 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800997};
998
999TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1000 mOutput.editState().isEnabled = false;
1001
1002 mOutput.prepareFrame();
1003}
1004
1005TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1006 mOutput.editState().isEnabled = true;
1007 mOutput.editState().usesClientComposition = false;
1008 mOutput.editState().usesDeviceComposition = true;
1009
1010 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001011 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001012 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1013
1014 mOutput.prepareFrame();
1015}
1016
1017// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1018// base chooseCompositionStrategy() is invoked.
1019TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001020 mOutput->editState().isEnabled = true;
1021 mOutput->editState().usesClientComposition = false;
1022 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001023
1024 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1025
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001026 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001027
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001028 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1029 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001030}
1031
Lloyd Pique56eba802019-08-28 15:45:25 -07001032/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001033 * Output::prepare()
1034 */
1035
1036struct OutputPrepareTest : public testing::Test {
1037 struct OutputPartialMock : public OutputPartialMockBase {
1038 // Sets up the helper functions called by the function under test to use
1039 // mock implementations.
1040 MOCK_METHOD2(rebuildLayerStacks,
1041 void(const compositionengine::CompositionRefreshArgs&,
1042 compositionengine::LayerFESet&));
1043 };
1044
1045 StrictMock<OutputPartialMock> mOutput;
1046 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001047 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001048};
1049
1050TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1051 InSequence seq;
1052 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1053
1054 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1055}
1056
1057/*
1058 * Output::rebuildLayerStacks()
1059 */
1060
1061struct OutputRebuildLayerStacksTest : public testing::Test {
1062 struct OutputPartialMock : public OutputPartialMockBase {
1063 // Sets up the helper functions called by the function under test to use
1064 // mock implementations.
1065 MOCK_METHOD2(collectVisibleLayers,
1066 void(const compositionengine::CompositionRefreshArgs&,
1067 compositionengine::Output::CoverageState&));
1068 };
1069
1070 OutputRebuildLayerStacksTest() {
1071 mOutput.mState.isEnabled = true;
1072 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001073 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001074
1075 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1076
1077 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1078
1079 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1080 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1081 }
1082
1083 void setTestCoverageValues(const CompositionRefreshArgs&,
1084 compositionengine::Output::CoverageState& state) {
1085 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1086 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1087 state.dirtyRegion = mCoverageDirtyRegionToSet;
1088 }
1089
1090 static const ui::Transform kIdentityTransform;
1091 static const ui::Transform kRotate90Transform;
1092 static const Rect kOutputBounds;
1093
1094 StrictMock<OutputPartialMock> mOutput;
1095 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001096 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001097 Region mCoverageAboveCoveredLayersToSet;
1098 Region mCoverageAboveOpaqueLayersToSet;
1099 Region mCoverageDirtyRegionToSet;
1100};
1101
1102const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1103const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1104const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1105
1106TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1107 mOutput.mState.isEnabled = false;
1108
1109 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1110}
1111
1112TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1113 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1114
1115 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1116}
1117
1118TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1119 mOutput.mState.transform = kIdentityTransform;
1120
1121 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1122
1123 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1124
1125 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1126}
1127
1128TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1129 mOutput.mState.transform = kIdentityTransform;
1130
1131 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1132
1133 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1134
1135 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1136}
1137
1138TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1139 mOutput.mState.transform = kRotate90Transform;
1140
1141 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1142
1143 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1144
1145 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1146}
1147
1148TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1149 mOutput.mState.transform = kRotate90Transform;
1150
1151 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1152
1153 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1154
1155 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1156}
1157
1158TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1159 mOutput.mState.transform = kIdentityTransform;
1160 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1161
1162 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1163
1164 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1165
1166 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1167}
1168
1169TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1170 mOutput.mState.transform = kRotate90Transform;
1171 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1172
1173 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1174
1175 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1176
1177 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1178}
1179
1180/*
1181 * Output::collectVisibleLayers()
1182 */
1183
Lloyd Pique1ef93222019-11-21 16:41:53 -08001184struct OutputCollectVisibleLayersTest : public testing::Test {
1185 struct OutputPartialMock : public OutputPartialMockBase {
1186 // Sets up the helper functions called by the function under test to use
1187 // mock implementations.
1188 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001189 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001190 compositionengine::Output::CoverageState&));
1191 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1192 MOCK_METHOD0(finalizePendingOutputLayers, void());
1193 };
1194
1195 struct Layer {
1196 Layer() {
1197 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1198 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1199 }
1200
1201 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001202 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001203 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001204 };
1205
1206 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001207 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001208 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1209 .WillRepeatedly(Return(&mLayer1.outputLayer));
1210 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1211 .WillRepeatedly(Return(&mLayer2.outputLayer));
1212 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1213 .WillRepeatedly(Return(&mLayer3.outputLayer));
1214
Lloyd Piquede196652020-01-22 17:29:58 -08001215 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1216 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1217 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001218 }
1219
1220 StrictMock<OutputPartialMock> mOutput;
1221 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001222 LayerFESet mGeomSnapshots;
1223 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001224 Layer mLayer1;
1225 Layer mLayer2;
1226 Layer mLayer3;
1227};
1228
1229TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1230 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001231 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001232
1233 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1234 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1235
1236 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1237}
1238
1239TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1240 // Enforce a call order sequence for this test.
1241 InSequence seq;
1242
1243 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001244 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1245 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1246 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001247
1248 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1249 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1250
1251 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001252}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001253
1254/*
1255 * Output::ensureOutputLayerIfVisible()
1256 */
1257
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001258struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1259 struct OutputPartialMock : public OutputPartialMockBase {
1260 // Sets up the helper functions called by the function under test to use
1261 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001262 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1263 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001264 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001265 MOCK_METHOD2(ensureOutputLayer,
1266 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267 };
1268
1269 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001270 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001271 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001272 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001274 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001275
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001276 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1277 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001278 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1279
Lloyd Piquede196652020-01-22 17:29:58 -08001280 mLayer.layerFEState.isVisible = true;
1281 mLayer.layerFEState.isOpaque = true;
1282 mLayer.layerFEState.contentDirty = true;
1283 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1284 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1285 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001286
Lloyd Piquede196652020-01-22 17:29:58 -08001287 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1288 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001289
Lloyd Piquede196652020-01-22 17:29:58 -08001290 mGeomSnapshots.insert(mLayer.layerFE);
1291 }
1292
1293 void ensureOutputLayerIfVisible() {
1294 sp<LayerFE> layerFE(mLayer.layerFE);
1295 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001296 }
1297
1298 static const Region kEmptyRegion;
1299 static const Region kFullBoundsNoRotation;
1300 static const Region kRightHalfBoundsNoRotation;
1301 static const Region kLowerHalfBoundsNoRotation;
1302 static const Region kFullBounds90Rotation;
1303
1304 StrictMock<OutputPartialMock> mOutput;
1305 LayerFESet mGeomSnapshots;
1306 Output::CoverageState mCoverageState{mGeomSnapshots};
1307
Lloyd Piquede196652020-01-22 17:29:58 -08001308 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001309};
1310
1311const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1312const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1313 Region(Rect(0, 0, 100, 200));
1314const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1315 Region(Rect(0, 100, 100, 200));
1316const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1317 Region(Rect(50, 0, 100, 200));
1318const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1319 Region(Rect(0, 0, 200, 100));
1320
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001321TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1322 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001323 EXPECT_CALL(*mLayer.layerFE,
1324 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001325
1326 mGeomSnapshots.clear();
1327
Lloyd Piquede196652020-01-22 17:29:58 -08001328 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001329}
1330
1331TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001332 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1333 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001334
Lloyd Piquede196652020-01-22 17:29:58 -08001335 ensureOutputLayerIfVisible();
1336}
1337
1338TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1339 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1340
1341 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342}
1343
1344TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001345 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346
Lloyd Piquede196652020-01-22 17:29:58 -08001347 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001351 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352
Lloyd Piquede196652020-01-22 17:29:58 -08001353 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354}
1355
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001356TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001357 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360}
1361
1362TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1363 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001364 mLayer.layerFEState.isOpaque = true;
1365 mLayer.layerFEState.contentDirty = true;
1366 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001367
1368 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001369 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1370 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001371
Lloyd Piquede196652020-01-22 17:29:58 -08001372 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373
1374 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1375 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1376 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1377
Lloyd Piquede196652020-01-22 17:29:58 -08001378 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1379 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1380 RegionEq(kFullBoundsNoRotation));
1381 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1382 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383}
1384
1385TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1386 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001387 mLayer.layerFEState.isOpaque = true;
1388 mLayer.layerFEState.contentDirty = true;
1389 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001390
Lloyd Piquede196652020-01-22 17:29:58 -08001391 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1392 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001393
Lloyd Piquede196652020-01-22 17:29:58 -08001394 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001395
1396 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1397 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1398 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1399
Lloyd Piquede196652020-01-22 17:29:58 -08001400 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1401 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1402 RegionEq(kFullBoundsNoRotation));
1403 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1404 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001405}
1406
1407TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1408 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001409 mLayer.layerFEState.isOpaque = false;
1410 mLayer.layerFEState.contentDirty = true;
1411 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001412
1413 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001414 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1415 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001416
Lloyd Piquede196652020-01-22 17:29:58 -08001417 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001418
1419 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1420 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1421 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1422
Lloyd Piquede196652020-01-22 17:29:58 -08001423 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1424 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001425 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001426 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1427 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428}
1429
1430TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1431 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001432 mLayer.layerFEState.isOpaque = false;
1433 mLayer.layerFEState.contentDirty = true;
1434 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001435
Lloyd Piquede196652020-01-22 17:29:58 -08001436 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1437 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438
Lloyd Piquede196652020-01-22 17:29:58 -08001439 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440
1441 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1442 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1443 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1444
Lloyd Piquede196652020-01-22 17:29:58 -08001445 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1446 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001448 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1449 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450}
1451
1452TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1453 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001454 mLayer.layerFEState.isOpaque = true;
1455 mLayer.layerFEState.contentDirty = false;
1456 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001457
1458 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001459 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1460 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461
Lloyd Piquede196652020-01-22 17:29:58 -08001462 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001463
1464 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1465 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1466 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1467
Lloyd Piquede196652020-01-22 17:29:58 -08001468 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1469 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1470 RegionEq(kFullBoundsNoRotation));
1471 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1472 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001473}
1474
1475TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1476 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001477 mLayer.layerFEState.isOpaque = true;
1478 mLayer.layerFEState.contentDirty = false;
1479 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001480
Lloyd Piquede196652020-01-22 17:29:58 -08001481 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1482 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001483
Lloyd Piquede196652020-01-22 17:29:58 -08001484 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001485
1486 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1487 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1488 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1489
Lloyd Piquede196652020-01-22 17:29:58 -08001490 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1491 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1492 RegionEq(kFullBoundsNoRotation));
1493 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1494 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495}
1496
1497TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1498 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001499 mLayer.layerFEState.isOpaque = true;
1500 mLayer.layerFEState.contentDirty = true;
1501 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1502 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1503 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1504 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001505
1506 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001507 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1508 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001509
Lloyd Piquede196652020-01-22 17:29:58 -08001510 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001511
1512 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1513 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1514 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1515
Lloyd Piquede196652020-01-22 17:29:58 -08001516 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1517 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1518 RegionEq(kFullBoundsNoRotation));
1519 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1520 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521}
1522
1523TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1524 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001525 mLayer.layerFEState.isOpaque = true;
1526 mLayer.layerFEState.contentDirty = true;
1527 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1528 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1529 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1530 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001531
Lloyd Piquede196652020-01-22 17:29:58 -08001532 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1533 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
Lloyd Piquede196652020-01-22 17:29:58 -08001535 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536
1537 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1538 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1539 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1540
Lloyd Piquede196652020-01-22 17:29:58 -08001541 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1542 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1543 RegionEq(kFullBoundsNoRotation));
1544 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1545 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546}
1547
1548TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1549 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001550 mLayer.layerFEState.isOpaque = true;
1551 mLayer.layerFEState.contentDirty = true;
1552 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001554 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001555 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1556
1557 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001558 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1559 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001560
Lloyd Piquede196652020-01-22 17:29:58 -08001561 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001562
1563 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1564 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1565 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1566
Lloyd Piquede196652020-01-22 17:29:58 -08001567 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1568 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1569 RegionEq(kFullBoundsNoRotation));
1570 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1571 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572}
1573
1574TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1575 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001576 mLayer.layerFEState.isOpaque = true;
1577 mLayer.layerFEState.contentDirty = true;
1578 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001579
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001580 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001581 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1582
Lloyd Piquede196652020-01-22 17:29:58 -08001583 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1584 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
Lloyd Piquede196652020-01-22 17:29:58 -08001586 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587
1588 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1589 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1590 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1591
Lloyd Piquede196652020-01-22 17:29:58 -08001592 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1593 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1594 RegionEq(kFullBoundsNoRotation));
1595 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1596 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001597}
1598
1599TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1600 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1601 ui::Transform arbitraryTransform;
1602 arbitraryTransform.set(1, 1, -1, 1);
1603 arbitraryTransform.set(0, 100);
1604
Lloyd Piquede196652020-01-22 17:29:58 -08001605 mLayer.layerFEState.isOpaque = true;
1606 mLayer.layerFEState.contentDirty = true;
1607 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1608 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001609
1610 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001611 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1612 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001613
Lloyd Piquede196652020-01-22 17:29:58 -08001614 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001615
1616 const Region kRegion = Region(Rect(0, 0, 300, 300));
1617 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1618
1619 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1620 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1621 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1622
Lloyd Piquede196652020-01-22 17:29:58 -08001623 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1624 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1625 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1626 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627}
1628
1629TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001630 mLayer.layerFEState.isOpaque = false;
1631 mLayer.layerFEState.contentDirty = true;
1632 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001633
1634 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1635 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1636 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1639 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640
Lloyd Piquede196652020-01-22 17:29:58 -08001641 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001642
1643 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1644 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1645 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1646 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1647 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1648 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1649
1650 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1651 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1652 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1653
Lloyd Piquede196652020-01-22 17:29:58 -08001654 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1655 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001656 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001657 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1658 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1659 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001660}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001661
Vishnu Naira483b4a2019-12-12 15:07:52 -08001662TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1663 ui::Transform translate;
1664 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001665 mLayer.layerFEState.geomLayerTransform = translate;
1666 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001667
1668 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1669 // half of the layer including the casting shadow is covered and opaque
1670 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1671 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1672
Lloyd Piquede196652020-01-22 17:29:58 -08001673 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1674 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001675
Lloyd Piquede196652020-01-22 17:29:58 -08001676 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001677
1678 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1679 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1680 // add starting opaque region to the opaque half of the casting layer bounds
1681 const Region kExpectedAboveOpaqueRegion =
1682 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1683 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1684 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1685 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1686 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1687 const Region kExpectedLayerShadowRegion =
1688 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1689
1690 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1691 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1692 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1693
Lloyd Piquede196652020-01-22 17:29:58 -08001694 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1695 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001696 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001697 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1698 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001699 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001700 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001701 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1702}
1703
1704TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1705 ui::Transform translate;
1706 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001707 mLayer.layerFEState.geomLayerTransform = translate;
1708 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001709
1710 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1711 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1712 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1713 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1714
Lloyd Piquede196652020-01-22 17:29:58 -08001715 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1716 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001717
Lloyd Piquede196652020-01-22 17:29:58 -08001718 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001719
1720 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1721 const Region kExpectedLayerShadowRegion =
1722 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1723
Lloyd Piquede196652020-01-22 17:29:58 -08001724 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1725 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001726 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1727}
1728
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001729TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001730 ui::Transform translate;
1731 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001732 mLayer.layerFEState.geomLayerTransform = translate;
1733 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001734
1735 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1736 // Casting layer and its shadows are covered by an opaque region
1737 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1738 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1739
Lloyd Piquede196652020-01-22 17:29:58 -08001740 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001741}
1742
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001743/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001744 * Output::present()
1745 */
1746
1747struct OutputPresentTest : public testing::Test {
1748 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001749 // Sets up the helper functions called by the function under test to use
1750 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001751 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001752 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001753 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001754 MOCK_METHOD0(planComposition, void());
1755 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001756 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1757 MOCK_METHOD0(beginFrame, void());
1758 MOCK_METHOD0(prepareFrame, void());
1759 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1760 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1761 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001762 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001763 };
1764
1765 StrictMock<OutputPartialMock> mOutput;
1766};
1767
1768TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1769 CompositionRefreshArgs args;
1770
1771 InSequence seq;
1772 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001773 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1774 EXPECT_CALL(mOutput, planComposition());
1775 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001776 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1777 EXPECT_CALL(mOutput, beginFrame());
1778 EXPECT_CALL(mOutput, prepareFrame());
1779 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1780 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1781 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001782 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001783
1784 mOutput.present(args);
1785}
1786
1787/*
1788 * Output::updateColorProfile()
1789 */
1790
Lloyd Pique17ca7422019-11-14 14:24:10 -08001791struct OutputUpdateColorProfileTest : public testing::Test {
1792 using TestType = OutputUpdateColorProfileTest;
1793
1794 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001795 // Sets up the helper functions called by the function under test to use
1796 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001797 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1798 };
1799
1800 struct Layer {
1801 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001802 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1803 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001804 }
1805
1806 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001807 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001808 LayerFECompositionState mLayerFEState;
1809 };
1810
1811 OutputUpdateColorProfileTest() {
1812 mOutput.setDisplayColorProfileForTest(
1813 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1814 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1815
1816 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1817 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1818 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1819 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1820 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1821 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1822 }
1823
1824 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1825 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1826 };
1827
1828 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1829 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1830 StrictMock<OutputPartialMock> mOutput;
1831
1832 Layer mLayer1;
1833 Layer mLayer2;
1834 Layer mLayer3;
1835
1836 CompositionRefreshArgs mRefreshArgs;
1837};
1838
1839// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1840// to make it easier to write unit tests.
1841
1842TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1843 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1844 // a simple default color profile without looking at anything else.
1845
Lloyd Pique0a456232020-01-16 17:51:13 -08001846 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001847 EXPECT_CALL(mOutput,
1848 setColorProfile(ColorProfileEq(
1849 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1850 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1851
1852 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1853 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1854
1855 mOutput.updateColorProfile(mRefreshArgs);
1856}
1857
1858struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1859 : public OutputUpdateColorProfileTest {
1860 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001861 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001862 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1863 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1864 }
1865
1866 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1867 : public CallOrderStateMachineHelper<
1868 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1869 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1870 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1871 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1872 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1873 _))
1874 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1875 SetArgPointee<4>(renderIntent)));
1876 EXPECT_CALL(getInstance()->mOutput,
1877 setColorProfile(
1878 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1879 ui::Dataspace::UNKNOWN})));
1880 return nextState<ExecuteState>();
1881 }
1882 };
1883
1884 // Call this member function to start using the mini-DSL defined above.
1885 [[nodiscard]] auto verify() {
1886 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1887 }
1888};
1889
1890TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1891 Native_Unknown_Colorimetric_Set) {
1892 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1893 ui::Dataspace::UNKNOWN,
1894 ui::RenderIntent::COLORIMETRIC)
1895 .execute();
1896}
1897
1898TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1899 DisplayP3_DisplayP3_Enhance_Set) {
1900 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1901 ui::Dataspace::DISPLAY_P3,
1902 ui::RenderIntent::ENHANCE)
1903 .execute();
1904}
1905
1906struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1907 : public OutputUpdateColorProfileTest {
1908 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001909 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001910 EXPECT_CALL(*mDisplayColorProfile,
1911 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1912 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1913 SetArgPointee<3>(ui::ColorMode::NATIVE),
1914 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1915 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1916 }
1917
1918 struct IfColorSpaceAgnosticDataspaceSetToState
1919 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1920 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1921 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1922 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1923 }
1924 };
1925
1926 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1927 : public CallOrderStateMachineHelper<
1928 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1929 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1930 ui::Dataspace dataspace) {
1931 EXPECT_CALL(getInstance()->mOutput,
1932 setColorProfile(ColorProfileEq(
1933 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1934 ui::RenderIntent::COLORIMETRIC, dataspace})));
1935 return nextState<ExecuteState>();
1936 }
1937 };
1938
1939 // Call this member function to start using the mini-DSL defined above.
1940 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1941};
1942
1943TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1944 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1945 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1946 .execute();
1947}
1948
1949TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1950 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1951 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1952 .execute();
1953}
1954
1955struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1956 : public OutputUpdateColorProfileTest {
1957 // Internally the implementation looks through the dataspaces of all the
1958 // visible layers. The topmost one that also has an actual dataspace
1959 // preference set is used to drive subsequent choices.
1960
1961 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1962 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1963 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1964
Lloyd Pique0a456232020-01-16 17:51:13 -08001965 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001966 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1967 }
1968
1969 struct IfTopLayerDataspaceState
1970 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1971 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1972 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1973 return nextState<AndIfMiddleLayerDataspaceState>();
1974 }
1975 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1976 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1977 }
1978 };
1979
1980 struct AndIfMiddleLayerDataspaceState
1981 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1982 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1983 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1984 return nextState<AndIfBottomLayerDataspaceState>();
1985 }
1986 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1987 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1988 }
1989 };
1990
1991 struct AndIfBottomLayerDataspaceState
1992 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1993 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1994 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1995 return nextState<ThenExpectBestColorModeCallUsesState>();
1996 }
1997 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1998 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1999 }
2000 };
2001
2002 struct ThenExpectBestColorModeCallUsesState
2003 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2004 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2005 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2006 getBestColorMode(dataspace, _, _, _, _));
2007 return nextState<ExecuteState>();
2008 }
2009 };
2010
2011 // Call this member function to start using the mini-DSL defined above.
2012 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2013};
2014
2015TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2016 noStrongLayerPrefenceUses_V0_SRGB) {
2017 // If none of the layers indicate a preference, then V0_SRGB is the
2018 // preferred choice (subject to additional checks).
2019 verify().ifTopLayerHasNoPreference()
2020 .andIfMiddleLayerHasNoPreference()
2021 .andIfBottomLayerHasNoPreference()
2022 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2023 .execute();
2024}
2025
2026TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2027 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2028 // If only the topmost layer has a preference, then that is what is chosen.
2029 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2030 .andIfMiddleLayerHasNoPreference()
2031 .andIfBottomLayerHasNoPreference()
2032 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2033 .execute();
2034}
2035
2036TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2037 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2038 // If only the middle layer has a preference, that that is what is chosen.
2039 verify().ifTopLayerHasNoPreference()
2040 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2041 .andIfBottomLayerHasNoPreference()
2042 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2043 .execute();
2044}
2045
2046TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2047 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2048 // If only the middle layer has a preference, that that is what is chosen.
2049 verify().ifTopLayerHasNoPreference()
2050 .andIfMiddleLayerHasNoPreference()
2051 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2052 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2053 .execute();
2054}
2055
2056TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2057 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2058 // If multiple layers have a preference, the topmost value is what is used.
2059 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2060 .andIfMiddleLayerHasNoPreference()
2061 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2062 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2063 .execute();
2064}
2065
2066TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2067 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2068 // If multiple layers have a preference, the topmost value is what is used.
2069 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2070 .andIfMiddleLayerHasNoPreference()
2071 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2072 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2073 .execute();
2074}
2075
2076struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2077 : public OutputUpdateColorProfileTest {
2078 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2079 // values, it overrides the layer dataspace choice.
2080
2081 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2082 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2083 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2084
2085 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2086
Lloyd Pique0a456232020-01-16 17:51:13 -08002087 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002088 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2089 }
2090
2091 struct IfForceOutputColorModeState
2092 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2093 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2094 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2095 return nextState<ThenExpectBestColorModeCallUsesState>();
2096 }
2097 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2098 };
2099
2100 struct ThenExpectBestColorModeCallUsesState
2101 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2102 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2103 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2104 getBestColorMode(dataspace, _, _, _, _));
2105 return nextState<ExecuteState>();
2106 }
2107 };
2108
2109 // Call this member function to start using the mini-DSL defined above.
2110 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2111};
2112
2113TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2114 // By default the layer state is used to set the preferred dataspace
2115 verify().ifNoOverride()
2116 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2117 .execute();
2118}
2119
2120TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2121 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2122 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2123 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2124 .execute();
2125}
2126
2127TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2128 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2129 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2130 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2131 .execute();
2132}
2133
2134// HDR output requires all layers to be compatible with the chosen HDR
2135// dataspace, along with there being proper support.
2136struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2137 OutputUpdateColorProfileTest_Hdr() {
2138 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2139 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002140 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002141 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2142 }
2143
2144 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2145 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2146 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2147 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2148
2149 struct IfTopLayerDataspaceState
2150 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2151 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2152 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2153 return nextState<AndTopLayerCompositionTypeState>();
2154 }
2155 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2156 };
2157
2158 struct AndTopLayerCompositionTypeState
2159 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2160 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2161 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2162 return nextState<AndIfBottomLayerDataspaceState>();
2163 }
2164 };
2165
2166 struct AndIfBottomLayerDataspaceState
2167 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2168 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2169 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2170 return nextState<AndBottomLayerCompositionTypeState>();
2171 }
2172 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2173 return andIfBottomLayerIs(kNonHdrDataspace);
2174 }
2175 };
2176
2177 struct AndBottomLayerCompositionTypeState
2178 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2179 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2180 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2181 return nextState<AndIfHasLegacySupportState>();
2182 }
2183 };
2184
2185 struct AndIfHasLegacySupportState
2186 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2187 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2188 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2189 .WillOnce(Return(legacySupport));
2190 return nextState<ThenExpectBestColorModeCallUsesState>();
2191 }
2192 };
2193
2194 struct ThenExpectBestColorModeCallUsesState
2195 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2196 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2197 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2198 getBestColorMode(dataspace, _, _, _, _));
2199 return nextState<ExecuteState>();
2200 }
2201 };
2202
2203 // Call this member function to start using the mini-DSL defined above.
2204 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2205};
2206
2207TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2208 // If all layers use BT2020_PQ, and there are no other special conditions,
2209 // BT2020_PQ is used.
2210 verify().ifTopLayerIs(BT2020_PQ)
2211 .andTopLayerIsREComposed(false)
2212 .andIfBottomLayerIs(BT2020_PQ)
2213 .andBottomLayerIsREComposed(false)
2214 .andIfLegacySupportFor(BT2020_PQ, false)
2215 .thenExpectBestColorModeCallUses(BT2020_PQ)
2216 .execute();
2217}
2218
2219TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2220 // BT2020_PQ is not used if there is only legacy support for it.
2221 verify().ifTopLayerIs(BT2020_PQ)
2222 .andTopLayerIsREComposed(false)
2223 .andIfBottomLayerIs(BT2020_PQ)
2224 .andBottomLayerIsREComposed(false)
2225 .andIfLegacySupportFor(BT2020_PQ, true)
2226 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2227 .execute();
2228}
2229
2230TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2231 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2232 verify().ifTopLayerIs(BT2020_PQ)
2233 .andTopLayerIsREComposed(false)
2234 .andIfBottomLayerIs(BT2020_PQ)
2235 .andBottomLayerIsREComposed(true)
2236 .andIfLegacySupportFor(BT2020_PQ, false)
2237 .thenExpectBestColorModeCallUses(BT2020_PQ)
2238 .execute();
2239}
2240
2241TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2242 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2243 verify().ifTopLayerIs(BT2020_PQ)
2244 .andTopLayerIsREComposed(true)
2245 .andIfBottomLayerIs(BT2020_PQ)
2246 .andBottomLayerIsREComposed(false)
2247 .andIfLegacySupportFor(BT2020_PQ, false)
2248 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2249 .execute();
2250}
2251
2252TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2253 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2254 // are no other special conditions.
2255 verify().ifTopLayerIs(BT2020_PQ)
2256 .andTopLayerIsREComposed(false)
2257 .andIfBottomLayerIs(BT2020_HLG)
2258 .andBottomLayerIsREComposed(false)
2259 .andIfLegacySupportFor(BT2020_PQ, false)
2260 .thenExpectBestColorModeCallUses(BT2020_PQ)
2261 .execute();
2262}
2263
2264TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2265 // BT2020_PQ is not used if there is only legacy support for it.
2266 verify().ifTopLayerIs(BT2020_PQ)
2267 .andTopLayerIsREComposed(false)
2268 .andIfBottomLayerIs(BT2020_HLG)
2269 .andBottomLayerIsREComposed(false)
2270 .andIfLegacySupportFor(BT2020_PQ, true)
2271 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2272 .execute();
2273}
2274
2275TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2276 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2277 verify().ifTopLayerIs(BT2020_PQ)
2278 .andTopLayerIsREComposed(false)
2279 .andIfBottomLayerIs(BT2020_HLG)
2280 .andBottomLayerIsREComposed(true)
2281 .andIfLegacySupportFor(BT2020_PQ, false)
2282 .thenExpectBestColorModeCallUses(BT2020_PQ)
2283 .execute();
2284}
2285
2286TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2287 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2288 verify().ifTopLayerIs(BT2020_PQ)
2289 .andTopLayerIsREComposed(true)
2290 .andIfBottomLayerIs(BT2020_HLG)
2291 .andBottomLayerIsREComposed(false)
2292 .andIfLegacySupportFor(BT2020_PQ, false)
2293 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2294 .execute();
2295}
2296
2297TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2298 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2299 // used if there are no other special conditions.
2300 verify().ifTopLayerIs(BT2020_HLG)
2301 .andTopLayerIsREComposed(false)
2302 .andIfBottomLayerIs(BT2020_PQ)
2303 .andBottomLayerIsREComposed(false)
2304 .andIfLegacySupportFor(BT2020_PQ, false)
2305 .thenExpectBestColorModeCallUses(BT2020_PQ)
2306 .execute();
2307}
2308
2309TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2310 // BT2020_PQ is not used if there is only legacy support for it.
2311 verify().ifTopLayerIs(BT2020_HLG)
2312 .andTopLayerIsREComposed(false)
2313 .andIfBottomLayerIs(BT2020_PQ)
2314 .andBottomLayerIsREComposed(false)
2315 .andIfLegacySupportFor(BT2020_PQ, true)
2316 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2317 .execute();
2318}
2319
2320TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2321 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2322 verify().ifTopLayerIs(BT2020_HLG)
2323 .andTopLayerIsREComposed(false)
2324 .andIfBottomLayerIs(BT2020_PQ)
2325 .andBottomLayerIsREComposed(true)
2326 .andIfLegacySupportFor(BT2020_PQ, false)
2327 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2328 .execute();
2329}
2330
2331TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2332 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2333 verify().ifTopLayerIs(BT2020_HLG)
2334 .andTopLayerIsREComposed(true)
2335 .andIfBottomLayerIs(BT2020_PQ)
2336 .andBottomLayerIsREComposed(false)
2337 .andIfLegacySupportFor(BT2020_PQ, false)
2338 .thenExpectBestColorModeCallUses(BT2020_PQ)
2339 .execute();
2340}
2341
2342TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2343 // If all layers use HLG then HLG is used if there are no other special
2344 // conditions.
2345 verify().ifTopLayerIs(BT2020_HLG)
2346 .andTopLayerIsREComposed(false)
2347 .andIfBottomLayerIs(BT2020_HLG)
2348 .andBottomLayerIsREComposed(false)
2349 .andIfLegacySupportFor(BT2020_HLG, false)
2350 .thenExpectBestColorModeCallUses(BT2020_HLG)
2351 .execute();
2352}
2353
2354TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2355 // BT2020_HLG is not used if there is legacy support for it.
2356 verify().ifTopLayerIs(BT2020_HLG)
2357 .andTopLayerIsREComposed(false)
2358 .andIfBottomLayerIs(BT2020_HLG)
2359 .andBottomLayerIsREComposed(false)
2360 .andIfLegacySupportFor(BT2020_HLG, true)
2361 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2362 .execute();
2363}
2364
2365TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2366 // BT2020_HLG is used even if the bottom layer is client composed.
2367 verify().ifTopLayerIs(BT2020_HLG)
2368 .andTopLayerIsREComposed(false)
2369 .andIfBottomLayerIs(BT2020_HLG)
2370 .andBottomLayerIsREComposed(true)
2371 .andIfLegacySupportFor(BT2020_HLG, false)
2372 .thenExpectBestColorModeCallUses(BT2020_HLG)
2373 .execute();
2374}
2375
2376TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2377 // BT2020_HLG is used even if the top layer is client composed.
2378 verify().ifTopLayerIs(BT2020_HLG)
2379 .andTopLayerIsREComposed(true)
2380 .andIfBottomLayerIs(BT2020_HLG)
2381 .andBottomLayerIsREComposed(false)
2382 .andIfLegacySupportFor(BT2020_HLG, false)
2383 .thenExpectBestColorModeCallUses(BT2020_HLG)
2384 .execute();
2385}
2386
2387TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2388 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2389 verify().ifTopLayerIs(BT2020_PQ)
2390 .andTopLayerIsREComposed(false)
2391 .andIfBottomLayerIsNotHdr()
2392 .andBottomLayerIsREComposed(false)
2393 .andIfLegacySupportFor(BT2020_PQ, false)
2394 .thenExpectBestColorModeCallUses(BT2020_PQ)
2395 .execute();
2396}
2397
2398TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2399 // If all layers use HLG then HLG is used if there are no other special
2400 // conditions.
2401 verify().ifTopLayerIs(BT2020_HLG)
2402 .andTopLayerIsREComposed(false)
2403 .andIfBottomLayerIsNotHdr()
2404 .andBottomLayerIsREComposed(true)
2405 .andIfLegacySupportFor(BT2020_HLG, false)
2406 .thenExpectBestColorModeCallUses(BT2020_HLG)
2407 .execute();
2408}
2409
2410struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2411 : public OutputUpdateColorProfileTest {
2412 // The various values for CompositionRefreshArgs::outputColorSetting affect
2413 // the chosen renderIntent, along with whether the preferred dataspace is an
2414 // HDR dataspace or not.
2415
2416 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2417 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2418 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2419 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002420 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002421 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2422 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2423 .WillRepeatedly(Return(false));
2424 }
2425
2426 // The tests here involve enough state and GMock setup that using a mini-DSL
2427 // makes the tests much more readable, and allows the test to focus more on
2428 // the intent than on some of the details.
2429
2430 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2431 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2432
2433 struct IfDataspaceChosenState
2434 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2435 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2436 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2437 return nextState<AndOutputColorSettingState>();
2438 }
2439 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2440 return ifDataspaceChosenIs(kNonHdrDataspace);
2441 }
2442 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2443 };
2444
2445 struct AndOutputColorSettingState
2446 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2447 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2448 getInstance()->mRefreshArgs.outputColorSetting = setting;
2449 return nextState<ThenExpectBestColorModeCallUsesState>();
2450 }
2451 };
2452
2453 struct ThenExpectBestColorModeCallUsesState
2454 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2455 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2456 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2457 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2458 _, _));
2459 return nextState<ExecuteState>();
2460 }
2461 };
2462
2463 // Tests call one of these two helper member functions to start using the
2464 // mini-DSL defined above.
2465 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2466};
2467
2468TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2469 Managed_NonHdr_Prefers_Colorimetric) {
2470 verify().ifDataspaceChosenIsNonHdr()
2471 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2472 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2473 .execute();
2474}
2475
2476TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2477 Managed_Hdr_Prefers_ToneMapColorimetric) {
2478 verify().ifDataspaceChosenIsHdr()
2479 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2480 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2481 .execute();
2482}
2483
2484TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2485 verify().ifDataspaceChosenIsNonHdr()
2486 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2487 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2488 .execute();
2489}
2490
2491TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2492 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2493 verify().ifDataspaceChosenIsHdr()
2494 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2495 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2496 .execute();
2497}
2498
2499TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2500 verify().ifDataspaceChosenIsNonHdr()
2501 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2502 .thenExpectBestColorModeCallUses(
2503 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2504 .execute();
2505}
2506
2507TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2508 verify().ifDataspaceChosenIsHdr()
2509 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2510 .thenExpectBestColorModeCallUses(
2511 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2512 .execute();
2513}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002514
2515/*
2516 * Output::beginFrame()
2517 */
2518
Lloyd Piquee5965952019-11-18 16:16:32 -08002519struct OutputBeginFrameTest : public ::testing::Test {
2520 using TestType = OutputBeginFrameTest;
2521
2522 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002523 // Sets up the helper functions called by the function under test to use
2524 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002525 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2526 };
2527
2528 OutputBeginFrameTest() {
2529 mOutput.setDisplayColorProfileForTest(
2530 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2531 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2532 }
2533
2534 struct IfGetDirtyRegionExpectationState
2535 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2536 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2537 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2538 .WillOnce(Return(dirtyRegion));
2539 return nextState<AndIfGetOutputLayerCountExpectationState>();
2540 }
2541 };
2542
2543 struct AndIfGetOutputLayerCountExpectationState
2544 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2545 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2546 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2547 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2548 }
2549 };
2550
2551 struct AndIfLastCompositionHadVisibleLayersState
2552 : public CallOrderStateMachineHelper<TestType,
2553 AndIfLastCompositionHadVisibleLayersState> {
2554 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2555 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2556 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2557 }
2558 };
2559
2560 struct ThenExpectRenderSurfaceBeginFrameCallState
2561 : public CallOrderStateMachineHelper<TestType,
2562 ThenExpectRenderSurfaceBeginFrameCallState> {
2563 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2564 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2565 return nextState<ExecuteState>();
2566 }
2567 };
2568
2569 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2570 [[nodiscard]] auto execute() {
2571 getInstance()->mOutput.beginFrame();
2572 return nextState<CheckPostconditionHadVisibleLayersState>();
2573 }
2574 };
2575
2576 struct CheckPostconditionHadVisibleLayersState
2577 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2578 void checkPostconditionHadVisibleLayers(bool expected) {
2579 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2580 }
2581 };
2582
2583 // Tests call one of these two helper member functions to start using the
2584 // mini-DSL defined above.
2585 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2586
2587 static const Region kEmptyRegion;
2588 static const Region kNotEmptyRegion;
2589
2590 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2591 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2592 StrictMock<OutputPartialMock> mOutput;
2593};
2594
2595const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2596const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2597
2598TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2599 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2600 .andIfGetOutputLayerCountReturns(1u)
2601 .andIfLastCompositionHadVisibleLayersIs(true)
2602 .thenExpectRenderSurfaceBeginFrameCall(true)
2603 .execute()
2604 .checkPostconditionHadVisibleLayers(true);
2605}
2606
2607TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2608 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2609 .andIfGetOutputLayerCountReturns(0u)
2610 .andIfLastCompositionHadVisibleLayersIs(true)
2611 .thenExpectRenderSurfaceBeginFrameCall(true)
2612 .execute()
2613 .checkPostconditionHadVisibleLayers(false);
2614}
2615
2616TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2617 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2618 .andIfGetOutputLayerCountReturns(1u)
2619 .andIfLastCompositionHadVisibleLayersIs(false)
2620 .thenExpectRenderSurfaceBeginFrameCall(true)
2621 .execute()
2622 .checkPostconditionHadVisibleLayers(true);
2623}
2624
2625TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2626 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2627 .andIfGetOutputLayerCountReturns(0u)
2628 .andIfLastCompositionHadVisibleLayersIs(false)
2629 .thenExpectRenderSurfaceBeginFrameCall(false)
2630 .execute()
2631 .checkPostconditionHadVisibleLayers(false);
2632}
2633
2634TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2635 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2636 .andIfGetOutputLayerCountReturns(1u)
2637 .andIfLastCompositionHadVisibleLayersIs(true)
2638 .thenExpectRenderSurfaceBeginFrameCall(false)
2639 .execute()
2640 .checkPostconditionHadVisibleLayers(true);
2641}
2642
2643TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2644 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2645 .andIfGetOutputLayerCountReturns(0u)
2646 .andIfLastCompositionHadVisibleLayersIs(true)
2647 .thenExpectRenderSurfaceBeginFrameCall(false)
2648 .execute()
2649 .checkPostconditionHadVisibleLayers(true);
2650}
2651
2652TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2653 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2654 .andIfGetOutputLayerCountReturns(1u)
2655 .andIfLastCompositionHadVisibleLayersIs(false)
2656 .thenExpectRenderSurfaceBeginFrameCall(false)
2657 .execute()
2658 .checkPostconditionHadVisibleLayers(false);
2659}
2660
2661TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2662 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2663 .andIfGetOutputLayerCountReturns(0u)
2664 .andIfLastCompositionHadVisibleLayersIs(false)
2665 .thenExpectRenderSurfaceBeginFrameCall(false)
2666 .execute()
2667 .checkPostconditionHadVisibleLayers(false);
2668}
2669
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002670/*
2671 * Output::devOptRepaintFlash()
2672 */
2673
Lloyd Piquedb462d82019-11-19 17:58:46 -08002674struct OutputDevOptRepaintFlashTest : public testing::Test {
2675 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002676 // Sets up the helper functions called by the function under test to use
2677 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002678 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002679 MOCK_METHOD2(composeSurfaces,
2680 std::optional<base::unique_fd>(
2681 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002682 MOCK_METHOD0(postFramebuffer, void());
2683 MOCK_METHOD0(prepareFrame, void());
2684 };
2685
2686 OutputDevOptRepaintFlashTest() {
2687 mOutput.setDisplayColorProfileForTest(
2688 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2689 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2690 }
2691
2692 static const Region kEmptyRegion;
2693 static const Region kNotEmptyRegion;
2694
2695 StrictMock<OutputPartialMock> mOutput;
2696 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2697 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2698 CompositionRefreshArgs mRefreshArgs;
2699};
2700
2701const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2702const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2703
2704TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2705 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2706 mRefreshArgs.repaintEverything = true;
2707 mOutput.mState.isEnabled = true;
2708
2709 mOutput.devOptRepaintFlash(mRefreshArgs);
2710}
2711
2712TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2713 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2714 mRefreshArgs.repaintEverything = true;
2715 mOutput.mState.isEnabled = false;
2716
2717 InSequence seq;
2718 EXPECT_CALL(mOutput, postFramebuffer());
2719 EXPECT_CALL(mOutput, prepareFrame());
2720
2721 mOutput.devOptRepaintFlash(mRefreshArgs);
2722}
2723
2724TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2725 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2726 mRefreshArgs.repaintEverything = true;
2727 mOutput.mState.isEnabled = true;
2728
2729 InSequence seq;
2730 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2731 EXPECT_CALL(mOutput, postFramebuffer());
2732 EXPECT_CALL(mOutput, prepareFrame());
2733
2734 mOutput.devOptRepaintFlash(mRefreshArgs);
2735}
2736
2737TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2738 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2739 mRefreshArgs.repaintEverything = false;
2740 mOutput.mState.isEnabled = true;
2741
2742 InSequence seq;
2743 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002744 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002745 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2746 EXPECT_CALL(mOutput, postFramebuffer());
2747 EXPECT_CALL(mOutput, prepareFrame());
2748
2749 mOutput.devOptRepaintFlash(mRefreshArgs);
2750}
2751
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002752/*
2753 * Output::finishFrame()
2754 */
2755
Lloyd Pique03561a62019-11-19 18:34:52 -08002756struct OutputFinishFrameTest : public testing::Test {
2757 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002758 // Sets up the helper functions called by the function under test to use
2759 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002760 MOCK_METHOD2(composeSurfaces,
2761 std::optional<base::unique_fd>(
2762 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002763 MOCK_METHOD0(postFramebuffer, void());
2764 };
2765
2766 OutputFinishFrameTest() {
2767 mOutput.setDisplayColorProfileForTest(
2768 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2769 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2770 }
2771
2772 StrictMock<OutputPartialMock> mOutput;
2773 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2774 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2775 CompositionRefreshArgs mRefreshArgs;
2776};
2777
2778TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2779 mOutput.mState.isEnabled = false;
2780
2781 mOutput.finishFrame(mRefreshArgs);
2782}
2783
2784TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2785 mOutput.mState.isEnabled = true;
2786
2787 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002788 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002789
2790 mOutput.finishFrame(mRefreshArgs);
2791}
2792
2793TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2794 mOutput.mState.isEnabled = true;
2795
2796 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002797 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002798 .WillOnce(Return(ByMove(base::unique_fd())));
2799 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2800
2801 mOutput.finishFrame(mRefreshArgs);
2802}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002803
2804/*
2805 * Output::postFramebuffer()
2806 */
2807
Lloyd Pique07178e32019-11-19 19:15:26 -08002808struct OutputPostFramebufferTest : public testing::Test {
2809 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002810 // Sets up the helper functions called by the function under test to use
2811 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002812 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2813 };
2814
2815 struct Layer {
2816 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002817 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002818 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2819 }
2820
2821 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002822 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002823 StrictMock<HWC2::mock::Layer> hwc2Layer;
2824 };
2825
2826 OutputPostFramebufferTest() {
2827 mOutput.setDisplayColorProfileForTest(
2828 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2829 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2830
2831 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2832 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2833 .WillRepeatedly(Return(&mLayer1.outputLayer));
2834 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2835 .WillRepeatedly(Return(&mLayer2.outputLayer));
2836 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2837 .WillRepeatedly(Return(&mLayer3.outputLayer));
2838 }
2839
2840 StrictMock<OutputPartialMock> mOutput;
2841 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2842 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2843
2844 Layer mLayer1;
2845 Layer mLayer2;
2846 Layer mLayer3;
2847};
2848
2849TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2850 mOutput.mState.isEnabled = false;
2851
2852 mOutput.postFramebuffer();
2853}
2854
2855TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2856 mOutput.mState.isEnabled = true;
2857
2858 compositionengine::Output::FrameFences frameFences;
2859
2860 // This should happen even if there are no output layers.
2861 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2862
2863 // For this test in particular we want to make sure the call expectations
2864 // setup below are satisfied in the specific order.
2865 InSequence seq;
2866
2867 EXPECT_CALL(*mRenderSurface, flip());
2868 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2869 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2870
2871 mOutput.postFramebuffer();
2872}
2873
2874TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2875 // Simulate getting release fences from each layer, and ensure they are passed to the
2876 // front-end layer interface for each layer correctly.
2877
2878 mOutput.mState.isEnabled = true;
2879
2880 // Create three unique fence instances
2881 sp<Fence> layer1Fence = new Fence();
2882 sp<Fence> layer2Fence = new Fence();
2883 sp<Fence> layer3Fence = new Fence();
2884
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002885 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002886 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2887 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2888 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2889
2890 EXPECT_CALL(*mRenderSurface, flip());
2891 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2892 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2893
2894 // Compare the pointers values of each fence to make sure the correct ones
2895 // are passed. This happens to work with the current implementation, but
2896 // would not survive certain calls like Fence::merge() which would return a
2897 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002898 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002899 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002900 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002901 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002902 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002903 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2904
2905 mOutput.postFramebuffer();
2906}
2907
2908TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2909 mOutput.mState.isEnabled = true;
2910 mOutput.mState.usesClientComposition = true;
2911
2912 sp<Fence> clientTargetAcquireFence = new Fence();
2913 sp<Fence> layer1Fence = new Fence();
2914 sp<Fence> layer2Fence = new Fence();
2915 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002916 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002917 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2918 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2919 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2920 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2921
2922 EXPECT_CALL(*mRenderSurface, flip());
2923 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2924 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2925
2926 // Fence::merge is called, and since none of the fences are actually valid,
2927 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2928 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002929 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2930 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2931 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002932
2933 mOutput.postFramebuffer();
2934}
2935
2936TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2937 mOutput.mState.isEnabled = true;
2938 mOutput.mState.usesClientComposition = true;
2939
2940 // This should happen even if there are no (current) output layers.
2941 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2942
2943 // Load up the released layers with some mock instances
2944 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2945 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2946 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2947 Output::ReleasedLayers layers;
2948 layers.push_back(releasedLayer1);
2949 layers.push_back(releasedLayer2);
2950 layers.push_back(releasedLayer3);
2951 mOutput.setReleasedLayers(std::move(layers));
2952
2953 // Set up a fake present fence
2954 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002955 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002956 frameFences.presentFence = presentFence;
2957
2958 EXPECT_CALL(*mRenderSurface, flip());
2959 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2960 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2961
2962 // Each released layer should be given the presentFence.
2963 EXPECT_CALL(*releasedLayer1,
2964 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2965 EXPECT_CALL(*releasedLayer2,
2966 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2967 EXPECT_CALL(*releasedLayer3,
2968 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2969
2970 mOutput.postFramebuffer();
2971
2972 // After the call the list of released layers should have been cleared.
2973 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2974}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002975
2976/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002977 * Output::composeSurfaces()
2978 */
2979
2980struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002981 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002982
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002983 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002984 // Sets up the helper functions called by the function under test to use
2985 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002986 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Sally Qidf3da512021-07-08 17:27:02 +00002987 MOCK_METHOD2(generateClientCompositionRequests,
2988 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002989 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002990 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002991 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
2992 };
2993
2994 OutputComposeSurfacesTest() {
2995 mOutput.setDisplayColorProfileForTest(
2996 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2997 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08002998 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07002999
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003000 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
3001 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003002 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003003 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003004 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003005 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003006 mOutput.mState.dataspace = kDefaultOutputDataspace;
3007 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3008 mOutput.mState.isSecure = false;
3009 mOutput.mState.needsFiltering = false;
3010 mOutput.mState.usesClientComposition = true;
3011 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003012 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003013 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003014
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003015 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003016 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003017 EXPECT_CALL(mCompositionEngine, getTimeStats())
3018 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003019 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3020 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003021 }
3022
Lloyd Pique6818fa52019-12-03 12:32:13 -08003023 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3024 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003025 getInstance()->mReadyFence =
3026 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003027 return nextState<FenceCheckState>();
3028 }
3029 };
3030
3031 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3032 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3033
3034 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3035 };
3036
3037 // Call this member function to start using the mini-DSL defined above.
3038 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3039
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003040 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3041 static constexpr uint32_t kDefaultOutputOrientationFlags =
3042 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003043 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3044 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3045 static constexpr float kDefaultMaxLuminance = 0.9f;
3046 static constexpr float kDefaultAvgLuminance = 0.7f;
3047 static constexpr float kDefaultMinLuminance = 0.1f;
3048
3049 static const Rect kDefaultOutputFrame;
3050 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003051 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003052 static const mat4 kDefaultColorTransformMat;
3053
3054 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003055 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003056 static const HdrCapabilities kHdrCapabilities;
3057
Lloyd Pique56eba802019-08-28 15:45:25 -07003058 StrictMock<mock::CompositionEngine> mCompositionEngine;
3059 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003060 // TODO: make this is a proper mock.
3061 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003062 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3063 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003064 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003065 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3066 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3067 renderengine::ExternalTexture::Usage::READABLE |
3068 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003069
3070 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003071};
3072
3073const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3074const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003075const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003076const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003077const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003078const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3079const HdrCapabilities OutputComposeSurfacesTest::
3080 kHdrCapabilities{{},
3081 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3082 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3083 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003084
Lloyd Piquea76ce462020-01-14 13:06:37 -08003085TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003086 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003087
Lloyd Piquee9eff972020-05-05 12:36:44 -07003088 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003089 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003090
Lloyd Piquea76ce462020-01-14 13:06:37 -08003091 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3092
Lloyd Pique6818fa52019-12-03 12:32:13 -08003093 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003094}
3095
Lloyd Piquee9eff972020-05-05 12:36:44 -07003096TEST_F(OutputComposeSurfacesTest,
3097 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3098 mOutput.mState.usesClientComposition = false;
3099 mOutput.mState.flipClientTarget = true;
3100
Lloyd Pique6818fa52019-12-03 12:32:13 -08003101 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003102 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003103
3104 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3105 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3106
3107 verify().execute().expectAFenceWasReturned();
3108}
3109
3110TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3111 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003112 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003113
3114 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3115
3116 verify().execute().expectNoFenceWasReturned();
3117}
3118
3119TEST_F(OutputComposeSurfacesTest,
3120 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3121 mOutput.mState.usesClientComposition = false;
3122 mOutput.mState.flipClientTarget = true;
3123
3124 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003125 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003126
Lloyd Pique6818fa52019-12-03 12:32:13 -08003127 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003128
Lloyd Pique6818fa52019-12-03 12:32:13 -08003129 verify().execute().expectNoFenceWasReturned();
3130}
Lloyd Pique56eba802019-08-28 15:45:25 -07003131
Lloyd Pique6818fa52019-12-03 12:32:13 -08003132TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3133 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3134 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3135 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003136 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003137 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003138 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003139 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3140 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003141
Lloyd Pique6818fa52019-12-03 12:32:13 -08003142 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003143 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003144 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003145
Lloyd Pique6818fa52019-12-03 12:32:13 -08003146 verify().execute().expectAFenceWasReturned();
3147}
Lloyd Pique56eba802019-08-28 15:45:25 -07003148
Lloyd Pique6818fa52019-12-03 12:32:13 -08003149TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003150 LayerFE::LayerSettings r1;
3151 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003152
3153 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3154 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3155
3156 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3157 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3158 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003159 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003160 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003161 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003162 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3163 .WillRepeatedly(
3164 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003165 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003166 clientCompositionLayers.emplace_back(r2);
3167 }));
3168
3169 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003170 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3171 .WillRepeatedly(Return(NO_ERROR));
3172
3173 verify().execute().expectAFenceWasReturned();
3174}
3175
3176TEST_F(OutputComposeSurfacesTest,
3177 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3178 LayerFE::LayerSettings r1;
3179 LayerFE::LayerSettings r2;
3180
3181 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3182 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003183 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003184
3185 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3186 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3187 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3188 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003189 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Alec Mouri1684c702021-02-04 12:27:26 -08003190 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3191 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3192 .WillRepeatedly(
3193 Invoke([&](const Region&,
3194 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3195 clientCompositionLayers.emplace_back(r2);
3196 }));
3197
3198 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003199 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003200 .WillRepeatedly(Return(NO_ERROR));
3201
3202 verify().execute().expectAFenceWasReturned();
3203}
3204
Vishnu Nair9b079a22020-01-21 14:36:08 -08003205TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3206 mOutput.cacheClientCompositionRequests(0);
3207 LayerFE::LayerSettings r1;
3208 LayerFE::LayerSettings r2;
3209
3210 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3211 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3212
3213 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3214 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3215 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003216 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003217 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003218 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3219 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3220 .WillRepeatedly(Return());
3221
3222 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003223 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003224 .Times(2)
3225 .WillOnce(Return(NO_ERROR));
3226
3227 verify().execute().expectAFenceWasReturned();
3228 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3229
3230 verify().execute().expectAFenceWasReturned();
3231 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3232}
3233
3234TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3235 mOutput.cacheClientCompositionRequests(3);
3236 LayerFE::LayerSettings r1;
3237 LayerFE::LayerSettings r2;
3238
3239 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3240 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3241
3242 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3243 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3244 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003245 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003246 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003247 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3248 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3249 .WillRepeatedly(Return());
3250
3251 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003252 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003253 .WillOnce(Return(NO_ERROR));
3254 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3255
3256 verify().execute().expectAFenceWasReturned();
3257 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3258
3259 // We do not expect another call to draw layers.
3260 verify().execute().expectAFenceWasReturned();
3261 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3262}
3263
3264TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3265 LayerFE::LayerSettings r1;
3266 LayerFE::LayerSettings r2;
3267
3268 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3269 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3270
3271 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3272 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3273 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003274 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003275 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003276 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3277 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3278 .WillRepeatedly(Return());
3279
Alec Mouria90a5702021-04-16 16:36:21 +00003280 const auto otherOutputBuffer = std::make_shared<
3281 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3282 renderengine::ExternalTexture::Usage::READABLE |
3283 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003284 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3285 .WillOnce(Return(mOutputBuffer))
3286 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003287 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003288 .WillRepeatedly(Return(NO_ERROR));
3289
3290 verify().execute().expectAFenceWasReturned();
3291 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3292
3293 verify().execute().expectAFenceWasReturned();
3294 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3295}
3296
3297TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3298 LayerFE::LayerSettings r1;
3299 LayerFE::LayerSettings r2;
3300 LayerFE::LayerSettings r3;
3301
3302 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3303 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3304 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3305
3306 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3307 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3308 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003309 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003310 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003311 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3312 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3313 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3314 .WillRepeatedly(Return());
3315
3316 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003317 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003318 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003319 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003320 .WillOnce(Return(NO_ERROR));
3321
3322 verify().execute().expectAFenceWasReturned();
3323 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3324
3325 verify().execute().expectAFenceWasReturned();
3326 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3327}
3328
Lloyd Pique6818fa52019-12-03 12:32:13 -08003329struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3330 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3331 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003332 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Sally Qidf3da512021-07-08 17:27:02 +00003333 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003334 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003335 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3336 .WillRepeatedly(Return());
3337 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3338 }
3339
3340 struct MixedCompositionState
3341 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3342 auto ifMixedCompositionIs(bool used) {
3343 getInstance()->mOutput.mState.usesDeviceComposition = used;
3344 return nextState<OutputUsesHdrState>();
3345 }
3346 };
3347
3348 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3349 auto andIfUsesHdr(bool used) {
3350 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3351 .WillOnce(Return(used));
3352 return nextState<SkipColorTransformState>();
3353 }
3354 };
3355
3356 struct SkipColorTransformState
3357 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3358 auto andIfSkipColorTransform(bool skip) {
3359 // May be called zero or one times.
3360 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3361 .WillRepeatedly(Return(skip));
3362 return nextState<ExpectDisplaySettingsState>();
3363 }
3364 };
3365
3366 struct ExpectDisplaySettingsState
3367 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3368 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003369 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003370 .WillOnce(Return(NO_ERROR));
3371 return nextState<ExecuteState>();
3372 }
3373 };
3374
3375 // Call this member function to start using the mini-DSL defined above.
3376 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3377};
3378
3379TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3380 verify().ifMixedCompositionIs(true)
3381 .andIfUsesHdr(true)
3382 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003383 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003384 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003385 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003386 .execute()
3387 .expectAFenceWasReturned();
3388}
3389
3390TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3391 verify().ifMixedCompositionIs(true)
3392 .andIfUsesHdr(false)
3393 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003394 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003395 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003396 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003397 .execute()
3398 .expectAFenceWasReturned();
3399}
3400
3401TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3402 verify().ifMixedCompositionIs(false)
3403 .andIfUsesHdr(true)
3404 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003405 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003406 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003407 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003408 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003409 .execute()
3410 .expectAFenceWasReturned();
3411}
3412
3413TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3414 verify().ifMixedCompositionIs(false)
3415 .andIfUsesHdr(false)
3416 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003417 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003418 kDefaultMaxLuminance, kDefaultOutputDataspace,
Sally Qidf3da512021-07-08 17:27:02 +00003419 kDefaultColorTransformMat,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003420 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003421 .execute()
3422 .expectAFenceWasReturned();
3423}
3424
3425TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3426 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3427 verify().ifMixedCompositionIs(false)
3428 .andIfUsesHdr(true)
3429 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003430 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003431 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Sally Qidf3da512021-07-08 17:27:02 +00003432 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003433 .execute()
3434 .expectAFenceWasReturned();
3435}
3436
3437struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3438 struct Layer {
3439 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003440 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3441 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003442 }
3443
3444 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003445 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003446 LayerFECompositionState mLayerFEState;
3447 };
3448
3449 OutputComposeSurfacesTest_HandlesProtectedContent() {
3450 mLayer1.mLayerFEState.hasProtectedContent = false;
3451 mLayer2.mLayerFEState.hasProtectedContent = false;
3452
3453 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3454 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3455 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3456 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3457 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3458
3459 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3460
3461 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3462
Sally Qidf3da512021-07-08 17:27:02 +00003463 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003464 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003465 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3466 .WillRepeatedly(Return());
3467 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003468 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003469 .WillRepeatedly(Return(NO_ERROR));
3470 }
3471
3472 Layer mLayer1;
3473 Layer mLayer2;
3474};
3475
3476TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3477 mOutput.mState.isSecure = false;
3478 mLayer2.mLayerFEState.hasProtectedContent = true;
3479 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003480 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003481 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003482
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003483 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003484}
3485
3486TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3487 mOutput.mState.isSecure = true;
3488 mLayer2.mLayerFEState.hasProtectedContent = true;
3489 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3490
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003491 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003492}
3493
3494TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3495 mOutput.mState.isSecure = true;
3496 mLayer2.mLayerFEState.hasProtectedContent = false;
3497 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3498 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3499 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3500 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3501 EXPECT_CALL(*mRenderSurface, setProtected(false));
3502
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003503 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003504}
3505
3506TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3507 mOutput.mState.isSecure = true;
3508 mLayer2.mLayerFEState.hasProtectedContent = true;
3509 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3510
3511 // For this test, we also check the call order of key functions.
3512 InSequence seq;
3513
3514 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3515 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3516 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3517 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3518 EXPECT_CALL(*mRenderSurface, setProtected(true));
3519 // Must happen after setting the protected content state.
3520 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003521 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003522
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, ifAlreadyEnabledEverywhere) {
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));
3531 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3532
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003533 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003534}
3535
3536TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3537 mOutput.mState.isSecure = true;
3538 mLayer2.mLayerFEState.hasProtectedContent = true;
3539 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3540 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3541 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3542 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3543
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003544 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003545}
3546
3547TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3548 mOutput.mState.isSecure = true;
3549 mLayer2.mLayerFEState.hasProtectedContent = true;
3550 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3551 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3552 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3553 EXPECT_CALL(*mRenderSurface, setProtected(true));
3554
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003555 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003556}
3557
3558TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3559 mOutput.mState.isSecure = true;
3560 mLayer2.mLayerFEState.hasProtectedContent = true;
3561 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3562 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3563 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3564 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3565
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003566 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003567}
3568
3569struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3570 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3571 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3572 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3573 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003574 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003575 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3576 .WillRepeatedly(Return());
3577 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3578 }
3579};
3580
3581TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3582 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3583
Sally Qidf3da512021-07-08 17:27:02 +00003584 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003585 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003586
3587 // For this test, we also check the call order of key functions.
3588 InSequence seq;
3589
3590 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003591 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003592
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003593 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3594}
3595
3596struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3597 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3598 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3599 mLayer.layerFEState.backgroundBlurRadius = 10;
3600 mOutput.editState().isEnabled = true;
3601
Snild Dolkow9e217d62020-04-22 15:53:42 +02003602 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003603 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003604 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3605 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Sally Qidf3da512021-07-08 17:27:02 +00003606 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003607 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003608 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003609 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3610 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3611 .WillRepeatedly(Return(&mLayer.outputLayer));
3612 }
3613
3614 NonInjectedLayer mLayer;
3615 compositionengine::CompositionRefreshArgs mRefreshArgs;
3616};
3617
3618TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3619 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003620 mOutput.updateCompositionState(mRefreshArgs);
3621 mOutput.planComposition();
3622 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003623
3624 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3625 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3626}
3627
3628TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3629 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003630 mOutput.updateCompositionState(mRefreshArgs);
3631 mOutput.planComposition();
3632 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003633
3634 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3635 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003636}
3637
3638/*
3639 * Output::generateClientCompositionRequests()
3640 */
3641
3642struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003643 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003644 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003645 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Sally Qidf3da512021-07-08 17:27:02 +00003646 bool supportsProtectedContent, ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003647 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Sally Qidf3da512021-07-08 17:27:02 +00003648 dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003649 }
3650 };
3651
Lloyd Piquea4863342019-12-04 18:45:02 -08003652 struct Layer {
3653 Layer() {
3654 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3655 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003656 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3657 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003658 }
3659
3660 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003661 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003662 LayerFECompositionState mLayerFEState;
3663 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003664 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003665 };
3666
Lloyd Pique56eba802019-08-28 15:45:25 -07003667 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003668 mOutput.mState.needsFiltering = false;
3669
Lloyd Pique56eba802019-08-28 15:45:25 -07003670 mOutput.setDisplayColorProfileForTest(
3671 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3672 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3673 }
3674
Lloyd Pique56eba802019-08-28 15:45:25 -07003675 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3676 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003677 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003678};
3679
Lloyd Piquea4863342019-12-04 18:45:02 -08003680struct GenerateClientCompositionRequestsTest_ThreeLayers
3681 : public GenerateClientCompositionRequestsTest {
3682 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003683 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3684 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3685 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003686 mOutput.mState.transform =
3687 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3688 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003689 mOutput.mState.needsFiltering = false;
3690 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003691
Lloyd Piquea4863342019-12-04 18:45:02 -08003692 for (size_t i = 0; i < mLayers.size(); i++) {
3693 mLayers[i].mOutputLayerState.clearClientTarget = false;
3694 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3695 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003696 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003697 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003698 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3699 mLayers[i].mLayerSettings.alpha = 1.0f;
3700 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003701
Lloyd Piquea4863342019-12-04 18:45:02 -08003702 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3703 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3704 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3705 .WillRepeatedly(Return(true));
3706 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3707 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003708
Lloyd Piquea4863342019-12-04 18:45:02 -08003709 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3710 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003711
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003712 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003713 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003714
Lloyd Piquea4863342019-12-04 18:45:02 -08003715 static const Rect kDisplayFrame;
3716 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003717 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003718
Lloyd Piquea4863342019-12-04 18:45:02 -08003719 std::array<Layer, 3> mLayers;
3720};
Lloyd Pique56eba802019-08-28 15:45:25 -07003721
Lloyd Piquea4863342019-12-04 18:45:02 -08003722const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3723const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003724const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3725 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003726
Lloyd Piquea4863342019-12-04 18:45:02 -08003727TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3728 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3729 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3730 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003731
Lloyd Piquea4863342019-12-04 18:45:02 -08003732 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003733 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003734 EXPECT_EQ(0u, requests.size());
3735}
3736
Lloyd Piquea4863342019-12-04 18:45:02 -08003737TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3738 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3739 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3740 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3741
Lloyd Piquea4863342019-12-04 18:45:02 -08003742 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003743 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003744 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003745}
3746
3747TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003748 LayerFE::LayerSettings mShadowSettings;
3749 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003750
Ady Abrahameca9d752021-03-03 12:20:00 -08003751 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003752 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003753 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003754 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003755 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003756 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3757 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003758
Lloyd Piquea4863342019-12-04 18:45:02 -08003759 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003760 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003761 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003762 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3763 EXPECT_EQ(mShadowSettings, requests[1]);
3764 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003765
Lloyd Piquea4863342019-12-04 18:45:02 -08003766 // Check that a timestamp was set for the layers that generated requests
3767 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3768 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3769 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3770}
3771
Alec Mourif54453c2021-05-13 16:28:28 -07003772MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3773 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3774 *result_listener << "expected " << expectedBlurSetting << "\n";
3775 *result_listener << "actual " << arg.blurSetting << "\n";
3776
3777 return expectedBlurSetting == arg.blurSetting;
3778}
3779
3780TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3781 LayerFE::LayerSettings mShadowSettings;
3782 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3783
3784 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3785
3786 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3787 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3788 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3789 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3790 EXPECT_CALL(*mLayers[2].mLayerFE,
3791 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3792 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3793 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3794 {mShadowSettings, mLayers[2].mLayerSettings})));
3795
Alec Mourif54453c2021-05-13 16:28:28 -07003796 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003797 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003798 ASSERT_EQ(3u, requests.size());
3799 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3800 EXPECT_EQ(mShadowSettings, requests[1]);
3801 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3802
Alec Mourif54453c2021-05-13 16:28:28 -07003803 // Check that a timestamp was set for the layers that generated requests
3804 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3805 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3806 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3807}
3808
Lloyd Piquea4863342019-12-04 18:45:02 -08003809TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3810 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3811 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3812 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3813 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3814
3815 mLayers[0].mOutputLayerState.clearClientTarget = false;
3816 mLayers[1].mOutputLayerState.clearClientTarget = false;
3817 mLayers[2].mOutputLayerState.clearClientTarget = false;
3818
3819 mLayers[0].mLayerFEState.isOpaque = true;
3820 mLayers[1].mLayerFEState.isOpaque = true;
3821 mLayers[2].mLayerFEState.isOpaque = true;
3822
Ady Abrahameca9d752021-03-03 12:20:00 -08003823 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003824 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003825
Lloyd Piquea4863342019-12-04 18:45:02 -08003826 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003827 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003828 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003829 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003830}
3831
3832TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3833 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3834 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3835 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3836 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3837
3838 mLayers[0].mOutputLayerState.clearClientTarget = true;
3839 mLayers[1].mOutputLayerState.clearClientTarget = true;
3840 mLayers[2].mOutputLayerState.clearClientTarget = true;
3841
3842 mLayers[0].mLayerFEState.isOpaque = false;
3843 mLayers[1].mLayerFEState.isOpaque = false;
3844 mLayers[2].mLayerFEState.isOpaque = false;
3845
Ady Abrahameca9d752021-03-03 12:20:00 -08003846 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003847 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003848
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003850 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003851 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003852 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003853}
3854
3855TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003856 // If client composition is performed with some layers set to use device
3857 // composition, device layers after the first layer (device or client) will
3858 // clear the frame buffer if they are opaque and if that layer has a flag
3859 // set to do so. The first layer is skipped as the frame buffer is already
3860 // expected to be clear.
3861
Lloyd Piquea4863342019-12-04 18:45:02 -08003862 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3863 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3864 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003865
Lloyd Piquea4863342019-12-04 18:45:02 -08003866 mLayers[0].mOutputLayerState.clearClientTarget = true;
3867 mLayers[1].mOutputLayerState.clearClientTarget = true;
3868 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003869
Lloyd Piquea4863342019-12-04 18:45:02 -08003870 mLayers[0].mLayerFEState.isOpaque = true;
3871 mLayers[1].mLayerFEState.isOpaque = true;
3872 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003873
3874 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3875 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003876 false, /* needs filtering */
3877 false, /* secure */
3878 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003879 kDisplayViewport,
3880 kDisplayDataspace,
3881 false /* realContentIsVisible */,
3882 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003883 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003884 };
3885 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3886 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003887 false, /* needs filtering */
3888 false, /* secure */
3889 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003890 kDisplayViewport,
3891 kDisplayDataspace,
3892 true /* realContentIsVisible */,
3893 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003894 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003895 };
3896
3897 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3898 mBlackoutSettings.source.buffer.buffer = nullptr;
3899 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3900 mBlackoutSettings.alpha = 0.f;
3901 mBlackoutSettings.disableBlending = true;
3902
Ady Abrahameca9d752021-03-03 12:20:00 -08003903 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003904 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003905 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003906 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3907
Lloyd Piquea4863342019-12-04 18:45:02 -08003908 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003909 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003910 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003911
Lloyd Piquea4863342019-12-04 18:45:02 -08003912 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003913 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003914
Vishnu Nair9b079a22020-01-21 14:36:08 -08003915 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003916}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003917
Lloyd Piquea4863342019-12-04 18:45:02 -08003918TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3919 clippedVisibleRegionUsedToGenerateRequest) {
3920 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3921 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3922 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003923
Lloyd Piquea4863342019-12-04 18:45:02 -08003924 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3925 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003926 false, /* needs filtering */
3927 false, /* secure */
3928 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003929 kDisplayViewport,
3930 kDisplayDataspace,
3931 true /* realContentIsVisible */,
3932 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003933 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003934 };
3935 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3936 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003937 false, /* needs filtering */
3938 false, /* secure */
3939 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003940 kDisplayViewport,
3941 kDisplayDataspace,
3942 true /* realContentIsVisible */,
3943 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003944 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003945 };
3946 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3947 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003948 false, /* needs filtering */
3949 false, /* secure */
3950 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003951 kDisplayViewport,
3952 kDisplayDataspace,
3953 true /* realContentIsVisible */,
3954 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003955 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 };
3957
Ady Abrahameca9d752021-03-03 12:20:00 -08003958 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003959 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003960 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003961 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003962 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003963 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08003964
3965 static_cast<void>(
3966 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003967 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08003968}
3969
3970TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3971 perLayerNeedsFilteringUsedToGenerateRequests) {
3972 mOutput.mState.needsFiltering = false;
3973 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
3974
Lloyd Piquea4863342019-12-04 18:45:02 -08003975 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3976 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003977 true, /* needs filtering */
3978 false, /* secure */
3979 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003980 kDisplayViewport,
3981 kDisplayDataspace,
3982 true /* realContentIsVisible */,
3983 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003984 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003985 };
3986 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3987 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003988 false, /* needs filtering */
3989 false, /* secure */
3990 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003991 kDisplayViewport,
3992 kDisplayDataspace,
3993 true /* realContentIsVisible */,
3994 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003995 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003996 };
3997 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3998 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08003999 false, /* needs filtering */
4000 false, /* secure */
4001 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004002 kDisplayViewport,
4003 kDisplayDataspace,
4004 true /* realContentIsVisible */,
4005 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004006 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004007 };
4008
Ady Abrahameca9d752021-03-03 12:20:00 -08004009 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004010 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004011 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004012 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004013 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004014 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004015
4016 static_cast<void>(
4017 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004018 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004019}
4020
4021TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4022 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4023 mOutput.mState.needsFiltering = true;
4024 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4025
Lloyd Piquea4863342019-12-04 18:45:02 -08004026 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4027 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004028 true, /* needs filtering */
4029 false, /* secure */
4030 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004031 kDisplayViewport,
4032 kDisplayDataspace,
4033 true /* realContentIsVisible */,
4034 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004035 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004036
Lloyd Piquea4863342019-12-04 18:45:02 -08004037 };
4038 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4039 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004040 true, /* needs filtering */
4041 false, /* secure */
4042 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004043 kDisplayViewport,
4044 kDisplayDataspace,
4045 true /* realContentIsVisible */,
4046 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004047 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004048 };
4049 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4050 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004051 true, /* needs filtering */
4052 false, /* secure */
4053 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004054 kDisplayViewport,
4055 kDisplayDataspace,
4056 true /* realContentIsVisible */,
4057 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004058 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004059 };
4060
Ady Abrahameca9d752021-03-03 12:20:00 -08004061 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004062 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004063 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004064 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004065 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004066 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004067
4068 static_cast<void>(
4069 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004070 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004071}
4072
4073TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4074 wholeOutputSecurityUsedToGenerateRequests) {
4075 mOutput.mState.isSecure = true;
4076
Lloyd Piquea4863342019-12-04 18:45:02 -08004077 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4078 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004079 false, /* needs filtering */
4080 true, /* secure */
4081 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004082 kDisplayViewport,
4083 kDisplayDataspace,
4084 true /* realContentIsVisible */,
4085 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004086 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004087 };
4088 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4089 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004090 false, /* needs filtering */
4091 true, /* secure */
4092 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004093 kDisplayViewport,
4094 kDisplayDataspace,
4095 true /* realContentIsVisible */,
4096 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004097 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004098 };
4099 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4100 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004101 false, /* needs filtering */
4102 true, /* secure */
4103 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004104 kDisplayViewport,
4105 kDisplayDataspace,
4106 true /* realContentIsVisible */,
4107 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004108 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004109 };
4110
Ady Abrahameca9d752021-03-03 12:20:00 -08004111 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004112 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004113 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004114 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004115 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004116 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004117
4118 static_cast<void>(
4119 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004120 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004121}
4122
4123TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4124 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004125
4126 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4127 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004128 false, /* needs filtering */
4129 false, /* secure */
4130 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004131 kDisplayViewport,
4132 kDisplayDataspace,
4133 true /* realContentIsVisible */,
4134 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004135 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004136 };
4137 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4138 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004139 false, /* needs filtering */
4140 false, /* secure */
4141 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004142 kDisplayViewport,
4143 kDisplayDataspace,
4144 true /* realContentIsVisible */,
4145 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004146 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004147 };
4148 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4149 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004150 false, /* needs filtering */
4151 false, /* secure */
4152 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004153 kDisplayViewport,
4154 kDisplayDataspace,
4155 true /* realContentIsVisible */,
4156 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004157 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004158 };
4159
Ady Abrahameca9d752021-03-03 12:20:00 -08004160 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004161 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004162 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004163 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004164 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004165 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004166
4167 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004168 kDisplayDataspace));
4169}
4170
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004171TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004172 InjectedLayer layer1;
4173 InjectedLayer layer2;
4174 InjectedLayer layer3;
4175
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004176 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004177 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004178 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004179 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004180 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4181 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004182 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004183 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004184 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4185 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004186 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004187 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004188 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4189 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004190
Lloyd Piquede196652020-01-22 17:29:58 -08004191 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004192
Lloyd Piquede196652020-01-22 17:29:58 -08004193 injectOutputLayer(layer1);
4194 injectOutputLayer(layer2);
4195 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004196
4197 mOutput->editState().isEnabled = true;
4198
4199 CompositionRefreshArgs args;
4200 args.updatingGeometryThisFrame = false;
4201 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004202 mOutput->updateCompositionState(args);
4203 mOutput->planComposition();
4204 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004205}
4206
Lucas Dupinc3800b82020-10-02 16:24:48 -07004207TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4208 InjectedLayer layer1;
4209 InjectedLayer layer2;
4210 InjectedLayer layer3;
4211
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004212 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004213 // Layer requesting blur, or below, should request client composition.
4214 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004215 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004216 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4217 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004218 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004219 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004220 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4221 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004222 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004223 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004224 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4225 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004226
4227 BlurRegion region;
4228 layer2.layerFEState.blurRegions.push_back(region);
4229
4230 injectOutputLayer(layer1);
4231 injectOutputLayer(layer2);
4232 injectOutputLayer(layer3);
4233
4234 mOutput->editState().isEnabled = true;
4235
4236 CompositionRefreshArgs args;
4237 args.updatingGeometryThisFrame = false;
4238 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004239 mOutput->updateCompositionState(args);
4240 mOutput->planComposition();
4241 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004242}
4243
Lloyd Piquea4863342019-12-04 18:45:02 -08004244TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4245 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4246 // one layer on the left covering the left side of the output, and one layer
4247 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004248
4249 const Rect kPortraitFrame(0, 0, 1000, 2000);
4250 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004251 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004252 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004253 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004254
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004255 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4256 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4257 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004258 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4259 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004260 mOutput.mState.needsFiltering = false;
4261 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004262
Lloyd Piquea4863342019-12-04 18:45:02 -08004263 Layer leftLayer;
4264 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004265
Lloyd Piquea4863342019-12-04 18:45:02 -08004266 leftLayer.mOutputLayerState.clearClientTarget = false;
4267 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4268 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004269 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004270
Lloyd Piquea4863342019-12-04 18:45:02 -08004271 rightLayer.mOutputLayerState.clearClientTarget = false;
4272 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4273 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004274 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004275
4276 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4277 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4278 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4279 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4280 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4281
Lloyd Piquea4863342019-12-04 18:45:02 -08004282 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4283 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004284 false, /* needs filtering */
4285 true, /* secure */
4286 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004287 kPortraitViewport,
4288 kOutputDataspace,
4289 true /* realContentIsVisible */,
4290 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004291 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004292 };
4293
4294 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4295 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004296 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004297 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004298
4299 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4300 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004301 false, /* needs filtering */
4302 true, /* secure */
4303 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004304 kPortraitViewport,
4305 kOutputDataspace,
4306 true /* realContentIsVisible */,
4307 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004308 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004309 };
4310
4311 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4312 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004313 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004314 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004315
4316 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004317 auto requests =
4318 mOutput.generateClientCompositionRequests(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004319 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004320 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4321 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004322}
4323
Vishnu Naira483b4a2019-12-12 15:07:52 -08004324TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4325 shadowRegionOnlyVisibleSkipsContentComposition) {
4326 const Rect kContentWithShadow(40, 40, 70, 90);
4327 const Rect kContent(50, 50, 60, 80);
4328 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4329 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4330
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004331 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4332 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004333 false, /* needs filtering */
4334 false, /* secure */
4335 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004336 kDisplayViewport,
4337 kDisplayDataspace,
4338 false /* realContentIsVisible */,
4339 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004340 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004341 };
4342
Vishnu Nair9b079a22020-01-21 14:36:08 -08004343 LayerFE::LayerSettings mShadowSettings;
4344 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004345
4346 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4347 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4348
4349 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4350 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004351 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004352 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004353
Vishnu Naira483b4a2019-12-12 15:07:52 -08004354 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004355 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004356 ASSERT_EQ(1u, requests.size());
4357
Vishnu Nair9b079a22020-01-21 14:36:08 -08004358 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004359}
4360
4361TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4362 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4363 const Rect kContentWithShadow(40, 40, 70, 90);
4364 const Rect kContent(50, 50, 60, 80);
4365 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4366 const Region kPartialContentWithPartialShadowRegion =
4367 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4368
Vishnu Nair9b079a22020-01-21 14:36:08 -08004369 LayerFE::LayerSettings mShadowSettings;
4370 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004371
4372 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4373 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4374
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004375 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4376 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004377 false, /* needs filtering */
4378 false, /* secure */
4379 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004380 kDisplayViewport,
4381 kDisplayDataspace,
4382 true /* realContentIsVisible */,
4383 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004384 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004385 };
4386
Vishnu Naira483b4a2019-12-12 15:07:52 -08004387 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4388 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004389 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004390 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4391 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004392
Vishnu Naira483b4a2019-12-12 15:07:52 -08004393 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004394 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004395 ASSERT_EQ(2u, requests.size());
4396
Vishnu Nair9b079a22020-01-21 14:36:08 -08004397 EXPECT_EQ(mShadowSettings, requests[0]);
4398 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004399}
4400
Lloyd Pique32cbe282018-10-19 13:09:22 -07004401} // namespace
4402} // namespace android::compositionengine