blob: 66a9ef7179bb680aea82735d30fb076c1589731e [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.
Robert Carr6fe2bef2022-03-09 13:49:41 -0800992 MOCK_METHOD0(chooseCompositionStrategy, void());
Lloyd Pique66d68602019-02-13 14:23:31 -0800993 };
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;
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001313 static const Region kTransparentRegionHint90Rotation;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001314
1315 StrictMock<OutputPartialMock> mOutput;
1316 LayerFESet mGeomSnapshots;
1317 Output::CoverageState mCoverageState{mGeomSnapshots};
1318
Lloyd Piquede196652020-01-22 17:29:58 -08001319 NonInjectedLayer mLayer;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001320};
1321
1322const Region OutputEnsureOutputLayerIfVisibleTest::kEmptyRegion = Region(Rect(0, 0, 0, 0));
1323const Region OutputEnsureOutputLayerIfVisibleTest::kFullBoundsNoRotation =
1324 Region(Rect(0, 0, 100, 200));
1325const Region OutputEnsureOutputLayerIfVisibleTest::kRightHalfBoundsNoRotation =
1326 Region(Rect(0, 100, 100, 200));
1327const Region OutputEnsureOutputLayerIfVisibleTest::kLowerHalfBoundsNoRotation =
1328 Region(Rect(50, 0, 100, 200));
1329const Region OutputEnsureOutputLayerIfVisibleTest::kFullBounds90Rotation =
1330 Region(Rect(0, 0, 200, 100));
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001331const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint =
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001332 Region(Rect(25, 20, 50, 75));
1333const Region OutputEnsureOutputLayerIfVisibleTest::kTransparentRegionHint90Rotation =
1334 Region(Rect(125, 25, 180, 50));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001335
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001336TEST_F(OutputEnsureOutputLayerIfVisibleTest, performsGeomLatchBeforeCheckingIfLayerIncluded) {
1337 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquede196652020-01-22 17:29:58 -08001338 EXPECT_CALL(*mLayer.layerFE,
1339 prepareCompositionState(compositionengine::LayerFE::StateSubset::BasicGeometry));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001340
1341 mGeomSnapshots.clear();
1342
Lloyd Piquede196652020-01-22 17:29:58 -08001343 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001344}
1345
1346TEST_F(OutputEnsureOutputLayerIfVisibleTest,
Dominik Laskowski29fa1462021-04-27 15:51:50 -07001347 skipsLatchIfAlreadyLatchedBeforeCheckingIfLayerIncluded) {
1348 EXPECT_CALL(mOutput, includesLayer(sp<LayerFE>(mLayer.layerFE))).WillOnce(Return(false));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001349
Lloyd Piquede196652020-01-22 17:29:58 -08001350 ensureOutputLayerIfVisible();
1351}
1352
1353TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasNoCompositionState) {
1354 EXPECT_CALL(*mLayer.layerFE, getCompositionState()).WillOnce(Return(nullptr));
1355
1356 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001357}
1358
1359TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerNotVisible) {
Lloyd Piquede196652020-01-22 17:29:58 -08001360 mLayer.layerFEState.isVisible = false;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001361
Lloyd Piquede196652020-01-22 17:29:58 -08001362 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001363}
1364
1365TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesEarlyOutIfLayerHasEmptyVisibleRegion) {
Lloyd Piquede196652020-01-22 17:29:58 -08001366 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 0, 0};
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001367
Lloyd Piquede196652020-01-22 17:29:58 -08001368 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001369}
1370
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001371TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifDrawRegionEmpty) {
Angel Aguayob084e0c2021-08-04 23:27:28 +00001372 mOutput.mState.displaySpace.setBounds(ui::Size(0, 0));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001373
Lloyd Piquede196652020-01-22 17:29:58 -08001374 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001375}
1376
1377TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1378 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001379 mLayer.layerFEState.isOpaque = true;
1380 mLayer.layerFEState.contentDirty = true;
1381 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001382
1383 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001384 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1385 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001386
Lloyd Piquede196652020-01-22 17:29:58 -08001387 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001388
1389 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1390 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1391 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1392
Lloyd Piquede196652020-01-22 17:29:58 -08001393 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1394 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1395 RegionEq(kFullBoundsNoRotation));
1396 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1397 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001398}
1399
1400TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1401 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001402 mLayer.layerFEState.isOpaque = true;
1403 mLayer.layerFEState.contentDirty = true;
1404 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001405
Lloyd Piquede196652020-01-22 17:29:58 -08001406 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1407 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001408
Lloyd Piquede196652020-01-22 17:29:58 -08001409 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001410
1411 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1412 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1413 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1414
Lloyd Piquede196652020-01-22 17:29:58 -08001415 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1416 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1417 RegionEq(kFullBoundsNoRotation));
1418 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1419 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001420}
1421
1422TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1423 handlesCreatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001424 mLayer.layerFEState.isOpaque = false;
1425 mLayer.layerFEState.contentDirty = true;
1426 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001427
1428 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001429 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1430 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001431
Lloyd Piquede196652020-01-22 17:29:58 -08001432 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001433
1434 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1435 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1436 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1437
Lloyd Piquede196652020-01-22 17:29:58 -08001438 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1439 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001440 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001441 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1442 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001443}
1444
1445TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1446 handlesUpdatingOutputLayerForTransparentDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001447 mLayer.layerFEState.isOpaque = false;
1448 mLayer.layerFEState.contentDirty = true;
1449 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001450
Lloyd Piquede196652020-01-22 17:29:58 -08001451 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1452 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001453
Lloyd Piquede196652020-01-22 17:29:58 -08001454 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001455
1456 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1457 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1458 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1459
Lloyd Piquede196652020-01-22 17:29:58 -08001460 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1461 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001462 RegionEq(kRightHalfBoundsNoRotation));
Lloyd Piquede196652020-01-22 17:29:58 -08001463 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1464 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001465}
1466
1467TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1468 handlesCreatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001469 mLayer.layerFEState.isOpaque = true;
1470 mLayer.layerFEState.contentDirty = false;
1471 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001472
1473 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001474 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1475 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001476
Lloyd Piquede196652020-01-22 17:29:58 -08001477 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001478
1479 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1480 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1481 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1482
Lloyd Piquede196652020-01-22 17:29:58 -08001483 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1484 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1485 RegionEq(kFullBoundsNoRotation));
1486 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1487 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001488}
1489
1490TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1491 handlesUpdatingOutputLayerForOpaqueNonDirtyNotRotatedLayer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001492 mLayer.layerFEState.isOpaque = true;
1493 mLayer.layerFEState.contentDirty = false;
1494 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001495
Lloyd Piquede196652020-01-22 17:29:58 -08001496 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1497 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001498
Lloyd Piquede196652020-01-22 17:29:58 -08001499 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001500
1501 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kLowerHalfBoundsNoRotation));
1502 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1503 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1504
Lloyd Piquede196652020-01-22 17:29:58 -08001505 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1506 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1507 RegionEq(kFullBoundsNoRotation));
1508 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1509 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001510}
1511
1512TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1513 handlesCreatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001514 mLayer.layerFEState.isOpaque = true;
1515 mLayer.layerFEState.contentDirty = true;
1516 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1517 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1518 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1519 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001520
1521 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001522 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1523 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001524
Lloyd Piquede196652020-01-22 17:29:58 -08001525 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001526
1527 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1528 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1529 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1530
Lloyd Piquede196652020-01-22 17:29:58 -08001531 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1532 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1533 RegionEq(kFullBoundsNoRotation));
1534 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1535 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001536}
1537
1538TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1539 handlesUpdatingOutputLayerForOpaqueDirtyRotated90Layer) {
Lloyd Piquede196652020-01-22 17:29:58 -08001540 mLayer.layerFEState.isOpaque = true;
1541 mLayer.layerFEState.contentDirty = true;
1542 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 200, 100};
1543 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_ROT_90, 100, 200);
1544 mLayer.outputLayerState.visibleRegion = Region(Rect(0, 0, 100, 100));
1545 mLayer.outputLayerState.coveredRegion = Region(Rect(100, 0, 200, 100));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001546
Lloyd Piquede196652020-01-22 17:29:58 -08001547 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1548 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001549
Lloyd Piquede196652020-01-22 17:29:58 -08001550 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001551
1552 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1553 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1554 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1555
Lloyd Piquede196652020-01-22 17:29:58 -08001556 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1557 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1558 RegionEq(kFullBoundsNoRotation));
1559 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1560 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBoundsNoRotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001561}
1562
1563TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1564 handlesCreatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001565 mLayer.layerFEState.isOpaque = true;
1566 mLayer.layerFEState.contentDirty = true;
1567 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001568
Angel Aguayob084e0c2021-08-04 23:27:28 +00001569 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001570 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1571
1572 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001573 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1574 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001575
Lloyd Piquede196652020-01-22 17:29:58 -08001576 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001577
1578 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1579 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1580 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1581
Lloyd Piquede196652020-01-22 17:29:58 -08001582 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1583 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1584 RegionEq(kFullBoundsNoRotation));
1585 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1586 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001587}
1588
1589TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1590 handlesUpdatingOutputLayerForOpaqueDirtyNotRotatedLayerRotatedOutput) {
Lloyd Piquede196652020-01-22 17:29:58 -08001591 mLayer.layerFEState.isOpaque = true;
1592 mLayer.layerFEState.contentDirty = true;
1593 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001594
Angel Aguayob084e0c2021-08-04 23:27:28 +00001595 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001596 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1597
Lloyd Piquede196652020-01-22 17:29:58 -08001598 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1599 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001600
Lloyd Piquede196652020-01-22 17:29:58 -08001601 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001602
1603 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kFullBoundsNoRotation));
1604 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kFullBoundsNoRotation));
1605 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kFullBoundsNoRotation));
1606
Lloyd Piquede196652020-01-22 17:29:58 -08001607 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kFullBoundsNoRotation));
1608 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
1609 RegionEq(kFullBoundsNoRotation));
1610 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1611 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kFullBounds90Rotation));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001612}
1613
1614TEST_F(OutputEnsureOutputLayerIfVisibleTest,
1615 handlesCreatingOutputLayerForOpaqueDirtyArbitraryTransformLayer) {
1616 ui::Transform arbitraryTransform;
1617 arbitraryTransform.set(1, 1, -1, 1);
1618 arbitraryTransform.set(0, 100);
1619
Lloyd Piquede196652020-01-22 17:29:58 -08001620 mLayer.layerFEState.isOpaque = true;
1621 mLayer.layerFEState.contentDirty = true;
1622 mLayer.layerFEState.geomLayerBounds = FloatRect{0, 0, 100, 200};
1623 mLayer.layerFEState.geomLayerTransform = arbitraryTransform;
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001624
1625 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
Lloyd Piquede196652020-01-22 17:29:58 -08001626 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1627 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001628
Lloyd Piquede196652020-01-22 17:29:58 -08001629 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001630
1631 const Region kRegion = Region(Rect(0, 0, 300, 300));
1632 const Region kRegionClipped = Region(Rect(0, 0, 200, 300));
1633
1634 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kRegion));
1635 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kRegion));
1636 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kEmptyRegion));
1637
Lloyd Piquede196652020-01-22 17:29:58 -08001638 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kRegion));
1639 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion, RegionEq(kRegion));
1640 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kEmptyRegion));
1641 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion, RegionEq(kRegionClipped));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001642}
1643
1644TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesTest) {
Lloyd Piquede196652020-01-22 17:29:58 -08001645 mLayer.layerFEState.isOpaque = false;
1646 mLayer.layerFEState.contentDirty = true;
1647 mLayer.layerFEState.geomLayerTransform = ui::Transform(TR_IDENT, 100, 200);
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001648
1649 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1650 mCoverageState.aboveCoveredLayers = Region(Rect(50, 0, 150, 200));
1651 mCoverageState.aboveOpaqueLayers = Region(Rect(50, 0, 150, 200));
1652
Lloyd Piquede196652020-01-22 17:29:58 -08001653 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1654 .WillOnce(Return(&mLayer.outputLayer));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001655
Lloyd Piquede196652020-01-22 17:29:58 -08001656 ensureOutputLayerIfVisible();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001657
1658 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1659 const Region kExpectedAboveCoveredRegion = Region(Rect(0, 0, 150, 200));
1660 const Region kExpectedAboveOpaqueRegion = Region(Rect(50, 0, 150, 200));
1661 const Region kExpectedLayerVisibleRegion = Region(Rect(0, 0, 50, 200));
1662 const Region kExpectedLayerCoveredRegion = Region(Rect(50, 0, 100, 200));
1663 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(0, 100, 50, 200));
1664
1665 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1666 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1667 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1668
Lloyd Piquede196652020-01-22 17:29:58 -08001669 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1670 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001671 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001672 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1673 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
1674 RegionEq(kExpectedLayerVisibleRegion));
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08001675}
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001676
Vishnu Naira483b4a2019-12-12 15:07:52 -08001677TEST_F(OutputEnsureOutputLayerIfVisibleTest, coverageAccumulatesWithShadowsTest) {
1678 ui::Transform translate;
1679 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001680 mLayer.layerFEState.geomLayerTransform = translate;
1681 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001682
1683 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1684 // half of the layer including the casting shadow is covered and opaque
1685 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 100, 260));
1686 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 100, 260));
1687
Lloyd Piquede196652020-01-22 17:29:58 -08001688 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1689 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001690
Lloyd Piquede196652020-01-22 17:29:58 -08001691 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001692
1693 const Region kExpectedDirtyRegion = Region(Rect(0, 0, 500, 500));
1694 const Region kExpectedAboveCoveredRegion = Region(Rect(40, 40, 160, 260));
1695 // add starting opaque region to the opaque half of the casting layer bounds
1696 const Region kExpectedAboveOpaqueRegion =
1697 Region(Rect(40, 40, 100, 260)).orSelf(Rect(100, 50, 150, 250));
1698 const Region kExpectedLayerVisibleRegion = Region(Rect(100, 40, 160, 260));
1699 const Region kExpectedoutputSpaceLayerVisibleRegion = Region(Rect(100, 50, 150, 250));
1700 const Region kExpectedLayerCoveredRegion = Region(Rect(40, 40, 100, 260));
1701 const Region kExpectedLayerVisibleNonTransparentRegion = Region(Rect(100, 40, 160, 260));
1702 const Region kExpectedLayerShadowRegion =
1703 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1704
1705 EXPECT_THAT(mCoverageState.dirtyRegion, RegionEq(kExpectedDirtyRegion));
1706 EXPECT_THAT(mCoverageState.aboveCoveredLayers, RegionEq(kExpectedAboveCoveredRegion));
1707 EXPECT_THAT(mCoverageState.aboveOpaqueLayers, RegionEq(kExpectedAboveOpaqueRegion));
1708
Lloyd Piquede196652020-01-22 17:29:58 -08001709 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1710 EXPECT_THAT(mLayer.outputLayerState.visibleNonTransparentRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001711 RegionEq(kExpectedLayerVisibleNonTransparentRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001712 EXPECT_THAT(mLayer.outputLayerState.coveredRegion, RegionEq(kExpectedLayerCoveredRegion));
1713 EXPECT_THAT(mLayer.outputLayerState.outputSpaceVisibleRegion,
Vishnu Naira483b4a2019-12-12 15:07:52 -08001714 RegionEq(kExpectedoutputSpaceLayerVisibleRegion));
Lloyd Piquede196652020-01-22 17:29:58 -08001715 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001716 EXPECT_FALSE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1717}
1718
1719TEST_F(OutputEnsureOutputLayerIfVisibleTest, shadowRegionOnlyTest) {
1720 ui::Transform translate;
1721 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001722 mLayer.layerFEState.geomLayerTransform = translate;
1723 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001724
1725 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1726 // Casting layer is covered by an opaque region leaving only part of its shadow to be drawn
1727 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 150, 260));
1728 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 150, 260));
1729
Lloyd Piquede196652020-01-22 17:29:58 -08001730 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(0u), Eq(mLayer.layerFE)))
1731 .WillOnce(Return(&mLayer.outputLayer));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001732
Lloyd Piquede196652020-01-22 17:29:58 -08001733 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001734
1735 const Region kExpectedLayerVisibleRegion = Region(Rect(150, 40, 160, 260));
1736 const Region kExpectedLayerShadowRegion =
1737 Region(Rect(40, 40, 160, 260)).subtractSelf(Rect(50, 50, 150, 250));
1738
Lloyd Piquede196652020-01-22 17:29:58 -08001739 EXPECT_THAT(mLayer.outputLayerState.visibleRegion, RegionEq(kExpectedLayerVisibleRegion));
1740 EXPECT_THAT(mLayer.outputLayerState.shadowRegion, RegionEq(kExpectedLayerShadowRegion));
Vishnu Naira483b4a2019-12-12 15:07:52 -08001741 EXPECT_TRUE(kExpectedLayerVisibleRegion.subtract(kExpectedLayerShadowRegion).isEmpty());
1742}
1743
Marin Shalamanove67fcd02020-07-01 13:25:38 +00001744TEST_F(OutputEnsureOutputLayerIfVisibleTest, takesNotSoEarlyOutifLayerWithShadowIsCovered) {
Vishnu Naira483b4a2019-12-12 15:07:52 -08001745 ui::Transform translate;
1746 translate.set(50, 50);
Lloyd Piquede196652020-01-22 17:29:58 -08001747 mLayer.layerFEState.geomLayerTransform = translate;
1748 mLayer.layerFEState.shadowRadius = 10.0f;
Vishnu Naira483b4a2019-12-12 15:07:52 -08001749
1750 mCoverageState.dirtyRegion = Region(Rect(0, 0, 500, 500));
1751 // Casting layer and its shadows are covered by an opaque region
1752 mCoverageState.aboveCoveredLayers = Region(Rect(40, 40, 160, 260));
1753 mCoverageState.aboveOpaqueLayers = Region(Rect(40, 40, 160, 260));
1754
Lloyd Piquede196652020-01-22 17:29:58 -08001755 ensureOutputLayerIfVisible();
Vishnu Naira483b4a2019-12-12 15:07:52 -08001756}
1757
Leon Scroggins III9a0afda2022-01-11 16:53:09 -05001758TEST_F(OutputEnsureOutputLayerIfVisibleTest, displayDecorSetsBlockingFromTransparentRegion) {
1759 mLayer.layerFEState.isOpaque = false;
1760 mLayer.layerFEState.contentDirty = true;
1761 mLayer.layerFEState.compositionType =
1762 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1763
1764 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1765 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1766 .WillOnce(Return(&mLayer.outputLayer));
1767 ensureOutputLayerIfVisible();
1768
1769 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1770 RegionEq(kTransparentRegionHint));
1771}
1772
1773TEST_F(OutputEnsureOutputLayerIfVisibleTest, normalLayersDoNotSetBlockingRegion) {
1774 mLayer.layerFEState.isOpaque = false;
1775 mLayer.layerFEState.contentDirty = true;
1776
1777 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1778 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1779 .WillOnce(Return(&mLayer.outputLayer));
1780 ensureOutputLayerIfVisible();
1781
1782 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint, RegionEq(Region()));
1783}
1784
Leon Scroggins III7f7ad2c2022-03-17 17:06:20 -04001785TEST_F(OutputEnsureOutputLayerIfVisibleTest, blockingRegionIsInOutputSpace) {
1786 mLayer.layerFEState.isOpaque = false;
1787 mLayer.layerFEState.contentDirty = true;
1788 mLayer.layerFEState.compositionType =
1789 aidl::android::hardware::graphics::composer3::Composition::DISPLAY_DECORATION;
1790
1791 mOutput.mState.layerStackSpace.setContent(Rect(0, 0, 300, 200));
1792 mOutput.mState.transform = ui::Transform(TR_ROT_90, 200, 300);
1793
1794 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
1795 EXPECT_CALL(mOutput, ensureOutputLayer(Eq(std::nullopt), Eq(mLayer.layerFE)))
1796 .WillOnce(Return(&mLayer.outputLayer));
1797 ensureOutputLayerIfVisible();
1798
1799 EXPECT_THAT(mLayer.outputLayerState.outputSpaceBlockingRegionHint,
1800 RegionEq(kTransparentRegionHint90Rotation));
1801}
1802
Lloyd Piqueb62cebc2019-11-20 18:31:52 -08001803/*
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001804 * Output::present()
1805 */
1806
1807struct OutputPresentTest : public testing::Test {
1808 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001809 // Sets up the helper functions called by the function under test to use
1810 // mock implementations.
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001811 MOCK_METHOD1(updateColorProfile, void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001812 MOCK_METHOD1(updateCompositionState,
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001813 void(const compositionengine::CompositionRefreshArgs&));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001814 MOCK_METHOD0(planComposition, void());
1815 MOCK_METHOD1(writeCompositionState, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001816 MOCK_METHOD1(setColorTransform, void(const compositionengine::CompositionRefreshArgs&));
1817 MOCK_METHOD0(beginFrame, void());
1818 MOCK_METHOD0(prepareFrame, void());
1819 MOCK_METHOD1(devOptRepaintFlash, void(const compositionengine::CompositionRefreshArgs&));
Robert Carr6fe2bef2022-03-09 13:49:41 -08001820 MOCK_METHOD1(finishFrame, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001821 MOCK_METHOD0(postFramebuffer, void());
Alec Mouriaa831582021-06-07 16:23:01 -07001822 MOCK_METHOD1(renderCachedSets, void(const compositionengine::CompositionRefreshArgs&));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001823 };
1824
1825 StrictMock<OutputPartialMock> mOutput;
1826};
1827
1828TEST_F(OutputPresentTest, justInvokesChildFunctionsInSequence) {
1829 CompositionRefreshArgs args;
1830
1831 InSequence seq;
1832 EXPECT_CALL(mOutput, updateColorProfile(Ref(args)));
Dan Stoza269dc4d2021-01-15 15:07:43 -08001833 EXPECT_CALL(mOutput, updateCompositionState(Ref(args)));
1834 EXPECT_CALL(mOutput, planComposition());
1835 EXPECT_CALL(mOutput, writeCompositionState(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001836 EXPECT_CALL(mOutput, setColorTransform(Ref(args)));
1837 EXPECT_CALL(mOutput, beginFrame());
1838 EXPECT_CALL(mOutput, prepareFrame());
1839 EXPECT_CALL(mOutput, devOptRepaintFlash(Ref(args)));
Robert Carr6fe2bef2022-03-09 13:49:41 -08001840 EXPECT_CALL(mOutput, finishFrame(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001841 EXPECT_CALL(mOutput, postFramebuffer());
Alec Mouriaa831582021-06-07 16:23:01 -07001842 EXPECT_CALL(mOutput, renderCachedSets(Ref(args)));
Lloyd Piquefaa3f192019-11-14 14:05:09 -08001843
1844 mOutput.present(args);
1845}
1846
1847/*
1848 * Output::updateColorProfile()
1849 */
1850
Lloyd Pique17ca7422019-11-14 14:24:10 -08001851struct OutputUpdateColorProfileTest : public testing::Test {
1852 using TestType = OutputUpdateColorProfileTest;
1853
1854 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08001855 // Sets up the helper functions called by the function under test to use
1856 // mock implementations.
Lloyd Pique17ca7422019-11-14 14:24:10 -08001857 MOCK_METHOD1(setColorProfile, void(const ColorProfile&));
1858 };
1859
1860 struct Layer {
1861 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08001862 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
1863 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001864 }
1865
1866 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08001867 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique17ca7422019-11-14 14:24:10 -08001868 LayerFECompositionState mLayerFEState;
1869 };
1870
1871 OutputUpdateColorProfileTest() {
1872 mOutput.setDisplayColorProfileForTest(
1873 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
1874 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
1875
1876 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0))
1877 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
1878 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1))
1879 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
1880 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2))
1881 .WillRepeatedly(Return(&mLayer3.mOutputLayer));
1882 }
1883
1884 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
1885 void execute() { getInstance()->mOutput.updateColorProfile(getInstance()->mRefreshArgs); }
1886 };
1887
1888 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
1889 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
1890 StrictMock<OutputPartialMock> mOutput;
1891
1892 Layer mLayer1;
1893 Layer mLayer2;
1894 Layer mLayer3;
1895
1896 CompositionRefreshArgs mRefreshArgs;
1897};
1898
1899// TODO(b/144522012): Refactor Output::updateColorProfile and the related code
1900// to make it easier to write unit tests.
1901
1902TEST_F(OutputUpdateColorProfileTest, setsAColorProfileWhenUnmanaged) {
1903 // When the outputColorSetting is set to kUnmanaged, the implementation sets
1904 // a simple default color profile without looking at anything else.
1905
Lloyd Pique0a456232020-01-16 17:51:13 -08001906 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001907 EXPECT_CALL(mOutput,
1908 setColorProfile(ColorProfileEq(
1909 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1910 ui::RenderIntent::COLORIMETRIC, ui::Dataspace::UNKNOWN})));
1911
1912 mRefreshArgs.outputColorSetting = OutputColorSetting::kUnmanaged;
1913 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1914
1915 mOutput.updateColorProfile(mRefreshArgs);
1916}
1917
1918struct OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile
1919 : public OutputUpdateColorProfileTest {
1920 OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001921 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001922 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1923 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
1924 }
1925
1926 struct ExpectBestColorModeCallResultUsedToSetColorProfileState
1927 : public CallOrderStateMachineHelper<
1928 TestType, ExpectBestColorModeCallResultUsedToSetColorProfileState> {
1929 [[nodiscard]] auto expectBestColorModeCallResultUsedToSetColorProfile(
1930 ui::ColorMode colorMode, ui::Dataspace dataspace, ui::RenderIntent renderIntent) {
1931 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
1932 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _,
1933 _))
1934 .WillOnce(DoAll(SetArgPointee<2>(dataspace), SetArgPointee<3>(colorMode),
1935 SetArgPointee<4>(renderIntent)));
1936 EXPECT_CALL(getInstance()->mOutput,
1937 setColorProfile(
1938 ColorProfileEq(ColorProfile{colorMode, dataspace, renderIntent,
1939 ui::Dataspace::UNKNOWN})));
1940 return nextState<ExecuteState>();
1941 }
1942 };
1943
1944 // Call this member function to start using the mini-DSL defined above.
1945 [[nodiscard]] auto verify() {
1946 return ExpectBestColorModeCallResultUsedToSetColorProfileState::make(this);
1947 }
1948};
1949
1950TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1951 Native_Unknown_Colorimetric_Set) {
1952 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::NATIVE,
1953 ui::Dataspace::UNKNOWN,
1954 ui::RenderIntent::COLORIMETRIC)
1955 .execute();
1956}
1957
1958TEST_F(OutputUpdateColorProfileTest_GetBestColorModeResultBecomesSetProfile,
1959 DisplayP3_DisplayP3_Enhance_Set) {
1960 verify().expectBestColorModeCallResultUsedToSetColorProfile(ui::ColorMode::DISPLAY_P3,
1961 ui::Dataspace::DISPLAY_P3,
1962 ui::RenderIntent::ENHANCE)
1963 .execute();
1964}
1965
1966struct OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile
1967 : public OutputUpdateColorProfileTest {
1968 OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile() {
Lloyd Pique0a456232020-01-16 17:51:13 -08001969 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(0u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08001970 EXPECT_CALL(*mDisplayColorProfile,
1971 getBestColorMode(ui::Dataspace::V0_SRGB, ui::RenderIntent::ENHANCE, _, _, _))
1972 .WillRepeatedly(DoAll(SetArgPointee<2>(ui::Dataspace::UNKNOWN),
1973 SetArgPointee<3>(ui::ColorMode::NATIVE),
1974 SetArgPointee<4>(ui::RenderIntent::COLORIMETRIC)));
1975 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
1976 }
1977
1978 struct IfColorSpaceAgnosticDataspaceSetToState
1979 : public CallOrderStateMachineHelper<TestType, IfColorSpaceAgnosticDataspaceSetToState> {
1980 [[nodiscard]] auto ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace dataspace) {
1981 getInstance()->mRefreshArgs.colorSpaceAgnosticDataspace = dataspace;
1982 return nextState<ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState>();
1983 }
1984 };
1985
1986 struct ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState
1987 : public CallOrderStateMachineHelper<
1988 TestType, ThenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspaceState> {
1989 [[nodiscard]] auto thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(
1990 ui::Dataspace dataspace) {
1991 EXPECT_CALL(getInstance()->mOutput,
1992 setColorProfile(ColorProfileEq(
1993 ColorProfile{ui::ColorMode::NATIVE, ui::Dataspace::UNKNOWN,
1994 ui::RenderIntent::COLORIMETRIC, dataspace})));
1995 return nextState<ExecuteState>();
1996 }
1997 };
1998
1999 // Call this member function to start using the mini-DSL defined above.
2000 [[nodiscard]] auto verify() { return IfColorSpaceAgnosticDataspaceSetToState::make(this); }
2001};
2002
2003TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, DisplayP3) {
2004 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::DISPLAY_P3)
2005 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::DISPLAY_P3)
2006 .execute();
2007}
2008
2009TEST_F(OutputUpdateColorProfileTest_ColorSpaceAgnosticeDataspaceAffectsSetColorProfile, V0_SRGB) {
2010 verify().ifColorSpaceAgnosticDataspaceSetTo(ui::Dataspace::V0_SRGB)
2011 .thenExpectSetColorProfileCallUsesColorSpaceAgnosticDataspace(ui::Dataspace::V0_SRGB)
2012 .execute();
2013}
2014
2015struct OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference
2016 : public OutputUpdateColorProfileTest {
2017 // Internally the implementation looks through the dataspaces of all the
2018 // visible layers. The topmost one that also has an actual dataspace
2019 // preference set is used to drive subsequent choices.
2020
2021 OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference() {
2022 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2023 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2024
Lloyd Pique0a456232020-01-16 17:51:13 -08002025 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002026 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2027 }
2028
2029 struct IfTopLayerDataspaceState
2030 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2031 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2032 getInstance()->mLayer3.mLayerFEState.dataspace = dataspace;
2033 return nextState<AndIfMiddleLayerDataspaceState>();
2034 }
2035 [[nodiscard]] auto ifTopLayerHasNoPreference() {
2036 return ifTopLayerIs(ui::Dataspace::UNKNOWN);
2037 }
2038 };
2039
2040 struct AndIfMiddleLayerDataspaceState
2041 : public CallOrderStateMachineHelper<TestType, AndIfMiddleLayerDataspaceState> {
2042 [[nodiscard]] auto andIfMiddleLayerIs(ui::Dataspace dataspace) {
2043 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2044 return nextState<AndIfBottomLayerDataspaceState>();
2045 }
2046 [[nodiscard]] auto andIfMiddleLayerHasNoPreference() {
2047 return andIfMiddleLayerIs(ui::Dataspace::UNKNOWN);
2048 }
2049 };
2050
2051 struct AndIfBottomLayerDataspaceState
2052 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2053 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2054 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2055 return nextState<ThenExpectBestColorModeCallUsesState>();
2056 }
2057 [[nodiscard]] auto andIfBottomLayerHasNoPreference() {
2058 return andIfBottomLayerIs(ui::Dataspace::UNKNOWN);
2059 }
2060 };
2061
2062 struct ThenExpectBestColorModeCallUsesState
2063 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2064 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2065 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2066 getBestColorMode(dataspace, _, _, _, _));
2067 return nextState<ExecuteState>();
2068 }
2069 };
2070
2071 // Call this member function to start using the mini-DSL defined above.
2072 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2073};
2074
2075TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2076 noStrongLayerPrefenceUses_V0_SRGB) {
2077 // If none of the layers indicate a preference, then V0_SRGB is the
2078 // preferred choice (subject to additional checks).
2079 verify().ifTopLayerHasNoPreference()
2080 .andIfMiddleLayerHasNoPreference()
2081 .andIfBottomLayerHasNoPreference()
2082 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2083 .execute();
2084}
2085
2086TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2087 ifTopmostUses_DisplayP3_Then_DisplayP3_Chosen) {
2088 // If only the topmost layer has a preference, then that is what is chosen.
2089 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2090 .andIfMiddleLayerHasNoPreference()
2091 .andIfBottomLayerHasNoPreference()
2092 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2093 .execute();
2094}
2095
2096TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2097 ifMiddleUses_DisplayP3_Then_DisplayP3_Chosen) {
2098 // If only the middle layer has a preference, that that is what is chosen.
2099 verify().ifTopLayerHasNoPreference()
2100 .andIfMiddleLayerIs(ui::Dataspace::DISPLAY_P3)
2101 .andIfBottomLayerHasNoPreference()
2102 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2103 .execute();
2104}
2105
2106TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2107 ifBottomUses_DisplayP3_Then_DisplayP3_Chosen) {
2108 // If only the middle layer has a preference, that that is what is chosen.
2109 verify().ifTopLayerHasNoPreference()
2110 .andIfMiddleLayerHasNoPreference()
2111 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2112 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2113 .execute();
2114}
2115
2116TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2117 ifTopUses_DisplayBT2020_AndBottomUses_DisplayP3_Then_DisplayBT2020_Chosen) {
2118 // If multiple layers have a preference, the topmost value is what is used.
2119 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_BT2020)
2120 .andIfMiddleLayerHasNoPreference()
2121 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_P3)
2122 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2123 .execute();
2124}
2125
2126TEST_F(OutputUpdateColorProfileTest_TopmostLayerPreferenceSetsOutputPreference,
2127 ifTopUses_DisplayP3_AndBottomUses_V0_SRGB_Then_DisplayP3_Chosen) {
2128 // If multiple layers have a preference, the topmost value is what is used.
2129 verify().ifTopLayerIs(ui::Dataspace::DISPLAY_P3)
2130 .andIfMiddleLayerHasNoPreference()
2131 .andIfBottomLayerIs(ui::Dataspace::DISPLAY_BT2020)
2132 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2133 .execute();
2134}
2135
2136struct OutputUpdateColorProfileTest_ForceOutputColorOverrides
2137 : public OutputUpdateColorProfileTest {
2138 // If CompositionRefreshArgs::forceOutputColorMode is set to some specific
2139 // values, it overrides the layer dataspace choice.
2140
2141 OutputUpdateColorProfileTest_ForceOutputColorOverrides() {
2142 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2143 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2144
2145 mLayer1.mLayerFEState.dataspace = ui::Dataspace::DISPLAY_BT2020;
2146
Lloyd Pique0a456232020-01-16 17:51:13 -08002147 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002148 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2149 }
2150
2151 struct IfForceOutputColorModeState
2152 : public CallOrderStateMachineHelper<TestType, IfForceOutputColorModeState> {
2153 [[nodiscard]] auto ifForceOutputColorMode(ui::ColorMode colorMode) {
2154 getInstance()->mRefreshArgs.forceOutputColorMode = colorMode;
2155 return nextState<ThenExpectBestColorModeCallUsesState>();
2156 }
2157 [[nodiscard]] auto ifNoOverride() { return ifForceOutputColorMode(ui::ColorMode::NATIVE); }
2158 };
2159
2160 struct ThenExpectBestColorModeCallUsesState
2161 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2162 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2163 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2164 getBestColorMode(dataspace, _, _, _, _));
2165 return nextState<ExecuteState>();
2166 }
2167 };
2168
2169 // Call this member function to start using the mini-DSL defined above.
2170 [[nodiscard]] auto verify() { return IfForceOutputColorModeState::make(this); }
2171};
2172
2173TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, NoOverride_DoesNotOverride) {
2174 // By default the layer state is used to set the preferred dataspace
2175 verify().ifNoOverride()
2176 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_BT2020)
2177 .execute();
2178}
2179
2180TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, SRGB_Override_USES_V0_SRGB) {
2181 // Setting ui::ColorMode::SRGB overrides it with ui::Dataspace::V0_SRGB
2182 verify().ifForceOutputColorMode(ui::ColorMode::SRGB)
2183 .thenExpectBestColorModeCallUses(ui::Dataspace::V0_SRGB)
2184 .execute();
2185}
2186
2187TEST_F(OutputUpdateColorProfileTest_ForceOutputColorOverrides, DisplayP3_Override_Uses_DisplayP3) {
2188 // Setting ui::ColorMode::DISPLAY_P3 overrides it with ui::Dataspace::DISPLAY_P3
2189 verify().ifForceOutputColorMode(ui::ColorMode::DISPLAY_P3)
2190 .thenExpectBestColorModeCallUses(ui::Dataspace::DISPLAY_P3)
2191 .execute();
2192}
2193
2194// HDR output requires all layers to be compatible with the chosen HDR
2195// dataspace, along with there being proper support.
2196struct OutputUpdateColorProfileTest_Hdr : public OutputUpdateColorProfileTest {
2197 OutputUpdateColorProfileTest_Hdr() {
2198 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2199 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
Lloyd Pique0a456232020-01-16 17:51:13 -08002200 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002201 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2202 }
2203
2204 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2205 static constexpr ui::Dataspace BT2020_PQ = ui::Dataspace::BT2020_PQ;
2206 static constexpr ui::Dataspace BT2020_HLG = ui::Dataspace::BT2020_HLG;
2207 static constexpr ui::Dataspace DISPLAY_P3 = ui::Dataspace::DISPLAY_P3;
2208
2209 struct IfTopLayerDataspaceState
2210 : public CallOrderStateMachineHelper<TestType, IfTopLayerDataspaceState> {
2211 [[nodiscard]] auto ifTopLayerIs(ui::Dataspace dataspace) {
2212 getInstance()->mLayer2.mLayerFEState.dataspace = dataspace;
2213 return nextState<AndTopLayerCompositionTypeState>();
2214 }
2215 [[nodiscard]] auto ifTopLayerIsNotHdr() { return ifTopLayerIs(kNonHdrDataspace); }
2216 };
2217
2218 struct AndTopLayerCompositionTypeState
2219 : public CallOrderStateMachineHelper<TestType, AndTopLayerCompositionTypeState> {
2220 [[nodiscard]] auto andTopLayerIsREComposed(bool renderEngineComposed) {
2221 getInstance()->mLayer2.mLayerFEState.forceClientComposition = renderEngineComposed;
2222 return nextState<AndIfBottomLayerDataspaceState>();
2223 }
2224 };
2225
2226 struct AndIfBottomLayerDataspaceState
2227 : public CallOrderStateMachineHelper<TestType, AndIfBottomLayerDataspaceState> {
2228 [[nodiscard]] auto andIfBottomLayerIs(ui::Dataspace dataspace) {
2229 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2230 return nextState<AndBottomLayerCompositionTypeState>();
2231 }
2232 [[nodiscard]] auto andIfBottomLayerIsNotHdr() {
2233 return andIfBottomLayerIs(kNonHdrDataspace);
2234 }
2235 };
2236
2237 struct AndBottomLayerCompositionTypeState
2238 : public CallOrderStateMachineHelper<TestType, AndBottomLayerCompositionTypeState> {
2239 [[nodiscard]] auto andBottomLayerIsREComposed(bool renderEngineComposed) {
2240 getInstance()->mLayer1.mLayerFEState.forceClientComposition = renderEngineComposed;
2241 return nextState<AndIfHasLegacySupportState>();
2242 }
2243 };
2244
2245 struct AndIfHasLegacySupportState
2246 : public CallOrderStateMachineHelper<TestType, AndIfHasLegacySupportState> {
2247 [[nodiscard]] auto andIfLegacySupportFor(ui::Dataspace dataspace, bool legacySupport) {
2248 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasLegacyHdrSupport(dataspace))
2249 .WillOnce(Return(legacySupport));
2250 return nextState<ThenExpectBestColorModeCallUsesState>();
2251 }
2252 };
2253
2254 struct ThenExpectBestColorModeCallUsesState
2255 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2256 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::Dataspace dataspace) {
2257 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2258 getBestColorMode(dataspace, _, _, _, _));
2259 return nextState<ExecuteState>();
2260 }
2261 };
2262
2263 // Call this member function to start using the mini-DSL defined above.
2264 [[nodiscard]] auto verify() { return IfTopLayerDataspaceState::make(this); }
2265};
2266
2267TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_Uses_PQ) {
2268 // If all layers use BT2020_PQ, and there are no other special conditions,
2269 // BT2020_PQ is used.
2270 verify().ifTopLayerIs(BT2020_PQ)
2271 .andTopLayerIsREComposed(false)
2272 .andIfBottomLayerIs(BT2020_PQ)
2273 .andBottomLayerIsREComposed(false)
2274 .andIfLegacySupportFor(BT2020_PQ, false)
2275 .thenExpectBestColorModeCallUses(BT2020_PQ)
2276 .execute();
2277}
2278
2279TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2280 // BT2020_PQ is not used if there is only legacy support for it.
2281 verify().ifTopLayerIs(BT2020_PQ)
2282 .andTopLayerIsREComposed(false)
2283 .andIfBottomLayerIs(BT2020_PQ)
2284 .andBottomLayerIsREComposed(false)
2285 .andIfLegacySupportFor(BT2020_PQ, true)
2286 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2287 .execute();
2288}
2289
2290TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_PQ_RE_Uses_PQ) {
2291 // BT2020_PQ is still used if the bottom layer is RenderEngine composed.
2292 verify().ifTopLayerIs(BT2020_PQ)
2293 .andTopLayerIsREComposed(false)
2294 .andIfBottomLayerIs(BT2020_PQ)
2295 .andBottomLayerIsREComposed(true)
2296 .andIfLegacySupportFor(BT2020_PQ, false)
2297 .thenExpectBestColorModeCallUses(BT2020_PQ)
2298 .execute();
2299}
2300
2301TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_PQ_HW_Uses_DisplayP3) {
2302 // BT2020_PQ is not used if the top layer is RenderEngine composed.
2303 verify().ifTopLayerIs(BT2020_PQ)
2304 .andTopLayerIsREComposed(true)
2305 .andIfBottomLayerIs(BT2020_PQ)
2306 .andBottomLayerIsREComposed(false)
2307 .andIfLegacySupportFor(BT2020_PQ, false)
2308 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2309 .execute();
2310}
2311
2312TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_Uses_PQ) {
2313 // If there is mixed HLG/PQ use, and the topmost layer is PQ, then PQ is used if there
2314 // are no other special conditions.
2315 verify().ifTopLayerIs(BT2020_PQ)
2316 .andTopLayerIsREComposed(false)
2317 .andIfBottomLayerIs(BT2020_HLG)
2318 .andBottomLayerIsREComposed(false)
2319 .andIfLegacySupportFor(BT2020_PQ, false)
2320 .thenExpectBestColorModeCallUses(BT2020_PQ)
2321 .execute();
2322}
2323
2324TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2325 // BT2020_PQ is not used if there is only legacy support for it.
2326 verify().ifTopLayerIs(BT2020_PQ)
2327 .andTopLayerIsREComposed(false)
2328 .andIfBottomLayerIs(BT2020_HLG)
2329 .andBottomLayerIsREComposed(false)
2330 .andIfLegacySupportFor(BT2020_PQ, true)
2331 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2332 .execute();
2333}
2334
2335TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_HLG_RE_Uses_PQ) {
2336 // BT2020_PQ is used if the bottom HLG layer is RenderEngine composed.
2337 verify().ifTopLayerIs(BT2020_PQ)
2338 .andTopLayerIsREComposed(false)
2339 .andIfBottomLayerIs(BT2020_HLG)
2340 .andBottomLayerIsREComposed(true)
2341 .andIfLegacySupportFor(BT2020_PQ, false)
2342 .thenExpectBestColorModeCallUses(BT2020_PQ)
2343 .execute();
2344}
2345
2346TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_RE_On_HLG_HW_Uses_DisplayP3) {
2347 // BT2020_PQ is not used if the top PQ layer is RenderEngine composed.
2348 verify().ifTopLayerIs(BT2020_PQ)
2349 .andTopLayerIsREComposed(true)
2350 .andIfBottomLayerIs(BT2020_HLG)
2351 .andBottomLayerIsREComposed(false)
2352 .andIfLegacySupportFor(BT2020_PQ, false)
2353 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2354 .execute();
2355}
2356
2357TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_Uses_PQ) {
2358 // If there is mixed HLG/PQ use, and the topmost layer is HLG, then PQ is
2359 // used if there are no other special conditions.
2360 verify().ifTopLayerIs(BT2020_HLG)
2361 .andTopLayerIsREComposed(false)
2362 .andIfBottomLayerIs(BT2020_PQ)
2363 .andBottomLayerIsREComposed(false)
2364 .andIfLegacySupportFor(BT2020_PQ, false)
2365 .thenExpectBestColorModeCallUses(BT2020_PQ)
2366 .execute();
2367}
2368
2369TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2370 // BT2020_PQ is not used if there is only legacy support for it.
2371 verify().ifTopLayerIs(BT2020_HLG)
2372 .andTopLayerIsREComposed(false)
2373 .andIfBottomLayerIs(BT2020_PQ)
2374 .andBottomLayerIsREComposed(false)
2375 .andIfLegacySupportFor(BT2020_PQ, true)
2376 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2377 .execute();
2378}
2379
2380TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_PQ_RE_Uses_DisplayP3) {
2381 // BT2020_PQ is not used if the bottom PQ layer is RenderEngine composed.
2382 verify().ifTopLayerIs(BT2020_HLG)
2383 .andTopLayerIsREComposed(false)
2384 .andIfBottomLayerIs(BT2020_PQ)
2385 .andBottomLayerIsREComposed(true)
2386 .andIfLegacySupportFor(BT2020_PQ, false)
2387 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2388 .execute();
2389}
2390
2391TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_PQ_HW_Uses_PQ) {
2392 // BT2020_PQ is still used if the top HLG layer is RenderEngine composed.
2393 verify().ifTopLayerIs(BT2020_HLG)
2394 .andTopLayerIsREComposed(true)
2395 .andIfBottomLayerIs(BT2020_PQ)
2396 .andBottomLayerIsREComposed(false)
2397 .andIfLegacySupportFor(BT2020_PQ, false)
2398 .thenExpectBestColorModeCallUses(BT2020_PQ)
2399 .execute();
2400}
2401
2402TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_Uses_HLG) {
2403 // If all layers use HLG then HLG is used if there are no other special
2404 // conditions.
2405 verify().ifTopLayerIs(BT2020_HLG)
2406 .andTopLayerIsREComposed(false)
2407 .andIfBottomLayerIs(BT2020_HLG)
2408 .andBottomLayerIsREComposed(false)
2409 .andIfLegacySupportFor(BT2020_HLG, false)
2410 .thenExpectBestColorModeCallUses(BT2020_HLG)
2411 .execute();
2412}
2413
2414TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_HW_IfPQHasLegacySupport_Uses_DisplayP3) {
2415 // BT2020_HLG is not used if there is legacy support for it.
2416 verify().ifTopLayerIs(BT2020_HLG)
2417 .andTopLayerIsREComposed(false)
2418 .andIfBottomLayerIs(BT2020_HLG)
2419 .andBottomLayerIsREComposed(false)
2420 .andIfLegacySupportFor(BT2020_HLG, true)
2421 .thenExpectBestColorModeCallUses(DISPLAY_P3)
2422 .execute();
2423}
2424
2425TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_HLG_RE_Uses_HLG) {
2426 // BT2020_HLG is used even if the bottom layer is client composed.
2427 verify().ifTopLayerIs(BT2020_HLG)
2428 .andTopLayerIsREComposed(false)
2429 .andIfBottomLayerIs(BT2020_HLG)
2430 .andBottomLayerIsREComposed(true)
2431 .andIfLegacySupportFor(BT2020_HLG, false)
2432 .thenExpectBestColorModeCallUses(BT2020_HLG)
2433 .execute();
2434}
2435
2436TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_RE_On_HLG_HW_Uses_HLG) {
2437 // BT2020_HLG is used even if the top layer is client composed.
2438 verify().ifTopLayerIs(BT2020_HLG)
2439 .andTopLayerIsREComposed(true)
2440 .andIfBottomLayerIs(BT2020_HLG)
2441 .andBottomLayerIsREComposed(false)
2442 .andIfLegacySupportFor(BT2020_HLG, false)
2443 .thenExpectBestColorModeCallUses(BT2020_HLG)
2444 .execute();
2445}
2446
2447TEST_F(OutputUpdateColorProfileTest_Hdr, PQ_HW_On_NonHdr_HW_Uses_PQ) {
2448 // Even if there are non-HDR layers present, BT2020_PQ can still be used.
2449 verify().ifTopLayerIs(BT2020_PQ)
2450 .andTopLayerIsREComposed(false)
2451 .andIfBottomLayerIsNotHdr()
2452 .andBottomLayerIsREComposed(false)
2453 .andIfLegacySupportFor(BT2020_PQ, false)
2454 .thenExpectBestColorModeCallUses(BT2020_PQ)
2455 .execute();
2456}
2457
2458TEST_F(OutputUpdateColorProfileTest_Hdr, HLG_HW_On_NonHdr_RE_Uses_HLG) {
2459 // If all layers use HLG then HLG is used if there are no other special
2460 // conditions.
2461 verify().ifTopLayerIs(BT2020_HLG)
2462 .andTopLayerIsREComposed(false)
2463 .andIfBottomLayerIsNotHdr()
2464 .andBottomLayerIsREComposed(true)
2465 .andIfLegacySupportFor(BT2020_HLG, false)
2466 .thenExpectBestColorModeCallUses(BT2020_HLG)
2467 .execute();
2468}
2469
2470struct OutputUpdateColorProfile_AffectsChosenRenderIntentTest
2471 : public OutputUpdateColorProfileTest {
2472 // The various values for CompositionRefreshArgs::outputColorSetting affect
2473 // the chosen renderIntent, along with whether the preferred dataspace is an
2474 // HDR dataspace or not.
2475
2476 OutputUpdateColorProfile_AffectsChosenRenderIntentTest() {
2477 mRefreshArgs.outputColorSetting = OutputColorSetting::kEnhanced;
2478 mRefreshArgs.colorSpaceAgnosticDataspace = ui::Dataspace::UNKNOWN;
2479 mLayer1.mLayerFEState.dataspace = ui::Dataspace::BT2020_PQ;
Lloyd Pique0a456232020-01-16 17:51:13 -08002480 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
Lloyd Pique17ca7422019-11-14 14:24:10 -08002481 EXPECT_CALL(mOutput, setColorProfile(_)).WillRepeatedly(Return());
2482 EXPECT_CALL(*mDisplayColorProfile, hasLegacyHdrSupport(ui::Dataspace::BT2020_PQ))
2483 .WillRepeatedly(Return(false));
2484 }
2485
2486 // The tests here involve enough state and GMock setup that using a mini-DSL
2487 // makes the tests much more readable, and allows the test to focus more on
2488 // the intent than on some of the details.
2489
2490 static constexpr ui::Dataspace kNonHdrDataspace = ui::Dataspace::DISPLAY_P3;
2491 static constexpr ui::Dataspace kHdrDataspace = ui::Dataspace::BT2020_PQ;
2492
2493 struct IfDataspaceChosenState
2494 : public CallOrderStateMachineHelper<TestType, IfDataspaceChosenState> {
2495 [[nodiscard]] auto ifDataspaceChosenIs(ui::Dataspace dataspace) {
2496 getInstance()->mLayer1.mLayerFEState.dataspace = dataspace;
2497 return nextState<AndOutputColorSettingState>();
2498 }
2499 [[nodiscard]] auto ifDataspaceChosenIsNonHdr() {
2500 return ifDataspaceChosenIs(kNonHdrDataspace);
2501 }
2502 [[nodiscard]] auto ifDataspaceChosenIsHdr() { return ifDataspaceChosenIs(kHdrDataspace); }
2503 };
2504
2505 struct AndOutputColorSettingState
2506 : public CallOrderStateMachineHelper<TestType, AndOutputColorSettingState> {
2507 [[nodiscard]] auto andOutputColorSettingIs(OutputColorSetting setting) {
2508 getInstance()->mRefreshArgs.outputColorSetting = setting;
2509 return nextState<ThenExpectBestColorModeCallUsesState>();
2510 }
2511 };
2512
2513 struct ThenExpectBestColorModeCallUsesState
2514 : public CallOrderStateMachineHelper<TestType, ThenExpectBestColorModeCallUsesState> {
2515 [[nodiscard]] auto thenExpectBestColorModeCallUses(ui::RenderIntent intent) {
2516 EXPECT_CALL(*getInstance()->mDisplayColorProfile,
2517 getBestColorMode(getInstance()->mLayer1.mLayerFEState.dataspace, intent, _,
2518 _, _));
2519 return nextState<ExecuteState>();
2520 }
2521 };
2522
2523 // Tests call one of these two helper member functions to start using the
2524 // mini-DSL defined above.
2525 [[nodiscard]] auto verify() { return IfDataspaceChosenState::make(this); }
2526};
2527
2528TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2529 Managed_NonHdr_Prefers_Colorimetric) {
2530 verify().ifDataspaceChosenIsNonHdr()
2531 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2532 .thenExpectBestColorModeCallUses(ui::RenderIntent::COLORIMETRIC)
2533 .execute();
2534}
2535
2536TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2537 Managed_Hdr_Prefers_ToneMapColorimetric) {
2538 verify().ifDataspaceChosenIsHdr()
2539 .andOutputColorSettingIs(OutputColorSetting::kManaged)
2540 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_COLORIMETRIC)
2541 .execute();
2542}
2543
2544TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Enhanced_NonHdr_Prefers_Enhance) {
2545 verify().ifDataspaceChosenIsNonHdr()
2546 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2547 .thenExpectBestColorModeCallUses(ui::RenderIntent::ENHANCE)
2548 .execute();
2549}
2550
2551TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest,
2552 Enhanced_Hdr_Prefers_ToneMapEnhance) {
2553 verify().ifDataspaceChosenIsHdr()
2554 .andOutputColorSettingIs(OutputColorSetting::kEnhanced)
2555 .thenExpectBestColorModeCallUses(ui::RenderIntent::TONE_MAP_ENHANCE)
2556 .execute();
2557}
2558
2559TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_NonHdr_Prefers_Vendor) {
2560 verify().ifDataspaceChosenIsNonHdr()
2561 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2562 .thenExpectBestColorModeCallUses(
2563 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2564 .execute();
2565}
2566
2567TEST_F(OutputUpdateColorProfile_AffectsChosenRenderIntentTest, Vendor_Hdr_Prefers_Vendor) {
2568 verify().ifDataspaceChosenIsHdr()
2569 .andOutputColorSettingIs(kVendorSpecifiedOutputColorSetting)
2570 .thenExpectBestColorModeCallUses(
2571 static_cast<ui::RenderIntent>(kVendorSpecifiedOutputColorSetting))
2572 .execute();
2573}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002574
2575/*
2576 * Output::beginFrame()
2577 */
2578
Lloyd Piquee5965952019-11-18 16:16:32 -08002579struct OutputBeginFrameTest : public ::testing::Test {
2580 using TestType = OutputBeginFrameTest;
2581
2582 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002583 // Sets up the helper functions called by the function under test to use
2584 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002585 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Lloyd Piquee5965952019-11-18 16:16:32 -08002586 };
2587
2588 OutputBeginFrameTest() {
2589 mOutput.setDisplayColorProfileForTest(
2590 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2591 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2592 }
2593
2594 struct IfGetDirtyRegionExpectationState
2595 : public CallOrderStateMachineHelper<TestType, IfGetDirtyRegionExpectationState> {
2596 [[nodiscard]] auto ifGetDirtyRegionReturns(Region dirtyRegion) {
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002597 EXPECT_CALL(getInstance()->mOutput, getDirtyRegion()).WillOnce(Return(dirtyRegion));
Lloyd Piquee5965952019-11-18 16:16:32 -08002598 return nextState<AndIfGetOutputLayerCountExpectationState>();
2599 }
2600 };
2601
2602 struct AndIfGetOutputLayerCountExpectationState
2603 : public CallOrderStateMachineHelper<TestType, AndIfGetOutputLayerCountExpectationState> {
2604 [[nodiscard]] auto andIfGetOutputLayerCountReturns(size_t layerCount) {
2605 EXPECT_CALL(getInstance()->mOutput, getOutputLayerCount()).WillOnce(Return(layerCount));
2606 return nextState<AndIfLastCompositionHadVisibleLayersState>();
2607 }
2608 };
2609
2610 struct AndIfLastCompositionHadVisibleLayersState
2611 : public CallOrderStateMachineHelper<TestType,
2612 AndIfLastCompositionHadVisibleLayersState> {
2613 [[nodiscard]] auto andIfLastCompositionHadVisibleLayersIs(bool hadOutputLayers) {
2614 getInstance()->mOutput.mState.lastCompositionHadVisibleLayers = hadOutputLayers;
2615 return nextState<ThenExpectRenderSurfaceBeginFrameCallState>();
2616 }
2617 };
2618
2619 struct ThenExpectRenderSurfaceBeginFrameCallState
2620 : public CallOrderStateMachineHelper<TestType,
2621 ThenExpectRenderSurfaceBeginFrameCallState> {
2622 [[nodiscard]] auto thenExpectRenderSurfaceBeginFrameCall(bool mustRecompose) {
2623 EXPECT_CALL(*getInstance()->mRenderSurface, beginFrame(mustRecompose));
2624 return nextState<ExecuteState>();
2625 }
2626 };
2627
2628 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
2629 [[nodiscard]] auto execute() {
2630 getInstance()->mOutput.beginFrame();
2631 return nextState<CheckPostconditionHadVisibleLayersState>();
2632 }
2633 };
2634
2635 struct CheckPostconditionHadVisibleLayersState
2636 : public CallOrderStateMachineHelper<TestType, CheckPostconditionHadVisibleLayersState> {
2637 void checkPostconditionHadVisibleLayers(bool expected) {
2638 EXPECT_EQ(expected, getInstance()->mOutput.mState.lastCompositionHadVisibleLayers);
2639 }
2640 };
2641
2642 // Tests call one of these two helper member functions to start using the
2643 // mini-DSL defined above.
2644 [[nodiscard]] auto verify() { return IfGetDirtyRegionExpectationState::make(this); }
2645
2646 static const Region kEmptyRegion;
2647 static const Region kNotEmptyRegion;
2648
2649 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2650 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2651 StrictMock<OutputPartialMock> mOutput;
2652};
2653
2654const Region OutputBeginFrameTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2655const Region OutputBeginFrameTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2656
2657TEST_F(OutputBeginFrameTest, hasDirtyHasLayersHadLayersLastFrame) {
2658 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2659 .andIfGetOutputLayerCountReturns(1u)
2660 .andIfLastCompositionHadVisibleLayersIs(true)
2661 .thenExpectRenderSurfaceBeginFrameCall(true)
2662 .execute()
2663 .checkPostconditionHadVisibleLayers(true);
2664}
2665
2666TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersHadLayersLastFrame) {
2667 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2668 .andIfGetOutputLayerCountReturns(0u)
2669 .andIfLastCompositionHadVisibleLayersIs(true)
2670 .thenExpectRenderSurfaceBeginFrameCall(true)
2671 .execute()
2672 .checkPostconditionHadVisibleLayers(false);
2673}
2674
2675TEST_F(OutputBeginFrameTest, hasDirtyHasLayersNotHadLayersLastFrame) {
2676 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2677 .andIfGetOutputLayerCountReturns(1u)
2678 .andIfLastCompositionHadVisibleLayersIs(false)
2679 .thenExpectRenderSurfaceBeginFrameCall(true)
2680 .execute()
2681 .checkPostconditionHadVisibleLayers(true);
2682}
2683
2684TEST_F(OutputBeginFrameTest, hasDirtyNotHasLayersNotHadLayersLastFrame) {
2685 verify().ifGetDirtyRegionReturns(kNotEmptyRegion)
2686 .andIfGetOutputLayerCountReturns(0u)
2687 .andIfLastCompositionHadVisibleLayersIs(false)
2688 .thenExpectRenderSurfaceBeginFrameCall(false)
2689 .execute()
2690 .checkPostconditionHadVisibleLayers(false);
2691}
2692
2693TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersHadLayersLastFrame) {
2694 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2695 .andIfGetOutputLayerCountReturns(1u)
2696 .andIfLastCompositionHadVisibleLayersIs(true)
2697 .thenExpectRenderSurfaceBeginFrameCall(false)
2698 .execute()
2699 .checkPostconditionHadVisibleLayers(true);
2700}
2701
2702TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersHadLayersLastFrame) {
2703 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2704 .andIfGetOutputLayerCountReturns(0u)
2705 .andIfLastCompositionHadVisibleLayersIs(true)
2706 .thenExpectRenderSurfaceBeginFrameCall(false)
2707 .execute()
2708 .checkPostconditionHadVisibleLayers(true);
2709}
2710
2711TEST_F(OutputBeginFrameTest, notHasDirtyHasLayersNotHadLayersLastFrame) {
2712 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2713 .andIfGetOutputLayerCountReturns(1u)
2714 .andIfLastCompositionHadVisibleLayersIs(false)
2715 .thenExpectRenderSurfaceBeginFrameCall(false)
2716 .execute()
2717 .checkPostconditionHadVisibleLayers(false);
2718}
2719
2720TEST_F(OutputBeginFrameTest, notHasDirtyNotHasLayersNotHadLayersLastFrame) {
2721 verify().ifGetDirtyRegionReturns(kEmptyRegion)
2722 .andIfGetOutputLayerCountReturns(0u)
2723 .andIfLastCompositionHadVisibleLayersIs(false)
2724 .thenExpectRenderSurfaceBeginFrameCall(false)
2725 .execute()
2726 .checkPostconditionHadVisibleLayers(false);
2727}
2728
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002729/*
2730 * Output::devOptRepaintFlash()
2731 */
2732
Lloyd Piquedb462d82019-11-19 17:58:46 -08002733struct OutputDevOptRepaintFlashTest : public testing::Test {
2734 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002735 // Sets up the helper functions called by the function under test to use
2736 // mock implementations.
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002737 MOCK_METHOD(Region, getDirtyRegion, (), (const));
Robert Carr6fe2bef2022-03-09 13:49:41 -08002738 MOCK_METHOD2(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002739 std::optional<base::unique_fd>(
Robert Carr6fe2bef2022-03-09 13:49:41 -08002740 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002741 MOCK_METHOD0(postFramebuffer, void());
2742 MOCK_METHOD0(prepareFrame, void());
2743 };
2744
2745 OutputDevOptRepaintFlashTest() {
2746 mOutput.setDisplayColorProfileForTest(
2747 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2748 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2749 }
2750
2751 static const Region kEmptyRegion;
2752 static const Region kNotEmptyRegion;
2753
2754 StrictMock<OutputPartialMock> mOutput;
2755 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2756 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2757 CompositionRefreshArgs mRefreshArgs;
2758};
2759
2760const Region OutputDevOptRepaintFlashTest::kEmptyRegion{Rect{0, 0, 0, 0}};
2761const Region OutputDevOptRepaintFlashTest::kNotEmptyRegion{Rect{0, 0, 1, 1}};
2762
2763TEST_F(OutputDevOptRepaintFlashTest, doesNothingIfFlashDelayNotSet) {
2764 mRefreshArgs.devOptFlashDirtyRegionsDelay = {};
Lloyd Piquedb462d82019-11-19 17:58:46 -08002765 mOutput.mState.isEnabled = true;
2766
2767 mOutput.devOptRepaintFlash(mRefreshArgs);
2768}
2769
2770TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfNotEnabled) {
2771 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002772 mOutput.mState.isEnabled = false;
2773
2774 InSequence seq;
2775 EXPECT_CALL(mOutput, postFramebuffer());
2776 EXPECT_CALL(mOutput, prepareFrame());
2777
2778 mOutput.devOptRepaintFlash(mRefreshArgs);
2779}
2780
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002781TEST_F(OutputDevOptRepaintFlashTest, postsAndPreparesANewFrameIfEnabled) {
Lloyd Piquedb462d82019-11-19 17:58:46 -08002782 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002783 mOutput.mState.isEnabled = true;
2784
2785 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002786 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kEmptyRegion));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002787 EXPECT_CALL(mOutput, postFramebuffer());
2788 EXPECT_CALL(mOutput, prepareFrame());
2789
2790 mOutput.devOptRepaintFlash(mRefreshArgs);
2791}
2792
2793TEST_F(OutputDevOptRepaintFlashTest, alsoComposesSurfacesAndQueuesABufferIfDirty) {
2794 mRefreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::microseconds(1);
Lloyd Piquedb462d82019-11-19 17:58:46 -08002795 mOutput.mState.isEnabled = true;
2796
2797 InSequence seq;
Dominik Laskowski8da6b0e2021-05-12 15:34:13 -07002798 EXPECT_CALL(mOutput, getDirtyRegion()).WillOnce(Return(kNotEmptyRegion));
Robert Carr6fe2bef2022-03-09 13:49:41 -08002799 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(kNotEmptyRegion), Ref(mRefreshArgs)));
Lloyd Piquedb462d82019-11-19 17:58:46 -08002800 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2801 EXPECT_CALL(mOutput, postFramebuffer());
2802 EXPECT_CALL(mOutput, prepareFrame());
2803
2804 mOutput.devOptRepaintFlash(mRefreshArgs);
2805}
2806
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002807/*
2808 * Output::finishFrame()
2809 */
2810
Lloyd Pique03561a62019-11-19 18:34:52 -08002811struct OutputFinishFrameTest : public testing::Test {
2812 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002813 // Sets up the helper functions called by the function under test to use
2814 // mock implementations.
Robert Carr6fe2bef2022-03-09 13:49:41 -08002815 MOCK_METHOD2(composeSurfaces,
Lucas Dupin2dd6f392020-02-18 17:43:36 -08002816 std::optional<base::unique_fd>(
Robert Carr6fe2bef2022-03-09 13:49:41 -08002817 const Region&, const compositionengine::CompositionRefreshArgs&));
Lloyd Pique03561a62019-11-19 18:34:52 -08002818 MOCK_METHOD0(postFramebuffer, void());
2819 };
2820
2821 OutputFinishFrameTest() {
2822 mOutput.setDisplayColorProfileForTest(
2823 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2824 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2825 }
2826
2827 StrictMock<OutputPartialMock> mOutput;
2828 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2829 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2830 CompositionRefreshArgs mRefreshArgs;
2831};
2832
2833TEST_F(OutputFinishFrameTest, ifNotEnabledDoesNothing) {
2834 mOutput.mState.isEnabled = false;
2835
Robert Carr6fe2bef2022-03-09 13:49:41 -08002836 mOutput.finishFrame(mRefreshArgs);
Lloyd Pique03561a62019-11-19 18:34:52 -08002837}
2838
2839TEST_F(OutputFinishFrameTest, takesEarlyOutifComposeSurfacesReturnsNoFence) {
2840 mOutput.mState.isEnabled = true;
2841
Robert Carr6fe2bef2022-03-09 13:49:41 -08002842 InSequence seq;
2843 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _));
2844
2845 mOutput.finishFrame(mRefreshArgs);
Lloyd Pique03561a62019-11-19 18:34:52 -08002846}
2847
2848TEST_F(OutputFinishFrameTest, queuesBufferIfComposeSurfacesReturnsAFence) {
2849 mOutput.mState.isEnabled = true;
2850
2851 InSequence seq;
Robert Carr6fe2bef2022-03-09 13:49:41 -08002852 EXPECT_CALL(mOutput, composeSurfaces(RegionEq(Region::INVALID_REGION), _))
Lloyd Pique03561a62019-11-19 18:34:52 -08002853 .WillOnce(Return(ByMove(base::unique_fd())));
2854 EXPECT_CALL(*mRenderSurface, queueBuffer(_));
2855
Robert Carr6fe2bef2022-03-09 13:49:41 -08002856 mOutput.finishFrame(mRefreshArgs);
Lloyd Pique03561a62019-11-19 18:34:52 -08002857}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08002858
2859/*
2860 * Output::postFramebuffer()
2861 */
2862
Lloyd Pique07178e32019-11-19 19:15:26 -08002863struct OutputPostFramebufferTest : public testing::Test {
2864 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08002865 // Sets up the helper functions called by the function under test to use
2866 // mock implementations.
Lloyd Pique07178e32019-11-19 19:15:26 -08002867 MOCK_METHOD0(presentAndGetFrameFences, compositionengine::Output::FrameFences());
2868 };
2869
2870 struct Layer {
2871 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08002872 EXPECT_CALL(outputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*layerFE));
Lloyd Pique07178e32019-11-19 19:15:26 -08002873 EXPECT_CALL(outputLayer, getHwcLayer()).WillRepeatedly(Return(&hwc2Layer));
2874 }
2875
2876 StrictMock<mock::OutputLayer> outputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08002877 sp<StrictMock<mock::LayerFE>> layerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08002878 StrictMock<HWC2::mock::Layer> hwc2Layer;
2879 };
2880
2881 OutputPostFramebufferTest() {
2882 mOutput.setDisplayColorProfileForTest(
2883 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
2884 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
2885
2886 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(3u));
2887 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
2888 .WillRepeatedly(Return(&mLayer1.outputLayer));
2889 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
2890 .WillRepeatedly(Return(&mLayer2.outputLayer));
2891 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(2u))
2892 .WillRepeatedly(Return(&mLayer3.outputLayer));
2893 }
2894
2895 StrictMock<OutputPartialMock> mOutput;
2896 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
2897 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
2898
2899 Layer mLayer1;
2900 Layer mLayer2;
2901 Layer mLayer3;
2902};
2903
2904TEST_F(OutputPostFramebufferTest, ifNotEnabledDoesNothing) {
2905 mOutput.mState.isEnabled = false;
2906
2907 mOutput.postFramebuffer();
2908}
2909
2910TEST_F(OutputPostFramebufferTest, ifEnabledMustFlipThenPresentThenSendPresentCompleted) {
2911 mOutput.mState.isEnabled = true;
2912
2913 compositionengine::Output::FrameFences frameFences;
2914
2915 // This should happen even if there are no output layers.
2916 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
2917
2918 // For this test in particular we want to make sure the call expectations
2919 // setup below are satisfied in the specific order.
2920 InSequence seq;
2921
2922 EXPECT_CALL(*mRenderSurface, flip());
2923 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2924 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2925
2926 mOutput.postFramebuffer();
2927}
2928
2929TEST_F(OutputPostFramebufferTest, releaseFencesAreSentToLayerFE) {
2930 // Simulate getting release fences from each layer, and ensure they are passed to the
2931 // front-end layer interface for each layer correctly.
2932
2933 mOutput.mState.isEnabled = true;
2934
2935 // Create three unique fence instances
2936 sp<Fence> layer1Fence = new Fence();
2937 sp<Fence> layer2Fence = new Fence();
2938 sp<Fence> layer3Fence = new Fence();
2939
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002940 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002941 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2942 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2943 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2944
2945 EXPECT_CALL(*mRenderSurface, flip());
2946 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2947 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2948
2949 // Compare the pointers values of each fence to make sure the correct ones
2950 // are passed. This happens to work with the current implementation, but
2951 // would not survive certain calls like Fence::merge() which would return a
2952 // new instance.
Sally Qi59a9f502021-10-12 18:53:23 +00002953 base::unique_fd layer1FD(layer1Fence->dup());
2954 base::unique_fd layer2FD(layer2Fence->dup());
2955 base::unique_fd layer3FD(layer3Fence->dup());
2956 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed(_))
2957 .WillOnce([&layer1FD](std::shared_future<renderengine::RenderEngineResult>
2958 futureRenderEngineResult) {
2959 EXPECT_EQ(layer1FD, futureRenderEngineResult.get().drawFence);
2960 });
2961 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed(_))
2962 .WillOnce([&layer2FD](std::shared_future<renderengine::RenderEngineResult>
2963 futureRenderEngineResult) {
2964 EXPECT_EQ(layer2FD, futureRenderEngineResult.get().drawFence);
2965 });
2966 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed(_))
2967 .WillOnce([&layer3FD](std::shared_future<renderengine::RenderEngineResult>
2968 futureRenderEngineResult) {
2969 EXPECT_EQ(layer3FD, futureRenderEngineResult.get().drawFence);
2970 });
Lloyd Pique07178e32019-11-19 19:15:26 -08002971
2972 mOutput.postFramebuffer();
2973}
2974
2975TEST_F(OutputPostFramebufferTest, releaseFencesIncludeClientTargetAcquireFence) {
2976 mOutput.mState.isEnabled = true;
2977 mOutput.mState.usesClientComposition = true;
2978
2979 sp<Fence> clientTargetAcquireFence = new Fence();
2980 sp<Fence> layer1Fence = new Fence();
2981 sp<Fence> layer2Fence = new Fence();
2982 sp<Fence> layer3Fence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08002983 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08002984 frameFences.clientTargetAcquireFence = clientTargetAcquireFence;
2985 frameFences.layerFences.emplace(&mLayer1.hwc2Layer, layer1Fence);
2986 frameFences.layerFences.emplace(&mLayer2.hwc2Layer, layer2Fence);
2987 frameFences.layerFences.emplace(&mLayer3.hwc2Layer, layer3Fence);
2988
2989 EXPECT_CALL(*mRenderSurface, flip());
2990 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
2991 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
2992
2993 // Fence::merge is called, and since none of the fences are actually valid,
2994 // Fence::NO_FENCE is returned and passed to each onLayerDisplayed() call.
2995 // This is the best we can do without creating a real kernel fence object.
Sally Qi59a9f502021-10-12 18:53:23 +00002996 EXPECT_CALL(*mLayer1.layerFE, onLayerDisplayed).WillOnce(Return());
2997 EXPECT_CALL(*mLayer2.layerFE, onLayerDisplayed).WillOnce(Return());
2998 EXPECT_CALL(*mLayer3.layerFE, onLayerDisplayed).WillOnce(Return());
Lloyd Pique07178e32019-11-19 19:15:26 -08002999
3000 mOutput.postFramebuffer();
3001}
3002
3003TEST_F(OutputPostFramebufferTest, releasedLayersSentPresentFence) {
3004 mOutput.mState.isEnabled = true;
3005 mOutput.mState.usesClientComposition = true;
3006
3007 // This should happen even if there are no (current) output layers.
3008 EXPECT_CALL(mOutput, getOutputLayerCount()).WillOnce(Return(0u));
3009
3010 // Load up the released layers with some mock instances
Ady Abrahame0eafa82022-02-02 19:30:47 -08003011 sp<StrictMock<mock::LayerFE>> releasedLayer1 = sp<StrictMock<mock::LayerFE>>::make();
3012 sp<StrictMock<mock::LayerFE>> releasedLayer2 = sp<StrictMock<mock::LayerFE>>::make();
3013 sp<StrictMock<mock::LayerFE>> releasedLayer3 = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique07178e32019-11-19 19:15:26 -08003014 Output::ReleasedLayers layers;
3015 layers.push_back(releasedLayer1);
3016 layers.push_back(releasedLayer2);
3017 layers.push_back(releasedLayer3);
3018 mOutput.setReleasedLayers(std::move(layers));
3019
3020 // Set up a fake present fence
3021 sp<Fence> presentFence = new Fence();
Lloyd Piquefe0ee9e2019-11-22 16:30:30 -08003022 Output::FrameFences frameFences;
Lloyd Pique07178e32019-11-19 19:15:26 -08003023 frameFences.presentFence = presentFence;
3024
3025 EXPECT_CALL(*mRenderSurface, flip());
3026 EXPECT_CALL(mOutput, presentAndGetFrameFences()).WillOnce(Return(frameFences));
3027 EXPECT_CALL(*mRenderSurface, onPresentDisplayCompleted());
3028
3029 // Each released layer should be given the presentFence.
Sally Qi59a9f502021-10-12 18:53:23 +00003030 base::unique_fd layerFD(presentFence.get()->dup());
3031 EXPECT_CALL(*releasedLayer1, onLayerDisplayed(_))
3032 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3033 futureRenderEngineResult) {
3034 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3035 });
3036 EXPECT_CALL(*releasedLayer2, onLayerDisplayed(_))
3037 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3038 futureRenderEngineResult) {
3039 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3040 });
3041 EXPECT_CALL(*releasedLayer3, onLayerDisplayed(_))
3042 .WillOnce([&layerFD](std::shared_future<renderengine::RenderEngineResult>
3043 futureRenderEngineResult) {
3044 EXPECT_EQ(layerFD, futureRenderEngineResult.get().drawFence);
3045 });
Lloyd Pique07178e32019-11-19 19:15:26 -08003046
3047 mOutput.postFramebuffer();
3048
3049 // After the call the list of released layers should have been cleared.
3050 EXPECT_TRUE(mOutput.getReleasedLayersForTest().empty());
3051}
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003052
3053/*
Lloyd Pique56eba802019-08-28 15:45:25 -07003054 * Output::composeSurfaces()
3055 */
3056
3057struct OutputComposeSurfacesTest : public testing::Test {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003058 using TestType = OutputComposeSurfacesTest;
Lloyd Pique56eba802019-08-28 15:45:25 -07003059
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003060 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Pique739afaf2019-11-21 16:40:05 -08003061 // Sets up the helper functions called by the function under test to use
3062 // mock implementations.
Lloyd Pique56eba802019-08-28 15:45:25 -07003063 MOCK_CONST_METHOD0(getSkipColorTransform, bool());
Robert Carrccab4242021-09-28 16:53:03 -07003064 MOCK_METHOD3(generateClientCompositionRequests,
3065 std::vector<LayerFE::LayerSettings>(bool, ui::Dataspace, std::vector<LayerFE*>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003066 MOCK_METHOD2(appendRegionFlashRequests,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003067 void(const Region&, std::vector<LayerFE::LayerSettings>&));
Lloyd Pique56eba802019-08-28 15:45:25 -07003068 MOCK_METHOD1(setExpensiveRenderingExpected, void(bool));
3069 };
3070
3071 OutputComposeSurfacesTest() {
3072 mOutput.setDisplayColorProfileForTest(
3073 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3074 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003075 mOutput.cacheClientCompositionRequests(MAX_CLIENT_COMPOSITION_CACHE_SIZE);
Lloyd Pique56eba802019-08-28 15:45:25 -07003076
Angel Aguayob084e0c2021-08-04 23:27:28 +00003077 mOutput.mState.orientedDisplaySpace.setContent(kDefaultOutputFrame);
3078 mOutput.mState.layerStackSpace.setContent(kDefaultOutputViewport);
3079 mOutput.mState.framebufferSpace.setContent(kDefaultOutputDestinationClip);
3080 mOutput.mState.displaySpace.setContent(kDefaultOutputDestinationClip);
3081 mOutput.mState.displaySpace.setOrientation(kDefaultOutputOrientation);
Marin Shalamanovb15d2272020-09-17 21:41:52 +02003082 mOutput.mState.transform = ui::Transform{kDefaultOutputOrientationFlags};
Lloyd Pique6818fa52019-12-03 12:32:13 -08003083 mOutput.mState.dataspace = kDefaultOutputDataspace;
3084 mOutput.mState.colorTransformMatrix = kDefaultColorTransformMat;
3085 mOutput.mState.isSecure = false;
3086 mOutput.mState.needsFiltering = false;
3087 mOutput.mState.usesClientComposition = true;
3088 mOutput.mState.usesDeviceComposition = false;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003089 mOutput.mState.reusedClientComposition = false;
Lloyd Piquee9eff972020-05-05 12:36:44 -07003090 mOutput.mState.flipClientTarget = false;
Alec Mourif8d093d2022-02-10 15:16:59 -08003091 mOutput.mState.clientTargetBrightness = kClientTargetBrightness;
Lloyd Pique56eba802019-08-28 15:45:25 -07003092
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003093 EXPECT_CALL(mOutput, getCompositionEngine()).WillRepeatedly(ReturnRef(mCompositionEngine));
Lloyd Pique56eba802019-08-28 15:45:25 -07003094 EXPECT_CALL(mCompositionEngine, getRenderEngine()).WillRepeatedly(ReturnRef(mRenderEngine));
Alec Mourie4034bb2019-11-19 12:45:54 -08003095 EXPECT_CALL(mCompositionEngine, getTimeStats())
3096 .WillRepeatedly(ReturnRef(*mTimeStats.get()));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003097 EXPECT_CALL(*mDisplayColorProfile, getHdrCapabilities())
3098 .WillRepeatedly(ReturnRef(kHdrCapabilities));
Lloyd Pique56eba802019-08-28 15:45:25 -07003099 }
3100
Lloyd Pique6818fa52019-12-03 12:32:13 -08003101 struct ExecuteState : public CallOrderStateMachineHelper<TestType, ExecuteState> {
3102 auto execute() {
Robert Carr6fe2bef2022-03-09 13:49:41 -08003103 getInstance()->mReadyFence =
3104 getInstance()->mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003105 return nextState<FenceCheckState>();
3106 }
3107 };
3108
3109 struct FenceCheckState : public CallOrderStateMachineHelper<TestType, FenceCheckState> {
3110 void expectNoFenceWasReturned() { EXPECT_FALSE(getInstance()->mReadyFence); }
3111
3112 void expectAFenceWasReturned() { EXPECT_TRUE(getInstance()->mReadyFence); }
3113 };
3114
3115 // Call this member function to start using the mini-DSL defined above.
3116 [[nodiscard]] auto verify() { return ExecuteState::make(this); }
3117
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003118 static constexpr ui::Rotation kDefaultOutputOrientation = ui::ROTATION_0;
3119 static constexpr uint32_t kDefaultOutputOrientationFlags =
3120 ui::Transform::toRotationFlags(kDefaultOutputOrientation);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003121 static constexpr ui::Dataspace kDefaultOutputDataspace = ui::Dataspace::UNKNOWN;
3122 static constexpr ui::Dataspace kExpensiveOutputDataspace = ui::Dataspace::DISPLAY_P3;
3123 static constexpr float kDefaultMaxLuminance = 0.9f;
3124 static constexpr float kDefaultAvgLuminance = 0.7f;
3125 static constexpr float kDefaultMinLuminance = 0.1f;
Alec Mourib21d94e2022-01-13 17:44:10 -08003126 static constexpr float kUnknownLuminance = -1.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003127 static constexpr float kDisplayLuminance = 400.f;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003128 static constexpr float kClientTargetLuminanceNits = 200.f;
Alec Mourif8d093d2022-02-10 15:16:59 -08003129 static constexpr float kClientTargetBrightness = 0.5f;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003130
3131 static const Rect kDefaultOutputFrame;
3132 static const Rect kDefaultOutputViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003133 static const Rect kDefaultOutputDestinationClip;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003134 static const mat4 kDefaultColorTransformMat;
3135
3136 static const Region kDebugRegion;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003137 static const compositionengine::CompositionRefreshArgs kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003138 static const HdrCapabilities kHdrCapabilities;
3139
Lloyd Pique56eba802019-08-28 15:45:25 -07003140 StrictMock<mock::CompositionEngine> mCompositionEngine;
3141 StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
Alec Mourie4034bb2019-11-19 12:45:54 -08003142 // TODO: make this is a proper mock.
3143 std::shared_ptr<TimeStats> mTimeStats = std::make_shared<android::impl::TimeStats>();
Lloyd Pique56eba802019-08-28 15:45:25 -07003144 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3145 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003146 StrictMock<OutputPartialMock> mOutput;
Alec Mouria90a5702021-04-16 16:36:21 +00003147 std::shared_ptr<renderengine::ExternalTexture> mOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003148 renderengine::impl::
3149 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3150 renderengine::impl::ExternalTexture::Usage::READABLE |
3151 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003152
3153 std::optional<base::unique_fd> mReadyFence;
Lloyd Pique56eba802019-08-28 15:45:25 -07003154};
3155
3156const Rect OutputComposeSurfacesTest::kDefaultOutputFrame{1001, 1002, 1003, 1004};
3157const Rect OutputComposeSurfacesTest::kDefaultOutputViewport{1005, 1006, 1007, 1008};
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003158const Rect OutputComposeSurfacesTest::kDefaultOutputDestinationClip{1013, 1014, 1015, 1016};
Lloyd Pique0a456232020-01-16 17:51:13 -08003159const mat4 OutputComposeSurfacesTest::kDefaultColorTransformMat{mat4() * 0.5f};
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003160const compositionengine::CompositionRefreshArgs OutputComposeSurfacesTest::kDefaultRefreshArgs;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003161const Region OutputComposeSurfacesTest::kDebugRegion{Rect{100, 101, 102, 103}};
Alec Mourib21d94e2022-01-13 17:44:10 -08003162
Lloyd Pique6818fa52019-12-03 12:32:13 -08003163const HdrCapabilities OutputComposeSurfacesTest::
3164 kHdrCapabilities{{},
3165 OutputComposeSurfacesTest::kDefaultMaxLuminance,
3166 OutputComposeSurfacesTest::kDefaultAvgLuminance,
3167 OutputComposeSurfacesTest::kDefaultMinLuminance};
Lloyd Pique56eba802019-08-28 15:45:25 -07003168
Lloyd Piquea76ce462020-01-14 13:06:37 -08003169TEST_F(OutputComposeSurfacesTest, doesNothingButSignalNoExpensiveRenderingIfNoClientComposition) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003170 mOutput.mState.usesClientComposition = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003171
Lloyd Piquee9eff972020-05-05 12:36:44 -07003172 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003173 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003174
Lloyd Piquea76ce462020-01-14 13:06:37 -08003175 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3176
Lloyd Pique6818fa52019-12-03 12:32:13 -08003177 verify().execute().expectAFenceWasReturned();
Lloyd Pique56eba802019-08-28 15:45:25 -07003178}
3179
Lloyd Piquee9eff972020-05-05 12:36:44 -07003180TEST_F(OutputComposeSurfacesTest,
3181 dequeuesABufferIfNoClientCompositionButFlipClientTargetRequested) {
3182 mOutput.mState.usesClientComposition = false;
3183 mOutput.mState.flipClientTarget = true;
3184
Lloyd Pique6818fa52019-12-03 12:32:13 -08003185 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003186 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003187
3188 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(mOutputBuffer));
3189 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3190
3191 verify().execute().expectAFenceWasReturned();
3192}
3193
3194TEST_F(OutputComposeSurfacesTest, doesMinimalWorkIfDequeueBufferFailsForClientComposition) {
3195 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003196 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Piquee9eff972020-05-05 12:36:44 -07003197
3198 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
3199
3200 verify().execute().expectNoFenceWasReturned();
3201}
3202
3203TEST_F(OutputComposeSurfacesTest,
3204 doesMinimalWorkIfDequeueBufferFailsForNoClientCompositionButFlipClientTargetRequested) {
3205 mOutput.mState.usesClientComposition = false;
3206 mOutput.mState.flipClientTarget = true;
3207
3208 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003209 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003210
Lloyd Pique6818fa52019-12-03 12:32:13 -08003211 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillOnce(Return(nullptr));
Lloyd Pique56eba802019-08-28 15:45:25 -07003212
Lloyd Pique6818fa52019-12-03 12:32:13 -08003213 verify().execute().expectNoFenceWasReturned();
3214}
Lloyd Pique56eba802019-08-28 15:45:25 -07003215
Lloyd Pique6818fa52019-12-03 12:32:13 -08003216TEST_F(OutputComposeSurfacesTest, handlesZeroCompositionRequests) {
3217 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3218 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3219 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003220 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003221 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003222 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003223 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3224 .WillRepeatedly(Return());
Lloyd Pique56eba802019-08-28 15:45:25 -07003225
Lloyd Pique6818fa52019-12-03 12:32:13 -08003226 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003227 EXPECT_CALL(mRenderEngine, drawLayers(_, IsEmpty(), _, false, _))
3228 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003229 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003230 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003231 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003232 -> std::future<renderengine::RenderEngineResult> {
3233 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3234 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003235 verify().execute().expectAFenceWasReturned();
3236}
Lloyd Pique56eba802019-08-28 15:45:25 -07003237
Lloyd Pique6818fa52019-12-03 12:32:13 -08003238TEST_F(OutputComposeSurfacesTest, buildsAndRendersRequestList) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003239 LayerFE::LayerSettings r1;
3240 LayerFE::LayerSettings r2;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003241
3242 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3243 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3244
3245 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3246 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3247 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003248 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003249 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003250 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003251 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3252 .WillRepeatedly(
3253 Invoke([&](const Region&,
Vishnu Nair9b079a22020-01-21 14:36:08 -08003254 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
Lloyd Pique6818fa52019-12-03 12:32:13 -08003255 clientCompositionLayers.emplace_back(r2);
3256 }));
3257
3258 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003259 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003260 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003261 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003262 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003263 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003264 -> std::future<renderengine::RenderEngineResult> {
3265 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3266 });
Alec Mouri1684c702021-02-04 12:27:26 -08003267
3268 verify().execute().expectAFenceWasReturned();
3269}
3270
3271TEST_F(OutputComposeSurfacesTest,
3272 buildsAndRendersRequestListAndCachesFramebufferForInternalLayers) {
3273 LayerFE::LayerSettings r1;
3274 LayerFE::LayerSettings r2;
3275
3276 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3277 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
Dominik Laskowski29fa1462021-04-27 15:51:50 -07003278 mOutput.setLayerFilter({ui::LayerStack{1234u}, true});
Alec Mouri1684c702021-02-04 12:27:26 -08003279
3280 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3281 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3282 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3283 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003284 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Alec Mouri1684c702021-02-04 12:27:26 -08003285 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1}));
3286 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3287 .WillRepeatedly(
3288 Invoke([&](const Region&,
3289 std::vector<LayerFE::LayerSettings>& clientCompositionLayers) {
3290 clientCompositionLayers.emplace_back(r2);
3291 }));
3292
3293 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003294 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, true, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003295 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003296 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003297 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003298 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003299 -> std::future<renderengine::RenderEngineResult> {
3300 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3301 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003302
3303 verify().execute().expectAFenceWasReturned();
3304}
3305
Vishnu Nair9b079a22020-01-21 14:36:08 -08003306TEST_F(OutputComposeSurfacesTest, renderDuplicateClientCompositionRequestsWithoutCache) {
3307 mOutput.cacheClientCompositionRequests(0);
3308 LayerFE::LayerSettings r1;
3309 LayerFE::LayerSettings r2;
3310
3311 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3312 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3313
3314 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3315 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3316 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003317 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003318 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003319 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3320 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3321 .WillRepeatedly(Return());
3322
3323 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003324 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003325 .Times(2)
Sally Qi4cabdd02021-08-05 16:45:57 -07003326 .WillOnce(Return(ByMove(
3327 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))))
3328 .WillOnce(Return(ByMove(
3329 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003330
3331 verify().execute().expectAFenceWasReturned();
3332 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3333
3334 verify().execute().expectAFenceWasReturned();
3335 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3336}
3337
3338TEST_F(OutputComposeSurfacesTest, skipDuplicateClientCompositionRequests) {
3339 mOutput.cacheClientCompositionRequests(3);
3340 LayerFE::LayerSettings r1;
3341 LayerFE::LayerSettings r2;
3342
3343 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3344 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3345
3346 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3347 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3348 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003349 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003350 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003351 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3352 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3353 .WillRepeatedly(Return());
3354
3355 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003356 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003357 .WillOnce(Return(ByMove(
3358 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003359 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(false));
3360
3361 verify().execute().expectAFenceWasReturned();
3362 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3363
3364 // We do not expect another call to draw layers.
3365 verify().execute().expectAFenceWasReturned();
3366 EXPECT_TRUE(mOutput.mState.reusedClientComposition);
3367}
3368
3369TEST_F(OutputComposeSurfacesTest, clientCompositionIfBufferChanges) {
3370 LayerFE::LayerSettings r1;
3371 LayerFE::LayerSettings r2;
3372
3373 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3374 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3375
3376 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3377 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3378 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003379 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003380 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003381 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{r1, r2}));
3382 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3383 .WillRepeatedly(Return());
3384
Alec Mouria90a5702021-04-16 16:36:21 +00003385 const auto otherOutputBuffer = std::make_shared<
Vishnu Nairdbbe3852022-01-12 20:22:11 -08003386 renderengine::impl::
3387 ExternalTexture>(new GraphicBuffer(), mRenderEngine,
3388 renderengine::impl::ExternalTexture::Usage::READABLE |
3389 renderengine::impl::ExternalTexture::Usage::WRITEABLE);
Vishnu Nair9b079a22020-01-21 14:36:08 -08003390 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_))
3391 .WillOnce(Return(mOutputBuffer))
3392 .WillOnce(Return(otherOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003393 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003394 .WillRepeatedly([&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003395 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003396 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003397 base::unique_fd&&)
Sally Qi4cabdd02021-08-05 16:45:57 -07003398 -> std::future<renderengine::RenderEngineResult> {
3399 return futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()});
3400 });
Vishnu Nair9b079a22020-01-21 14:36:08 -08003401
3402 verify().execute().expectAFenceWasReturned();
3403 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3404
3405 verify().execute().expectAFenceWasReturned();
3406 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3407}
3408
3409TEST_F(OutputComposeSurfacesTest, clientCompositionIfRequestChanges) {
3410 LayerFE::LayerSettings r1;
3411 LayerFE::LayerSettings r2;
3412 LayerFE::LayerSettings r3;
3413
3414 r1.geometry.boundaries = FloatRect{1, 2, 3, 4};
3415 r2.geometry.boundaries = FloatRect{5, 6, 7, 8};
3416 r3.geometry.boundaries = FloatRect{5, 6, 7, 9};
3417
3418 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3419 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3420 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003421 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003422 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003423 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r2}))
3424 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{r1, r3}));
3425 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3426 .WillRepeatedly(Return());
3427
3428 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi59a9f502021-10-12 18:53:23 +00003429 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r2), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003430 .WillOnce(Return(ByMove(
3431 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Sally Qi59a9f502021-10-12 18:53:23 +00003432 EXPECT_CALL(mRenderEngine, drawLayers(_, ElementsAre(r1, r3), _, false, _))
Sally Qi4cabdd02021-08-05 16:45:57 -07003433 .WillOnce(Return(ByMove(
3434 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Vishnu Nair9b079a22020-01-21 14:36:08 -08003435
3436 verify().execute().expectAFenceWasReturned();
3437 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3438
3439 verify().execute().expectAFenceWasReturned();
3440 EXPECT_FALSE(mOutput.mState.reusedClientComposition);
3441}
3442
Lloyd Pique6818fa52019-12-03 12:32:13 -08003443struct OutputComposeSurfacesTest_UsesExpectedDisplaySettings : public OutputComposeSurfacesTest {
3444 OutputComposeSurfacesTest_UsesExpectedDisplaySettings() {
3445 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003446 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Robert Carrccab4242021-09-28 16:53:03 -07003447 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003448 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003449 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3450 .WillRepeatedly(Return());
3451 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3452 }
3453
3454 struct MixedCompositionState
3455 : public CallOrderStateMachineHelper<TestType, MixedCompositionState> {
3456 auto ifMixedCompositionIs(bool used) {
3457 getInstance()->mOutput.mState.usesDeviceComposition = used;
3458 return nextState<OutputUsesHdrState>();
3459 }
3460 };
3461
3462 struct OutputUsesHdrState : public CallOrderStateMachineHelper<TestType, OutputUsesHdrState> {
3463 auto andIfUsesHdr(bool used) {
3464 EXPECT_CALL(*getInstance()->mDisplayColorProfile, hasWideColorGamut())
3465 .WillOnce(Return(used));
Alec Mourib21d94e2022-01-13 17:44:10 -08003466 return nextState<OutputWithDisplayBrightnessNits>();
3467 }
3468 };
3469
3470 struct OutputWithDisplayBrightnessNits
3471 : public CallOrderStateMachineHelper<TestType, OutputWithDisplayBrightnessNits> {
3472 auto withDisplayBrightnessNits(float nits) {
3473 getInstance()->mOutput.mState.displayBrightnessNits = nits;
Lloyd Pique6818fa52019-12-03 12:32:13 -08003474 return nextState<SkipColorTransformState>();
3475 }
3476 };
3477
3478 struct SkipColorTransformState
3479 : public CallOrderStateMachineHelper<TestType, SkipColorTransformState> {
3480 auto andIfSkipColorTransform(bool skip) {
3481 // May be called zero or one times.
3482 EXPECT_CALL(getInstance()->mOutput, getSkipColorTransform())
3483 .WillRepeatedly(Return(skip));
3484 return nextState<ExpectDisplaySettingsState>();
3485 }
3486 };
3487
3488 struct ExpectDisplaySettingsState
3489 : public CallOrderStateMachineHelper<TestType, ExpectDisplaySettingsState> {
3490 auto thenExpectDisplaySettingsUsed(renderengine::DisplaySettings settings) {
Sally Qi4cabdd02021-08-05 16:45:57 -07003491 EXPECT_CALL(getInstance()->mRenderEngine, drawLayers(settings, _, _, false, _))
3492 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3493 {NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003494 return nextState<ExecuteState>();
3495 }
3496 };
3497
3498 // Call this member function to start using the mini-DSL defined above.
3499 [[nodiscard]] auto verify() { return MixedCompositionState::make(this); }
3500};
3501
3502TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrMixedComposition) {
3503 verify().ifMixedCompositionIs(true)
3504 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003505 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003506 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003507 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3508 .clip = kDefaultOutputViewport,
3509 .maxLuminance = kDefaultMaxLuminance,
3510 .currentLuminanceNits = kDefaultMaxLuminance,
3511 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003512 .colorTransform = kDefaultColorTransformMat,
3513 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003514 .orientation = kDefaultOutputOrientationFlags,
3515 .targetLuminanceNits = kClientTargetLuminanceNits})
3516 .execute()
3517 .expectAFenceWasReturned();
3518}
3519
3520TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3521 forHdrMixedCompositionWithDisplayBrightness) {
3522 verify().ifMixedCompositionIs(true)
3523 .andIfUsesHdr(true)
3524 .withDisplayBrightnessNits(kDisplayLuminance)
3525 .andIfSkipColorTransform(false)
3526 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3527 .clip = kDefaultOutputViewport,
3528 .maxLuminance = kDefaultMaxLuminance,
3529 .currentLuminanceNits = kDisplayLuminance,
3530 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003531 .colorTransform = kDefaultColorTransformMat,
3532 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003533 .orientation = kDefaultOutputOrientationFlags,
3534 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003535 .execute()
3536 .expectAFenceWasReturned();
3537}
3538
3539TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrMixedComposition) {
3540 verify().ifMixedCompositionIs(true)
3541 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003542 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003543 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003544 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3545 .clip = kDefaultOutputViewport,
3546 .maxLuminance = kDefaultMaxLuminance,
3547 .currentLuminanceNits = kDefaultMaxLuminance,
3548 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003549 .colorTransform = kDefaultColorTransformMat,
3550 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003551 .orientation = kDefaultOutputOrientationFlags,
3552 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003553 .execute()
3554 .expectAFenceWasReturned();
3555}
3556
3557TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forHdrOnlyClientComposition) {
3558 verify().ifMixedCompositionIs(false)
3559 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003560 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003561 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003562 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3563 .clip = kDefaultOutputViewport,
3564 .maxLuminance = kDefaultMaxLuminance,
3565 .currentLuminanceNits = kDefaultMaxLuminance,
3566 .outputDataspace = kDefaultOutputDataspace,
3567 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003568 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003569 .orientation = kDefaultOutputOrientationFlags,
3570 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003571 .execute()
3572 .expectAFenceWasReturned();
3573}
3574
3575TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings, forNonHdrOnlyClientComposition) {
3576 verify().ifMixedCompositionIs(false)
3577 .andIfUsesHdr(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003578 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003579 .andIfSkipColorTransform(false)
Alec Mourib21d94e2022-01-13 17:44:10 -08003580 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3581 .clip = kDefaultOutputViewport,
3582 .maxLuminance = kDefaultMaxLuminance,
3583 .currentLuminanceNits = kDefaultMaxLuminance,
3584 .outputDataspace = kDefaultOutputDataspace,
3585 .colorTransform = kDefaultColorTransformMat,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003586 .deviceHandlesColorTransform = false,
Alec Mourib21d94e2022-01-13 17:44:10 -08003587 .orientation = kDefaultOutputOrientationFlags,
3588 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003589 .execute()
3590 .expectAFenceWasReturned();
3591}
3592
3593TEST_F(OutputComposeSurfacesTest_UsesExpectedDisplaySettings,
3594 usesExpectedDisplaySettingsForHdrOnlyClientCompositionWithSkipClientTransform) {
3595 verify().ifMixedCompositionIs(false)
3596 .andIfUsesHdr(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003597 .withDisplayBrightnessNits(kUnknownLuminance)
Lloyd Pique6818fa52019-12-03 12:32:13 -08003598 .andIfSkipColorTransform(true)
Alec Mourib21d94e2022-01-13 17:44:10 -08003599 .thenExpectDisplaySettingsUsed({.physicalDisplay = kDefaultOutputDestinationClip,
3600 .clip = kDefaultOutputViewport,
3601 .maxLuminance = kDefaultMaxLuminance,
3602 .currentLuminanceNits = kDefaultMaxLuminance,
3603 .outputDataspace = kDefaultOutputDataspace,
Leon Scroggins III745dcaa2022-01-26 11:55:58 -05003604 .colorTransform = kDefaultColorTransformMat,
3605 .deviceHandlesColorTransform = true,
Alec Mourib21d94e2022-01-13 17:44:10 -08003606 .orientation = kDefaultOutputOrientationFlags,
3607 .targetLuminanceNits = kClientTargetLuminanceNits})
Lloyd Pique6818fa52019-12-03 12:32:13 -08003608 .execute()
3609 .expectAFenceWasReturned();
3610}
3611
3612struct OutputComposeSurfacesTest_HandlesProtectedContent : public OutputComposeSurfacesTest {
3613 struct Layer {
3614 Layer() {
Ady Abrahameca9d752021-03-03 12:20:00 -08003615 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
3616 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003617 }
3618
3619 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003620 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Pique6818fa52019-12-03 12:32:13 -08003621 LayerFECompositionState mLayerFEState;
3622 };
3623
3624 OutputComposeSurfacesTest_HandlesProtectedContent() {
3625 mLayer1.mLayerFEState.hasProtectedContent = false;
3626 mLayer2.mLayerFEState.hasProtectedContent = false;
3627
3628 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
3629 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3630 .WillRepeatedly(Return(&mLayer1.mOutputLayer));
3631 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
3632 .WillRepeatedly(Return(&mLayer2.mOutputLayer));
3633
3634 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3635
3636 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3637
Robert Carrccab4242021-09-28 16:53:03 -07003638 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, _, _))
Vishnu Nair9b079a22020-01-21 14:36:08 -08003639 .WillRepeatedly(Return(std::vector<LayerFE::LayerSettings>{}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003640 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3641 .WillRepeatedly(Return());
3642 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003643 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3644 .WillRepeatedly(
3645 [&](const renderengine::DisplaySettings&,
Sally Qi59a9f502021-10-12 18:53:23 +00003646 const std::vector<renderengine::LayerSettings>&,
Sally Qi4cabdd02021-08-05 16:45:57 -07003647 const std::shared_ptr<renderengine::ExternalTexture>&, const bool,
Sally Qi59a9f502021-10-12 18:53:23 +00003648 base::unique_fd&&) -> std::future<renderengine::RenderEngineResult> {
Sally Qi4cabdd02021-08-05 16:45:57 -07003649 return futureOf<renderengine::RenderEngineResult>(
3650 {NO_ERROR, base::unique_fd()});
3651 });
Lloyd Pique6818fa52019-12-03 12:32:13 -08003652 }
3653
3654 Layer mLayer1;
3655 Layer mLayer2;
3656};
3657
3658TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifDisplayIsNotSecure) {
3659 mOutput.mState.isSecure = false;
3660 mLayer2.mLayerFEState.hasProtectedContent = true;
3661 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003662 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
Derek Sollenberger1ec2fb52021-06-16 15:11:27 -04003663 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003664
Robert Carr6fe2bef2022-03-09 13:49:41 -08003665 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003666}
3667
3668TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifRenderEngineDoesNotSupportIt) {
3669 mOutput.mState.isSecure = true;
3670 mLayer2.mLayerFEState.hasProtectedContent = true;
3671 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
3672
Robert Carr6fe2bef2022-03-09 13:49:41 -08003673 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003674}
3675
3676TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNoProtectedContentLayers) {
3677 mOutput.mState.isSecure = true;
3678 mLayer2.mLayerFEState.hasProtectedContent = false;
3679 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3680 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(false));
3681 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3682 EXPECT_CALL(mRenderEngine, useProtectedContext(false));
3683 EXPECT_CALL(*mRenderSurface, setProtected(false));
3684
Robert Carr6fe2bef2022-03-09 13:49:41 -08003685 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003686}
3687
3688TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifNotEnabled) {
3689 mOutput.mState.isSecure = true;
3690 mLayer2.mLayerFEState.hasProtectedContent = true;
3691 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3692
3693 // For this test, we also check the call order of key functions.
3694 InSequence seq;
3695
3696 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3697 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3698 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3699 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3700 EXPECT_CALL(*mRenderSurface, setProtected(true));
3701 // Must happen after setting the protected content state.
3702 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
Sally Qi4cabdd02021-08-05 16:45:57 -07003703 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3704 .WillOnce(Return(ByMove(
3705 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003706
Robert Carr6fe2bef2022-03-09 13:49:41 -08003707 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003708}
3709
3710TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledEverywhere) {
3711 mOutput.mState.isSecure = true;
3712 mLayer2.mLayerFEState.hasProtectedContent = true;
3713 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3714 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true));
3715 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3716
Robert Carr6fe2bef2022-03-09 13:49:41 -08003717 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003718}
3719
3720TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifFailsToEnableInRenderEngine) {
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)).WillOnce(Return(false));
3725 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3726 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3727
Robert Carr6fe2bef2022-03-09 13:49:41 -08003728 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003729}
3730
3731TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderEngine) {
3732 mOutput.mState.isSecure = true;
3733 mLayer2.mLayerFEState.hasProtectedContent = true;
3734 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3735 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(true)).WillOnce(Return(true));
3736 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(false));
3737 EXPECT_CALL(*mRenderSurface, setProtected(true));
3738
Robert Carr6fe2bef2022-03-09 13:49:41 -08003739 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003740}
3741
3742TEST_F(OutputComposeSurfacesTest_HandlesProtectedContent, ifAlreadyEnabledInRenderSurface) {
3743 mOutput.mState.isSecure = true;
3744 mLayer2.mLayerFEState.hasProtectedContent = true;
3745 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(true));
3746 EXPECT_CALL(mRenderEngine, isProtected).WillOnce(Return(false));
3747 EXPECT_CALL(*mRenderSurface, isProtected).WillOnce(Return(true));
3748 EXPECT_CALL(mRenderEngine, useProtectedContext(true));
3749
Robert Carr6fe2bef2022-03-09 13:49:41 -08003750 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lloyd Pique6818fa52019-12-03 12:32:13 -08003751}
3752
3753struct OutputComposeSurfacesTest_SetsExpensiveRendering : public OutputComposeSurfacesTest {
3754 OutputComposeSurfacesTest_SetsExpensiveRendering() {
3755 EXPECT_CALL(mOutput, getSkipColorTransform()).WillRepeatedly(Return(false));
3756 EXPECT_CALL(*mDisplayColorProfile, hasWideColorGamut()).WillRepeatedly(Return(true));
3757 EXPECT_CALL(mRenderEngine, supportsProtectedContent()).WillRepeatedly(Return(false));
Peiyong Lin09f910f2020-09-25 10:54:13 -07003758 EXPECT_CALL(mRenderEngine, isProtected()).WillRepeatedly(Return(false));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003759 EXPECT_CALL(mOutput, appendRegionFlashRequests(RegionEq(kDebugRegion), _))
3760 .WillRepeatedly(Return());
3761 EXPECT_CALL(*mRenderSurface, dequeueBuffer(_)).WillRepeatedly(Return(mOutputBuffer));
3762 }
3763};
3764
3765TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering, IfExepensiveOutputDataspaceIsUsed) {
3766 mOutput.mState.dataspace = kExpensiveOutputDataspace;
3767
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05003768 LayerFE::LayerSettings layerSettings;
Robert Carrccab4242021-09-28 16:53:03 -07003769 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kExpensiveOutputDataspace, _))
Leon Scroggins III7bdcceb2022-03-09 16:53:52 -05003770 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{layerSettings}));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003771
3772 // For this test, we also check the call order of key functions.
3773 InSequence seq;
3774
3775 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Sally Qi4cabdd02021-08-05 16:45:57 -07003776 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3777 .WillOnce(Return(ByMove(
3778 futureOf<renderengine::RenderEngineResult>({NO_ERROR, base::unique_fd()}))));
Lloyd Pique6818fa52019-12-03 12:32:13 -08003779
Robert Carr6fe2bef2022-03-09 13:49:41 -08003780 mOutput.composeSurfaces(kDebugRegion, kDefaultRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003781}
3782
3783struct OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur
3784 : public OutputComposeSurfacesTest_SetsExpensiveRendering {
3785 OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur() {
3786 mLayer.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00003787 mLayer.layerFEState.isOpaque = false;
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003788 mOutput.editState().isEnabled = true;
3789
Snild Dolkow9e217d62020-04-22 15:53:42 +02003790 EXPECT_CALL(mLayer.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08003791 EXPECT_CALL(mLayer.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04003792 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, 0,
3793 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Robert Carrccab4242021-09-28 16:53:03 -07003794 EXPECT_CALL(mOutput, generateClientCompositionRequests(_, kDefaultOutputDataspace, _))
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003795 .WillOnce(Return(std::vector<LayerFE::LayerSettings>{}));
Sally Qi4cabdd02021-08-05 16:45:57 -07003796 EXPECT_CALL(mRenderEngine, drawLayers(_, _, _, false, _))
3797 .WillOnce(Return(ByMove(futureOf<renderengine::RenderEngineResult>(
3798 {NO_ERROR, base::unique_fd()}))));
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003799 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(1u));
3800 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
3801 .WillRepeatedly(Return(&mLayer.outputLayer));
3802 }
3803
3804 NonInjectedLayer mLayer;
3805 compositionengine::CompositionRefreshArgs mRefreshArgs;
3806};
3807
3808TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreExpensive) {
3809 mRefreshArgs.blursAreExpensive = true;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003810 mOutput.updateCompositionState(mRefreshArgs);
3811 mOutput.planComposition();
3812 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003813
3814 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true));
Robert Carr6fe2bef2022-03-09 13:49:41 -08003815 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003816}
3817
3818TEST_F(OutputComposeSurfacesTest_SetsExpensiveRendering_ForBlur, IfBlursAreNotExpensive) {
3819 mRefreshArgs.blursAreExpensive = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08003820 mOutput.updateCompositionState(mRefreshArgs);
3821 mOutput.planComposition();
3822 mOutput.writeCompositionState(mRefreshArgs);
Lucas Dupin2dd6f392020-02-18 17:43:36 -08003823
3824 EXPECT_CALL(mOutput, setExpensiveRenderingExpected(true)).Times(0);
Robert Carr6fe2bef2022-03-09 13:49:41 -08003825 mOutput.composeSurfaces(kDebugRegion, mRefreshArgs);
Lloyd Pique56eba802019-08-28 15:45:25 -07003826}
3827
3828/*
3829 * Output::generateClientCompositionRequests()
3830 */
3831
3832struct GenerateClientCompositionRequestsTest : public testing::Test {
Lloyd Piquefaa3f192019-11-14 14:05:09 -08003833 struct OutputPartialMock : public OutputPartialMockBase {
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003834 // compositionengine::Output overrides
Robert Carrccab4242021-09-28 16:53:03 -07003835 std::vector<LayerFE::LayerSettings> generateClientCompositionRequestsHelper(
3836 bool supportsProtectedContent, ui::Dataspace dataspace) {
3837 std::vector<LayerFE*> ignore;
Lloyd Pique56eba802019-08-28 15:45:25 -07003838 return impl::Output::generateClientCompositionRequests(supportsProtectedContent,
Robert Carrccab4242021-09-28 16:53:03 -07003839 dataspace, ignore);
Lloyd Pique56eba802019-08-28 15:45:25 -07003840 }
3841 };
3842
Lloyd Piquea4863342019-12-04 18:45:02 -08003843 struct Layer {
3844 Layer() {
3845 EXPECT_CALL(mOutputLayer, getState()).WillRepeatedly(ReturnRef(mOutputLayerState));
3846 EXPECT_CALL(mOutputLayer, editState()).WillRepeatedly(ReturnRef(mOutputLayerState));
Ady Abrahameca9d752021-03-03 12:20:00 -08003847 EXPECT_CALL(mOutputLayer, getLayerFE()).WillRepeatedly(ReturnRef(*mLayerFE));
3848 EXPECT_CALL(*mLayerFE, getCompositionState()).WillRepeatedly(Return(&mLayerFEState));
Lloyd Piquea4863342019-12-04 18:45:02 -08003849 }
3850
3851 StrictMock<mock::OutputLayer> mOutputLayer;
Ady Abrahameca9d752021-03-03 12:20:00 -08003852 sp<StrictMock<mock::LayerFE>> mLayerFE = sp<StrictMock<mock::LayerFE>>::make();
Lloyd Piquea4863342019-12-04 18:45:02 -08003853 LayerFECompositionState mLayerFEState;
3854 impl::OutputLayerCompositionState mOutputLayerState;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003855 LayerFE::LayerSettings mLayerSettings;
Lloyd Piquea4863342019-12-04 18:45:02 -08003856 };
3857
Lloyd Pique56eba802019-08-28 15:45:25 -07003858 GenerateClientCompositionRequestsTest() {
Lloyd Piquea4863342019-12-04 18:45:02 -08003859 mOutput.mState.needsFiltering = false;
3860
Lloyd Pique56eba802019-08-28 15:45:25 -07003861 mOutput.setDisplayColorProfileForTest(
3862 std::unique_ptr<DisplayColorProfile>(mDisplayColorProfile));
3863 mOutput.setRenderSurfaceForTest(std::unique_ptr<RenderSurface>(mRenderSurface));
3864 }
3865
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003866 static constexpr float kLayerWhitePointNits = 200.f;
3867
Lloyd Pique56eba802019-08-28 15:45:25 -07003868 mock::DisplayColorProfile* mDisplayColorProfile = new StrictMock<mock::DisplayColorProfile>();
3869 mock::RenderSurface* mRenderSurface = new StrictMock<mock::RenderSurface>();
Lloyd Piquea38ea7e2019-04-16 18:10:26 -07003870 StrictMock<OutputPartialMock> mOutput;
Lloyd Pique56eba802019-08-28 15:45:25 -07003871};
3872
Lloyd Piquea4863342019-12-04 18:45:02 -08003873struct GenerateClientCompositionRequestsTest_ThreeLayers
3874 : public GenerateClientCompositionRequestsTest {
3875 GenerateClientCompositionRequestsTest_ThreeLayers() {
Angel Aguayob084e0c2021-08-04 23:27:28 +00003876 mOutput.mState.orientedDisplaySpace.setContent(kDisplayFrame);
3877 mOutput.mState.layerStackSpace.setContent(kDisplayViewport);
3878 mOutput.mState.displaySpace.setContent(kDisplayDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003879 mOutput.mState.transform =
3880 ui::Transform{ui::Transform::toRotationFlags(kDisplayOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00003881 mOutput.mState.displaySpace.setOrientation(kDisplayOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08003882 mOutput.mState.needsFiltering = false;
3883 mOutput.mState.isSecure = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003884
Lloyd Piquea4863342019-12-04 18:45:02 -08003885 for (size_t i = 0; i < mLayers.size(); i++) {
3886 mLayers[i].mOutputLayerState.clearClientTarget = false;
3887 mLayers[i].mOutputLayerState.visibleRegion = Region(kDisplayFrame);
3888 mLayers[i].mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08003889 mLayers[i].mLayerSettings.geometry.boundaries =
Lloyd Piquea4863342019-12-04 18:45:02 -08003890 FloatRect{static_cast<float>(i + 1), 0.f, 0.f, 0.f};
Vishnu Nair9b079a22020-01-21 14:36:08 -08003891 mLayers[i].mLayerSettings.source.solidColor = {1.0f, 1.0f, 1.0f};
3892 mLayers[i].mLayerSettings.alpha = 1.0f;
3893 mLayers[i].mLayerSettings.disableBlending = false;
Lloyd Pique56eba802019-08-28 15:45:25 -07003894
Lloyd Piquea4863342019-12-04 18:45:02 -08003895 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(i))
3896 .WillRepeatedly(Return(&mLayers[i].mOutputLayer));
3897 EXPECT_CALL(mLayers[i].mOutputLayer, requiresClientComposition())
3898 .WillRepeatedly(Return(true));
3899 EXPECT_CALL(mLayers[i].mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
3900 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003901
Lloyd Piquea4863342019-12-04 18:45:02 -08003902 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(mLayers.size()));
3903 }
Lloyd Pique56eba802019-08-28 15:45:25 -07003904
Marin Shalamanov68933fb2020-09-10 17:58:12 +02003905 static constexpr ui::Rotation kDisplayOrientation = ui::ROTATION_0;
Lloyd Piquea4863342019-12-04 18:45:02 -08003906 static constexpr ui::Dataspace kDisplayDataspace = ui::Dataspace::UNKNOWN;
Alec Mouricdf6cbc2021-11-01 17:21:15 -07003907 static constexpr float kLayerWhitePointNits = 200.f;
Lloyd Pique56eba802019-08-28 15:45:25 -07003908
Lloyd Piquea4863342019-12-04 18:45:02 -08003909 static const Rect kDisplayFrame;
3910 static const Rect kDisplayViewport;
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003911 static const Rect kDisplayDestinationClip;
Lloyd Pique56eba802019-08-28 15:45:25 -07003912
Lloyd Piquea4863342019-12-04 18:45:02 -08003913 std::array<Layer, 3> mLayers;
3914};
Lloyd Pique56eba802019-08-28 15:45:25 -07003915
Lloyd Piquea4863342019-12-04 18:45:02 -08003916const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayFrame(0, 0, 100, 200);
3917const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayViewport(0, 0, 101, 201);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08003918const Rect GenerateClientCompositionRequestsTest_ThreeLayers::kDisplayDestinationClip(0, 0, 103,
3919 203);
Lloyd Pique56eba802019-08-28 15:45:25 -07003920
Lloyd Piquea4863342019-12-04 18:45:02 -08003921TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, handlesNoClientCompostionLayers) {
3922 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3923 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
3924 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Lloyd Pique56eba802019-08-28 15:45:25 -07003925
Robert Carrccab4242021-09-28 16:53:03 -07003926 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003927 kDisplayDataspace);
Lloyd Pique56eba802019-08-28 15:45:25 -07003928 EXPECT_EQ(0u, requests.size());
3929}
3930
Lloyd Piquea4863342019-12-04 18:45:02 -08003931TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, requiresVisibleRegionAfterViewportClip) {
3932 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 10, 10));
3933 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(4000, 0, 4010, 10));
3934 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 0, 0));
3935
Robert Carrccab4242021-09-28 16:53:03 -07003936 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003937 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003938 EXPECT_EQ(0u, requests.size());
Lloyd Piquea4863342019-12-04 18:45:02 -08003939}
3940
3941TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, gathersClientCompositionRequests) {
Vishnu Nair9b079a22020-01-21 14:36:08 -08003942 LayerFE::LayerSettings mShadowSettings;
3943 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Lloyd Piquea4863342019-12-04 18:45:02 -08003944
Ady Abrahameca9d752021-03-03 12:20:00 -08003945 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003946 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08003947 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003948 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08003949 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08003950 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3951 {mShadowSettings, mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08003952
Robert Carrccab4242021-09-28 16:53:03 -07003953 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003954 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08003955 ASSERT_EQ(3u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08003956 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3957 EXPECT_EQ(mShadowSettings, requests[1]);
3958 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
Lloyd Piquea4863342019-12-04 18:45:02 -08003959
Lloyd Piquea4863342019-12-04 18:45:02 -08003960 // Check that a timestamp was set for the layers that generated requests
3961 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3962 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
3963 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
3964}
3965
Alec Mourif54453c2021-05-13 16:28:28 -07003966MATCHER_P(ClientCompositionTargetSettingsBlurSettingsEq, expectedBlurSetting, "") {
3967 *result_listener << "ClientCompositionTargetSettings' BlurSettings aren't equal \n";
3968 *result_listener << "expected " << expectedBlurSetting << "\n";
3969 *result_listener << "actual " << arg.blurSetting << "\n";
3970
3971 return expectedBlurSetting == arg.blurSetting;
3972}
3973
3974TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, overridesBlur) {
3975 LayerFE::LayerSettings mShadowSettings;
3976 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
3977
3978 mLayers[2].mOutputLayerState.overrideInfo.disableBackgroundBlur = true;
3979
3980 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(_))
3981 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
3982 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(_))
3983 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[1].mLayerSettings})));
3984 EXPECT_CALL(*mLayers[2].mLayerFE,
3985 prepareClientCompositionList(ClientCompositionTargetSettingsBlurSettingsEq(
3986 LayerFE::ClientCompositionTargetSettings::BlurSetting::BlurRegionsOnly)))
3987 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
3988 {mShadowSettings, mLayers[2].mLayerSettings})));
3989
Robert Carrccab4242021-09-28 16:53:03 -07003990 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00003991 kDisplayDataspace);
Alec Mourif54453c2021-05-13 16:28:28 -07003992 ASSERT_EQ(3u, requests.size());
3993 EXPECT_EQ(mLayers[1].mLayerSettings, requests[0]);
3994 EXPECT_EQ(mShadowSettings, requests[1]);
3995 EXPECT_EQ(mLayers[2].mLayerSettings, requests[2]);
3996
Alec Mourif54453c2021-05-13 16:28:28 -07003997 // Check that a timestamp was set for the layers that generated requests
3998 EXPECT_TRUE(0 == mLayers[0].mOutputLayerState.clientCompositionTimestamp);
3999 EXPECT_TRUE(0 != mLayers[1].mOutputLayerState.clientCompositionTimestamp);
4000 EXPECT_TRUE(0 != mLayers[2].mOutputLayerState.clientCompositionTimestamp);
4001}
4002
Lloyd Piquea4863342019-12-04 18:45:02 -08004003TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4004 onlyClientComposesClientComposedLayersIfNoClearingNeeded) {
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 = false;
4010 mLayers[1].mOutputLayerState.clearClientTarget = false;
4011 mLayers[2].mOutputLayerState.clearClientTarget = false;
4012
4013 mLayers[0].mLayerFEState.isOpaque = true;
4014 mLayers[1].mLayerFEState.isOpaque = true;
4015 mLayers[2].mLayerFEState.isOpaque = true;
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,
4027 onlyClientComposesClientComposedLayersIfOthersAreNotOpaque) {
4028 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4029 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4030 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
4031
4032 mLayers[0].mOutputLayerState.clearClientTarget = true;
4033 mLayers[1].mOutputLayerState.clearClientTarget = true;
4034 mLayers[2].mOutputLayerState.clearClientTarget = true;
4035
4036 mLayers[0].mLayerFEState.isOpaque = false;
4037 mLayers[1].mLayerFEState.isOpaque = false;
4038 mLayers[2].mLayerFEState.isOpaque = false;
4039
Ady Abrahameca9d752021-03-03 12:20:00 -08004040 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(_))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004041 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004042
Robert Carrccab4242021-09-28 16:53:03 -07004043 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004044 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004045 ASSERT_EQ(1u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004046 EXPECT_EQ(mLayers[2].mLayerSettings, requests[0]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004047}
4048
4049TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers, clearsHWCLayersIfOpaqueAndNotFirst) {
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004050 // If client composition is performed with some layers set to use device
4051 // composition, device layers after the first layer (device or client) will
4052 // clear the frame buffer if they are opaque and if that layer has a flag
4053 // set to do so. The first layer is skipped as the frame buffer is already
4054 // expected to be clear.
4055
Lloyd Piquea4863342019-12-04 18:45:02 -08004056 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4057 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4058 EXPECT_CALL(mLayers[2].mOutputLayer, requiresClientComposition()).WillOnce(Return(true));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004059
Lloyd Piquea4863342019-12-04 18:45:02 -08004060 mLayers[0].mOutputLayerState.clearClientTarget = true;
4061 mLayers[1].mOutputLayerState.clearClientTarget = true;
4062 mLayers[2].mOutputLayerState.clearClientTarget = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004063
Lloyd Piquea4863342019-12-04 18:45:02 -08004064 mLayers[0].mLayerFEState.isOpaque = true;
4065 mLayers[1].mLayerFEState.isOpaque = true;
4066 mLayers[2].mLayerFEState.isOpaque = true;
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004067
4068 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4069 Region(kDisplayFrame),
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004070 false, /* needs filtering */
4071 false, /* secure */
4072 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004073 kDisplayViewport,
4074 kDisplayDataspace,
4075 false /* realContentIsVisible */,
4076 true /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004077 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004078 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004079 };
4080 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4081 Region(kDisplayFrame),
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004082 false, /* needs filtering */
4083 false, /* secure */
4084 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004085 kDisplayViewport,
4086 kDisplayDataspace,
4087 true /* realContentIsVisible */,
4088 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004089 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004090 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004091 };
4092
4093 LayerFE::LayerSettings mBlackoutSettings = mLayers[1].mLayerSettings;
4094 mBlackoutSettings.source.buffer.buffer = nullptr;
4095 mBlackoutSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
4096 mBlackoutSettings.alpha = 0.f;
4097 mBlackoutSettings.disableBlending = true;
4098
Ady Abrahameca9d752021-03-03 12:20:00 -08004099 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004100 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mBlackoutSettings})));
Ady Abrahameca9d752021-03-03 12:20:00 -08004101 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004102 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mLayers[2].mLayerSettings})));
4103
Robert Carrccab4242021-09-28 16:53:03 -07004104 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004105 kDisplayDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004106 ASSERT_EQ(2u, requests.size());
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004107
Lloyd Piquea4863342019-12-04 18:45:02 -08004108 // The second layer is expected to be rendered as alpha=0 black with no blending
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004109 EXPECT_EQ(mBlackoutSettings, requests[0]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004110
Vishnu Nair9b079a22020-01-21 14:36:08 -08004111 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Lloyd Piquea4863342019-12-04 18:45:02 -08004112}
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004113
Lloyd Piquea4863342019-12-04 18:45:02 -08004114TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4115 clippedVisibleRegionUsedToGenerateRequest) {
4116 mLayers[0].mOutputLayerState.visibleRegion = Region(Rect(10, 10, 20, 20));
4117 mLayers[1].mOutputLayerState.visibleRegion = Region(Rect(-10, -10, 30, 30));
4118 mLayers[2].mOutputLayerState.visibleRegion = Region(Rect(-10, 0, 40, 4000));
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004119
Lloyd Piquea4863342019-12-04 18:45:02 -08004120 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4121 Region(Rect(10, 10, 20, 20)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004122 false, /* needs filtering */
4123 false, /* secure */
4124 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004125 kDisplayViewport,
4126 kDisplayDataspace,
4127 true /* realContentIsVisible */,
4128 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004129 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004130 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004131 };
4132 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4133 Region(Rect(0, 0, 30, 30)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004134 false, /* needs filtering */
4135 false, /* secure */
4136 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004137 kDisplayViewport,
4138 kDisplayDataspace,
4139 true /* realContentIsVisible */,
4140 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004141 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004142 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004143 };
4144 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4145 Region(Rect(0, 0, 40, 201)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004146 false, /* needs filtering */
4147 false, /* secure */
4148 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004149 kDisplayViewport,
4150 kDisplayDataspace,
4151 true /* realContentIsVisible */,
4152 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004153 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004154 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004155 };
4156
Ady Abrahameca9d752021-03-03 12:20:00 -08004157 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004158 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004159 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004160 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004161 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004162 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004163
4164 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004165 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004166 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004167}
4168
4169TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4170 perLayerNeedsFilteringUsedToGenerateRequests) {
4171 mOutput.mState.needsFiltering = false;
4172 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4173
Lloyd Piquea4863342019-12-04 18:45:02 -08004174 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4175 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004176 true, /* needs filtering */
4177 false, /* secure */
4178 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004179 kDisplayViewport,
4180 kDisplayDataspace,
4181 true /* realContentIsVisible */,
4182 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004183 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004184 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004185 };
4186 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4187 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004188 false, /* needs filtering */
4189 false, /* secure */
4190 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004191 kDisplayViewport,
4192 kDisplayDataspace,
4193 true /* realContentIsVisible */,
4194 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004195 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004196 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004197 };
4198 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4199 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004200 false, /* needs filtering */
4201 false, /* secure */
4202 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004203 kDisplayViewport,
4204 kDisplayDataspace,
4205 true /* realContentIsVisible */,
4206 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004207 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004208 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004209 };
4210
Ady Abrahameca9d752021-03-03 12:20:00 -08004211 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004212 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004213 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004214 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004215 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004216 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004217
4218 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004219 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4220 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004221}
4222
4223TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4224 wholeOutputNeedsFilteringUsedToGenerateRequests) {
4225 mOutput.mState.needsFiltering = true;
4226 EXPECT_CALL(mLayers[0].mOutputLayer, needsFiltering()).WillRepeatedly(Return(true));
4227
Lloyd Piquea4863342019-12-04 18:45:02 -08004228 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4229 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004230 true, /* needs filtering */
4231 false, /* secure */
4232 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004233 kDisplayViewport,
4234 kDisplayDataspace,
4235 true /* realContentIsVisible */,
4236 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004237 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004238 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004239 };
4240 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4241 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004242 true, /* needs filtering */
4243 false, /* secure */
4244 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004245 kDisplayViewport,
4246 kDisplayDataspace,
4247 true /* realContentIsVisible */,
4248 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004249 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004250 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004251 };
4252 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4253 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004254 true, /* needs filtering */
4255 false, /* secure */
4256 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004257 kDisplayViewport,
4258 kDisplayDataspace,
4259 true /* realContentIsVisible */,
4260 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004261 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004262 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004263 };
4264
Ady Abrahameca9d752021-03-03 12:20:00 -08004265 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004266 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004267 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004268 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004269 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004270 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004271
4272 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004273 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4274 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004275}
4276
4277TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4278 wholeOutputSecurityUsedToGenerateRequests) {
4279 mOutput.mState.isSecure = true;
4280
Lloyd Piquea4863342019-12-04 18:45:02 -08004281 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4282 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004283 false, /* needs filtering */
4284 true, /* secure */
4285 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004286 kDisplayViewport,
4287 kDisplayDataspace,
4288 true /* realContentIsVisible */,
4289 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004290 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004291 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004292 };
4293 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4294 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004295 false, /* needs filtering */
4296 true, /* secure */
4297 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004298 kDisplayViewport,
4299 kDisplayDataspace,
4300 true /* realContentIsVisible */,
4301 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004302 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004303 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004304 };
4305 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4306 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004307 false, /* needs filtering */
4308 true, /* secure */
4309 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004310 kDisplayViewport,
4311 kDisplayDataspace,
4312 true /* realContentIsVisible */,
4313 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004314 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004315 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004316 };
4317
Ady Abrahameca9d752021-03-03 12:20:00 -08004318 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004319 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004320 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004321 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004322 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004323 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004324
4325 static_cast<void>(
Robert Carrccab4242021-09-28 16:53:03 -07004326 mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
4327 kDisplayDataspace));
Lloyd Piquea4863342019-12-04 18:45:02 -08004328}
4329
4330TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4331 protectedContentSupportUsedToGenerateRequests) {
Lloyd Piquea4863342019-12-04 18:45:02 -08004332 compositionengine::LayerFE::ClientCompositionTargetSettings layer0TargetSettings{
4333 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004334 false, /* needs filtering */
4335 false, /* secure */
4336 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004337 kDisplayViewport,
4338 kDisplayDataspace,
4339 true /* realContentIsVisible */,
4340 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004341 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004342 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004343 };
4344 compositionengine::LayerFE::ClientCompositionTargetSettings layer1TargetSettings{
4345 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004346 false, /* needs filtering */
4347 false, /* secure */
4348 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004349 kDisplayViewport,
4350 kDisplayDataspace,
4351 true /* realContentIsVisible */,
4352 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004353 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004354 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004355 };
4356 compositionengine::LayerFE::ClientCompositionTargetSettings layer2TargetSettings{
4357 Region(kDisplayFrame),
Lloyd Piquea4863342019-12-04 18:45:02 -08004358 false, /* needs filtering */
4359 false, /* secure */
4360 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004361 kDisplayViewport,
4362 kDisplayDataspace,
4363 true /* realContentIsVisible */,
4364 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004365 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004366 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004367 };
4368
Ady Abrahameca9d752021-03-03 12:20:00 -08004369 EXPECT_CALL(*mLayers[0].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer0TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004370 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004371 EXPECT_CALL(*mLayers[1].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer1TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004372 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Ady Abrahameca9d752021-03-03 12:20:00 -08004373 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2TargetSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004374 .WillOnce(Return(std::vector<LayerFE::LayerSettings>()));
Lloyd Piquea4863342019-12-04 18:45:02 -08004375
Robert Carrccab4242021-09-28 16:53:03 -07004376 static_cast<void>(mOutput.generateClientCompositionRequestsHelper(true /* supportsProtectedContent */,
Lloyd Piquea4863342019-12-04 18:45:02 -08004377 kDisplayDataspace));
4378}
4379
Lucas Dupin084a6d42021-08-26 22:10:29 +00004380TEST_F(OutputUpdateAndWriteCompositionStateTest, noBackgroundBlurWhenOpaque) {
4381 InjectedLayer layer1;
4382 InjectedLayer layer2;
4383
4384 uint32_t z = 0;
4385 // Layer requesting blur, or below, should request client composition, unless opaque.
4386 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4387 EXPECT_CALL(*layer1.outputLayer,
4388 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4389 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4390 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
4391 EXPECT_CALL(*layer2.outputLayer,
4392 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4393 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
4394
4395 layer2.layerFEState.backgroundBlurRadius = 10;
4396 layer2.layerFEState.isOpaque = true;
4397
4398 injectOutputLayer(layer1);
4399 injectOutputLayer(layer2);
4400
4401 mOutput->editState().isEnabled = true;
4402
4403 CompositionRefreshArgs args;
4404 args.updatingGeometryThisFrame = false;
4405 args.devOptForceClientComposition = false;
4406 mOutput->updateCompositionState(args);
4407 mOutput->planComposition();
4408 mOutput->writeCompositionState(args);
4409}
4410
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004411TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBackgroundBlurRequests) {
Lloyd Piquede196652020-01-22 17:29:58 -08004412 InjectedLayer layer1;
4413 InjectedLayer layer2;
4414 InjectedLayer layer3;
4415
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004416 uint32_t z = 0;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004417 // Layer requesting blur, or below, should request client composition.
Snild Dolkow9e217d62020-04-22 15:53:42 +02004418 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004419 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004420 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4421 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004422 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004423 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004424 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4425 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Snild Dolkow9e217d62020-04-22 15:53:42 +02004426 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004427 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004428 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4429 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004430
Lloyd Piquede196652020-01-22 17:29:58 -08004431 layer2.layerFEState.backgroundBlurRadius = 10;
Lucas Dupin084a6d42021-08-26 22:10:29 +00004432 layer2.layerFEState.isOpaque = false;
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004433
Lloyd Piquede196652020-01-22 17:29:58 -08004434 injectOutputLayer(layer1);
4435 injectOutputLayer(layer2);
4436 injectOutputLayer(layer3);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004437
4438 mOutput->editState().isEnabled = true;
4439
4440 CompositionRefreshArgs args;
4441 args.updatingGeometryThisFrame = false;
4442 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004443 mOutput->updateCompositionState(args);
4444 mOutput->planComposition();
4445 mOutput->writeCompositionState(args);
Lucas Dupin19c8f0e2019-11-25 17:55:44 -08004446}
4447
Lucas Dupinc3800b82020-10-02 16:24:48 -07004448TEST_F(OutputUpdateAndWriteCompositionStateTest, handlesBlurRegionRequests) {
4449 InjectedLayer layer1;
4450 InjectedLayer layer2;
4451 InjectedLayer layer3;
4452
Leon Scroggins IIIe2ee0402021-04-02 16:59:37 -04004453 uint32_t z = 0;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004454 // Layer requesting blur, or below, should request client composition.
4455 EXPECT_CALL(*layer1.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004456 EXPECT_CALL(*layer1.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004457 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4458 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004459 EXPECT_CALL(*layer2.outputLayer, updateCompositionState(false, true, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004460 EXPECT_CALL(*layer2.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004461 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4462 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004463 EXPECT_CALL(*layer3.outputLayer, updateCompositionState(false, false, ui::Transform::ROT_0));
Dan Stoza6166c312021-01-15 16:34:05 -08004464 EXPECT_CALL(*layer3.outputLayer,
Leon Scroggins III9aa25c22021-04-15 15:30:19 -04004465 writeStateToHWC(/*includeGeometry*/ false, /*skipLayer*/ false, z++,
4466 /*zIsOverridden*/ false, /*isPeekingThrough*/ false));
Lucas Dupinc3800b82020-10-02 16:24:48 -07004467
4468 BlurRegion region;
4469 layer2.layerFEState.blurRegions.push_back(region);
Lucas Dupin084a6d42021-08-26 22:10:29 +00004470 layer2.layerFEState.isOpaque = false;
Lucas Dupinc3800b82020-10-02 16:24:48 -07004471
4472 injectOutputLayer(layer1);
4473 injectOutputLayer(layer2);
4474 injectOutputLayer(layer3);
4475
4476 mOutput->editState().isEnabled = true;
4477
4478 CompositionRefreshArgs args;
4479 args.updatingGeometryThisFrame = false;
4480 args.devOptForceClientComposition = false;
Dan Stoza269dc4d2021-01-15 15:07:43 -08004481 mOutput->updateCompositionState(args);
4482 mOutput->planComposition();
4483 mOutput->writeCompositionState(args);
Lucas Dupinc3800b82020-10-02 16:24:48 -07004484}
4485
Lloyd Piquea4863342019-12-04 18:45:02 -08004486TEST_F(GenerateClientCompositionRequestsTest, handlesLandscapeModeSplitScreenRequests) {
4487 // In split-screen landscape mode, the screen is rotated 90 degrees, with
4488 // one layer on the left covering the left side of the output, and one layer
4489 // on the right covering that side of the output.
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004490
4491 const Rect kPortraitFrame(0, 0, 1000, 2000);
4492 const Rect kPortraitViewport(0, 0, 2000, 1000);
Lloyd Piquee8fe4742020-01-21 15:26:18 -08004493 const Rect kPortraitDestinationClip(0, 0, 1000, 2000);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004494 const ui::Rotation kPortraitOrientation = ui::ROTATION_90;
Lloyd Piquea4863342019-12-04 18:45:02 -08004495 constexpr ui::Dataspace kOutputDataspace = ui::Dataspace::DISPLAY_P3;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004496
Angel Aguayob084e0c2021-08-04 23:27:28 +00004497 mOutput.mState.orientedDisplaySpace.setContent(kPortraitFrame);
4498 mOutput.mState.layerStackSpace.setContent(kPortraitViewport);
4499 mOutput.mState.displaySpace.setContent(kPortraitDestinationClip);
Marin Shalamanov68933fb2020-09-10 17:58:12 +02004500 mOutput.mState.transform = ui::Transform{ui::Transform::toRotationFlags(kPortraitOrientation)};
Angel Aguayob084e0c2021-08-04 23:27:28 +00004501 mOutput.mState.displaySpace.setOrientation(kPortraitOrientation);
Lloyd Piquea4863342019-12-04 18:45:02 -08004502 mOutput.mState.needsFiltering = false;
4503 mOutput.mState.isSecure = true;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004504
Lloyd Piquea4863342019-12-04 18:45:02 -08004505 Layer leftLayer;
4506 Layer rightLayer;
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004507
Lloyd Piquea4863342019-12-04 18:45:02 -08004508 leftLayer.mOutputLayerState.clearClientTarget = false;
4509 leftLayer.mOutputLayerState.visibleRegion = Region(Rect(0, 0, 1000, 1000));
4510 leftLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004511 leftLayer.mLayerSettings.source.solidColor = {1.f, 0.f, 0.f};
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004512
Lloyd Piquea4863342019-12-04 18:45:02 -08004513 rightLayer.mOutputLayerState.clearClientTarget = false;
4514 rightLayer.mOutputLayerState.visibleRegion = Region(Rect(1000, 0, 2000, 1000));
4515 rightLayer.mLayerFEState.isOpaque = true;
Vishnu Nair9b079a22020-01-21 14:36:08 -08004516 rightLayer.mLayerSettings.source.solidColor = {0.f, 1.f, 0.f};
Lloyd Piquea4863342019-12-04 18:45:02 -08004517
4518 EXPECT_CALL(mOutput, getOutputLayerCount()).WillRepeatedly(Return(2u));
4519 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(0u))
4520 .WillRepeatedly(Return(&leftLayer.mOutputLayer));
4521 EXPECT_CALL(mOutput, getOutputLayerOrderedByZByIndex(1u))
4522 .WillRepeatedly(Return(&rightLayer.mOutputLayer));
4523
Lloyd Piquea4863342019-12-04 18:45:02 -08004524 compositionengine::LayerFE::ClientCompositionTargetSettings leftLayerSettings{
4525 Region(Rect(0, 0, 1000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004526 false, /* needs filtering */
4527 true, /* secure */
4528 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004529 kPortraitViewport,
4530 kOutputDataspace,
4531 true /* realContentIsVisible */,
4532 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004533 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004534 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004535 };
4536
4537 EXPECT_CALL(leftLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4538 EXPECT_CALL(leftLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004539 EXPECT_CALL(*leftLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(leftLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004540 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({leftLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004541
4542 compositionengine::LayerFE::ClientCompositionTargetSettings rightLayerSettings{
4543 Region(Rect(1000, 0, 2000, 1000)),
Lloyd Piquea4863342019-12-04 18:45:02 -08004544 false, /* needs filtering */
4545 true, /* secure */
4546 true, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004547 kPortraitViewport,
4548 kOutputDataspace,
4549 true /* realContentIsVisible */,
4550 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004551 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004552 kLayerWhitePointNits,
Lloyd Piquea4863342019-12-04 18:45:02 -08004553 };
4554
4555 EXPECT_CALL(rightLayer.mOutputLayer, requiresClientComposition()).WillRepeatedly(Return(true));
4556 EXPECT_CALL(rightLayer.mOutputLayer, needsFiltering()).WillRepeatedly(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004557 EXPECT_CALL(*rightLayer.mLayerFE, prepareClientCompositionList(Eq(ByRef(rightLayerSettings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004558 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({rightLayer.mLayerSettings})));
Lloyd Piquea4863342019-12-04 18:45:02 -08004559
4560 constexpr bool supportsProtectedContent = true;
Sally Qidf3da512021-07-08 17:27:02 +00004561 auto requests =
Robert Carrccab4242021-09-28 16:53:03 -07004562 mOutput.generateClientCompositionRequestsHelper(supportsProtectedContent, kOutputDataspace);
Lloyd Piquea4863342019-12-04 18:45:02 -08004563 ASSERT_EQ(2u, requests.size());
Vishnu Nair9b079a22020-01-21 14:36:08 -08004564 EXPECT_EQ(leftLayer.mLayerSettings, requests[0]);
4565 EXPECT_EQ(rightLayer.mLayerSettings, requests[1]);
Lloyd Piquec2d54d42019-08-28 18:04:21 -07004566}
4567
Vishnu Naira483b4a2019-12-12 15:07:52 -08004568TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4569 shadowRegionOnlyVisibleSkipsContentComposition) {
4570 const Rect kContentWithShadow(40, 40, 70, 90);
4571 const Rect kContent(50, 50, 60, 80);
4572 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4573 const Region kPartialShadowRegion = Region(kContentWithShadow).subtract(Rect(40, 40, 60, 80));
4574
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004575 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4576 Region(Rect(60, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004577 false, /* needs filtering */
4578 false, /* secure */
4579 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004580 kDisplayViewport,
4581 kDisplayDataspace,
4582 false /* realContentIsVisible */,
4583 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004584 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004585 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004586 };
4587
Vishnu Nair9b079a22020-01-21 14:36:08 -08004588 LayerFE::LayerSettings mShadowSettings;
4589 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004590
4591 mLayers[2].mOutputLayerState.visibleRegion = kPartialShadowRegion;
4592 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4593
4594 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4595 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004596 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004597 .WillOnce(Return(std::vector<LayerFE::LayerSettings>({mShadowSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004598
Robert Carrccab4242021-09-28 16:53:03 -07004599 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004600 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004601 ASSERT_EQ(1u, requests.size());
4602
Vishnu Nair9b079a22020-01-21 14:36:08 -08004603 EXPECT_EQ(mShadowSettings, requests[0]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004604}
4605
4606TEST_F(GenerateClientCompositionRequestsTest_ThreeLayers,
4607 shadowRegionWithContentVisibleRequestsContentAndShadowComposition) {
4608 const Rect kContentWithShadow(40, 40, 70, 90);
4609 const Rect kContent(50, 50, 60, 80);
4610 const Region kShadowRegion = Region(kContentWithShadow).subtract(kContent);
4611 const Region kPartialContentWithPartialShadowRegion =
4612 Region(kContentWithShadow).subtract(Rect(40, 40, 50, 80));
4613
Vishnu Nair9b079a22020-01-21 14:36:08 -08004614 LayerFE::LayerSettings mShadowSettings;
4615 mShadowSettings.source.solidColor = {0.1f, 0.1f, 0.1f};
Vishnu Naira483b4a2019-12-12 15:07:52 -08004616
4617 mLayers[2].mOutputLayerState.visibleRegion = kPartialContentWithPartialShadowRegion;
4618 mLayers[2].mOutputLayerState.shadowRegion = kShadowRegion;
4619
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004620 compositionengine::LayerFE::ClientCompositionTargetSettings layer2Settings{
4621 Region(Rect(50, 40, 70, 80)).merge(Rect(40, 80, 70, 90)), /* visible region */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004622 false, /* needs filtering */
4623 false, /* secure */
4624 false, /* supports protected content */
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004625 kDisplayViewport,
4626 kDisplayDataspace,
4627 true /* realContentIsVisible */,
4628 false /* clearContent */,
Alec Mourif54453c2021-05-13 16:28:28 -07004629 compositionengine::LayerFE::ClientCompositionTargetSettings::BlurSetting::Enabled,
Alec Mouricdf6cbc2021-11-01 17:21:15 -07004630 kLayerWhitePointNits,
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004631 };
4632
Vishnu Naira483b4a2019-12-12 15:07:52 -08004633 EXPECT_CALL(mLayers[0].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
4634 EXPECT_CALL(mLayers[1].mOutputLayer, requiresClientComposition()).WillOnce(Return(false));
Ady Abrahameca9d752021-03-03 12:20:00 -08004635 EXPECT_CALL(*mLayers[2].mLayerFE, prepareClientCompositionList(Eq(ByRef(layer2Settings))))
Vishnu Nairb87d94f2020-02-13 09:17:36 -08004636 .WillOnce(Return(std::vector<LayerFE::LayerSettings>(
4637 {mShadowSettings, mLayers[2].mLayerSettings})));
Vishnu Naira483b4a2019-12-12 15:07:52 -08004638
Robert Carrccab4242021-09-28 16:53:03 -07004639 auto requests = mOutput.generateClientCompositionRequestsHelper(false /* supportsProtectedContent */,
Sally Qidf3da512021-07-08 17:27:02 +00004640 kDisplayDataspace);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004641 ASSERT_EQ(2u, requests.size());
4642
Vishnu Nair9b079a22020-01-21 14:36:08 -08004643 EXPECT_EQ(mShadowSettings, requests[0]);
4644 EXPECT_EQ(mLayers[2].mLayerSettings, requests[1]);
Vishnu Naira483b4a2019-12-12 15:07:52 -08004645}
4646
Lloyd Pique32cbe282018-10-19 13:09:22 -07004647} // namespace
4648} // namespace android::compositionengine