blob: 5fcb52d2602282a1c37178fea533a992f2ff3ac2 [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>
Sally Qi59a9f502021-10-12 18:53:23 +000027#include <ftl/future.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070028#include <gtest/gtest.h>
Vishnu Nairdbbe3852022-01-12 20:22:11 -080029#include <renderengine/ExternalTexture.h>
30#include <renderengine/impl/ExternalTexture.h>
Lloyd Pique56eba802019-08-28 15:45:25 -070031#include <renderengine/mock/RenderEngine.h>
Lloyd Pique32cbe282018-10-19 13:09:22 -070032#include <ui/Rect.h>
33#include <ui/Region.h>
34
Alec Mouria90a5702021-04-16 16:36:21 +000035#include <cmath>
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -040036#include <cstdint>
Alec Mouria90a5702021-04-16 16:36:21 +000037
Lloyd Pique17ca7422019-11-14 14:24:10 -080038#include "CallOrderStateMachineHelper.h"
Lloyd Pique07178e32019-11-19 19:15:26 -080039#include "MockHWC2.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070040#include "RegionMatcher.h"
Sally Qi4cabdd02021-08-05 16:45:57 -070041#include "TestUtils.h"
Lloyd Pique32cbe282018-10-19 13:09:22 -070042
43namespace android::compositionengine {
44namespace {
45
Lloyd Pique56eba802019-08-28 15:45:25 -070046using testing::_;
Lloyd Pique03561a62019-11-19 18:34:52 -080047using testing::ByMove;
Lloyd Piquea4863342019-12-04 18:45:02 -080048using testing::ByRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080049using testing::DoAll;
Vishnu Nair9b079a22020-01-21 14:36:08 -080050using testing::ElementsAre;
Lloyd Pique6818fa52019-12-03 12:32:13 -080051using testing::ElementsAreArray;
Lloyd Pique07178e32019-11-19 19:15:26 -080052using testing::Eq;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080053using testing::InSequence;
Lloyd Pique6818fa52019-12-03 12:32:13 -080054using testing::Invoke;
55using testing::IsEmpty;
Lloyd Pique17ca7422019-11-14 14:24:10 -080056using testing::Mock;
Vishnu Nair9b079a22020-01-21 14:36:08 -080057using testing::Pointee;
Lloyd Pique07178e32019-11-19 19:15:26 -080058using testing::Property;
Lloyd Piquefaa3f192019-11-14 14:05:09 -080059using testing::Ref;
Lloyd Pique31cb2942018-10-19 17:23:03 -070060using testing::Return;
Lloyd Pique32cbe282018-10-19 13:09:22 -070061using testing::ReturnRef;
Lloyd Pique17ca7422019-11-14 14:24:10 -080062using testing::SetArgPointee;
Lloyd Pique32cbe282018-10-19 13:09:22 -070063using testing::StrictMock;
64
Lloyd Pique56eba802019-08-28 15:45:25 -070065constexpr auto TR_IDENT = 0u;
66constexpr auto TR_ROT_90 = HAL_TRANSFORM_ROT_90;
Vishnu Nair9b079a22020-01-21 14:36:08 -080067constexpr auto MAX_CLIENT_COMPOSITION_CACHE_SIZE = 3;
Lloyd Pique56eba802019-08-28 15:45:25 -070068
Lloyd Pique3eb1b212019-03-07 21:15:40 -080069const mat4 kIdentity;
Lloyd Pique0a456232020-01-16 17:51:13 -080070const mat4 kNonIdentityHalf = mat4() * 0.5f;
71const mat4 kNonIdentityQuarter = mat4() * 0.25f;
Lloyd Pique3eb1b212019-03-07 21:15:40 -080072
Lloyd Pique17ca7422019-11-14 14:24:10 -080073constexpr OutputColorSetting kVendorSpecifiedOutputColorSetting =
74 static_cast<OutputColorSetting>(0x100);
75
Lloyd Piquefaa3f192019-11-14 14:05:09 -080076struct OutputPartialMockBase : public impl::Output {
77 // compositionengine::Output overrides
78 const OutputCompositionState& getState() const override { return mState; }
79 OutputCompositionState& editState() override { return mState; }
80
81 // Use mocks for all the remaining virtual functions
82 // not implemented by the base implementation class.
83 MOCK_CONST_METHOD0(getOutputLayerCount, size_t());
84 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, compositionengine::OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -080085 MOCK_METHOD2(ensureOutputLayer,
86 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080087 MOCK_METHOD0(finalizePendingOutputLayers, void());
88 MOCK_METHOD0(clearOutputLayers, void());
89 MOCK_CONST_METHOD1(dumpState, void(std::string&));
90 MOCK_CONST_METHOD0(getCompositionEngine, const CompositionEngine&());
Lloyd Piquede196652020-01-22 17:29:58 -080091 MOCK_METHOD1(injectOutputLayerForTest, compositionengine::OutputLayer*(const sp<LayerFE>&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -080092 MOCK_METHOD1(injectOutputLayerForTest, void(std::unique_ptr<OutputLayer>));
93
94 impl::OutputCompositionState mState;
95};
96
Lloyd Piquede196652020-01-22 17:29:58 -080097struct InjectedLayer {
98 InjectedLayer() {
99 EXPECT_CALL(*outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
100 EXPECT_CALL(*outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
101 EXPECT_CALL(*outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
102
103 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800104 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
105 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("InjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800106 }
107
108 mock::OutputLayer* outputLayer = {new StrictMock<mock::OutputLayer>};
109 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
110 LayerFECompositionState layerFEState;
111 impl::OutputLayerCompositionState outputLayerState;
112};
113
114struct NonInjectedLayer {
115 NonInjectedLayer() {
116 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE.get()));
117 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
118 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
119
120 EXPECT_CALL(*layerFE, getCompositionState()).WillRepeatedly(Return(&layerFEState));
Dan Stoza269dc4d2021-01-15 15:07:43 -0800121 EXPECT_CALL(*layerFE, getSequence()).WillRepeatedly(Return(0));
122 EXPECT_CALL(*layerFE, getDebugName()).WillRepeatedly(Return("NonInjectedLayer"));
Lloyd Piquede196652020-01-22 17:29:58 -0800123 }
124
125 mock::OutputLayer outputLayer;
126 sp<StrictMock<mock::LayerFE>> layerFE = new StrictMock<mock::LayerFE>();
127 LayerFECompositionState layerFEState;
128 impl::OutputLayerCompositionState outputLayerState;
129};
130
Lloyd Pique66d68602019-02-13 14:23:31 -0800131struct OutputTest : public testing::Test {
Lloyd Pique01c77c12019-04-17 12:48:32 -0700132 class Output : public impl::Output {
133 public:
134 using impl::Output::injectOutputLayerForTest;
135 virtual void injectOutputLayerForTest(std::unique_ptr<compositionengine::OutputLayer>) = 0;
136 };
137
138 static std::shared_ptr<Output> createOutput(
139 const compositionengine::CompositionEngine& compositionEngine) {
140 return impl::createOutputTemplated<Output>(compositionEngine);
141 }
142
Lloyd Pique31cb2942018-10-19 17:23:03 -0700143 OutputTest() {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700144 mOutput->setDisplayColorProfileForTest(
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700145 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700146 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Lloyd Piqueef958122019-02-05 18:00:12 -0800147
Angel Aguayob084e0c2021-08-04 23:27:28 +0000148 mOutput->editState().displaySpace.setBounds(
149 ui::Size(kDefaultDisplaySize.getWidth(), kDefaultDisplaySize.getHeight()));
Alec Mouridf6201b2021-06-01 16:20:42 -0700150 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700151 }
Lloyd Pique32cbe282018-10-19 13:09:22 -0700152
Lloyd Piquede196652020-01-22 17:29:58 -0800153 void injectOutputLayer(InjectedLayer& layer) {
154 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(layer.outputLayer));
155 }
156
157 void injectNullOutputLayer() {
158 mOutput->injectOutputLayerForTest(std::unique_ptr<OutputLayer>(nullptr));
159 }
160
Lloyd Piqueef958122019-02-05 18:00:12 -0800161 static const Rect kDefaultDisplaySize;
162
Lloyd Pique32cbe282018-10-19 13:09:22 -0700163 StrictMock<mock::CompositionEngine> mCompositionEngine;
Alec Mouridf6201b2021-06-01 16:20:42 -0700164 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700165 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
Lloyd Pique31cb2942018-10-19 17:23:03 -0700166 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Pique01c77c12019-04-17 12:48:32 -0700167 std::shared_ptr<Output> mOutput = createOutput(mCompositionEngine);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700168};
169
Lloyd Piqueef958122019-02-05 18:00:12 -0800170const Rect OutputTest::kDefaultDisplaySize{100, 200};
171
Lloyd Pique17ca7422019-11-14 14:24:10 -0800172using ColorProfile = compositionengine::Output::ColorProfile;
173
174void dumpColorProfile(ColorProfile profile, std::string& result, const char* name) {
175 android::base::StringAppendF(&result, "%s (%s[%d] %s[%d] %s[%d] %s[%d]) ", name,
176 toString(profile.mode).c_str(), profile.mode,
177 toString(profile.dataspace).c_str(), profile.dataspace,
178 toString(profile.renderIntent).c_str(), profile.renderIntent,
179 toString(profile.colorSpaceAgnosticDataspace).c_str(),
180 profile.colorSpaceAgnosticDataspace);
181}
182
183// Checks for a ColorProfile match
184MATCHER_P(ColorProfileEq, expected, "") {
185 std::string buf;
186 buf.append("ColorProfiles are not equal\n");
187 dumpColorProfile(expected, buf, "expected value");
188 dumpColorProfile(arg, buf, "actual value");
189 *result_listener << buf;
190
191 return (expected.mode == arg.mode) && (expected.dataspace == arg.dataspace) &&
192 (expected.renderIntent == arg.renderIntent) &&
193 (expected.colorSpaceAgnosticDataspace == arg.colorSpaceAgnosticDataspace);
194}
195
Lloyd Pique66d68602019-02-13 14:23:31 -0800196/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700197 * Basic construction
198 */
199
Lloyd Pique31cb2942018-10-19 17:23:03 -0700200TEST_F(OutputTest, canInstantiateOutput) {
201 // The validation check checks each required component.
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700202 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700203 EXPECT_CALL(*mRenderSurface, isValid()).WillOnce(Return(true));
204
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700205 EXPECT_TRUE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700206
207 // If we take away the required components, it is no longer valid.
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700208 mOutput->setRenderSurfaceForTest(std::unique_ptr<RenderSurface>());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700209
Lloyd Pique3d0c02e2018-10-19 18:38:12 -0700210 EXPECT_CALL(*mDisplayColorProfile, isValid()).WillOnce(Return(true));
211
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700212 EXPECT_FALSE(mOutput->isValid());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700213}
Lloyd Pique32cbe282018-10-19 13:09:22 -0700214
Lloyd Pique66d68602019-02-13 14:23:31 -0800215/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700216 * Output::setCompositionEnabled()
217 */
218
219TEST_F(OutputTest, setCompositionEnabledDoesNothingIfAlreadyEnabled) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700220 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700221
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700222 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700223
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700224 EXPECT_TRUE(mOutput->getState().isEnabled);
225 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700226}
227
228TEST_F(OutputTest, setCompositionEnabledSetsEnabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700229 mOutput->editState().isEnabled = false;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700230
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700231 mOutput->setCompositionEnabled(true);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700232
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700233 EXPECT_TRUE(mOutput->getState().isEnabled);
234 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700235}
236
237TEST_F(OutputTest, setCompositionEnabledSetsDisabledAndDirtiesEntireOutput) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700238 mOutput->editState().isEnabled = true;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700239
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700240 mOutput->setCompositionEnabled(false);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700241
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700242 EXPECT_FALSE(mOutput->getState().isEnabled);
243 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700244}
245
Lloyd Pique66d68602019-02-13 14:23:31 -0800246/*
Alec Mouri023c1882021-05-08 16:36:33 -0700247 * Output::setLayerCachingEnabled()
248 */
249
250TEST_F(OutputTest, setLayerCachingEnabled_enablesCaching) {
251 const auto kSize = ui::Size(1, 1);
252 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
253 mOutput->setLayerCachingEnabled(false);
254 mOutput->setLayerCachingEnabled(true);
255
256 EXPECT_TRUE(mOutput->plannerEnabled());
257}
258
259TEST_F(OutputTest, setLayerCachingEnabled_disablesCaching) {
260 const auto kSize = ui::Size(1, 1);
261 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
262 mOutput->setLayerCachingEnabled(true);
263 mOutput->setLayerCachingEnabled(false);
264
265 EXPECT_FALSE(mOutput->plannerEnabled());
266}
267
Alec Mouric773472b2021-05-19 14:29:05 -0700268TEST_F(OutputTest, setLayerCachingEnabled_disablesCachingAndResetsOverrideInfo) {
269 renderengine::mock::RenderEngine renderEngine;
270 const auto kSize = ui::Size(1, 1);
271 EXPECT_CALL(*mRenderSurface, getSize()).WillRepeatedly(ReturnRef(kSize));
272 mOutput->setLayerCachingEnabled(true);
273
274 // Inject some layers
275 InjectedLayer layer;
276 layer.outputLayerState.overrideInfo.buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800277 renderengine::impl::
278 ExternalTexture>(new GraphicBuffer(), renderEngine,
279 renderengine::impl::ExternalTexture::Usage::READABLE |
280 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Alec Mouric773472b2021-05-19 14:29:05 -0700281 injectOutputLayer(layer);
282 // inject a null layer to check for null exceptions
283 injectNullOutputLayer();
284
285 EXPECT_NE(nullptr, layer.outputLayerState.overrideInfo.buffer);
286 mOutput->setLayerCachingEnabled(false);
287 EXPECT_EQ(nullptr, layer.outputLayerState.overrideInfo.buffer);
288}
289
Alec Mouri023c1882021-05-08 16:36:33 -0700290/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700291 * Output::setProjection()
292 */
293
Marin Shalamanov209ae612020-10-01 00:17:39 +0200294TEST_F(OutputTest, setProjectionWorks) {
295 const Rect displayRect{0, 0, 1000, 2000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000296 mOutput->editState().displaySpace.setBounds(
297 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
298 mOutput->editState().framebufferSpace.setBounds(
299 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200300
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200301 const ui::Rotation orientation = ui::ROTATION_90;
Marin Shalamanov209ae612020-10-01 00:17:39 +0200302 const Rect frame{50, 60, 100, 100};
303 const Rect viewport{10, 20, 30, 40};
Lloyd Pique32cbe282018-10-19 13:09:22 -0700304
Marin Shalamanov68933fb2020-09-10 17:58:12 +0200305 mOutput->setProjection(orientation, viewport, frame);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700306
Angel Aguayob084e0c2021-08-04 23:27:28 +0000307 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
308 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
309 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200310
311 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000312 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
313 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
314 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200315
Angel Aguayob084e0c2021-08-04 23:27:28 +0000316 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
317 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
318 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200319
Angel Aguayob084e0c2021-08-04 23:27:28 +0000320 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
321 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
322 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200323
Angel Aguayob084e0c2021-08-04 23:27:28 +0000324 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
325 EXPECT_EQ(Rect(900, 50, 940, 100), state.framebufferSpace.getContent());
326 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200327
Angel Aguayob084e0c2021-08-04 23:27:28 +0000328 EXPECT_EQ(state.displaySpace.getContent(),
329 state.transform.transform(state.layerStackSpace.getContent()));
Garfield Tan54edd912020-10-21 16:31:41 -0700330
331 EXPECT_EQ(ui::Transform::ROT_90, mOutput->getTransformHint());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200332}
333
334TEST_F(OutputTest, setProjectionWithSmallFramebufferWorks) {
335 const Rect displayRect{0, 0, 1000, 2000};
336 const Rect framebufferRect{0, 0, 500, 1000};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000337 mOutput->editState().displaySpace.setBounds(
338 ui::Size(displayRect.getWidth(), displayRect.getHeight()));
339 mOutput->editState().framebufferSpace.setBounds(
340 ui::Size(framebufferRect.getWidth(), framebufferRect.getHeight()));
Marin Shalamanov209ae612020-10-01 00:17:39 +0200341
342 const ui::Rotation orientation = ui::ROTATION_90;
343 const Rect frame{50, 60, 100, 100};
344 const Rect viewport{10, 20, 30, 40};
345
346 mOutput->setProjection(orientation, viewport, frame);
347
Angel Aguayob084e0c2021-08-04 23:27:28 +0000348 EXPECT_EQ(orientation, mOutput->getState().displaySpace.getOrientation());
349 EXPECT_EQ(frame, mOutput->getState().orientedDisplaySpace.getContent());
350 EXPECT_EQ(viewport, mOutput->getState().layerStackSpace.getContent());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200351
352 const auto state = mOutput->getState();
Angel Aguayob084e0c2021-08-04 23:27:28 +0000353 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
354 EXPECT_EQ(viewport, state.layerStackSpace.getContent());
355 EXPECT_EQ(Rect(0, 0, 20, 20), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200356
Angel Aguayob084e0c2021-08-04 23:27:28 +0000357 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
358 EXPECT_EQ(frame, state.orientedDisplaySpace.getContent());
359 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200360
Angel Aguayob084e0c2021-08-04 23:27:28 +0000361 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
362 EXPECT_EQ(Rect(900, 50, 940, 100), state.displaySpace.getContent());
363 EXPECT_EQ(orientation, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200364
Angel Aguayob084e0c2021-08-04 23:27:28 +0000365 EXPECT_EQ(framebufferRect, state.framebufferSpace.getBoundsAsRect());
366 EXPECT_EQ(Rect(450, 25, 470, 50), state.framebufferSpace.getContent());
367 EXPECT_EQ(orientation, state.framebufferSpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200368
Angel Aguayob084e0c2021-08-04 23:27:28 +0000369 EXPECT_EQ(state.displaySpace.getContent(),
370 state.transform.transform(state.layerStackSpace.getContent()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700371}
372
Lloyd Pique66d68602019-02-13 14:23:31 -0800373/*
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200374 * Output::setDisplaySize()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700375 */
376
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200377TEST_F(OutputTest, setDisplaySpaceSizeUpdatesOutputStateAndDirtiesEntireOutput) {
Angel Aguayob084e0c2021-08-04 23:27:28 +0000378 mOutput->editState().layerStackSpace.setContent(Rect(0, 0, 2000, 1000));
379 mOutput->editState().layerStackSpace.setBounds(ui::Size(2000, 1000));
380 mOutput->editState().orientedDisplaySpace.setContent(Rect(0, 0, 1800, 900));
381 mOutput->editState().orientedDisplaySpace.setBounds(ui::Size(2000, 1000));
382 mOutput->editState().framebufferSpace.setContent(Rect(0, 0, 900, 1800));
383 mOutput->editState().framebufferSpace.setBounds(ui::Size(1000, 2000));
384 mOutput->editState().framebufferSpace.setOrientation(ui::ROTATION_90);
385 mOutput->editState().displaySpace.setContent(Rect(0, 0, 900, 1800));
386 mOutput->editState().displaySpace.setBounds(ui::Size(1000, 2000));
387 mOutput->editState().displaySpace.setOrientation(ui::ROTATION_90);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700388
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200389 const ui::Size newDisplaySize{500, 1000};
Lloyd Pique31cb2942018-10-19 17:23:03 -0700390
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200391 EXPECT_CALL(*mRenderSurface, setDisplaySize(newDisplaySize)).Times(1);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700392
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200393 mOutput->setDisplaySize(newDisplaySize);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700394
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200395 const auto state = mOutput->getState();
396
397 const Rect displayRect(newDisplaySize);
Angel Aguayob084e0c2021-08-04 23:27:28 +0000398 EXPECT_EQ(ui::ROTATION_0, state.layerStackSpace.getOrientation());
399 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getContent());
400 EXPECT_EQ(Rect(0, 0, 2000, 1000), state.layerStackSpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200401
Angel Aguayob084e0c2021-08-04 23:27:28 +0000402 EXPECT_EQ(ui::ROTATION_0, state.orientedDisplaySpace.getOrientation());
403 EXPECT_EQ(Rect(0, 0, 1000, 500), state.orientedDisplaySpace.getBoundsAsRect());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200404
Angel Aguayob084e0c2021-08-04 23:27:28 +0000405 EXPECT_EQ(displayRect, state.displaySpace.getBoundsAsRect());
406 EXPECT_EQ(ui::ROTATION_90, state.displaySpace.getOrientation());
Marin Shalamanov209ae612020-10-01 00:17:39 +0200407
Angel Aguayob084e0c2021-08-04 23:27:28 +0000408 EXPECT_EQ(displayRect, state.framebufferSpace.getBoundsAsRect());
409 EXPECT_EQ(ui::ROTATION_90, state.framebufferSpace.getOrientation());
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200410
Angel Aguayob084e0c2021-08-04 23:27:28 +0000411 EXPECT_EQ(state.displaySpace.getContent(),
412 state.transform.transform(state.layerStackSpace.getContent()));
Marin Shalamanovb15d2272020-09-17 21:41:52 +0200413
414 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(displayRect)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700415}
416
Lloyd Pique66d68602019-02-13 14:23:31 -0800417/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700418 * Output::setLayerFilter()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700419 */
420
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700421TEST_F(OutputTest, setLayerFilterSetsFilterAndDirtiesEntireOutput) {
422 constexpr ui::LayerFilter kFilter{ui::LayerStack{123u}, true};
423 mOutput->setLayerFilter(kFilter);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700424
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700425 const auto& state = mOutput->getState();
426 EXPECT_EQ(kFilter.layerStack, state.layerFilter.layerStack);
427 EXPECT_TRUE(state.layerFilter.toInternalDisplay);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700428
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700429 EXPECT_THAT(state.dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700430}
431
Lloyd Pique66d68602019-02-13 14:23:31 -0800432/*
Lloyd Pique32cbe282018-10-19 13:09:22 -0700433 * Output::setColorTransform
434 */
435
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800436TEST_F(OutputTest, setColorTransformWithNoChangeFlaggedSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700437 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700438
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800439 // If no colorTransformMatrix is set the update should be skipped.
440 CompositionRefreshArgs refreshArgs;
441 refreshArgs.colorTransformMatrix = std::nullopt;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700442
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700443 mOutput->setColorTransform(refreshArgs);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700444
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800445 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700446 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800447
448 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700449 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800450}
Lloyd Piqueef958122019-02-05 18:00:12 -0800451
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800452TEST_F(OutputTest, setColorTransformWithNoActualChangeSkipsUpdates) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700453 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700454
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800455 // Attempting to set the same colorTransformMatrix that is already set should
456 // also skip the update.
457 CompositionRefreshArgs refreshArgs;
458 refreshArgs.colorTransformMatrix = kIdentity;
Lloyd Pique32cbe282018-10-19 13:09:22 -0700459
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700460 mOutput->setColorTransform(refreshArgs);
Lloyd Pique77f79a22019-04-29 15:55:40 -0700461
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800462 // The internal state should be unchanged
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700463 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800464
465 // No dirty region should be set
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700466 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800467}
468
469TEST_F(OutputTest, setColorTransformPerformsUpdateToIdentity) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700470 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800471
472 // Setting a different colorTransformMatrix should perform the update.
473 CompositionRefreshArgs refreshArgs;
474 refreshArgs.colorTransformMatrix = kIdentity;
475
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700476 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800477
478 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700479 EXPECT_EQ(kIdentity, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800480
481 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700482 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800483}
Lloyd Pique77f79a22019-04-29 15:55:40 -0700484
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800485TEST_F(OutputTest, setColorTransformPerformsUpdateForIdentityToHalf) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700486 mOutput->editState().colorTransformMatrix = kIdentity;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700487
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800488 // Setting a different colorTransformMatrix should perform the update.
489 CompositionRefreshArgs refreshArgs;
490 refreshArgs.colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique77f79a22019-04-29 15:55:40 -0700491
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700492 mOutput->setColorTransform(refreshArgs);
Lloyd Piqueef958122019-02-05 18:00:12 -0800493
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800494 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700495 EXPECT_EQ(kNonIdentityHalf, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800496
497 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700498 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800499}
500
501TEST_F(OutputTest, setColorTransformPerformsUpdateForHalfToQuarter) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700502 mOutput->editState().colorTransformMatrix = kNonIdentityHalf;
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800503
504 // Setting a different colorTransformMatrix should perform the update.
505 CompositionRefreshArgs refreshArgs;
506 refreshArgs.colorTransformMatrix = kNonIdentityQuarter;
507
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700508 mOutput->setColorTransform(refreshArgs);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800509
510 // The internal state should have been updated
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700511 EXPECT_EQ(kNonIdentityQuarter, mOutput->getState().colorTransformMatrix);
Lloyd Pique3eb1b212019-03-07 21:15:40 -0800512
513 // The dirtyRegion should be set to the full display size
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700514 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700515}
516
Lloyd Pique66d68602019-02-13 14:23:31 -0800517/*
Lloyd Pique17ca7422019-11-14 14:24:10 -0800518 * Output::setColorProfile
Lloyd Pique32cbe282018-10-19 13:09:22 -0700519 */
520
Lloyd Pique17ca7422019-11-14 14:24:10 -0800521using OutputSetColorProfileTest = OutputTest;
522
523TEST_F(OutputSetColorProfileTest, setsStateAndDirtiesOutputIfChanged) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800524 using ColorProfile = Output::ColorProfile;
525
Lloyd Piquef5275482019-01-29 18:42:42 -0800526 EXPECT_CALL(*mDisplayColorProfile,
527 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
528 ui::Dataspace::UNKNOWN))
529 .WillOnce(Return(ui::Dataspace::UNKNOWN));
Lloyd Piqueef958122019-02-05 18:00:12 -0800530 EXPECT_CALL(*mRenderSurface, setBufferDataspace(ui::Dataspace::DISPLAY_P3)).Times(1);
Lloyd Pique31cb2942018-10-19 17:23:03 -0700531
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700532 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
533 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
534 ui::Dataspace::UNKNOWN});
Lloyd Pique32cbe282018-10-19 13:09:22 -0700535
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700536 EXPECT_EQ(ui::ColorMode::DISPLAY_P3, mOutput->getState().colorMode);
537 EXPECT_EQ(ui::Dataspace::DISPLAY_P3, mOutput->getState().dataspace);
538 EXPECT_EQ(ui::RenderIntent::TONE_MAP_COLORIMETRIC, mOutput->getState().renderIntent);
539 EXPECT_EQ(ui::Dataspace::UNKNOWN, mOutput->getState().targetDataspace);
Lloyd Piquef5275482019-01-29 18:42:42 -0800540
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700541 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region(kDefaultDisplaySize)));
Lloyd Piqueef958122019-02-05 18:00:12 -0800542}
543
Lloyd Pique17ca7422019-11-14 14:24:10 -0800544TEST_F(OutputSetColorProfileTest, doesNothingIfNoChange) {
Lloyd Pique6a3b4462019-03-07 20:58:12 -0800545 using ColorProfile = Output::ColorProfile;
546
Lloyd Piquef5275482019-01-29 18:42:42 -0800547 EXPECT_CALL(*mDisplayColorProfile,
548 getTargetDataspace(ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
549 ui::Dataspace::UNKNOWN))
550 .WillOnce(Return(ui::Dataspace::UNKNOWN));
551
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700552 mOutput->editState().colorMode = ui::ColorMode::DISPLAY_P3;
553 mOutput->editState().dataspace = ui::Dataspace::DISPLAY_P3;
554 mOutput->editState().renderIntent = ui::RenderIntent::TONE_MAP_COLORIMETRIC;
555 mOutput->editState().targetDataspace = ui::Dataspace::UNKNOWN;
Lloyd Piqueef958122019-02-05 18:00:12 -0800556
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700557 mOutput->setColorProfile(ColorProfile{ui::ColorMode::DISPLAY_P3, ui::Dataspace::DISPLAY_P3,
558 ui::RenderIntent::TONE_MAP_COLORIMETRIC,
559 ui::Dataspace::UNKNOWN});
Lloyd Piqueef958122019-02-05 18:00:12 -0800560
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700561 EXPECT_THAT(mOutput->getState().dirtyRegion, RegionEq(Region()));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700562}
563
Lloyd Pique66d68602019-02-13 14:23:31 -0800564/*
Lloyd Pique31cb2942018-10-19 17:23:03 -0700565 * Output::setRenderSurface()
566 */
567
568TEST_F(OutputTest, setRenderSurfaceResetsBounds) {
569 const ui::Size newDisplaySize{640, 480};
570
571 mock::RenderSurface* renderSurface = new StrictMock<mock::RenderSurface>();
572 EXPECT_CALL(*renderSurface, getSize()).WillOnce(ReturnRef(newDisplaySize));
573
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700574 mOutput->setRenderSurface(std::unique_ptr<RenderSurface>(renderSurface));
Lloyd Pique31cb2942018-10-19 17:23:03 -0700575
Angel Aguayob084e0c2021-08-04 23:27:28 +0000576 EXPECT_EQ(Rect(newDisplaySize), mOutput->getState().framebufferSpace.getBoundsAsRect());
Lloyd Pique31cb2942018-10-19 17:23:03 -0700577}
578
Lloyd Pique66d68602019-02-13 14:23:31 -0800579/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000580 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700581 */
582
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700583TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000584 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000585 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700586 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700587
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700588 // The dirty region should be clipped to the display bounds.
589 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700590}
591
Lloyd Pique66d68602019-02-13 14:23:31 -0800592/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700593 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800594 */
595
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700596TEST_F(OutputTest, layerFiltering) {
597 const ui::LayerStack layerStack1{123u};
598 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800599
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700600 // If the output is associated to layerStack1 and to an internal display...
601 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800602
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700603 // It excludes layers with no layer stack, internal-only or not.
604 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
605 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800606
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700607 // It includes layers on layerStack1, internal-only or not.
608 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
609 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
610 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
611 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800612
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700613 // If the output is associated to layerStack1 but not to an internal display...
614 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800615
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700616 // It includes layers on layerStack1, unless they are internal-only.
617 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
618 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
619 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
620 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800621}
622
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700623TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800624 NonInjectedLayer layer;
625 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800626
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800628 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700629 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800630}
631
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700632TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800633 NonInjectedLayer layer;
634 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800635
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700636 const ui::LayerStack layerStack1{123u};
637 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800638
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700639 // If the output is associated to layerStack1 and to an internal display...
640 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800641
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700642 // It excludes layers with no layer stack, internal-only or not.
643 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
644 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800645
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700646 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
647 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800648
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700649 // It includes layers on layerStack1, internal-only or not.
650 layer.layerFEState.outputFilter = {layerStack1, false};
651 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 layer.layerFEState.outputFilter = {layerStack1, true};
654 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800655
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700656 layer.layerFEState.outputFilter = {layerStack2, true};
657 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800658
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700659 layer.layerFEState.outputFilter = {layerStack2, false};
660 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800661
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700662 // If the output is associated to layerStack1 but not to an internal display...
663 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800664
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700665 // It includes layers on layerStack1, unless they are internal-only.
666 layer.layerFEState.outputFilter = {layerStack1, false};
667 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800668
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700669 layer.layerFEState.outputFilter = {layerStack1, true};
670 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800671
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700672 layer.layerFEState.outputFilter = {layerStack2, true};
673 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800674
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700675 layer.layerFEState.outputFilter = {layerStack2, false};
676 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800677}
678
Lloyd Pique66d68602019-02-13 14:23:31 -0800679/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800680 * Output::getOutputLayerForLayer()
681 */
682
683TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800684 InjectedLayer layer1;
685 InjectedLayer layer2;
686 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800687
Lloyd Piquede196652020-01-22 17:29:58 -0800688 injectOutputLayer(layer1);
689 injectNullOutputLayer();
690 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800691
692 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800693 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
694 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800695
696 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800697 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
698 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
699 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800700
701 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800702 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
703 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
704 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800705}
706
Lloyd Pique66d68602019-02-13 14:23:31 -0800707/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800708 * Output::setReleasedLayers()
709 */
710
711using OutputSetReleasedLayersTest = OutputTest;
712
713TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
714 sp<StrictMock<mock::LayerFE>> layer1FE{new StrictMock<mock::LayerFE>()};
715 sp<StrictMock<mock::LayerFE>> layer2FE{new StrictMock<mock::LayerFE>()};
716 sp<StrictMock<mock::LayerFE>> layer3FE{new StrictMock<mock::LayerFE>()};
717
718 Output::ReleasedLayers layers;
719 layers.push_back(layer1FE);
720 layers.push_back(layer2FE);
721 layers.push_back(layer3FE);
722
723 mOutput->setReleasedLayers(std::move(layers));
724
725 const auto& setLayers = mOutput->getReleasedLayersForTest();
726 ASSERT_EQ(3u, setLayers.size());
727 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
728 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
729 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
730}
731
732/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800733 * Output::updateLayerStateFromFE()
734 */
735
Lloyd Piquede196652020-01-22 17:29:58 -0800736using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800737
738TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
739 CompositionRefreshArgs refreshArgs;
740
741 mOutput->updateLayerStateFromFE(refreshArgs);
742}
743
Lloyd Piquede196652020-01-22 17:29:58 -0800744TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
745 InjectedLayer layer1;
746 InjectedLayer layer2;
747 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800748
Lloyd Piquede196652020-01-22 17:29:58 -0800749 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
750 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
751 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
752
753 injectOutputLayer(layer1);
754 injectOutputLayer(layer2);
755 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800756
757 CompositionRefreshArgs refreshArgs;
758 refreshArgs.updatingGeometryThisFrame = false;
759
760 mOutput->updateLayerStateFromFE(refreshArgs);
761}
762
Lloyd Piquede196652020-01-22 17:29:58 -0800763TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
764 InjectedLayer layer1;
765 InjectedLayer layer2;
766 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800767
Lloyd Piquede196652020-01-22 17:29:58 -0800768 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
769 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
770 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
771
772 injectOutputLayer(layer1);
773 injectOutputLayer(layer2);
774 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800775
776 CompositionRefreshArgs refreshArgs;
777 refreshArgs.updatingGeometryThisFrame = true;
778
779 mOutput->updateLayerStateFromFE(refreshArgs);
780}
781
782/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800783 * Output::updateAndWriteCompositionState()
784 */
785
Lloyd Piquede196652020-01-22 17:29:58 -0800786using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800787
788TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
789 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800790
791 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800792 mOutput->updateCompositionState(args);
793 mOutput->planComposition();
794 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800795}
796
Lloyd Piqueef63b612019-11-14 13:19:56 -0800797TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800798 InjectedLayer layer1;
799 InjectedLayer layer2;
800 InjectedLayer layer3;
801
Lloyd Piqueef63b612019-11-14 13:19:56 -0800802 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800803
Lloyd Piquede196652020-01-22 17:29:58 -0800804 injectOutputLayer(layer1);
805 injectOutputLayer(layer2);
806 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800807
808 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800809 mOutput->updateCompositionState(args);
810 mOutput->planComposition();
811 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800812}
813
814TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800815 InjectedLayer layer1;
816 InjectedLayer layer2;
817 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800818
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400819 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200820 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800821 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400822 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
823 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200824 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800825 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400826 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
827 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200828 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800829 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400830 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
831 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800832
833 injectOutputLayer(layer1);
834 injectOutputLayer(layer2);
835 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800836
837 mOutput->editState().isEnabled = true;
838
839 CompositionRefreshArgs args;
840 args.updatingGeometryThisFrame = false;
841 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200842 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800843 mOutput->updateCompositionState(args);
844 mOutput->planComposition();
845 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800846}
847
848TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800849 InjectedLayer layer1;
850 InjectedLayer layer2;
851 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800852
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400853 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200854 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800855 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400856 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
857 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200858 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800859 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400860 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
861 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200862 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800863 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400864 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
865 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800866
867 injectOutputLayer(layer1);
868 injectOutputLayer(layer2);
869 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800870
871 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800872
873 CompositionRefreshArgs args;
874 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800875 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800876 mOutput->updateCompositionState(args);
877 mOutput->planComposition();
878 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800879}
880
881TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800882 InjectedLayer layer1;
883 InjectedLayer layer2;
884 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800885
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400886 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200887 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800888 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400889 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
890 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200891 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800892 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400893 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
894 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200895 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800896 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400897 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
898 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800899
900 injectOutputLayer(layer1);
901 injectOutputLayer(layer2);
902 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800903
904 mOutput->editState().isEnabled = true;
905
906 CompositionRefreshArgs args;
907 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800908 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800909 mOutput->updateCompositionState(args);
910 mOutput->planComposition();
911 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800912}
913
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400914TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
915 renderengine::mock::RenderEngine renderEngine;
916 InjectedLayer layer0;
917 InjectedLayer layer1;
918 InjectedLayer layer2;
919 InjectedLayer layer3;
920
921 InSequence seq;
922 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
923 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
924 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
925 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
926
927 uint32_t z = 0;
928 EXPECT_CALL(*layer0.outputLayer,
929 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
930 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
931
932 // After calling planComposition (which clears overrideInfo), this test sets
933 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
934 // comes first, setting isPeekingThrough to true and zIsOverridden to true
935 // for it and the following layers.
936 EXPECT_CALL(*layer3.outputLayer,
937 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
938 /*zIsOverridden*/ true, /*isPeekingThrough*/
939 true));
940 EXPECT_CALL(*layer1.outputLayer,
941 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
942 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
943 EXPECT_CALL(*layer2.outputLayer,
944 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
945 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
946
947 injectOutputLayer(layer0);
948 injectOutputLayer(layer1);
949 injectOutputLayer(layer2);
950 injectOutputLayer(layer3);
951
952 mOutput->editState().isEnabled = true;
953
954 CompositionRefreshArgs args;
955 args.updatingGeometryThisFrame = true;
956 args.devOptForceClientComposition = false;
957 mOutput->updateCompositionState(args);
958 mOutput->planComposition();
959
960 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800961 renderengine::impl::
962 ExternalTexture>(new GraphicBuffer(), renderEngine,
963 renderengine::impl::ExternalTexture::Usage::READABLE |
964 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400965 layer1.outputLayerState.overrideInfo.buffer = buffer;
966 layer2.outputLayerState.overrideInfo.buffer = buffer;
967 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
968 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
969
970 mOutput->writeCompositionState(args);
971}
972
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800973/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800974 * Output::prepareFrame()
975 */
976
977struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800978 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800979 // Sets up the helper functions called by the function under test to use
980 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800981 MOCK_METHOD0(chooseCompositionStrategy, void());
982 };
983
984 OutputPrepareFrameTest() {
985 mOutput.setDisplayColorProfileForTest(
986 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
987 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
988 }
989
990 StrictMock<mock::CompositionEngine> mCompositionEngine;
991 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
992 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700993 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -0800994};
995
996TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
997 mOutput.editState().isEnabled = false;
998
999 mOutput.prepareFrame();
1000}
1001
1002TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1003 mOutput.editState().isEnabled = true;
1004 mOutput.editState().usesClientComposition = false;
1005 mOutput.editState().usesDeviceComposition = true;
1006
1007 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001008 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001009 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1010
1011 mOutput.prepareFrame();
1012}
1013
1014// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1015// base chooseCompositionStrategy() is invoked.
1016TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001017 mOutput->editState().isEnabled = true;
1018 mOutput->editState().usesClientComposition = false;
1019 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001020
1021 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1022
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001023 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001024
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001025 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1026 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001027}
1028
Lloyd Pique56eba802019-08-28 15:45:25 -07001029/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001030 * Output::prepare()
1031 */
1032
1033struct OutputPrepareTest : public testing::Test {
1034 struct OutputPartialMock : public OutputPartialMockBase {
1035 // Sets up the helper functions called by the function under test to use
1036 // mock implementations.
1037 MOCK_METHOD2(rebuildLayerStacks,
1038 void(const compositionengine::CompositionRefreshArgs&,
1039 compositionengine::LayerFESet&));
1040 };
1041
1042 StrictMock<OutputPartialMock> mOutput;
1043 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001044 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001045};
1046
1047TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1048 InSequence seq;
1049 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1050
1051 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1052}
1053
1054/*
1055 * Output::rebuildLayerStacks()
1056 */
1057
1058struct OutputRebuildLayerStacksTest : public testing::Test {
1059 struct OutputPartialMock : public OutputPartialMockBase {
1060 // Sets up the helper functions called by the function under test to use
1061 // mock implementations.
1062 MOCK_METHOD2(collectVisibleLayers,
1063 void(const compositionengine::CompositionRefreshArgs&,
1064 compositionengine::Output::CoverageState&));
1065 };
1066
1067 OutputRebuildLayerStacksTest() {
1068 mOutput.mState.isEnabled = true;
1069 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001070 mOutput.mState.displaySpace.setBounds(
1071 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001072
1073 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1074
1075 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1076
1077 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1078 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1079 }
1080
1081 void setTestCoverageValues(const CompositionRefreshArgs&,
1082 compositionengine::Output::CoverageState& state) {
1083 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1084 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1085 state.dirtyRegion = mCoverageDirtyRegionToSet;
1086 }
1087
1088 static const ui::Transform kIdentityTransform;
1089 static const ui::Transform kRotate90Transform;
1090 static const Rect kOutputBounds;
1091
1092 StrictMock<OutputPartialMock> mOutput;
1093 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001094 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001095 Region mCoverageAboveCoveredLayersToSet;
1096 Region mCoverageAboveOpaqueLayersToSet;
1097 Region mCoverageDirtyRegionToSet;
1098};
1099
1100const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1101const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1102const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1103
1104TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1105 mOutput.mState.isEnabled = false;
1106
1107 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1108}
1109
1110TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1111 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1112
1113 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1114}
1115
1116TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1117 mOutput.mState.transform = kIdentityTransform;
1118
1119 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1120
1121 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1122
1123 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1124}
1125
1126TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1127 mOutput.mState.transform = kIdentityTransform;
1128
1129 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1130
1131 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1132
1133 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1134}
1135
1136TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1137 mOutput.mState.transform = kRotate90Transform;
1138
1139 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1140
1141 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1142
1143 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1144}
1145
1146TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1147 mOutput.mState.transform = kRotate90Transform;
1148
1149 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1150
1151 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1152
1153 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1154}
1155
1156TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1157 mOutput.mState.transform = kIdentityTransform;
1158 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1159
1160 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1161
1162 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1163
1164 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1165}
1166
1167TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1168 mOutput.mState.transform = kRotate90Transform;
1169 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1170
1171 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1172
1173 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1174
1175 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1176}
1177
1178/*
1179 * Output::collectVisibleLayers()
1180 */
1181
Lloyd Pique1ef93222019-11-21 16:41:53 -08001182struct OutputCollectVisibleLayersTest : public testing::Test {
1183 struct OutputPartialMock : public OutputPartialMockBase {
1184 // Sets up the helper functions called by the function under test to use
1185 // mock implementations.
1186 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001187 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001188 compositionengine::Output::CoverageState&));
1189 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1190 MOCK_METHOD0(finalizePendingOutputLayers, void());
1191 };
1192
1193 struct Layer {
1194 Layer() {
1195 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1196 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1197 }
1198
1199 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001200 impl::OutputLayerCompositionState outputLayerState;
Lloyd Piquede196652020-01-22 17:29:58 -08001201 sp<StrictMock<mock::LayerFE>> layerFE{new StrictMock<mock::LayerFE>()};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001202 };
1203
1204 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001205 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001206 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1207 .WillRepeatedly(Return(&mLayer1.outputLayer));
1208 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1209 .WillRepeatedly(Return(&mLayer2.outputLayer));
1210 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1211 .WillRepeatedly(Return(&mLayer3.outputLayer));
1212
Lloyd Piquede196652020-01-22 17:29:58 -08001213 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1214 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1215 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001216 }
1217
1218 StrictMock<OutputPartialMock> mOutput;
1219 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001220 LayerFESet mGeomSnapshots;
1221 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001222 Layer mLayer1;
1223 Layer mLayer2;
1224 Layer mLayer3;
1225};
1226
1227TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1228 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001229 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001230
1231 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1232 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1233
1234 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1235}
1236
1237TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1238 // Enforce a call order sequence for this test.
1239 InSequence seq;
1240
1241 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001242 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1243 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1244 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001245
1246 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1247 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1248
1249 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001250}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001251
1252/*
1253 * Output::ensureOutputLayerIfVisible()
1254 */
1255
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001256struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1257 struct OutputPartialMock : public OutputPartialMockBase {
1258 // Sets up the helper functions called by the function under test to use
1259 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001260 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1261 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001262 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001263 MOCK_METHOD2(ensureOutputLayer,
1264 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001265 };
1266
1267 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001268 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001269 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001270 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001271 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001272 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273
Angel Aguayob084e0c2021-08-04 23:27:28 +00001274 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1275 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001276 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1277
Lloyd Piquede196652020-01-22 17:29:58 -08001278 mLayer.layerFEState.isVisible = true;
1279 mLayer.layerFEState.isOpaque = true;
1280 mLayer.layerFEState.contentDirty = true;
1281 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1282 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
1283 mLayer.layerFEState.transparentRegionHint = Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284
Lloyd Piquede196652020-01-22 17:29:58 -08001285 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1286 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001287
Lloyd Piquede196652020-01-22 17:29:58 -08001288 mGeomSnapshots.insert(mLayer.layerFE);
1289 }
1290
1291 void ensureOutputLayerIfVisible() {
1292 sp<LayerFE> layerFE(mLayer.layerFE);
1293 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001294 }
1295
1296 static const Region kEmptyRegion;
1297 static const Region kFullBoundsNoRotation;
1298 static const Region kRightHalfBoundsNoRotation;
1299 static const Region kLowerHalfBoundsNoRotation;
1300 static const Region kFullBounds90Rotation;
1301
1302 StrictMock<OutputPartialMock> mOutput;
1303 LayerFESet mGeomSnapshots;
1304 Output::CoverageState mCoverageState{mGeomSnapshots};
1305
Lloyd Piquede196652020-01-22 17:29:58 -08001306 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001307};
1308
1309const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1310const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1311 Region(Rect(0, 0, 100, 200));
1312const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1313 Region(Rect(0, 100, 100, 200));
1314const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1315 Region(Rect(50, 0, 100, 200));
1316const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1317 Region(Rect(0, 0, 200, 100));
1318
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001319TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1320 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001321 EXPECT_CALL(*mLayer.layerFE,
1322 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001323
1324 mGeomSnapshots.clear();
1325
Lloyd Piquede196652020-01-22 17:29:58 -08001326 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001327}
1328
1329TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001330 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1331 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332
Lloyd Piquede196652020-01-22 17:29:58 -08001333 ensureOutputLayerIfVisible();
1334}
1335
1336TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1337 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1338
1339 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340}
1341
1342TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001343 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001344
Lloyd Piquede196652020-01-22 17:29:58 -08001345 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346}
1347
1348TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001349 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001350
Lloyd Piquede196652020-01-22 17:29:58 -08001351 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001352}
1353
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001354TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001355 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001356
Lloyd Piquede196652020-01-22 17:29:58 -08001357 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358}
1359
1360TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1361 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001362 mLayer.layerFEState.isOpaque = true;
1363 mLayer.layerFEState.contentDirty = true;
1364 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001365
1366 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001367 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1368 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001369
Lloyd Piquede196652020-01-22 17:29:58 -08001370 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001371
1372 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1373 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1374 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1375
Lloyd Piquede196652020-01-22 17:29:58 -08001376 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1377 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1378 RegionEq(kFullBoundsNoRotation));
1379 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1380 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001381}
1382
1383TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1384 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001385 mLayer.layerFEState.isOpaque = true;
1386 mLayer.layerFEState.contentDirty = true;
1387 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001388
Lloyd Piquede196652020-01-22 17:29:58 -08001389 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1390 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001391
Lloyd Piquede196652020-01-22 17:29:58 -08001392 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001393
1394 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1395 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1396 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1397
Lloyd Piquede196652020-01-22 17:29:58 -08001398 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1399 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1400 RegionEq(kFullBoundsNoRotation));
1401 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1402 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001403}
1404
1405TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1406 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001407 mLayer.layerFEState.isOpaque = false;
1408 mLayer.layerFEState.contentDirty = true;
1409 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410
1411 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001412 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1413 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001414
Lloyd Piquede196652020-01-22 17:29:58 -08001415 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001416
1417 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1418 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1419 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1420
Lloyd Piquede196652020-01-22 17:29:58 -08001421 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1422 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001423 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001424 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1425 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001426}
1427
1428TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1429 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001430 mLayer.layerFEState.isOpaque = false;
1431 mLayer.layerFEState.contentDirty = true;
1432 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433
Lloyd Piquede196652020-01-22 17:29:58 -08001434 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1435 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001436
Lloyd Piquede196652020-01-22 17:29:58 -08001437 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001438
1439 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1440 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1441 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1442
Lloyd Piquede196652020-01-22 17:29:58 -08001443 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1444 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001445 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001446 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1447 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001448}
1449
1450TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1451 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001452 mLayer.layerFEState.isOpaque = true;
1453 mLayer.layerFEState.contentDirty = false;
1454 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001455
1456 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001457 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1458 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459
Lloyd Piquede196652020-01-22 17:29:58 -08001460 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001461
1462 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1463 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1464 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1465
Lloyd Piquede196652020-01-22 17:29:58 -08001466 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1467 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1468 RegionEq(kFullBoundsNoRotation));
1469 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1470 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001471}
1472
1473TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1474 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001475 mLayer.layerFEState.isOpaque = true;
1476 mLayer.layerFEState.contentDirty = false;
1477 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001478
Lloyd Piquede196652020-01-22 17:29:58 -08001479 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1480 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001481
Lloyd Piquede196652020-01-22 17:29:58 -08001482 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001483
1484 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1485 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1486 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1487
Lloyd Piquede196652020-01-22 17:29:58 -08001488 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1489 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1490 RegionEq(kFullBoundsNoRotation));
1491 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1492 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001493}
1494
1495TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1496 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001497 mLayer.layerFEState.isOpaque = true;
1498 mLayer.layerFEState.contentDirty = true;
1499 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1500 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1501 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1502 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001503
1504 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001505 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1506 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001507
Lloyd Piquede196652020-01-22 17:29:58 -08001508 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001509
1510 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1511 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1512 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1513
Lloyd Piquede196652020-01-22 17:29:58 -08001514 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1515 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1516 RegionEq(kFullBoundsNoRotation));
1517 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1518 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001519}
1520
1521TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1522 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001523 mLayer.layerFEState.isOpaque = true;
1524 mLayer.layerFEState.contentDirty = true;
1525 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1526 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1527 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1528 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001529
Lloyd Piquede196652020-01-22 17:29:58 -08001530 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1531 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001532
Lloyd Piquede196652020-01-22 17:29:58 -08001533 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001534
1535 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1536 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1537 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1538
Lloyd Piquede196652020-01-22 17:29:58 -08001539 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1540 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1541 RegionEq(kFullBoundsNoRotation));
1542 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1543 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001544}
1545
1546TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1547 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001548 mLayer.layerFEState.isOpaque = true;
1549 mLayer.layerFEState.contentDirty = true;
1550 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001551
Angel Aguayob084e0c2021-08-04 23:27:28 +00001552 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001553 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1554
1555 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001556 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1557 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558
Lloyd Piquede196652020-01-22 17:29:58 -08001559 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001560
1561 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1562 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1563 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1564
Lloyd Piquede196652020-01-22 17:29:58 -08001565 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1566 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1567 RegionEq(kFullBoundsNoRotation));
1568 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1569 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570}
1571
1572TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1573 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001574 mLayer.layerFEState.isOpaque = true;
1575 mLayer.layerFEState.contentDirty = true;
1576 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001577
Angel Aguayob084e0c2021-08-04 23:27:28 +00001578 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001579 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1580
Lloyd Piquede196652020-01-22 17:29:58 -08001581 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1582 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001583
Lloyd Piquede196652020-01-22 17:29:58 -08001584 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001585
1586 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1587 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1588 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1589
Lloyd Piquede196652020-01-22 17:29:58 -08001590 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1591 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1592 RegionEq(kFullBoundsNoRotation));
1593 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1594 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001595}
1596
1597TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1598 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1599 ui::Transform arbitraryTransform;
1600 arbitraryTransform.set(1, 1, -1, 1);
1601 arbitraryTransform.set(0, 100);
1602
Lloyd Piquede196652020-01-22 17:29:58 -08001603 mLayer.layerFEState.isOpaque = true;
1604 mLayer.layerFEState.contentDirty = true;
1605 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1606 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001607
1608 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001609 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1610 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001611
Lloyd Piquede196652020-01-22 17:29:58 -08001612 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001613
1614 const Region kRegion = Region(Rect(0, 0, 300, 300));
1615 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1616
1617 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1618 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1619 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1620
Lloyd Piquede196652020-01-22 17:29:58 -08001621 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1622 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1623 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1624 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625}
1626
1627TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001628 mLayer.layerFEState.isOpaque = false;
1629 mLayer.layerFEState.contentDirty = true;
1630 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001631
1632 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1633 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1634 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1635
Lloyd Piquede196652020-01-22 17:29:58 -08001636 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1637 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001638
Lloyd Piquede196652020-01-22 17:29:58 -08001639 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001640
1641 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1642 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1643 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1644 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1645 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1646 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1647
1648 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1649 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1650 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1651
Lloyd Piquede196652020-01-22 17:29:58 -08001652 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1653 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001655 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1656 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1657 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001658}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001659
Vishnu Naira483b4a2019-12-12 15:07:52 -08001660TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1661 ui::Transform translate;
1662 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001663 mLayer.layerFEState.geomLayerTransform = translate;
1664 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001665
1666 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1667 // half of the layer including the casting shadow is covered and opaque
1668 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1669 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1670
Lloyd Piquede196652020-01-22 17:29:58 -08001671 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1672 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001673
Lloyd Piquede196652020-01-22 17:29:58 -08001674 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001675
1676 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1677 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1678 // add starting opaque region to the opaque half of the casting layer bounds
1679 const Region kExpectedAboveOpaqueRegion =
1680 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1681 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1682 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1683 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1684 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1685 const Region kExpectedLayerShadowRegion =
1686 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1687
1688 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1689 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1690 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1691
Lloyd Piquede196652020-01-22 17:29:58 -08001692 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1693 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001694 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001695 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1696 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001697 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001698 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001699 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1700}
1701
1702TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1703 ui::Transform translate;
1704 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001705 mLayer.layerFEState.geomLayerTransform = translate;
1706 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001707
1708 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1709 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1710 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1711 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1712
Lloyd Piquede196652020-01-22 17:29:58 -08001713 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1714 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001715
Lloyd Piquede196652020-01-22 17:29:58 -08001716 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001717
1718 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1719 const Region kExpectedLayerShadowRegion =
1720 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1721
Lloyd Piquede196652020-01-22 17:29:58 -08001722 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1723 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001724 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1725}
1726
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001727TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001728 ui::Transform translate;
1729 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001730 mLayer.layerFEState.geomLayerTransform = translate;
1731 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001732
1733 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1734 // Casting layer and its shadows are covered by an opaque region
1735 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1736 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1737
Lloyd Piquede196652020-01-22 17:29:58 -08001738 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001739}
1740
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001741/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001742 * Output::present()
1743 */
1744
1745struct OutputPresentTest : public testing::Test {
1746 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001747 // Sets up the helper functions called by the function under test to use
1748 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001749 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001750 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001751 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001752 MOCK_METHOD0(planComposition, void());
1753 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001754 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1755 MOCK_METHOD0(beginFrame, void());
1756 MOCK_METHOD0(prepareFrame, void());
1757 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1758 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1759 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001760 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001761 };
1762
1763 StrictMock<OutputPartialMock> mOutput;
1764};
1765
1766TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1767 CompositionRefreshArgs args;
1768
1769 InSequence seq;
1770 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001771 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1772 EXPECT_CALL(mOutput, planComposition());
1773 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001774 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1775 EXPECT_CALL(mOutput, beginFrame());
1776 EXPECT_CALL(mOutput, prepareFrame());
1777 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1778 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1779 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001780 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001781
1782 mOutput.present(args);
1783}
1784
1785/*
1786 * Output::updateColorProfile()
1787 */
1788
Lloyd Pique17ca7422019-11-14 14:24:10 -08001789struct OutputUpdateColorProfileTest : public testing::Test {
1790 using TestType = OutputUpdateColorProfileTest;
1791
1792 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001793 // Sets up the helper functions called by the function under test to use
1794 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001795 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1796 };
1797
1798 struct Layer {
1799 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001800 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1801 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001802 }
1803
1804 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001805 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001806 LayerFECompositionState mLayerFEState;
1807 };
1808
1809 OutputUpdateColorProfileTest() {
1810 mOutput.setDisplayColorProfileForTest(
1811 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1812 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1813
1814 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1815 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1816 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1817 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1818 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1819 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1820 }
1821
1822 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1823 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1824 };
1825
1826 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1827 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1828 StrictMock<OutputPartialMock> mOutput;
1829
1830 Layer mLayer1;
1831 Layer mLayer2;
1832 Layer mLayer3;
1833
1834 CompositionRefreshArgs mRefreshArgs;
1835};
1836
1837// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1838// to make it easier to write unit tests.
1839
1840TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1841 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1842 // a simple default color profile without looking at anything else.
1843
Lloyd Pique0a456232020-01-16 17:51:13 -08001844 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001845 EXPECT_CALL(mOutput,
1846 setColorProfile(ColorProfileEq(
1847 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1848 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1849
1850 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1851 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1852
1853 mOutput.updateColorProfile(mRefreshArgs);
1854}
1855
1856struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1857 : public OutputUpdateColorProfileTest {
1858 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001859 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001860 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1861 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1862 }
1863
1864 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1865 : public CallOrderStateMachineHelper<
1866 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1867 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1868 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1869 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1870 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1871 _))
1872 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1873 SetArgPointee<4>(renderIntent)));
1874 EXPECT_CALL(getInstance()->mOutput,
1875 setColorProfile(
1876 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1877 ui::Dataspace::UNKNOWN})));
1878 return nextState<ExecuteState>();
1879 }
1880 };
1881
1882 // Call this member function to start using the mini-DSL defined above.
1883 [[nodiscard]] auto verify() {
1884 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1885 }
1886};
1887
1888TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1889 Native_Unknown_Colorimetric_Set) {
1890 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1891 ui::Dataspace::UNKNOWN,
1892 ui::RenderIntent::COLORIMETRIC)
1893 .execute();
1894}
1895
1896TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1897 DisplayP3_DisplayP3_Enhance_Set) {
1898 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1899 ui::Dataspace::DISPLAY_P3,
1900 ui::RenderIntent::ENHANCE)
1901 .execute();
1902}
1903
1904struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1905 : public OutputUpdateColorProfileTest {
1906 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001907 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001908 EXPECT_CALL(*mDisplayColorProfile,
1909 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1910 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1911 SetArgPointee<3>(ui::ColorMode::NATIVE),
1912 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1913 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1914 }
1915
1916 struct IfColorSpaceAgnosticDataspaceSetToState
1917 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1918 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1919 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1920 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1921 }
1922 };
1923
1924 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1925 : public CallOrderStateMachineHelper<
1926 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1927 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1928 ui::Dataspace dataspace) {
1929 EXPECT_CALL(getInstance()->mOutput,
1930 setColorProfile(ColorProfileEq(
1931 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1932 ui::RenderIntent::COLORIMETRIC, dataspace})));
1933 return nextState<ExecuteState>();
1934 }
1935 };
1936
1937 // Call this member function to start using the mini-DSL defined above.
1938 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1939};
1940
1941TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1942 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1943 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1944 .execute();
1945}
1946
1947TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1948 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1949 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1950 .execute();
1951}
1952
1953struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1954 : public OutputUpdateColorProfileTest {
1955 // Internally the implementation looks through the dataspaces of all the
1956 // visible layers. The topmost one that also has an actual dataspace
1957 // preference set is used to drive subsequent choices.
1958
1959 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
1960 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1961 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1962
Lloyd Pique0a456232020-01-16 17:51:13 -08001963 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001964 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
1965 }
1966
1967 struct IfTopLayerDataspaceState
1968 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
1969 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
1970 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
1971 return nextState<AndIfMiddleLayerDataspaceState>();
1972 }
1973 [[nodiscard]] auto ifTopLayerHasNoPreference() {
1974 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
1975 }
1976 };
1977
1978 struct AndIfMiddleLayerDataspaceState
1979 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
1980 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
1981 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
1982 return nextState<AndIfBottomLayerDataspaceState>();
1983 }
1984 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
1985 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
1986 }
1987 };
1988
1989 struct AndIfBottomLayerDataspaceState
1990 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
1991 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
1992 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
1993 return nextState<ThenExpectBestColorModeCallUsesState>();
1994 }
1995 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
1996 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
1997 }
1998 };
1999
2000 struct ThenExpectBestColorModeCallUsesState
2001 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2002 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2003 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2004 getBestColorMode(dataspace, _, _, _, _));
2005 return nextState<ExecuteState>();
2006 }
2007 };
2008
2009 // Call this member function to start using the mini-DSL defined above.
2010 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2011};
2012
2013TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2014 noStrongLayerPrefenceUses_V0_SRGB) {
2015 // If none of the layers indicate a preference, then V0_SRGB is the
2016 // preferred choice (subject to additional checks).
2017 verify().ifTopLayerHasNoPreference()
2018 .andIfMiddleLayerHasNoPreference()
2019 .andIfBottomLayerHasNoPreference()
2020 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2021 .execute();
2022}
2023
2024TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2025 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2026 // If only the topmost layer has a preference, then that is what is chosen.
2027 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2028 .andIfMiddleLayerHasNoPreference()
2029 .andIfBottomLayerHasNoPreference()
2030 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2031 .execute();
2032}
2033
2034TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2035 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2036 // If only the middle layer has a preference, that that is what is chosen.
2037 verify().ifTopLayerHasNoPreference()
2038 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2039 .andIfBottomLayerHasNoPreference()
2040 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2041 .execute();
2042}
2043
2044TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2045 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2046 // If only the middle layer has a preference, that that is what is chosen.
2047 verify().ifTopLayerHasNoPreference()
2048 .andIfMiddleLayerHasNoPreference()
2049 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2050 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2051 .execute();
2052}
2053
2054TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2055 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2056 // If multiple layers have a preference, the topmost value is what is used.
2057 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2058 .andIfMiddleLayerHasNoPreference()
2059 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2060 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2061 .execute();
2062}
2063
2064TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2065 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2066 // If multiple layers have a preference, the topmost value is what is used.
2067 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2068 .andIfMiddleLayerHasNoPreference()
2069 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2070 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2071 .execute();
2072}
2073
2074struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2075 : public OutputUpdateColorProfileTest {
2076 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2077 // values, it overrides the layer dataspace choice.
2078
2079 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2080 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2081 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2082
2083 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2084
Lloyd Pique0a456232020-01-16 17:51:13 -08002085 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002086 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2087 }
2088
2089 struct IfForceOutputColorModeState
2090 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2091 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2092 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2093 return nextState<ThenExpectBestColorModeCallUsesState>();
2094 }
2095 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2096 };
2097
2098 struct ThenExpectBestColorModeCallUsesState
2099 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2100 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2101 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2102 getBestColorMode(dataspace, _, _, _, _));
2103 return nextState<ExecuteState>();
2104 }
2105 };
2106
2107 // Call this member function to start using the mini-DSL defined above.
2108 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2109};
2110
2111TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2112 // By default the layer state is used to set the preferred dataspace
2113 verify().ifNoOverride()
2114 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2115 .execute();
2116}
2117
2118TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2119 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2120 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2121 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2122 .execute();
2123}
2124
2125TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2126 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2127 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2128 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2129 .execute();
2130}
2131
2132// HDR output requires all layers to be compatible with the chosen HDR
2133// dataspace, along with there being proper support.
2134struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2135 OutputUpdateColorProfileTest_Hdr() {
2136 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2137 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002138 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002139 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2140 }
2141
2142 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2143 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2144 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2145 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2146
2147 struct IfTopLayerDataspaceState
2148 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2149 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2150 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2151 return nextState<AndTopLayerCompositionTypeState>();
2152 }
2153 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2154 };
2155
2156 struct AndTopLayerCompositionTypeState
2157 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2158 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2159 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2160 return nextState<AndIfBottomLayerDataspaceState>();
2161 }
2162 };
2163
2164 struct AndIfBottomLayerDataspaceState
2165 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2166 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2167 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2168 return nextState<AndBottomLayerCompositionTypeState>();
2169 }
2170 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2171 return andIfBottomLayerIs(kNonHdrDataspace);
2172 }
2173 };
2174
2175 struct AndBottomLayerCompositionTypeState
2176 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2177 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2178 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2179 return nextState<AndIfHasLegacySupportState>();
2180 }
2181 };
2182
2183 struct AndIfHasLegacySupportState
2184 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2185 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2186 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2187 .WillOnce(Return(legacySupport));
2188 return nextState<ThenExpectBestColorModeCallUsesState>();
2189 }
2190 };
2191
2192 struct ThenExpectBestColorModeCallUsesState
2193 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2194 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2195 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2196 getBestColorMode(dataspace, _, _, _, _));
2197 return nextState<ExecuteState>();
2198 }
2199 };
2200
2201 // Call this member function to start using the mini-DSL defined above.
2202 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2203};
2204
2205TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2206 // If all layers use BT2020_PQ, and there are no other special conditions,
2207 // BT2020_PQ is used.
2208 verify().ifTopLayerIs(BT2020_PQ)
2209 .andTopLayerIsREComposed(false)
2210 .andIfBottomLayerIs(BT2020_PQ)
2211 .andBottomLayerIsREComposed(false)
2212 .andIfLegacySupportFor(BT2020_PQ, false)
2213 .thenExpectBestColorModeCallUses(BT2020_PQ)
2214 .execute();
2215}
2216
2217TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2218 // BT2020_PQ is not used if there is only legacy support for it.
2219 verify().ifTopLayerIs(BT2020_PQ)
2220 .andTopLayerIsREComposed(false)
2221 .andIfBottomLayerIs(BT2020_PQ)
2222 .andBottomLayerIsREComposed(false)
2223 .andIfLegacySupportFor(BT2020_PQ, true)
2224 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2225 .execute();
2226}
2227
2228TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2229 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2230 verify().ifTopLayerIs(BT2020_PQ)
2231 .andTopLayerIsREComposed(false)
2232 .andIfBottomLayerIs(BT2020_PQ)
2233 .andBottomLayerIsREComposed(true)
2234 .andIfLegacySupportFor(BT2020_PQ, false)
2235 .thenExpectBestColorModeCallUses(BT2020_PQ)
2236 .execute();
2237}
2238
2239TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2240 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2241 verify().ifTopLayerIs(BT2020_PQ)
2242 .andTopLayerIsREComposed(true)
2243 .andIfBottomLayerIs(BT2020_PQ)
2244 .andBottomLayerIsREComposed(false)
2245 .andIfLegacySupportFor(BT2020_PQ, false)
2246 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2247 .execute();
2248}
2249
2250TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2251 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2252 // are no other special conditions.
2253 verify().ifTopLayerIs(BT2020_PQ)
2254 .andTopLayerIsREComposed(false)
2255 .andIfBottomLayerIs(BT2020_HLG)
2256 .andBottomLayerIsREComposed(false)
2257 .andIfLegacySupportFor(BT2020_PQ, false)
2258 .thenExpectBestColorModeCallUses(BT2020_PQ)
2259 .execute();
2260}
2261
2262TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2263 // BT2020_PQ is not used if there is only legacy support for it.
2264 verify().ifTopLayerIs(BT2020_PQ)
2265 .andTopLayerIsREComposed(false)
2266 .andIfBottomLayerIs(BT2020_HLG)
2267 .andBottomLayerIsREComposed(false)
2268 .andIfLegacySupportFor(BT2020_PQ, true)
2269 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2270 .execute();
2271}
2272
2273TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2274 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2275 verify().ifTopLayerIs(BT2020_PQ)
2276 .andTopLayerIsREComposed(false)
2277 .andIfBottomLayerIs(BT2020_HLG)
2278 .andBottomLayerIsREComposed(true)
2279 .andIfLegacySupportFor(BT2020_PQ, false)
2280 .thenExpectBestColorModeCallUses(BT2020_PQ)
2281 .execute();
2282}
2283
2284TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2285 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2286 verify().ifTopLayerIs(BT2020_PQ)
2287 .andTopLayerIsREComposed(true)
2288 .andIfBottomLayerIs(BT2020_HLG)
2289 .andBottomLayerIsREComposed(false)
2290 .andIfLegacySupportFor(BT2020_PQ, false)
2291 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2292 .execute();
2293}
2294
2295TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2296 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2297 // used if there are no other special conditions.
2298 verify().ifTopLayerIs(BT2020_HLG)
2299 .andTopLayerIsREComposed(false)
2300 .andIfBottomLayerIs(BT2020_PQ)
2301 .andBottomLayerIsREComposed(false)
2302 .andIfLegacySupportFor(BT2020_PQ, false)
2303 .thenExpectBestColorModeCallUses(BT2020_PQ)
2304 .execute();
2305}
2306
2307TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2308 // BT2020_PQ is not used if there is only legacy support for it.
2309 verify().ifTopLayerIs(BT2020_HLG)
2310 .andTopLayerIsREComposed(false)
2311 .andIfBottomLayerIs(BT2020_PQ)
2312 .andBottomLayerIsREComposed(false)
2313 .andIfLegacySupportFor(BT2020_PQ, true)
2314 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2315 .execute();
2316}
2317
2318TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2319 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2320 verify().ifTopLayerIs(BT2020_HLG)
2321 .andTopLayerIsREComposed(false)
2322 .andIfBottomLayerIs(BT2020_PQ)
2323 .andBottomLayerIsREComposed(true)
2324 .andIfLegacySupportFor(BT2020_PQ, false)
2325 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2326 .execute();
2327}
2328
2329TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2330 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2331 verify().ifTopLayerIs(BT2020_HLG)
2332 .andTopLayerIsREComposed(true)
2333 .andIfBottomLayerIs(BT2020_PQ)
2334 .andBottomLayerIsREComposed(false)
2335 .andIfLegacySupportFor(BT2020_PQ, false)
2336 .thenExpectBestColorModeCallUses(BT2020_PQ)
2337 .execute();
2338}
2339
2340TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2341 // If all layers use HLG then HLG is used if there are no other special
2342 // conditions.
2343 verify().ifTopLayerIs(BT2020_HLG)
2344 .andTopLayerIsREComposed(false)
2345 .andIfBottomLayerIs(BT2020_HLG)
2346 .andBottomLayerIsREComposed(false)
2347 .andIfLegacySupportFor(BT2020_HLG, false)
2348 .thenExpectBestColorModeCallUses(BT2020_HLG)
2349 .execute();
2350}
2351
2352TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2353 // BT2020_HLG is not used if there is legacy support for it.
2354 verify().ifTopLayerIs(BT2020_HLG)
2355 .andTopLayerIsREComposed(false)
2356 .andIfBottomLayerIs(BT2020_HLG)
2357 .andBottomLayerIsREComposed(false)
2358 .andIfLegacySupportFor(BT2020_HLG, true)
2359 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2360 .execute();
2361}
2362
2363TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2364 // BT2020_HLG is used even if the bottom layer is client composed.
2365 verify().ifTopLayerIs(BT2020_HLG)
2366 .andTopLayerIsREComposed(false)
2367 .andIfBottomLayerIs(BT2020_HLG)
2368 .andBottomLayerIsREComposed(true)
2369 .andIfLegacySupportFor(BT2020_HLG, false)
2370 .thenExpectBestColorModeCallUses(BT2020_HLG)
2371 .execute();
2372}
2373
2374TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2375 // BT2020_HLG is used even if the top layer is client composed.
2376 verify().ifTopLayerIs(BT2020_HLG)
2377 .andTopLayerIsREComposed(true)
2378 .andIfBottomLayerIs(BT2020_HLG)
2379 .andBottomLayerIsREComposed(false)
2380 .andIfLegacySupportFor(BT2020_HLG, false)
2381 .thenExpectBestColorModeCallUses(BT2020_HLG)
2382 .execute();
2383}
2384
2385TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2386 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2387 verify().ifTopLayerIs(BT2020_PQ)
2388 .andTopLayerIsREComposed(false)
2389 .andIfBottomLayerIsNotHdr()
2390 .andBottomLayerIsREComposed(false)
2391 .andIfLegacySupportFor(BT2020_PQ, false)
2392 .thenExpectBestColorModeCallUses(BT2020_PQ)
2393 .execute();
2394}
2395
2396TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2397 // If all layers use HLG then HLG is used if there are no other special
2398 // conditions.
2399 verify().ifTopLayerIs(BT2020_HLG)
2400 .andTopLayerIsREComposed(false)
2401 .andIfBottomLayerIsNotHdr()
2402 .andBottomLayerIsREComposed(true)
2403 .andIfLegacySupportFor(BT2020_HLG, false)
2404 .thenExpectBestColorModeCallUses(BT2020_HLG)
2405 .execute();
2406}
2407
2408struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2409 : public OutputUpdateColorProfileTest {
2410 // The various values for CompositionRefreshArgs::outputColorSetting affect
2411 // the chosen renderIntent, along with whether the preferred dataspace is an
2412 // HDR dataspace or not.
2413
2414 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2415 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2416 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2417 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002418 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002419 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2420 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2421 .WillRepeatedly(Return(false));
2422 }
2423
2424 // The tests here involve enough state and GMock setup that using a mini-DSL
2425 // makes the tests much more readable, and allows the test to focus more on
2426 // the intent than on some of the details.
2427
2428 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2429 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2430
2431 struct IfDataspaceChosenState
2432 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2433 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2434 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2435 return nextState<AndOutputColorSettingState>();
2436 }
2437 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2438 return ifDataspaceChosenIs(kNonHdrDataspace);
2439 }
2440 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2441 };
2442
2443 struct AndOutputColorSettingState
2444 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2445 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2446 getInstance()->mRefreshArgs.outputColorSetting = setting;
2447 return nextState<ThenExpectBestColorModeCallUsesState>();
2448 }
2449 };
2450
2451 struct ThenExpectBestColorModeCallUsesState
2452 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2453 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2454 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2455 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2456 _, _));
2457 return nextState<ExecuteState>();
2458 }
2459 };
2460
2461 // Tests call one of these two helper member functions to start using the
2462 // mini-DSL defined above.
2463 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2464};
2465
2466TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2467 Managed_NonHdr_Prefers_Colorimetric) {
2468 verify().ifDataspaceChosenIsNonHdr()
2469 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2470 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2471 .execute();
2472}
2473
2474TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2475 Managed_Hdr_Prefers_ToneMapColorimetric) {
2476 verify().ifDataspaceChosenIsHdr()
2477 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2478 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2479 .execute();
2480}
2481
2482TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2483 verify().ifDataspaceChosenIsNonHdr()
2484 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2485 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2486 .execute();
2487}
2488
2489TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2490 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2491 verify().ifDataspaceChosenIsHdr()
2492 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2493 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2494 .execute();
2495}
2496
2497TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2498 verify().ifDataspaceChosenIsNonHdr()
2499 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2500 .thenExpectBestColorModeCallUses(
2501 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2502 .execute();
2503}
2504
2505TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2506 verify().ifDataspaceChosenIsHdr()
2507 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2508 .thenExpectBestColorModeCallUses(
2509 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2510 .execute();
2511}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002512
2513/*
2514 * Output::beginFrame()
2515 */
2516
Lloyd Piquee5965952019-11-18 16:16:32 -08002517struct OutputBeginFrameTest : public ::testing::Test {
2518 using TestType = OutputBeginFrameTest;
2519
2520 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002521 // Sets up the helper functions called by the function under test to use
2522 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002523 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002524 };
2525
2526 OutputBeginFrameTest() {
2527 mOutput.setDisplayColorProfileForTest(
2528 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2529 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2530 }
2531
2532 struct IfGetDirtyRegionExpectationState
2533 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2534 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002535 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002536 return nextState<AndIfGetOutputLayerCountExpectationState>();
2537 }
2538 };
2539
2540 struct AndIfGetOutputLayerCountExpectationState
2541 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2542 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2543 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2544 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2545 }
2546 };
2547
2548 struct AndIfLastCompositionHadVisibleLayersState
2549 : public CallOrderStateMachineHelper<TestType,
2550 AndIfLastCompositionHadVisibleLayersState> {
2551 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2552 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2553 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2554 }
2555 };
2556
2557 struct ThenExpectRenderSurfaceBeginFrameCallState
2558 : public CallOrderStateMachineHelper<TestType,
2559 ThenExpectRenderSurfaceBeginFrameCallState> {
2560 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2561 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2562 return nextState<ExecuteState>();
2563 }
2564 };
2565
2566 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2567 [[nodiscard]] auto execute() {
2568 getInstance()->mOutput.beginFrame();
2569 return nextState<CheckPostconditionHadVisibleLayersState>();
2570 }
2571 };
2572
2573 struct CheckPostconditionHadVisibleLayersState
2574 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2575 void checkPostconditionHadVisibleLayers(bool expected) {
2576 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2577 }
2578 };
2579
2580 // Tests call one of these two helper member functions to start using the
2581 // mini-DSL defined above.
2582 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2583
2584 static const Region kEmptyRegion;
2585 static const Region kNotEmptyRegion;
2586
2587 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2588 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2589 StrictMock<OutputPartialMock> mOutput;
2590};
2591
2592const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2593const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2594
2595TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2596 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2597 .andIfGetOutputLayerCountReturns(1u)
2598 .andIfLastCompositionHadVisibleLayersIs(true)
2599 .thenExpectRenderSurfaceBeginFrameCall(true)
2600 .execute()
2601 .checkPostconditionHadVisibleLayers(true);
2602}
2603
2604TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2605 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2606 .andIfGetOutputLayerCountReturns(0u)
2607 .andIfLastCompositionHadVisibleLayersIs(true)
2608 .thenExpectRenderSurfaceBeginFrameCall(true)
2609 .execute()
2610 .checkPostconditionHadVisibleLayers(false);
2611}
2612
2613TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2614 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2615 .andIfGetOutputLayerCountReturns(1u)
2616 .andIfLastCompositionHadVisibleLayersIs(false)
2617 .thenExpectRenderSurfaceBeginFrameCall(true)
2618 .execute()
2619 .checkPostconditionHadVisibleLayers(true);
2620}
2621
2622TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2623 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2624 .andIfGetOutputLayerCountReturns(0u)
2625 .andIfLastCompositionHadVisibleLayersIs(false)
2626 .thenExpectRenderSurfaceBeginFrameCall(false)
2627 .execute()
2628 .checkPostconditionHadVisibleLayers(false);
2629}
2630
2631TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2632 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2633 .andIfGetOutputLayerCountReturns(1u)
2634 .andIfLastCompositionHadVisibleLayersIs(true)
2635 .thenExpectRenderSurfaceBeginFrameCall(false)
2636 .execute()
2637 .checkPostconditionHadVisibleLayers(true);
2638}
2639
2640TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2641 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2642 .andIfGetOutputLayerCountReturns(0u)
2643 .andIfLastCompositionHadVisibleLayersIs(true)
2644 .thenExpectRenderSurfaceBeginFrameCall(false)
2645 .execute()
2646 .checkPostconditionHadVisibleLayers(true);
2647}
2648
2649TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2650 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2651 .andIfGetOutputLayerCountReturns(1u)
2652 .andIfLastCompositionHadVisibleLayersIs(false)
2653 .thenExpectRenderSurfaceBeginFrameCall(false)
2654 .execute()
2655 .checkPostconditionHadVisibleLayers(false);
2656}
2657
2658TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2659 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2660 .andIfGetOutputLayerCountReturns(0u)
2661 .andIfLastCompositionHadVisibleLayersIs(false)
2662 .thenExpectRenderSurfaceBeginFrameCall(false)
2663 .execute()
2664 .checkPostconditionHadVisibleLayers(false);
2665}
2666
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002667/*
2668 * Output::devOptRepaintFlash()
2669 */
2670
Lloyd Piquedb462d82019-11-19 17:58:46 -08002671struct OutputDevOptRepaintFlashTest : public testing::Test {
2672 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002673 // Sets up the helper functions called by the function under test to use
2674 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002675 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002676 MOCK_METHOD2(composeSurfaces,
2677 std::optional<base::unique_fd>(
2678 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002679 MOCK_METHOD0(postFramebuffer, void());
2680 MOCK_METHOD0(prepareFrame, void());
2681 };
2682
2683 OutputDevOptRepaintFlashTest() {
2684 mOutput.setDisplayColorProfileForTest(
2685 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2686 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2687 }
2688
2689 static const Region kEmptyRegion;
2690 static const Region kNotEmptyRegion;
2691
2692 StrictMock<OutputPartialMock> mOutput;
2693 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2694 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2695 CompositionRefreshArgs mRefreshArgs;
2696};
2697
2698const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2699const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2700
2701TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2702 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002703 mOutput.mState.isEnabled = true;
2704
2705 mOutput.devOptRepaintFlash(mRefreshArgs);
2706}
2707
2708TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2709 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002710 mOutput.mState.isEnabled = false;
2711
2712 InSequence seq;
2713 EXPECT_CALL(mOutput, postFramebuffer());
2714 EXPECT_CALL(mOutput, prepareFrame());
2715
2716 mOutput.devOptRepaintFlash(mRefreshArgs);
2717}
2718
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002719TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002720 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002721 mOutput.mState.isEnabled = true;
2722
2723 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002724 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002725 EXPECT_CALL(mOutput, postFramebuffer());
2726 EXPECT_CALL(mOutput, prepareFrame());
2727
2728 mOutput.devOptRepaintFlash(mRefreshArgs);
2729}
2730
2731TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2732 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002733 mOutput.mState.isEnabled = true;
2734
2735 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002736 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002737 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002738 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2739 EXPECT_CALL(mOutput, postFramebuffer());
2740 EXPECT_CALL(mOutput, prepareFrame());
2741
2742 mOutput.devOptRepaintFlash(mRefreshArgs);
2743}
2744
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002745/*
2746 * Output::finishFrame()
2747 */
2748
Lloyd Pique03561a62019-11-19 18:34:52 -08002749struct OutputFinishFrameTest : public testing::Test {
2750 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002751 // Sets up the helper functions called by the function under test to use
2752 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002753 MOCK_METHOD2(composeSurfaces,
2754 std::optional<base::unique_fd>(
2755 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002756 MOCK_METHOD0(postFramebuffer, void());
2757 };
2758
2759 OutputFinishFrameTest() {
2760 mOutput.setDisplayColorProfileForTest(
2761 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2762 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2763 }
2764
2765 StrictMock<OutputPartialMock> mOutput;
2766 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2767 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2768 CompositionRefreshArgs mRefreshArgs;
2769};
2770
2771TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2772 mOutput.mState.isEnabled = false;
2773
2774 mOutput.finishFrame(mRefreshArgs);
2775}
2776
2777TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2778 mOutput.mState.isEnabled = true;
2779
2780 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002781 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002782
2783 mOutput.finishFrame(mRefreshArgs);
2784}
2785
2786TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2787 mOutput.mState.isEnabled = true;
2788
2789 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002790 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002791 .WillOnce(Return(ByMove(base::unique_fd())));
2792 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2793
2794 mOutput.finishFrame(mRefreshArgs);
2795}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002796
2797/*
2798 * Output::postFramebuffer()
2799 */
2800
Lloyd Pique07178e32019-11-19 19:15:26 -08002801struct OutputPostFramebufferTest : public testing::Test {
2802 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002803 // Sets up the helper functions called by the function under test to use
2804 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002805 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2806 };
2807
2808 struct Layer {
2809 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002810 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002811 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2812 }
2813
2814 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002815 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002816 StrictMock<HWC2::mock::Layer> hwc2Layer;
2817 };
2818
2819 OutputPostFramebufferTest() {
2820 mOutput.setDisplayColorProfileForTest(
2821 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2822 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2823
2824 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2825 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2826 .WillRepeatedly(Return(&mLayer1.outputLayer));
2827 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2828 .WillRepeatedly(Return(&mLayer2.outputLayer));
2829 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2830 .WillRepeatedly(Return(&mLayer3.outputLayer));
2831 }
2832
2833 StrictMock<OutputPartialMock> mOutput;
2834 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2835 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2836
2837 Layer mLayer1;
2838 Layer mLayer2;
2839 Layer mLayer3;
2840};
2841
2842TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2843 mOutput.mState.isEnabled = false;
2844
2845 mOutput.postFramebuffer();
2846}
2847
2848TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2849 mOutput.mState.isEnabled = true;
2850
2851 compositionengine::Output::FrameFences frameFences;
2852
2853 // This should happen even if there are no output layers.
2854 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2855
2856 // For this test in particular we want to make sure the call expectations
2857 // setup below are satisfied in the specific order.
2858 InSequence seq;
2859
2860 EXPECT_CALL(*mRenderSurface, flip());
2861 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2862 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2863
2864 mOutput.postFramebuffer();
2865}
2866
2867TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2868 // Simulate getting release fences from each layer, and ensure they are passed to the
2869 // front-end layer interface for each layer correctly.
2870
2871 mOutput.mState.isEnabled = true;
2872
2873 // Create three unique fence instances
2874 sp<Fence> layer1Fence = new Fence();
2875 sp<Fence> layer2Fence = new Fence();
2876 sp<Fence> layer3Fence = new Fence();
2877
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002878 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002879 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2880 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2881 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2882
2883 EXPECT_CALL(*mRenderSurface, flip());
2884 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2885 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2886
2887 // Compare the pointers values of each fence to make sure the correct ones
2888 // are passed. This happens to work with the current implementation, but
2889 // would not survive certain calls like Fence::merge() which would return a
2890 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002891 base::unique_fd layer1FD(layer1Fence->dup());
2892 base::unique_fd layer2FD(layer2Fence->dup());
2893 base::unique_fd layer3FD(layer3Fence->dup());
2894 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2895 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2896 futureRenderEngineResult) {
2897 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2898 });
2899 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2900 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2901 futureRenderEngineResult) {
2902 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2903 });
2904 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2905 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2906 futureRenderEngineResult) {
2907 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2908 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002909
2910 mOutput.postFramebuffer();
2911}
2912
2913TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2914 mOutput.mState.isEnabled = true;
2915 mOutput.mState.usesClientComposition = true;
2916
2917 sp<Fence> clientTargetAcquireFence = new Fence();
2918 sp<Fence> layer1Fence = new Fence();
2919 sp<Fence> layer2Fence = new Fence();
2920 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002921 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002922 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2923 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2924 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2925 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2926
2927 EXPECT_CALL(*mRenderSurface, flip());
2928 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2929 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2930
2931 // Fence::merge is called, and since none of the fences are actually valid,
2932 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2933 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00002934 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
2935 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
2936 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08002937
2938 mOutput.postFramebuffer();
2939}
2940
2941TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2942 mOutput.mState.isEnabled = true;
2943 mOutput.mState.usesClientComposition = true;
2944
2945 // This should happen even if there are no (current) output layers.
2946 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2947
2948 // Load up the released layers with some mock instances
2949 sp<StrictMock<mock::LayerFE>> releasedLayer1{new StrictMock<mock::LayerFE>()};
2950 sp<StrictMock<mock::LayerFE>> releasedLayer2{new StrictMock<mock::LayerFE>()};
2951 sp<StrictMock<mock::LayerFE>> releasedLayer3{new StrictMock<mock::LayerFE>()};
2952 Output::ReleasedLayers layers;
2953 layers.push_back(releasedLayer1);
2954 layers.push_back(releasedLayer2);
2955 layers.push_back(releasedLayer3);
2956 mOutput.setReleasedLayers(std::move(layers));
2957
2958 // Set up a fake present fence
2959 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002960 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002961 frameFences.presentFence = presentFence;
2962
2963 EXPECT_CALL(*mRenderSurface, flip());
2964 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2965 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2966
2967 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00002968 base::unique_fd layerFD(presentFence.get()->dup());
2969 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
2970 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2971 futureRenderEngineResult) {
2972 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2973 });
2974 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
2975 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2976 futureRenderEngineResult) {
2977 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2978 });
2979 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
2980 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
2981 futureRenderEngineResult) {
2982 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
2983 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002984
2985 mOutput.postFramebuffer();
2986
2987 // After the call the list of released layers should have been cleared.
2988 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
2989}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002990
2991/*
Lloyd Pique56eba802019-08-28 15:45:25 -07002992 * Output::composeSurfaces()
2993 */
2994
2995struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08002996 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07002997
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002998 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002999 // Sets up the helper functions called by the function under test to use
3000 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003001 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003002 MOCK_METHOD3(generateClientCompositionRequests,
3003 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003004 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003005 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003006 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3007 };
3008
3009 OutputComposeSurfacesTest() {
3010 mOutput.setDisplayColorProfileForTest(
3011 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3012 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003013 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003014
Angel Aguayob084e0c2021-08-04 23:27:28 +00003015 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3016 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3017 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3018 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3019 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003020 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003021 mOutput.mState.dataspace = kDefaultOutputDataspace;
3022 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3023 mOutput.mState.isSecure = false;
3024 mOutput.mState.needsFiltering = false;
3025 mOutput.mState.usesClientComposition = true;
3026 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003027 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003028 mOutput.mState.flipClientTarget = false;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003029 mOutput.mState.clientTargetWhitePointNits = kClientTargetLuminanceNits;
Lloyd Pique56eba802019-08-28 15:45:25 -07003030
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003031 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003032 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003033 EXPECT_CALL(mCompositionEngine, getTimeStats())
3034 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003035 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3036 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003037 }
3038
Lloyd Pique6818fa52019-12-03 12:32:13 -08003039 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3040 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003041 getInstance()->mReadyFence =
3042 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003043 return nextState<FenceCheckState>();
3044 }
3045 };
3046
3047 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3048 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3049
3050 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3051 };
3052
3053 // Call this member function to start using the mini-DSL defined above.
3054 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3055
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003056 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3057 static constexpr uint32_t kDefaultOutputOrientationFlags =
3058 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003059 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3060 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3061 static constexpr float kDefaultMaxLuminance = 0.9f;
3062 static constexpr float kDefaultAvgLuminance = 0.7f;
3063 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003064 static constexpr float kClientTargetLuminanceNits = 200.f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003065
3066 static const Rect kDefaultOutputFrame;
3067 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003068 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003069 static const mat4 kDefaultColorTransformMat;
3070
3071 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003072 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003073 static const HdrCapabilities kHdrCapabilities;
3074
Lloyd Pique56eba802019-08-28 15:45:25 -07003075 StrictMock<mock::CompositionEngine> mCompositionEngine;
3076 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003077 // TODO: make this is a proper mock.
3078 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003079 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3080 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003081 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003082 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003083 renderengine::impl::
3084 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3085 renderengine::impl::ExternalTexture::Usage::READABLE |
3086 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003087
3088 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003089};
3090
3091const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3092const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003093const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003094const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003095const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003096const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
3097const HdrCapabilities OutputComposeSurfacesTest::
3098 kHdrCapabilities{{},
3099 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3100 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3101 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003102
Lloyd Piquea76ce462020-01-14 13:06:37 -08003103TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003104 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003105
Lloyd Piquee9eff972020-05-05 12:36:44 -07003106 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003107 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003108
Lloyd Piquea76ce462020-01-14 13:06:37 -08003109 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3110
Lloyd Pique6818fa52019-12-03 12:32:13 -08003111 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003112}
3113
Lloyd Piquee9eff972020-05-05 12:36:44 -07003114TEST_F(OutputComposeSurfacesTest,
3115 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3116 mOutput.mState.usesClientComposition = false;
3117 mOutput.mState.flipClientTarget = true;
3118
Lloyd Pique6818fa52019-12-03 12:32:13 -08003119 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(mOutputBuffer));
3123 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3124
3125 verify().execute().expectAFenceWasReturned();
3126}
3127
3128TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3129 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003130 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003131
3132 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3133
3134 verify().execute().expectNoFenceWasReturned();
3135}
3136
3137TEST_F(OutputComposeSurfacesTest,
3138 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3139 mOutput.mState.usesClientComposition = false;
3140 mOutput.mState.flipClientTarget = true;
3141
3142 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003143 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003144
Lloyd Pique6818fa52019-12-03 12:32:13 -08003145 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003146
Lloyd Pique6818fa52019-12-03 12:32:13 -08003147 verify().execute().expectNoFenceWasReturned();
3148}
Lloyd Pique56eba802019-08-28 15:45:25 -07003149
Lloyd Pique6818fa52019-12-03 12:32:13 -08003150TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3151 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3152 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3153 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003154 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003155 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003156 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003157 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3158 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003159
Lloyd Pique6818fa52019-12-03 12:32:13 -08003160 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003161 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3162 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003163 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003164 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003165 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003166 -> std::future<renderengine::RenderEngineResult> {
3167 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3168 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003169 verify().execute().expectAFenceWasReturned();
3170}
Lloyd Pique56eba802019-08-28 15:45:25 -07003171
Lloyd Pique6818fa52019-12-03 12:32:13 -08003172TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003173 LayerFE::LayerSettings r1;
3174 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003175
3176 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3177 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3178
3179 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3180 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3181 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003182 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003183 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003184 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003185 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3186 .WillRepeatedly(
3187 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003188 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003189 clientCompositionLayers.emplace_back(r2);
3190 }));
3191
3192 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003193 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003194 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003195 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003196 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003197 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003198 -> std::future<renderengine::RenderEngineResult> {
3199 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3200 });
Alec Mouri1684c702021-02-04 12:27:26 -08003201
3202 verify().execute().expectAFenceWasReturned();
3203}
3204
3205TEST_F(OutputComposeSurfacesTest,
3206 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3207 LayerFE::LayerSettings r1;
3208 LayerFE::LayerSettings r2;
3209
3210 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3211 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003212 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003213
3214 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3215 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3216 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3217 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003218 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003219 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3220 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3221 .WillRepeatedly(
3222 Invoke([&](const Region&,
3223 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3224 clientCompositionLayers.emplace_back(r2);
3225 }));
3226
3227 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003228 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003229 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003230 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003231 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003232 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003233 -> std::future<renderengine::RenderEngineResult> {
3234 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3235 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003236
3237 verify().execute().expectAFenceWasReturned();
3238}
3239
Vishnu Nair9b079a22020-01-21 14:36:08 -08003240TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3241 mOutput.cacheClientCompositionRequests(0);
3242 LayerFE::LayerSettings r1;
3243 LayerFE::LayerSettings r2;
3244
3245 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3246 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3247
3248 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3249 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3250 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003251 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003252 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003253 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3254 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3255 .WillRepeatedly(Return());
3256
3257 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003258 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003259 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003260 .WillOnce(Return(ByMove(
3261 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3262 .WillOnce(Return(ByMove(
3263 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003264
3265 verify().execute().expectAFenceWasReturned();
3266 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3267
3268 verify().execute().expectAFenceWasReturned();
3269 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3270}
3271
3272TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3273 mOutput.cacheClientCompositionRequests(3);
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));
Robert Carrccab4242021-09-28 16:53:03 -07003284 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003285 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3286 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3287 .WillRepeatedly(Return());
3288
3289 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003290 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003291 .WillOnce(Return(ByMove(
3292 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003293 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3294
3295 verify().execute().expectAFenceWasReturned();
3296 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3297
3298 // We do not expect another call to draw layers.
3299 verify().execute().expectAFenceWasReturned();
3300 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3301}
3302
3303TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3304 LayerFE::LayerSettings r1;
3305 LayerFE::LayerSettings r2;
3306
3307 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3308 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3309
3310 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3311 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3312 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003313 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003314 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003315 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3316 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3317 .WillRepeatedly(Return());
3318
Alec Mouria90a5702021-04-16 16:36:21 +00003319 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003320 renderengine::impl::
3321 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3322 renderengine::impl::ExternalTexture::Usage::READABLE |
3323 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003324 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3325 .WillOnce(Return(mOutputBuffer))
3326 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003327 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003328 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003329 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003330 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003331 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003332 -> std::future<renderengine::RenderEngineResult> {
3333 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3334 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003335
3336 verify().execute().expectAFenceWasReturned();
3337 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3338
3339 verify().execute().expectAFenceWasReturned();
3340 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3341}
3342
3343TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3344 LayerFE::LayerSettings r1;
3345 LayerFE::LayerSettings r2;
3346 LayerFE::LayerSettings r3;
3347
3348 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3349 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3350 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3351
3352 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3353 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3354 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003355 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003356 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003357 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3358 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3359 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3360 .WillRepeatedly(Return());
3361
3362 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003363 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003364 .WillOnce(Return(ByMove(
3365 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003366 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003367 .WillOnce(Return(ByMove(
3368 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003369
3370 verify().execute().expectAFenceWasReturned();
3371 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3372
3373 verify().execute().expectAFenceWasReturned();
3374 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3375}
3376
Lloyd Pique6818fa52019-12-03 12:32:13 -08003377struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3378 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3379 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003380 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003381 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003382 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003383 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3384 .WillRepeatedly(Return());
3385 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3386 }
3387
3388 struct MixedCompositionState
3389 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3390 auto ifMixedCompositionIs(bool used) {
3391 getInstance()->mOutput.mState.usesDeviceComposition = used;
3392 return nextState<OutputUsesHdrState>();
3393 }
3394 };
3395
3396 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3397 auto andIfUsesHdr(bool used) {
3398 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3399 .WillOnce(Return(used));
3400 return nextState<SkipColorTransformState>();
3401 }
3402 };
3403
3404 struct SkipColorTransformState
3405 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3406 auto andIfSkipColorTransform(bool skip) {
3407 // May be called zero or one times.
3408 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3409 .WillRepeatedly(Return(skip));
3410 return nextState<ExpectDisplaySettingsState>();
3411 }
3412 };
3413
3414 struct ExpectDisplaySettingsState
3415 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3416 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003417 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3418 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3419 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003420 return nextState<ExecuteState>();
3421 }
3422 };
3423
3424 // Call this member function to start using the mini-DSL defined above.
3425 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3426};
3427
3428TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3429 verify().ifMixedCompositionIs(true)
3430 .andIfUsesHdr(true)
3431 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003432 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003433 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003434 kDefaultOutputOrientationFlags,
3435 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003436 .execute()
3437 .expectAFenceWasReturned();
3438}
3439
3440TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3441 verify().ifMixedCompositionIs(true)
3442 .andIfUsesHdr(false)
3443 .andIfSkipColorTransform(false)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003444 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003445 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003446 kDefaultOutputOrientationFlags,
3447 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003448 .execute()
3449 .expectAFenceWasReturned();
3450}
3451
3452TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3453 verify().ifMixedCompositionIs(false)
3454 .andIfUsesHdr(true)
3455 .andIfSkipColorTransform(false)
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003456 .thenExpectDisplaySettingsUsed(
3457 {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
3458 kDefaultOutputDataspace, kDefaultColorTransformMat,
3459 kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003460 .execute()
3461 .expectAFenceWasReturned();
3462}
3463
3464TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3465 verify().ifMixedCompositionIs(false)
3466 .andIfUsesHdr(false)
3467 .andIfSkipColorTransform(false)
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003468 .thenExpectDisplaySettingsUsed(
3469 {kDefaultOutputDestinationClip, kDefaultOutputViewport, kDefaultMaxLuminance,
3470 kDefaultOutputDataspace, kDefaultColorTransformMat,
3471 kDefaultOutputOrientationFlags, kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003472 .execute()
3473 .expectAFenceWasReturned();
3474}
3475
3476TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3477 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3478 verify().ifMixedCompositionIs(false)
3479 .andIfUsesHdr(true)
3480 .andIfSkipColorTransform(true)
Marin Shalamanov06ca1632020-07-28 12:32:01 +02003481 .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputViewport,
Alec Mourid4bf7952020-04-06 20:28:16 -07003482 kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003483 kDefaultOutputOrientationFlags,
3484 kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003485 .execute()
3486 .expectAFenceWasReturned();
3487}
3488
3489struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3490 struct Layer {
3491 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003492 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3493 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003494 }
3495
3496 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003497 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003498 LayerFECompositionState mLayerFEState;
3499 };
3500
3501 OutputComposeSurfacesTest_HandlesProtectedContent() {
3502 mLayer1.mLayerFEState.hasProtectedContent = false;
3503 mLayer2.mLayerFEState.hasProtectedContent = false;
3504
3505 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3506 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3507 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3508 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3509 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3510
3511 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3512
3513 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3514
Robert Carrccab4242021-09-28 16:53:03 -07003515 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003516 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003517 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3518 .WillRepeatedly(Return());
3519 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003520 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3521 .WillRepeatedly(
3522 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003523 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003524 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003525 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003526 return futureOf<renderengine::RenderEngineResult>(
3527 {NO_ERROR, base::unique_fd()});
3528 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003529 }
3530
3531 Layer mLayer1;
3532 Layer mLayer2;
3533};
3534
3535TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3536 mOutput.mState.isSecure = false;
3537 mLayer2.mLayerFEState.hasProtectedContent = true;
3538 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003539 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003540 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003541
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003542 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003543}
3544
3545TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3546 mOutput.mState.isSecure = true;
3547 mLayer2.mLayerFEState.hasProtectedContent = true;
3548 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3549
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003550 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003551}
3552
3553TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3554 mOutput.mState.isSecure = true;
3555 mLayer2.mLayerFEState.hasProtectedContent = false;
3556 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3557 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3558 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3559 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3560 EXPECT_CALL(*mRenderSurface, setProtected(false));
3561
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003562 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003563}
3564
3565TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3566 mOutput.mState.isSecure = true;
3567 mLayer2.mLayerFEState.hasProtectedContent = true;
3568 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3569
3570 // For this test, we also check the call order of key functions.
3571 InSequence seq;
3572
3573 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3574 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3575 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3576 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3577 EXPECT_CALL(*mRenderSurface, setProtected(true));
3578 // Must happen after setting the protected content state.
3579 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003580 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3581 .WillOnce(Return(ByMove(
3582 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003583
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003584 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003585}
3586
3587TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3588 mOutput.mState.isSecure = true;
3589 mLayer2.mLayerFEState.hasProtectedContent = true;
3590 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3591 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3592 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3593
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003594 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003595}
3596
3597TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3598 mOutput.mState.isSecure = true;
3599 mLayer2.mLayerFEState.hasProtectedContent = true;
3600 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3601 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3602 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3603 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3604
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003605 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003606}
3607
3608TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3609 mOutput.mState.isSecure = true;
3610 mLayer2.mLayerFEState.hasProtectedContent = true;
3611 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3612 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3613 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3614 EXPECT_CALL(*mRenderSurface, setProtected(true));
3615
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003616 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003617}
3618
3619TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3620 mOutput.mState.isSecure = true;
3621 mLayer2.mLayerFEState.hasProtectedContent = true;
3622 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3623 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3624 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3625 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3626
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003627 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003628}
3629
3630struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3631 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3632 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3633 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3634 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003635 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003636 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3637 .WillRepeatedly(Return());
3638 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3639 }
3640};
3641
3642TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3643 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3644
Robert Carrccab4242021-09-28 16:53:03 -07003645 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003646 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003647
3648 // For this test, we also check the call order of key functions.
3649 InSequence seq;
3650
3651 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003652 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3653 .WillOnce(Return(ByMove(
3654 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003655
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003656 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3657}
3658
3659struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3660 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3661 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3662 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003663 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003664 mOutput.editState().isEnabled = true;
3665
Snild Dolkow9e217d62020-04-22 15:53:42 +02003666 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003667 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003668 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3669 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003670 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003671 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003672 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3673 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3674 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003675 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3676 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3677 .WillRepeatedly(Return(&mLayer.outputLayer));
3678 }
3679
3680 NonInjectedLayer mLayer;
3681 compositionengine::CompositionRefreshArgs mRefreshArgs;
3682};
3683
3684TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3685 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003686 mOutput.updateCompositionState(mRefreshArgs);
3687 mOutput.planComposition();
3688 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003689
3690 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3691 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3692}
3693
3694TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3695 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003696 mOutput.updateCompositionState(mRefreshArgs);
3697 mOutput.planComposition();
3698 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003699
3700 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3701 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003702}
3703
3704/*
3705 * Output::generateClientCompositionRequests()
3706 */
3707
3708struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003709 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003710 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003711 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3712 bool supportsProtectedContent, ui::Dataspace dataspace) {
3713 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003714 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003715 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003716 }
3717 };
3718
Lloyd Piquea4863342019-12-04 18:45:02 -08003719 struct Layer {
3720 Layer() {
3721 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3722 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003723 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3724 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003725 }
3726
3727 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003728 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003729 LayerFECompositionState mLayerFEState;
3730 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003731 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003732 };
3733
Lloyd Pique56eba802019-08-28 15:45:25 -07003734 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003735 mOutput.mState.needsFiltering = false;
3736
Lloyd Pique56eba802019-08-28 15:45:25 -07003737 mOutput.setDisplayColorProfileForTest(
3738 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3739 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3740 }
3741
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003742 static constexpr float kLayerWhitePointNits = 200.f;
3743
Lloyd Pique56eba802019-08-28 15:45:25 -07003744 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3745 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003746 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003747};
3748
Lloyd Piquea4863342019-12-04 18:45:02 -08003749struct GenerateClientCompositionRequestsTest_ThreeLayers
3750 : public GenerateClientCompositionRequestsTest {
3751 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003752 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3753 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3754 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003755 mOutput.mState.transform =
3756 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003757 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003758 mOutput.mState.needsFiltering = false;
3759 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003760
Lloyd Piquea4863342019-12-04 18:45:02 -08003761 for (size_t i = 0; i < mLayers.size(); i++) {
3762 mLayers[i].mOutputLayerState.clearClientTarget = false;
3763 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3764 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003765 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003766 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003767 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3768 mLayers[i].mLayerSettings.alpha = 1.0f;
3769 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003770
Lloyd Piquea4863342019-12-04 18:45:02 -08003771 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3772 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3773 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3774 .WillRepeatedly(Return(true));
3775 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3776 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003777
Lloyd Piquea4863342019-12-04 18:45:02 -08003778 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3779 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003780
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003781 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003782 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003783 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003784
Lloyd Piquea4863342019-12-04 18:45:02 -08003785 static const Rect kDisplayFrame;
3786 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003787 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003788
Lloyd Piquea4863342019-12-04 18:45:02 -08003789 std::array<Layer, 3> mLayers;
3790};
Lloyd Pique56eba802019-08-28 15:45:25 -07003791
Lloyd Piquea4863342019-12-04 18:45:02 -08003792const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3793const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003794const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3795 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003796
Lloyd Piquea4863342019-12-04 18:45:02 -08003797TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3798 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3799 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3800 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003801
Robert Carrccab4242021-09-28 16:53:03 -07003802 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003803 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003804 EXPECT_EQ(0u, requests.size());
3805}
3806
Lloyd Piquea4863342019-12-04 18:45:02 -08003807TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3808 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3809 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3810 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3811
Robert Carrccab4242021-09-28 16:53:03 -07003812 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003813 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003814 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003815}
3816
3817TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003818 LayerFE::LayerSettings mShadowSettings;
3819 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003820
Ady Abrahameca9d752021-03-03 12:20:00 -08003821 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003822 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003823 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003824 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003825 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003826 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3827 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003828
Robert Carrccab4242021-09-28 16:53:03 -07003829 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003830 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003831 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003832 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3833 EXPECT_EQ(mShadowSettings, requests[1]);
3834 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003835
Lloyd Piquea4863342019-12-04 18:45:02 -08003836 // Check that a timestamp was set for the layers that generated requests
3837 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3838 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3839 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3840}
3841
Alec Mourif54453c2021-05-13 16:28:28 -07003842MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3843 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3844 *result_listener << "expected " << expectedBlurSetting << "\n";
3845 *result_listener << "actual " << arg.blurSetting << "\n";
3846
3847 return expectedBlurSetting == arg.blurSetting;
3848}
3849
3850TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3851 LayerFE::LayerSettings mShadowSettings;
3852 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3853
3854 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3855
3856 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3857 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3858 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3859 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3860 EXPECT_CALL(*mLayers[2].mLayerFE,
3861 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3862 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3863 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3864 {mShadowSettings, mLayers[2].mLayerSettings})));
3865
Robert Carrccab4242021-09-28 16:53:03 -07003866 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003867 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003868 ASSERT_EQ(3u, requests.size());
3869 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3870 EXPECT_EQ(mShadowSettings, requests[1]);
3871 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3872
Alec Mourif54453c2021-05-13 16:28:28 -07003873 // Check that a timestamp was set for the layers that generated requests
3874 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3875 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3876 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3877}
3878
Lloyd Piquea4863342019-12-04 18:45:02 -08003879TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3880 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3881 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3882 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3883 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3884
3885 mLayers[0].mOutputLayerState.clearClientTarget = false;
3886 mLayers[1].mOutputLayerState.clearClientTarget = false;
3887 mLayers[2].mOutputLayerState.clearClientTarget = false;
3888
3889 mLayers[0].mLayerFEState.isOpaque = true;
3890 mLayers[1].mLayerFEState.isOpaque = true;
3891 mLayers[2].mLayerFEState.isOpaque = true;
3892
Ady Abrahameca9d752021-03-03 12:20:00 -08003893 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003894 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003895
Robert Carrccab4242021-09-28 16:53:03 -07003896 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003897 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003898 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003899 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003900}
3901
3902TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3903 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
3904 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3905 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3906 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3907
3908 mLayers[0].mOutputLayerState.clearClientTarget = true;
3909 mLayers[1].mOutputLayerState.clearClientTarget = true;
3910 mLayers[2].mOutputLayerState.clearClientTarget = true;
3911
3912 mLayers[0].mLayerFEState.isOpaque = false;
3913 mLayers[1].mLayerFEState.isOpaque = false;
3914 mLayers[2].mLayerFEState.isOpaque = false;
3915
Ady Abrahameca9d752021-03-03 12:20:00 -08003916 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003917 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003918
Robert Carrccab4242021-09-28 16:53:03 -07003919 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003920 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003921 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003922 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003923}
3924
3925TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003926 // If client composition is performed with some layers set to use device
3927 // composition, device layers after the first layer (device or client) will
3928 // clear the frame buffer if they are opaque and if that layer has a flag
3929 // set to do so. The first layer is skipped as the frame buffer is already
3930 // expected to be clear.
3931
Lloyd Piquea4863342019-12-04 18:45:02 -08003932 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3933 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3934 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003935
Lloyd Piquea4863342019-12-04 18:45:02 -08003936 mLayers[0].mOutputLayerState.clearClientTarget = true;
3937 mLayers[1].mOutputLayerState.clearClientTarget = true;
3938 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003939
Lloyd Piquea4863342019-12-04 18:45:02 -08003940 mLayers[0].mLayerFEState.isOpaque = true;
3941 mLayers[1].mLayerFEState.isOpaque = true;
3942 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003943
3944 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
3945 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003946 false, /* needs filtering */
3947 false, /* secure */
3948 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003949 kDisplayViewport,
3950 kDisplayDataspace,
3951 false /* realContentIsVisible */,
3952 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003953 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003954 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003955 };
3956 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
3957 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003958 false, /* needs filtering */
3959 false, /* secure */
3960 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003961 kDisplayViewport,
3962 kDisplayDataspace,
3963 true /* realContentIsVisible */,
3964 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07003965 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003966 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003967 };
3968
3969 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
3970 mBlackoutSettings.source.buffer.buffer = nullptr;
3971 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3972 mBlackoutSettings.alpha = 0.f;
3973 mBlackoutSettings.disableBlending = true;
3974
Ady Abrahameca9d752021-03-03 12:20:00 -08003975 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003976 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003977 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003978 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
3979
Robert Carrccab4242021-09-28 16:53:03 -07003980 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003981 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003982 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003983
Lloyd Piquea4863342019-12-04 18:45:02 -08003984 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003985 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003986
Vishnu Nair9b079a22020-01-21 14:36:08 -08003987 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003988}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003989
Lloyd Piquea4863342019-12-04 18:45:02 -08003990TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3991 clippedVisibleRegionUsedToGenerateRequest) {
3992 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
3993 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
3994 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07003995
Lloyd Piquea4863342019-12-04 18:45:02 -08003996 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
3997 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08003998 false, /* needs filtering */
3999 false, /* secure */
4000 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004001 kDisplayViewport,
4002 kDisplayDataspace,
4003 true /* realContentIsVisible */,
4004 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004005 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004006 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004007 };
4008 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4009 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004010 false, /* needs filtering */
4011 false, /* secure */
4012 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004013 kDisplayViewport,
4014 kDisplayDataspace,
4015 true /* realContentIsVisible */,
4016 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004017 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004018 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004019 };
4020 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4021 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004022 false, /* needs filtering */
4023 false, /* secure */
4024 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004025 kDisplayViewport,
4026 kDisplayDataspace,
4027 true /* realContentIsVisible */,
4028 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004029 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004030 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004031 };
4032
Ady Abrahameca9d752021-03-03 12:20:00 -08004033 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004034 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004035 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004036 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004037 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004038 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004039
4040 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004041 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004042 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004043}
4044
4045TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4046 perLayerNeedsFilteringUsedToGenerateRequests) {
4047 mOutput.mState.needsFiltering = false;
4048 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4049
Lloyd Piquea4863342019-12-04 18:45:02 -08004050 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4051 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004052 true, /* needs filtering */
4053 false, /* secure */
4054 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004055 kDisplayViewport,
4056 kDisplayDataspace,
4057 true /* realContentIsVisible */,
4058 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004059 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004060 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004061 };
4062 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4063 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004064 false, /* needs filtering */
4065 false, /* secure */
4066 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004067 kDisplayViewport,
4068 kDisplayDataspace,
4069 true /* realContentIsVisible */,
4070 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004071 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004072 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004073 };
4074 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4075 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004076 false, /* needs filtering */
4077 false, /* secure */
4078 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004079 kDisplayViewport,
4080 kDisplayDataspace,
4081 true /* realContentIsVisible */,
4082 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004083 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004084 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004085 };
4086
Ady Abrahameca9d752021-03-03 12:20:00 -08004087 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004088 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004089 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004090 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004091 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004092 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004093
4094 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004095 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4096 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004097}
4098
4099TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4100 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4101 mOutput.mState.needsFiltering = true;
4102 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4103
Lloyd Piquea4863342019-12-04 18:45:02 -08004104 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4105 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004106 true, /* needs filtering */
4107 false, /* secure */
4108 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004109 kDisplayViewport,
4110 kDisplayDataspace,
4111 true /* realContentIsVisible */,
4112 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004113 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004114 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004115 };
4116 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4117 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004118 true, /* needs filtering */
4119 false, /* secure */
4120 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004121 kDisplayViewport,
4122 kDisplayDataspace,
4123 true /* realContentIsVisible */,
4124 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004125 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004126 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004127 };
4128 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4129 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004130 true, /* needs filtering */
4131 false, /* secure */
4132 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004133 kDisplayViewport,
4134 kDisplayDataspace,
4135 true /* realContentIsVisible */,
4136 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004137 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004138 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004139 };
4140
Ady Abrahameca9d752021-03-03 12:20:00 -08004141 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004142 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004143 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004144 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004145 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004146 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004147
4148 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004149 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4150 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004151}
4152
4153TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4154 wholeOutputSecurityUsedToGenerateRequests) {
4155 mOutput.mState.isSecure = true;
4156
Lloyd Piquea4863342019-12-04 18:45:02 -08004157 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4158 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004159 false, /* needs filtering */
4160 true, /* secure */
4161 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004162 kDisplayViewport,
4163 kDisplayDataspace,
4164 true /* realContentIsVisible */,
4165 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004166 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004167 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004168 };
4169 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4170 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004171 false, /* needs filtering */
4172 true, /* secure */
4173 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004174 kDisplayViewport,
4175 kDisplayDataspace,
4176 true /* realContentIsVisible */,
4177 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004178 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004179 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004180 };
4181 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4182 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004183 false, /* needs filtering */
4184 true, /* secure */
4185 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004186 kDisplayViewport,
4187 kDisplayDataspace,
4188 true /* realContentIsVisible */,
4189 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004190 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004191 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004192 };
4193
Ady Abrahameca9d752021-03-03 12:20:00 -08004194 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004195 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004196 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004197 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004198 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004199 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004200
4201 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004202 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4203 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004204}
4205
4206TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4207 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004208 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4209 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004210 false, /* needs filtering */
4211 false, /* secure */
4212 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004213 kDisplayViewport,
4214 kDisplayDataspace,
4215 true /* realContentIsVisible */,
4216 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004217 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004218 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004219 };
4220 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4221 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004222 false, /* needs filtering */
4223 false, /* secure */
4224 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004225 kDisplayViewport,
4226 kDisplayDataspace,
4227 true /* realContentIsVisible */,
4228 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004229 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004230 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004231 };
4232 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4233 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004234 false, /* needs filtering */
4235 false, /* secure */
4236 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004237 kDisplayViewport,
4238 kDisplayDataspace,
4239 true /* realContentIsVisible */,
4240 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004241 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004242 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004243 };
4244
Ady Abrahameca9d752021-03-03 12:20:00 -08004245 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004246 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004247 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004248 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004249 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004250 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004251
Robert Carrccab4242021-09-28 16:53:03 -07004252 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004253 kDisplayDataspace));
4254}
4255
Lucas Dupin084a6d42021-08-26 22:10:29 +00004256TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4257 InjectedLayer layer1;
4258 InjectedLayer layer2;
4259
4260 uint32_t z = 0;
4261 // Layer requesting blur, or below, should request client composition, unless opaque.
4262 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4263 EXPECT_CALL(*layer1.outputLayer,
4264 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4265 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4266 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4267 EXPECT_CALL(*layer2.outputLayer,
4268 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4269 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4270
4271 layer2.layerFEState.backgroundBlurRadius = 10;
4272 layer2.layerFEState.isOpaque = true;
4273
4274 injectOutputLayer(layer1);
4275 injectOutputLayer(layer2);
4276
4277 mOutput->editState().isEnabled = true;
4278
4279 CompositionRefreshArgs args;
4280 args.updatingGeometryThisFrame = false;
4281 args.devOptForceClientComposition = false;
4282 mOutput->updateCompositionState(args);
4283 mOutput->planComposition();
4284 mOutput->writeCompositionState(args);
4285}
4286
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004287TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004288 InjectedLayer layer1;
4289 InjectedLayer layer2;
4290 InjectedLayer layer3;
4291
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004292 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004293 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004294 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004295 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004296 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4297 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004298 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004299 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004300 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4301 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004302 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004303 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004304 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4305 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004306
Lloyd Piquede196652020-01-22 17:29:58 -08004307 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004308 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004309
Lloyd Piquede196652020-01-22 17:29:58 -08004310 injectOutputLayer(layer1);
4311 injectOutputLayer(layer2);
4312 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004313
4314 mOutput->editState().isEnabled = true;
4315
4316 CompositionRefreshArgs args;
4317 args.updatingGeometryThisFrame = false;
4318 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004319 mOutput->updateCompositionState(args);
4320 mOutput->planComposition();
4321 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004322}
4323
Lucas Dupinc3800b82020-10-02 16:24:48 -07004324TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4325 InjectedLayer layer1;
4326 InjectedLayer layer2;
4327 InjectedLayer layer3;
4328
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004329 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004330 // Layer requesting blur, or below, should request client composition.
4331 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004332 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004333 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4334 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004335 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004336 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004337 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4338 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004339 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004340 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004341 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4342 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004343
4344 BlurRegion region;
4345 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004346 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004347
4348 injectOutputLayer(layer1);
4349 injectOutputLayer(layer2);
4350 injectOutputLayer(layer3);
4351
4352 mOutput->editState().isEnabled = true;
4353
4354 CompositionRefreshArgs args;
4355 args.updatingGeometryThisFrame = false;
4356 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004357 mOutput->updateCompositionState(args);
4358 mOutput->planComposition();
4359 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004360}
4361
Lloyd Piquea4863342019-12-04 18:45:02 -08004362TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4363 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4364 // one layer on the left covering the left side of the output, and one layer
4365 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004366
4367 const Rect kPortraitFrame(0, 0, 1000, 2000);
4368 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004369 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004370 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004371 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004372
Angel Aguayob084e0c2021-08-04 23:27:28 +00004373 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4374 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4375 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004376 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004377 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004378 mOutput.mState.needsFiltering = false;
4379 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004380
Lloyd Piquea4863342019-12-04 18:45:02 -08004381 Layer leftLayer;
4382 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004383
Lloyd Piquea4863342019-12-04 18:45:02 -08004384 leftLayer.mOutputLayerState.clearClientTarget = false;
4385 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4386 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004387 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004388
Lloyd Piquea4863342019-12-04 18:45:02 -08004389 rightLayer.mOutputLayerState.clearClientTarget = false;
4390 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4391 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004392 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004393
4394 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4395 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4396 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4397 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4398 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4399
Lloyd Piquea4863342019-12-04 18:45:02 -08004400 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4401 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004402 false, /* needs filtering */
4403 true, /* secure */
4404 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004405 kPortraitViewport,
4406 kOutputDataspace,
4407 true /* realContentIsVisible */,
4408 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004409 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004410 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004411 };
4412
4413 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4414 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004415 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004416 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004417
4418 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4419 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004420 false, /* needs filtering */
4421 true, /* secure */
4422 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004423 kPortraitViewport,
4424 kOutputDataspace,
4425 true /* realContentIsVisible */,
4426 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004427 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004428 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004429 };
4430
4431 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4432 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004433 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004434 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004435
4436 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004437 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004438 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004439 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004440 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4441 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004442}
4443
Vishnu Naira483b4a2019-12-12 15:07:52 -08004444TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4445 shadowRegionOnlyVisibleSkipsContentComposition) {
4446 const Rect kContentWithShadow(40, 40, 70, 90);
4447 const Rect kContent(50, 50, 60, 80);
4448 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4449 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4450
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004451 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4452 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004453 false, /* needs filtering */
4454 false, /* secure */
4455 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004456 kDisplayViewport,
4457 kDisplayDataspace,
4458 false /* realContentIsVisible */,
4459 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004460 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004461 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004462 };
4463
Vishnu Nair9b079a22020-01-21 14:36:08 -08004464 LayerFE::LayerSettings mShadowSettings;
4465 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004466
4467 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4468 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4469
4470 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4471 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004472 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004473 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004474
Robert Carrccab4242021-09-28 16:53:03 -07004475 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004476 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004477 ASSERT_EQ(1u, requests.size());
4478
Vishnu Nair9b079a22020-01-21 14:36:08 -08004479 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004480}
4481
4482TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4483 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4484 const Rect kContentWithShadow(40, 40, 70, 90);
4485 const Rect kContent(50, 50, 60, 80);
4486 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4487 const Region kPartialContentWithPartialShadowRegion =
4488 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4489
Vishnu Nair9b079a22020-01-21 14:36:08 -08004490 LayerFE::LayerSettings mShadowSettings;
4491 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004492
4493 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4494 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4495
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004496 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4497 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004498 false, /* needs filtering */
4499 false, /* secure */
4500 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004501 kDisplayViewport,
4502 kDisplayDataspace,
4503 true /* realContentIsVisible */,
4504 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004505 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004506 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004507 };
4508
Vishnu Naira483b4a2019-12-12 15:07:52 -08004509 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4510 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004511 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004512 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4513 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004514
Robert Carrccab4242021-09-28 16:53:03 -07004515 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004516 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004517 ASSERT_EQ(2u, requests.size());
4518
Vishnu Nair9b079a22020-01-21 14:36:08 -08004519 EXPECT_EQ(mShadowSettings, requests[0]);
4520 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004521}
4522
Lloyd Pique32cbe282018-10-19 13:09:22 -07004523} // namespace
4524} // namespace android::compositionengine