blob: cab4b8de568a258331a4c7b2dbf853299cfea57c [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>};
Ady Abrahame0eafa82022-02-02 19:30:47 -0800109 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800110 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;
Ady Abrahame0eafa82022-02-02 19:30:47 -0800126 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquede196652020-01-22 17:29:58 -0800127 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
Alec Mouricdf16792021-12-10 13:16:06 -0800579/**
580 * Output::setDisplayBrightness()
581 */
582
583TEST_F(OutputTest, setNextBrightness) {
584 constexpr float kDisplayBrightness = 0.5f;
585 mOutput->setNextBrightness(kDisplayBrightness);
586 ASSERT_TRUE(mOutput->getState().displayBrightness.has_value());
587 EXPECT_EQ(kDisplayBrightness, mOutput->getState().displayBrightness);
588}
589
Lloyd Pique66d68602019-02-13 14:23:31 -0800590/*
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000591 * Output::getDirtyRegion()
Lloyd Pique32cbe282018-10-19 13:09:22 -0700592 */
593
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700594TEST_F(OutputTest, getDirtyRegion) {
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000595 const Rect viewport{100, 200};
Angel Aguayob084e0c2021-08-04 23:27:28 +0000596 mOutput->editState().layerStackSpace.setContent(viewport);
Lloyd Piquea38ea7e2019-04-16 18:10:26 -0700597 mOutput->editState().dirtyRegion.set(50, 300);
Lloyd Pique32cbe282018-10-19 13:09:22 -0700598
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -0700599 // The dirty region should be clipped to the display bounds.
600 EXPECT_THAT(mOutput->getDirtyRegion(), RegionEq(Region(Rect(50, 200))));
Lloyd Pique32cbe282018-10-19 13:09:22 -0700601}
602
Lloyd Pique66d68602019-02-13 14:23:31 -0800603/*
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700604 * Output::includesLayer()
Lloyd Piqueef36b002019-01-23 17:52:04 -0800605 */
606
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700607TEST_F(OutputTest, layerFiltering) {
608 const ui::LayerStack layerStack1{123u};
609 const ui::LayerStack layerStack2{456u};
Lloyd Piqueef36b002019-01-23 17:52:04 -0800610
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700611 // If the output is associated to layerStack1 and to an internal display...
612 mOutput->setLayerFilter({layerStack1, true});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800613
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700614 // It excludes layers with no layer stack, internal-only or not.
615 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, false}));
616 EXPECT_FALSE(mOutput->includesLayer({ui::INVALID_LAYER_STACK, true}));
Lloyd Piquec6687342019-03-07 21:34:57 -0800617
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700618 // It includes layers on layerStack1, internal-only or not.
619 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
620 EXPECT_TRUE(mOutput->includesLayer({layerStack1, true}));
621 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
622 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800623
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700624 // If the output is associated to layerStack1 but not to an internal display...
625 mOutput->setLayerFilter({layerStack1, false});
Lloyd Piqueef36b002019-01-23 17:52:04 -0800626
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700627 // It includes layers on layerStack1, unless they are internal-only.
628 EXPECT_TRUE(mOutput->includesLayer({layerStack1, false}));
629 EXPECT_FALSE(mOutput->includesLayer({layerStack1, true}));
630 EXPECT_FALSE(mOutput->includesLayer({layerStack2, true}));
631 EXPECT_FALSE(mOutput->includesLayer({layerStack2, false}));
Lloyd Piqueef36b002019-01-23 17:52:04 -0800632}
633
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700634TEST_F(OutputTest, layerFilteringWithoutCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800635 NonInjectedLayer layer;
636 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800637
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700638 // Layers without composition state are excluded.
Lloyd Piquede196652020-01-22 17:29:58 -0800639 EXPECT_CALL(*layer.layerFE, getCompositionState).WillOnce(Return(nullptr));
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700640 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Piquede196652020-01-22 17:29:58 -0800641}
642
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700643TEST_F(OutputTest, layerFilteringWithCompositionState) {
Lloyd Piquede196652020-01-22 17:29:58 -0800644 NonInjectedLayer layer;
645 sp<LayerFE> layerFE(layer.layerFE);
Lloyd Pique66c20c42019-03-07 21:44:02 -0800646
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700647 const ui::LayerStack layerStack1{123u};
648 const ui::LayerStack layerStack2{456u};
Lloyd Pique66c20c42019-03-07 21:44:02 -0800649
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700650 // If the output is associated to layerStack1 and to an internal display...
651 mOutput->setLayerFilter({layerStack1, true});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800652
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 // It excludes layers with no layer stack, internal-only or not.
654 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, false};
655 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800656
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700657 layer.layerFEState.outputFilter = {ui::INVALID_LAYER_STACK, true};
658 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800659
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700660 // It includes layers on layerStack1, internal-only or not.
661 layer.layerFEState.outputFilter = {layerStack1, false};
662 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800663
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700664 layer.layerFEState.outputFilter = {layerStack1, true};
665 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800666
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700667 layer.layerFEState.outputFilter = {layerStack2, true};
668 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800669
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700670 layer.layerFEState.outputFilter = {layerStack2, false};
671 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800672
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700673 // If the output is associated to layerStack1 but not to an internal display...
674 mOutput->setLayerFilter({layerStack1, false});
Lloyd Pique66c20c42019-03-07 21:44:02 -0800675
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700676 // It includes layers on layerStack1, unless they are internal-only.
677 layer.layerFEState.outputFilter = {layerStack1, false};
678 EXPECT_TRUE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800679
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700680 layer.layerFEState.outputFilter = {layerStack1, true};
681 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800682
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700683 layer.layerFEState.outputFilter = {layerStack2, true};
684 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800685
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700686 layer.layerFEState.outputFilter = {layerStack2, false};
687 EXPECT_FALSE(mOutput->includesLayer(layerFE));
Lloyd Pique66c20c42019-03-07 21:44:02 -0800688}
689
Lloyd Pique66d68602019-02-13 14:23:31 -0800690/*
Lloyd Piquecc01a452018-12-04 17:24:00 -0800691 * Output::getOutputLayerForLayer()
692 */
693
694TEST_F(OutputTest, getOutputLayerForLayerWorks) {
Lloyd Piquede196652020-01-22 17:29:58 -0800695 InjectedLayer layer1;
696 InjectedLayer layer2;
697 NonInjectedLayer layer3;
Lloyd Piquecc01a452018-12-04 17:24:00 -0800698
Lloyd Piquede196652020-01-22 17:29:58 -0800699 injectOutputLayer(layer1);
700 injectNullOutputLayer();
701 injectOutputLayer(layer2);
Lloyd Piquecc01a452018-12-04 17:24:00 -0800702
703 // If the input layer matches the first OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800704 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
705 EXPECT_EQ(layer1.outputLayer, mOutput->getOutputLayerForLayer(layer1.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800706
707 // If the input layer matches the second OutputLayer, it will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800708 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
709 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
710 EXPECT_EQ(layer2.outputLayer, mOutput->getOutputLayerForLayer(layer2.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800711
712 // If the input layer does not match an output layer, null will be returned.
Lloyd Piquede196652020-01-22 17:29:58 -0800713 EXPECT_CALL(*layer1.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer1.layerFE.get()));
714 EXPECT_CALL(*layer2.outputLayer, getLayerFE()).WillOnce(ReturnRef(*layer2.layerFE.get()));
715 EXPECT_EQ(nullptr, mOutput->getOutputLayerForLayer(layer3.layerFE));
Lloyd Piquecc01a452018-12-04 17:24:00 -0800716}
717
Lloyd Pique66d68602019-02-13 14:23:31 -0800718/*
Lloyd Piquec9e60032019-11-14 11:47:26 -0800719 * Output::setReleasedLayers()
720 */
721
722using OutputSetReleasedLayersTest = OutputTest;
723
724TEST_F(OutputSetReleasedLayersTest, setReleasedLayersTakesGivenLayers) {
Ady Abrahame0eafa82022-02-02 19:30:47 -0800725 sp<StrictMock<mock::LayerFE>> layer1FE = sp<StrictMock<mock::LayerFE>>::make();
726 sp<StrictMock<mock::LayerFE>> layer2FE = sp<StrictMock<mock::LayerFE>>::make();
727 sp<StrictMock<mock::LayerFE>> layer3FE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquec9e60032019-11-14 11:47:26 -0800728
729 Output::ReleasedLayers layers;
730 layers.push_back(layer1FE);
731 layers.push_back(layer2FE);
732 layers.push_back(layer3FE);
733
734 mOutput->setReleasedLayers(std::move(layers));
735
736 const auto& setLayers = mOutput->getReleasedLayersForTest();
737 ASSERT_EQ(3u, setLayers.size());
738 ASSERT_EQ(layer1FE.get(), setLayers[0].promote().get());
739 ASSERT_EQ(layer2FE.get(), setLayers[1].promote().get());
740 ASSERT_EQ(layer3FE.get(), setLayers[2].promote().get());
741}
742
743/*
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800744 * Output::updateLayerStateFromFE()
745 */
746
Lloyd Piquede196652020-01-22 17:29:58 -0800747using OutputUpdateLayerStateFromFETest = OutputTest;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800748
749TEST_F(OutputUpdateLayerStateFromFETest, handlesNoOutputLayerCase) {
750 CompositionRefreshArgs refreshArgs;
751
752 mOutput->updateLayerStateFromFE(refreshArgs);
753}
754
Lloyd Piquede196652020-01-22 17:29:58 -0800755TEST_F(OutputUpdateLayerStateFromFETest, preparesContentStateForAllContainedLayers) {
756 InjectedLayer layer1;
757 InjectedLayer layer2;
758 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800759
Lloyd Piquede196652020-01-22 17:29:58 -0800760 EXPECT_CALL(*layer1.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
761 EXPECT_CALL(*layer2.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
762 EXPECT_CALL(*layer3.layerFE.get(), prepareCompositionState(LayerFE::StateSubset::Content));
763
764 injectOutputLayer(layer1);
765 injectOutputLayer(layer2);
766 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800767
768 CompositionRefreshArgs refreshArgs;
769 refreshArgs.updatingGeometryThisFrame = false;
770
771 mOutput->updateLayerStateFromFE(refreshArgs);
772}
773
Lloyd Piquede196652020-01-22 17:29:58 -0800774TEST_F(OutputUpdateLayerStateFromFETest, preparesGeometryAndContentStateForAllContainedLayers) {
775 InjectedLayer layer1;
776 InjectedLayer layer2;
777 InjectedLayer layer3;
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800778
Lloyd Piquede196652020-01-22 17:29:58 -0800779 EXPECT_CALL(*layer1.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
780 EXPECT_CALL(*layer2.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
781 EXPECT_CALL(*layer3.layerFE, prepareCompositionState(LayerFE::StateSubset::GeometryAndContent));
782
783 injectOutputLayer(layer1);
784 injectOutputLayer(layer2);
785 injectOutputLayer(layer3);
Lloyd Piquec0ee6ba2019-11-14 12:55:53 -0800786
787 CompositionRefreshArgs refreshArgs;
788 refreshArgs.updatingGeometryThisFrame = true;
789
790 mOutput->updateLayerStateFromFE(refreshArgs);
791}
792
793/*
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800794 * Output::updateAndWriteCompositionState()
795 */
796
Lloyd Piquede196652020-01-22 17:29:58 -0800797using OutputUpdateAndWriteCompositionStateTest = OutputTest;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800798
799TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfLayers) {
800 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800801
802 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800803 mOutput->updateCompositionState(args);
804 mOutput->planComposition();
805 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800806}
807
Lloyd Piqueef63b612019-11-14 13:19:56 -0800808TEST_F(OutputUpdateAndWriteCompositionStateTest, doesNothingIfOutputNotEnabled) {
Lloyd Piquede196652020-01-22 17:29:58 -0800809 InjectedLayer layer1;
810 InjectedLayer layer2;
811 InjectedLayer layer3;
812
Lloyd Piqueef63b612019-11-14 13:19:56 -0800813 mOutput->editState().isEnabled = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800814
Lloyd Piquede196652020-01-22 17:29:58 -0800815 injectOutputLayer(layer1);
816 injectOutputLayer(layer2);
817 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800818
819 CompositionRefreshArgs args;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800820 mOutput->updateCompositionState(args);
821 mOutput->planComposition();
822 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800823}
824
825TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800826 InjectedLayer layer1;
827 InjectedLayer layer2;
828 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800829
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400830 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200831 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800832 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400833 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
834 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200835 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800836 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400837 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
838 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200839 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_180));
Dan Stoza6166c312021-01-15 16:34:05 -0800840 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400841 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
842 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800843
844 injectOutputLayer(layer1);
845 injectOutputLayer(layer2);
846 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800847
848 mOutput->editState().isEnabled = true;
849
850 CompositionRefreshArgs args;
851 args.updatingGeometryThisFrame = false;
852 args.devOptForceClientComposition = false;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200853 args.internalDisplayRotationFlags = ui::Transform::ROT_180;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800854 mOutput->updateCompositionState(args);
855 mOutput->planComposition();
856 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800857}
858
859TEST_F(OutputUpdateAndWriteCompositionStateTest, updatesLayerGeometryAndContentForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800860 InjectedLayer layer1;
861 InjectedLayer layer2;
862 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800863
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400864 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200865 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800866 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400867 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
868 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200869 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800870 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400871 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
872 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200873 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800874 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400875 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
876 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800877
878 injectOutputLayer(layer1);
879 injectOutputLayer(layer2);
880 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800881
882 mOutput->editState().isEnabled = true;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800883
884 CompositionRefreshArgs args;
885 args.updatingGeometryThisFrame = true;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800886 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800887 mOutput->updateCompositionState(args);
888 mOutput->planComposition();
889 mOutput->writeCompositionState(args);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800890}
891
892TEST_F(OutputUpdateAndWriteCompositionStateTest, forcesClientCompositionForAllLayers) {
Lloyd Piquede196652020-01-22 17:29:58 -0800893 InjectedLayer layer1;
894 InjectedLayer layer2;
895 InjectedLayer layer3;
Lloyd Piqueef63b612019-11-14 13:19:56 -0800896
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -0400897 uint32_t z = 0;
Snild Dolkow9e217d62020-04-22 15:53:42 +0200898 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800899 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400900 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
901 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200902 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800903 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400904 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
905 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +0200906 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -0800907 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -0400908 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
909 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lloyd Piquede196652020-01-22 17:29:58 -0800910
911 injectOutputLayer(layer1);
912 injectOutputLayer(layer2);
913 injectOutputLayer(layer3);
Lloyd Piqueef63b612019-11-14 13:19:56 -0800914
915 mOutput->editState().isEnabled = true;
916
917 CompositionRefreshArgs args;
918 args.updatingGeometryThisFrame = false;
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800919 args.devOptForceClientComposition = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -0800920 mOutput->updateCompositionState(args);
921 mOutput->planComposition();
922 mOutput->writeCompositionState(args);
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800923}
924
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400925TEST_F(OutputUpdateAndWriteCompositionStateTest, peekThroughLayerChangesOrder) {
926 renderengine::mock::RenderEngine renderEngine;
927 InjectedLayer layer0;
928 InjectedLayer layer1;
929 InjectedLayer layer2;
930 InjectedLayer layer3;
931
932 InSequence seq;
933 EXPECT_CALL(*layer0.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
934 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
935 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
936 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(true, false, ui::Transform::ROT_0));
937
938 uint32_t z = 0;
939 EXPECT_CALL(*layer0.outputLayer,
940 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
941 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
942
943 // After calling planComposition (which clears overrideInfo), this test sets
944 // layer3 to be the peekThroughLayer for layer1 and layer2. As a result, it
945 // comes first, setting isPeekingThrough to true and zIsOverridden to true
946 // for it and the following layers.
947 EXPECT_CALL(*layer3.outputLayer,
948 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
949 /*zIsOverridden*/ true, /*isPeekingThrough*/
950 true));
951 EXPECT_CALL(*layer1.outputLayer,
952 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ false, z++,
953 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
954 EXPECT_CALL(*layer2.outputLayer,
955 writeStateToHWC(/*includeGeometry*/ true, /*skipLayer*/ true, z++,
956 /*zIsOverridden*/ true, /*isPeekingThrough*/ false));
957
958 injectOutputLayer(layer0);
959 injectOutputLayer(layer1);
960 injectOutputLayer(layer2);
961 injectOutputLayer(layer3);
962
963 mOutput->editState().isEnabled = true;
964
965 CompositionRefreshArgs args;
966 args.updatingGeometryThisFrame = true;
967 args.devOptForceClientComposition = false;
968 mOutput->updateCompositionState(args);
969 mOutput->planComposition();
970
971 std::shared_ptr<renderengine::ExternalTexture> buffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -0800972 renderengine::impl::
973 ExternalTexture>(new GraphicBuffer(), renderEngine,
974 renderengine::impl::ExternalTexture::Usage::READABLE |
975 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Leon Scroggins III2e74a4c2021-04-09 13:41:14 -0400976 layer1.outputLayerState.overrideInfo.buffer = buffer;
977 layer2.outputLayerState.overrideInfo.buffer = buffer;
978 layer1.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
979 layer2.outputLayerState.overrideInfo.peekThroughLayer = layer3.outputLayer;
980
981 mOutput->writeCompositionState(args);
982}
983
Alec Mourif9a2a2c2019-11-12 12:46:02 -0800984/*
Lloyd Pique66d68602019-02-13 14:23:31 -0800985 * Output::prepareFrame()
986 */
987
988struct OutputPrepareFrameTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -0800989 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -0800990 // Sets up the helper functions called by the function under test to use
991 // mock implementations.
Lloyd Pique66d68602019-02-13 14:23:31 -0800992 MOCK_METHOD0(chooseCompositionStrategy, void());
993 };
994
995 OutputPrepareFrameTest() {
996 mOutput.setDisplayColorProfileForTest(
997 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
998 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
999 }
1000
1001 StrictMock<mock::CompositionEngine> mCompositionEngine;
1002 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1003 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001004 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique66d68602019-02-13 14:23:31 -08001005};
1006
1007TEST_F(OutputPrepareFrameTest, takesEarlyOutIfNotEnabled) {
1008 mOutput.editState().isEnabled = false;
1009
1010 mOutput.prepareFrame();
1011}
1012
1013TEST_F(OutputPrepareFrameTest, delegatesToChooseCompositionStrategyAndRenderSurface) {
1014 mOutput.editState().isEnabled = true;
1015 mOutput.editState().usesClientComposition = false;
1016 mOutput.editState().usesDeviceComposition = true;
1017
1018 EXPECT_CALL(mOutput, chooseCompositionStrategy()).Times(1);
Alec Mouri023c1882021-05-08 16:36:33 -07001019 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique66d68602019-02-13 14:23:31 -08001020 EXPECT_CALL(*mRenderSurface, prepareFrame(false, true));
1021
1022 mOutput.prepareFrame();
1023}
1024
1025// Note: Use OutputTest and not OutputPrepareFrameTest, so the real
1026// base chooseCompositionStrategy() is invoked.
1027TEST_F(OutputTest, prepareFrameSetsClientCompositionOnlyByDefault) {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001028 mOutput->editState().isEnabled = true;
1029 mOutput->editState().usesClientComposition = false;
1030 mOutput->editState().usesDeviceComposition = true;
Lloyd Pique66d68602019-02-13 14:23:31 -08001031
1032 EXPECT_CALL(*mRenderSurface, prepareFrame(true, false));
1033
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001034 mOutput->prepareFrame();
Lloyd Pique66d68602019-02-13 14:23:31 -08001035
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07001036 EXPECT_TRUE(mOutput->getState().usesClientComposition);
1037 EXPECT_FALSE(mOutput->getState().usesDeviceComposition);
Lloyd Pique66d68602019-02-13 14:23:31 -08001038}
1039
Lloyd Pique56eba802019-08-28 15:45:25 -07001040/*
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001041 * Output::prepare()
1042 */
1043
1044struct OutputPrepareTest : public testing::Test {
1045 struct OutputPartialMock : public OutputPartialMockBase {
1046 // Sets up the helper functions called by the function under test to use
1047 // mock implementations.
1048 MOCK_METHOD2(rebuildLayerStacks,
1049 void(const compositionengine::CompositionRefreshArgs&,
1050 compositionengine::LayerFESet&));
1051 };
1052
1053 StrictMock<OutputPartialMock> mOutput;
1054 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001055 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001056};
1057
1058TEST_F(OutputPrepareTest, justInvokesRebuildLayerStacks) {
1059 InSequence seq;
1060 EXPECT_CALL(mOutput, rebuildLayerStacks(Ref(mRefreshArgs), Ref(mGeomSnapshots)));
1061
1062 mOutput.prepare(mRefreshArgs, mGeomSnapshots);
1063}
1064
1065/*
1066 * Output::rebuildLayerStacks()
1067 */
1068
1069struct OutputRebuildLayerStacksTest : public testing::Test {
1070 struct OutputPartialMock : public OutputPartialMockBase {
1071 // Sets up the helper functions called by the function under test to use
1072 // mock implementations.
1073 MOCK_METHOD2(collectVisibleLayers,
1074 void(const compositionengine::CompositionRefreshArgs&,
1075 compositionengine::Output::CoverageState&));
1076 };
1077
1078 OutputRebuildLayerStacksTest() {
1079 mOutput.mState.isEnabled = true;
1080 mOutput.mState.transform = kIdentityTransform;
Angel Aguayob084e0c2021-08-04 23:27:28 +00001081 mOutput.mState.displaySpace.setBounds(
1082 ui::Size(kOutputBounds.getWidth(), kOutputBounds.getHeight()));
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001083
1084 mRefreshArgs.updatingOutputGeometryThisFrame = true;
1085
1086 mCoverageAboveCoveredLayersToSet = Region(Rect(0, 0, 10, 10));
1087
1088 EXPECT_CALL(mOutput, collectVisibleLayers(Ref(mRefreshArgs), _))
1089 .WillRepeatedly(Invoke(this, &OutputRebuildLayerStacksTest::setTestCoverageValues));
1090 }
1091
1092 void setTestCoverageValues(const CompositionRefreshArgs&,
1093 compositionengine::Output::CoverageState& state) {
1094 state.aboveCoveredLayers = mCoverageAboveCoveredLayersToSet;
1095 state.aboveOpaqueLayers = mCoverageAboveOpaqueLayersToSet;
1096 state.dirtyRegion = mCoverageDirtyRegionToSet;
1097 }
1098
1099 static const ui::Transform kIdentityTransform;
1100 static const ui::Transform kRotate90Transform;
1101 static const Rect kOutputBounds;
1102
1103 StrictMock<OutputPartialMock> mOutput;
1104 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001105 LayerFESet mGeomSnapshots;
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001106 Region mCoverageAboveCoveredLayersToSet;
1107 Region mCoverageAboveOpaqueLayersToSet;
1108 Region mCoverageDirtyRegionToSet;
1109};
1110
1111const ui::Transform OutputRebuildLayerStacksTest::kIdentityTransform{TR_IDENT, 1920, 1080};
1112const ui::Transform OutputRebuildLayerStacksTest::kRotate90Transform{TR_ROT_90, 1920, 1080};
1113const Rect OutputRebuildLayerStacksTest::kOutputBounds{0, 0, 1920, 1080};
1114
1115TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotEnabled) {
1116 mOutput.mState.isEnabled = false;
1117
1118 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1119}
1120
1121TEST_F(OutputRebuildLayerStacksTest, doesNothingIfNotUpdatingGeometryThisFrame) {
1122 mRefreshArgs.updatingOutputGeometryThisFrame = false;
1123
1124 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1125}
1126
1127TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndFullCoverage) {
1128 mOutput.mState.transform = kIdentityTransform;
1129
1130 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1920, 1080));
1131
1132 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1133
1134 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1135}
1136
1137TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWithNoRotationAndPartialCoverage) {
1138 mOutput.mState.transform = kIdentityTransform;
1139
1140 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 960, 1080));
1141
1142 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1143
1144 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(960, 0, 1920, 1080))));
1145}
1146
1147TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndFullCoverage) {
1148 mOutput.mState.transform = kRotate90Transform;
1149
1150 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 1920));
1151
1152 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1153
1154 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 0, 0))));
1155}
1156
1157TEST_F(OutputRebuildLayerStacksTest, computesUndefinedRegionWith90RotationAndPartialCoverage) {
1158 mOutput.mState.transform = kRotate90Transform;
1159
1160 mCoverageAboveOpaqueLayersToSet = Region(Rect(0, 0, 1080, 960));
1161
1162 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1163
1164 EXPECT_THAT(mOutput.mState.undefinedRegion, RegionEq(Region(Rect(0, 0, 960, 1080))));
1165}
1166
1167TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWithNoRotation) {
1168 mOutput.mState.transform = kIdentityTransform;
1169 mOutput.mState.dirtyRegion = Region(Rect(960, 0, 1920, 1080));
1170
1171 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 960, 1080));
1172
1173 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1174
1175 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1920, 1080))));
1176}
1177
1178TEST_F(OutputRebuildLayerStacksTest, addsToDirtyRegionWith90Rotation) {
1179 mOutput.mState.transform = kRotate90Transform;
1180 mOutput.mState.dirtyRegion = Region(Rect(0, 960, 1080, 1920));
1181
1182 mCoverageDirtyRegionToSet = Region(Rect(0, 0, 1080, 960));
1183
1184 mOutput.rebuildLayerStacks(mRefreshArgs, mGeomSnapshots);
1185
1186 EXPECT_THAT(mOutput.mState.dirtyRegion, RegionEq(Region(Rect(0, 0, 1080, 1920))));
1187}
1188
1189/*
1190 * Output::collectVisibleLayers()
1191 */
1192
Lloyd Pique1ef93222019-11-21 16:41:53 -08001193struct OutputCollectVisibleLayersTest : public testing::Test {
1194 struct OutputPartialMock : public OutputPartialMockBase {
1195 // Sets up the helper functions called by the function under test to use
1196 // mock implementations.
1197 MOCK_METHOD2(ensureOutputLayerIfVisible,
Lloyd Piquede196652020-01-22 17:29:58 -08001198 void(sp<compositionengine::LayerFE>&,
Lloyd Pique1ef93222019-11-21 16:41:53 -08001199 compositionengine::Output::CoverageState&));
1200 MOCK_METHOD1(setReleasedLayers, void(const compositionengine::CompositionRefreshArgs&));
1201 MOCK_METHOD0(finalizePendingOutputLayers, void());
1202 };
1203
1204 struct Layer {
1205 Layer() {
1206 EXPECT_CALL(outputLayer, getState()).WillRepeatedly(ReturnRef(outputLayerState));
1207 EXPECT_CALL(outputLayer, editState()).WillRepeatedly(ReturnRef(outputLayerState));
1208 }
1209
1210 StrictMock<mock::OutputLayer> outputLayer;
Lloyd Pique1ef93222019-11-21 16:41:53 -08001211 impl::OutputLayerCompositionState outputLayerState;
Ady Abrahame0eafa82022-02-02 19:30:47 -08001212 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique1ef93222019-11-21 16:41:53 -08001213 };
1214
1215 OutputCollectVisibleLayersTest() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001216 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001217 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1218 .WillRepeatedly(Return(&mLayer1.outputLayer));
1219 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1220 .WillRepeatedly(Return(&mLayer2.outputLayer));
1221 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1222 .WillRepeatedly(Return(&mLayer3.outputLayer));
1223
Lloyd Piquede196652020-01-22 17:29:58 -08001224 mRefreshArgs.layers.push_back(mLayer1.layerFE);
1225 mRefreshArgs.layers.push_back(mLayer2.layerFE);
1226 mRefreshArgs.layers.push_back(mLayer3.layerFE);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001227 }
1228
1229 StrictMock<OutputPartialMock> mOutput;
1230 CompositionRefreshArgs mRefreshArgs;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001231 LayerFESet mGeomSnapshots;
1232 Output::CoverageState mCoverageState{mGeomSnapshots};
Lloyd Pique1ef93222019-11-21 16:41:53 -08001233 Layer mLayer1;
1234 Layer mLayer2;
1235 Layer mLayer3;
1236};
1237
1238TEST_F(OutputCollectVisibleLayersTest, doesMinimalWorkIfNoLayers) {
1239 mRefreshArgs.layers.clear();
Lloyd Pique0a456232020-01-16 17:51:13 -08001240 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001241
1242 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1243 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1244
1245 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
1246}
1247
1248TEST_F(OutputCollectVisibleLayersTest, processesCandidateLayersReversedAndSetsOutputLayerZ) {
1249 // Enforce a call order sequence for this test.
1250 InSequence seq;
1251
1252 // Layer coverage is evaluated from front to back!
Lloyd Piquede196652020-01-22 17:29:58 -08001253 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer3.layerFE), Ref(mCoverageState)));
1254 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer2.layerFE), Ref(mCoverageState)));
1255 EXPECT_CALL(mOutput, ensureOutputLayerIfVisible(Eq(mLayer1.layerFE), Ref(mCoverageState)));
Lloyd Pique1ef93222019-11-21 16:41:53 -08001256
1257 EXPECT_CALL(mOutput, setReleasedLayers(Ref(mRefreshArgs)));
1258 EXPECT_CALL(mOutput, finalizePendingOutputLayers());
1259
1260 mOutput.collectVisibleLayers(mRefreshArgs, mCoverageState);
Lloyd Pique1ef93222019-11-21 16:41:53 -08001261}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001262
1263/*
1264 * Output::ensureOutputLayerIfVisible()
1265 */
1266
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001267struct OutputEnsureOutputLayerIfVisibleTest : public testing::Test {
1268 struct OutputPartialMock : public OutputPartialMockBase {
1269 // Sets up the helper functions called by the function under test to use
1270 // mock implementations.
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001271 MOCK_METHOD(bool, includesLayer, (const sp<compositionengine::LayerFE>&),
1272 (const, override));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001273 MOCK_CONST_METHOD1(getOutputLayerOrderedByZByIndex, OutputLayer*(size_t));
Lloyd Piquede196652020-01-22 17:29:58 -08001274 MOCK_METHOD2(ensureOutputLayer,
1275 compositionengine::OutputLayer*(std::optional<size_t>, const sp<LayerFE>&));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001276 };
1277
1278 OutputEnsureOutputLayerIfVisibleTest() {
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001279 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE)))
Lloyd Piquede196652020-01-22 17:29:58 -08001280 .WillRepeatedly(Return(true));
Lloyd Pique0a456232020-01-16 17:51:13 -08001281 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001282 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
Lloyd Piquede196652020-01-22 17:29:58 -08001283 .WillRepeatedly(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001284
Angel Aguayob084e0c2021-08-04 23:27:28 +00001285 mOutput.mState.displaySpace.setBounds(ui::Size(200, 300));
1286 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 200, 300));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001287 mOutput.mState.transform = ui::Transform(TR_IDENT, 200, 300);
1288
Lloyd Piquede196652020-01-22 17:29:58 -08001289 mLayer.layerFEState.isVisible = true;
1290 mLayer.layerFEState.isOpaque = true;
1291 mLayer.layerFEState.contentDirty = true;
1292 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1293 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001294 mLayer.layerFEState.transparentRegionHint = kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001295
Lloyd Piquede196652020-01-22 17:29:58 -08001296 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 50, 200));
1297 mLayer.outputLayerState.coveredRegion = Region(Rect(50, 0, 100, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001298
Lloyd Piquede196652020-01-22 17:29:58 -08001299 mGeomSnapshots.insert(mLayer.layerFE);
1300 }
1301
1302 void ensureOutputLayerIfVisible() {
1303 sp<LayerFE> layerFE(mLayer.layerFE);
1304 mOutput.ensureOutputLayerIfVisible(layerFE, mCoverageState);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001305 }
1306
1307 static const Region kEmptyRegion;
1308 static const Region kFullBoundsNoRotation;
1309 static const Region kRightHalfBoundsNoRotation;
1310 static const Region kLowerHalfBoundsNoRotation;
1311 static const Region kFullBounds90Rotation;
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001312 static const Region kTransparentRegionHint;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001313
1314 StrictMock<OutputPartialMock> mOutput;
1315 LayerFESet mGeomSnapshots;
1316 Output::CoverageState mCoverageState{mGeomSnapshots};
1317
Lloyd Piquede196652020-01-22 17:29:58 -08001318 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001319};
1320
1321const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1322const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1323 Region(Rect(0, 0, 100, 200));
1324const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1325 Region(Rect(0, 100, 100, 200));
1326const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1327 Region(Rect(50, 0, 100, 200));
1328const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1329 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001330const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
1331 Region(Rect(0, 0, 100, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001332
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001333TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1334 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001335 EXPECT_CALL(*mLayer.layerFE,
1336 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001337
1338 mGeomSnapshots.clear();
1339
Lloyd Piquede196652020-01-22 17:29:58 -08001340 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001341}
1342
1343TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001344 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1345 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001346
Lloyd Piquede196652020-01-22 17:29:58 -08001347 ensureOutputLayerIfVisible();
1348}
1349
1350TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1351 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1352
1353 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001354}
1355
1356TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001357 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001358
Lloyd Piquede196652020-01-22 17:29:58 -08001359 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001360}
1361
1362TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001363 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001364
Lloyd Piquede196652020-01-22 17:29:58 -08001365 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001366}
1367
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001368TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001369 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001370
Lloyd Piquede196652020-01-22 17:29:58 -08001371 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001372}
1373
1374TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1375 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001376 mLayer.layerFEState.isOpaque = true;
1377 mLayer.layerFEState.contentDirty = true;
1378 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001379
1380 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001381 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1382 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001383
Lloyd Piquede196652020-01-22 17:29:58 -08001384 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001385
1386 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1387 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1388 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1389
Lloyd Piquede196652020-01-22 17:29:58 -08001390 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1391 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1392 RegionEq(kFullBoundsNoRotation));
1393 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1394 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001395}
1396
1397TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1398 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001399 mLayer.layerFEState.isOpaque = true;
1400 mLayer.layerFEState.contentDirty = true;
1401 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001402
Lloyd Piquede196652020-01-22 17:29:58 -08001403 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1404 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001405
Lloyd Piquede196652020-01-22 17:29:58 -08001406 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001407
1408 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1409 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1410 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1411
Lloyd Piquede196652020-01-22 17:29:58 -08001412 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1413 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1414 RegionEq(kFullBoundsNoRotation));
1415 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1416 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001417}
1418
1419TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1420 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001421 mLayer.layerFEState.isOpaque = false;
1422 mLayer.layerFEState.contentDirty = true;
1423 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001424
1425 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001426 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1427 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001428
Lloyd Piquede196652020-01-22 17:29:58 -08001429 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001430
1431 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1432 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1433 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1434
Lloyd Piquede196652020-01-22 17:29:58 -08001435 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1436 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001437 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001438 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1439 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440}
1441
1442TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1443 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001444 mLayer.layerFEState.isOpaque = false;
1445 mLayer.layerFEState.contentDirty = true;
1446 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001447
Lloyd Piquede196652020-01-22 17:29:58 -08001448 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1449 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001452
1453 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1454 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1455 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1456
Lloyd Piquede196652020-01-22 17:29:58 -08001457 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1458 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001459 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001460 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1461 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001462}
1463
1464TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1465 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001466 mLayer.layerFEState.isOpaque = true;
1467 mLayer.layerFEState.contentDirty = false;
1468 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001469
1470 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001471 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1472 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001473
Lloyd Piquede196652020-01-22 17:29:58 -08001474 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001475
1476 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1477 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1478 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1479
Lloyd Piquede196652020-01-22 17:29:58 -08001480 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1481 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1482 RegionEq(kFullBoundsNoRotation));
1483 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1484 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001485}
1486
1487TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1488 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001489 mLayer.layerFEState.isOpaque = true;
1490 mLayer.layerFEState.contentDirty = false;
1491 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001492
Lloyd Piquede196652020-01-22 17:29:58 -08001493 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1494 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495
Lloyd Piquede196652020-01-22 17:29:58 -08001496 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001497
1498 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1499 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1500 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1501
Lloyd Piquede196652020-01-22 17:29:58 -08001502 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1503 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1504 RegionEq(kFullBoundsNoRotation));
1505 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1506 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001507}
1508
1509TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1510 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001511 mLayer.layerFEState.isOpaque = true;
1512 mLayer.layerFEState.contentDirty = true;
1513 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1514 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1515 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1516 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001517
1518 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001519 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1520 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001521
Lloyd Piquede196652020-01-22 17:29:58 -08001522 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001523
1524 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1525 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1526 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1527
Lloyd Piquede196652020-01-22 17:29:58 -08001528 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1529 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1530 RegionEq(kFullBoundsNoRotation));
1531 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1532 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001533}
1534
1535TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1536 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001537 mLayer.layerFEState.isOpaque = true;
1538 mLayer.layerFEState.contentDirty = true;
1539 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1540 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1541 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1542 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001543
Lloyd Piquede196652020-01-22 17:29:58 -08001544 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1545 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546
Lloyd Piquede196652020-01-22 17:29:58 -08001547 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001548
1549 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1550 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1551 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1552
Lloyd Piquede196652020-01-22 17:29:58 -08001553 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1554 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1555 RegionEq(kFullBoundsNoRotation));
1556 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1557 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001558}
1559
1560TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1561 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001562 mLayer.layerFEState.isOpaque = true;
1563 mLayer.layerFEState.contentDirty = true;
1564 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001565
Angel Aguayob084e0c2021-08-04 23:27:28 +00001566 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001567 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1568
1569 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001570 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1571 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001572
Lloyd Piquede196652020-01-22 17:29:58 -08001573 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001574
1575 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1576 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1577 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1578
Lloyd Piquede196652020-01-22 17:29:58 -08001579 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1581 RegionEq(kFullBoundsNoRotation));
1582 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1583 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001584}
1585
1586TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1587 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001588 mLayer.layerFEState.isOpaque = true;
1589 mLayer.layerFEState.contentDirty = true;
1590 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001591
Angel Aguayob084e0c2021-08-04 23:27:28 +00001592 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001593 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1594
Lloyd Piquede196652020-01-22 17:29:58 -08001595 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1596 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001597
Lloyd Piquede196652020-01-22 17:29:58 -08001598 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001599
1600 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1601 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1602 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1603
Lloyd Piquede196652020-01-22 17:29:58 -08001604 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1605 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1606 RegionEq(kFullBoundsNoRotation));
1607 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1608 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001609}
1610
1611TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1612 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1613 ui::Transform arbitraryTransform;
1614 arbitraryTransform.set(1, 1, -1, 1);
1615 arbitraryTransform.set(0, 100);
1616
Lloyd Piquede196652020-01-22 17:29:58 -08001617 mLayer.layerFEState.isOpaque = true;
1618 mLayer.layerFEState.contentDirty = true;
1619 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1620 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001621
1622 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001623 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1624 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001625
Lloyd Piquede196652020-01-22 17:29:58 -08001626 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001627
1628 const Region kRegion = Region(Rect(0, 0, 300, 300));
1629 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1630
1631 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1632 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1633 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1634
Lloyd Piquede196652020-01-22 17:29:58 -08001635 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1636 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1637 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1638 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001639}
1640
1641TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001642 mLayer.layerFEState.isOpaque = false;
1643 mLayer.layerFEState.contentDirty = true;
1644 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001645
1646 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1647 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1648 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1649
Lloyd Piquede196652020-01-22 17:29:58 -08001650 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1651 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001652
Lloyd Piquede196652020-01-22 17:29:58 -08001653 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001654
1655 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1656 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1657 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1658 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1659 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1660 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1661
1662 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1663 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1664 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1665
Lloyd Piquede196652020-01-22 17:29:58 -08001666 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1667 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001668 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001669 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1670 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1671 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001672}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001673
Vishnu Naira483b4a2019-12-12 15:07:52 -08001674TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1675 ui::Transform translate;
1676 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001677 mLayer.layerFEState.geomLayerTransform = translate;
1678 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001679
1680 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1681 // half of the layer including the casting shadow is covered and opaque
1682 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1683 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1684
Lloyd Piquede196652020-01-22 17:29:58 -08001685 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1686 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001687
Lloyd Piquede196652020-01-22 17:29:58 -08001688 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001689
1690 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1691 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1692 // add starting opaque region to the opaque half of the casting layer bounds
1693 const Region kExpectedAboveOpaqueRegion =
1694 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1695 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1696 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1697 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1698 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1699 const Region kExpectedLayerShadowRegion =
1700 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1701
1702 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1703 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1704 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1705
Lloyd Piquede196652020-01-22 17:29:58 -08001706 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1707 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001708 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1710 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001711 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001712 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001713 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1714}
1715
1716TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1717 ui::Transform translate;
1718 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001719 mLayer.layerFEState.geomLayerTransform = translate;
1720 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001721
1722 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1723 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1724 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1725 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1726
Lloyd Piquede196652020-01-22 17:29:58 -08001727 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1728 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001731
1732 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1733 const Region kExpectedLayerShadowRegion =
1734 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1735
Lloyd Piquede196652020-01-22 17:29:58 -08001736 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1737 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001738 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1739}
1740
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001741TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001742 ui::Transform translate;
1743 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001744 mLayer.layerFEState.geomLayerTransform = translate;
1745 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001746
1747 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1748 // Casting layer and its shadows are covered by an opaque region
1749 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1750 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1751
Lloyd Piquede196652020-01-22 17:29:58 -08001752 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001753}
1754
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001755TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1756 mLayer.layerFEState.isOpaque = false;
1757 mLayer.layerFEState.contentDirty = true;
1758 mLayer.layerFEState.compositionType =
1759 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1760
1761 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1762 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1763 .WillOnce(Return(&mLayer.outputLayer));
1764 ensureOutputLayerIfVisible();
1765
1766 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1767 RegionEq(kTransparentRegionHint));
1768}
1769
1770TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1771 mLayer.layerFEState.isOpaque = false;
1772 mLayer.layerFEState.contentDirty = true;
1773
1774 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1775 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1776 .WillOnce(Return(&mLayer.outputLayer));
1777 ensureOutputLayerIfVisible();
1778
1779 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1780}
1781
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001782/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001783 * Output::present()
1784 */
1785
1786struct OutputPresentTest : public testing::Test {
1787 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001788 // Sets up the helper functions called by the function under test to use
1789 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001790 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001791 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001792 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001793 MOCK_METHOD0(planComposition, void());
1794 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001795 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1796 MOCK_METHOD0(beginFrame, void());
1797 MOCK_METHOD0(prepareFrame, void());
1798 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
1799 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
1800 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001801 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001802 };
1803
1804 StrictMock<OutputPartialMock> mOutput;
1805};
1806
1807TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1808 CompositionRefreshArgs args;
1809
1810 InSequence seq;
1811 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001812 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1813 EXPECT_CALL(mOutput, planComposition());
1814 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001815 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1816 EXPECT_CALL(mOutput, beginFrame());
1817 EXPECT_CALL(mOutput, prepareFrame());
1818 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
1819 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
1820 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001821 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001822
1823 mOutput.present(args);
1824}
1825
1826/*
1827 * Output::updateColorProfile()
1828 */
1829
Lloyd Pique17ca7422019-11-14 14:24:10 -08001830struct OutputUpdateColorProfileTest : public testing::Test {
1831 using TestType = OutputUpdateColorProfileTest;
1832
1833 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001834 // Sets up the helper functions called by the function under test to use
1835 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001836 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1837 };
1838
1839 struct Layer {
1840 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001841 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1842 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001843 }
1844
1845 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001846 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001847 LayerFECompositionState mLayerFEState;
1848 };
1849
1850 OutputUpdateColorProfileTest() {
1851 mOutput.setDisplayColorProfileForTest(
1852 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1853 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1854
1855 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1856 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1857 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1858 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1859 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1860 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1861 }
1862
1863 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1864 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1865 };
1866
1867 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1868 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1869 StrictMock<OutputPartialMock> mOutput;
1870
1871 Layer mLayer1;
1872 Layer mLayer2;
1873 Layer mLayer3;
1874
1875 CompositionRefreshArgs mRefreshArgs;
1876};
1877
1878// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1879// to make it easier to write unit tests.
1880
1881TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1882 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1883 // a simple default color profile without looking at anything else.
1884
Lloyd Pique0a456232020-01-16 17:51:13 -08001885 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001886 EXPECT_CALL(mOutput,
1887 setColorProfile(ColorProfileEq(
1888 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1889 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1890
1891 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1892 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1893
1894 mOutput.updateColorProfile(mRefreshArgs);
1895}
1896
1897struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1898 : public OutputUpdateColorProfileTest {
1899 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001900 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001901 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1902 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1903 }
1904
1905 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1906 : public CallOrderStateMachineHelper<
1907 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1908 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1909 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1910 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1911 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1912 _))
1913 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1914 SetArgPointee<4>(renderIntent)));
1915 EXPECT_CALL(getInstance()->mOutput,
1916 setColorProfile(
1917 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1918 ui::Dataspace::UNKNOWN})));
1919 return nextState<ExecuteState>();
1920 }
1921 };
1922
1923 // Call this member function to start using the mini-DSL defined above.
1924 [[nodiscard]] auto verify() {
1925 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1926 }
1927};
1928
1929TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1930 Native_Unknown_Colorimetric_Set) {
1931 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1932 ui::Dataspace::UNKNOWN,
1933 ui::RenderIntent::COLORIMETRIC)
1934 .execute();
1935}
1936
1937TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1938 DisplayP3_DisplayP3_Enhance_Set) {
1939 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1940 ui::Dataspace::DISPLAY_P3,
1941 ui::RenderIntent::ENHANCE)
1942 .execute();
1943}
1944
1945struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1946 : public OutputUpdateColorProfileTest {
1947 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001948 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001949 EXPECT_CALL(*mDisplayColorProfile,
1950 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1951 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1952 SetArgPointee<3>(ui::ColorMode::NATIVE),
1953 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1954 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1955 }
1956
1957 struct IfColorSpaceAgnosticDataspaceSetToState
1958 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1959 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1960 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1961 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1962 }
1963 };
1964
1965 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1966 : public CallOrderStateMachineHelper<
1967 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1968 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1969 ui::Dataspace dataspace) {
1970 EXPECT_CALL(getInstance()->mOutput,
1971 setColorProfile(ColorProfileEq(
1972 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1973 ui::RenderIntent::COLORIMETRIC, dataspace})));
1974 return nextState<ExecuteState>();
1975 }
1976 };
1977
1978 // Call this member function to start using the mini-DSL defined above.
1979 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
1980};
1981
1982TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
1983 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
1984 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
1985 .execute();
1986}
1987
1988TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
1989 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
1990 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
1991 .execute();
1992}
1993
1994struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
1995 : public OutputUpdateColorProfileTest {
1996 // Internally the implementation looks through the dataspaces of all the
1997 // visible layers. The topmost one that also has an actual dataspace
1998 // preference set is used to drive subsequent choices.
1999
2000 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2001 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2002 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2003
Lloyd Pique0a456232020-01-16 17:51:13 -08002004 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002005 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2006 }
2007
2008 struct IfTopLayerDataspaceState
2009 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2010 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2011 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2012 return nextState<AndIfMiddleLayerDataspaceState>();
2013 }
2014 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2015 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2016 }
2017 };
2018
2019 struct AndIfMiddleLayerDataspaceState
2020 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2021 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2022 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2023 return nextState<AndIfBottomLayerDataspaceState>();
2024 }
2025 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2026 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2027 }
2028 };
2029
2030 struct AndIfBottomLayerDataspaceState
2031 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2032 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2033 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2034 return nextState<ThenExpectBestColorModeCallUsesState>();
2035 }
2036 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2037 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2038 }
2039 };
2040
2041 struct ThenExpectBestColorModeCallUsesState
2042 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2043 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2044 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2045 getBestColorMode(dataspace, _, _, _, _));
2046 return nextState<ExecuteState>();
2047 }
2048 };
2049
2050 // Call this member function to start using the mini-DSL defined above.
2051 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2052};
2053
2054TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2055 noStrongLayerPrefenceUses_V0_SRGB) {
2056 // If none of the layers indicate a preference, then V0_SRGB is the
2057 // preferred choice (subject to additional checks).
2058 verify().ifTopLayerHasNoPreference()
2059 .andIfMiddleLayerHasNoPreference()
2060 .andIfBottomLayerHasNoPreference()
2061 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2062 .execute();
2063}
2064
2065TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2066 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2067 // If only the topmost layer has a preference, then that is what is chosen.
2068 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2069 .andIfMiddleLayerHasNoPreference()
2070 .andIfBottomLayerHasNoPreference()
2071 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2072 .execute();
2073}
2074
2075TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2076 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2077 // If only the middle layer has a preference, that that is what is chosen.
2078 verify().ifTopLayerHasNoPreference()
2079 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2080 .andIfBottomLayerHasNoPreference()
2081 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2082 .execute();
2083}
2084
2085TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2086 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2087 // If only the middle layer has a preference, that that is what is chosen.
2088 verify().ifTopLayerHasNoPreference()
2089 .andIfMiddleLayerHasNoPreference()
2090 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2091 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2092 .execute();
2093}
2094
2095TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2096 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2097 // If multiple layers have a preference, the topmost value is what is used.
2098 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2099 .andIfMiddleLayerHasNoPreference()
2100 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2101 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2102 .execute();
2103}
2104
2105TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2106 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2107 // If multiple layers have a preference, the topmost value is what is used.
2108 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2109 .andIfMiddleLayerHasNoPreference()
2110 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2111 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2112 .execute();
2113}
2114
2115struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2116 : public OutputUpdateColorProfileTest {
2117 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2118 // values, it overrides the layer dataspace choice.
2119
2120 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2121 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2122 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2123
2124 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2125
Lloyd Pique0a456232020-01-16 17:51:13 -08002126 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002127 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2128 }
2129
2130 struct IfForceOutputColorModeState
2131 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2132 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2133 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2134 return nextState<ThenExpectBestColorModeCallUsesState>();
2135 }
2136 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2137 };
2138
2139 struct ThenExpectBestColorModeCallUsesState
2140 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2141 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2142 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2143 getBestColorMode(dataspace, _, _, _, _));
2144 return nextState<ExecuteState>();
2145 }
2146 };
2147
2148 // Call this member function to start using the mini-DSL defined above.
2149 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2150};
2151
2152TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2153 // By default the layer state is used to set the preferred dataspace
2154 verify().ifNoOverride()
2155 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2156 .execute();
2157}
2158
2159TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2160 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2161 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2162 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2163 .execute();
2164}
2165
2166TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2167 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2168 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2169 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2170 .execute();
2171}
2172
2173// HDR output requires all layers to be compatible with the chosen HDR
2174// dataspace, along with there being proper support.
2175struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2176 OutputUpdateColorProfileTest_Hdr() {
2177 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2178 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002179 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002180 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2181 }
2182
2183 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2184 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2185 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2186 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2187
2188 struct IfTopLayerDataspaceState
2189 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2190 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2191 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2192 return nextState<AndTopLayerCompositionTypeState>();
2193 }
2194 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2195 };
2196
2197 struct AndTopLayerCompositionTypeState
2198 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2199 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2200 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2201 return nextState<AndIfBottomLayerDataspaceState>();
2202 }
2203 };
2204
2205 struct AndIfBottomLayerDataspaceState
2206 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2207 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2208 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2209 return nextState<AndBottomLayerCompositionTypeState>();
2210 }
2211 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2212 return andIfBottomLayerIs(kNonHdrDataspace);
2213 }
2214 };
2215
2216 struct AndBottomLayerCompositionTypeState
2217 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2218 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2219 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2220 return nextState<AndIfHasLegacySupportState>();
2221 }
2222 };
2223
2224 struct AndIfHasLegacySupportState
2225 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2226 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2227 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2228 .WillOnce(Return(legacySupport));
2229 return nextState<ThenExpectBestColorModeCallUsesState>();
2230 }
2231 };
2232
2233 struct ThenExpectBestColorModeCallUsesState
2234 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2235 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2236 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2237 getBestColorMode(dataspace, _, _, _, _));
2238 return nextState<ExecuteState>();
2239 }
2240 };
2241
2242 // Call this member function to start using the mini-DSL defined above.
2243 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2244};
2245
2246TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2247 // If all layers use BT2020_PQ, and there are no other special conditions,
2248 // BT2020_PQ is used.
2249 verify().ifTopLayerIs(BT2020_PQ)
2250 .andTopLayerIsREComposed(false)
2251 .andIfBottomLayerIs(BT2020_PQ)
2252 .andBottomLayerIsREComposed(false)
2253 .andIfLegacySupportFor(BT2020_PQ, false)
2254 .thenExpectBestColorModeCallUses(BT2020_PQ)
2255 .execute();
2256}
2257
2258TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2259 // BT2020_PQ is not used if there is only legacy support for it.
2260 verify().ifTopLayerIs(BT2020_PQ)
2261 .andTopLayerIsREComposed(false)
2262 .andIfBottomLayerIs(BT2020_PQ)
2263 .andBottomLayerIsREComposed(false)
2264 .andIfLegacySupportFor(BT2020_PQ, true)
2265 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2266 .execute();
2267}
2268
2269TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2270 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2271 verify().ifTopLayerIs(BT2020_PQ)
2272 .andTopLayerIsREComposed(false)
2273 .andIfBottomLayerIs(BT2020_PQ)
2274 .andBottomLayerIsREComposed(true)
2275 .andIfLegacySupportFor(BT2020_PQ, false)
2276 .thenExpectBestColorModeCallUses(BT2020_PQ)
2277 .execute();
2278}
2279
2280TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2281 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2282 verify().ifTopLayerIs(BT2020_PQ)
2283 .andTopLayerIsREComposed(true)
2284 .andIfBottomLayerIs(BT2020_PQ)
2285 .andBottomLayerIsREComposed(false)
2286 .andIfLegacySupportFor(BT2020_PQ, false)
2287 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2288 .execute();
2289}
2290
2291TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2292 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2293 // are no other special conditions.
2294 verify().ifTopLayerIs(BT2020_PQ)
2295 .andTopLayerIsREComposed(false)
2296 .andIfBottomLayerIs(BT2020_HLG)
2297 .andBottomLayerIsREComposed(false)
2298 .andIfLegacySupportFor(BT2020_PQ, false)
2299 .thenExpectBestColorModeCallUses(BT2020_PQ)
2300 .execute();
2301}
2302
2303TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2304 // BT2020_PQ is not used if there is only legacy support for it.
2305 verify().ifTopLayerIs(BT2020_PQ)
2306 .andTopLayerIsREComposed(false)
2307 .andIfBottomLayerIs(BT2020_HLG)
2308 .andBottomLayerIsREComposed(false)
2309 .andIfLegacySupportFor(BT2020_PQ, true)
2310 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2311 .execute();
2312}
2313
2314TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2315 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2316 verify().ifTopLayerIs(BT2020_PQ)
2317 .andTopLayerIsREComposed(false)
2318 .andIfBottomLayerIs(BT2020_HLG)
2319 .andBottomLayerIsREComposed(true)
2320 .andIfLegacySupportFor(BT2020_PQ, false)
2321 .thenExpectBestColorModeCallUses(BT2020_PQ)
2322 .execute();
2323}
2324
2325TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2326 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2327 verify().ifTopLayerIs(BT2020_PQ)
2328 .andTopLayerIsREComposed(true)
2329 .andIfBottomLayerIs(BT2020_HLG)
2330 .andBottomLayerIsREComposed(false)
2331 .andIfLegacySupportFor(BT2020_PQ, false)
2332 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2333 .execute();
2334}
2335
2336TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2337 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2338 // used if there are no other special conditions.
2339 verify().ifTopLayerIs(BT2020_HLG)
2340 .andTopLayerIsREComposed(false)
2341 .andIfBottomLayerIs(BT2020_PQ)
2342 .andBottomLayerIsREComposed(false)
2343 .andIfLegacySupportFor(BT2020_PQ, false)
2344 .thenExpectBestColorModeCallUses(BT2020_PQ)
2345 .execute();
2346}
2347
2348TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2349 // BT2020_PQ is not used if there is only legacy support for it.
2350 verify().ifTopLayerIs(BT2020_HLG)
2351 .andTopLayerIsREComposed(false)
2352 .andIfBottomLayerIs(BT2020_PQ)
2353 .andBottomLayerIsREComposed(false)
2354 .andIfLegacySupportFor(BT2020_PQ, true)
2355 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2356 .execute();
2357}
2358
2359TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2360 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2361 verify().ifTopLayerIs(BT2020_HLG)
2362 .andTopLayerIsREComposed(false)
2363 .andIfBottomLayerIs(BT2020_PQ)
2364 .andBottomLayerIsREComposed(true)
2365 .andIfLegacySupportFor(BT2020_PQ, false)
2366 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2367 .execute();
2368}
2369
2370TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2371 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2372 verify().ifTopLayerIs(BT2020_HLG)
2373 .andTopLayerIsREComposed(true)
2374 .andIfBottomLayerIs(BT2020_PQ)
2375 .andBottomLayerIsREComposed(false)
2376 .andIfLegacySupportFor(BT2020_PQ, false)
2377 .thenExpectBestColorModeCallUses(BT2020_PQ)
2378 .execute();
2379}
2380
2381TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2382 // If all layers use HLG then HLG is used if there are no other special
2383 // conditions.
2384 verify().ifTopLayerIs(BT2020_HLG)
2385 .andTopLayerIsREComposed(false)
2386 .andIfBottomLayerIs(BT2020_HLG)
2387 .andBottomLayerIsREComposed(false)
2388 .andIfLegacySupportFor(BT2020_HLG, false)
2389 .thenExpectBestColorModeCallUses(BT2020_HLG)
2390 .execute();
2391}
2392
2393TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2394 // BT2020_HLG is not used if there is legacy support for it.
2395 verify().ifTopLayerIs(BT2020_HLG)
2396 .andTopLayerIsREComposed(false)
2397 .andIfBottomLayerIs(BT2020_HLG)
2398 .andBottomLayerIsREComposed(false)
2399 .andIfLegacySupportFor(BT2020_HLG, true)
2400 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2401 .execute();
2402}
2403
2404TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2405 // BT2020_HLG is used even if the bottom layer is client composed.
2406 verify().ifTopLayerIs(BT2020_HLG)
2407 .andTopLayerIsREComposed(false)
2408 .andIfBottomLayerIs(BT2020_HLG)
2409 .andBottomLayerIsREComposed(true)
2410 .andIfLegacySupportFor(BT2020_HLG, false)
2411 .thenExpectBestColorModeCallUses(BT2020_HLG)
2412 .execute();
2413}
2414
2415TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2416 // BT2020_HLG is used even if the top layer is client composed.
2417 verify().ifTopLayerIs(BT2020_HLG)
2418 .andTopLayerIsREComposed(true)
2419 .andIfBottomLayerIs(BT2020_HLG)
2420 .andBottomLayerIsREComposed(false)
2421 .andIfLegacySupportFor(BT2020_HLG, false)
2422 .thenExpectBestColorModeCallUses(BT2020_HLG)
2423 .execute();
2424}
2425
2426TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2427 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2428 verify().ifTopLayerIs(BT2020_PQ)
2429 .andTopLayerIsREComposed(false)
2430 .andIfBottomLayerIsNotHdr()
2431 .andBottomLayerIsREComposed(false)
2432 .andIfLegacySupportFor(BT2020_PQ, false)
2433 .thenExpectBestColorModeCallUses(BT2020_PQ)
2434 .execute();
2435}
2436
2437TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2438 // If all layers use HLG then HLG is used if there are no other special
2439 // conditions.
2440 verify().ifTopLayerIs(BT2020_HLG)
2441 .andTopLayerIsREComposed(false)
2442 .andIfBottomLayerIsNotHdr()
2443 .andBottomLayerIsREComposed(true)
2444 .andIfLegacySupportFor(BT2020_HLG, false)
2445 .thenExpectBestColorModeCallUses(BT2020_HLG)
2446 .execute();
2447}
2448
2449struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2450 : public OutputUpdateColorProfileTest {
2451 // The various values for CompositionRefreshArgs::outputColorSetting affect
2452 // the chosen renderIntent, along with whether the preferred dataspace is an
2453 // HDR dataspace or not.
2454
2455 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2456 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2457 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2458 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002459 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002460 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2461 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2462 .WillRepeatedly(Return(false));
2463 }
2464
2465 // The tests here involve enough state and GMock setup that using a mini-DSL
2466 // makes the tests much more readable, and allows the test to focus more on
2467 // the intent than on some of the details.
2468
2469 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2470 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2471
2472 struct IfDataspaceChosenState
2473 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2474 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2475 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2476 return nextState<AndOutputColorSettingState>();
2477 }
2478 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2479 return ifDataspaceChosenIs(kNonHdrDataspace);
2480 }
2481 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2482 };
2483
2484 struct AndOutputColorSettingState
2485 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2486 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2487 getInstance()->mRefreshArgs.outputColorSetting = setting;
2488 return nextState<ThenExpectBestColorModeCallUsesState>();
2489 }
2490 };
2491
2492 struct ThenExpectBestColorModeCallUsesState
2493 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2494 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2495 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2496 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2497 _, _));
2498 return nextState<ExecuteState>();
2499 }
2500 };
2501
2502 // Tests call one of these two helper member functions to start using the
2503 // mini-DSL defined above.
2504 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2505};
2506
2507TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2508 Managed_NonHdr_Prefers_Colorimetric) {
2509 verify().ifDataspaceChosenIsNonHdr()
2510 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2511 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2512 .execute();
2513}
2514
2515TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2516 Managed_Hdr_Prefers_ToneMapColorimetric) {
2517 verify().ifDataspaceChosenIsHdr()
2518 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2519 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2520 .execute();
2521}
2522
2523TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2524 verify().ifDataspaceChosenIsNonHdr()
2525 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2526 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2527 .execute();
2528}
2529
2530TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2531 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2532 verify().ifDataspaceChosenIsHdr()
2533 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2534 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2535 .execute();
2536}
2537
2538TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2539 verify().ifDataspaceChosenIsNonHdr()
2540 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2541 .thenExpectBestColorModeCallUses(
2542 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2543 .execute();
2544}
2545
2546TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2547 verify().ifDataspaceChosenIsHdr()
2548 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2549 .thenExpectBestColorModeCallUses(
2550 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2551 .execute();
2552}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002553
2554/*
2555 * Output::beginFrame()
2556 */
2557
Lloyd Piquee5965952019-11-18 16:16:32 -08002558struct OutputBeginFrameTest : public ::testing::Test {
2559 using TestType = OutputBeginFrameTest;
2560
2561 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002562 // Sets up the helper functions called by the function under test to use
2563 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002564 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002565 };
2566
2567 OutputBeginFrameTest() {
2568 mOutput.setDisplayColorProfileForTest(
2569 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2570 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2571 }
2572
2573 struct IfGetDirtyRegionExpectationState
2574 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2575 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002576 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002577 return nextState<AndIfGetOutputLayerCountExpectationState>();
2578 }
2579 };
2580
2581 struct AndIfGetOutputLayerCountExpectationState
2582 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2583 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2584 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2585 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2586 }
2587 };
2588
2589 struct AndIfLastCompositionHadVisibleLayersState
2590 : public CallOrderStateMachineHelper<TestType,
2591 AndIfLastCompositionHadVisibleLayersState> {
2592 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2593 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2594 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2595 }
2596 };
2597
2598 struct ThenExpectRenderSurfaceBeginFrameCallState
2599 : public CallOrderStateMachineHelper<TestType,
2600 ThenExpectRenderSurfaceBeginFrameCallState> {
2601 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2602 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2603 return nextState<ExecuteState>();
2604 }
2605 };
2606
2607 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2608 [[nodiscard]] auto execute() {
2609 getInstance()->mOutput.beginFrame();
2610 return nextState<CheckPostconditionHadVisibleLayersState>();
2611 }
2612 };
2613
2614 struct CheckPostconditionHadVisibleLayersState
2615 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2616 void checkPostconditionHadVisibleLayers(bool expected) {
2617 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2618 }
2619 };
2620
2621 // Tests call one of these two helper member functions to start using the
2622 // mini-DSL defined above.
2623 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2624
2625 static const Region kEmptyRegion;
2626 static const Region kNotEmptyRegion;
2627
2628 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2629 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2630 StrictMock<OutputPartialMock> mOutput;
2631};
2632
2633const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2634const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2635
2636TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2637 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2638 .andIfGetOutputLayerCountReturns(1u)
2639 .andIfLastCompositionHadVisibleLayersIs(true)
2640 .thenExpectRenderSurfaceBeginFrameCall(true)
2641 .execute()
2642 .checkPostconditionHadVisibleLayers(true);
2643}
2644
2645TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2646 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2647 .andIfGetOutputLayerCountReturns(0u)
2648 .andIfLastCompositionHadVisibleLayersIs(true)
2649 .thenExpectRenderSurfaceBeginFrameCall(true)
2650 .execute()
2651 .checkPostconditionHadVisibleLayers(false);
2652}
2653
2654TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2655 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2656 .andIfGetOutputLayerCountReturns(1u)
2657 .andIfLastCompositionHadVisibleLayersIs(false)
2658 .thenExpectRenderSurfaceBeginFrameCall(true)
2659 .execute()
2660 .checkPostconditionHadVisibleLayers(true);
2661}
2662
2663TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2664 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2665 .andIfGetOutputLayerCountReturns(0u)
2666 .andIfLastCompositionHadVisibleLayersIs(false)
2667 .thenExpectRenderSurfaceBeginFrameCall(false)
2668 .execute()
2669 .checkPostconditionHadVisibleLayers(false);
2670}
2671
2672TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2673 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2674 .andIfGetOutputLayerCountReturns(1u)
2675 .andIfLastCompositionHadVisibleLayersIs(true)
2676 .thenExpectRenderSurfaceBeginFrameCall(false)
2677 .execute()
2678 .checkPostconditionHadVisibleLayers(true);
2679}
2680
2681TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2682 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2683 .andIfGetOutputLayerCountReturns(0u)
2684 .andIfLastCompositionHadVisibleLayersIs(true)
2685 .thenExpectRenderSurfaceBeginFrameCall(false)
2686 .execute()
2687 .checkPostconditionHadVisibleLayers(true);
2688}
2689
2690TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2691 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2692 .andIfGetOutputLayerCountReturns(1u)
2693 .andIfLastCompositionHadVisibleLayersIs(false)
2694 .thenExpectRenderSurfaceBeginFrameCall(false)
2695 .execute()
2696 .checkPostconditionHadVisibleLayers(false);
2697}
2698
2699TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2700 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2701 .andIfGetOutputLayerCountReturns(0u)
2702 .andIfLastCompositionHadVisibleLayersIs(false)
2703 .thenExpectRenderSurfaceBeginFrameCall(false)
2704 .execute()
2705 .checkPostconditionHadVisibleLayers(false);
2706}
2707
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002708/*
2709 * Output::devOptRepaintFlash()
2710 */
2711
Lloyd Piquedb462d82019-11-19 17:58:46 -08002712struct OutputDevOptRepaintFlashTest : public testing::Test {
2713 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002714 // Sets up the helper functions called by the function under test to use
2715 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002716 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002717 MOCK_METHOD2(composeSurfaces,
2718 std::optional<base::unique_fd>(
2719 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002720 MOCK_METHOD0(postFramebuffer, void());
2721 MOCK_METHOD0(prepareFrame, void());
2722 };
2723
2724 OutputDevOptRepaintFlashTest() {
2725 mOutput.setDisplayColorProfileForTest(
2726 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2727 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2728 }
2729
2730 static const Region kEmptyRegion;
2731 static const Region kNotEmptyRegion;
2732
2733 StrictMock<OutputPartialMock> mOutput;
2734 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2735 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2736 CompositionRefreshArgs mRefreshArgs;
2737};
2738
2739const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2740const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2741
2742TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2743 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002744 mOutput.mState.isEnabled = true;
2745
2746 mOutput.devOptRepaintFlash(mRefreshArgs);
2747}
2748
2749TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2750 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002751 mOutput.mState.isEnabled = false;
2752
2753 InSequence seq;
2754 EXPECT_CALL(mOutput, postFramebuffer());
2755 EXPECT_CALL(mOutput, prepareFrame());
2756
2757 mOutput.devOptRepaintFlash(mRefreshArgs);
2758}
2759
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002760TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002761 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002762 mOutput.mState.isEnabled = true;
2763
2764 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002765 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002766 EXPECT_CALL(mOutput, postFramebuffer());
2767 EXPECT_CALL(mOutput, prepareFrame());
2768
2769 mOutput.devOptRepaintFlash(mRefreshArgs);
2770}
2771
2772TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2773 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002774 mOutput.mState.isEnabled = true;
2775
2776 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002777 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002778 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002779 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2780 EXPECT_CALL(mOutput, postFramebuffer());
2781 EXPECT_CALL(mOutput, prepareFrame());
2782
2783 mOutput.devOptRepaintFlash(mRefreshArgs);
2784}
2785
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002786/*
2787 * Output::finishFrame()
2788 */
2789
Lloyd Pique03561a62019-11-19 18:34:52 -08002790struct OutputFinishFrameTest : public testing::Test {
2791 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002792 // Sets up the helper functions called by the function under test to use
2793 // mock implementations.
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002794 MOCK_METHOD2(composeSurfaces,
2795 std::optional<base::unique_fd>(
2796 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002797 MOCK_METHOD0(postFramebuffer, void());
2798 };
2799
2800 OutputFinishFrameTest() {
2801 mOutput.setDisplayColorProfileForTest(
2802 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2803 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2804 }
2805
2806 StrictMock<OutputPartialMock> mOutput;
2807 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2808 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2809 CompositionRefreshArgs mRefreshArgs;
2810};
2811
2812TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2813 mOutput.mState.isEnabled = false;
2814
2815 mOutput.finishFrame(mRefreshArgs);
2816}
2817
2818TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2819 mOutput.mState.isEnabled = true;
2820
2821 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002822 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
Lloyd Pique03561a62019-11-19 18:34:52 -08002823
2824 mOutput.finishFrame(mRefreshArgs);
2825}
2826
2827TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2828 mOutput.mState.isEnabled = true;
2829
2830 InSequence seq;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002831 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002832 .WillOnce(Return(ByMove(base::unique_fd())));
2833 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2834
2835 mOutput.finishFrame(mRefreshArgs);
2836}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002837
2838/*
2839 * Output::postFramebuffer()
2840 */
2841
Lloyd Pique07178e32019-11-19 19:15:26 -08002842struct OutputPostFramebufferTest : public testing::Test {
2843 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002844 // Sets up the helper functions called by the function under test to use
2845 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002846 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2847 };
2848
2849 struct Layer {
2850 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002851 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002852 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2853 }
2854
2855 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002856 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002857 StrictMock<HWC2::mock::Layer> hwc2Layer;
2858 };
2859
2860 OutputPostFramebufferTest() {
2861 mOutput.setDisplayColorProfileForTest(
2862 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2863 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2864
2865 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2866 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2867 .WillRepeatedly(Return(&mLayer1.outputLayer));
2868 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2869 .WillRepeatedly(Return(&mLayer2.outputLayer));
2870 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2871 .WillRepeatedly(Return(&mLayer3.outputLayer));
2872 }
2873
2874 StrictMock<OutputPartialMock> mOutput;
2875 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2876 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2877
2878 Layer mLayer1;
2879 Layer mLayer2;
2880 Layer mLayer3;
2881};
2882
2883TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2884 mOutput.mState.isEnabled = false;
2885
2886 mOutput.postFramebuffer();
2887}
2888
2889TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2890 mOutput.mState.isEnabled = true;
2891
2892 compositionengine::Output::FrameFences frameFences;
2893
2894 // This should happen even if there are no output layers.
2895 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2896
2897 // For this test in particular we want to make sure the call expectations
2898 // setup below are satisfied in the specific order.
2899 InSequence seq;
2900
2901 EXPECT_CALL(*mRenderSurface, flip());
2902 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2903 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2904
2905 mOutput.postFramebuffer();
2906}
2907
2908TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2909 // Simulate getting release fences from each layer, and ensure they are passed to the
2910 // front-end layer interface for each layer correctly.
2911
2912 mOutput.mState.isEnabled = true;
2913
2914 // Create three unique fence instances
2915 sp<Fence> layer1Fence = new Fence();
2916 sp<Fence> layer2Fence = new Fence();
2917 sp<Fence> layer3Fence = new Fence();
2918
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002919 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002920 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2921 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2922 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2923
2924 EXPECT_CALL(*mRenderSurface, flip());
2925 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2926 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2927
2928 // Compare the pointers values of each fence to make sure the correct ones
2929 // are passed. This happens to work with the current implementation, but
2930 // would not survive certain calls like Fence::merge() which would return a
2931 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002932 base::unique_fd layer1FD(layer1Fence->dup());
2933 base::unique_fd layer2FD(layer2Fence->dup());
2934 base::unique_fd layer3FD(layer3Fence->dup());
2935 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2936 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2937 futureRenderEngineResult) {
2938 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2939 });
2940 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2941 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2942 futureRenderEngineResult) {
2943 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2944 });
2945 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2946 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2947 futureRenderEngineResult) {
2948 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2949 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002950
2951 mOutput.postFramebuffer();
2952}
2953
2954TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2955 mOutput.mState.isEnabled = true;
2956 mOutput.mState.usesClientComposition = true;
2957
2958 sp<Fence> clientTargetAcquireFence = new Fence();
2959 sp<Fence> layer1Fence = new Fence();
2960 sp<Fence> layer2Fence = new Fence();
2961 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002962 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002963 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2964 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2965 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2966 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2967
2968 EXPECT_CALL(*mRenderSurface, flip());
2969 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2970 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2971
2972 // Fence::merge is called, and since none of the fences are actually valid,
2973 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2974 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00002975 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
2976 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
2977 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08002978
2979 mOutput.postFramebuffer();
2980}
2981
2982TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
2983 mOutput.mState.isEnabled = true;
2984 mOutput.mState.usesClientComposition = true;
2985
2986 // This should happen even if there are no (current) output layers.
2987 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2988
2989 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08002990 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
2991 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
2992 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002993 Output::ReleasedLayers layers;
2994 layers.push_back(releasedLayer1);
2995 layers.push_back(releasedLayer2);
2996 layers.push_back(releasedLayer3);
2997 mOutput.setReleasedLayers(std::move(layers));
2998
2999 // Set up a fake present fence
3000 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003001 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003002 frameFences.presentFence = presentFence;
3003
3004 EXPECT_CALL(*mRenderSurface, flip());
3005 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3006 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3007
3008 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003009 base::unique_fd layerFD(presentFence.get()->dup());
3010 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3011 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3012 futureRenderEngineResult) {
3013 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3014 });
3015 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3016 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3017 futureRenderEngineResult) {
3018 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3019 });
3020 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3021 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3022 futureRenderEngineResult) {
3023 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3024 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003025
3026 mOutput.postFramebuffer();
3027
3028 // After the call the list of released layers should have been cleared.
3029 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3030}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003031
3032/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003033 * Output::composeSurfaces()
3034 */
3035
3036struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003037 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003038
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003039 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003040 // Sets up the helper functions called by the function under test to use
3041 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003042 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003043 MOCK_METHOD3(generateClientCompositionRequests,
3044 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003045 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003046 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003047 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3048 };
3049
3050 OutputComposeSurfacesTest() {
3051 mOutput.setDisplayColorProfileForTest(
3052 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3053 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003054 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003055
Angel Aguayob084e0c2021-08-04 23:27:28 +00003056 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3057 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3058 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3059 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3060 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003061 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003062 mOutput.mState.dataspace = kDefaultOutputDataspace;
3063 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3064 mOutput.mState.isSecure = false;
3065 mOutput.mState.needsFiltering = false;
3066 mOutput.mState.usesClientComposition = true;
3067 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003068 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003069 mOutput.mState.flipClientTarget = false;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003070 mOutput.mState.clientTargetWhitePointNits = kClientTargetLuminanceNits;
Lloyd Pique56eba802019-08-28 15:45:25 -07003071
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003072 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003073 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003074 EXPECT_CALL(mCompositionEngine, getTimeStats())
3075 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003076 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3077 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003078 }
3079
Lloyd Pique6818fa52019-12-03 12:32:13 -08003080 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3081 auto execute() {
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003082 getInstance()->mReadyFence =
3083 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003084 return nextState<FenceCheckState>();
3085 }
3086 };
3087
3088 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3089 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3090
3091 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3092 };
3093
3094 // Call this member function to start using the mini-DSL defined above.
3095 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3096
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003097 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3098 static constexpr uint32_t kDefaultOutputOrientationFlags =
3099 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003100 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3101 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3102 static constexpr float kDefaultMaxLuminance = 0.9f;
3103 static constexpr float kDefaultAvgLuminance = 0.7f;
3104 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003105 static constexpr float kUnknownLuminance = -1.f;
3106 static constexpr float kDisplayLuminance = 80.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003107 static constexpr float kClientTargetLuminanceNits = 200.f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003108
3109 static const Rect kDefaultOutputFrame;
3110 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003111 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003112 static const mat4 kDefaultColorTransformMat;
3113
3114 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003115 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003116 static const HdrCapabilities kHdrCapabilities;
3117
Lloyd Pique56eba802019-08-28 15:45:25 -07003118 StrictMock<mock::CompositionEngine> mCompositionEngine;
3119 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003120 // TODO: make this is a proper mock.
3121 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003122 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3123 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003124 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003125 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003126 renderengine::impl::
3127 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3128 renderengine::impl::ExternalTexture::Usage::READABLE |
3129 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003130
3131 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003132};
3133
3134const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3135const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003136const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003137const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003138const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003139const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003140
Lloyd Pique6818fa52019-12-03 12:32:13 -08003141const HdrCapabilities OutputComposeSurfacesTest::
3142 kHdrCapabilities{{},
3143 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3144 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3145 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003146
Lloyd Piquea76ce462020-01-14 13:06:37 -08003147TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003148 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003149
Lloyd Piquee9eff972020-05-05 12:36:44 -07003150 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003151 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003152
Lloyd Piquea76ce462020-01-14 13:06:37 -08003153 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3154
Lloyd Pique6818fa52019-12-03 12:32:13 -08003155 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003156}
3157
Lloyd Piquee9eff972020-05-05 12:36:44 -07003158TEST_F(OutputComposeSurfacesTest,
3159 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3160 mOutput.mState.usesClientComposition = false;
3161 mOutput.mState.flipClientTarget = true;
3162
Lloyd Pique6818fa52019-12-03 12:32:13 -08003163 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003164 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003165
3166 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3167 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3168
3169 verify().execute().expectAFenceWasReturned();
3170}
3171
3172TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3173 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003174 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003175
3176 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3177
3178 verify().execute().expectNoFenceWasReturned();
3179}
3180
3181TEST_F(OutputComposeSurfacesTest,
3182 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3183 mOutput.mState.usesClientComposition = false;
3184 mOutput.mState.flipClientTarget = true;
3185
3186 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003187 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003188
Lloyd Pique6818fa52019-12-03 12:32:13 -08003189 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003190
Lloyd Pique6818fa52019-12-03 12:32:13 -08003191 verify().execute().expectNoFenceWasReturned();
3192}
Lloyd Pique56eba802019-08-28 15:45:25 -07003193
Lloyd Pique6818fa52019-12-03 12:32:13 -08003194TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3195 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3196 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3197 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003198 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003199 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003200 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003201 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3202 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003203
Lloyd Pique6818fa52019-12-03 12:32:13 -08003204 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003205 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3206 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003207 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003208 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003209 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003210 -> std::future<renderengine::RenderEngineResult> {
3211 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3212 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003213 verify().execute().expectAFenceWasReturned();
3214}
Lloyd Pique56eba802019-08-28 15:45:25 -07003215
Lloyd Pique6818fa52019-12-03 12:32:13 -08003216TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003217 LayerFE::LayerSettings r1;
3218 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003219
3220 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3221 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3222
3223 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3224 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3225 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003226 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003227 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003228 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003229 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3230 .WillRepeatedly(
3231 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003232 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003233 clientCompositionLayers.emplace_back(r2);
3234 }));
3235
3236 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003237 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003238 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003239 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003240 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003241 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003242 -> std::future<renderengine::RenderEngineResult> {
3243 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3244 });
Alec Mouri1684c702021-02-04 12:27:26 -08003245
3246 verify().execute().expectAFenceWasReturned();
3247}
3248
3249TEST_F(OutputComposeSurfacesTest,
3250 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3251 LayerFE::LayerSettings r1;
3252 LayerFE::LayerSettings r2;
3253
3254 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3255 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003256 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003257
3258 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3259 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3260 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3261 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003262 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003263 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3264 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3265 .WillRepeatedly(
3266 Invoke([&](const Region&,
3267 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3268 clientCompositionLayers.emplace_back(r2);
3269 }));
3270
3271 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003272 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003273 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003274 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003275 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003276 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003277 -> std::future<renderengine::RenderEngineResult> {
3278 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3279 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003280
3281 verify().execute().expectAFenceWasReturned();
3282}
3283
Vishnu Nair9b079a22020-01-21 14:36:08 -08003284TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3285 mOutput.cacheClientCompositionRequests(0);
3286 LayerFE::LayerSettings r1;
3287 LayerFE::LayerSettings r2;
3288
3289 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3290 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3291
3292 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3293 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3294 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003295 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003296 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003297 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3298 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3299 .WillRepeatedly(Return());
3300
3301 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003302 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003303 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003304 .WillOnce(Return(ByMove(
3305 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3306 .WillOnce(Return(ByMove(
3307 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003308
3309 verify().execute().expectAFenceWasReturned();
3310 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3311
3312 verify().execute().expectAFenceWasReturned();
3313 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3314}
3315
3316TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3317 mOutput.cacheClientCompositionRequests(3);
3318 LayerFE::LayerSettings r1;
3319 LayerFE::LayerSettings r2;
3320
3321 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3322 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3323
3324 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3325 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3326 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003327 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003328 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003329 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3330 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3331 .WillRepeatedly(Return());
3332
3333 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003334 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003335 .WillOnce(Return(ByMove(
3336 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003337 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3338
3339 verify().execute().expectAFenceWasReturned();
3340 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3341
3342 // We do not expect another call to draw layers.
3343 verify().execute().expectAFenceWasReturned();
3344 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3345}
3346
3347TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3348 LayerFE::LayerSettings r1;
3349 LayerFE::LayerSettings r2;
3350
3351 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3352 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3353
3354 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3355 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3356 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003357 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003358 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003359 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3360 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3361 .WillRepeatedly(Return());
3362
Alec Mouria90a5702021-04-16 16:36:21 +00003363 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003364 renderengine::impl::
3365 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3366 renderengine::impl::ExternalTexture::Usage::READABLE |
3367 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003368 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3369 .WillOnce(Return(mOutputBuffer))
3370 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003371 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003372 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003373 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003374 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003375 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003376 -> std::future<renderengine::RenderEngineResult> {
3377 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3378 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003379
3380 verify().execute().expectAFenceWasReturned();
3381 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3382
3383 verify().execute().expectAFenceWasReturned();
3384 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3385}
3386
3387TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3388 LayerFE::LayerSettings r1;
3389 LayerFE::LayerSettings r2;
3390 LayerFE::LayerSettings r3;
3391
3392 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3393 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3394 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3395
3396 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3397 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3398 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003399 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003400 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003401 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3402 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3403 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3404 .WillRepeatedly(Return());
3405
3406 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003407 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003408 .WillOnce(Return(ByMove(
3409 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003410 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003411 .WillOnce(Return(ByMove(
3412 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003413
3414 verify().execute().expectAFenceWasReturned();
3415 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3416
3417 verify().execute().expectAFenceWasReturned();
3418 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3419}
3420
Lloyd Pique6818fa52019-12-03 12:32:13 -08003421struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3422 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3423 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003424 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003425 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003426 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003427 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3428 .WillRepeatedly(Return());
3429 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3430 }
3431
3432 struct MixedCompositionState
3433 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3434 auto ifMixedCompositionIs(bool used) {
3435 getInstance()->mOutput.mState.usesDeviceComposition = used;
3436 return nextState<OutputUsesHdrState>();
3437 }
3438 };
3439
3440 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3441 auto andIfUsesHdr(bool used) {
3442 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3443 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003444 return nextState<OutputWithDisplayBrightnessNits>();
3445 }
3446 };
3447
3448 struct OutputWithDisplayBrightnessNits
3449 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3450 auto withDisplayBrightnessNits(float nits) {
3451 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003452 return nextState<SkipColorTransformState>();
3453 }
3454 };
3455
3456 struct SkipColorTransformState
3457 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3458 auto andIfSkipColorTransform(bool skip) {
3459 // May be called zero or one times.
3460 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3461 .WillRepeatedly(Return(skip));
3462 return nextState<ExpectDisplaySettingsState>();
3463 }
3464 };
3465
3466 struct ExpectDisplaySettingsState
3467 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3468 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003469 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3470 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3471 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003472 return nextState<ExecuteState>();
3473 }
3474 };
3475
3476 // Call this member function to start using the mini-DSL defined above.
3477 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3478};
3479
3480TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3481 verify().ifMixedCompositionIs(true)
3482 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003483 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003484 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003485 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3486 .clip = kDefaultOutputViewport,
3487 .maxLuminance = kDefaultMaxLuminance,
3488 .currentLuminanceNits = kDefaultMaxLuminance,
3489 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003490 .colorTransform = kDefaultColorTransformMat,
3491 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003492 .orientation = kDefaultOutputOrientationFlags,
3493 .targetLuminanceNits = kClientTargetLuminanceNits})
3494 .execute()
3495 .expectAFenceWasReturned();
3496}
3497
3498TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3499 forHdrMixedCompositionWithDisplayBrightness) {
3500 verify().ifMixedCompositionIs(true)
3501 .andIfUsesHdr(true)
3502 .withDisplayBrightnessNits(kDisplayLuminance)
3503 .andIfSkipColorTransform(false)
3504 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3505 .clip = kDefaultOutputViewport,
3506 .maxLuminance = kDefaultMaxLuminance,
3507 .currentLuminanceNits = kDisplayLuminance,
3508 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003509 .colorTransform = kDefaultColorTransformMat,
3510 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003511 .orientation = kDefaultOutputOrientationFlags,
3512 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003513 .execute()
3514 .expectAFenceWasReturned();
3515}
3516
3517TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3518 verify().ifMixedCompositionIs(true)
3519 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003520 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003521 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003522 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3523 .clip = kDefaultOutputViewport,
3524 .maxLuminance = kDefaultMaxLuminance,
3525 .currentLuminanceNits = kDefaultMaxLuminance,
3526 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003527 .colorTransform = kDefaultColorTransformMat,
3528 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003529 .orientation = kDefaultOutputOrientationFlags,
3530 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003531 .execute()
3532 .expectAFenceWasReturned();
3533}
3534
3535TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3536 verify().ifMixedCompositionIs(false)
3537 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003538 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003539 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003540 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3541 .clip = kDefaultOutputViewport,
3542 .maxLuminance = kDefaultMaxLuminance,
3543 .currentLuminanceNits = kDefaultMaxLuminance,
3544 .outputDataspace = kDefaultOutputDataspace,
3545 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003546 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003547 .orientation = kDefaultOutputOrientationFlags,
3548 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003549 .execute()
3550 .expectAFenceWasReturned();
3551}
3552
3553TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3554 verify().ifMixedCompositionIs(false)
3555 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003556 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003557 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003558 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3559 .clip = kDefaultOutputViewport,
3560 .maxLuminance = kDefaultMaxLuminance,
3561 .currentLuminanceNits = kDefaultMaxLuminance,
3562 .outputDataspace = kDefaultOutputDataspace,
3563 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003564 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003565 .orientation = kDefaultOutputOrientationFlags,
3566 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003567 .execute()
3568 .expectAFenceWasReturned();
3569}
3570
3571TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3572 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3573 verify().ifMixedCompositionIs(false)
3574 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003575 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003576 .andIfSkipColorTransform(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003577 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3578 .clip = kDefaultOutputViewport,
3579 .maxLuminance = kDefaultMaxLuminance,
3580 .currentLuminanceNits = kDefaultMaxLuminance,
3581 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003582 .colorTransform = kDefaultColorTransformMat,
3583 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003584 .orientation = kDefaultOutputOrientationFlags,
3585 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003586 .execute()
3587 .expectAFenceWasReturned();
3588}
3589
3590struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3591 struct Layer {
3592 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003593 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3594 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003595 }
3596
3597 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003598 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003599 LayerFECompositionState mLayerFEState;
3600 };
3601
3602 OutputComposeSurfacesTest_HandlesProtectedContent() {
3603 mLayer1.mLayerFEState.hasProtectedContent = false;
3604 mLayer2.mLayerFEState.hasProtectedContent = false;
3605
3606 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3607 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3608 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3609 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3610 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3611
3612 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3613
3614 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3615
Robert Carrccab4242021-09-28 16:53:03 -07003616 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003617 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003618 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3619 .WillRepeatedly(Return());
3620 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003621 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3622 .WillRepeatedly(
3623 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003624 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003625 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003626 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003627 return futureOf<renderengine::RenderEngineResult>(
3628 {NO_ERROR, base::unique_fd()});
3629 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003630 }
3631
3632 Layer mLayer1;
3633 Layer mLayer2;
3634};
3635
3636TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3637 mOutput.mState.isSecure = false;
3638 mLayer2.mLayerFEState.hasProtectedContent = true;
3639 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003640 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003641 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003642
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003643 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003644}
3645
3646TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3647 mOutput.mState.isSecure = true;
3648 mLayer2.mLayerFEState.hasProtectedContent = true;
3649 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3650
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003651 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003652}
3653
3654TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3655 mOutput.mState.isSecure = true;
3656 mLayer2.mLayerFEState.hasProtectedContent = false;
3657 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3658 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3659 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3660 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3661 EXPECT_CALL(*mRenderSurface, setProtected(false));
3662
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003663 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003664}
3665
3666TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3667 mOutput.mState.isSecure = true;
3668 mLayer2.mLayerFEState.hasProtectedContent = true;
3669 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3670
3671 // For this test, we also check the call order of key functions.
3672 InSequence seq;
3673
3674 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3675 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3676 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3677 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3678 EXPECT_CALL(*mRenderSurface, setProtected(true));
3679 // Must happen after setting the protected content state.
3680 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003681 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3682 .WillOnce(Return(ByMove(
3683 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003684
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003685 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003686}
3687
3688TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3689 mOutput.mState.isSecure = true;
3690 mLayer2.mLayerFEState.hasProtectedContent = true;
3691 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3692 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3693 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3694
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003695 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003696}
3697
3698TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
3699 mOutput.mState.isSecure = true;
3700 mLayer2.mLayerFEState.hasProtectedContent = true;
3701 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3702 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false)).WillOnce(Return(false));
3703 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3704 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3705
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003706 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003707}
3708
3709TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3710 mOutput.mState.isSecure = true;
3711 mLayer2.mLayerFEState.hasProtectedContent = true;
3712 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3713 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3714 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3715 EXPECT_CALL(*mRenderSurface, setProtected(true));
3716
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003717 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003718}
3719
3720TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3721 mOutput.mState.isSecure = true;
3722 mLayer2.mLayerFEState.hasProtectedContent = true;
3723 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3724 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3725 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3726 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3727
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003728 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003729}
3730
3731struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3732 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3733 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3734 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3735 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003736 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003737 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3738 .WillRepeatedly(Return());
3739 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3740 }
3741};
3742
3743TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3744 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3745
Robert Carrccab4242021-09-28 16:53:03 -07003746 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003747 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003748
3749 // For this test, we also check the call order of key functions.
3750 InSequence seq;
3751
3752 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003753 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3754 .WillOnce(Return(ByMove(
3755 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003756
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003757 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
3758}
3759
3760struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3761 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3762 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3763 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003764 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003765 mOutput.editState().isEnabled = true;
3766
Snild Dolkow9e217d62020-04-22 15:53:42 +02003767 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003768 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003769 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3770 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003771 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003772 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003773 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3774 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3775 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003776 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3777 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3778 .WillRepeatedly(Return(&mLayer.outputLayer));
3779 }
3780
3781 NonInjectedLayer mLayer;
3782 compositionengine::CompositionRefreshArgs mRefreshArgs;
3783};
3784
3785TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3786 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003787 mOutput.updateCompositionState(mRefreshArgs);
3788 mOutput.planComposition();
3789 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003790
3791 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
3792 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
3793}
3794
3795TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3796 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003797 mOutput.updateCompositionState(mRefreshArgs);
3798 mOutput.planComposition();
3799 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003800
3801 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
3802 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003803}
3804
3805/*
3806 * Output::generateClientCompositionRequests()
3807 */
3808
3809struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003810 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003811 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003812 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3813 bool supportsProtectedContent, ui::Dataspace dataspace) {
3814 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003815 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003816 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003817 }
3818 };
3819
Lloyd Piquea4863342019-12-04 18:45:02 -08003820 struct Layer {
3821 Layer() {
3822 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3823 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003824 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3825 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003826 }
3827
3828 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003829 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003830 LayerFECompositionState mLayerFEState;
3831 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003832 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003833 };
3834
Lloyd Pique56eba802019-08-28 15:45:25 -07003835 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003836 mOutput.mState.needsFiltering = false;
3837
Lloyd Pique56eba802019-08-28 15:45:25 -07003838 mOutput.setDisplayColorProfileForTest(
3839 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3840 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3841 }
3842
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003843 static constexpr float kLayerWhitePointNits = 200.f;
3844
Lloyd Pique56eba802019-08-28 15:45:25 -07003845 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3846 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003847 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003848};
3849
Lloyd Piquea4863342019-12-04 18:45:02 -08003850struct GenerateClientCompositionRequestsTest_ThreeLayers
3851 : public GenerateClientCompositionRequestsTest {
3852 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003853 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3854 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3855 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003856 mOutput.mState.transform =
3857 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003858 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003859 mOutput.mState.needsFiltering = false;
3860 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003861
Lloyd Piquea4863342019-12-04 18:45:02 -08003862 for (size_t i = 0; i < mLayers.size(); i++) {
3863 mLayers[i].mOutputLayerState.clearClientTarget = false;
3864 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3865 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003866 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003867 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003868 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3869 mLayers[i].mLayerSettings.alpha = 1.0f;
3870 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003871
Lloyd Piquea4863342019-12-04 18:45:02 -08003872 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3873 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3874 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3875 .WillRepeatedly(Return(true));
3876 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3877 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003878
Lloyd Piquea4863342019-12-04 18:45:02 -08003879 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3880 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003881
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003882 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003883 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003884 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003885
Lloyd Piquea4863342019-12-04 18:45:02 -08003886 static const Rect kDisplayFrame;
3887 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003888 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003889
Lloyd Piquea4863342019-12-04 18:45:02 -08003890 std::array<Layer, 3> mLayers;
3891};
Lloyd Pique56eba802019-08-28 15:45:25 -07003892
Lloyd Piquea4863342019-12-04 18:45:02 -08003893const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3894const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003895const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3896 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003897
Lloyd Piquea4863342019-12-04 18:45:02 -08003898TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3899 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3900 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3901 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003902
Robert Carrccab4242021-09-28 16:53:03 -07003903 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003904 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003905 EXPECT_EQ(0u, requests.size());
3906}
3907
Lloyd Piquea4863342019-12-04 18:45:02 -08003908TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3909 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3910 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3911 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3912
Robert Carrccab4242021-09-28 16:53:03 -07003913 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003914 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003915 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003916}
3917
3918TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003919 LayerFE::LayerSettings mShadowSettings;
3920 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003921
Ady Abrahameca9d752021-03-03 12:20:00 -08003922 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003923 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003924 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003925 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003926 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003927 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3928 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003929
Robert Carrccab4242021-09-28 16:53:03 -07003930 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003931 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003932 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003933 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3934 EXPECT_EQ(mShadowSettings, requests[1]);
3935 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003936
Lloyd Piquea4863342019-12-04 18:45:02 -08003937 // Check that a timestamp was set for the layers that generated requests
3938 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3939 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3940 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3941}
3942
Alec Mourif54453c2021-05-13 16:28:28 -07003943MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3944 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3945 *result_listener << "expected " << expectedBlurSetting << "\n";
3946 *result_listener << "actual " << arg.blurSetting << "\n";
3947
3948 return expectedBlurSetting == arg.blurSetting;
3949}
3950
3951TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3952 LayerFE::LayerSettings mShadowSettings;
3953 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3954
3955 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3956
3957 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3958 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3959 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3960 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3961 EXPECT_CALL(*mLayers[2].mLayerFE,
3962 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3963 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3964 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3965 {mShadowSettings, mLayers[2].mLayerSettings})));
3966
Robert Carrccab4242021-09-28 16:53:03 -07003967 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003968 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003969 ASSERT_EQ(3u, requests.size());
3970 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3971 EXPECT_EQ(mShadowSettings, requests[1]);
3972 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3973
Alec Mourif54453c2021-05-13 16:28:28 -07003974 // Check that a timestamp was set for the layers that generated requests
3975 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3976 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3977 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3978}
3979
Lloyd Piquea4863342019-12-04 18:45:02 -08003980TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
3981 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
3982 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3983 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3984 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
3985
3986 mLayers[0].mOutputLayerState.clearClientTarget = false;
3987 mLayers[1].mOutputLayerState.clearClientTarget = false;
3988 mLayers[2].mOutputLayerState.clearClientTarget = false;
3989
3990 mLayers[0].mLayerFEState.isOpaque = true;
3991 mLayers[1].mLayerFEState.isOpaque = true;
3992 mLayers[2].mLayerFEState.isOpaque = true;
3993
Ady Abrahameca9d752021-03-03 12:20:00 -08003994 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003995 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003996
Robert Carrccab4242021-09-28 16:53:03 -07003997 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003998 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003999 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004000 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004001}
4002
4003TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4004 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4005 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4006 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4007 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4008
4009 mLayers[0].mOutputLayerState.clearClientTarget = true;
4010 mLayers[1].mOutputLayerState.clearClientTarget = true;
4011 mLayers[2].mOutputLayerState.clearClientTarget = true;
4012
4013 mLayers[0].mLayerFEState.isOpaque = false;
4014 mLayers[1].mLayerFEState.isOpaque = false;
4015 mLayers[2].mLayerFEState.isOpaque = false;
4016
Ady Abrahameca9d752021-03-03 12:20:00 -08004017 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004018 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004019
Robert Carrccab4242021-09-28 16:53:03 -07004020 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004021 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004022 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004023 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004024}
4025
4026TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004027 // If client composition is performed with some layers set to use device
4028 // composition, device layers after the first layer (device or client) will
4029 // clear the frame buffer if they are opaque and if that layer has a flag
4030 // set to do so. The first layer is skipped as the frame buffer is already
4031 // expected to be clear.
4032
Lloyd Piquea4863342019-12-04 18:45:02 -08004033 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4034 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4035 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004036
Lloyd Piquea4863342019-12-04 18:45:02 -08004037 mLayers[0].mOutputLayerState.clearClientTarget = true;
4038 mLayers[1].mOutputLayerState.clearClientTarget = true;
4039 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004040
Lloyd Piquea4863342019-12-04 18:45:02 -08004041 mLayers[0].mLayerFEState.isOpaque = true;
4042 mLayers[1].mLayerFEState.isOpaque = true;
4043 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004044
4045 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4046 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004047 false, /* needs filtering */
4048 false, /* secure */
4049 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004050 kDisplayViewport,
4051 kDisplayDataspace,
4052 false /* realContentIsVisible */,
4053 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004054 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004055 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004056 };
4057 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4058 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004059 false, /* needs filtering */
4060 false, /* secure */
4061 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004062 kDisplayViewport,
4063 kDisplayDataspace,
4064 true /* realContentIsVisible */,
4065 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004066 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004067 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004068 };
4069
4070 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4071 mBlackoutSettings.source.buffer.buffer = nullptr;
4072 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4073 mBlackoutSettings.alpha = 0.f;
4074 mBlackoutSettings.disableBlending = true;
4075
Ady Abrahameca9d752021-03-03 12:20:00 -08004076 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004077 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004078 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004079 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4080
Robert Carrccab4242021-09-28 16:53:03 -07004081 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004082 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004083 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004084
Lloyd Piquea4863342019-12-04 18:45:02 -08004085 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004086 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004087
Vishnu Nair9b079a22020-01-21 14:36:08 -08004088 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004089}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004090
Lloyd Piquea4863342019-12-04 18:45:02 -08004091TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4092 clippedVisibleRegionUsedToGenerateRequest) {
4093 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4094 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4095 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004096
Lloyd Piquea4863342019-12-04 18:45:02 -08004097 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4098 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004099 false, /* needs filtering */
4100 false, /* secure */
4101 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004102 kDisplayViewport,
4103 kDisplayDataspace,
4104 true /* realContentIsVisible */,
4105 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004106 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004107 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004108 };
4109 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4110 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004111 false, /* needs filtering */
4112 false, /* secure */
4113 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004114 kDisplayViewport,
4115 kDisplayDataspace,
4116 true /* realContentIsVisible */,
4117 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004118 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004119 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004120 };
4121 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4122 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004123 false, /* needs filtering */
4124 false, /* secure */
4125 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004126 kDisplayViewport,
4127 kDisplayDataspace,
4128 true /* realContentIsVisible */,
4129 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004130 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004131 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004132 };
4133
Ady Abrahameca9d752021-03-03 12:20:00 -08004134 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004135 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004136 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004137 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004138 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004139 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004140
4141 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004142 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004143 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004144}
4145
4146TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4147 perLayerNeedsFilteringUsedToGenerateRequests) {
4148 mOutput.mState.needsFiltering = false;
4149 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4150
Lloyd Piquea4863342019-12-04 18:45:02 -08004151 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4152 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004153 true, /* needs filtering */
4154 false, /* secure */
4155 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004156 kDisplayViewport,
4157 kDisplayDataspace,
4158 true /* realContentIsVisible */,
4159 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004160 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004161 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004162 };
4163 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4164 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004165 false, /* needs filtering */
4166 false, /* secure */
4167 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004168 kDisplayViewport,
4169 kDisplayDataspace,
4170 true /* realContentIsVisible */,
4171 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004172 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004173 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004174 };
4175 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4176 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004177 false, /* needs filtering */
4178 false, /* secure */
4179 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004180 kDisplayViewport,
4181 kDisplayDataspace,
4182 true /* realContentIsVisible */,
4183 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004184 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004185 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004186 };
4187
Ady Abrahameca9d752021-03-03 12:20:00 -08004188 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004189 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004190 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004191 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004192 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004193 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004194
4195 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004196 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4197 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004198}
4199
4200TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4201 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4202 mOutput.mState.needsFiltering = true;
4203 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4204
Lloyd Piquea4863342019-12-04 18:45:02 -08004205 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4206 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004207 true, /* needs filtering */
4208 false, /* secure */
4209 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004210 kDisplayViewport,
4211 kDisplayDataspace,
4212 true /* realContentIsVisible */,
4213 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004214 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004215 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004216 };
4217 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4218 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004219 true, /* needs filtering */
4220 false, /* secure */
4221 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004222 kDisplayViewport,
4223 kDisplayDataspace,
4224 true /* realContentIsVisible */,
4225 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004226 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004227 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004228 };
4229 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4230 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004231 true, /* needs filtering */
4232 false, /* secure */
4233 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004234 kDisplayViewport,
4235 kDisplayDataspace,
4236 true /* realContentIsVisible */,
4237 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004238 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004239 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004240 };
4241
Ady Abrahameca9d752021-03-03 12:20:00 -08004242 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004243 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004244 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004245 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004246 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004247 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004248
4249 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004250 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4251 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004252}
4253
4254TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4255 wholeOutputSecurityUsedToGenerateRequests) {
4256 mOutput.mState.isSecure = true;
4257
Lloyd Piquea4863342019-12-04 18:45:02 -08004258 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4259 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004260 false, /* needs filtering */
4261 true, /* secure */
4262 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004263 kDisplayViewport,
4264 kDisplayDataspace,
4265 true /* realContentIsVisible */,
4266 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004267 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004268 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004269 };
4270 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4271 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004272 false, /* needs filtering */
4273 true, /* secure */
4274 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004275 kDisplayViewport,
4276 kDisplayDataspace,
4277 true /* realContentIsVisible */,
4278 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004279 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004280 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004281 };
4282 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4283 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004284 false, /* needs filtering */
4285 true, /* secure */
4286 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004287 kDisplayViewport,
4288 kDisplayDataspace,
4289 true /* realContentIsVisible */,
4290 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004291 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004292 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004293 };
4294
Ady Abrahameca9d752021-03-03 12:20:00 -08004295 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004296 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004297 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004298 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004299 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004300 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004301
4302 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004303 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4304 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004305}
4306
4307TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4308 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004309 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4310 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004311 false, /* needs filtering */
4312 false, /* secure */
4313 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004314 kDisplayViewport,
4315 kDisplayDataspace,
4316 true /* realContentIsVisible */,
4317 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004318 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004319 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004320 };
4321 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4322 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004323 false, /* needs filtering */
4324 false, /* secure */
4325 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004326 kDisplayViewport,
4327 kDisplayDataspace,
4328 true /* realContentIsVisible */,
4329 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004330 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004331 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004332 };
4333 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4334 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004335 false, /* needs filtering */
4336 false, /* secure */
4337 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004338 kDisplayViewport,
4339 kDisplayDataspace,
4340 true /* realContentIsVisible */,
4341 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004342 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004343 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004344 };
4345
Ady Abrahameca9d752021-03-03 12:20:00 -08004346 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004347 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004348 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004349 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004350 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004351 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004352
Robert Carrccab4242021-09-28 16:53:03 -07004353 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004354 kDisplayDataspace));
4355}
4356
Lucas Dupin084a6d42021-08-26 22:10:29 +00004357TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4358 InjectedLayer layer1;
4359 InjectedLayer layer2;
4360
4361 uint32_t z = 0;
4362 // Layer requesting blur, or below, should request client composition, unless opaque.
4363 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4364 EXPECT_CALL(*layer1.outputLayer,
4365 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4366 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4367 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4368 EXPECT_CALL(*layer2.outputLayer,
4369 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4370 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4371
4372 layer2.layerFEState.backgroundBlurRadius = 10;
4373 layer2.layerFEState.isOpaque = true;
4374
4375 injectOutputLayer(layer1);
4376 injectOutputLayer(layer2);
4377
4378 mOutput->editState().isEnabled = true;
4379
4380 CompositionRefreshArgs args;
4381 args.updatingGeometryThisFrame = false;
4382 args.devOptForceClientComposition = false;
4383 mOutput->updateCompositionState(args);
4384 mOutput->planComposition();
4385 mOutput->writeCompositionState(args);
4386}
4387
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004388TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004389 InjectedLayer layer1;
4390 InjectedLayer layer2;
4391 InjectedLayer layer3;
4392
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004393 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004394 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004395 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004396 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004397 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4398 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004399 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004400 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004401 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4402 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004403 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004404 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004405 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4406 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004407
Lloyd Piquede196652020-01-22 17:29:58 -08004408 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004409 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004410
Lloyd Piquede196652020-01-22 17:29:58 -08004411 injectOutputLayer(layer1);
4412 injectOutputLayer(layer2);
4413 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004414
4415 mOutput->editState().isEnabled = true;
4416
4417 CompositionRefreshArgs args;
4418 args.updatingGeometryThisFrame = false;
4419 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004420 mOutput->updateCompositionState(args);
4421 mOutput->planComposition();
4422 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004423}
4424
Lucas Dupinc3800b82020-10-02 16:24:48 -07004425TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4426 InjectedLayer layer1;
4427 InjectedLayer layer2;
4428 InjectedLayer layer3;
4429
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004430 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004431 // Layer requesting blur, or below, should request client composition.
4432 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004433 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004434 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4435 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004436 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004437 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004438 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4439 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004440 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004441 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004442 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4443 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004444
4445 BlurRegion region;
4446 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004447 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004448
4449 injectOutputLayer(layer1);
4450 injectOutputLayer(layer2);
4451 injectOutputLayer(layer3);
4452
4453 mOutput->editState().isEnabled = true;
4454
4455 CompositionRefreshArgs args;
4456 args.updatingGeometryThisFrame = false;
4457 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004458 mOutput->updateCompositionState(args);
4459 mOutput->planComposition();
4460 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004461}
4462
Lloyd Piquea4863342019-12-04 18:45:02 -08004463TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4464 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4465 // one layer on the left covering the left side of the output, and one layer
4466 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004467
4468 const Rect kPortraitFrame(0, 0, 1000, 2000);
4469 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004470 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004471 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004472 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004473
Angel Aguayob084e0c2021-08-04 23:27:28 +00004474 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4475 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4476 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004477 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004478 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004479 mOutput.mState.needsFiltering = false;
4480 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004481
Lloyd Piquea4863342019-12-04 18:45:02 -08004482 Layer leftLayer;
4483 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004484
Lloyd Piquea4863342019-12-04 18:45:02 -08004485 leftLayer.mOutputLayerState.clearClientTarget = false;
4486 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4487 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004488 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004489
Lloyd Piquea4863342019-12-04 18:45:02 -08004490 rightLayer.mOutputLayerState.clearClientTarget = false;
4491 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4492 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004493 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004494
4495 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4496 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4497 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4498 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4499 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4500
Lloyd Piquea4863342019-12-04 18:45:02 -08004501 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4502 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004503 false, /* needs filtering */
4504 true, /* secure */
4505 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004506 kPortraitViewport,
4507 kOutputDataspace,
4508 true /* realContentIsVisible */,
4509 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004510 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004511 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004512 };
4513
4514 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4515 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004516 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004517 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004518
4519 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4520 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004521 false, /* needs filtering */
4522 true, /* secure */
4523 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004524 kPortraitViewport,
4525 kOutputDataspace,
4526 true /* realContentIsVisible */,
4527 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004528 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004529 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004530 };
4531
4532 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4533 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004534 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004535 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004536
4537 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004538 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004539 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004540 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004541 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4542 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004543}
4544
Vishnu Naira483b4a2019-12-12 15:07:52 -08004545TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4546 shadowRegionOnlyVisibleSkipsContentComposition) {
4547 const Rect kContentWithShadow(40, 40, 70, 90);
4548 const Rect kContent(50, 50, 60, 80);
4549 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4550 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4551
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004552 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4553 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004554 false, /* needs filtering */
4555 false, /* secure */
4556 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004557 kDisplayViewport,
4558 kDisplayDataspace,
4559 false /* realContentIsVisible */,
4560 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004561 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004562 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004563 };
4564
Vishnu Nair9b079a22020-01-21 14:36:08 -08004565 LayerFE::LayerSettings mShadowSettings;
4566 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004567
4568 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4569 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4570
4571 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4572 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004573 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004574 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004575
Robert Carrccab4242021-09-28 16:53:03 -07004576 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004577 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004578 ASSERT_EQ(1u, requests.size());
4579
Vishnu Nair9b079a22020-01-21 14:36:08 -08004580 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004581}
4582
4583TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4584 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4585 const Rect kContentWithShadow(40, 40, 70, 90);
4586 const Rect kContent(50, 50, 60, 80);
4587 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4588 const Region kPartialContentWithPartialShadowRegion =
4589 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4590
Vishnu Nair9b079a22020-01-21 14:36:08 -08004591 LayerFE::LayerSettings mShadowSettings;
4592 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004593
4594 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4595 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4596
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004597 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4598 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004599 false, /* needs filtering */
4600 false, /* secure */
4601 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004602 kDisplayViewport,
4603 kDisplayDataspace,
4604 true /* realContentIsVisible */,
4605 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004606 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004607 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004608 };
4609
Vishnu Naira483b4a2019-12-12 15:07:52 -08004610 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4611 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004612 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004613 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4614 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004615
Robert Carrccab4242021-09-28 16:53:03 -07004616 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004617 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004618 ASSERT_EQ(2u, requests.size());
4619
Vishnu Nair9b079a22020-01-21 14:36:08 -08004620 EXPECT_EQ(mShadowSettings, requests[0]);
4621 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004622}
4623
Lloyd Pique32cbe282018-10-19 13:09:22 -07004624} // namespace
4625} // namespace android::compositionengine