blob: ee73cfc0c1ce6f61786d1c0fd4a97aef73f1a39c [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/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700406 * Output::setLayerStackFilter()
407 */
408
409TEST_F(OutputTest, setLayerStackFilterSetsFilterAndDirtiesEntireOutput) {
Lloyd Pique32cbe282018-10-19 13:09:22 -0700410 const uint32_t layerStack = 123u;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700411 mOutput->setLayerStackFilter(layerStack, true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700412
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700413 EXPECT_TRUE(mOutput->getState().layerStackInternal);
414 EXPECT_EQ(layerStack, mOutput->getState().layerStackId);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700416 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700417}
418
Lloyd Pique66d68602019-02-13 14:23:31 -0800419/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700420 * Output::setColorTransform
421 */
422
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800423TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700424 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700425
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800426 // If no colorTransformMatrix is set the update should be skipped.
427 CompositionRefreshArgs refreshArgs;
428 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700429
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700430 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700431
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800432 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700433 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800434
435 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700436 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800437}
Lloyd Piqueef958122019-02-05 18:00:12 -0800438
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800439TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700440 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700441
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800442 // Attempting to set the same colorTransformMatrix that is already set should
443 // also skip the update.
444 CompositionRefreshArgs refreshArgs;
445 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700446
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700447 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700448
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800449 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700450 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800451
452 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800454}
455
456TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700457 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800458
459 // Setting a different colorTransformMatrix should perform the update.
460 CompositionRefreshArgs refreshArgs;
461 refreshArgs.colorTransformMatrix = kIdentity;
462
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464
465 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467
468 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700469 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800470}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700471
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800472TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700473 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700474
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800475 // Setting a different colorTransformMatrix should perform the update.
476 CompositionRefreshArgs refreshArgs;
477 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700478
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800480
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800481 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483
484 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700485 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800486}
487
488TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700489 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800490
491 // Setting a different colorTransformMatrix should perform the update.
492 CompositionRefreshArgs refreshArgs;
493 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
494
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800496
497 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800499
500 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700501 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700502}
503
Lloyd Pique66d68602019-02-13 14:23:31 -0800504/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800505 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700506 */
507
Lloyd Pique17ca7422019-11-14 14:24:10 -0800508using OutputSetColorProfileTest = OutputTest;
509
510TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800511 using ColorProfile = Output::ColorProfile;
512
Lloyd Piquef5275482019-01-29 18:42:42 -0800513 EXPECT_CALL(*mDisplayColorProfile,
514 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
515 ui::Dataspace::UNKNOWN))
516 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800517 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700518
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700519 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
520 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
521 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700522
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700523 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
524 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
525 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
526 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800527
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700528 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800529}
530
Lloyd Pique17ca7422019-11-14 14:24:10 -0800531TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800532 using ColorProfile = Output::ColorProfile;
533
Lloyd Piquef5275482019-01-29 18:42:42 -0800534 EXPECT_CALL(*mDisplayColorProfile,
535 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
536 ui::Dataspace::UNKNOWN))
537 .WillOnce(Return(ui::Dataspace::UNKNOWN));
538
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700539 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
540 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
541 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
542 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800543
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700544 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
545 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
546 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800547
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700548 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700549}
550
Lloyd Pique66d68602019-02-13 14:23:31 -0800551/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700552 * Output::setRenderSurface()
553 */
554
555TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
556 const ui::Size newDisplaySize{640, 480};
557
558 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
559 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700562
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200563 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.bounds);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700564}
565
Lloyd Pique66d68602019-02-13 14:23:31 -0800566/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000567 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700568 */
569
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000570TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingTrue) {
571 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200572 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700573 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700574
575 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700576 Region result = mOutput->getDirtyRegion(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700577
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000578 EXPECT_THAT(result, RegionEq(Region(viewport)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700579 }
580}
581
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000582TEST_F(OutputTest, getDirtyRegionWithRepaintEverythingFalse) {
583 const Rect viewport{100, 200};
Marin Shalamanov6ad317c2020-07-29 23:34:07 +0200584 mOutput->editState().layerStackSpace.content = viewport;
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700585 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700586
587 {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700588 Region result = mOutput->getDirtyRegion(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700589
590 // The dirtyRegion should be clipped to the display bounds.
591 EXPECT_THAT(result, RegionEq(Region(Rect(50, 200))));
592 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700593}
594
Lloyd Pique66d68602019-02-13 14:23:31 -0800595/*
Lloyd Piqueef36b002019-01-23 17:52:04 -0800596 * Output::belongsInOutput()
597 */
598
599TEST_F(OutputTest, belongsInOutputFiltersAsExpected) {
600 const uint32_t layerStack1 = 123u;
601 const uint32_t layerStack2 = 456u;
602
603 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700604 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800605
Lloyd Piquec6687342019-03-07 21:34:57 -0800606 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700607 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, false));
608 EXPECT_FALSE(mOutput->belongsInOutput(std::nullopt, true));
Lloyd Piquec6687342019-03-07 21:34:57 -0800609
Lloyd Piqueef36b002019-01-23 17:52:04 -0800610 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700611 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
612 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, true));
613 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
614 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800615
616 // If the output accepts layerStack21 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700617 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Piqueef36b002019-01-23 17:52:04 -0800618
619 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700620 EXPECT_TRUE(mOutput->belongsInOutput(layerStack1, false));
621 EXPECT_FALSE(mOutput->belongsInOutput(layerStack1, true));
622 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, true));
623 EXPECT_FALSE(mOutput->belongsInOutput(layerStack2, false));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800624}
625
Lloyd Piquede196652020-01-22 17:29:58 -0800626TEST_F(OutputTest, belongsInOutputHandlesLayerWithNoCompositionState) {
627 NonInjectedLayer layer;
628 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800629
Lloyd Piquede196652020-01-22 17:29:58 -0800630 // If the layer has no composition state, it does not belong to any output.
631 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
632 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
633}
634
635TEST_F(OutputTest, belongsInOutputFiltersLayersAsExpected) {
636 NonInjectedLayer layer;
637 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
639 const uint32_t layerStack1 = 123u;
640 const uint32_t layerStack2 = 456u;
641
642 // If the output accepts layerStack1 and internal-only layers....
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700643 mOutput->setLayerStackFilter(layerStack1, true);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800644
Lloyd Pique66c20c42019-03-07 21:44:02 -0800645 // A layer with no layerStack does not belong to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800646 layer.layerFEState.layerStackId = std::nullopt;
647 layer.layerFEState.internalOnly = false;
648 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Lloyd Piquede196652020-01-22 17:29:58 -0800650 layer.layerFEState.layerStackId = std::nullopt;
651 layer.layerFEState.internalOnly = true;
652 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800653
654 // Any layer with layerStack1 belongs to it, internal-only or not.
Lloyd Piquede196652020-01-22 17:29:58 -0800655 layer.layerFEState.layerStackId = layerStack1;
656 layer.layerFEState.internalOnly = false;
657 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800658
Lloyd Piquede196652020-01-22 17:29:58 -0800659 layer.layerFEState.layerStackId = layerStack1;
660 layer.layerFEState.internalOnly = true;
661 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800662
Lloyd Piquede196652020-01-22 17:29:58 -0800663 layer.layerFEState.layerStackId = layerStack2;
664 layer.layerFEState.internalOnly = true;
665 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Lloyd Piquede196652020-01-22 17:29:58 -0800667 layer.layerFEState.layerStackId = layerStack2;
668 layer.layerFEState.internalOnly = false;
669 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800670
671 // If the output accepts layerStack1 but not internal-only layers...
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700672 mOutput->setLayerStackFilter(layerStack1, false);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800673
Lloyd Pique66c20c42019-03-07 21:44:02 -0800674 // Only non-internal layers with layerStack1 belong to it.
Lloyd Piquede196652020-01-22 17:29:58 -0800675 layer.layerFEState.layerStackId = layerStack1;
676 layer.layerFEState.internalOnly = false;
677 EXPECT_TRUE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800678
Lloyd Piquede196652020-01-22 17:29:58 -0800679 layer.layerFEState.layerStackId = layerStack1;
680 layer.layerFEState.internalOnly = true;
681 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800682
Lloyd Piquede196652020-01-22 17:29:58 -0800683 layer.layerFEState.layerStackId = layerStack2;
684 layer.layerFEState.internalOnly = true;
685 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800686
Lloyd Piquede196652020-01-22 17:29:58 -0800687 layer.layerFEState.layerStackId = layerStack2;
688 layer.layerFEState.internalOnly = false;
689 EXPECT_FALSE(mOutput->belongsInOutput(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800690}
691
Lloyd Pique66d68602019-02-13 14:23:31 -0800692/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800693 * Output::getOutputLayerForLayer()
694 */
695
696TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800697 InjectedLayer layer1;
698 InjectedLayer layer2;
699 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800700
Lloyd Piquede196652020-01-22 17:29:58 -0800701 injectOutputLayer(layer1);
702 injectNullOutputLayer();
703 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800704
705 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800706 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
707 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800708
709 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800710 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
711 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
712 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800713
714 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800715 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
716 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
717 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800718}
719
Lloyd Pique66d68602019-02-13 14:23:31 -0800720/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800721 * Output::setReleasedLayers()
722 */
723
724using OutputSetReleasedLayersTest = OutputTest;
725
726TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
727 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
728 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
729 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
730
731 Output::ReleasedLayers layers;
732 layers.push_back(layer1FE);
733 layers.push_back(layer2FE);
734 layers.push_back(layer3FE);
735
736 mOutput->setReleasedLayers(std::move(layers));
737
738 const auto& setLayers = mOutput->getReleasedLayersForTest();
739 ASSERT_EQ(3u, setLayers.size());
740 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
741 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
742 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
743}
744
745/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800746 * Output::updateLayerStateFromFE()
747 */
748
Lloyd Piquede196652020-01-22 17:29:58 -0800749using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800750
751TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
752 CompositionRefreshArgs refreshArgs;
753
754 mOutput->updateLayerStateFromFE(refreshArgs);
755}
756
Lloyd Piquede196652020-01-22 17:29:58 -0800757TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
758 InjectedLayer layer1;
759 InjectedLayer layer2;
760 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800761
Lloyd Piquede196652020-01-22 17:29:58 -0800762 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
763 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
764 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
765
766 injectOutputLayer(layer1);
767 injectOutputLayer(layer2);
768 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800769
770 CompositionRefreshArgs refreshArgs;
771 refreshArgs.updatingGeometryThisFrame = false;
772
773 mOutput->updateLayerStateFromFE(refreshArgs);
774}
775
Lloyd Piquede196652020-01-22 17:29:58 -0800776TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
777 InjectedLayer layer1;
778 InjectedLayer layer2;
779 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800780
Lloyd Piquede196652020-01-22 17:29:58 -0800781 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
782 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
783 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
784
785 injectOutputLayer(layer1);
786 injectOutputLayer(layer2);
787 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800788
789 CompositionRefreshArgs refreshArgs;
790 refreshArgs.updatingGeometryThisFrame = true;
791
792 mOutput->updateLayerStateFromFE(refreshArgs);
793}
794
795/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800796 * Output::updateAndWriteCompositionState()
797 */
798
Lloyd Piquede196652020-01-22 17:29:58 -0800799using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800800
801TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
802 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800803
804 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800805 mOutput->updateCompositionState(args);
806 mOutput->planComposition();
807 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800808}
809
Lloyd Piqueef63b612019-11-14 13:19:56 -0800810TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800811 InjectedLayer layer1;
812 InjectedLayer layer2;
813 InjectedLayer layer3;
814
Lloyd Piqueef63b612019-11-14 13:19:56 -0800815 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800816
Lloyd Piquede196652020-01-22 17:29:58 -0800817 injectOutputLayer(layer1);
818 injectOutputLayer(layer2);
819 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800820
821 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800822 mOutput->updateCompositionState(args);
823 mOutput->planComposition();
824 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800825}
826
827TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800828 InjectedLayer layer1;
829 InjectedLayer layer2;
830 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800831
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400832 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200833 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800834 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400835 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
836 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200837 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800838 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400839 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
840 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200841 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800842 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400843 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
844 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800845
846 injectOutputLayer(layer1);
847 injectOutputLayer(layer2);
848 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800849
850 mOutput->editState().isEnabled = true;
851
852 CompositionRefreshArgs args;
853 args.updatingGeometryThisFrame = false;
854 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200855 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800856 mOutput->updateCompositionState(args);
857 mOutput->planComposition();
858 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800859}
860
861TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800862 InjectedLayer layer1;
863 InjectedLayer layer2;
864 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800865
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400866 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200867 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800868 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400869 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
870 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200871 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800872 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400873 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
874 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200875 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800876 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400877 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
878 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800879
880 injectOutputLayer(layer1);
881 injectOutputLayer(layer2);
882 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800883
884 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800885
886 CompositionRefreshArgs args;
887 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800888 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800889 mOutput->updateCompositionState(args);
890 mOutput->planComposition();
891 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800892}
893
894TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800895 InjectedLayer layer1;
896 InjectedLayer layer2;
897 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800898
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400899 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200900 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800901 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400902 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
903 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200904 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800905 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400906 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
907 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200908 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800909 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400910 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
911 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800912
913 injectOutputLayer(layer1);
914 injectOutputLayer(layer2);
915 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800916
917 mOutput->editState().isEnabled = true;
918
919 CompositionRefreshArgs args;
920 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800921 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800922 mOutput->updateCompositionState(args);
923 mOutput->planComposition();
924 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800925}
926
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400927TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
928 renderengine::mock::RenderEngine renderEngine;
929 InjectedLayer layer0;
930 InjectedLayer layer1;
931 InjectedLayer layer2;
932 InjectedLayer layer3;
933
934 InSequence seq;
935 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
936 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
937 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
938 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
939
940 uint32_t z = 0;
941 EXPECT_CALL(*layer0.outputLayer,
942 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
943 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
944
945 // After calling planComposition (which clears overrideInfo), this test sets
946 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
947 // comes first, setting isPeekingThrough to true and zIsOverridden to true
948 // for it and the following layers.
949 EXPECT_CALL(*layer3.outputLayer,
950 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
951 /*zIsOverridden*/ true, /*isPeekingThrough*/
952 true));
953 EXPECT_CALL(*layer1.outputLayer,
954 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
955 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
956 EXPECT_CALL(*layer2.outputLayer,
957 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
958 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
959
960 injectOutputLayer(layer0);
961 injectOutputLayer(layer1);
962 injectOutputLayer(layer2);
963 injectOutputLayer(layer3);
964
965 mOutput->editState().isEnabled = true;
966
967 CompositionRefreshArgs args;
968 args.updatingGeometryThisFrame = true;
969 args.devOptForceClientComposition = false;
970 mOutput->updateCompositionState(args);
971 mOutput->planComposition();
972
973 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
974 renderengine::ExternalTexture>(new GraphicBuffer(), renderEngine,
975 renderengine::ExternalTexture::Usage::READABLE |
976 renderengine::ExternalTexture::Usage::WRITEABLE);
977 layer1.outputLayerState.overrideInfo.buffer = buffer;
978 layer2.outputLayerState.overrideInfo.buffer = buffer;
979 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
980 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
981
982 mOutput->writeCompositionState(args);
983}
984
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800985/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800986 * Output::prepareFrame()
987 */
988
989struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800990 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800991 // Sets up the helper functions called by the function under test to use
992 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800993 MOCK_METHOD0(chooseCompositionStrategy, void());
994 };
995
996 OutputPrepareFrameTest() {
997 mOutput.setDisplayColorProfileForTest(
998 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
999 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1000 }
1001
1002 StrictMock<mock::CompositionEngine> mCompositionEngine;
1003 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1004 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001005 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001006};
1007
1008TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1009 mOutput.editState().isEnabled = false;
1010
1011 mOutput.prepareFrame();
1012}
1013
1014TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1015 mOutput.editState().isEnabled = true;
1016 mOutput.editState().usesClientComposition = false;
1017 mOutput.editState().usesDeviceComposition = true;
1018
1019 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001020 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001021 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1022
1023 mOutput.prepareFrame();
1024}
1025
1026// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1027// base chooseCompositionStrategy() is invoked.
1028TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001029 mOutput->editState().isEnabled = true;
1030 mOutput->editState().usesClientComposition = false;
1031 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001032
1033 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1034
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001035 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001036
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001037 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1038 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001039}
1040
Lloyd Pique56eba802019-08-28 15:45:25 -07001041/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001042 * Output::prepare()
1043 */
1044
1045struct OutputPrepareTest : public testing::Test {
1046 struct OutputPartialMock : public OutputPartialMockBase {
1047 // Sets up the helper functions called by the function under test to use
1048 // mock implementations.
1049 MOCK_METHOD2(rebuildLayerStacks,
1050 void(const compositionengine::CompositionRefreshArgs&,
1051 compositionengine::LayerFESet&));
1052 };
1053
1054 StrictMock<OutputPartialMock> mOutput;
1055 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001056 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001057};
1058
1059TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1060 InSequence seq;
1061 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1062
1063 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1064}
1065
1066/*
1067 * Output::rebuildLayerStacks()
1068 */
1069
1070struct OutputRebuildLayerStacksTest : public testing::Test {
1071 struct OutputPartialMock : public OutputPartialMockBase {
1072 // Sets up the helper functions called by the function under test to use
1073 // mock implementations.
1074 MOCK_METHOD2(collectVisibleLayers,
1075 void(const compositionengine::CompositionRefreshArgs&,
1076 compositionengine::Output::CoverageState&));
1077 };
1078
1079 OutputRebuildLayerStacksTest() {
1080 mOutput.mState.isEnabled = true;
1081 mOutput.mState.transform = kIdentityTransform;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001082 mOutput.mState.displaySpace.bounds = kOutputBounds;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001083
1084 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1085
1086 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1087
1088 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1089 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1090 }
1091
1092 void setTestCoverageValues(const CompositionRefreshArgs&,
1093 compositionengine::Output::CoverageState& state) {
1094 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1095 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1096 state.dirtyRegion = mCoverageDirtyRegionToSet;
1097 }
1098
1099 static const ui::Transform kIdentityTransform;
1100 static const ui::Transform kRotate90Transform;
1101 static const Rect kOutputBounds;
1102
1103 StrictMock<OutputPartialMock> mOutput;
1104 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001105 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001106 Region mCoverageAboveCoveredLayersToSet;
1107 Region mCoverageAboveOpaqueLayersToSet;
1108 Region mCoverageDirtyRegionToSet;
1109};
1110
1111const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1112const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1113const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1114
1115TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1116 mOutput.mState.isEnabled = false;
1117
1118 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1119}
1120
1121TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1122 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1123
1124 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1125}
1126
1127TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1128 mOutput.mState.transform = kIdentityTransform;
1129
1130 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1131
1132 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1133
1134 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1135}
1136
1137TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1138 mOutput.mState.transform = kIdentityTransform;
1139
1140 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1141
1142 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1143
1144 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1145}
1146
1147TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1148 mOutput.mState.transform = kRotate90Transform;
1149
1150 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1151
1152 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1153
1154 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1155}
1156
1157TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1158 mOutput.mState.transform = kRotate90Transform;
1159
1160 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1161
1162 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1163
1164 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1165}
1166
1167TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1168 mOutput.mState.transform = kIdentityTransform;
1169 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1170
1171 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1172
1173 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1174
1175 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1176}
1177
1178TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1179 mOutput.mState.transform = kRotate90Transform;
1180 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1181
1182 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1183
1184 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1185
1186 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1187}
1188
1189/*
1190 * Output::collectVisibleLayers()
1191 */
1192
Lloyd Pique1ef93222019-11-21 16:41:53 -08001193struct OutputCollectVisibleLayersTest : public testing::Test {
1194 struct OutputPartialMock : public OutputPartialMockBase {
1195 // Sets up the helper functions called by the function under test to use
1196 // mock implementations.
1197 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001198 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001199 compositionengine::Output::CoverageState&));
1200 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1201 MOCK_METHOD0(finalizePendingOutputLayers, void());
1202 };
1203
1204 struct Layer {
1205 Layer() {
1206 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1207 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1208 }
1209
1210 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001211 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001212 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001213 };
1214
1215 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001216 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001217 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1218 .WillRepeatedly(Return(&mLayer1.outputLayer));
1219 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1220 .WillRepeatedly(Return(&mLayer2.outputLayer));
1221 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1222 .WillRepeatedly(Return(&mLayer3.outputLayer));
1223
Lloyd Piquede196652020-01-22 17:29:58 -08001224 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1225 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1226 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001227 }
1228
1229 StrictMock<OutputPartialMock> mOutput;
1230 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001231 LayerFESet mGeomSnapshots;
1232 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001233 Layer mLayer1;
1234 Layer mLayer2;
1235 Layer mLayer3;
1236};
1237
1238TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1239 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001240 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001241
1242 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1243 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1244
1245 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1246}
1247
1248TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1249 // Enforce a call order sequence for this test.
1250 InSequence seq;
1251
1252 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001253 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1254 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1255 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001256
1257 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1258 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1259
1260 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001261}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001262
1263/*
1264 * Output::ensureOutputLayerIfVisible()
1265 */
1266
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1268 struct OutputPartialMock : public OutputPartialMockBase {
1269 // Sets up the helper functions called by the function under test to use
1270 // mock implementations.
Lloyd Piquede196652020-01-22 17:29:58 -08001271 MOCK_CONST_METHOD1(belongsInOutput, bool(const sp<compositionengine::LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001272 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001273 MOCK_METHOD2(ensureOutputLayer,
1274 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001275 };
1276
1277 OutputEnsureOutputLayerIfVisibleTest() {
Lloyd Piquede196652020-01-22 17:29:58 -08001278 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE)))
1279 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001280 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001281 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001282 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001283
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001284 mOutput.mState.displaySpace.bounds = Rect(0, 0, 200, 300);
1285 mOutput.mState.layerStackSpace.content = Rect(0, 0, 200, 300);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001286 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1287
Lloyd Piquede196652020-01-22 17:29:58 -08001288 mLayer.layerFEState.isVisible = true;
1289 mLayer.layerFEState.isOpaque = true;
1290 mLayer.layerFEState.contentDirty = true;
1291 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1292 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1293 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294
Lloyd Piquede196652020-01-22 17:29:58 -08001295 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1296 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001297
Lloyd Piquede196652020-01-22 17:29:58 -08001298 mGeomSnapshots.insert(mLayer.layerFE);
1299 }
1300
1301 void ensureOutputLayerIfVisible() {
1302 sp<LayerFE> layerFE(mLayer.layerFE);
1303 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001304 }
1305
1306 static const Region kEmptyRegion;
1307 static const Region kFullBoundsNoRotation;
1308 static const Region kRightHalfBoundsNoRotation;
1309 static const Region kLowerHalfBoundsNoRotation;
1310 static const Region kFullBounds90Rotation;
1311
1312 StrictMock<OutputPartialMock> mOutput;
1313 LayerFESet mGeomSnapshots;
1314 Output::CoverageState mCoverageState{mGeomSnapshots};
1315
Lloyd Piquede196652020-01-22 17:29:58 -08001316 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001317};
1318
1319const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1320const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1321 Region(Rect(0, 0, 100, 200));
1322const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1323 Region(Rect(0, 100, 100, 200));
1324const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1325 Region(Rect(50, 0, 100, 200));
1326const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1327 Region(Rect(0, 0, 200, 100));
1328
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001329TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001330 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
1331 EXPECT_CALL(*mLayer.layerFE,
1332 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001333
1334 mGeomSnapshots.clear();
1335
Lloyd Piquede196652020-01-22 17:29:58 -08001336 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001337}
1338
1339TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1340 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerBelongs) {
Lloyd Piquede196652020-01-22 17:29:58 -08001341 EXPECT_CALL(mOutput, belongsInOutput(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 ensureOutputLayerIfVisible();
1344}
1345
1346TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1347 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1348
1349 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001350}
1351
1352TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001353 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354
Lloyd Piquede196652020-01-22 17:29:58 -08001355 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356}
1357
1358TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001359 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360
Lloyd Piquede196652020-01-22 17:29:58 -08001361 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001362}
1363
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001364TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001365 mOutput.mState.displaySpace.bounds = Rect(0, 0, 0, 0);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366
Lloyd Piquede196652020-01-22 17:29:58 -08001367 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001368}
1369
1370TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1371 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001372 mLayer.layerFEState.isOpaque = true;
1373 mLayer.layerFEState.contentDirty = true;
1374 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001375
1376 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001377 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1378 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
Lloyd Piquede196652020-01-22 17:29:58 -08001380 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381
1382 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1383 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1384 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1385
Lloyd Piquede196652020-01-22 17:29:58 -08001386 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1388 RegionEq(kFullBoundsNoRotation));
1389 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1390 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001391}
1392
1393TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1394 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001395 mLayer.layerFEState.isOpaque = true;
1396 mLayer.layerFEState.contentDirty = true;
1397 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001398
Lloyd Piquede196652020-01-22 17:29:58 -08001399 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1400 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001401
Lloyd Piquede196652020-01-22 17:29:58 -08001402 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403
1404 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1405 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1406 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1407
Lloyd Piquede196652020-01-22 17:29:58 -08001408 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1409 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1410 RegionEq(kFullBoundsNoRotation));
1411 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1412 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001413}
1414
1415TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1416 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001417 mLayer.layerFEState.isOpaque = false;
1418 mLayer.layerFEState.contentDirty = true;
1419 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420
1421 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001422 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1423 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424
Lloyd Piquede196652020-01-22 17:29:58 -08001425 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426
1427 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1428 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1429 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1430
Lloyd Piquede196652020-01-22 17:29:58 -08001431 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1432 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001434 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1435 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001436}
1437
1438TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1439 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001440 mLayer.layerFEState.isOpaque = false;
1441 mLayer.layerFEState.contentDirty = true;
1442 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443
Lloyd Piquede196652020-01-22 17:29:58 -08001444 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1445 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001446
Lloyd Piquede196652020-01-22 17:29:58 -08001447 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448
1449 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1450 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1451 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1452
Lloyd Piquede196652020-01-22 17:29:58 -08001453 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1454 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001455 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001456 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1457 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001458}
1459
1460TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1461 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001462 mLayer.layerFEState.isOpaque = true;
1463 mLayer.layerFEState.contentDirty = false;
1464 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465
1466 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001467 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1468 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
Lloyd Piquede196652020-01-22 17:29:58 -08001470 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471
1472 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1473 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1474 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1475
Lloyd Piquede196652020-01-22 17:29:58 -08001476 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1477 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1478 RegionEq(kFullBoundsNoRotation));
1479 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1480 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001481}
1482
1483TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1484 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001485 mLayer.layerFEState.isOpaque = true;
1486 mLayer.layerFEState.contentDirty = false;
1487 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488
Lloyd Piquede196652020-01-22 17:29:58 -08001489 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1490 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001491
Lloyd Piquede196652020-01-22 17:29:58 -08001492 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001493
1494 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1495 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1496 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1497
Lloyd Piquede196652020-01-22 17:29:58 -08001498 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1499 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1500 RegionEq(kFullBoundsNoRotation));
1501 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1502 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503}
1504
1505TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1506 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001507 mLayer.layerFEState.isOpaque = true;
1508 mLayer.layerFEState.contentDirty = true;
1509 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1510 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1511 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1512 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001513
1514 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001515 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1516 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517
Lloyd Piquede196652020-01-22 17:29:58 -08001518 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519
1520 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1521 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1522 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1523
Lloyd Piquede196652020-01-22 17:29:58 -08001524 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1525 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1526 RegionEq(kFullBoundsNoRotation));
1527 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1528 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529}
1530
1531TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1532 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001533 mLayer.layerFEState.isOpaque = true;
1534 mLayer.layerFEState.contentDirty = true;
1535 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1536 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1537 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1538 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001539
Lloyd Piquede196652020-01-22 17:29:58 -08001540 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1541 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001542
Lloyd Piquede196652020-01-22 17:29:58 -08001543 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544
1545 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1546 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1547 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1548
Lloyd Piquede196652020-01-22 17:29:58 -08001549 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1551 RegionEq(kFullBoundsNoRotation));
1552 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1553 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001554}
1555
1556TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1557 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001558 mLayer.layerFEState.isOpaque = true;
1559 mLayer.layerFEState.contentDirty = true;
1560 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001561
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001562 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001563 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1564
1565 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001566 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1567 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568
Lloyd Piquede196652020-01-22 17:29:58 -08001569 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570
1571 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1572 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1573 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1574
Lloyd Piquede196652020-01-22 17:29:58 -08001575 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1576 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1577 RegionEq(kFullBoundsNoRotation));
1578 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1579 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001580}
1581
1582TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1583 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001584 mLayer.layerFEState.isOpaque = true;
1585 mLayer.layerFEState.contentDirty = true;
1586 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02001588 mOutput.mState.layerStackSpace.content = Rect(0, 0, 300, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001589 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1590
Lloyd Piquede196652020-01-22 17:29:58 -08001591 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1592 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593
Lloyd Piquede196652020-01-22 17:29:58 -08001594 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595
1596 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1597 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1598 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1599
Lloyd Piquede196652020-01-22 17:29:58 -08001600 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1602 RegionEq(kFullBoundsNoRotation));
1603 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1604 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001605}
1606
1607TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1608 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1609 ui::Transform arbitraryTransform;
1610 arbitraryTransform.set(1, 1, -1, 1);
1611 arbitraryTransform.set(0, 100);
1612
Lloyd Piquede196652020-01-22 17:29:58 -08001613 mLayer.layerFEState.isOpaque = true;
1614 mLayer.layerFEState.contentDirty = true;
1615 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1616 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001617
1618 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001619 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1620 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621
Lloyd Piquede196652020-01-22 17:29:58 -08001622 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001623
1624 const Region kRegion = Region(Rect(0, 0, 300, 300));
1625 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1626
1627 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1628 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1629 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1630
Lloyd Piquede196652020-01-22 17:29:58 -08001631 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1632 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1633 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1634 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001635}
1636
1637TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001638 mLayer.layerFEState.isOpaque = false;
1639 mLayer.layerFEState.contentDirty = true;
1640 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001641
1642 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1643 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1644 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1645
Lloyd Piquede196652020-01-22 17:29:58 -08001646 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1647 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648
Lloyd Piquede196652020-01-22 17:29:58 -08001649 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001650
1651 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1652 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1653 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1654 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1655 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1656 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1657
1658 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1659 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1660 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1661
Lloyd Piquede196652020-01-22 17:29:58 -08001662 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1663 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001664 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001665 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1666 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1667 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001669
Vishnu Naira483b4a2019-12-12 15:07:52 -08001670TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1671 ui::Transform translate;
1672 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001673 mLayer.layerFEState.geomLayerTransform = translate;
1674 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001675
1676 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1677 // half of the layer including the casting shadow is covered and opaque
1678 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1679 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1680
Lloyd Piquede196652020-01-22 17:29:58 -08001681 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1682 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001683
Lloyd Piquede196652020-01-22 17:29:58 -08001684 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001685
1686 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1687 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1688 // add starting opaque region to the opaque half of the casting layer bounds
1689 const Region kExpectedAboveOpaqueRegion =
1690 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1691 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1692 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1693 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1694 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1695 const Region kExpectedLayerShadowRegion =
1696 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1697
1698 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1699 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1700 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1701
Lloyd Piquede196652020-01-22 17:29:58 -08001702 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1703 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001704 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001705 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1706 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001707 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001708 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001709 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1710}
1711
1712TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1713 ui::Transform translate;
1714 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001715 mLayer.layerFEState.geomLayerTransform = translate;
1716 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001717
1718 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1719 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1720 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1721 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1722
Lloyd Piquede196652020-01-22 17:29:58 -08001723 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1724 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001725
Lloyd Piquede196652020-01-22 17:29:58 -08001726 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001727
1728 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1729 const Region kExpectedLayerShadowRegion =
1730 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1731
Lloyd Piquede196652020-01-22 17:29:58 -08001732 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1733 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001734 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1735}
1736
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001737TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001738 ui::Transform translate;
1739 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001740 mLayer.layerFEState.geomLayerTransform = translate;
1741 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001742
1743 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1744 // Casting layer and its shadows are covered by an opaque region
1745 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1746 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1747
Lloyd Piquede196652020-01-22 17:29:58 -08001748 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001749}
1750
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001751/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001752 * Output::present()
1753 */
1754
1755struct OutputPresentTest : public testing::Test {
1756 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001757 // Sets up the helper functions called by the function under test to use
1758 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001759 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001760 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001761 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001762 MOCK_METHOD0(planComposition, void());
1763 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001764 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1765 MOCK_METHOD0(beginFrame, void());
1766 MOCK_METHOD0(prepareFrame, void());
1767 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1768 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1769 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001770 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001771 };
1772
1773 StrictMock<OutputPartialMock> mOutput;
1774};
1775
1776TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1777 CompositionRefreshArgs args;
1778
1779 InSequence seq;
1780 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001781 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1782 EXPECT_CALL(mOutput, planComposition());
1783 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001784 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1785 EXPECT_CALL(mOutput, beginFrame());
1786 EXPECT_CALL(mOutput, prepareFrame());
1787 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1788 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1789 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001790 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001791
1792 mOutput.present(args);
1793}
1794
1795/*
1796 * Output::updateColorProfile()
1797 */
1798
Lloyd Pique17ca7422019-11-14 14:24:10 -08001799struct OutputUpdateColorProfileTest : public testing::Test {
1800 using TestType = OutputUpdateColorProfileTest;
1801
1802 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001803 // Sets up the helper functions called by the function under test to use
1804 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001805 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1806 };
1807
1808 struct Layer {
1809 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001810 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1811 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001812 }
1813
1814 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001815 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001816 LayerFECompositionState mLayerFEState;
1817 };
1818
1819 OutputUpdateColorProfileTest() {
1820 mOutput.setDisplayColorProfileForTest(
1821 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1822 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1823
1824 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1825 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1826 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1827 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1828 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1829 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1830 }
1831
1832 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1833 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1834 };
1835
1836 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1837 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1838 StrictMock<OutputPartialMock> mOutput;
1839
1840 Layer mLayer1;
1841 Layer mLayer2;
1842 Layer mLayer3;
1843
1844 CompositionRefreshArgs mRefreshArgs;
1845};
1846
1847// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1848// to make it easier to write unit tests.
1849
1850TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1851 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1852 // a simple default color profile without looking at anything else.
1853
Lloyd Pique0a456232020-01-16 17:51:13 -08001854 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001855 EXPECT_CALL(mOutput,
1856 setColorProfile(ColorProfileEq(
1857 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1858 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1859
1860 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1861 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1862
1863 mOutput.updateColorProfile(mRefreshArgs);
1864}
1865
1866struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1867 : public OutputUpdateColorProfileTest {
1868 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001869 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001870 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1871 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1872 }
1873
1874 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1875 : public CallOrderStateMachineHelper<
1876 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1877 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1878 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1879 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1880 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1881 _))
1882 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1883 SetArgPointee<4>(renderIntent)));
1884 EXPECT_CALL(getInstance()->mOutput,
1885 setColorProfile(
1886 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1887 ui::Dataspace::UNKNOWN})));
1888 return nextState<ExecuteState>();
1889 }
1890 };
1891
1892 // Call this member function to start using the mini-DSL defined above.
1893 [[nodiscard]] auto verify() {
1894 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1895 }
1896};
1897
1898TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1899 Native_Unknown_Colorimetric_Set) {
1900 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1901 ui::Dataspace::UNKNOWN,
1902 ui::RenderIntent::COLORIMETRIC)
1903 .execute();
1904}
1905
1906TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1907 DisplayP3_DisplayP3_Enhance_Set) {
1908 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1909 ui::Dataspace::DISPLAY_P3,
1910 ui::RenderIntent::ENHANCE)
1911 .execute();
1912}
1913
1914struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1915 : public OutputUpdateColorProfileTest {
1916 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001917 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001918 EXPECT_CALL(*mDisplayColorProfile,
1919 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1920 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1921 SetArgPointee<3>(ui::ColorMode::NATIVE),
1922 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1923 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1924 }
1925
1926 struct IfColorSpaceAgnosticDataspaceSetToState
1927 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1928 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1929 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1930 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1931 }
1932 };
1933
1934 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1935 : public CallOrderStateMachineHelper<
1936 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1937 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1938 ui::Dataspace dataspace) {
1939 EXPECT_CALL(getInstance()->mOutput,
1940 setColorProfile(ColorProfileEq(
1941 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1942 ui::RenderIntent::COLORIMETRIC, dataspace})));
1943 return nextState<ExecuteState>();
1944 }
1945 };
1946
1947 // Call this member function to start using the mini-DSL defined above.
1948 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1949};
1950
1951TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1952 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1953 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1954 .execute();
1955}
1956
1957TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1958 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1959 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1960 .execute();
1961}
1962
1963struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1964 : public OutputUpdateColorProfileTest {
1965 // Internally the implementation looks through the dataspaces of all the
1966 // visible layers. The topmost one that also has an actual dataspace
1967 // preference set is used to drive subsequent choices.
1968
1969 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1970 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1971 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1972
Lloyd Pique0a456232020-01-16 17:51:13 -08001973 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001974 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1975 }
1976
1977 struct IfTopLayerDataspaceState
1978 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1979 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1980 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1981 return nextState<AndIfMiddleLayerDataspaceState>();
1982 }
1983 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1984 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1985 }
1986 };
1987
1988 struct AndIfMiddleLayerDataspaceState
1989 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1990 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1991 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1992 return nextState<AndIfBottomLayerDataspaceState>();
1993 }
1994 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1995 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1996 }
1997 };
1998
1999 struct AndIfBottomLayerDataspaceState
2000 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2001 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2002 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2003 return nextState<ThenExpectBestColorModeCallUsesState>();
2004 }
2005 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2006 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2007 }
2008 };
2009
2010 struct ThenExpectBestColorModeCallUsesState
2011 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2012 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2013 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2014 getBestColorMode(dataspace, _, _, _, _));
2015 return nextState<ExecuteState>();
2016 }
2017 };
2018
2019 // Call this member function to start using the mini-DSL defined above.
2020 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2021};
2022
2023TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2024 noStrongLayerPrefenceUses_V0_SRGB) {
2025 // If none of the layers indicate a preference, then V0_SRGB is the
2026 // preferred choice (subject to additional checks).
2027 verify().ifTopLayerHasNoPreference()
2028 .andIfMiddleLayerHasNoPreference()
2029 .andIfBottomLayerHasNoPreference()
2030 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2031 .execute();
2032}
2033
2034TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2035 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2036 // If only the topmost layer has a preference, then that is what is chosen.
2037 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2038 .andIfMiddleLayerHasNoPreference()
2039 .andIfBottomLayerHasNoPreference()
2040 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2041 .execute();
2042}
2043
2044TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2045 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2046 // If only the middle layer has a preference, that that is what is chosen.
2047 verify().ifTopLayerHasNoPreference()
2048 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2049 .andIfBottomLayerHasNoPreference()
2050 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2051 .execute();
2052}
2053
2054TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2055 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2056 // If only the middle layer has a preference, that that is what is chosen.
2057 verify().ifTopLayerHasNoPreference()
2058 .andIfMiddleLayerHasNoPreference()
2059 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2060 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2061 .execute();
2062}
2063
2064TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2065 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2066 // If multiple layers have a preference, the topmost value is what is used.
2067 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2068 .andIfMiddleLayerHasNoPreference()
2069 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2070 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2071 .execute();
2072}
2073
2074TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2075 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2076 // If multiple layers have a preference, the topmost value is what is used.
2077 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2078 .andIfMiddleLayerHasNoPreference()
2079 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2080 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2081 .execute();
2082}
2083
2084struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2085 : public OutputUpdateColorProfileTest {
2086 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2087 // values, it overrides the layer dataspace choice.
2088
2089 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2090 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2091 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2092
2093 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2094
Lloyd Pique0a456232020-01-16 17:51:13 -08002095 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002096 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2097 }
2098
2099 struct IfForceOutputColorModeState
2100 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2101 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2102 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2103 return nextState<ThenExpectBestColorModeCallUsesState>();
2104 }
2105 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2106 };
2107
2108 struct ThenExpectBestColorModeCallUsesState
2109 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2110 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2111 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2112 getBestColorMode(dataspace, _, _, _, _));
2113 return nextState<ExecuteState>();
2114 }
2115 };
2116
2117 // Call this member function to start using the mini-DSL defined above.
2118 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2119};
2120
2121TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2122 // By default the layer state is used to set the preferred dataspace
2123 verify().ifNoOverride()
2124 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2125 .execute();
2126}
2127
2128TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2129 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2130 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2131 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2132 .execute();
2133}
2134
2135TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2136 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2137 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2138 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2139 .execute();
2140}
2141
2142// HDR output requires all layers to be compatible with the chosen HDR
2143// dataspace, along with there being proper support.
2144struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2145 OutputUpdateColorProfileTest_Hdr() {
2146 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2147 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002148 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002149 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2150 }
2151
2152 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2153 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2154 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2155 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2156
2157 struct IfTopLayerDataspaceState
2158 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2159 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2160 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2161 return nextState<AndTopLayerCompositionTypeState>();
2162 }
2163 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2164 };
2165
2166 struct AndTopLayerCompositionTypeState
2167 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2168 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2169 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2170 return nextState<AndIfBottomLayerDataspaceState>();
2171 }
2172 };
2173
2174 struct AndIfBottomLayerDataspaceState
2175 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2176 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2177 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2178 return nextState<AndBottomLayerCompositionTypeState>();
2179 }
2180 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2181 return andIfBottomLayerIs(kNonHdrDataspace);
2182 }
2183 };
2184
2185 struct AndBottomLayerCompositionTypeState
2186 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2187 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2188 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2189 return nextState<AndIfHasLegacySupportState>();
2190 }
2191 };
2192
2193 struct AndIfHasLegacySupportState
2194 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2195 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2196 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2197 .WillOnce(Return(legacySupport));
2198 return nextState<ThenExpectBestColorModeCallUsesState>();
2199 }
2200 };
2201
2202 struct ThenExpectBestColorModeCallUsesState
2203 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2204 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2205 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2206 getBestColorMode(dataspace, _, _, _, _));
2207 return nextState<ExecuteState>();
2208 }
2209 };
2210
2211 // Call this member function to start using the mini-DSL defined above.
2212 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2213};
2214
2215TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2216 // If all layers use BT2020_PQ, and there are no other special conditions,
2217 // BT2020_PQ is used.
2218 verify().ifTopLayerIs(BT2020_PQ)
2219 .andTopLayerIsREComposed(false)
2220 .andIfBottomLayerIs(BT2020_PQ)
2221 .andBottomLayerIsREComposed(false)
2222 .andIfLegacySupportFor(BT2020_PQ, false)
2223 .thenExpectBestColorModeCallUses(BT2020_PQ)
2224 .execute();
2225}
2226
2227TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2228 // BT2020_PQ is not used if there is only legacy support for it.
2229 verify().ifTopLayerIs(BT2020_PQ)
2230 .andTopLayerIsREComposed(false)
2231 .andIfBottomLayerIs(BT2020_PQ)
2232 .andBottomLayerIsREComposed(false)
2233 .andIfLegacySupportFor(BT2020_PQ, true)
2234 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2235 .execute();
2236}
2237
2238TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2239 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2240 verify().ifTopLayerIs(BT2020_PQ)
2241 .andTopLayerIsREComposed(false)
2242 .andIfBottomLayerIs(BT2020_PQ)
2243 .andBottomLayerIsREComposed(true)
2244 .andIfLegacySupportFor(BT2020_PQ, false)
2245 .thenExpectBestColorModeCallUses(BT2020_PQ)
2246 .execute();
2247}
2248
2249TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2250 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2251 verify().ifTopLayerIs(BT2020_PQ)
2252 .andTopLayerIsREComposed(true)
2253 .andIfBottomLayerIs(BT2020_PQ)
2254 .andBottomLayerIsREComposed(false)
2255 .andIfLegacySupportFor(BT2020_PQ, false)
2256 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2257 .execute();
2258}
2259
2260TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2261 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2262 // are no other special conditions.
2263 verify().ifTopLayerIs(BT2020_PQ)
2264 .andTopLayerIsREComposed(false)
2265 .andIfBottomLayerIs(BT2020_HLG)
2266 .andBottomLayerIsREComposed(false)
2267 .andIfLegacySupportFor(BT2020_PQ, false)
2268 .thenExpectBestColorModeCallUses(BT2020_PQ)
2269 .execute();
2270}
2271
2272TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2273 // BT2020_PQ is not used if there is only legacy support for it.
2274 verify().ifTopLayerIs(BT2020_PQ)
2275 .andTopLayerIsREComposed(false)
2276 .andIfBottomLayerIs(BT2020_HLG)
2277 .andBottomLayerIsREComposed(false)
2278 .andIfLegacySupportFor(BT2020_PQ, true)
2279 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2280 .execute();
2281}
2282
2283TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2284 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2285 verify().ifTopLayerIs(BT2020_PQ)
2286 .andTopLayerIsREComposed(false)
2287 .andIfBottomLayerIs(BT2020_HLG)
2288 .andBottomLayerIsREComposed(true)
2289 .andIfLegacySupportFor(BT2020_PQ, false)
2290 .thenExpectBestColorModeCallUses(BT2020_PQ)
2291 .execute();
2292}
2293
2294TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2295 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2296 verify().ifTopLayerIs(BT2020_PQ)
2297 .andTopLayerIsREComposed(true)
2298 .andIfBottomLayerIs(BT2020_HLG)
2299 .andBottomLayerIsREComposed(false)
2300 .andIfLegacySupportFor(BT2020_PQ, false)
2301 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2302 .execute();
2303}
2304
2305TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2306 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2307 // used if there are no other special conditions.
2308 verify().ifTopLayerIs(BT2020_HLG)
2309 .andTopLayerIsREComposed(false)
2310 .andIfBottomLayerIs(BT2020_PQ)
2311 .andBottomLayerIsREComposed(false)
2312 .andIfLegacySupportFor(BT2020_PQ, false)
2313 .thenExpectBestColorModeCallUses(BT2020_PQ)
2314 .execute();
2315}
2316
2317TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2318 // BT2020_PQ is not used if there is only legacy support for it.
2319 verify().ifTopLayerIs(BT2020_HLG)
2320 .andTopLayerIsREComposed(false)
2321 .andIfBottomLayerIs(BT2020_PQ)
2322 .andBottomLayerIsREComposed(false)
2323 .andIfLegacySupportFor(BT2020_PQ, true)
2324 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2325 .execute();
2326}
2327
2328TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2329 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2330 verify().ifTopLayerIs(BT2020_HLG)
2331 .andTopLayerIsREComposed(false)
2332 .andIfBottomLayerIs(BT2020_PQ)
2333 .andBottomLayerIsREComposed(true)
2334 .andIfLegacySupportFor(BT2020_PQ, false)
2335 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2336 .execute();
2337}
2338
2339TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2340 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2341 verify().ifTopLayerIs(BT2020_HLG)
2342 .andTopLayerIsREComposed(true)
2343 .andIfBottomLayerIs(BT2020_PQ)
2344 .andBottomLayerIsREComposed(false)
2345 .andIfLegacySupportFor(BT2020_PQ, false)
2346 .thenExpectBestColorModeCallUses(BT2020_PQ)
2347 .execute();
2348}
2349
2350TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2351 // If all layers use HLG then HLG is used if there are no other special
2352 // conditions.
2353 verify().ifTopLayerIs(BT2020_HLG)
2354 .andTopLayerIsREComposed(false)
2355 .andIfBottomLayerIs(BT2020_HLG)
2356 .andBottomLayerIsREComposed(false)
2357 .andIfLegacySupportFor(BT2020_HLG, false)
2358 .thenExpectBestColorModeCallUses(BT2020_HLG)
2359 .execute();
2360}
2361
2362TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2363 // BT2020_HLG is not used if there is legacy support for it.
2364 verify().ifTopLayerIs(BT2020_HLG)
2365 .andTopLayerIsREComposed(false)
2366 .andIfBottomLayerIs(BT2020_HLG)
2367 .andBottomLayerIsREComposed(false)
2368 .andIfLegacySupportFor(BT2020_HLG, true)
2369 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2370 .execute();
2371}
2372
2373TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2374 // BT2020_HLG is used even if the bottom layer is client composed.
2375 verify().ifTopLayerIs(BT2020_HLG)
2376 .andTopLayerIsREComposed(false)
2377 .andIfBottomLayerIs(BT2020_HLG)
2378 .andBottomLayerIsREComposed(true)
2379 .andIfLegacySupportFor(BT2020_HLG, false)
2380 .thenExpectBestColorModeCallUses(BT2020_HLG)
2381 .execute();
2382}
2383
2384TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2385 // BT2020_HLG is used even if the top layer is client composed.
2386 verify().ifTopLayerIs(BT2020_HLG)
2387 .andTopLayerIsREComposed(true)
2388 .andIfBottomLayerIs(BT2020_HLG)
2389 .andBottomLayerIsREComposed(false)
2390 .andIfLegacySupportFor(BT2020_HLG, false)
2391 .thenExpectBestColorModeCallUses(BT2020_HLG)
2392 .execute();
2393}
2394
2395TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2396 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2397 verify().ifTopLayerIs(BT2020_PQ)
2398 .andTopLayerIsREComposed(false)
2399 .andIfBottomLayerIsNotHdr()
2400 .andBottomLayerIsREComposed(false)
2401 .andIfLegacySupportFor(BT2020_PQ, false)
2402 .thenExpectBestColorModeCallUses(BT2020_PQ)
2403 .execute();
2404}
2405
2406TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2407 // If all layers use HLG then HLG is used if there are no other special
2408 // conditions.
2409 verify().ifTopLayerIs(BT2020_HLG)
2410 .andTopLayerIsREComposed(false)
2411 .andIfBottomLayerIsNotHdr()
2412 .andBottomLayerIsREComposed(true)
2413 .andIfLegacySupportFor(BT2020_HLG, false)
2414 .thenExpectBestColorModeCallUses(BT2020_HLG)
2415 .execute();
2416}
2417
2418struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2419 : public OutputUpdateColorProfileTest {
2420 // The various values for CompositionRefreshArgs::outputColorSetting affect
2421 // the chosen renderIntent, along with whether the preferred dataspace is an
2422 // HDR dataspace or not.
2423
2424 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2425 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2426 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2427 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002428 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002429 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2430 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2431 .WillRepeatedly(Return(false));
2432 }
2433
2434 // The tests here involve enough state and GMock setup that using a mini-DSL
2435 // makes the tests much more readable, and allows the test to focus more on
2436 // the intent than on some of the details.
2437
2438 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2439 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2440
2441 struct IfDataspaceChosenState
2442 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2443 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2444 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2445 return nextState<AndOutputColorSettingState>();
2446 }
2447 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2448 return ifDataspaceChosenIs(kNonHdrDataspace);
2449 }
2450 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2451 };
2452
2453 struct AndOutputColorSettingState
2454 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2455 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2456 getInstance()->mRefreshArgs.outputColorSetting = setting;
2457 return nextState<ThenExpectBestColorModeCallUsesState>();
2458 }
2459 };
2460
2461 struct ThenExpectBestColorModeCallUsesState
2462 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2463 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2464 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2465 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2466 _, _));
2467 return nextState<ExecuteState>();
2468 }
2469 };
2470
2471 // Tests call one of these two helper member functions to start using the
2472 // mini-DSL defined above.
2473 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2474};
2475
2476TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2477 Managed_NonHdr_Prefers_Colorimetric) {
2478 verify().ifDataspaceChosenIsNonHdr()
2479 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2480 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2481 .execute();
2482}
2483
2484TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2485 Managed_Hdr_Prefers_ToneMapColorimetric) {
2486 verify().ifDataspaceChosenIsHdr()
2487 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2488 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2489 .execute();
2490}
2491
2492TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2493 verify().ifDataspaceChosenIsNonHdr()
2494 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2495 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2496 .execute();
2497}
2498
2499TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2500 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2501 verify().ifDataspaceChosenIsHdr()
2502 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2503 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2504 .execute();
2505}
2506
2507TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2508 verify().ifDataspaceChosenIsNonHdr()
2509 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2510 .thenExpectBestColorModeCallUses(
2511 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2512 .execute();
2513}
2514
2515TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2516 verify().ifDataspaceChosenIsHdr()
2517 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2518 .thenExpectBestColorModeCallUses(
2519 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2520 .execute();
2521}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002522
2523/*
2524 * Output::beginFrame()
2525 */
2526
Lloyd Piquee5965952019-11-18 16:16:32 -08002527struct OutputBeginFrameTest : public ::testing::Test {
2528 using TestType = OutputBeginFrameTest;
2529
2530 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002531 // Sets up the helper functions called by the function under test to use
2532 // mock implementations.
Lloyd Piquee5965952019-11-18 16:16:32 -08002533 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
2534 };
2535
2536 OutputBeginFrameTest() {
2537 mOutput.setDisplayColorProfileForTest(
2538 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2539 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2540 }
2541
2542 struct IfGetDirtyRegionExpectationState
2543 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2544 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
2545 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion(false))
2546 .WillOnce(Return(dirtyRegion));
2547 return nextState<AndIfGetOutputLayerCountExpectationState>();
2548 }
2549 };
2550
2551 struct AndIfGetOutputLayerCountExpectationState
2552 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2553 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2554 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2555 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2556 }
2557 };
2558
2559 struct AndIfLastCompositionHadVisibleLayersState
2560 : public CallOrderStateMachineHelper<TestType,
2561 AndIfLastCompositionHadVisibleLayersState> {
2562 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2563 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2564 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2565 }
2566 };
2567
2568 struct ThenExpectRenderSurfaceBeginFrameCallState
2569 : public CallOrderStateMachineHelper<TestType,
2570 ThenExpectRenderSurfaceBeginFrameCallState> {
2571 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2572 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2573 return nextState<ExecuteState>();
2574 }
2575 };
2576
2577 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2578 [[nodiscard]] auto execute() {
2579 getInstance()->mOutput.beginFrame();
2580 return nextState<CheckPostconditionHadVisibleLayersState>();
2581 }
2582 };
2583
2584 struct CheckPostconditionHadVisibleLayersState
2585 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2586 void checkPostconditionHadVisibleLayers(bool expected) {
2587 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2588 }
2589 };
2590
2591 // Tests call one of these two helper member functions to start using the
2592 // mini-DSL defined above.
2593 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2594
2595 static const Region kEmptyRegion;
2596 static const Region kNotEmptyRegion;
2597
2598 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2599 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2600 StrictMock<OutputPartialMock> mOutput;
2601};
2602
2603const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2604const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2605
2606TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2607 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2608 .andIfGetOutputLayerCountReturns(1u)
2609 .andIfLastCompositionHadVisibleLayersIs(true)
2610 .thenExpectRenderSurfaceBeginFrameCall(true)
2611 .execute()
2612 .checkPostconditionHadVisibleLayers(true);
2613}
2614
2615TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2616 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2617 .andIfGetOutputLayerCountReturns(0u)
2618 .andIfLastCompositionHadVisibleLayersIs(true)
2619 .thenExpectRenderSurfaceBeginFrameCall(true)
2620 .execute()
2621 .checkPostconditionHadVisibleLayers(false);
2622}
2623
2624TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2625 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2626 .andIfGetOutputLayerCountReturns(1u)
2627 .andIfLastCompositionHadVisibleLayersIs(false)
2628 .thenExpectRenderSurfaceBeginFrameCall(true)
2629 .execute()
2630 .checkPostconditionHadVisibleLayers(true);
2631}
2632
2633TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2634 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2635 .andIfGetOutputLayerCountReturns(0u)
2636 .andIfLastCompositionHadVisibleLayersIs(false)
2637 .thenExpectRenderSurfaceBeginFrameCall(false)
2638 .execute()
2639 .checkPostconditionHadVisibleLayers(false);
2640}
2641
2642TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2643 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2644 .andIfGetOutputLayerCountReturns(1u)
2645 .andIfLastCompositionHadVisibleLayersIs(true)
2646 .thenExpectRenderSurfaceBeginFrameCall(false)
2647 .execute()
2648 .checkPostconditionHadVisibleLayers(true);
2649}
2650
2651TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2652 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2653 .andIfGetOutputLayerCountReturns(0u)
2654 .andIfLastCompositionHadVisibleLayersIs(true)
2655 .thenExpectRenderSurfaceBeginFrameCall(false)
2656 .execute()
2657 .checkPostconditionHadVisibleLayers(true);
2658}
2659
2660TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2661 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2662 .andIfGetOutputLayerCountReturns(1u)
2663 .andIfLastCompositionHadVisibleLayersIs(false)
2664 .thenExpectRenderSurfaceBeginFrameCall(false)
2665 .execute()
2666 .checkPostconditionHadVisibleLayers(false);
2667}
2668
2669TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2670 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2671 .andIfGetOutputLayerCountReturns(0u)
2672 .andIfLastCompositionHadVisibleLayersIs(false)
2673 .thenExpectRenderSurfaceBeginFrameCall(false)
2674 .execute()
2675 .checkPostconditionHadVisibleLayers(false);
2676}
2677
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002678/*
2679 * Output::devOptRepaintFlash()
2680 */
2681
Lloyd Piquedb462d82019-11-19 17:58:46 -08002682struct OutputDevOptRepaintFlashTest : public testing::Test {
2683 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002684 // Sets up the helper functions called by the function under test to use
2685 // mock implementations.
Lloyd Piquedb462d82019-11-19 17:58:46 -08002686 MOCK_CONST_METHOD1(getDirtyRegion, Region(bool));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002687 MOCK_METHOD2(composeSurfaces,
2688 std::optional<base::unique_fd>(
2689 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002690 MOCK_METHOD0(postFramebuffer, void());
2691 MOCK_METHOD0(prepareFrame, void());
2692 };
2693
2694 OutputDevOptRepaintFlashTest() {
2695 mOutput.setDisplayColorProfileForTest(
2696 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2697 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2698 }
2699
2700 static const Region kEmptyRegion;
2701 static const Region kNotEmptyRegion;
2702
2703 StrictMock<OutputPartialMock> mOutput;
2704 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2705 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2706 CompositionRefreshArgs mRefreshArgs;
2707};
2708
2709const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2710const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2711
2712TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2713 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
2714 mRefreshArgs.repaintEverything = true;
2715 mOutput.mState.isEnabled = true;
2716
2717 mOutput.devOptRepaintFlash(mRefreshArgs);
2718}
2719
2720TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2721 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2722 mRefreshArgs.repaintEverything = true;
2723 mOutput.mState.isEnabled = false;
2724
2725 InSequence seq;
2726 EXPECT_CALL(mOutput, postFramebuffer());
2727 EXPECT_CALL(mOutput, prepareFrame());
2728
2729 mOutput.devOptRepaintFlash(mRefreshArgs);
2730}
2731
2732TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotDirty) {
2733 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2734 mRefreshArgs.repaintEverything = true;
2735 mOutput.mState.isEnabled = true;
2736
2737 InSequence seq;
2738 EXPECT_CALL(mOutput, getDirtyRegion(true)).WillOnce(Return(kEmptyRegion));
2739 EXPECT_CALL(mOutput, postFramebuffer());
2740 EXPECT_CALL(mOutput, prepareFrame());
2741
2742 mOutput.devOptRepaintFlash(mRefreshArgs);
2743}
2744
2745TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2746 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
2747 mRefreshArgs.repaintEverything = false;
2748 mOutput.mState.isEnabled = true;
2749
2750 InSequence seq;
2751 EXPECT_CALL(mOutput, getDirtyRegion(false)).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002752 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002753 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2754 EXPECT_CALL(mOutput, postFramebuffer());
2755 EXPECT_CALL(mOutput, prepareFrame());
2756
2757 mOutput.devOptRepaintFlash(mRefreshArgs);
2758}
2759
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002760/*
2761 * Output::finishFrame()
2762 */
2763
Lloyd Pique03561a62019-11-19 18:34:52 -08002764struct OutputFinishFrameTest : public testing::Test {
2765 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002766 // Sets up the helper functions called by the function under test to use
2767 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002768 MOCK_METHOD2(composeSurfaces,
2769 std::optional<base::unique_fd>(
2770 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002771 MOCK_METHOD0(postFramebuffer, void());
2772 };
2773
2774 OutputFinishFrameTest() {
2775 mOutput.setDisplayColorProfileForTest(
2776 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2777 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2778 }
2779
2780 StrictMock<OutputPartialMock> mOutput;
2781 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2782 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2783 CompositionRefreshArgs mRefreshArgs;
2784};
2785
2786TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2787 mOutput.mState.isEnabled = false;
2788
2789 mOutput.finishFrame(mRefreshArgs);
2790}
2791
2792TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2793 mOutput.mState.isEnabled = true;
2794
2795 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002796 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002797
2798 mOutput.finishFrame(mRefreshArgs);
2799}
2800
2801TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2802 mOutput.mState.isEnabled = true;
2803
2804 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002805 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002806 .WillOnce(Return(ByMove(base::unique_fd())));
2807 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2808
2809 mOutput.finishFrame(mRefreshArgs);
2810}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002811
2812/*
2813 * Output::postFramebuffer()
2814 */
2815
Lloyd Pique07178e32019-11-19 19:15:26 -08002816struct OutputPostFramebufferTest : public testing::Test {
2817 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002818 // Sets up the helper functions called by the function under test to use
2819 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002820 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2821 };
2822
2823 struct Layer {
2824 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002825 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002826 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2827 }
2828
2829 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002830 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002831 StrictMock<HWC2::mock::Layer> hwc2Layer;
2832 };
2833
2834 OutputPostFramebufferTest() {
2835 mOutput.setDisplayColorProfileForTest(
2836 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2837 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2838
2839 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2840 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2841 .WillRepeatedly(Return(&mLayer1.outputLayer));
2842 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2843 .WillRepeatedly(Return(&mLayer2.outputLayer));
2844 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2845 .WillRepeatedly(Return(&mLayer3.outputLayer));
2846 }
2847
2848 StrictMock<OutputPartialMock> mOutput;
2849 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2850 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2851
2852 Layer mLayer1;
2853 Layer mLayer2;
2854 Layer mLayer3;
2855};
2856
2857TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2858 mOutput.mState.isEnabled = false;
2859
2860 mOutput.postFramebuffer();
2861}
2862
2863TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2864 mOutput.mState.isEnabled = true;
2865
2866 compositionengine::Output::FrameFences frameFences;
2867
2868 // This should happen even if there are no output layers.
2869 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2870
2871 // For this test in particular we want to make sure the call expectations
2872 // setup below are satisfied in the specific order.
2873 InSequence seq;
2874
2875 EXPECT_CALL(*mRenderSurface, flip());
2876 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2877 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2878
2879 mOutput.postFramebuffer();
2880}
2881
2882TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2883 // Simulate getting release fences from each layer, and ensure they are passed to the
2884 // front-end layer interface for each layer correctly.
2885
2886 mOutput.mState.isEnabled = true;
2887
2888 // Create three unique fence instances
2889 sp<Fence> layer1Fence = new Fence();
2890 sp<Fence> layer2Fence = new Fence();
2891 sp<Fence> layer3Fence = new Fence();
2892
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002893 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002894 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2895 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2896 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2897
2898 EXPECT_CALL(*mRenderSurface, flip());
2899 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2900 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2901
2902 // Compare the pointers values of each fence to make sure the correct ones
2903 // are passed. This happens to work with the current implementation, but
2904 // would not survive certain calls like Fence::merge() which would return a
2905 // new instance.
Ady Abrahameca9d752021-03-03 12:20:00 -08002906 EXPECT_CALL(*mLayer1.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002907 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer1Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002908 EXPECT_CALL(*mLayer2.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002909 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer2Fence.get()))));
Ady Abrahameca9d752021-03-03 12:20:00 -08002910 EXPECT_CALL(*mLayer3.layerFE,
Lloyd Pique07178e32019-11-19 19:15:26 -08002911 onLayerDisplayed(Property(&sp<Fence>::get, Eq(layer3Fence.get()))));
2912
2913 mOutput.postFramebuffer();
2914}
2915
2916TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2917 mOutput.mState.isEnabled = true;
2918 mOutput.mState.usesClientComposition = true;
2919
2920 sp<Fence> clientTargetAcquireFence = new Fence();
2921 sp<Fence> layer1Fence = new Fence();
2922 sp<Fence> layer2Fence = new Fence();
2923 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002924 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002925 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2926 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2927 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2928 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2929
2930 EXPECT_CALL(*mRenderSurface, flip());
2931 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2932 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2933
2934 // Fence::merge is called, and since none of the fences are actually valid,
2935 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2936 // This is the best we can do without creating a real kernel fence object.
Ady Abrahameca9d752021-03-03 12:20:00 -08002937 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2938 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(Fence::NO_FENCE));
2939 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(Fence::NO_FENCE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002940
2941 mOutput.postFramebuffer();
2942}
2943
2944TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2945 mOutput.mState.isEnabled = true;
2946 mOutput.mState.usesClientComposition = true;
2947
2948 // This should happen even if there are no (current) output layers.
2949 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2950
2951 // Load up the released layers with some mock instances
2952 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2953 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2954 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2955 Output::ReleasedLayers layers;
2956 layers.push_back(releasedLayer1);
2957 layers.push_back(releasedLayer2);
2958 layers.push_back(releasedLayer3);
2959 mOutput.setReleasedLayers(std::move(layers));
2960
2961 // Set up a fake present fence
2962 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002963 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002964 frameFences.presentFence = presentFence;
2965
2966 EXPECT_CALL(*mRenderSurface, flip());
2967 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2968 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2969
2970 // Each released layer should be given the presentFence.
2971 EXPECT_CALL(*releasedLayer1,
2972 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2973 EXPECT_CALL(*releasedLayer2,
2974 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2975 EXPECT_CALL(*releasedLayer3,
2976 onLayerDisplayed(Property(&sp<Fence>::get, Eq(presentFence.get()))));
2977
2978 mOutput.postFramebuffer();
2979
2980 // After the call the list of released layers should have been cleared.
2981 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2982}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002983
2984/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002985 * Output::composeSurfaces()
2986 */
2987
2988struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002989 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002990
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002991 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002992 // Sets up the helper functions called by the function under test to use
2993 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07002994 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Vishnu Nair3a7346c2019-12-04 08:09:09 -08002995 MOCK_METHOD3(generateClientCompositionRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002996 std::vector<LayerFE::LayerSettings>(bool, Region&, ui::Dataspace));
Lloyd Pique56eba802019-08-28 15:45:25 -07002997 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08002998 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07002999 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3000 };
3001
3002 OutputComposeSurfacesTest() {
3003 mOutput.setDisplayColorProfileForTest(
3004 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3005 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003006 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003007
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003008 mOutput.mState.orientedDisplaySpace.content = kDefaultOutputFrame;
3009 mOutput.mState.layerStackSpace.content = kDefaultOutputViewport;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003010 mOutput.mState.framebufferSpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003011 mOutput.mState.displaySpace.content = kDefaultOutputDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003012 mOutput.mState.displaySpace.orientation = kDefaultOutputOrientation;
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003013 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003014 mOutput.mState.dataspace = kDefaultOutputDataspace;
3015 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3016 mOutput.mState.isSecure = false;
3017 mOutput.mState.needsFiltering = false;
3018 mOutput.mState.usesClientComposition = true;
3019 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003020 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003021 mOutput.mState.flipClientTarget = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003022
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003023 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003024 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003025 EXPECT_CALL(mCompositionEngine, getTimeStats())
3026 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003027 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3028 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003029 }
3030
Lloyd Pique6818fa52019-12-03 12:32:13 -08003031 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3032 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003033 getInstance()->mReadyFence =
3034 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003035 return nextState<FenceCheckState>();
3036 }
3037 };
3038
3039 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3040 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3041
3042 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3043 };
3044
3045 // Call this member function to start using the mini-DSL defined above.
3046 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3047
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003048 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3049 static constexpr uint32_t kDefaultOutputOrientationFlags =
3050 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003051 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3052 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3053 static constexpr float kDefaultMaxLuminance = 0.9f;
3054 static constexpr float kDefaultAvgLuminance = 0.7f;
3055 static constexpr float kDefaultMinLuminance = 0.1f;
3056
3057 static const Rect kDefaultOutputFrame;
3058 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003059 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003060 static const mat4 kDefaultColorTransformMat;
3061
3062 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003063 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003064 static const HdrCapabilities kHdrCapabilities;
3065
Lloyd Pique56eba802019-08-28 15:45:25 -07003066 StrictMock<mock::CompositionEngine> mCompositionEngine;
3067 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003068 // TODO: make this is a proper mock.
3069 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003070 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3071 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003072 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003073 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
3074 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3075 renderengine::ExternalTexture::Usage::READABLE |
3076 renderengine::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003077
3078 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003079};
3080
3081const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3082const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003083const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003084const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003085const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003086const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3087const HdrCapabilities OutputComposeSurfacesTest::
3088 kHdrCapabilities{{},
3089 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3090 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3091 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003092
Lloyd Piquea76ce462020-01-14 13:06:37 -08003093TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003094 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003095
Lloyd Piquee9eff972020-05-05 12:36:44 -07003096 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003097 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003098
Lloyd Piquea76ce462020-01-14 13:06:37 -08003099 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3100
Lloyd Pique6818fa52019-12-03 12:32:13 -08003101 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003102}
3103
Lloyd Piquee9eff972020-05-05 12:36:44 -07003104TEST_F(OutputComposeSurfacesTest,
3105 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3106 mOutput.mState.usesClientComposition = false;
3107 mOutput.mState.flipClientTarget = true;
3108
Lloyd Pique6818fa52019-12-03 12:32:13 -08003109 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003110 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003111
3112 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3113 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3114
3115 verify().execute().expectAFenceWasReturned();
3116}
3117
3118TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3119 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003120 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003121
3122 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3123
3124 verify().execute().expectNoFenceWasReturned();
3125}
3126
3127TEST_F(OutputComposeSurfacesTest,
3128 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3129 mOutput.mState.usesClientComposition = false;
3130 mOutput.mState.flipClientTarget = true;
3131
3132 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003133 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003134
Lloyd Pique6818fa52019-12-03 12:32:13 -08003135 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003136
Lloyd Pique6818fa52019-12-03 12:32:13 -08003137 verify().execute().expectNoFenceWasReturned();
3138}
Lloyd Pique56eba802019-08-28 15:45:25 -07003139
Lloyd Pique6818fa52019-12-03 12:32:13 -08003140TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3141 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3142 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3143 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003144 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003145 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003146 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003147 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3148 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003149
Lloyd Pique6818fa52019-12-03 12:32:13 -08003150 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003151 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003152 .WillRepeatedly(Return(NO_ERROR));
Lloyd Pique56eba802019-08-28 15:45:25 -07003153
Lloyd Pique6818fa52019-12-03 12:32:13 -08003154 verify().execute().expectAFenceWasReturned();
3155}
Lloyd Pique56eba802019-08-28 15:45:25 -07003156
Lloyd Pique6818fa52019-12-03 12:32:13 -08003157TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003158 LayerFE::LayerSettings r1;
3159 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003160
3161 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3162 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3163
3164 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3165 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3166 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003167 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003168 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003169 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003170 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3171 .WillRepeatedly(
3172 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003173 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003174 clientCompositionLayers.emplace_back(r2);
3175 }));
3176
3177 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003178 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
3179 .WillRepeatedly(Return(NO_ERROR));
3180
3181 verify().execute().expectAFenceWasReturned();
3182}
3183
3184TEST_F(OutputComposeSurfacesTest,
3185 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3186 LayerFE::LayerSettings r1;
3187 LayerFE::LayerSettings r2;
3188
3189 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3190 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3191 const constexpr uint32_t kInternalLayerStack = 1234;
3192 mOutput.setLayerStackFilter(kInternalLayerStack, true);
3193
3194 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3195 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3196 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3197 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
3198 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3199 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3200 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3201 .WillRepeatedly(
3202 Invoke([&](const Region&,
3203 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3204 clientCompositionLayers.emplace_back(r2);
3205 }));
3206
3207 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003208 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, true, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003209 .WillRepeatedly(Return(NO_ERROR));
3210
3211 verify().execute().expectAFenceWasReturned();
3212}
3213
Vishnu Nair9b079a22020-01-21 14:36:08 -08003214TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3215 mOutput.cacheClientCompositionRequests(0);
3216 LayerFE::LayerSettings r1;
3217 LayerFE::LayerSettings r2;
3218
3219 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3220 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3221
3222 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3223 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3224 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003225 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003226 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3227 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3228 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3229 .WillRepeatedly(Return());
3230
3231 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003232 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003233 .Times(2)
3234 .WillOnce(Return(NO_ERROR));
3235
3236 verify().execute().expectAFenceWasReturned();
3237 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3238
3239 verify().execute().expectAFenceWasReturned();
3240 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3241}
3242
3243TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3244 mOutput.cacheClientCompositionRequests(3);
3245 LayerFE::LayerSettings r1;
3246 LayerFE::LayerSettings r2;
3247
3248 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3249 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3250
3251 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3252 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3253 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003254 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003255 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3256 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3257 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3258 .WillRepeatedly(Return());
3259
3260 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003261 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003262 .WillOnce(Return(NO_ERROR));
3263 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3264
3265 verify().execute().expectAFenceWasReturned();
3266 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3267
3268 // We do not expect another call to draw layers.
3269 verify().execute().expectAFenceWasReturned();
3270 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3271}
3272
3273TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3274 LayerFE::LayerSettings r1;
3275 LayerFE::LayerSettings r2;
3276
3277 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3278 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3279
3280 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3281 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3282 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003283 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003284 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3285 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3286 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3287 .WillRepeatedly(Return());
3288
Alec Mouria90a5702021-04-16 16:36:21 +00003289 const auto otherOutputBuffer = std::make_shared<
3290 renderengine::ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3291 renderengine::ExternalTexture::Usage::READABLE |
3292 renderengine::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003293 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3294 .WillOnce(Return(mOutputBuffer))
3295 .WillOnce(Return(otherOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003296 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003297 .WillRepeatedly(Return(NO_ERROR));
3298
3299 verify().execute().expectAFenceWasReturned();
3300 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3301
3302 verify().execute().expectAFenceWasReturned();
3303 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3304}
3305
3306TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3307 LayerFE::LayerSettings r1;
3308 LayerFE::LayerSettings r2;
3309 LayerFE::LayerSettings r3;
3310
3311 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3312 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3313 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3314
3315 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3316 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3317 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003318 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003319 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3320 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3321 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3322 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3323 .WillRepeatedly(Return());
3324
3325 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003326 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r2)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003327 .WillOnce(Return(NO_ERROR));
Alec Mouri1684c702021-02-04 12:27:26 -08003328 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(Pointee(r1), Pointee(r3)), _, false, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003329 .WillOnce(Return(NO_ERROR));
3330
3331 verify().execute().expectAFenceWasReturned();
3332 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3333
3334 verify().execute().expectAFenceWasReturned();
3335 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3336}
3337
Lloyd Pique6818fa52019-12-03 12:32:13 -08003338struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3339 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3340 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003341 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003342 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003343 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003344 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3345 .WillRepeatedly(Return());
3346 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3347 }
3348
3349 struct MixedCompositionState
3350 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3351 auto ifMixedCompositionIs(bool used) {
3352 getInstance()->mOutput.mState.usesDeviceComposition = used;
3353 return nextState<OutputUsesHdrState>();
3354 }
3355 };
3356
3357 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3358 auto andIfUsesHdr(bool used) {
3359 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3360 .WillOnce(Return(used));
3361 return nextState<SkipColorTransformState>();
3362 }
3363 };
3364
3365 struct SkipColorTransformState
3366 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3367 auto andIfSkipColorTransform(bool skip) {
3368 // May be called zero or one times.
3369 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3370 .WillRepeatedly(Return(skip));
3371 return nextState<ExpectDisplaySettingsState>();
3372 }
3373 };
3374
3375 struct ExpectDisplaySettingsState
3376 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3377 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Alec Mouri1684c702021-02-04 12:27:26 -08003378 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003379 .WillOnce(Return(NO_ERROR));
3380 return nextState<ExecuteState>();
3381 }
3382 };
3383
3384 // Call this member function to start using the mini-DSL defined above.
3385 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3386};
3387
3388TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3389 verify().ifMixedCompositionIs(true)
3390 .andIfUsesHdr(true)
3391 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003392 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003393 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003394 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003395 .execute()
3396 .expectAFenceWasReturned();
3397}
3398
3399TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3400 verify().ifMixedCompositionIs(true)
3401 .andIfUsesHdr(false)
3402 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003403 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003404 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003405 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003406 .execute()
3407 .expectAFenceWasReturned();
3408}
3409
3410TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3411 verify().ifMixedCompositionIs(false)
3412 .andIfUsesHdr(true)
3413 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003414 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003415 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003416 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003417 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003418 .execute()
3419 .expectAFenceWasReturned();
3420}
3421
3422TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3423 verify().ifMixedCompositionIs(false)
3424 .andIfUsesHdr(false)
3425 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003426 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003427 kDefaultMaxLuminance, kDefaultOutputDataspace,
Lloyd Pique6818fa52019-12-03 12:32:13 -08003428 kDefaultColorTransformMat, Region::INVALID_REGION,
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003429 kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003430 .execute()
3431 .expectAFenceWasReturned();
3432}
3433
3434TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3435 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3436 verify().ifMixedCompositionIs(false)
3437 .andIfUsesHdr(true)
3438 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003439 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003440 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003441 Region::INVALID_REGION, kDefaultOutputOrientationFlags})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003442 .execute()
3443 .expectAFenceWasReturned();
3444}
3445
3446struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3447 struct Layer {
3448 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003449 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3450 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003451 }
3452
3453 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003454 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003455 LayerFECompositionState mLayerFEState;
3456 };
3457
3458 OutputComposeSurfacesTest_HandlesProtectedContent() {
3459 mLayer1.mLayerFEState.hasProtectedContent = false;
3460 mLayer2.mLayerFEState.hasProtectedContent = false;
3461
3462 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3463 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3464 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3465 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3466 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3467
3468 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3469
3470 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3471
3472 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003473 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003474 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3475 .WillRepeatedly(Return());
3476 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003477 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _))
Lloyd Pique6818fa52019-12-03 12:32:13 -08003478 .WillRepeatedly(Return(NO_ERROR));
3479 }
3480
3481 Layer mLayer1;
3482 Layer mLayer2;
3483};
3484
3485TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3486 mOutput.mState.isSecure = false;
3487 mLayer2.mLayerFEState.hasProtectedContent = true;
3488 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003489 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003490 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003491
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003492 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003493}
3494
3495TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3496 mOutput.mState.isSecure = true;
3497 mLayer2.mLayerFEState.hasProtectedContent = true;
3498 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3499
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003500 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003501}
3502
3503TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3504 mOutput.mState.isSecure = true;
3505 mLayer2.mLayerFEState.hasProtectedContent = false;
3506 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3507 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3508 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3509 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3510 EXPECT_CALL(*mRenderSurface, setProtected(false));
3511
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003512 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513}
3514
3515TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3516 mOutput.mState.isSecure = true;
3517 mLayer2.mLayerFEState.hasProtectedContent = true;
3518 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3519
3520 // For this test, we also check the call order of key functions.
3521 InSequence seq;
3522
3523 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3524 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3525 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3526 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3527 EXPECT_CALL(*mRenderSurface, setProtected(true));
3528 // Must happen after setting the protected content state.
3529 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Alec Mouri1684c702021-02-04 12:27:26 -08003530 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003531
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003532 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003533}
3534
3535TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3536 mOutput.mState.isSecure = true;
3537 mLayer2.mLayerFEState.hasProtectedContent = true;
3538 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3539 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3540 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3541
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003542 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003543}
3544
3545TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3546 mOutput.mState.isSecure = true;
3547 mLayer2.mLayerFEState.hasProtectedContent = true;
3548 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3549 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3550 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3551 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3552
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003553 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003554}
3555
3556TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3557 mOutput.mState.isSecure = true;
3558 mLayer2.mLayerFEState.hasProtectedContent = true;
3559 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3560 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3561 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3562 EXPECT_CALL(*mRenderSurface, setProtected(true));
3563
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003564 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003565}
3566
3567TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3568 mOutput.mState.isSecure = true;
3569 mLayer2.mLayerFEState.hasProtectedContent = true;
3570 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3571 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3572 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3573 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3574
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003575 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003576}
3577
3578struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3579 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3580 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3581 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3582 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003583 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003584 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3585 .WillRepeatedly(Return());
3586 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3587 }
3588};
3589
3590TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3591 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3592
3593 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kExpensiveOutputDataspace))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003594 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003595
3596 // For this test, we also check the call order of key functions.
3597 InSequence seq;
3598
3599 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Alec Mouri1684c702021-02-04 12:27:26 -08003600 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003601
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003602 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3603}
3604
3605struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3606 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3607 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3608 mLayer.layerFEState.backgroundBlurRadius = 10;
3609 mOutput.editState().isEnabled = true;
3610
Snild Dolkow9e217d62020-04-22 15:53:42 +02003611 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003612 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003613 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3614 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003615 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, kDefaultOutputDataspace))
3616 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Alec Mouri1684c702021-02-04 12:27:26 -08003617 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _, _)).WillOnce(Return(NO_ERROR));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003618 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3619 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3620 .WillRepeatedly(Return(&mLayer.outputLayer));
3621 }
3622
3623 NonInjectedLayer mLayer;
3624 compositionengine::CompositionRefreshArgs mRefreshArgs;
3625};
3626
3627TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3628 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003629 mOutput.updateCompositionState(mRefreshArgs);
3630 mOutput.planComposition();
3631 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003632
3633 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3634 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3635}
3636
3637TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3638 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003639 mOutput.updateCompositionState(mRefreshArgs);
3640 mOutput.planComposition();
3641 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003642
3643 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3644 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003645}
3646
3647/*
3648 * Output::generateClientCompositionRequests()
3649 */
3650
3651struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003652 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003653 // compositionengine::Output overrides
Vishnu Nair9b079a22020-01-21 14:36:08 -08003654 std::vector<LayerFE::LayerSettings> generateClientCompositionRequests(
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003655 bool supportsProtectedContent, Region& clearRegion,
3656 ui::Dataspace dataspace) override {
Lloyd Pique56eba802019-08-28 15:45:25 -07003657 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Vishnu Nair3a7346c2019-12-04 08:09:09 -08003658 clearRegion, dataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003659 }
3660 };
3661
Lloyd Piquea4863342019-12-04 18:45:02 -08003662 struct Layer {
3663 Layer() {
3664 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3665 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003666 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3667 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003668 }
3669
3670 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003671 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003672 LayerFECompositionState mLayerFEState;
3673 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003674 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003675 };
3676
Lloyd Pique56eba802019-08-28 15:45:25 -07003677 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003678 mOutput.mState.needsFiltering = false;
3679
Lloyd Pique56eba802019-08-28 15:45:25 -07003680 mOutput.setDisplayColorProfileForTest(
3681 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3682 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3683 }
3684
Lloyd Pique56eba802019-08-28 15:45:25 -07003685 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3686 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003687 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003688};
3689
Lloyd Piquea4863342019-12-04 18:45:02 -08003690struct GenerateClientCompositionRequestsTest_ThreeLayers
3691 : public GenerateClientCompositionRequestsTest {
3692 GenerateClientCompositionRequestsTest_ThreeLayers() {
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02003693 mOutput.mState.orientedDisplaySpace.content = kDisplayFrame;
3694 mOutput.mState.layerStackSpace.content = kDisplayViewport;
3695 mOutput.mState.displaySpace.content = kDisplayDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003696 mOutput.mState.transform =
3697 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
3698 mOutput.mState.displaySpace.orientation = kDisplayOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08003699 mOutput.mState.needsFiltering = false;
3700 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003701
Lloyd Piquea4863342019-12-04 18:45:02 -08003702 for (size_t i = 0; i < mLayers.size(); i++) {
3703 mLayers[i].mOutputLayerState.clearClientTarget = false;
3704 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3705 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003706 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003707 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003708 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3709 mLayers[i].mLayerSettings.alpha = 1.0f;
3710 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003711
Lloyd Piquea4863342019-12-04 18:45:02 -08003712 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3713 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3714 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3715 .WillRepeatedly(Return(true));
3716 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3717 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003718
Lloyd Piquea4863342019-12-04 18:45:02 -08003719 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3720 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003721
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003722 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003723 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique56eba802019-08-28 15:45:25 -07003724
Lloyd Piquea4863342019-12-04 18:45:02 -08003725 static const Rect kDisplayFrame;
3726 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003727 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003728
Lloyd Piquea4863342019-12-04 18:45:02 -08003729 std::array<Layer, 3> mLayers;
3730};
Lloyd Pique56eba802019-08-28 15:45:25 -07003731
Lloyd Piquea4863342019-12-04 18:45:02 -08003732const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3733const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003734const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3735 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003736
Lloyd Piquea4863342019-12-04 18:45:02 -08003737TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3738 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3739 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3740 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003741
Lloyd Piquea4863342019-12-04 18:45:02 -08003742 Region accumClearRegion(Rect(10, 11, 12, 13));
3743 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3744 accumClearRegion, kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003745 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003746 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
Lloyd Pique56eba802019-08-28 15:45:25 -07003747}
3748
Lloyd Piquea4863342019-12-04 18:45:02 -08003749TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3750 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3751 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3752 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3753
3754 Region accumClearRegion(Rect(10, 11, 12, 13));
3755 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3756 accumClearRegion, kDisplayDataspace);
3757 EXPECT_EQ(0u, requests.size());
3758 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3759}
3760
3761TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003762 LayerFE::LayerSettings mShadowSettings;
3763 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003764
Ady Abrahameca9d752021-03-03 12:20:00 -08003765 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003766 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003767 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003768 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003769 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003770 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3771 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003772
3773 Region accumClearRegion(Rect(10, 11, 12, 13));
3774 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3775 accumClearRegion, kDisplayDataspace);
3776 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003777 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3778 EXPECT_EQ(mShadowSettings, requests[1]);
3779 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003780
3781 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3782
3783 // Check that a timestamp was set for the layers that generated requests
3784 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3785 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3786 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3787}
3788
Alec Mourif54453c2021-05-13 16:28:28 -07003789MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3790 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3791 *result_listener << "expected " << expectedBlurSetting << "\n";
3792 *result_listener << "actual " << arg.blurSetting << "\n";
3793
3794 return expectedBlurSetting == arg.blurSetting;
3795}
3796
3797TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3798 LayerFE::LayerSettings mShadowSettings;
3799 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3800
3801 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3802
3803 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3804 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3805 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3806 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3807 EXPECT_CALL(*mLayers[2].mLayerFE,
3808 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3809 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3810 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3811 {mShadowSettings, mLayers[2].mLayerSettings})));
3812
3813 Region accumClearRegion(Rect(10, 11, 12, 13));
3814 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3815 accumClearRegion, kDisplayDataspace);
3816 ASSERT_EQ(3u, requests.size());
3817 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3818 EXPECT_EQ(mShadowSettings, requests[1]);
3819 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3820
3821 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3822
3823 // Check that a timestamp was set for the layers that generated requests
3824 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3825 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3826 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3827}
3828
Lloyd Piquea4863342019-12-04 18:45:02 -08003829TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3830 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3831 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3832 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3833 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3834
3835 mLayers[0].mOutputLayerState.clearClientTarget = false;
3836 mLayers[1].mOutputLayerState.clearClientTarget = false;
3837 mLayers[2].mOutputLayerState.clearClientTarget = false;
3838
3839 mLayers[0].mLayerFEState.isOpaque = true;
3840 mLayers[1].mLayerFEState.isOpaque = true;
3841 mLayers[2].mLayerFEState.isOpaque = true;
3842
Ady Abrahameca9d752021-03-03 12:20:00 -08003843 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003844 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003845
3846 Region accumClearRegion(Rect(10, 11, 12, 13));
3847 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3848 accumClearRegion, kDisplayDataspace);
3849 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003850 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003851
3852 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3853}
3854
3855TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3856 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3857 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3858 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3859 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3860
3861 mLayers[0].mOutputLayerState.clearClientTarget = true;
3862 mLayers[1].mOutputLayerState.clearClientTarget = true;
3863 mLayers[2].mOutputLayerState.clearClientTarget = true;
3864
3865 mLayers[0].mLayerFEState.isOpaque = false;
3866 mLayers[1].mLayerFEState.isOpaque = false;
3867 mLayers[2].mLayerFEState.isOpaque = false;
3868
Ady Abrahameca9d752021-03-03 12:20:00 -08003869 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003870 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003871
3872 Region accumClearRegion(Rect(10, 11, 12, 13));
3873 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3874 accumClearRegion, kDisplayDataspace);
3875 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003876 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003877
3878 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3879}
3880
3881TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003882 // If client composition is performed with some layers set to use device
3883 // composition, device layers after the first layer (device or client) will
3884 // clear the frame buffer if they are opaque and if that layer has a flag
3885 // set to do so. The first layer is skipped as the frame buffer is already
3886 // expected to be clear.
3887
Lloyd Piquea4863342019-12-04 18:45:02 -08003888 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3889 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3890 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003891
Lloyd Piquea4863342019-12-04 18:45:02 -08003892 mLayers[0].mOutputLayerState.clearClientTarget = true;
3893 mLayers[1].mOutputLayerState.clearClientTarget = true;
3894 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003895
Lloyd Piquea4863342019-12-04 18:45:02 -08003896 mLayers[0].mLayerFEState.isOpaque = true;
3897 mLayers[1].mLayerFEState.isOpaque = true;
3898 mLayers[2].mLayerFEState.isOpaque = true;
Lloyd Piquea4863342019-12-04 18:45:02 -08003899 Region accumClearRegion(Rect(10, 11, 12, 13));
Peiyong Lind8460c82020-07-28 16:04:22 -07003900 Region stubRegion;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003901
3902 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3903 Region(kDisplayFrame),
Peiyong Lind8460c82020-07-28 16:04:22 -07003904 false, /* needs filtering */
3905 false, /* secure */
3906 false, /* supports protected content */
3907 stubRegion, /* clear region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003908 kDisplayViewport,
3909 kDisplayDataspace,
3910 false /* realContentIsVisible */,
3911 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003912 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003913 };
3914 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3915 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003916 false, /* needs filtering */
3917 false, /* secure */
3918 false, /* supports protected content */
3919 accumClearRegion,
3920 kDisplayViewport,
3921 kDisplayDataspace,
3922 true /* realContentIsVisible */,
3923 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003924 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003925 };
3926
3927 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3928 mBlackoutSettings.source.buffer.buffer = nullptr;
3929 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3930 mBlackoutSettings.alpha = 0.f;
3931 mBlackoutSettings.disableBlending = true;
3932
Ady Abrahameca9d752021-03-03 12:20:00 -08003933 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003934 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003935 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003936 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3937
Lloyd Piquea4863342019-12-04 18:45:02 -08003938 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
3939 accumClearRegion, kDisplayDataspace);
3940 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003941
Lloyd Piquea4863342019-12-04 18:45:02 -08003942 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003943 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003944
Vishnu Nair9b079a22020-01-21 14:36:08 -08003945 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003946
Lloyd Piquea4863342019-12-04 18:45:02 -08003947 EXPECT_THAT(accumClearRegion, RegionEq(Region(Rect(10, 11, 12, 13))));
3948}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003949
Lloyd Piquea4863342019-12-04 18:45:02 -08003950TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3951 clippedVisibleRegionUsedToGenerateRequest) {
3952 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3953 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3954 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003955
Lloyd Piquea4863342019-12-04 18:45:02 -08003956 Region accumClearRegion(Rect(10, 11, 12, 13));
3957
3958 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3959 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003960 false, /* needs filtering */
3961 false, /* secure */
3962 false, /* supports protected content */
3963 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003964 kDisplayViewport,
3965 kDisplayDataspace,
3966 true /* realContentIsVisible */,
3967 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003968 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003969 };
3970 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3971 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003972 false, /* needs filtering */
3973 false, /* secure */
3974 false, /* supports protected content */
3975 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003976 kDisplayViewport,
3977 kDisplayDataspace,
3978 true /* realContentIsVisible */,
3979 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003980 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003981 };
3982 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3983 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003984 false, /* needs filtering */
3985 false, /* secure */
3986 false, /* supports protected content */
3987 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003988 kDisplayViewport,
3989 kDisplayDataspace,
3990 true /* realContentIsVisible */,
3991 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003992 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08003993 };
3994
Ady Abrahameca9d752021-03-03 12:20:00 -08003995 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003996 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003997 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003998 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003999 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004000 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004001
4002 static_cast<void>(
4003 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4004 accumClearRegion, kDisplayDataspace));
4005}
4006
4007TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4008 perLayerNeedsFilteringUsedToGenerateRequests) {
4009 mOutput.mState.needsFiltering = false;
4010 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4011
4012 Region accumClearRegion(Rect(10, 11, 12, 13));
4013
4014 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4015 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004016 true, /* needs filtering */
4017 false, /* secure */
4018 false, /* supports protected content */
4019 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004020 kDisplayViewport,
4021 kDisplayDataspace,
4022 true /* realContentIsVisible */,
4023 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004024 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004025 };
4026 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4027 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004028 false, /* needs filtering */
4029 false, /* secure */
4030 false, /* supports protected content */
4031 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004032 kDisplayViewport,
4033 kDisplayDataspace,
4034 true /* realContentIsVisible */,
4035 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004036 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004037 };
4038 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4039 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004040 false, /* needs filtering */
4041 false, /* secure */
4042 false, /* supports protected content */
4043 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004044 kDisplayViewport,
4045 kDisplayDataspace,
4046 true /* realContentIsVisible */,
4047 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004048 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004049 };
4050
Ady Abrahameca9d752021-03-03 12:20:00 -08004051 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004052 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004053 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004054 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004055 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004056 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004057
4058 static_cast<void>(
4059 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4060 accumClearRegion, kDisplayDataspace));
4061}
4062
4063TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4064 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4065 mOutput.mState.needsFiltering = true;
4066 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4067
4068 Region accumClearRegion(Rect(10, 11, 12, 13));
4069
4070 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4071 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004072 true, /* needs filtering */
4073 false, /* secure */
4074 false, /* supports protected content */
4075 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004076 kDisplayViewport,
4077 kDisplayDataspace,
4078 true /* realContentIsVisible */,
4079 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004080 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004081
Lloyd Piquea4863342019-12-04 18:45:02 -08004082 };
4083 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4084 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004085 true, /* needs filtering */
4086 false, /* secure */
4087 false, /* supports protected content */
4088 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004089 kDisplayViewport,
4090 kDisplayDataspace,
4091 true /* realContentIsVisible */,
4092 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004093 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004094 };
4095 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4096 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004097 true, /* needs filtering */
4098 false, /* secure */
4099 false, /* supports protected content */
4100 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004101 kDisplayViewport,
4102 kDisplayDataspace,
4103 true /* realContentIsVisible */,
4104 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004105 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004106 };
4107
Ady Abrahameca9d752021-03-03 12:20:00 -08004108 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004109 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004110 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004111 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004112 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004113 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004114
4115 static_cast<void>(
4116 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4117 accumClearRegion, kDisplayDataspace));
4118}
4119
4120TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4121 wholeOutputSecurityUsedToGenerateRequests) {
4122 mOutput.mState.isSecure = true;
4123
4124 Region accumClearRegion(Rect(10, 11, 12, 13));
4125
4126 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4127 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004128 false, /* needs filtering */
4129 true, /* secure */
4130 false, /* supports protected content */
4131 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004132 kDisplayViewport,
4133 kDisplayDataspace,
4134 true /* realContentIsVisible */,
4135 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004136 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004137 };
4138 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4139 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004140 false, /* needs filtering */
4141 true, /* secure */
4142 false, /* supports protected content */
4143 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004144 kDisplayViewport,
4145 kDisplayDataspace,
4146 true /* realContentIsVisible */,
4147 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004148 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004149 };
4150 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4151 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004152 false, /* needs filtering */
4153 true, /* secure */
4154 false, /* supports protected content */
4155 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004156 kDisplayViewport,
4157 kDisplayDataspace,
4158 true /* realContentIsVisible */,
4159 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004160 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004161 };
4162
Ady Abrahameca9d752021-03-03 12:20:00 -08004163 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004164 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004165 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004166 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004167 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004168 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004169
4170 static_cast<void>(
4171 mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4172 accumClearRegion, kDisplayDataspace));
4173}
4174
4175TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4176 protectedContentSupportUsedToGenerateRequests) {
4177 Region accumClearRegion(Rect(10, 11, 12, 13));
4178
4179 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4180 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004181 false, /* needs filtering */
4182 false, /* secure */
4183 true, /* supports protected content */
4184 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004185 kDisplayViewport,
4186 kDisplayDataspace,
4187 true /* realContentIsVisible */,
4188 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004189 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004190 };
4191 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4192 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004193 false, /* needs filtering */
4194 false, /* secure */
4195 true, /* supports protected content */
4196 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004197 kDisplayViewport,
4198 kDisplayDataspace,
4199 true /* realContentIsVisible */,
4200 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004201 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004202 };
4203 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4204 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004205 false, /* needs filtering */
4206 false, /* secure */
4207 true, /* supports protected content */
4208 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004209 kDisplayViewport,
4210 kDisplayDataspace,
4211 true /* realContentIsVisible */,
4212 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004213 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004214 };
4215
Ady Abrahameca9d752021-03-03 12:20:00 -08004216 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004217 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004218 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004219 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004220 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004221 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004222
4223 static_cast<void>(mOutput.generateClientCompositionRequests(true /* supportsProtectedContent */,
4224 accumClearRegion,
4225 kDisplayDataspace));
4226}
4227
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004228TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004229 InjectedLayer layer1;
4230 InjectedLayer layer2;
4231 InjectedLayer layer3;
4232
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004233 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004234 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004235 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004236 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004237 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4238 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004239 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004240 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004241 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4242 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004243 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004244 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004245 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4246 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004247
Lloyd Piquede196652020-01-22 17:29:58 -08004248 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004249
Lloyd Piquede196652020-01-22 17:29:58 -08004250 injectOutputLayer(layer1);
4251 injectOutputLayer(layer2);
4252 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004253
4254 mOutput->editState().isEnabled = true;
4255
4256 CompositionRefreshArgs args;
4257 args.updatingGeometryThisFrame = false;
4258 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004259 mOutput->updateCompositionState(args);
4260 mOutput->planComposition();
4261 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004262}
4263
Lucas Dupinc3800b82020-10-02 16:24:48 -07004264TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4265 InjectedLayer layer1;
4266 InjectedLayer layer2;
4267 InjectedLayer layer3;
4268
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004269 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004270 // Layer requesting blur, or below, should request client composition.
4271 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004272 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004273 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4274 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004275 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004276 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004277 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4278 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004279 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004280 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004281 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4282 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004283
4284 BlurRegion region;
4285 layer2.layerFEState.blurRegions.push_back(region);
4286
4287 injectOutputLayer(layer1);
4288 injectOutputLayer(layer2);
4289 injectOutputLayer(layer3);
4290
4291 mOutput->editState().isEnabled = true;
4292
4293 CompositionRefreshArgs args;
4294 args.updatingGeometryThisFrame = false;
4295 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004296 mOutput->updateCompositionState(args);
4297 mOutput->planComposition();
4298 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004299}
4300
Lloyd Piquea4863342019-12-04 18:45:02 -08004301TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4302 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4303 // one layer on the left covering the left side of the output, and one layer
4304 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004305
4306 const Rect kPortraitFrame(0, 0, 1000, 2000);
4307 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004308 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004309 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004310 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004311
Marin Shalamanov6ad317c2020-07-29 23:34:07 +02004312 mOutput.mState.orientedDisplaySpace.content = kPortraitFrame;
4313 mOutput.mState.layerStackSpace.content = kPortraitViewport;
4314 mOutput.mState.displaySpace.content = kPortraitDestinationClip;
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004315 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
4316 mOutput.mState.displaySpace.orientation = kPortraitOrientation;
Lloyd Piquea4863342019-12-04 18:45:02 -08004317 mOutput.mState.needsFiltering = false;
4318 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004319
Lloyd Piquea4863342019-12-04 18:45:02 -08004320 Layer leftLayer;
4321 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004322
Lloyd Piquea4863342019-12-04 18:45:02 -08004323 leftLayer.mOutputLayerState.clearClientTarget = false;
4324 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4325 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004326 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004327
Lloyd Piquea4863342019-12-04 18:45:02 -08004328 rightLayer.mOutputLayerState.clearClientTarget = false;
4329 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4330 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004331 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004332
4333 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4334 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4335 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4336 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4337 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4338
4339 Region accumClearRegion(Rect(10, 11, 12, 13));
4340
4341 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4342 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004343 false, /* needs filtering */
4344 true, /* secure */
4345 true, /* supports protected content */
4346 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004347 kPortraitViewport,
4348 kOutputDataspace,
4349 true /* realContentIsVisible */,
4350 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004351 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004352 };
4353
4354 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4355 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004356 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004357 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004358
4359 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4360 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004361 false, /* needs filtering */
4362 true, /* secure */
4363 true, /* supports protected content */
4364 accumClearRegion,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004365 kPortraitViewport,
4366 kOutputDataspace,
4367 true /* realContentIsVisible */,
4368 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004369 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Lloyd Piquea4863342019-12-04 18:45:02 -08004370 };
4371
4372 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4373 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004374 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004375 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004376
4377 constexpr bool supportsProtectedContent = true;
4378 auto requests = mOutput.generateClientCompositionRequests(supportsProtectedContent,
4379 accumClearRegion, kOutputDataspace);
4380 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004381 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4382 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004383}
4384
Vishnu Naira483b4a2019-12-12 15:07:52 -08004385TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4386 shadowRegionOnlyVisibleSkipsContentComposition) {
4387 const Rect kContentWithShadow(40, 40, 70, 90);
4388 const Rect kContent(50, 50, 60, 80);
4389 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4390 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4391
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004392 Region accumClearRegion(Rect(10, 11, 12, 13));
4393 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4394 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004395 false, /* needs filtering */
4396 false, /* secure */
4397 false, /* supports protected content */
4398 accumClearRegion,
4399 kDisplayViewport,
4400 kDisplayDataspace,
4401 false /* realContentIsVisible */,
4402 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004403 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004404 };
4405
Vishnu Nair9b079a22020-01-21 14:36:08 -08004406 LayerFE::LayerSettings mShadowSettings;
4407 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004408
4409 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4410 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4411
4412 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4413 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004414 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004415 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004416
Vishnu Naira483b4a2019-12-12 15:07:52 -08004417 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4418 accumClearRegion, kDisplayDataspace);
4419 ASSERT_EQ(1u, requests.size());
4420
Vishnu Nair9b079a22020-01-21 14:36:08 -08004421 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004422}
4423
4424TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4425 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4426 const Rect kContentWithShadow(40, 40, 70, 90);
4427 const Rect kContent(50, 50, 60, 80);
4428 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4429 const Region kPartialContentWithPartialShadowRegion =
4430 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4431
Vishnu Nair9b079a22020-01-21 14:36:08 -08004432 LayerFE::LayerSettings mShadowSettings;
4433 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004434
4435 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4436 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4437
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004438 Region accumClearRegion(Rect(10, 11, 12, 13));
4439 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4440 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004441 false, /* needs filtering */
4442 false, /* secure */
4443 false, /* supports protected content */
4444 accumClearRegion,
4445 kDisplayViewport,
4446 kDisplayDataspace,
4447 true /* realContentIsVisible */,
4448 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004449 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004450 };
4451
Vishnu Naira483b4a2019-12-12 15:07:52 -08004452 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4453 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004454 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004455 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4456 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004457
Vishnu Naira483b4a2019-12-12 15:07:52 -08004458 auto requests = mOutput.generateClientCompositionRequests(false /* supportsProtectedContent */,
4459 accumClearRegion, kDisplayDataspace);
4460 ASSERT_EQ(2u, requests.size());
4461
Vishnu Nair9b079a22020-01-21 14:36:08 -08004462 EXPECT_EQ(mShadowSettings, requests[0]);
4463 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004464}
4465
Lloyd Pique32cbe282018-10-19 13:09:22 -07004466} // namespace
4467} // namespace android::compositionengine